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.
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