activefacts-compositions 1.9.22 → 1.9.23

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 (35) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +1 -1
  3. data/activefacts-compositions.gemspec +1 -1
  4. data/bin/schema_compositor +71 -27
  5. data/lib/activefacts/compositions/binary.rb +4 -0
  6. data/lib/activefacts/compositions/datavault.rb +4 -0
  7. data/lib/activefacts/compositions/relational.rb +4 -0
  8. data/lib/activefacts/compositions/staging.rb +4 -0
  9. data/lib/activefacts/compositions/version.rb +1 -1
  10. data/lib/activefacts/generator/doc/css/glossary-print.css +72 -0
  11. data/lib/activefacts/generator/doc/css/glossary.css +194 -0
  12. data/lib/activefacts/generator/doc/css/ldm.css +12 -17
  13. data/lib/activefacts/generator/doc/css/orm2-print.css +19 -0
  14. data/lib/activefacts/generator/doc/css/orm2.css +28 -0
  15. data/lib/activefacts/generator/doc/css/reset.css +18 -0
  16. data/lib/activefacts/generator/doc/css/treetable.css +83 -0
  17. data/lib/activefacts/generator/doc/cwm.rb +60 -54
  18. data/lib/activefacts/generator/doc/glossary.rb +261 -137
  19. data/lib/activefacts/generator/doc/graphviz.rb +6 -2
  20. data/lib/activefacts/generator/doc/ldm.rb +7 -3
  21. data/lib/activefacts/generator/etl/unidex.rb +7 -2
  22. data/lib/activefacts/generator/oo.rb +2 -1
  23. data/lib/activefacts/generator/population.rb +174 -0
  24. data/lib/activefacts/generator/rails/active_admin.rb +81 -0
  25. data/lib/activefacts/generator/rails/application_record_shell.rb +78 -0
  26. data/lib/activefacts/generator/rails/models.rb +31 -72
  27. data/lib/activefacts/generator/rails/ruby_folder_generator.rb +87 -0
  28. data/lib/activefacts/generator/rails/schema.rb +12 -4
  29. data/lib/activefacts/generator/ruby.rb +7 -3
  30. data/lib/activefacts/generator/sql.rb +2 -1
  31. data/lib/activefacts/generator/summary.rb +24 -19
  32. data/lib/activefacts/generator/traits/sql.rb +4 -0
  33. data/lib/activefacts/generator/transgen.rb +7 -1
  34. data/lib/activefacts/generator/validate.rb +10 -2
  35. 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
- .vocabulary, .object_type {
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
- .literal, .value {
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,19 @@
1
+ .keyword {
2
+ color: #0000CC;
3
+ font-style: italic;
4
+ display: inline;
5
+ }
6
+
7
+ .schema, .term {
8
+ color: #8A0092;
9
+ font-weight: bold;
10
+ }
11
+
12
+ .reading {
13
+ color: #0E5400;
14
+ }
15
+
16
+ .value {
17
+ color: #FF990E;
18
+ display: inline;
19
+ }
@@ -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 initialize composition, options = {}
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