kwatable 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/ChangeLog +46 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.txt +4 -2
  4. data/bin/kwatable +4 -4
  5. data/examples/ex1/Makefile +40 -14
  6. data/examples/ex1/{example1.yaml → tabledef.yaml} +42 -11
  7. data/examples/ex2/Makefile +41 -14
  8. data/examples/ex2/{example2.yaml → tabledef.yaml} +45 -30
  9. data/examples/ex3/Makefile +52 -0
  10. data/examples/ex3/tabledef.yaml +136 -0
  11. data/kwatable.gemspec +11 -10
  12. data/lib/kwatable.rb +24 -18
  13. data/lib/kwatable/kwatable.schema.yaml +95 -5
  14. data/lib/kwatable/main.rb +331 -0
  15. data/lib/kwatable/manipulator.rb +320 -192
  16. data/lib/kwatable/messages.rb +59 -0
  17. data/lib/kwatable/template/ddl-mysql.eruby +202 -0
  18. data/lib/kwatable/{templates → template}/ddl-postgresql.eruby +71 -45
  19. data/lib/kwatable/{templates → template}/defaults.yaml +2 -2
  20. data/lib/kwatable/template/dictionary.en.yaml +70 -0
  21. data/lib/kwatable/template/dictionary.ja.yaml +165 -0
  22. data/lib/kwatable/template/dto-java.eruby +77 -0
  23. data/lib/kwatable/template/dto-java.sub.eruby +259 -0
  24. data/lib/kwatable/template/dto-ruby.eruby +63 -0
  25. data/lib/kwatable/template/dto-ruby.sub.eruby +213 -0
  26. data/lib/kwatable/template/helper/column.rb +70 -0
  27. data/lib/kwatable/template/helper/common.rb +151 -0
  28. data/lib/kwatable/template/helper/java.rb +83 -0
  29. data/lib/kwatable/template/helper/label.rb +90 -0
  30. data/lib/kwatable/template/helper/ruby.rb +36 -0
  31. data/lib/kwatable/template/helper/table.rb +62 -0
  32. data/lib/kwatable/template/hibernate.eruby +139 -0
  33. data/lib/kwatable/template/rails-controller.eruby +66 -0
  34. data/lib/kwatable/template/rails-controller.sub.eruby +114 -0
  35. data/lib/kwatable/template/rails-kwartz.eruby +164 -0
  36. data/lib/kwatable/template/rails-kwartz/_attr.plogic.eruby +56 -0
  37. data/lib/kwatable/template/rails-kwartz/_form.plogic.eruby +81 -0
  38. data/lib/kwatable/template/rails-kwartz/_link.plogic.eruby +36 -0
  39. data/lib/kwatable/template/rails-kwartz/edit.cfg.yaml.eruby +16 -0
  40. data/lib/kwatable/template/rails-kwartz/edit.html.eruby +46 -0
  41. data/lib/kwatable/template/rails-kwartz/edit.plogic.eruby +20 -0
  42. data/lib/kwatable/template/rails-kwartz/layout.html.eruby +39 -0
  43. data/lib/kwatable/template/rails-kwartz/layout.plogic.eruby +32 -0
  44. data/lib/kwatable/template/rails-kwartz/list.html.eruby +94 -0
  45. data/lib/kwatable/template/rails-kwartz/list.plogic.eruby +41 -0
  46. data/lib/kwatable/template/rails-kwartz/new.html.eruby +100 -0
  47. data/lib/kwatable/template/rails-kwartz/new.plogic.eruby +26 -0
  48. data/lib/kwatable/template/rails-kwartz/show.html.eruby +51 -0
  49. data/lib/kwatable/template/rails-kwartz/show.plogic.eruby +9 -0
  50. data/lib/kwatable/template/rails-model.eruby +35 -0
  51. data/lib/kwatable/template/rails-model.sub.eruby +136 -0
  52. data/lib/kwatable/{templates → template}/validator-ruby.eruby +18 -11
  53. data/lib/kwatable/util.rb +133 -0
  54. data/lib/kwatable/util/assert-text-equal.rb +47 -0
  55. data/lib/kwatable/util/assertion.rb +115 -0
  56. data/lib/kwatable/validator.rb +50 -0
  57. data/test/assert-diff.rb +1 -1
  58. data/test/test-ex.rb +306 -0
  59. data/test/test.rb +37 -127
  60. metadata +66 -17
  61. data/COPYING +0 -340
  62. data/ChangeLog.txt +0 -65
  63. data/lib/kwatable/error-msg.rb +0 -38
  64. data/lib/kwatable/main-program.rb +0 -216
  65. data/lib/kwatable/templates/ddl-mysql.eruby +0 -172
  66. data/lib/kwatable/templates/dto-java.eruby +0 -260
  67. data/lib/kwatable/templates/dto-ruby.eruby +0 -185
