kwatable 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/COPYING +340 -0
  2. data/ChangeLog.txt +27 -0
  3. data/README.txt +81 -0
  4. data/bin/kwatable +20 -0
  5. data/examples/ex1/Makefile +34 -0
  6. data/examples/ex1/example1.yaml +85 -0
  7. data/examples/ex2/Makefile +34 -0
  8. data/examples/ex2/example2.yaml +94 -0
  9. data/kwatable.gemspec +48 -0
  10. data/lib/kwatable.rb +31 -0
  11. data/lib/kwatable/error-msg.rb +37 -0
  12. data/lib/kwatable/kwatable.schema.yaml +133 -0
  13. data/lib/kwatable/main-program.rb +197 -0
  14. data/lib/kwatable/manufactory.rb +213 -0
  15. data/lib/kwatable/templates/ddl-mysql.eruby +169 -0
  16. data/lib/kwatable/templates/ddl-postgresql.eruby +153 -0
  17. data/lib/kwatable/templates/defaults.yaml +87 -0
  18. data/lib/kwatable/templates/dto-java.eruby +204 -0
  19. data/lib/kwatable/templates/dto-ruby.eruby +180 -0
  20. data/setup.rb +1331 -0
  21. data/test/assert-diff.rb +44 -0
  22. data/test/test.rb +202 -0
  23. data/test/test1/test1.ddl-mysql.expected +22 -0
  24. data/test/test1/test1.ddl-postgresql.expected +22 -0
  25. data/test/test1/test1.dto-java.Group.expected +32 -0
  26. data/test/test1/test1.dto-java.User.expected +59 -0
  27. data/test/test1/test1.dto-ruby.Group.expected +21 -0
  28. data/test/test1/test1.dto-ruby.User.expected +36 -0
  29. data/test/test1/test1.yaml +85 -0
  30. data/test/test2/test2.ddl-mysql.expected +49 -0
  31. data/test/test2/test2.ddl-postgresql.expected +49 -0
  32. data/test/test2/test2.dto-java.Address.expected +42 -0
  33. data/test/test2/test2.dto-java.Customer.expected +49 -0
  34. data/test/test2/test2.dto-java.Item.expected +37 -0
  35. data/test/test2/test2.dto-java.SalesOrder.expected +50 -0
  36. data/test/test2/test2.dto-java.SalesOrderLine.expected +56 -0
  37. data/test/test2/test2.dto-ruby.Address.expected +25 -0
  38. data/test/test2/test2.dto-ruby.Customer.expected +32 -0
  39. data/test/test2/test2.dto-ruby.Item.expected +23 -0
  40. data/test/test2/test2.dto-ruby.SalesOrder.expected +32 -0
  41. data/test/test2/test2.dto-ruby.SalesOrderLine.expected +39 -0
  42. data/test/test2/test2.yaml +94 -0
  43. metadata +91 -0
