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,9 @@
1
+ <%
2
+ ###
3
+ ### $Rev$
4
+ ### $Release: 0.3.0 $
5
+ ### copyright(c) 2005 kuwata-lab.com all rights reserved.
6
+ ###
7
+ %>
8
+ @import '_link.plogic';
9
+ @import '_attr.plogic';
@@ -0,0 +1,35 @@
1
+ <%
2
+
3
+ ##
4
+ ## kwatable template to generate Rails model class
5
+ ##
6
+ ## $Rev$
7
+ ## $Release: 0.3.0 $
8
+ ## copyright(c) 2005 kuwata-lab.com all rights reserved.
9
+ ##
10
+ ## <template-desc>generate Rails model classes</template-desc>
11
+ ## <template-properties>
12
+ ## --lang=lang : language (ex. --lang=ja)
13
+ ## --backup[=.bkup] : create backup file when updating
14
+ ## --encoding=encoding : encoding (ex. --encoding=UTF8)
15
+ ## </template-properties>
16
+ ##
17
+
18
+
19
+ require 'kwatable/template/helper/common'
20
+ require 'kwatable/template/helper/table'
21
+ require 'kwatable/template/helper/column'
22
+ require 'kwatable/template/helper/label'
23
+ extend Kwatable::CommonHelper
24
+ extend Kwatable::TableHelper
25
+ extend Kwatable::ColumnHelper
26
+ extend Kwatable::LabelHelper
27
+
28
+
29
+ @output_files = apply_subtemplate_for_each_tables(@tables) { |table|
30
+ output_filename = table_model(table) + '.rb'
31
+ output_filename
32
+ }
33
+
34
+
35
+ %>
@@ -0,0 +1,136 @@
1
+ <%
2
+
3
+ ##
4
+ ## $Rev$
5
+ ## $Release: 0.3.0 $
6
+ ## copyright(c) 2005 kuwata-lab.com all rights reserved.
7
+ ##
8
+
9
+ ##
10
+ def relation_options(hash)
11
+ list = hash.collect { |key, val|
12
+ k = Inflector.underscore(key)
13
+ v = val.inspect
14
+ case k
15
+ when 'kind' ; nil
16
+ when 'desc' ; nil
17
+ when 'table' ; nil
18
+ when 'columns' ; nil
19
+ when 'where' ; ":conditions=>#{v}"
20
+ when 'orderby' ; ":order=>#{v}"
21
+ #when 'as' ; ":#{k}=>#{v}"
22
+ #when 'through' ; ":#{k}=>#{v}"
23
+ #when 'source' ; ":#{k}=>#{v}"
24
+ else ; ":#{k}=>#{v}"
25
+ end
26
+ }.compact()
27
+ return list
28
+ end
29
+
30
+
31
+ ## generate model class
32
+ def generate_model_rb(table, user_code=nil)
33
+ controller_name = table['name']
34
+ class_name = table_class(table)
35
+ desc = (table['desc'] || '').gsub(/^/, '## ').chomp
36
+ # class start
37
+ s = ''
38
+ s << "#{desc}\n"
39
+ s << "class #{class_name} < ActiveRecord::Base\n"
40
+ # table name
41
+ if Inflector.pluralize(table_model(table)) != table['name']
42
+ s << " set_table_name '#{table['name']}'\n"
43
+ end
44
+ # primary key
45
+ ident_column = table['ident-columns'].first
46
+ if ident_column['name'] != 'id'
47
+ s << " set_primary_key '#{ident_column['name']}'\n"
48
+ end
49
+ # has_many, has_one
50
+ relmethods = { '1:1'=>'has_one', '1:n'=>'has_many', 'n:n'=>'has_and_belongs_to_many' }
51
+ for relation in table['relations']
52
+ relmethod = relmethods[relation['kind']]
53
+ relmodel = table_model(relation['table'])
54
+ relcolname = column_name(relation['columns'].first)
55
+ relopts = ''
56
+ relopts << ", :foreign_key=>'#{relcolname}'" if relcolname != "#{table_model(table)}_id"
57
+ relopts << ", :join_table=>'#{relation['join-table']['name']}'" if relation['join-table']
58
+ relopts << ", :conditions=>#{relation['where'].inspect}" if relation['where']
59
+ relopts << ", :order=>'#{relation['order-by']}'" if relation['order-by']
60
+ relopts << ", :group=>'#{relation['group-by']}'" if relation['group-by']
61
+ for key in ['as', 'through', 'source']
62
+ relopts << ", :#{key}=>#{relation[key].inspect}" if relation[key]
63
+ end
64
+ if relation['vendor'] && relation['vendor']['rails-model']
65
+ for param in relation['vendor']['rails-model']
66
+ key, value = param
67
+ key.gsub!(/-/, '_')
68
+ relopts << ", :#{key}=>#{value.inspect}"
69
+ end
70
+ end
71
+ s << " #{relmethod} :#{relmodel}#{relopts}\n"
72
+ end if table['relations']
73
+ # belongs_to
74
+ columns = table['columns']
75
+ for column in columns
76
+ if column['ref']
77
+ ref_name = column_refname(column)
78
+ s << " belongs_to :#{ref_name}"
79
+ ref_model_name = table_model(column['ref']['table'])
80
+ ref_class_name = table_class(column['ref']['table'])
81
+ s << ", :class_name=>'#{ref_class_name}'" if ref_name != ref_model_name
82
+ ref_attr = column_attr(column['ref'])
83
+ foreign_key = "#{ref_model_name}_#{ref_attr}"
84
+ s << ", :foreign_key=>'#{column_attr(column)}'" if column['name'] != foreign_key
85
+ s << "\n"
86
+ end
87
+ end if columns
88
+ # alias
89
+ for column in columns
90
+ if column_attr(column) != column['name']
91
+ #s << " alias #{column_attr(column)} #{column['name']}\n"
92
+ s << " def #{column_attr(column)}; #{column['name']}; end\n"
93
+ s << " def #{column_attr(column)}=(_val); #{column['name']}=(_val); end\n"
94
+ end
95
+ end if columns
96
+ # validator
97
+ for column in columns
98
+ next if !column_editable?(column)
99
+ colname = column_name(column)
100
+ if column['required']
101
+ s << " validates_presence_of :#{colname}\n"
102
+ end
103
+ if %w[int integer float double money].include?(column['type'])
104
+ s << " validates_numericality_of :#{colname}\n" unless column['ref']
105
+ end
106
+ if column['unique'] || (column['ident'] && colname != 'id')
107
+ s << " validates_uniqueness_of :#{colname}\n"
108
+ end
109
+ if column['pattern']
110
+ s << " validates_format_of :#{colname}, :with=>#{column['pattern']}\n"
111
+ end
112
+ if column['length']
113
+ h = column['length']
114
+ s << " validates_length_of :#{colname}"
115
+ s << ", :maximum=>#{h['max']}" if h['max']
116
+ s << ", :minimum=>#{h['min']}" if h['min']
117
+ s << "\n"
118
+ end
119
+ end if columns
120
+ s << "\n"
121
+ # user-code
122
+ if user_code
123
+ s << user_code
124
+ else
125
+ s << " ## <user-custom-code>\n"
126
+ s << " ## ... put user custom code here\n"
127
+ s << " ## </user-custom-code>\n"
128
+ end
129
+ s << "\n"
130
+ #
131
+ s << "end\n"
132
+ return s
133
+ end
134
+
135
+ %>
136
+ <%= generate_model_rb(@table, @user_custom_code) %>
@@ -3,20 +3,27 @@
3
3
  ##