@@ -0,0 +1,63 @@
1
+ <%
2
+
3
+ ##
4
+ ## kwatable template file for Ruby DTO class
5
+ ##
6
+ ## $Rev: 40 $
7
+ ## $Release: 0.3.0 $
8
+ ## copyright(c) 2005 kuwata-lab.com all rights reserved.
9
+ ##
10
+ ## <template-desc>generate DTO classes for Ruby</template-desc>
11
+ ## <template-properties>
12
+ ## --module=name : module name
13
+ ## --parent=name : parent class
14
+ ## --reqpath=path : require path
15
+ ## --populate : define populate method
16
+ ## --symbolkey : use symbol as hash key
17
+ ## </template-properties>
18
+ ##
19
+
20
+ require 'kwatable/template/helper/common'
21
+ require 'kwatable/template/helper/table'
22
+ require 'kwatable/template/helper/column'
23
+ require 'kwatable/template/helper/ruby'
24
+ extend Kwatable::CommonHelper
25
+ extend Kwatable::TableHelper
26
+ extend Kwatable::ColumnHelper
27
+ extend Kwatable::RubyHelper
28
+
29
+ require 'active_support/inflector'
30
+ #extend Inflector
31
+
32
+
33
+ ## context check
34
+ context_var_required('@tables')
35
+
36
+
37
+ ## use '_' as escape function
38
+ alias _ escape_ruby_keyword
39
+
40
+
41
+ ##
42
+ ## apply template
43
+ ##
44
+ basename = File.basename(@template_filename)
45
+ subtemplate_filename = basename.sub(/\.eruby\z/, '.sub.eruby')
46
+ subtemplate_filepath = Util.find_file(subtemplate_filename, @template_pathlist)
47
+ unless subtemplate_filepath
48
+ raise "#{basename}: subtemplate `#{subtemplate_filename}' not found."
49
+ end
50
+ @output_files = []
51
+ context = self
52
+ encoding = @properties[:encoding] || @properties[:charset]
53
+ each_table(@tables) do |table|p
54
+ @table = table
55
+ output = Util.eval_template(subtemplate_filepath, context)
56
+ output = Util.encode(output, encoding) if encoding
57
+ outfile = @output_filename # set in subtemplate
58
+ @output_files << [outfile, output, :create]
59
+ end
60
+ @table = nil
61
+
62
+
63
+ %>
@@ -0,0 +1,213 @@
1
+ <%
2
+
3
+ ##
4
+ ## sub-template of dto-ruby.eruby
5
+ ##
6
+ ## $Rev: 38 $
7
+ ## $Release: 0.3.0 $
8
+ ## copyright(c) 2005 kuwata-lab.com all rights reserved.
9
+ ##
10
+
11
+
12
+ #
13
+ # context check
14
+ #
15
+ context_var_required('@tables')
16
+
17
+
18
+ #
19
+ # output file name
20
+ #
21
+ @output_filename = Inflector.underscore(table_class(@table)) + ".rb"
22
+
23
+
24
+ #
25
+ # class definition
26
+ #
27
+ klass = {
28
+ :name => table_class(@table),
29
+ :module => @table['module'] || @properties[:module],
30
+ :parent => @table['parent'] || @properties[:parent],
31
+ :desc => @table['desc'],
32
+ }
33
+
34
+
35
+ #
36
+ # instance variables
37
+ #
38
+ variables = []
39
+ for column in @table['columns']
40
+ hash = {
41
+ :name => column_attr(column),
42
+ :type => column['class'] || column['type'],
43
+ :desc => column['desc'],
44
+ }
45
+ variables << hash
46
+ end
47
+
48
+
49
+ #
50
+ # relations
51
+ #
52
+ relations = []
53
+ for relation in @table['relations']
54
+ kind = relation['kind']
55
+ attr = Inflector.underscore(table_class(relation['table']))
56
+ attr = Inflector.pluralize(attr) unless kind == '1:1'
57
+ hash = {
58
+ :kind => kind,
59
+ :attr => relation['attr'] || attr,
60
+ }
61
+ relations << hash
62
+ end if @table['relations']
63
+
64
+
65
+ %>
66
+ ##
67
+ ## DTO for Ruby
68
+ ## generated by kwatable with template 'dto-ruby.eruby'
69
+ ## at <%= Time.now.to_s %>
70
+
71
+ ##
72
+ <%
73
+ #
74
+ # require other dto file
75
+ #
76
+ refclass_table = {}
77
+ coltypes = {}
78
+ for column in @table['columns']
79
+ coltypes[column['type']] = true
80
+ next unless column['ref']
81
+ refclass = table_class(column['ref']['table'])
82
+ reqpath = @properties[:reqpath]
83
+ next if refclass_table[refclass]
84
+ refclass_table[refclass] = true
85
+ libname = Inflector.underscore(refclass)
86
+ %>
87
+ require '<%= reqpath %><%= reqpath ? '/' : '' %><%= libname %>'
88
+ <%
89
+ end
90
+ %>
91
+ <% if @properties[:populate] %>
92
+ <% if coltypes['date'] || coltypes['datetime'] || coltypes['timestamp'] %>
93
+ require 'date'
94
+ <% end %>
95
+ <% if coltypes['time'] %>
96
+ require 'time'
97
+ <% end %>
98
+ <% end %>
99
+
100
+ <%
101
+ #
102
+ # class definition start
103
+ #
104
+ mod = klass[:module] ? "#{klass[:module]}::" : ""
105
+ extends = klass[:parent] ? " < #{klass[:parent]}" : ""
106
+
107
+ %>
108
+ <%= klass[:desc].gsub(/^/, '## ') %>
109
+
110
+ class <%= mod %><%= klass[:name] %><%= extends %>
111
+
112
+
113
+ <%
114
+ #
115
+ # accessor
116
+ #
117
+ %>
118
+ <% for var in variables %>
119
+ attr_accessor :<%= '%-14s' % var[:name] %> # <%= var[:desc] %>
120
+
121
+ <% end %>
122
+
123
+ <%
124
+ #
125
+ # set all values
126
+ #
127
+ %>
128
+ <% if @properties[:populate] %>
129
+ def populate(_hash={})
130
+ <%
131
+ flag_symbol = @properties[:symbolkey]
132
+ flag_date = flag_datetime = false
133
+ for var in variables
134
+ key = flag_symbol ? ":#{var[:name]}" : "'#{var[:name]}'"
135
+ case var[:type]
136
+ when 'str', 'string'
137
+ expr = "_hash[#{key}]"
138
+ when 'int', 'integer', 'short', 'long'
139
+ expr = "_hash[#{key}].to_i"
140
+ when 'float', 'double'
141
+ expr = "_hash[#{key}].to_f"
142
+ when 'char'
143
+ expr = "_hash[#{key}]"
144
+ when 'bool', 'boolean'
145
+ expr = "! _hash[#{key}].empty?"
146
+ when 'date'
147
+ expr = "Date.parse(_hash[#{key}])"
148
+ when 'time'
149
+ expr = "Time.parse(_hash[#{key}])"
150
+ when 'timestamp', 'datetime'
151
+ expr = "DateTime.parse(_hash[#{key}])"
152
+ when 'money'
153
+ expr = "_hash[#{key}].to_f"
154
+ else
155
+ raise "*** internal error: var=#{var.inspect}"
156
+ end
157
+ %>
158
+ <%= "@%-14s = %-25s if _hash.key?(%s)" % [var[:name], expr, key] %>
159
+
160
+ <%
161
+ end
162
+ %>
163
+ end
164
+
165
+ <% end %>
166
+ <%
167
+ #
168
+ # foreign keys
169
+ #
170
+ count = 0
171
+ for column in @table['columns']
172
+ if column['ref']
173
+ count += 1
174
+ refname = column_refname(column)
175
+ varname = column_name(column)
176
+ if refname == varname
177
+ raise "table #{@table['name']}: column #{column['name']}: proper ref-name is required."
178
+ end
179
+ reftype = table_class(column['ref']['table'])
180
+ argname = Inflector.underscore(reftype)
181
+ %>
182
+ <% if count == 1 %>
183
+ # accessors via foreign keys
184
+ <% end %>
185
+ attr_reader :<%= refname %>
186
+
187
+ def <%= refname %>=(<%=_ argname %>)
188
+ @<%= refname %> = <%=_ argname %>
189
+
190
+ self.<%= varname %> = <%=_ argname %>.<%= column_name(column['ref']) %>
191
+
192
+ end
193
+
194
+ <%
195
+ end
196
+ end
197
+ %>
198
+ <%
199
+ #
200
+ # relations
201
+ #
202
+ if !relations.empty?
203
+ %>
204
+ # relations
205
+ <% for relation in relations %>
206
+ attr_accessor :<%= '%-15s' % relation[:attr] %> # <%= relation[:kind] %>
207
+
208
+ <% end %>
209
+
210
+ <%
211
+ end
212
+ %>
213
+ end
@@ -0,0 +1,70 @@
1
+ ###
2
+ ### $Rev: 39 $
3
+ ### $Release: 0.3.0 $
4
+ ### copyright(c) 2005 kuwata-lab.com all rights reserved.
5
+ ###
6
+
7
+ module Kwatable
8
+
9
+ module ColumnHelper
10
+
11
+ module_function
12
+
13
+ ##
14
+ def column_attr(column)
15
+ return column['attr'] || column['name']
16
+ end
17
+
18
+ alias column_name column_attr
19
+
20
+ ##
21
+ def column_refname(column)
22
+ attr = column_attr(column)
23
+ return column['ref-name'] || \
24
+ (column['ref'] ? attr.sub(/_#{column['ref']['name']}\z/, '') : attr)
25
+ end
26
+
27
+ ##
28
+ def column_label(column)
29
+ return column['label'] || column_refname(column)
30
+ end
31
+
32
+
33
+ ##
34
+ def column_showable?(column)
35
+ #return column_control_type(column) ? true : false
36
+ name = column['name']
37
+ return false if name == 'id'
38
+ return false if name == 'password' || name == 'passwd'
39
+ return true
40
+ end
41
+
42
+ ##
43
+ def column_editable?(column)
44
+ name = column['name']
45
+ return false if name == 'id'
46
+ return false if name =~ /\A(created|updated)_(on|at)\z/
47
+ return true
48
+ end
49
+
50
+ ##
51
+ def column_control_type(column)
52
+ type = column['type']
53
+ name = column['name']
54
+ if name == 'id' ; return nil
55
+ elsif column['ref'] ; return 'select'
56
+ elsif column['enum'] ; return 'radio'
57
+ elsif %w[created_on created_at].include?(name) ; return nil
58
+ elsif %w[modified_on modified_at].include?(name) ; return nil
59
+ elsif %w[date timestamp datetime].include?(type) ; return 'select'
60
+ elsif %w[boolean bool].include?(type) ; return 'checkbox'
61
+ elsif %w[text].include?(type) ; return 'text_area'
62
+ elsif %w[password passwd].include?(name) ; return 'password_field'
63
+ else ; return 'text_field'
64
+ end
65
+ end
66
+
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,151 @@
1
+ ##
2
+ ## $Rev: 43 $
3
+ ## $Release: 0.3.0 $
4
+ ## copyright(c) 2005 kuwata-lab.com all rights reserved.
5
+ ##
6
+
7
+ require 'kwatable/util'
8
+
9
+ module Kwatable
10
+
11
+
12
+ module CommonHelper
13
+
14
+
15
+ ##
16
+ def context_var_required(var_name)
17
+ value = instance_variable_get(var_name)
18
+ return if value
19
+ template_name = File.basename(@template_filename).sub(/\.\w+$/, '')
20
+ msg = case var_name
21
+ when '@tables' ; "don't use '-m' option with '%s'." % template_name
22
+ when '@table' ; "option '-m' is required when using '%s'." % template_name
23
+ else ; "context value '%s' required but not found." % var_name
24
+ end
25
+ err = StandardError.new(msg)
26
+ err.set_backtrace(caller())
27
+ raise err
28
+ end
29
+
30
+
31
+ ## convert 'foo_bar_baz' into 'FooBarBaz'
32
+ def camel_case(name, flag_all=true)
33
+ s = ''
34
+ name.split('_').each_with_index do |word, i|
35
+ s << (!flag_all && i == 0 ? word.downcase : word.capitalize)
36
+ end
37
+ #s = name.split('_').collect { |w| w.capitalize }.join()
38
+ #s[0] = s[0].to_s.upcase.chr unless flag_all
39
+ return s
40
+ end
41
+
42
+
43
+ ## quote by single-quoation
44
+ def q(obj)
45
+ return "'#{obj.to_s.gsub(/['\\]/, '\\\\\1')}'"
46
+ end
47
+
48
+
49
+ ## find file from path_list
50
+ def find_file(filename, path_list, find_in_currdir=true)
51
+ return Util.find_file(filename, path_list, find_in_currdir)
52
+ end
53
+
54
+
55
+ ## find subtemplate
56
+ def find_subtemplate(template_filename=@template_filename, template_pathlist=@template_pathlist)
57
+ basename = File.basename(template_filename)
58
+ subtemplate_filename = basename.sub(/\.eruby\z/, '.sub.eruby')
59
+ subtemplate_filepath = Util.find_file(subtemplate_filename, template_pathlist)
60
+ unless subtemplate_filepath
61
+ raise "#{basename}: subtemplate `#{subtemplate_filepath}' not found."
62
+ end
63
+ return subtemplate_filepath
64
+ end
65
+
66
+
67
+ ## read user custom code from output filename and apply template with it.
68
+ ## return output string and action symbol(:create, :update, or :identical).
69
+ def eval_template_with_custom_code(template_filename, context, output_filename, options={})
70
+ # options
71
+ encoding = options[:encoding]
72
+ template = options[:template]
73
+ # get user custom code
74
+ if test(?f, output_filename)
75
+ content = File.read(output_filename)
76
+ custom_code = user_custom_code(content)
77
+ else
78
+ content = custom_code = nil
79
+ end
80
+ # eval template and get output
81
+ context.instance_variable_set("@user_custom_code", custom_code)
82
+ output = Util.eval_template(template_filename, context, template)
83
+ output = encode(output, encoding) if encoding
84
+ context.instance_variable_set("@user_custom_code", nil)
85
+ # detect action
86
+ action = content.nil? ? :create : (content == output ? :identical : :update)
87
+ return output, action
88
+ end
89
+
90
+
91
+ ## get user custom code
92
+ def user_custom_code(content)
93
+ pattern = /^.*<user-custom-code>(?:.|\n)*<\/user-custom-code>.*\n/
94
+ return content =~ pattern ? $& : nil
95
+ end
96
+
97
+
98
+ ## encode string
99
+ def encode(str, encoding)
100
+ require 'kconv'
101
+ out_code = case encoding
102
+ when /\Aeuc-jp\z/i ; Kconv::EUC
103
+ when /\As(hift[-_])?jis\z/i ; Kconv::SJIS
104
+ when /\Autf8\z/i ; Kconv::UTF8
105
+ when /\Autf16\z/i ; Kconv::UTF16
106
+ when /\Aiso-2022-jp\z/i ; Kconv::JIS
107
+ else ; nil
108
+ end
109
+ return Kconv.kconv(str, out_code)
110
+ end
111
+
112
+
113
+ ##
114
+ def each_table(tables, &block)
115
+ tables.each do |table|
116
+ reason = table_check_modeling(table)
117
+ if reason
118
+ msg = "*** table '#{table['name']}' skipped. (reason: #{reason})"
119
+ $stderr.puts msg unless @options[?q]
120
+ else
121
+ yield(table)
122
+ end
123
+ end
124
+ end
125
+
126
+
127
+ ## apply subtemplate for each tables
128
+ def apply_subtemplate_for_each_tables(tables, opthash={}, &block)
129
+ subtemplate_filepath = find_subtemplate()
130
+ subtemplate = File.read(subtemplate_filepath)
131
+ encoding = @properties[:encoding] || @properties[:charset]
132
+ context = self
133
+ output_files = []
134
+ opts = { :encoding=>encoding, :template=>subtemplate }
135
+ each_table(@tables) do |table|
136
+ output_filename = yield(table)
137
+ dir = @options[?d]
138
+ output_filename = "#{dir}/#{output_filename}" if dir
139
+ @table = table
140
+ output, action = eval_template_with_custom_code(subtemplate_filepath, context, output_filename, opts)
141
+ @table = nil
142
+ output_files << [output_filename, output, action]
143
+ end
144
+ return output_files
145
+ end
146
+
147
+
148
+ end
149
+
150
+
151
+ end