activefacts-compositions 1.9.22 → 1.9.23
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +1 -1
- data/activefacts-compositions.gemspec +1 -1
- data/bin/schema_compositor +71 -27
- data/lib/activefacts/compositions/binary.rb +4 -0
- data/lib/activefacts/compositions/datavault.rb +4 -0
- data/lib/activefacts/compositions/relational.rb +4 -0
- data/lib/activefacts/compositions/staging.rb +4 -0
- data/lib/activefacts/compositions/version.rb +1 -1
- data/lib/activefacts/generator/doc/css/glossary-print.css +72 -0
- data/lib/activefacts/generator/doc/css/glossary.css +194 -0
- data/lib/activefacts/generator/doc/css/ldm.css +12 -17
- data/lib/activefacts/generator/doc/css/orm2-print.css +19 -0
- data/lib/activefacts/generator/doc/css/orm2.css +28 -0
- data/lib/activefacts/generator/doc/css/reset.css +18 -0
- data/lib/activefacts/generator/doc/css/treetable.css +83 -0
- data/lib/activefacts/generator/doc/cwm.rb +60 -54
- data/lib/activefacts/generator/doc/glossary.rb +261 -137
- data/lib/activefacts/generator/doc/graphviz.rb +6 -2
- data/lib/activefacts/generator/doc/ldm.rb +7 -3
- data/lib/activefacts/generator/etl/unidex.rb +7 -2
- data/lib/activefacts/generator/oo.rb +2 -1
- data/lib/activefacts/generator/population.rb +174 -0
- data/lib/activefacts/generator/rails/active_admin.rb +81 -0
- data/lib/activefacts/generator/rails/application_record_shell.rb +78 -0
- data/lib/activefacts/generator/rails/models.rb +31 -72
- data/lib/activefacts/generator/rails/ruby_folder_generator.rb +87 -0
- data/lib/activefacts/generator/rails/schema.rb +12 -4
- data/lib/activefacts/generator/ruby.rb +7 -3
- data/lib/activefacts/generator/sql.rb +2 -1
- data/lib/activefacts/generator/summary.rb +24 -19
- data/lib/activefacts/generator/traits/sql.rb +4 -0
- data/lib/activefacts/generator/transgen.rb +7 -1
- data/lib/activefacts/generator/validate.rb +10 -2
- metadata +15 -5
@@ -1,33 +1,28 @@
|
|
1
|
-
a:link, a:visited {
|
2
|
-
color: #8A0092; text-decoration: underline;
|
3
|
-
}
|
4
|
-
|
5
|
-
span {
|
6
|
-
font-family: "Frutiger", sans-serif;
|
7
|
-
}
|
8
|
-
|
9
1
|
.keyword {
|
10
2
|
color: #0000CC;
|
11
3
|
}
|
12
4
|
|
13
|
-
.term, .concept {
|
5
|
+
.schema, .term, .concept {
|
14
6
|
/* Xcolor: #6A0072; The color used by NORMA */
|
15
7
|
color: #8A0092;
|
16
8
|
}
|
17
9
|
|
18
|
-
.
|
19
|
-
/* Xcolor: #6A0072; The color used by NORMA */
|
20
|
-
color: #8A0092;
|
21
|
-
}
|
22
|
-
|
23
|
-
.linking, .reading {
|
10
|
+
.reading {
|
24
11
|
color: #0E5400;
|
25
12
|
}
|
26
13
|
|
27
|
-
.
|
14
|
+
.value {
|
28
15
|
color: #FF990E;
|
29
16
|
}
|
30
17
|
|
18
|
+
a:link, a:visited {
|
19
|
+
color: #8A0092; text-decoration: underline;
|
20
|
+
}
|
21
|
+
|
22
|
+
span {
|
23
|
+
font-family: "Helvetica Neue", Helvetica,"Arial Unicode MS", Arial, sans-serif;
|
24
|
+
}
|
25
|
+
|
31
26
|
.glossary-objectification .glossary-reading {
|
32
27
|
margin-left: 30px;
|
33
28
|
}
|
@@ -42,4 +37,4 @@ span {
|
|
42
37
|
|
43
38
|
.row-bordered {
|
44
39
|
border: 1px solid #ddd;
|
45
|
-
}
|
40
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
span {
|
2
|
+
font-family: "Helvetica Neue", Helvetica,"Arial Unicode MS", Arial, sans-serif;
|
3
|
+
}
|
4
|
+
|
5
|
+
.keyword {
|
6
|
+
color: #0000CC;
|
7
|
+
display: inline;
|
8
|
+
}
|
9
|
+
|
10
|
+
.schema,
|
11
|
+
.term {
|
12
|
+
/* Xcolor: #6A0072; The color used by NORMA */
|
13
|
+
color: #8A0092;
|
14
|
+
}
|
15
|
+
|
16
|
+
.schema:link, .schema:visited,
|
17
|
+
.term:link, .term:visited {
|
18
|
+
color: #8A0092; text-decoration: underline;
|
19
|
+
}
|
20
|
+
|
21
|
+
.reading {
|
22
|
+
color: #0E5400;
|
23
|
+
}
|
24
|
+
|
25
|
+
.value {
|
26
|
+
color: #FF990E;
|
27
|
+
display: inline;
|
28
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
* {
|
2
|
+
margin: 0px;
|
3
|
+
padding: 0px;
|
4
|
+
}
|
5
|
+
|
6
|
+
ul, menu, dir {
|
7
|
+
display: block;
|
8
|
+
list-style-type: disc;
|
9
|
+
-webkit-margin-before: 0px;
|
10
|
+
-webkit-margin-after: 0px;
|
11
|
+
-webkit-margin-start: 0px;
|
12
|
+
-webkit-margin-end: 0px;
|
13
|
+
-webkit-padding-start: 0px;
|
14
|
+
}
|
15
|
+
li {
|
16
|
+
list-style: none;
|
17
|
+
}
|
18
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
/* Composition in the Treetable */
|
2
|
+
.mandatory {
|
3
|
+
font-weight: bold;
|
4
|
+
}
|
5
|
+
|
6
|
+
/* Treetable */
|
7
|
+
|
8
|
+
div.tt-outer { /* The wrapper for a Tree-Table structure */
|
9
|
+
line-height: 1.7em; /* Separate the lines by more than the height */
|
10
|
+
margin: 10px;
|
11
|
+
}
|
12
|
+
|
13
|
+
.tt-node { /* A node in a Tree-Table structure */
|
14
|
+
line-height: 1.5em;
|
15
|
+
background-color: #FFF; /* Make the message stand out from the background */
|
16
|
+
border: 3px ridge; /* A nice border around each node */
|
17
|
+
padding-left: 0.5em; /* Start text a bit further inside the border */
|
18
|
+
margin-left: 5px; /* Indent each node this much further */
|
19
|
+
margin-right: -3px; /* Overlay the right border of the outer object */
|
20
|
+
margin-bottom: -3px; /* Overlay the bottom border of the outer object */
|
21
|
+
}
|
22
|
+
|
23
|
+
.tt-list { /* A node for an array or list of items */
|
24
|
+
background: #DDF; /* Make it stand out by colour */
|
25
|
+
border: 4px ridge; /* Use a slightly fatter border */
|
26
|
+
margin-left: 1px; /* Stand a little further to the left than our peers */
|
27
|
+
margin-top: -3px; /* Stand a little to upwards */
|
28
|
+
margin-right: -3px; /* Bring the right margin to the left as well */
|
29
|
+
margin-bottom: 1px; /* Leave room below for the shadow to show */
|
30
|
+
box-shadow: 4px 4px 2px #888; /* Leave a shadow to the right and below */
|
31
|
+
}
|
32
|
+
|
33
|
+
.tt-list:before{
|
34
|
+
content:'(N) ';
|
35
|
+
font-size: 8pt;
|
36
|
+
vertical-align: top;
|
37
|
+
}
|
38
|
+
|
39
|
+
.tt-alt {
|
40
|
+
border-radius: 10px 10px 0px 10px; /* Use rounded corners */
|
41
|
+
margin-top: 10px; /* Leave a space above alternative items */
|
42
|
+
}
|
43
|
+
div:first-of-type.tt-alt {
|
44
|
+
margin-top: 0px !important; /* Don't leave a space above the first list item */
|
45
|
+
}
|
46
|
+
div:first-of-type.tt-alt:before {
|
47
|
+
content:'either';
|
48
|
+
font-size: 6pt;
|
49
|
+
}
|
50
|
+
|
51
|
+
.tt-alt:before{
|
52
|
+
content:'or';
|
53
|
+
font-size: 6pt;
|
54
|
+
}
|
55
|
+
|
56
|
+
.tt-desc { /* Display the data item description */
|
57
|
+
position: absolute; /* Glue it to the right of the outer block */
|
58
|
+
display: inline-block;
|
59
|
+
border-left: 3px ridge; /* Draw a vertical separator to the left */
|
60
|
+
background: #FFF; /* Ensure a long tt-type doesn't show through */
|
61
|
+
right: 11px; /* Fill the space to the far right, minus borders */
|
62
|
+
left: 36em; /* Start where the data type ends */
|
63
|
+
padding: 0px 5px 4px 5px; /* Leave room at the start and end */
|
64
|
+
line-height: 1.5em; /* Separate the lines by more than the height */
|
65
|
+
height: 1.3em; /* Clip the height to one line */
|
66
|
+
overflow: hidden; /* Don't attempt to show the whole text if it doesn't fit */
|
67
|
+
}
|
68
|
+
|
69
|
+
.tt-list > .tt-desc {
|
70
|
+
background: #DDF; /* Make it stand out by colour */
|
71
|
+
padding-bottom: 6px; /* -list has a bigger border, so the -desc needs to be taller */
|
72
|
+
}
|
73
|
+
.tt-type { /* Display the data type */
|
74
|
+
position: absolute; /* Glue it just left of the description */
|
75
|
+
display: inline-block;
|
76
|
+
border-left: 3px ridge; /* Draw a vertical separator to the left */
|
77
|
+
left: 24em; /* Start this far across */
|
78
|
+
width: 12em; /* Provide space for the type name */
|
79
|
+
padding: 0px 5px 0px 5px; /* Leave room at the start and end */
|
80
|
+
line-height: 1.5em; /* Separate the lines by more than the height */
|
81
|
+
height: 1.4em; /* Clip the height to one line */
|
82
|
+
overflow: hidden; /* Don't attempt to show the whole text if it doesn't fit */
|
83
|
+
}
|
@@ -15,26 +15,7 @@ require 'activefacts/support'
|
|
15
15
|
module ActiveFacts
|
16
16
|
module Generators
|
17
17
|
module Doc
|
18
|
-
|
19
|
-
# Add namespace id to metamodel forward referencing
|
20
|
-
class ActiveFacts::Metamodel::Composite # for tables
|
21
|
-
attr_accessor :xmiid
|
22
|
-
end
|
23
|
-
|
24
|
-
class ActiveFacts::Metamodel::Component # for columns
|
25
|
-
attr_accessor :xmiid
|
26
|
-
attr_accessor :index_xmiid
|
27
|
-
end
|
28
|
-
|
29
|
-
class ActiveFacts::Metamodel::Index # for primary and unique indexes
|
30
|
-
attr_accessor :xmiid
|
31
|
-
end
|
32
|
-
|
33
|
-
class ActiveFacts::Metamodel::ForeignKey # for foreign keys
|
34
|
-
attr_accessor :xmiid
|
35
|
-
end
|
36
|
-
|
37
|
-
class CWM
|
18
|
+
class CWM
|
38
19
|
MM = ActiveFacts::Metamodel unless const_defined?(:MM)
|
39
20
|
def self.options
|
40
21
|
{
|
@@ -42,7 +23,12 @@ module ActiveFacts
|
|
42
23
|
}
|
43
24
|
end
|
44
25
|
|
45
|
-
def
|
26
|
+
def self.compatibility
|
27
|
+
[1, %i{relational}] # one relational composition
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize constellation, composition, options = {}
|
31
|
+
@constellation = constellation
|
46
32
|
@composition = composition
|
47
33
|
@options = options
|
48
34
|
@underscore = options.has_key?("underscore") ? (options['underscore'] || '_') : ''
|
@@ -119,15 +105,15 @@ module ActiveFacts
|
|
119
105
|
def populate_namespace_ids
|
120
106
|
model_ns = rawnsdef
|
121
107
|
schema_ns = rawnsdef
|
122
|
-
|
108
|
+
|
123
109
|
@composition.
|
124
110
|
all_composite.
|
125
111
|
sort_by{|composite| composite.mapping.name}.
|
126
112
|
map{|composite| populate_table_ids(composite)}
|
127
|
-
|
113
|
+
|
128
114
|
[model_ns, schema_ns]
|
129
115
|
end
|
130
|
-
|
116
|
+
|
131
117
|
def populate_table_ids(table)
|
132
118
|
tname = table_name(table)
|
133
119
|
nsdef(table)
|
@@ -136,7 +122,7 @@ module ActiveFacts
|
|
136
122
|
next if leaf.is_a?(MM::Absorption) && leaf.parent_role.fact_type.is_a?(MM::TypeInheritance)
|
137
123
|
nsdef(leaf)
|
138
124
|
end
|
139
|
-
table.all_index.sort_by do |idx|
|
125
|
+
table.all_index.sort_by do |idx|
|
140
126
|
idx.all_index_field.map { |ixf| ixf.component.xmiid }
|
141
127
|
end.map do |index|
|
142
128
|
nsdef(index)
|
@@ -146,7 +132,7 @@ module ActiveFacts
|
|
146
132
|
nsdef(fk)
|
147
133
|
end
|
148
134
|
end
|
149
|
-
|
135
|
+
|
150
136
|
def generate_header
|
151
137
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
152
138
|
"<!DOCTYPE XMI SYSTEM \"CWM-1.1.dtd\">\n" +
|
@@ -167,11 +153,11 @@ module ActiveFacts
|
|
167
153
|
generate_data_types(2) +
|
168
154
|
" </XMI.content>\n"
|
169
155
|
end
|
170
|
-
|
156
|
+
|
171
157
|
def generate_footer
|
172
158
|
"</XMI>\n"
|
173
159
|
end
|
174
|
-
|
160
|
+
|
175
161
|
def generate_catalog(depth, model_ns, schema_ns)
|
176
162
|
catalog_start =
|
177
163
|
indent(depth, "<CWMRDB:Catalog xmi.id=\"#{model_ns}\" name=\"Model\" visibility=\"public\">") +
|
@@ -179,34 +165,34 @@ module ActiveFacts
|
|
179
165
|
indent(depth, " <CWMRDB:Schema xmi.id=\"#{schema_ns}\" name=\"Schema\" visibility=\"public\" namespace=\"#{model_ns}\">") +
|
180
166
|
indent(depth, " <CWM:Namespace.ownedElement>")
|
181
167
|
|
182
|
-
catalog_body =
|
168
|
+
catalog_body =
|
183
169
|
@composition.
|
184
170
|
all_composite.
|
185
171
|
sort_by{|composite| composite.mapping.name}.
|
186
172
|
map{|composite| generate_table(depth+4, schema_ns, composite)}*"\n" + "\n"
|
187
|
-
|
173
|
+
|
188
174
|
catalog_end =
|
189
175
|
indent(depth, " </CWM:Namespace.ownedElement>") +
|
190
176
|
indent(depth, " </CWMRDB:Schema>") +
|
191
177
|
indent(depth, " </CWM:Namespace.ownedElement>") +
|
192
178
|
indent(depth, "</CWMRDB:Catalog>")
|
193
|
-
|
179
|
+
|
194
180
|
catalog_start + catalog_body + catalog_end
|
195
181
|
end
|
196
|
-
|
182
|
+
|
197
183
|
def generate_data_types(depth)
|
198
184
|
@datatypes.map do | dt |
|
199
185
|
indent(depth, dt)
|
200
186
|
end * ""
|
201
187
|
end
|
202
|
-
|
188
|
+
|
203
189
|
def generate_table(depth, schema_ns, table)
|
204
190
|
name = table_name(table)
|
205
191
|
delayed_indices = []
|
206
|
-
|
192
|
+
|
207
193
|
table_start =
|
208
194
|
indent(depth, "<CWMRDB:Table xmi.id=\"#{table.xmiid}\" name=\"#{name}\" isSystem=\"false\" isTemporary=\"false\" visibility=\"public\" namespace=\"#{schema_ns}\">")
|
209
|
-
|
195
|
+
|
210
196
|
table_columns =
|
211
197
|
indent(depth, " <CWM:Classifier.feature>") +
|
212
198
|
(table.mapping.all_leaf.flat_map.sort_by{|c| column_name(c)}.map do |leaf|
|
@@ -220,7 +206,7 @@ module ActiveFacts
|
|
220
206
|
|
221
207
|
table_keys =
|
222
208
|
indent(depth, " <CWM:Namespace.ownedElement>") +
|
223
|
-
(table.all_index.sort_by do |idx|
|
209
|
+
(table.all_index.sort_by do |idx|
|
224
210
|
idx.all_index_field.map { |ixf| ixf.component.xmiid }
|
225
211
|
end.map do |index|
|
226
212
|
generate_index(depth+2, table.xmiid, index, name, table.all_foreign_key_as_target_composite)
|
@@ -231,23 +217,23 @@ module ActiveFacts
|
|
231
217
|
end
|
232
218
|
) * "" +
|
233
219
|
indent(depth, " </CWM:Namespace.ownedElement>")
|
234
|
-
|
220
|
+
|
235
221
|
table_end =
|
236
222
|
indent(depth, "</CWMRDB:Table>")
|
237
|
-
|
223
|
+
|
238
224
|
table_start + table_columns + table_keys + table_end
|
239
225
|
end
|
240
226
|
|
241
227
|
def generate_column(depth, table_ns, column)
|
242
228
|
name = safe_column_name(column)
|
243
|
-
|
229
|
+
|
244
230
|
is_nullable = column.path_mandatory ? "columnNoNulls" : "columnNullable"
|
245
231
|
constraints = column.all_leaf_constraint
|
246
232
|
|
247
233
|
type_name, options = column.data_type(data_type_context)
|
248
234
|
options ||= {}
|
249
235
|
length = options[:length]
|
250
|
-
|
236
|
+
|
251
237
|
type_name, type_num = normalise_type_cwm(type_name, length)
|
252
238
|
column_params = ""
|
253
239
|
type_params = ""
|
@@ -259,14 +245,14 @@ module ActiveFacts
|
|
259
245
|
|
260
246
|
def create_data_type(type_name, type_num, type_params)
|
261
247
|
type_ns = rawnsdef
|
262
|
-
|
263
|
-
cwm_data_type =
|
248
|
+
|
249
|
+
cwm_data_type =
|
264
250
|
"<CWMRDB:SQLSimpleType xmi.id=\"#{type_ns}\" name=\"#{type_name}\" visibility=\"public\" typeNumber=\"#{type_num}\" #{type_params}/>"
|
265
|
-
|
251
|
+
|
266
252
|
@datatypes << cwm_data_type
|
267
253
|
type_ns
|
268
254
|
end
|
269
|
-
|
255
|
+
|
270
256
|
def generate_index(depth, table_ns, index, table_name, all_fks_as_target)
|
271
257
|
key_ns = index.xmiid
|
272
258
|
|
@@ -285,7 +271,7 @@ module ActiveFacts
|
|
285
271
|
# (index.composite_as_primary_index ? ' CLUSTERED' : ' NONCLUSTERED')
|
286
272
|
|
287
273
|
key_type = primary ? 'CWMRDB:PrimaryKey' : 'CWM:UniqueKey'
|
288
|
-
|
274
|
+
|
289
275
|
# find target foreign keys for this index
|
290
276
|
fks_as_target = all_fks_as_target
|
291
277
|
|
@@ -307,7 +293,7 @@ module ActiveFacts
|
|
307
293
|
if fks_as_target.count > 0
|
308
294
|
indent(depth, "<CWM:UniqueKey.keyRelationship>") +
|
309
295
|
fks_as_target.map do |fk|
|
310
|
-
indent(depth, " <CWM:KeyRelationship xmi.idref=\"#{fk.xmiid}\"/>")
|
296
|
+
indent(depth, " <CWM:KeyRelationship xmi.idref=\"#{fk.xmiid}\"/>")
|
311
297
|
end * "" +
|
312
298
|
indent(depth, "</CWM:UniqueKey.keyRelationship>")
|
313
299
|
else
|
@@ -316,10 +302,10 @@ module ActiveFacts
|
|
316
302
|
indent(depth, "</#{key_type}>")
|
317
303
|
end
|
318
304
|
end
|
319
|
-
|
305
|
+
|
320
306
|
def generate_foreign_key(depth, table_ns, fk)
|
321
307
|
key_ns = fk.xmiid
|
322
|
-
|
308
|
+
|
323
309
|
if fk.all_foreign_key_field.size == 1
|
324
310
|
fkf = fk.all_foreign_key_field[0]
|
325
311
|
ixf = fk.all_index_field[0]
|
@@ -335,16 +321,16 @@ module ActiveFacts
|
|
335
321
|
out += indent(depth, " <CWM:StructuralFeature xmi.idref=\"#{fkf.component.xmiid}\" uniqueKey=\"#{ixf.component.index_xmiid}\" />")
|
336
322
|
end
|
337
323
|
out
|
338
|
-
end +
|
324
|
+
end +
|
339
325
|
indent(depth, " </CWM:KeyRelationship.feature>") +
|
340
326
|
indent(depth, "</CWMRDB:ForeignKey>")
|
341
327
|
end
|
342
328
|
# fk.all_foreign_key_field.map{|fkf| safe_column_name fkf.component}*", " +
|
343
329
|
# ") REFERENCES #{safe_table_name fk.composite} (" +
|
344
330
|
# fk.all_index_field.map{|ixf| safe_column_name ixf.component}*", " +
|
345
|
-
|
331
|
+
|
346
332
|
# indent(depth, "<CWMRDB:ForeignKey xmi.id=\"#{key_ns}\" name=\"R#{key_ns}\" visibility=\"public\" namespace=\"#{ns}\" feature=\"_41\" uniqueKey=\"_48\" deleteRule=\"importedKeyRestrict\" updateRule=\"importedKeyRestrict\"/>")
|
347
|
-
|
333
|
+
|
348
334
|
end
|
349
335
|
|
350
336
|
def boolean_type
|
@@ -426,8 +412,8 @@ module ActiveFacts
|
|
426
412
|
['int', 4]
|
427
413
|
end
|
428
414
|
end
|
429
|
-
|
430
|
-
|
415
|
+
|
416
|
+
|
431
417
|
def sql_value(value)
|
432
418
|
value.is_literal_string ? sql_string(value.literal) : value.literal
|
433
419
|
end
|
@@ -516,9 +502,29 @@ module ActiveFacts
|
|
516
502
|
default_varchar_type
|
517
503
|
end
|
518
504
|
end
|
519
|
-
|
505
|
+
|
520
506
|
end
|
521
507
|
end
|
522
508
|
publish_generator Doc::CWM, "Common Warehouse Metamodel represented as an XMI file. Use a relational compositor"
|
523
509
|
end
|
510
|
+
|
511
|
+
module Metamodel
|
512
|
+
# Add namespace id to metamodel forward referencing
|
513
|
+
class Composite # for tables
|
514
|
+
attr_accessor :xmiid
|
515
|
+
end
|
516
|
+
|
517
|
+
class Component # for columns
|
518
|
+
attr_accessor :xmiid
|
519
|
+
attr_accessor :index_xmiid
|
520
|
+
end
|
521
|
+
|
522
|
+
class Index # for primary and unique indexes
|
523
|
+
attr_accessor :xmiid
|
524
|
+
end
|
525
|
+
|
526
|
+
class ForeignKey # for foreign keys
|
527
|
+
attr_accessor :xmiid
|
528
|
+
end
|
529
|
+
end
|
524
530
|
end
|