4
4
  ## kwatable template file for Ruby Validator
5
5
  ##
6
+ ## $Rev: 32 $
7
+ ## $Release: 0.3.0 $
6
8
  ## copyright(c) 2005 kuwata-lab.com all rights reserved.
7
- ## $Release: 0.2.0 $
8
- ## $Rev$
9
9
  ##
10
- ## template properties:
11
- ## module - module/class name
10
+ ## <template-desc>generate validator class for Ruby</template-desc>
11
+ ## <template-properties>
12
+ ## --module=name : module/class name
13
+ ## </template-properties>
12
14
  ##
13
15
 
16
+ require 'kwatable/template/helper/common'
17
+ extend Kwatable::CommonHelper
18
+
19
+
14
20
  #
15
- # context variables
21
+ # context check
16
22
  #
17
- tables = context['tables']
18
- properties = context['properties']
19
-
23
+ context_var_required('@tables')
24
+ #@tables or raise "don't use '-m' option with '%'." % File.basename(@template_filename)
25
+
26
+
20
27
  #
21
28
  # constraint keys
22
29
  #
@@ -29,12 +36,12 @@
29
36
  ## at <%= Time.now.to_s %>
30
37
 
31
38
  ##
32
- <% if properties[:module] %>
39
+ <% if @properties[:module] %>
33
40
 
34
- module <%= properties[:module] %>
41
+ module <%= @properties[:module] %>
35
42
 
36
43
  <% end %>
37
- <% for table in tables %>
44
+ <% for table in @tables %>
38
45
 
39
46
  ## <%= table['name'] %> - <%= table['desc'] %>
40
47
 
