kwatable 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +46 -0
- data/MIT-LICENSE +20 -0
- data/README.txt +4 -2
- data/bin/kwatable +4 -4
- data/examples/ex1/Makefile +40 -14
- data/examples/ex1/{example1.yaml → tabledef.yaml} +42 -11
- data/examples/ex2/Makefile +41 -14
- data/examples/ex2/{example2.yaml → tabledef.yaml} +45 -30
- data/examples/ex3/Makefile +52 -0
- data/examples/ex3/tabledef.yaml +136 -0
- data/kwatable.gemspec +11 -10
- data/lib/kwatable.rb +24 -18
- data/lib/kwatable/kwatable.schema.yaml +95 -5
- data/lib/kwatable/main.rb +331 -0
- data/lib/kwatable/manipulator.rb +320 -192
- data/lib/kwatable/messages.rb +59 -0
- data/lib/kwatable/template/ddl-mysql.eruby +202 -0
- data/lib/kwatable/{templates → template}/ddl-postgresql.eruby +71 -45
- data/lib/kwatable/{templates → template}/defaults.yaml +2 -2
- data/lib/kwatable/template/dictionary.en.yaml +70 -0
- data/lib/kwatable/template/dictionary.ja.yaml +165 -0
- data/lib/kwatable/template/dto-java.eruby +77 -0
- data/lib/kwatable/template/dto-java.sub.eruby +259 -0
- data/lib/kwatable/template/dto-ruby.eruby +63 -0
- data/lib/kwatable/template/dto-ruby.sub.eruby +213 -0
- data/lib/kwatable/template/helper/column.rb +70 -0
- data/lib/kwatable/template/helper/common.rb +151 -0
- data/lib/kwatable/template/helper/java.rb +83 -0
- data/lib/kwatable/template/helper/label.rb +90 -0
- data/lib/kwatable/template/helper/ruby.rb +36 -0
- data/lib/kwatable/template/helper/table.rb +62 -0
- data/lib/kwatable/template/hibernate.eruby +139 -0
- data/lib/kwatable/template/rails-controller.eruby +66 -0
- data/lib/kwatable/template/rails-controller.sub.eruby +114 -0
- data/lib/kwatable/template/rails-kwartz.eruby +164 -0
- data/lib/kwatable/template/rails-kwartz/_attr.plogic.eruby +56 -0
- data/lib/kwatable/template/rails-kwartz/_form.plogic.eruby +81 -0
- data/lib/kwatable/template/rails-kwartz/_link.plogic.eruby +36 -0
- data/lib/kwatable/template/rails-kwartz/edit.cfg.yaml.eruby +16 -0
- data/lib/kwatable/template/rails-kwartz/edit.html.eruby +46 -0
- data/lib/kwatable/template/rails-kwartz/edit.plogic.eruby +20 -0
- data/lib/kwatable/template/rails-kwartz/layout.html.eruby +39 -0
- data/lib/kwatable/template/rails-kwartz/layout.plogic.eruby +32 -0
- data/lib/kwatable/template/rails-kwartz/list.html.eruby +94 -0
- data/lib/kwatable/template/rails-kwartz/list.plogic.eruby +41 -0
- data/lib/kwatable/template/rails-kwartz/new.html.eruby +100 -0
- data/lib/kwatable/template/rails-kwartz/new.plogic.eruby +26 -0
- data/lib/kwatable/template/rails-kwartz/show.html.eruby +51 -0
- data/lib/kwatable/template/rails-kwartz/show.plogic.eruby +9 -0
- data/lib/kwatable/template/rails-model.eruby +35 -0
- data/lib/kwatable/template/rails-model.sub.eruby +136 -0
- data/lib/kwatable/{templates → template}/validator-ruby.eruby +18 -11
- data/lib/kwatable/util.rb +133 -0
- data/lib/kwatable/util/assert-text-equal.rb +47 -0
- data/lib/kwatable/util/assertion.rb +115 -0
- data/lib/kwatable/validator.rb +50 -0
- data/test/assert-diff.rb +1 -1
- data/test/test-ex.rb +306 -0
- data/test/test.rb +37 -127
- metadata +66 -17
- data/COPYING +0 -340
- data/ChangeLog.txt +0 -65
- data/lib/kwatable/error-msg.rb +0 -38
- data/lib/kwatable/main-program.rb +0 -216
- data/lib/kwatable/templates/ddl-mysql.eruby +0 -172
- data/lib/kwatable/templates/dto-java.eruby +0 -260
- data/lib/kwatable/templates/dto-ruby.eruby +0 -185
data/lib/kwatable/error-msg.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
###
|
2
|
-
### copyright(c) 2005 kuwata-lab.com all rights reserved.
|
3
|
-
### $Release: 0.2.0 $
|
4
|
-
### $Rev: 15 $
|
5
|
-
###
|
6
|
-
|
7
|
-
module Kwatable
|
8
|
-
|
9
|
-
@@messages = {}
|
10
|
-
|
11
|
-
def self.msg(key)
|
12
|
-
return @@messages[key]
|
13
|
-
end
|
14
|
-
|
15
|
-
#----- begin auto generate
|
16
|
-
@@messages[:tabledef_empty] = "table definition file is empty."
|
17
|
-
@@messages[:tabledef_notmap] = "table definition is not a mapping."
|
18
|
-
@@messages[:template_required] = "template is not specified."
|
19
|
-
@@messages[:template_notfound] = "`%s': template file not found."
|
20
|
-
@@messages[:file_generated] = "generated: %s"
|
21
|
-
@@messages[:template_required] = "-%s: template filename required."
|
22
|
-
@@messages[:outdir_required] = "-%s: output directory required."
|
23
|
-
@@messages[:directory_required] = "-%s: directory required."
|
24
|
-
@@messages[:option_invalid] = "-%s: invalid option."
|
25
|
-
@@messages[:colname_required] = "table '%s': column name required (index=%d)."
|
26
|
-
@@messages[:regexp_invalid] = "table '%s': column '%s': pattern %s: %s"
|
27
|
-
@@messages[:coldef_duplicated] = "table '%s': column '%s': column name is duplicated."
|
28
|
-
@@messages[:tablename_required] = "table definition doesn't have a name (index=%d)."
|
29
|
-
@@messages[:tabledef_duplicated] = "table '%s': table name is duplicated."
|
30
|
-
@@messages[:tablecolumn_required] = "table '%s': column name requried (index=%d)."
|
31
|
-
@@messages[:tablecolumn_duplicated] = "table '%s': column '%s': column name is duplicated."
|
32
|
-
@@messages[:tabletype_required] = "table `%s': column `%s': type is not determined."
|
33
|
-
@@messages[:alias_conflict] = "table '%s', column '%s': alias key '%1:' and '%2:' are not allowed to use in the same time."
|
34
|
-
@@messages[:reftable_notfound] = "`table '%s': column '%s': 'ref: %s': reference table not found."
|
35
|
-
@@messages[:refcolumn_notfound] = "`table '%s': column '%s': ref: %s': reference column not found in the table."
|
36
|
-
#----- end auto generate
|
37
|
-
|
38
|
-
end
|
@@ -1,216 +0,0 @@
|
|
1
|
-
###
|
2
|
-
### copyright(c) 2005 kuwata-lab.com all rights reserved.
|
3
|
-
### $Release: 0.2.0 $
|
4
|
-
### $Rev: 17 $
|
5
|
-
###
|
6
|
-
|
7
|
-
require 'yaml'
|
8
|
-
require 'erb'
|
9
|
-
|
10
|
-
module Kwatable
|
11
|
-
|
12
|
-
class CommandOptionError < KwatableError
|
13
|
-
end
|
14
|
-
|
15
|
-
class MainProgram
|
16
|
-
def initialize(argv=ARGV)
|
17
|
-
@argv = argv
|
18
|
-
end
|
19
|
-
|
20
|
-
def execute()
|
21
|
-
options, properties = _parse_options(@argv)
|
22
|
-
|
23
|
-
## help or version
|
24
|
-
if options[?h] || options[?v]
|
25
|
-
puts _version() if options[?v]
|
26
|
-
puts _usage() if options[?h]
|
27
|
-
return
|
28
|
-
end
|
29
|
-
|
30
|
-
## load data file
|
31
|
-
s = ''
|
32
|
-
filenames = @argv
|
33
|
-
filenames.each do |filename|
|
34
|
-
File.open(filename) do |f|
|
35
|
-
f.each_line do |line|
|
36
|
-
s << line.gsub(/([^\t]{8})|([^\t]*)\t/n){[$+].pack("A8")} ## expand tab
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
tabledef = YAML.load(s)
|
41
|
-
unless tabledef
|
42
|
-
#* key=:tabledef_empty msg="table definition file is empty."
|
43
|
-
raise _option_error(:tabledef_empty)
|
44
|
-
end
|
45
|
-
unless tabledef.is_a?(Hash)
|
46
|
-
#* key=:tabledef_notmap msg="table definition is not a mapping."
|
47
|
-
raise _option_error(:tabledef_notmap)
|
48
|
-
end
|
49
|
-
|
50
|
-
## manipulation
|
51
|
-
manipulator = Manipulator.new()
|
52
|
-
manipulator.manipulate(tabledef)
|
53
|
-
$stderr.print tabledef.to_yaml if options[?D]
|
54
|
-
|
55
|
-
## template filename
|
56
|
-
template = options[?f]
|
57
|
-
unless template
|
58
|
-
return nil if options[?D]
|
59
|
-
#* key=:template_required msg="template is not specified."
|
60
|
-
raise _option_error(:template_required)
|
61
|
-
end
|
62
|
-
|
63
|
-
## template filepath
|
64
|
-
template_filepath = nil
|
65
|
-
if test(?f, template)
|
66
|
-
template_filepath = template
|
67
|
-
elsif options[?I] && t = _find_template(template, options[?I])
|
68
|
-
template_filepath = t
|
69
|
-
else
|
70
|
-
template_filepath = _find_template(template, Kwatable.template_path)
|
71
|
-
end
|
72
|
-
unless template_filepath
|
73
|
-
#* key=:template_notfound msg="`%s': template file not found."
|
74
|
-
raise _option_error(:template_notfound, template)
|
75
|
-
end
|
76
|
-
|
77
|
-
## apply template
|
78
|
-
if !options[?m]
|
79
|
-
context = { 'tables' => tabledef['tables'], 'properties' => properties, }
|
80
|
-
output = _apply_template(template_filepath, context)
|
81
|
-
else
|
82
|
-
tabledef['tables'].each do |table|
|
83
|
-
context = { 'table' => table, 'properties' => properties, }
|
84
|
-
output = _apply_template(template_filepath, context)
|
85
|
-
output_filename = context[:output_filename]
|
86
|
-
output_filename = "#{options[?d]}/#{output_filename}" if options[?d]
|
87
|
-
File.open(output_filename, 'w') { |f| f.write(output) }
|
88
|
-
unless options[?q]
|
89
|
-
#* key=:file_generated msg="generated: %s"
|
90
|
-
$stderr.puts(Kwatable.msg(:file_generated) % output_filename)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
output = nil
|
94
|
-
end
|
95
|
-
return output
|
96
|
-
end
|
97
|
-
|
98
|
-
def self.main(argv=ARGV)
|
99
|
-
begin
|
100
|
-
main = MainProgram.new(ARGV)
|
101
|
-
output = main.execute()
|
102
|
-
print output if output
|
103
|
-
rescue KwatableError => ex
|
104
|
-
$stderr.puts "[ERROR] #{ex.message()}"
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
private
|
109
|
-
|
110
|
-
|
111
|
-
def _option_error(message_key, *args)
|
112
|
-
msg = Kwatable.msg(message_key) % args
|
113
|
-
return CommandOptionError.new(msg)
|
114
|
-
end
|
115
|
-
|
116
|
-
def _parse_options(argv)
|
117
|
-
options = {}
|
118
|
-
properties = {}
|
119
|
-
while argv[0] && argv[0][0] == ?-
|
120
|
-
optstr = argv.shift
|
121
|
-
if optstr =~ /\A--([-\w]+)(=.*)?/ ## properties
|
122
|
-
key, value = $1, $2
|
123
|
-
key = key.gsub(/-/, '_')
|
124
|
-
if value
|
125
|
-
value.sub!(/\A=/, '')
|
126
|
-
else
|
127
|
-
value = true
|
128
|
-
end
|
129
|
-
case value
|
130
|
-
when "true", "yes" ; value = true
|
131
|
-
when "false", "no" ; value = false
|
132
|
-
when "null", "nil" ; value = nil
|
133
|
-
when /\A\d+\z/ ; value = value.to_i
|
134
|
-
when /\A\d+\.\d+\z/ ; value = value.to_f
|
135
|
-
when /\A'.*'\z/ ; value = eval(value)
|
136
|
-
when /\A".*"\z/ ; value = eval(value)
|
137
|
-
end
|
138
|
-
properties[key.intern] = value
|
139
|
-
else
|
140
|
-
optstr = optstr[1, optstr.length-1]
|
141
|
-
while optstr && !optstr.empty?
|
142
|
-
optchar = optstr[0]
|
143
|
-
optstr = optstr[1, optstr.length-1]
|
144
|
-
case optchar
|
145
|
-
when ?h, ?v, ?m, ?q, ?D
|
146
|
-
options[optchar] = true
|
147
|
-
when ?f, ?t
|
148
|
-
arg = optstr.empty? ? argv.shift : optstr
|
149
|
-
optstr = nil
|
150
|
-
#* key=:template_required msg="-%s: template filename required."
|
151
|
-
raise _option_error(:template_required, optchar.chr) unless arg
|
152
|
-
options[?f] = arg
|
153
|
-
#options[optchar] = arg
|
154
|
-
when ?d
|
155
|
-
arg = optstr.empty? ? argv.shift : optstr
|
156
|
-
optstr = nil
|
157
|
-
#* key=:outdir_required msg="-%s: output directory required."
|
158
|
-
raise _option_error(:outdir_required, optchar.chr) unless arg
|
159
|
-
options[optchar] = arg
|
160
|
-
when ?I
|
161
|
-
arg = optstr.empty? ? argv.shift : optstr
|
162
|
-
optstr = nil
|
163
|
-
#* key=:directory_required msg="-%s: directory required."
|
164
|
-
raise _option_error(:directory_required, optchar.chr) unless arg
|
165
|
-
(options[optchar] ||= []).concat(arg.split(/,/))
|
166
|
-
else
|
167
|
-
#* key=:option_invalid msg="-%s: invalid option."
|
168
|
-
raise _option_error(:option_invalid, optchar.chr)
|
169
|
-
end
|
170
|
-
end # end while
|
171
|
-
end # end if
|
172
|
-
end # end while
|
173
|
-
return options, properties
|
174
|
-
end
|
175
|
-
|
176
|
-
def _find_template(template, path_list)
|
177
|
-
path_list.each do |path|
|
178
|
-
t = "#{path}/#{template}"
|
179
|
-
return t if test(?f, t)
|
180
|
-
end
|
181
|
-
return nil
|
182
|
-
end
|
183
|
-
|
184
|
-
def _apply_template(filename, context)
|
185
|
-
str = File.open(filename) { |f| f.read() }
|
186
|
-
trim_mode = '>' # or '%'
|
187
|
-
erb = ERB.new(str, $SAFE, trim_mode)
|
188
|
-
result = _eval_erb(erb, context)
|
189
|
-
return result
|
190
|
-
end
|
191
|
-
|
192
|
-
def _eval_erb(__erb, context)
|
193
|
-
return __erb.result(binding())
|
194
|
-
end
|
195
|
-
|
196
|
-
def _usage()
|
197
|
-
command = File::basename($0)
|
198
|
-
s = ""
|
199
|
-
s << "Usage: #{command} [-hvm] [-I path] [-d dir] -f template datafile [datafile2 ...]\n"
|
200
|
-
s << " -h : help\n"
|
201
|
-
s << " -v : version\n"
|
202
|
-
s << " -I path : template directory path\n"
|
203
|
-
s << " -f template : template filename\n"
|
204
|
-
s << " -m : multiple output file\n"
|
205
|
-
s << " -d dir : output file directory (with '-m')\n"
|
206
|
-
s << " -q : quiet mode\n"
|
207
|
-
return s
|
208
|
-
end
|
209
|
-
|
210
|
-
def _version()
|
211
|
-
return ("$Release: 0.2.0 $" =~ /[\.\d]+/ && $&)
|
212
|
-
end
|
213
|
-
|
214
|
-
end
|
215
|
-
|
216
|
-
end
|
@@ -1,172 +0,0 @@
|
|
1
|
-
<%
|
2
|
-
|
3
|
-
##
|
4
|
-
## kwatable template file for MySQL
|
5
|
-
##
|
6
|
-
## copyright(c) 2005 kuwata-lab.com all rights reserved.
|
7
|
-
## $Release: 0.2.0 $
|
8
|
-
## $Rev: 15 $
|
9
|
-
##
|
10
|
-
## template properties:
|
11
|
-
## (none)
|
12
|
-
##
|
13
|
-
|
14
|
-
|
15
|
-
#
|
16
|
-
# context variables
|
17
|
-
#
|
18
|
-
tables = context['tables']
|
19
|
-
properties = context['properties']
|
20
|
-
raise "don't use '-m' option with 'ddl-mysql.eruby'." unless tables
|
21
|
-
|
22
|
-
|
23
|
-
#
|
24
|
-
# MySQL keywords
|
25
|
-
#
|
26
|
-
keywords = <<-END
|
27
|
-
add all alter analyze and as asc asensitive
|
28
|
-
before between bigint binary blob both by
|
29
|
-
call cascade case change char character check collate column
|
30
|
-
condition connection constraint continue convert create cross
|
31
|
-
current_date current_time current_timestamp current_user cursor
|
32
|
-
database databases day_hour day_microsecond day_minute day_second
|
33
|
-
dec decimal declare default delayed delete desc describe
|
34
|
-
deterministic distinct distinctrow div double drop dual
|
35
|
-
each else elseif enclosed escaped exists exit explain
|
36
|
-
false fetch float for force foreign from fulltext
|
37
|
-
goto grant group
|
38
|
-
having high_priority hour_microsecond hour_minute hour_second
|
39
|
-
if ignore in index infile inner inout insensitive insert
|
40
|
-
int integer interval into is iterate
|
41
|
-
join
|
42
|
-
key keys kill
|
43
|
-
leading leave left like limit lines load localtime
|
44
|
-
localtimestamp lock long longblob longtext loop low_priority
|
45
|
-
match mediumblob mediumint mediumtext middleint
|
46
|
-
minute_microsecond minute_second mod modifies
|
47
|
-
natural not no_write_to_binlog null numeric
|
48
|
-
on optimize option optionally or order out outer outfile
|
49
|
-
precision primary procedure purge
|
50
|
-
read reads real references regexp release rename repeat
|
51
|
-
replace require restrict return revoke right rlike
|
52
|
-
schema schemas second_microsecond select sensitive
|
53
|
-
separator set show smallint soname spatial specific sql
|
54
|
-
sqlexception sqlstate sqlwarning sql_big_result
|
55
|
-
sql_calc_found_rows sql_small_result ssl starting straight_join
|
56
|
-
table terminated then tinyblob tinyint tinytext to
|
57
|
-
trailing trigger true
|
58
|
-
undo union unique unlock unsigned update usage use using
|
59
|
-
utc_date utc_time utc_timestamp
|
60
|
-
values varbinary varchar varcharacter varying
|
61
|
-
when where while with write
|
62
|
-
xor
|
63
|
-
year_month
|
64
|
-
zerofill
|
65
|
-
END
|
66
|
-
@keywords = {}
|
67
|
-
keywords.split(/\s+/).each { |word| @keywords[word] = true }
|
68
|
-
|
69
|
-
|
70
|
-
#
|
71
|
-
# escape keyword
|
72
|
-
#
|
73
|
-
def self._(word)
|
74
|
-
return @keywords[word.downcase] ? "`#{word}`" : word
|
75
|
-
end
|
76
|
-
|
77
|
-
|
78
|
-
#
|
79
|
-
# start output
|
80
|
-
#
|
81
|
-
%>
|
82
|
-
----------------------------------------------------------------------
|
83
|
-
-- DDL for MySQL
|
84
|
-
-- generated by kwatable with template 'ddl-mysql.eruby'
|
85
|
-
-- at <%= Time.now.to_s %>
|
86
|
-
|
87
|
-
----------------------------------------------------------------------
|
88
|
-
<%
|
89
|
-
#
|
90
|
-
# create table statement
|
91
|
-
#
|
92
|
-
%>
|
93
|
-
<% for table in tables %>
|
94
|
-
|
95
|
-
-- <%= table['desc'] %>
|
96
|
-
|
97
|
-
create table <%= _(table['name']) %> (
|
98
|
-
<%
|
99
|
-
n = table['columns'].length
|
100
|
-
i = 0
|
101
|
-
for column in table['columns']
|
102
|
-
i += 1
|
103
|
-
flag_last_loop = (i == n)
|
104
|
-
|
105
|
-
name = column['name']
|
106
|
-
type = column['type']
|
107
|
-
width = column['width']
|
108
|
-
|
109
|
-
#
|
110
|
-
# column type
|
111
|
-
#
|
112
|
-
case type
|
113
|
-
when 'char' ; type = 'tinyint'
|
114
|
-
when 'short' ; type = 'mediumint'
|
115
|
-
when 'int' ; type = 'integer'
|
116
|
-
when 'inteter' ;
|
117
|
-
when 'str' ; type = 'varchar' ; width ||= 255
|
118
|
-
when 'string' ; type = 'varchar' ; width ||= 255
|
119
|
-
when 'text' ;
|
120
|
-
when 'float' ;
|
121
|
-
when 'double' ;
|
122
|
-
when 'bool' ; type = 'boolean'
|
123
|
-
when 'boolean' ;
|
124
|
-
when 'date' ;
|
125
|
-
when 'timestamp' ;
|
126
|
-
when 'money' ; type = 'decimal'
|
127
|
-
end
|
128
|
-
type += "(#{width})" if width
|
129
|
-
|
130
|
-
#
|
131
|
-
# set type with 'enum(...)' if column has enum
|
132
|
-
#
|
133
|
-
if column['enum']
|
134
|
-
type = "enum(" + column['enum'].collect{|v| "'#{v}'"}.join(", ") + ")"
|
135
|
-
width = nil
|
136
|
-
end
|
137
|
-
|
138
|
-
#
|
139
|
-
# constraints
|
140
|
-
#
|
141
|
-
constraints = []
|
142
|
-
constraints << 'auto_increment' if column['serial']
|
143
|
-
constraints << 'not null' if column['required'] && !column['serial'] && !column['ident']
|
144
|
-
constraints << 'primary key' if column['ident']
|
145
|
-
constraints << 'unique' if column['unique']
|
146
|
-
|
147
|
-
#
|
148
|
-
# column definition
|
149
|
-
#
|
150
|
-
name_part = '%-20s' % _(name)
|
151
|
-
type_part = '%-20s' % type
|
152
|
-
const_part = constraints.join(' ')
|
153
|
-
comma = flag_last_loop ? '' : ','
|
154
|
-
#comment = column['ref'] ? " -- references #{column['ref']}" : ""
|
155
|
-
ref = column['ref']
|
156
|
-
comment = ref ? " -- references #{ref['table']['name']}(#{ref['name']})" : ""
|
157
|
-
%>
|
158
|
-
<%= name_part %> <%= type_part %> <%= const_part %><%= comma %><%= comment %>
|
159
|
-
|
160
|
-
<%
|
161
|
-
end
|
162
|
-
|
163
|
-
#
|
164
|
-
# composite primary key
|
165
|
-
#
|
166
|
-
%>
|
167
|
-
<% if table['primary-keys'] %>
|
168
|
-
<% pkeystr = table['primary-keys'].collect { |pkey| _(pkey) }.join(', ') %>
|
169
|
-
, primary key (<%= pkeystr %>)
|
170
|
-
<% end %>
|
171
|
-
);
|
172
|
-
<% end %>
|
@@ -1,260 +0,0 @@
|
|
1
|
-
<%
|
2
|
-
|
3
|
-
##
|
4
|
-
## kwatable template file for Java DTO class
|
5
|
-
##
|
6
|
-
## copyright(c) 2005 kuwata-lab.com all rights reserved.
|
7
|
-
## $Release: 0.2.0 $
|
8
|
-
## $Rev: 17 $
|
9
|
-
##
|
10
|
-
## template properties:
|
11
|
-
## --package=name : package name
|
12
|
-
## --parent=name : parent class
|
13
|
-
## --constructor : define constructor
|
14
|
-
## --populate : define populate method
|
15
|
-
##
|
16
|
-
|
17
|
-
|
18
|
-
#
|
19
|
-
# context variables
|
20
|
-
#
|
21
|
-
table = context['table']
|
22
|
-
properties = context['properties']
|
23
|
-
raise "option '-m' is required when using 'dto-java.eruby'." unless table
|
24
|
-
|
25
|
-
|
26
|
-
#
|
27
|
-
# java keywords
|
28
|
-
#
|
29
|
-
keywords = <<-END
|
30
|
-
abstract assert boolean break byte case catch char class const
|
31
|
-
continue default do double else enum extends final finally float
|
32
|
-
for goto if implements import instanceof int interface long
|
33
|
-
native new package private protected public return short
|
34
|
-
static strictfp super switch synchronized this throw throws
|
35
|
-
transient try void volatile while
|
36
|
-
END
|
37
|
-
@keywords = {}
|
38
|
-
keywords.split(/\s+/).each { |word| @keywords[word] = true }
|
39
|
-
|
40
|
-
|
41
|
-
#
|
42
|
-
# escape java keywords
|
43
|
-
#
|
44
|
-
def self._(word)
|
45
|
-
return @keywords[word] ? "_#{word}" : word
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
#
|
50
|
-
# convert 'aaa_bbb_ccc' into 'AaaBbbCcc'
|
51
|
-
#
|
52
|
-
def self.camel_case(name, flag_all=true)
|
53
|
-
s = ''
|
54
|
-
name.split('_').each_with_index do |word, i|
|
55
|
-
s << (!flag_all && i == 0 ? word.downcase : word.capitalize)
|
56
|
-
end
|
57
|
-
return s
|
58
|
-
#s = name.split('_').collect { |w| w.capitalize }.join()
|
59
|
-
#s[0] = s[0].to_s.upcase.chr unless flag_all
|
60
|
-
end
|
61
|
-
|
62
|
-
|
63
|
-
#
|
64
|
-
# class definition
|
65
|
-
#
|
66
|
-
klass = {
|
67
|
-
:name => table['class'] || camel_case(table['name']),
|
68
|
-
:package => table['package'] || properties[:package],
|
69
|
-
:parent => table['parent'] || properties[:parent],
|
70
|
-
:desc => table['desc'],
|
71
|
-
}
|
72
|
-
|
73
|
-
|
74
|
-
#
|
75
|
-
# output file name
|
76
|
-
#
|
77
|
-
context[:output_filename] = klass[:name] + ".java"
|
78
|
-
|
79
|
-
|
80
|
-
#
|
81
|
-
# instance variables
|
82
|
-
#
|
83
|
-
variables = []
|
84
|
-
imports = []
|
85
|
-
for column in table['columns']
|
86
|
-
type = column['class']
|
87
|
-
unless type
|
88
|
-
type = column['type']
|
89
|
-
width = column['width']
|
90
|
-
case type
|
91
|
-
when 'char' ; type = (!width || width == 1) ? 'char' : 'String'
|
92
|
-
when 'short' ;
|
93
|
-
when 'int', 'integer' ; type = 'int'
|
94
|
-
when 'str', 'string' ; type = width == 1 ? 'char' : 'String'
|
95
|
-
when 'text' ; type = width == 1 ? 'char' : 'String'
|
96
|
-
when 'float' ;
|
97
|
-
when 'double' ;
|
98
|
-
when 'bool', 'boolean' ; type = 'boolean'
|
99
|
-
when 'date' ; type = 'Date' ; imports << 'java.util.Date'
|
100
|
-
when 'timestamp' ; type = 'Date' ; imports << 'java.util.Date'
|
101
|
-
when 'money' ; type = 'double'
|
102
|
-
end
|
103
|
-
end
|
104
|
-
var = {
|
105
|
-
:name => column['name'],
|
106
|
-
:type => type,
|
107
|
-
:desc => column['desc'],
|
108
|
-
}
|
109
|
-
variables << var
|
110
|
-
end
|
111
|
-
imports.uniq!
|
112
|
-
|
113
|
-
%>
|
114
|
-
/*
|
115
|
-
* DTO for Java
|
116
|
-
* generated by kwatable with template 'dto-java.eruby'
|
117
|
-
* at <%= Time.now.to_s %>
|
118
|
-
|
119
|
-
*/
|
120
|
-
<% if klass[:package] %>
|
121
|
-
package <%= klass[:package] %>;
|
122
|
-
<% end %>
|
123
|
-
<% for class_name in imports %>
|
124
|
-
import <%= class_name %>;
|
125
|
-
<% end %>
|
126
|
-
|
127
|
-
/**
|
128
|
-
* <%= klass[:desc] %>
|
129
|
-
|
130
|
-
*/
|
131
|
-
<% extends = klass[:parent] ? ' extends ' + klass[:parent] : '' %>
|
132
|
-
public class <%= klass[:name] %><%= extends %> implements java.io.Serializable {
|
133
|
-
|
134
|
-
<%
|
135
|
-
#
|
136
|
-
# instance variables
|
137
|
-
#
|
138
|
-
%>
|
139
|
-
<% for var in variables %>
|
140
|
-
<% varname = '%-12s' % ( _(var[:name]) + ';') %>
|
141
|
-
private <%= '%-12s' % var[:type] %> <%= varname %> /* <%= var[:desc] %> */
|
142
|
-
<% end %>
|
143
|
-
|
144
|
-
<%
|
145
|
-
#
|
146
|
-
# constructor
|
147
|
-
#
|
148
|
-
argstr = variables.collect { |var| "#{var[:type]} #{_(var[:name])}" }.join(', ')
|
149
|
-
%>
|
150
|
-
<% if properties[:constructor] %>
|
151
|
-
public <%= klass[:name] %>(<%= argstr %>) {
|
152
|
-
<% for var in variables %>
|
153
|
-
set<%= camel_case(var[:name]) %>(<%= _(var[:name]) %>);
|
154
|
-
<% end %>
|
155
|
-
}
|
156
|
-
|
157
|
-
<% end %>
|
158
|
-
<%
|
159
|
-
#
|
160
|
-
# set all values with java.sql.ResultSet
|
161
|
-
#
|
162
|
-
%>
|
163
|
-
<% if properties[:populate] %>
|
164
|
-
public void populate(java.sql.ResultSet resultset) throws java.sql.SQLException {
|
165
|
-
<% n = 0 %>
|
166
|
-
<% for var in variables %>
|
167
|
-
<% if var[:type] == 'char' %>
|
168
|
-
<% if (n += 1) == 1 %>
|
169
|
-
String val;
|
170
|
-
<% end %>
|
171
|
-
val = resultset.getString("<%= var[:name] %>");
|
172
|
-
set<%= camel_case(var[:name]) %>(val != null && val.length() > 0 ? val.charAt(0) : 0);
|
173
|
-
<% else %>
|
174
|
-
set<%= camel_case(var[:name]) %>(resultset.get<%= var[:type].capitalize %>("<%= var[:name] %>"));
|
175
|
-
<% end %>
|
176
|
-
<% end %>
|
177
|
-
}
|
178
|
-
|
179
|
-
<% end %>
|
180
|
-
<%
|
181
|
-
#
|
182
|
-
# set all properties
|
183
|
-
#
|
184
|
-
%>
|
185
|
-
<% if properties[:populate] %>
|
186
|
-
public void populate(java.util.Map _map) {
|
187
|
-
String val = null;
|
188
|
-
<% for var in variables %>
|
189
|
-
if (_map.containsKey("<%= var[:name] %>")) {
|
190
|
-
val = (String)_map.get("<%= var[:name] %>");
|
191
|
-
<% case var[:type] %>
|
192
|
-
<% when 'String' %>
|
193
|
-
this.<%= _(var[:name]) %> = val;
|
194
|
-
<% when 'int' %>
|
195
|
-
this.<%= _(var[:name]) %> = Integer.parseInt(val);
|
196
|
-
<% when 'long' %>
|
197
|
-
this.<%= _(var[:name]) %> = Long.parseLong(val);
|
198
|
-
<% when 'float' %>
|
199
|
-
this.<%= _(var[:name]) %> = Float.parseFloat(val);
|
200
|
-
<% when 'double' %>
|
201
|
-
this.<%= _(var[:name]) %> = Double.parseDouble(val);
|
202
|
-
<% when 'char' %>
|
203
|
-
this.<%= _(var[:name]) %> = val.length() > 0 ? val.charAt(0) : 0;
|
204
|
-
<% when 'boolean' %>
|
205
|
-
this.<%= _(var[:name]) %> = val.length() > 0;
|
206
|
-
<% when 'Date' %>
|
207
|
-
try {
|
208
|
-
this.<%= _(var[:name]) %> = java.text.DateFormat.getDateInstance().parse(val);
|
209
|
-
} catch (java.text.ParseException ignore) {
|
210
|
-
}
|
211
|
-
<% else %>
|
212
|
-
<% raise "*** internal error: template='dto-java.eruby', var[:type]=#{var[:type].inspect}" %>
|
213
|
-
<% end %>
|
214
|
-
}
|
215
|
-
<% end %>
|
216
|
-
}
|
217
|
-
|
218
|
-
<% end %>
|
219
|
-
<%
|
220
|
-
#
|
221
|
-
# getter/setter
|
222
|
-
#
|
223
|
-
for var in variables
|
224
|
-
vartype = var[:type]
|
225
|
-
varname = var[:name]
|
226
|
-
getter = "#{vartype == 'boolean' ? 'is' : 'get'}#{camel_case(varname)}"
|
227
|
-
setter = "set#{camel_case(varname)}"
|
228
|
-
%>
|
229
|
-
public <%= vartype %> <%= getter %>() { return <%= _(varname) %>; }
|
230
|
-
public void <%= setter %>(<%= vartype %> <%= _(varname) %>) { this.<%= _(varname) %> = <%= _(varname) %>; }
|
231
|
-
|
232
|
-
<% end %>
|
233
|
-
<%
|
234
|
-
#
|
235
|
-
# foreign keys
|
236
|
-
#
|
237
|
-
for column in table['columns']
|
238
|
-
if column['ref']
|
239
|
-
reftype = column['ref']['table']['class']
|
240
|
-
refcolname = column['ref']['name']
|
241
|
-
refname = column['ref-name']
|
242
|
-
varname = column['name']
|
243
|
-
if refname == varname
|
244
|
-
raise "table #{table['name']}: column #{column['name']}: proper ref-name is required."
|
245
|
-
end
|
246
|
-
getter = "get#{camel_case(column['ref-name'])}"
|
247
|
-
setter = getter.sub(/^get/, 'set')
|
248
|
-
%>
|
249
|
-
private <%= reftype %> <%= _(refname) %>;
|
250
|
-
public <%= reftype %> <%= getter %>() { return <%= _(refname) %>; }
|
251
|
-
public void <%= setter %>(<%= reftype %> <%= _(refname) %>) {
|
252
|
-
this.<%= _(refname) %> = <%= _(refname) %>;
|
253
|
-
this.<%= _(varname) %> = <%= _(refname) %>.get<%= camel_case(refcolname) %>();
|
254
|
-
}
|
255
|
-
|
256
|
-
<%
|
257
|
-
end
|
258
|
-
end
|
259
|
-
%>
|
260
|
-
}
|