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.
- data/ChangeLog +46 -0
- data/MIT-LICENSE +20 -0
- data/README.txt +4 -2
- data/bin/kwatable +4 -4
- data/examples/ex1/Makefile +40 -14
- data/examples/ex1/{example1.yaml → tabledef.yaml} +42 -11
- data/examples/ex2/Makefile +41 -14
- data/examples/ex2/{example2.yaml → tabledef.yaml} +45 -30
- data/examples/ex3/Makefile +52 -0
- data/examples/ex3/tabledef.yaml +136 -0
- data/kwatable.gemspec +11 -10
- data/lib/kwatable.rb +24 -18
- data/lib/kwatable/kwatable.schema.yaml +95 -5
- data/lib/kwatable/main.rb +331 -0
- data/lib/kwatable/manipulator.rb +320 -192
- data/lib/kwatable/messages.rb +59 -0
- data/lib/kwatable/template/ddl-mysql.eruby +202 -0
- data/lib/kwatable/{templates → template}/ddl-postgresql.eruby +71 -45
- data/lib/kwatable/{templates → template}/defaults.yaml +2 -2
- data/lib/kwatable/template/dictionary.en.yaml +70 -0
- data/lib/kwatable/template/dictionary.ja.yaml +165 -0
- data/lib/kwatable/template/dto-java.eruby +77 -0
- data/lib/kwatable/template/dto-java.sub.eruby +259 -0
- data/lib/kwatable/template/dto-ruby.eruby +63 -0
- data/lib/kwatable/template/dto-ruby.sub.eruby +213 -0
- data/lib/kwatable/template/helper/column.rb +70 -0
- data/lib/kwatable/template/helper/common.rb +151 -0
- data/lib/kwatable/template/helper/java.rb +83 -0
- data/lib/kwatable/template/helper/label.rb +90 -0
- data/lib/kwatable/template/helper/ruby.rb +36 -0
- data/lib/kwatable/template/helper/table.rb +62 -0
- data/lib/kwatable/template/hibernate.eruby +139 -0
- data/lib/kwatable/template/rails-controller.eruby +66 -0
- data/lib/kwatable/template/rails-controller.sub.eruby +114 -0
- data/lib/kwatable/template/rails-kwartz.eruby +164 -0
- data/lib/kwatable/template/rails-kwartz/_attr.plogic.eruby +56 -0
- data/lib/kwatable/template/rails-kwartz/_form.plogic.eruby +81 -0
- data/lib/kwatable/template/rails-kwartz/_link.plogic.eruby +36 -0
- data/lib/kwatable/template/rails-kwartz/edit.cfg.yaml.eruby +16 -0
- data/lib/kwatable/template/rails-kwartz/edit.html.eruby +46 -0
- data/lib/kwatable/template/rails-kwartz/edit.plogic.eruby +20 -0
- data/lib/kwatable/template/rails-kwartz/layout.html.eruby +39 -0
- data/lib/kwatable/template/rails-kwartz/layout.plogic.eruby +32 -0
- data/lib/kwatable/template/rails-kwartz/list.html.eruby +94 -0
- data/lib/kwatable/template/rails-kwartz/list.plogic.eruby +41 -0
- data/lib/kwatable/template/rails-kwartz/new.html.eruby +100 -0
- data/lib/kwatable/template/rails-kwartz/new.plogic.eruby +26 -0
- data/lib/kwatable/template/rails-kwartz/show.html.eruby +51 -0
- data/lib/kwatable/template/rails-kwartz/show.plogic.eruby +9 -0
- data/lib/kwatable/template/rails-model.eruby +35 -0
- data/lib/kwatable/template/rails-model.sub.eruby +136 -0
- data/lib/kwatable/{templates → template}/validator-ruby.eruby +18 -11
- data/lib/kwatable/util.rb +133 -0
- data/lib/kwatable/util/assert-text-equal.rb +47 -0
- data/lib/kwatable/util/assertion.rb +115 -0
- data/lib/kwatable/validator.rb +50 -0
- data/test/assert-diff.rb +1 -1
- data/test/test-ex.rb +306 -0
- data/test/test.rb +37 -127
- metadata +66 -17
- data/COPYING +0 -340
- data/ChangeLog.txt +0 -65
- data/lib/kwatable/error-msg.rb +0 -38
- data/lib/kwatable/main-program.rb +0 -216
- data/lib/kwatable/templates/ddl-mysql.eruby +0 -172
- data/lib/kwatable/templates/dto-java.eruby +0 -260
- data/lib/kwatable/templates/dto-ruby.eruby +0 -185
@@ -0,0 +1,59 @@
|
|
1
|
+
###
|
2
|
+
### copyright(c) 2005 kuwata-lab.com all rights reserved.
|
3
|
+
### $Release: 0.3.0 $
|
4
|
+
### $Rev: 43 $
|
5
|
+
###
|
6
|
+
|
7
|
+
module Kwatable
|
8
|
+
|
9
|
+
@@messages = {}
|
10
|
+
|
11
|
+
def self.msg(key)
|
12
|
+
return @@messages[key]
|
13
|
+
end
|
14
|
+
|
15
|
+
#----- begin auto generate
|
16
|
+
@@messages[:dir_notfound] = "-d %s: directory not found."
|
17
|
+
@@messages[:dir_notadir] = "-d %s: not a directory."
|
18
|
+
@@messages[:tabledef_validation_error] = "schema validation error.\n%s"
|
19
|
+
@@messages[:template_notspecified] = "template is not specified."
|
20
|
+
@@messages[:file_create] = "create: %s"
|
21
|
+
@@messages[:file_update] = "update: %s"
|
22
|
+
@@messages[:file_delete] = "delete: %s"
|
23
|
+
@@messages[:file_identical] = "identical: %s"
|
24
|
+
@@messages[:datafile_notfound] = "%s: datafile notfound."
|
25
|
+
@@messages[:datafile_notafile] = "%s: not a file."
|
26
|
+
@@messages[:tabledef_empty] = "table definition file is empty."
|
27
|
+
@@messages[:tabledef_notmap] = "table definition is not a mapping."
|
28
|
+
@@messages[:template_notfound] = "`%s': template file not found."
|
29
|
+
@@messages[:option_unknown] = "-%s: unknown option."
|
30
|
+
@@messages[:template_required] = "-%s: template filename required."
|
31
|
+
@@messages[:outdir_required] = "-%s: output directory required."
|
32
|
+
@@messages[:directory_required] = "-%s: directory required."
|
33
|
+
@@messages[:colname_required] = "column name required (index=%d)."
|
34
|
+
@@messages[:regexp_invalid] = "column '%s': pattern %s: %s"
|
35
|
+
@@messages[:coldef_duplicated] = "column '%s': column name is duplicated."
|
36
|
+
@@messages[:tablename_required] = "table definition doesn't have a name (index=%d)."
|
37
|
+
@@messages[:tabledef_duplicated] = "table '%s': table name is duplicated."
|
38
|
+
@@messages[:tablecolumns_required] = "table '%s': columns requried."
|
39
|
+
@@messages[:table_identcol_missing] = "table '%s': ident-column '%s': no such column."
|
40
|
+
@@messages[:tabletype_required] = "table '%s': column '%s': type is not determined.."
|
41
|
+
@@messages[:tablecolumn_required] = "table '%s': column name requried (index=%d)."
|
42
|
+
@@messages[:tablecolumn_duplicated] = "table '%s': column '%s': column name is duplicated."
|
43
|
+
@@messages[:alias_tablekey_conflict] = "table '%s': alias key '%1:' and '%2:' are not allowed to use in the same time."
|
44
|
+
@@messages[:alias_columnkey_conflict] = "table '%s', column '%s': alias key '%1:' and '%2:' are not allowed to use in the same time."
|
45
|
+
@@messages[:reftable_notfound] = "`table '%s': column '%s': 'ref: %s': reference table not found."
|
46
|
+
@@messages[:refcolumn_notfound] = "`table '%s': column '%s': ref: %s': reference column not found in the table."
|
47
|
+
@@messages[:relation_kind_required] = "table `%s': relation kind required."
|
48
|
+
@@messages[:relation_referrer_required] = "table `%s': relation referrer required."
|
49
|
+
@@messages[:referrer_invalid] = "table `%s': referrer `%s': invalid pattern."
|
50
|
+
@@messages[:referrer_table_notfound] = "table `%s': referrer `%s': table not found."
|
51
|
+
@@messages[:referrer_column_notfound] = "table `%s': referrer `%s': column not found."
|
52
|
+
@@messages[:referrer_jointable_required] = "table `%s': referrer `%s': `join-table:' is required when n:n relationship."
|
53
|
+
@@messages[:referrer_jointable_notfound] = "table `%s': referrer `%s': join-table '%s' not found."
|
54
|
+
@@messages[:referrer_identcolumn_notfound] = "table `%s': referrer `%s': table `%s' does not have ident column (it is required for have n:n relationship)."
|
55
|
+
@@messages[:referrer_joincolumn_notfound] = "table `%s': referrer `%s': join-table '%s' does not have column to link to %s table."
|
56
|
+
@@messages[:referrer_joincolumn2_notfound] = "table `%s': referrer `%s': join-table '%s' does not have column to link to table '%s'."
|
57
|
+
#----- end auto generate
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
<%
|
2
|
+
|
3
|
+
##
|
4
|
+
## kwatable template file for MySQL
|
5
|
+
##
|
6
|
+
## $Rev: 39 $
|
7
|
+
## $Release: 0.3.0 $
|
8
|
+
## copyright(c) 2005 kuwata-lab.com all rights reserved.
|
9
|
+
##
|
10
|
+
## <template-desc>generate SQL (create table statements) for PostgreSQL</template-desc>
|
11
|
+
## <template-properties>
|
12
|
+
## --droptable : add drop table statement
|
13
|
+
## </template-properties>
|
14
|
+
##
|
15
|
+
|
16
|
+
require 'kwatable/template/helper/common'
|
17
|
+
extend Kwatable::CommonHelper
|
18
|
+
|
19
|
+
|
20
|
+
#
|
21
|
+
# context check
|
22
|
+
#
|
23
|
+
context_var_required('@tables')
|
24
|
+
#raise "don't use '-m' option with '#{File.basename(@template_filename)}'." unless @tables
|
25
|
+
|
26
|
+
|
27
|
+
#
|
28
|
+
# MySQL keywords
|
29
|
+
#
|
30
|
+
def keywords()
|
31
|
+
keywords = <<-END
|
32
|
+
add all alter analyze and as asc asensitive
|
33
|
+
before between bigint binary blob both by
|
34
|
+
call cascade case change char character check collate column
|
35
|
+
condition connection constraint continue convert create cross
|
36
|
+
current_date current_time current_timestamp current_user cursor
|
37
|
+
database databases day_hour day_microsecond day_minute day_second
|
38
|
+
dec decimal declare default delayed delete desc describe
|
39
|
+
deterministic distinct distinctrow div double drop dual
|
40
|
+
each else elseif enclosed escaped exists exit explain
|
41
|
+
false fetch float for force foreign from fulltext
|
42
|
+
goto grant group
|
43
|
+
having high_priority hour_microsecond hour_minute hour_second
|
44
|
+
if ignore in index infile inner inout insensitive insert
|
45
|
+
int integer interval into is iterate
|
46
|
+
join
|
47
|
+
key keys kill
|
48
|
+
leading leave left like limit lines load localtime
|
49
|
+
localtimestamp lock long longblob longtext loop low_priority
|
50
|
+
match mediumblob mediumint mediumtext middleint
|
51
|
+
minute_microsecond minute_second mod modifies
|
52
|
+
natural not no_write_to_binlog null numeric
|
53
|
+
on optimize option optionally or order out outer outfile
|
54
|
+
precision primary procedure purge
|
55
|
+
read reads real references regexp release rename repeat
|
56
|
+
replace require restrict return revoke right rlike
|
57
|
+
schema schemas second_microsecond select sensitive
|
58
|
+
separator set show smallint soname spatial specific sql
|
59
|
+
sqlexception sqlstate sqlwarning sql_big_result
|
60
|
+
sql_calc_found_rows sql_small_result ssl starting straight_join
|
61
|
+
table terminated then tinyblob tinyint tinytext to
|
62
|
+
trailing trigger true
|
63
|
+
undo union unique unlock unsigned update usage use using
|
64
|
+
utc_date utc_time utc_timestamp
|
65
|
+
values varbinary varchar varcharacter varying
|
66
|
+
when where while with write
|
67
|
+
xor
|
68
|
+
year_month
|
69
|
+
zerofill
|
70
|
+
END
|
71
|
+
return keywords.split(/\s+/)
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
#
|
76
|
+
# escape keyword
|
77
|
+
#
|
78
|
+
def _(word)
|
79
|
+
@_keywords ||= keywords().inject({}) { |hash, keyword| hash[keyword] = true; hash }
|
80
|
+
return @_keywords[word.downcase] ? "`#{word}`" : word
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
#
|
85
|
+
# start output
|
86
|
+
#
|
87
|
+
%>
|
88
|
+
----------------------------------------------------------------------
|
89
|
+
-- DDL for MySQL
|
90
|
+
-- generated by kwatable with template 'ddl-mysql.eruby'
|
91
|
+
-- at <%= Time.now.to_s %>
|
92
|
+
|
93
|
+
----------------------------------------------------------------------
|
94
|
+
<%
|
95
|
+
#
|
96
|
+
# create table statement
|
97
|
+
#
|
98
|
+
%>
|
99
|
+
<% for table in @tables %>
|
100
|
+
|
101
|
+
<%= (table['desc'] || '').gsub(/^/, '-- ') %>
|
102
|
+
|
103
|
+
<% if @properties[:droptable] %>
|
104
|
+
drop table if exists <%=_ table['name'] %>;
|
105
|
+
<% end %>
|
106
|
+
create table <%=_ table['name'] %> (
|
107
|
+
<%
|
108
|
+
n = table['columns'].length
|
109
|
+
i = 0
|
110
|
+
for column in table['columns']
|
111
|
+
i += 1
|
112
|
+
flag_last_loop = (i == n)
|
113
|
+
|
114
|
+
name = column['name']
|
115
|
+
type = column['type']
|
116
|
+
width = column['width']
|
117
|
+
|
118
|
+
#
|
119
|
+
# column type
|
120
|
+
#
|
121
|
+
case type
|
122
|
+
when 'char' ; type = 'tinyint'
|
123
|
+
when 'short' ; type = 'mediumint'
|
124
|
+
when 'int' ; type = 'integer'
|
125
|
+
when 'inteter' ;
|
126
|
+
when 'str' ; type = 'varchar' ; width ||= 255
|
127
|
+
when 'string' ; type = 'varchar' ; width ||= 255
|
128
|
+
when 'text' ;
|
129
|
+
when 'float' ;
|
130
|
+
when 'double' ;
|
131
|
+
when 'bool' ; type = 'boolean'
|
132
|
+
when 'boolean' ;
|
133
|
+
when 'date' ;
|
134
|
+
when 'time' ;
|
135
|
+
when 'datetime' ;
|
136
|
+
when 'timestamp' ;
|
137
|
+
when 'money' ; type = 'decimal'
|
138
|
+
else ;
|
139
|
+
end
|
140
|
+
type += "(#{width})" if width
|
141
|
+
|
142
|
+
#
|
143
|
+
# set type with 'enum(...)' if column has enum
|
144
|
+
#
|
145
|
+
if column['enum']
|
146
|
+
type = "enum(" + column['enum'].collect{|v| "'#{v}'"}.join(", ") + ")"
|
147
|
+
width = nil
|
148
|
+
end
|
149
|
+
|
150
|
+
#
|
151
|
+
# default value
|
152
|
+
#
|
153
|
+
default = nil
|
154
|
+
if column.key?('default')
|
155
|
+
case default = column['default']
|
156
|
+
when 'now', 'today', 'current_time', 'current_date', 'current_datetime', 'current_timestamp'
|
157
|
+
default = nil # MySQL doesn't support dynamic default value
|
158
|
+
when String
|
159
|
+
default = q(default)
|
160
|
+
when nil
|
161
|
+
default = 'null'
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# constraints
|
167
|
+
#
|
168
|
+
constraints = []
|
169
|
+
constraints << "default #{default}" if !default.nil?
|
170
|
+
constraints << 'auto_increment' if column['serial']
|
171
|
+
constraints << 'not null' if column['required'] && !column['serial'] && !column['ident']
|
172
|
+
constraints << 'primary key' if column['ident']
|
173
|
+
constraints << 'unique' if column['unique']
|
174
|
+
ref = column['ref']
|
175
|
+
constraints << "references #{ref['table']['name']}(#{ref['name']})" if ref
|
176
|
+
|
177
|
+
#
|
178
|
+
# column definition
|
179
|
+
#
|
180
|
+
name_part = '%-20s' % _(name)
|
181
|
+
type_part = '%-20s' % type
|
182
|
+
const_part = constraints.join(' ')
|
183
|
+
comma = flag_last_loop ? '' : ','
|
184
|
+
comment = column.key?('default') && default.nil? \
|
185
|
+
? " -- default #{column['default']}" \
|
186
|
+
: ""
|
187
|
+
%>
|
188
|
+
<%= name_part %> <%= type_part %> <%= const_part %><%= comma %><%= comment %>
|
189
|
+
|
190
|
+
<%
|
191
|
+
end
|
192
|
+
|
193
|
+
#
|
194
|
+
# composite primary key
|
195
|
+
#
|
196
|
+
%>
|
197
|
+
<% if table['ident-columns'].length >= 2 %>
|
198
|
+
<% str = table['ident-columns'].collect { |col| _(col['name']) }.join(', ') %>
|
199
|
+
, primary key (<%= str %>)
|
200
|
+
<% end %>
|
201
|
+
);
|
202
|
+
<% end %>
|
@@ -3,60 +3,66 @@
|
|
3
3
|
##
|
4
4
|
## kwatable template file for PostgreSQL
|
5
5
|
##
|
6
|
+
## $Rev: 39 $
|
7
|
+
## $Release: 0.3.0 $
|
6
8
|
## copyright(c) 2005 kuwata-lab.com all rights reserved.
|
7
|
-
## $Release: 0.2.0 $
|
8
|
-
## $Rev: 17 $
|
9
9
|
##
|
10
|
-
## template
|
11
|
-
##
|
10
|
+
## <template-desc>generate SQL (create table statements) for MySQL</template-desc>
|
11
|
+
## <template-properties>
|
12
|
+
## --droptable : add drop table statement
|
13
|
+
## </template-properties>
|
12
14
|
##
|
13
15
|
|
16
|
+
require 'kwatable/template/helper/common'
|
17
|
+
extend Kwatable::CommonHelper
|
18
|
+
|
14
19
|
|
15
20
|
#
|
16
|
-
# context
|
21
|
+
# context check
|
17
22
|
#
|
18
|
-
|
19
|
-
|
20
|
-
raise "don't use '-m' option with 'ddl-postgresql.eruby'." unless tables
|
23
|
+
context_var_required('@tables')
|
24
|
+
#raise "don't use '-m' option with '#{File.basename(@template_filename)}'." unless @tables
|
21
25
|
|
22
26
|
|
23
27
|
#
|
24
28
|
# PostgreSQL keywords
|
25
29
|
#
|
26
|
-
keywords
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
30
|
+
def keywords()
|
31
|
+
keywords = <<-END
|
32
|
+
abort admin all analyse analyze and any as asc
|
33
|
+
between binary bit both
|
34
|
+
case cast char character check cluster coalesce
|
35
|
+
collate column constraint copy cross current_date
|
36
|
+
current_time current_timestamp current_user
|
37
|
+
dec decimal default deferrable desc distinct do
|
38
|
+
else end except exists explain extend extract
|
39
|
+
false float for foreign from full
|
40
|
+
global group
|
41
|
+
having
|
42
|
+
ilike in initially inner inout intersect into is isnull
|
43
|
+
join
|
44
|
+
leading leftlike limit listen local lock
|
45
|
+
move
|
46
|
+
natural nchar new not notnull null nullif numeric
|
47
|
+
off offset old on only or order out outer overlaps
|
48
|
+
position precision primary public
|
49
|
+
references reset right
|
50
|
+
select session_user setof showsome substring
|
51
|
+
table then to trailing transaction trim true
|
52
|
+
union unique user using
|
53
|
+
vacuum varchar verbose
|
54
|
+
when where
|
55
|
+
END
|
56
|
+
return keywords.split(/\s+/)
|
57
|
+
end
|
53
58
|
|
54
59
|
|
55
60
|
#
|
56
61
|
# escape keyword
|
57
62
|
#
|
58
|
-
def
|
59
|
-
|
63
|
+
def _(word)
|
64
|
+
@_keywords ||= keywords().inject({}) { |hash, keyword| hash[keyword] = true; hash }
|
65
|
+
return @_keywords[word.downcase] ? "\"#{word}\"" : word
|
60
66
|
end
|
61
67
|
|
62
68
|
|
@@ -75,11 +81,14 @@
|
|
75
81
|
# create table statement
|
76
82
|
#
|
77
83
|
%>
|
78
|
-
<% for table in tables %>
|
84
|
+
<% for table in @tables %>
|
79
85
|
|
80
|
-
|
86
|
+
<%= (table['desc'] || '').gsub(/^/, '-- ') %>
|
81
87
|
|
82
|
-
|
88
|
+
<% if @properties[:droptable] %>
|
89
|
+
drop table <%=_ table['name'] %>;
|
90
|
+
<% end %>
|
91
|
+
create table <%=_ table['name'] %> (
|
83
92
|
<%
|
84
93
|
n = table['columns'].length
|
85
94
|
i = 0
|
@@ -107,8 +116,11 @@ create table <%= _(table['name']) %> (
|
|
107
116
|
when 'bool' ; type = 'boolean'
|
108
117
|
when 'boolean' ;
|
109
118
|
when 'date' ;
|
119
|
+
when 'time' ;
|
120
|
+
when 'datetime' ; type = 'timestamp'
|
110
121
|
when 'timestamp' ;
|
111
122
|
when 'money' ; type = 'decimal'
|
123
|
+
else ;
|
112
124
|
end
|
113
125
|
type += "(#{width})" if width
|
114
126
|
|
@@ -119,18 +131,32 @@ create table <%= _(table['name']) %> (
|
|
119
131
|
type = width && width >= 10 ? 'bigserial' : 'serial'
|
120
132
|
end
|
121
133
|
|
134
|
+
#
|
135
|
+
# default value
|
136
|
+
#
|
137
|
+
default = nil
|
138
|
+
if column.key?('default')
|
139
|
+
case default = column['default']
|
140
|
+
when 'now', 'today', 'current_time', 'current_date', 'current_datetime', 'current_timestamp'
|
141
|
+
# nothing
|
142
|
+
when String
|
143
|
+
default = q(default)
|
144
|
+
when nil
|
145
|
+
default = 'null'
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
122
149
|
#
|
123
150
|
# constraints
|
124
151
|
#
|
125
152
|
constraints = []
|
153
|
+
constraints << "default #{default}" if !default.nil?
|
126
154
|
constraints << 'not null' if column['required'] && !column['serial'] && !column['ident']
|
127
155
|
constraints << 'primary key' if column['ident']
|
128
156
|
constraints << 'unique' if column['unique']
|
129
|
-
#constraints << "references #{column['ref-table']['name']}(#{column['ref-column']['name']})" if column['ref-table']
|
130
157
|
ref = column['ref']
|
131
158
|
constraints << "references #{ref['table']['name']}(#{ref['name']})" if ref
|
132
159
|
|
133
|
-
|
134
160
|
#
|
135
161
|
# column definition
|
136
162
|
#
|
@@ -149,9 +175,9 @@ create table <%= _(table['name']) %> (
|
|
149
175
|
# composite primary key
|
150
176
|
#
|
151
177
|
%>
|
152
|
-
<% if table['
|
153
|
-
<%
|
154
|
-
, primary key (<%=
|
178
|
+
<% if table['ident-columns'].length >= 2 %>
|
179
|
+
<% str = table['ident-columns'].collect { |col| _(col['name']) }.join(', ') %>
|
180
|
+
, primary key (<%= str %>)
|
155
181
|
<% end %>
|
156
182
|
);
|
157
183
|
<% end %>
|