@@ -0,0 +1,133 @@
1
+ ###
2
+ ### $Rev: 43 $
3
+ ### $Release: 0.3.0 $
4
+ ### copyright(c) 2005 kuwata-lab.com all rights reserved.
5
+ ###
6
+
7
+ module Kwatable
8
+
9
+
10
+ module Util
11
+
12
+
13
+ module_function
14
+
15
+
16
+ ##
17
+ ## expand tab characters into spaces
18
+ ##
19
+ def untabify(str, width=8)
20
+ list = str.split(/\t/)
21
+ last = list.pop
22
+ sb = ''
23
+ list.each do |s|
24
+ column = (n = s.rindex(?\n)) ? s.length - n - 1 : s.length
25
+ n = width - (column % width)
26
+ sb << s << (" " * n)
27
+ end
28
+ sb << last
29
+ return sb
30
+ end
31
+
32
+
33
+ ##
34
+ ## find file from path_list
35
+ ##
36
+ def find_file(filename, path_list, find_in_currdir=true, test_char=?f)
37
+ ch = test_char
38
+ return filename if find_in_currdir && test(ch, filename)
39
+ #return nil if filename[0] == ?/ # absolute path
40
+ fname = nil
41
+ found = path_list.find { |path| test(ch, fname = "#{path}/#{filename}") }
42
+ return found ? fname : nil
43
+ end
44
+
45
+
46
+ ##
47
+ ## evaluate template with context object
48
+ ##
49
+ def eval_template(template_filename, context, template=nil)
50
+ template ||= File.read(template_filename)
51
+ trim_mode = 1
52
+ erb = ERB.new(template, nil, trim_mode)
53
+ return context.instance_eval(erb.src, template_filename)
54
+ end
55
+
56
+
57
+ ##
58
+ ## encode string
59
+ ##
60
+ def encode(str, encoding)
61
+ require 'kconv'
62
+ out_code = case encoding
63
+ when /\Aeuc-jp\z/i ; Kconv::EUC
64
+ when /\As(hift[-_])?jis\z/i ; Kconv::SJIS
65
+ when /\Autf8\z/i ; Kconv::UTF8
66
+ when /\Autf16\z/i ; Kconv::UTF16
67
+ when /\Aiso-2022-jp\z/i ; Kconv::JIS
68
+ else ; nil
69
+ end
70
+ return Kconv.kconv(str, out_code)
71
+ end
72
+
73
+
74
+ ##
75
+ ## parse command-line options
76
+ ##
77
+ ## ex.
78
+ ## argv = %w[-hqu user -p passwd --help --name=val file1 file2]
79
+ ## options, properties, filenames = Util.parse_argv(argv, "hvq", "upl")
80
+ ## p options #=> { ?h=>true, ?q=>true, ?u=>"user", ?p=>"passwd" }
81
+ ## p properties #=> { :help=>true, :name=>"val" }
82
+ ## p filenames #=> [ "file1", "file2" ]
83
+ ##
84
+ def parse_argv(argv, single_opts='', arged_opts='', optional_opts='')
85
+ options = {}
86
+ properties = {}
87
+ while argv[0] && argv[0][0] == ?-
88
+ optstr = argv.shift
89
+ if optstr == '-'
90
+ break
91
+ elsif optstr =~ /\A--([-\w]+)(?:=(.*))?/ # properties
92
+ key, value = $1, $2
93
+ case value
94
+ when nil ; value = true
95
+ when "true", "yes" ; value = true
96
+ when "false", "no" ; value = false
97
+ when "null", "nil" ; value = nil
98
+ when /\A\d+\z/ ; value = value.to_i
99
+ when /\A\d+\.\d+\z/ ; value = value.to_f
100
+ when /\A'.*'\z/ ; value = eval(value)
101
+ when /\A".*"\z/ ; value = eval(value)
102
+ end
103
+ properties[key.gsub(/-/, '_').intern] = value
104
+ else # options
105
+ optstr = optstr.slice(1..-1)
106
+ while optstr && !optstr.empty?
107
+ optchar = optstr[0]
108
+ optstr = optstr.slice(1..-1)
109
+ if single_opts && single_opts.include?(optchar)
110
+ options[optchar] = true
111
+ elsif arged_opts && arged_opts.include?(optchar)
112
+ arg = optstr.empty? ? argv.shift : optstr
113
+ optstr = nil
114
+ raise "-#{optchar.chr}: argument required." unless arg
115
+ options[optchar] = arg
116
+ elsif optional_opts && optional_opts.include?(optchar)
117
+ arg = optstr.empty? ? true : optstr
118
+ optstr = nil
119
+ options[optchar] = arg
120
+ else
121
+ raise "-#{optchar.chr}: unknown option."
122
+ end
123
+ end #while
124
+ end #if
125
+ end #while
126
+ filenames = argv
127
+ return options, properties, filenames
128
+ end
129
+
130
+
131
+ end
132
+
133
+ end
@@ -0,0 +1,47 @@
1
+ ###
2
+ ### $Rev: 36 $
3
+ ### $Release: 0.3.0 $
4
+ ### copyright(c) 2005 kuwata-lab.com all rights reserved.
5
+ ###
6
+
7
+ require 'test/unit/testcase'
8
+ require 'tempfile'
9
+
10
+
11
+ class Test::Unit::TestCase # :nodoc:
12
+
13
+
14
+ def assert_text_equal(expected, actual, message=nil, options={}) # :nodoc:
15
+ diffopt = options[:diffopt] || '-u'
16
+ flag_cut = options.key?(:cut) ? options[:key] : true
17
+ prefix = options[:prefix] || ''
18
+ #prefix = prefix + "\n" if !prefix.empty? && prefix[-1] != ?\n
19
+
20
+ if expected == actual
21
+ assert(true)
22
+ return
23
+ end
24
+ if expected[-1] != ?\n || actual[-1] != ?\n
25
+ expected += "\n"
26
+ actual += "\n"
27
+ end
28
+ begin
29
+ expfile = Tempfile.new(".expected.")
30
+ expfile.write(expected); expfile.flush()
31
+ actfile = Tempfile.new(".actual.")
32
+ actfile.write(actual); actfile.flush()
33
+ diff = `diff #{diffopt} #{expfile.path} #{actfile.path}`
34
+ ensure
35
+ expfile.close(true) if expfile
36
+ actfile.close(true) if actfile
37
+ end
38
+ diff.sub!(/\A.*\n.*\n/, '') if flag_cut # cut 1st & 2nd lines
39
+ msg = prefix + (message || diff)
40
+ assert_block(msg) { false } # or assert(false, msg)
41
+ end
42
+
43
+ alias assert_equal_with_diff assert_text_equal # for compatibility
44
+ alias assert_text_equals assert_text_equal # for typo
45
+
46
+
47
+ end
@@ -0,0 +1,115 @@
1
+ ###
2
+ ### $Rev: 33 $
3
+ ### $Release: 0.3.0 $
4
+ ### copyright(c) 2005 kuwata-lab.com all rights reserved.
5
+ ###
6
+
7
+ ##
8
+ ## utility module for assertion
9
+ ##
10
+ ## ex.
11
+ ## require 'assertion'
12
+ ## include Assertion # or extend Assertion
13
+ ## assert s && !s.empty?
14
+ ## assert! unless s && !s.empty?
15
+ ##
16
+ module Assertion
17
+
18
+
19
+ ##
20
+ ## assertion error class
21
+ ##
22
+ class AssertionError < StandardError
23
+
24
+ def initialize(message='')
25
+ super
26
+ end
27
+
28
+ alias _to_s to_s
29
+
30
+ def to_s
31
+ #s = super
32
+ s = _to_s()
33
+ return "*** assertion error: #{s}"
34
+ end
35
+
36
+ end
37
+
38
+
39
+ ##
40
+ ## assertion error class
41
+ ##
42
+ class UnreachableError < AssertionError
43
+
44
+ def to_s
45
+ s = _to_s()
46
+ return "*** unreachable error: #{s}"
47
+ end
48
+
49
+ end
50
+
51
+
52
+ module_function
53
+
54
+
55
+ ##
56
+ ## raise AssertionError if condition is false
57
+ ##
58
+ ## ex.
59
+ ## assert s && !s.empty?, "s=#{s.inspect}"
60
+ ##
61
+ def assert(condition, message='')
62
+ _raise_error(AssertionError, message, caller()) unless condition
63
+ end
64
+
65
+
66
+ ##
67
+ ## raise AssertionError
68
+ ##
69
+ ## ex.
70
+ ## assert! "s=#{s.inspect}" unless s && !s.empty?
71
+ ##
72
+ def assert! (message='')
73
+ _raise_error(AssertionError, message, caller())
74
+ end
75
+
76
+
77
+ ##
78
+ ## raise UnreachableError
79
+ ##
80
+ ## ex.
81
+ ## case value
82
+ ## when true
83
+ ## ...
84
+ ## when false
85
+ ## ...
86
+ ## else
87
+ ## unreachable
88
+ ## end
89
+ ##
90
+ def unreachable(message='')
91
+ _raise_error(UnreachableError, message, caller())
92
+ end
93
+
94
+
95
+ private
96
+
97
+
98
+ def _raise_error(error_class, message, caller_obj)
99
+ error = error_class.new(message)
100
+ error.set_backtrace(caller_obj)
101
+ raise error
102
+ end
103
+
104
+
105
+ end
106
+
107
+
108
+ if $0 == __FILE__
109
+ include Assertion
110
+ case ARGV.shift
111
+ when 'assert' ; assert false, ARGV.join(' ')
112
+ when 'unreachable' ; unreachable ARGV.join(' ')
113
+ else ; assert! ARGV.join(' ')
114
+ end
115
+ end