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