@@ -0,0 +1,153 @@
1
+ <%
2
+
3
+ ##
4
+ ## kwatable template file for PostgreSQL
5
+ ##
6
+ ## copyright(c) 2005 kuwata-lab.com all rights reserved.
7
+ ## $Release: 0.0.1 $
8
+ ## $Rev: 12 $
9
+ ##
10
+ ## template properties:
11
+ ## (none)
12
+
13
+
14
+ #
15
+ # context variables
16
+ #
17
+ tables = context['tables']
18
+ properties = context['properties']
19
+ raise "don't use '-m' option with 'ddl-mysql.eruby'." unless tables
20
+
21
+
22
+ #
23
+ # PostgreSQL keywords
24
+ #
25
+ keywords = <<-END
26
+ abort admin all analyse analyze and any as asc
27
+ between binary bit both
28
+ case cast char character check cluster coalesce
29
+ collate column constraint copy cross current_date
30
+ current_time current_timestamp current_user
31
+ dec decimal default deferrable desc distinct do
32
+ else end except exists explain extend extract
33
+ false float for foreign from full
34
+ global group
35
+ having
36
+ ilike in initially inner inout intersect into is isnull
37
+ join
38
+ leading leftlike limit listen local lock
39
+ move
40
+ natural nchar new not notnull null nullif numeric
41
+ off offset old on only or order out outer overlaps
42
+ position precision primary public
43
+ references reset right
44
+ select session_user setof showsome substring
45
+ table then to trailing transaction trim true
46
+ union unique user using
47
+ vacuum varchar verbose
48
+ when where
49
+ END
50
+ KEYWORDS = {}
51
+ keywords.split(/\s+/).each { |word| KEYWORDS[word] = true }
52
+
53
+
54
+ #
55
+ # escape keyword
56
+ #
57
+ def _(word)
58
+ return KEYWORDS[word.downcase] ? "\"#{word}\"" : word
59
+ end
60
+
61
+
62
+ #
63
+ # start output
64
+ #
65
+ %>
66
+ ----------------------------------------------------------------------
67
+ -- DDL for PostgreSQL
68
+ -- generated by kwatable with template 'ddl-postgresql.eruby'
69
+ -- at <%= Time.now.to_s %>
70
+
71
+ ----------------------------------------------------------------------
72
+ <%
73
+ #
74
+ # create table statement
75
+ #
76
+ %>
77
+ <% for table in tables %>
78
+
79
+ -- <%= table['desc'] %>
80
+
81
+ create table <%= _(table['name']) %> (
82
+ <%
83
+ n = table['columns'].length
84
+ i = 0
85
+ for column in table['columns']
86
+ i += 1
87
+ flag_last_loop = (i == n)
88
+
89
+ name = column['name']
90
+ type = column['type']
91
+ width = column['width']
92
+
93
+ #
94
+ # column type
95
+ #
96
+ case type
97
+ when 'char' ;
98
+ when 'short' ; type = 'smallint'
99
+ when 'int' ; type = 'integer'
100
+ when 'inteter' ;
101
+ when 'str' ; type = 'varchar' ; width ||= 255
102
+ when 'string' ; type = 'varchar' ; width ||= 255
103
+ when 'text' ;
104
+ when 'float' ; type = 'real'
105
+ when 'double' ; type = 'double precision'
106
+ when 'bool' ; type = 'boolean'
107
+ when 'boolean' ;
108
+ when 'date' ;
109
+ when 'timestamp' ;
110
+ when 'money' ; type = 'decimal'
111
+ end
112
+ type += "(#{width})" if width
113
+
114
+ #
115
+ # use 'bigserial' instead of 'serial' if width is large
116
+ #
117
+ if column['serial']
118
+ type = width && width >= 10 ? 'bigserial' : 'serial'
119
+ end
120
+
121
+ #
122
+ # constraints
123
+ #
124
+ constraints = []
125
+ constraints << 'not null' if column['not-null'] && !column['serial'] && !column['primary-key']
126
+ constraints << 'primary key' if column['primary-key']
127
+ constraints << 'unique' if column['unique']
128
+ constraints << "references #{column['ref-table']['name']}(#{column['ref-column']['name']})" if column['ref-table']
129
+
130
+ #
131
+ # column definition
132
+ #
133
+ name_part = '%-20s' % _(name)
134
+ type_part = '%-20s' % type
135
+ const_part = constraints.join(' ')
136
+ comma = flag_last_loop ? '' : ','
137
+ comment = column['values'] ? " -- #{column['values'].join(',')}" : ""
138
+ %>
139
+ <%= name_part %> <%= type_part %> <%= const_part %><%= comma %><%= comment %>
140
+
141
+ <%
142
+ end
143
+
144
+ #
145
+ # composite primary key
146
+ #
147
+ %>
148
+ <% if table['primary-keys'] %>
149
+ <% pkeystr = table['primary-keys'].collect { |pkey| _(pkey) }.join(', ') %>
150
+ , primary key (<%= pkeystr %>)
151
+ <% end %>
152
+ );
153
+ <% end %>
@@ -0,0 +1,87 @@
1
+ ##
2
+ ## default definition of columns
3
+ ##
4
+ ## copyright(c) 2005 kuwata-lab all rights reserverd
5
+ ##
6
+ ## $Id: defaults.yaml 11 2005-09-11 13:15:45Z kwatch $
7
+ ## $Release: 0.0.1 $
8
+ ##
9
+
10
+ columns:
11
+ - name: id
12
+ type: integer
13
+ primary-key: yes
14
+ sequence: yes
15
+
16
+ - name: name
17
+ namepattern: /_name$/
18
+ type: string
19
+ #not-null: yes
20
+
21
+ - name: desc
22
+ type: string
23
+
24
+ - name: email
25
+ type: string
26
+
27
+ - name: status
28
+ type: string
29
+
30
+ - name: username
31
+ type: string
32
+
33
+ - name: password
34
+ type: string
35
+
36
+ - name: memo
37
+ type: text
38
+
39
+ - name: note
40
+ type: text
41
+
42
+ - name: comment
43
+ type: text
44
+
45
+ - name: text
46
+ type: text
47
+
48
+ - name: birth
49
+ type: date
50
+
51
+ - name: age
52
+ type: short
53
+ constraint: value >= 0
54
+
55
+ - name: date
56
+ namepattern: /_date$/
57
+ type: date
58
+
59
+ - name: time
60
+ namepattern: /_time$/
61
+ type: time
62
+
63
+ - name: gender
64
+ type: char
65
+ width: 1
66
+ values:
67
+ - M
68
+ - F
69
+
70
+ - name: blood
71
+ type: char
72
+ width: 2
73
+ values:
74
+ - A
75
+ - B
76
+ - O
77
+ - AB
78
+
79
+ - name: created_at
80
+ type: timestamp
81
+
82
+ - name: updated_at
83
+ type: timestamp
84
+
85
+ - name: last_update
86
+ type: timestamp
87
+
@@ -0,0 +1,204 @@
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.0.1 $
8
+ ## $Rev: 12 $
9
+ ##
10
+ ## template properties:
11
+ ## package - package name
12
+ ## parent - parent class
13
+
14
+
15
+ #
16
+ # context variables
17
+ #
18
+ table = context['table']
19
+ properties = context['properties']
20
+ raise "option '-m' is required when using 'dto-java.eruby'." unless table
21
+
22
+
23
+ unless defined?(KEYWORDS)
24
+ #
25
+ # java keywords
26
+ #
27
+ keywords = <<-END
28
+ abstract boolean break byte case catch char class const
29
+ continue default do double else extends final finally float
30
+ for goto if implements import instanceof int interface long
31
+ native new package private protected public return short
32
+ static strictfp super switch synchronized this throw throws
33
+ transient try void volatile while
34
+ END
35
+ KEYWORDS = {}
36
+ keywords.split(/\s+/).each { |word| KEYWORDS[word] = true }
37
+
38
+
39
+ #
40
+ # escape java keywords
41
+ #
42
+ def _(word)
43
+ return KEYWORDS[word] ? "_#{word}" : word
44
+ end
45
+
46
+
47
+ #
48
+ # convert 'aaa_bbb_ccc' into 'AaaBbbCcc'
49
+ #
50
+ def camel_case(name, flag_all=true)
51
+ s = ''
52
+ name.split('_').each_with_index do |word, i|
53
+ s << (!flag_all && i == 0 ? word.downcase : word.capitalize)
54
+ end
55
+ return s
56
+ #s = name.split('_').collect { |w| w.capitalize }.join()
57
+ #s[0] = s[0].to_s.upcase.chr unless flag_all
58
+ end
59
+
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 <%= 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
+ for var in variables
139
+ vartype = '%-12s' % var[:type]
140
+ varname = '%-12s' % (var[:name]+';')
141
+ %>
142
+ private <%= vartype %> <%= _(varname) %> /* <%= var[:desc] %> */
143
+ <%
144
+ end
145
+ %>
146
+
147
+ <%
148
+ #
149
+ # constructor
150
+ #
151
+ argstr = variables.collect { |var| "#{var[:type]} #{_(var[:name])}" }.join(', ')
152
+ %>
153
+ public <%= klass[:name] %>(<%= argstr %>) {
154
+ <% for var in variables %>
155
+ this.<%= _(var[:name]) %> = <%= _(var[:name]) %>;
156
+ <% end %>
157
+ }
158
+
159
+ <%
160
+ #
161
+ # getter/setter
162
+ #
163
+ for var in variables
164
+ vartype = var[:type]
165
+ varname = var[:name]
166
+ getter = "#{vartype == 'boolean' ? 'is' : 'get'}#{camel_case(varname)}"
167
+ setter = "set#{camel_case(varname)}"
168
+ %>
169
+ public <%= vartype %> <%= getter %>() { return <%= _(varname) %> }
170
+ public void <%= setter %>(<%= vartype %> <%= _(varname) %>) { this.<%= _(varname) %> = <%= _(varname) %>; }
171
+
172
+ <%
173
+ end
174
+ %>
175
+ // -----------
176
+
177
+ <%
178
+ #
179
+ # foreign keys
180
+ #
181
+ for column in table['columns']
182
+ if column['ref-table']
183
+ reftype = column['ref-table']['class']
184
+ refcol = column['ref-column']['name']
185
+ refname = column['ref-name']
186
+ varname = column['name']
187
+ if refname == varname
188
+ raise "table #{table['name']}: column #{column['name']}: proper ref-name is required."
189
+ end
190
+ getter = "get#{camel_case(column['ref-name'])}"
191
+ setter = getter.sub(/^get/, 'set')
192
+ %>
193
+ private <%= reftype %> <%= _(refname) %>;
194
+ public <%= reftype %> <%= getter %>() { return <%= _(refname) %>; }
195
+ public void <%= setter %>(<%= reftype %> <%= _(refname) %>) {
196
+ this.<%= _(refname) %> = <%= _(refname) %>;
197
+ this.<%= _(varname) %> = <%= _(refname) %>.get<%= camel_case(refcol) %>();
198
+ }
199
+
200
+ <%
201
+ end
202
+ end
203
+ %>
204
+ }
@@ -0,0 +1,180 @@
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.0.1 $
8
+ ## $Rev: 12 $
9
+ ##
10
+ ## template properties:
11
+ ## module - module name
12
+ ## parent - parent class
13
+ ## reqpath - require path
14
+
15
+
16
+ #
17
+ # context variables
18
+ #
19
+ table = context['table']
20
+ properties = context['properties']
21
+ raise "option '-m' is required when using 'dto-java.eruby'." unless table
22
+
23
+
24
+ unless defined?(KEYWORDS)
25
+ #
26
+ # java keywords
27
+ #
28
+ keywords = <<-END
29
+ BEGIN END alias and begin break case
30
+ class def defined do else elsif end
31
+ ensure false for if in module next
32
+ nil not or redo rescue retry return
33
+ self super then true undef unless
34
+ until when while yield
35
+ END
36
+ KEYWORDS = {}
37
+ keywords.split(/\s+/).each { |word| KEYWORDS[word] = true }
38
+
39
+
40
+ #
41
+ # escape java keywords
42
+ #
43
+ def _(word)
44
+ return KEYWORDS[word] ? "_#{word}" : word
45
+ end
46
+
47
+
48
+ #
49
+ # convert 'aaa_bbb_ccc' into 'AaaBbbCcc'
50
+ #
51
+ def camel_case(name, flag_all=true)
52
+ s = ''
53
+ name.split('_').each_with_index do |word, i|
54
+ s << (!flag_all && i == 0 ? word.downcase : word.capitalize)
55
+ end
56
+ return s
57
+ #s = name.split('_').collect { |w| w.capitalize }.join()
58
+ #s[0] = s[0].to_s.upcase.chr unless flag_all
59
+ end
60
+
61
+ end
62
+
63
+
64
+ #
65
+ # class definition
66
+ #
67
+ klass = {
68
+ :name => table['class'] || camel_case(table['name']),
69
+ :module => table['module'] || properties[:module],
70
+ :parent => table['parent'] || properties[:parent],
71
+ :desc => table['desc'],
72
+ }
73
+
74
+
75
+ #
76
+ # output file name
77
+ #
78
+ context[:output_filename] = klass[:name] + ".rb"
79
+
80
+
81
+ #
82
+ # instance variables
83
+ #
84
+ variables = []
85
+ for column in table['columns']
86
+ var = {
87
+ :name => column['name'],
88
+ :type => column['class'] || column['type'],
89
+ :desc => column['desc'],
90
+ }
91
+ variables << var
92
+ end
93
+
94
+ %>
95
+ ##
96
+ ## DTO for Ruby
97
+ ## generated by kwatable with template 'dto-ruby.eruby'
98
+ ## at <%= Time.now.to_s %>
99
+
100
+ ##
101
+ <%
102
+ #
103
+ # require other dto file
104
+ #
105
+ for column in table['columns']
106
+ if column['ref-table']
107
+ refclass = column['ref-table']['class']
108
+ refclass ||= camel_case(column['ref-table']['name'])
109
+ reqpath = properties[:reqpath]
110
+ %>
111
+ require '<%= reqpath %><%= reqpath ? '/' : '' %><%= refclass %>'
112
+ <%
113
+ end
114
+ end
115
+ %>
116
+
117
+ <%
118
+ #
119
+ # class definition start
120
+ #
121
+ mod = klass[:module] ? "#{klass[:module]}::" : ""
122
+ extends = klass[:parent] ? " < #{klass[:parent]}" : ""
123
+ %>
124
+ ## <%= klass[:desc] %>
125
+
126
+ class <%= mod %><%= klass[:name] %><% extends %>
127
+
128
+ <%
129
+ #
130
+ # initializer
131
+ #
132
+ argstr = variables.collect { |var| _(var[:name]) }.join(", ")
133
+ %>
134
+
135
+ def initialize(<%= argstr %>)
136
+ <% for var in variables %>
137
+ @<%= var[:name] %> = <%=_ var[:name] %>
138
+
139
+ <% end %>
140
+ end
141
+
142
+ <%
143
+ #
144
+ # accessor
145
+ #
146
+ %>
147
+ <% for var in variables %>
148
+ attr_accessor :<%= '%-14s' % var[:name] %> # <%= var[:desc] %>
149
+
150
+ <% end %>
151
+
152
+ // -----------
153
+
154
+ <%
155
+ #
156
+ # foreign keys
157
+ #
158
+ table['columns'].each do |column|
159
+ if column['ref-table']
160
+ refcol = column['ref-column']['name']
161
+ refname = column['ref-name']
162
+ varname = column['name']
163
+ if refname == varname
164
+ raise "table #{table['name']}: column #{column['name']}: proper ref-name is required."
165
+ end
166
+ %>
167
+ attr_reader :<%= refname %>
168
+
169
+ def <%= refname %>=(<%=_ refname %>)
170
+ @<%= refname %> = <%=_ refname %>
171
+
172
+ @<%= varname %> = <%=_ refname %>.<%= refcol %>
173
+
174
+ end
175
+
176
+ <%
177
+ end
178
+ end
179
+ %>
180
+ end