activefacts-metamodel 1.9.8 → 1.9.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b7afe6a26853ed01f535f4d7f5790f79ec9be7f5
4
- data.tar.gz: 746e2147513f5095bd03e1d16eaa3639ec7b7983
3
+ metadata.gz: 3e03674ba747b46f6f9ad28824b36f56f6a45fc5
4
+ data.tar.gz: 0f8eeb054a8cc86237ab65ef2a67ec1b0280dc11
5
5
  SHA512:
6
- metadata.gz: f4d217b455a600eb0899906962bad4f8fff3c0da763526bfd6251df02873fb6582ccdac618d43dc7fb882d8326c9a92dc1f8d29fa70f95ce5d867e6515f01690
7
- data.tar.gz: 71068e4a2c568f2f82c671412d37e11bf6eb9c0c35c58c26ec97508e64dc1065869197aae468ffd866f1273ec343bad98045af63f988ca9a4944cc31f4d43511
6
+ metadata.gz: 7958a809a59505eeb640cd02f612dc1d1a1ebb299b7eaff248a028fbc19eb5ce401caf1dd86d4c2e1b8e334e30a0452e9b9de88561d72c66f1b494742d41ea34
7
+ data.tar.gz: b3c17494c56c49883b19a19f20f00aa060cbb8eacee2d24a4590c724a7a7b677621bec3edb55e7f621f49850598e5c18090a21599842c6b9271ad0174739f9fb
data/.gitignore CHANGED
@@ -13,3 +13,4 @@ bin
13
13
  *.rej
14
14
  *.orig
15
15
  *.diff
16
+ Metamodel.old.cql
data/Rakefile CHANGED
@@ -29,8 +29,8 @@ task :cql do
29
29
  # This means that SOME PATCHES WILL FAIL
30
30
  system "afgen --cql orm/Metamodel.orm > Metamodel.cql"
31
31
  system "patch < orm/Metamodel.cql.diffs"
32
- system "afgen --cql cql/Metamodel.cql 2>/dev/null >Metamodel.cql.cql"
33
- system "diff -b -C 1 Metamodel.cql Metamodel.cql.cql | tee Metamodel.cql.diffs"
32
+ system "afgen --cql cql/Metamodel.cql 2>/dev/null >Metamodel.old.cql"
33
+ system "diff -b -C 1 Metamodel.old.cql Metamodel.cql | tee Metamodel.cql.diffs"
34
34
  end
35
35
 
36
36
  desc "Generate new Ruby from the CQL file"
@@ -11,7 +11,7 @@ Assimilation is written as String restricted to {'absorbed', 'partitioned', 'sep
11
11
  Context Note Kind is written as String restricted to {'as_opposed_to', 'because', 'so_that', 'to_avoid'};
12
12
  Date is written as Date;
13
13
  Denominator is written as Unsigned Integer(32);
14
- Discussion is written as String;
14
+ Description is written as String;
15
15
  Display Role Names Setting is written as String restricted to {'false', 'true'};
16
16
  Enforcement Code is written as String(16);
17
17
  Ephemera URL is written as String;
@@ -57,6 +57,7 @@ Coefficient is identified by Numerator and Denominator and Coefficient is precis
57
57
  Concept is identified by Guid where
58
58
  Concept has one Guid,
59
59
  Guid is of at most one Concept;
60
+ Concept has at most one informal-Description;
60
61
 
61
62
  Concept Annotation is where
62
63
  Concept has mapping-Annotation,
@@ -71,8 +72,8 @@ Context Note is identified by Concept where
71
72
  Context Note is an instance of one Concept;
72
73
  Context Note has one Context Note Kind,
73
74
  Context Note Kind is of Context Note;
74
- Context Note has one Discussion,
75
- Discussion is for Context Note;
75
+ Context Note has one Description,
76
+ Description is for Context Note;
76
77
  Context Note applies to at most one relevant-Concept,
77
78
  Concept has Context Note;
78
79
 
@@ -158,12 +159,6 @@ Instance plays Role Value,
158
159
 
159
160
  Set Constraint is a kind of Constraint;
160
161
 
161
- Shape is identified by Guid where
162
- Shape has one Guid,
163
- Guid is of at most one Shape;
164
- Shape is at at most one Location;
165
- Shape is expanded;
166
-
167
162
  Step is identified by Guid where
168
163
  Step has one Guid,
169
164
  Guid is of at most one Step;
@@ -246,9 +241,6 @@ Bound is identified by Value and Bound is inclusive where
246
241
  Value is of at least one Bound,
247
242
  Bound is inclusive;
248
243
 
249
- Constraint Shape is a kind of Shape;
250
- Constraint Shape is for one Constraint;
251
-
252
244
  Context According To is where
253
245
  Context Note is according to Agent,
254
246
  Agent claims Context Note;
@@ -262,29 +254,10 @@ Derivation is where
262
254
  Unit (as Derived Unit) is derived from base-Unit (as Base Unit) [acyclic, intransitive];
263
255
  Derivation has at most one Exponent;
264
256
 
265
- Diagram is identified by Vocabulary and Name where
266
- Diagram is for one Vocabulary,
267
- Vocabulary contains Diagram,
268
- Diagram is called one Name,
269
- Name is of Diagram;
270
-
271
- Fact Type Shape is a kind of Shape;
272
- Fact Type Shape has at most one Display Role Names Setting;
273
- Fact Type Shape is for one Fact Type,
274
- Fact Type has Fact Type Shape;
275
- Fact Type Shape has at most one Rotation Setting;
276
-
277
257
  Mirror Role is a kind of Role;
278
258
  Mirror Role is for at most one Role (as Base Role),
279
259
  Base Role implies at most one Mirror Role;
280
260
 
281
- Model Note Shape is a kind of Shape;
282
- Model Note Shape is for one Context Note;
283
-
284
- ORM Diagram is a kind of Diagram;
285
- Shape is in one ORM Diagram,
286
- ORM Diagram includes Shape;
287
-
288
261
  Object Type is identified by Vocabulary and Name where
289
262
  Object Type belongs to one Vocabulary,
290
263
  Object Type is called one Name;
@@ -293,19 +266,9 @@ Object Type is an instance of one Concept;
293
266
  Object Type uses at most one Pronoun;
294
267
  Object Type plays Role,
295
268
  Role is played by one Object Type;
296
- Object Type is independent;
297
269
  Variable is for one Object Type,
298
270
  Object Type is referenced in Variable;
299
271
 
300
- Object Type Shape is a kind of Shape;
301
- Object Type Shape is for one Object Type,
302
- Object Type has Object Type Shape;
303
- Object Type Shape has expanded reference mode;
304
-
305
- Objectified Fact Type Name Shape is a kind of Shape;
306
- Objectified Fact Type Name Shape is for one Fact Type Shape,
307
- Fact Type Shape has at most one Objectified Fact Type Name Shape;
308
-
309
272
  Play is where
310
273
  Variable is restricted by Role of Step,
311
274
  Step contains Role restricting one Variable;
@@ -324,23 +287,6 @@ Population includes Instance,
324
287
  Population includes Role Value,
325
288
  Role Value belongs to one Population;
326
289
 
327
- Reading Shape is a kind of Shape;
328
- Fact Type Shape has at most one Reading Shape,
329
- Reading Shape is for one Fact Type Shape;
330
- Reading Shape is for one Reading,
331
- Reading has Reading Shape;
332
-
333
- Ring Constraint Shape is a kind of Constraint Shape;
334
- Ring Constraint Shape is attached to one Fact Type Shape;
335
-
336
- Role Display is where
337
- Fact Type Shape displays Role in Ordinal position,
338
- Fact Type Shape displays in Ordinal position one Role;
339
-
340
- Role Name Shape is a kind of Shape;
341
- Role Name Shape is for one Role Display,
342
- Role Display has at most one Role Name Shape;
343
-
344
290
  Role Ref is where
345
291
  Role Sequence in Ordinal position includes one Role,
346
292
  Role is in Role Sequence in one Ordinal place,
@@ -364,12 +310,6 @@ Set Equality Constraint is a kind of Set Comparison Constraint;
364
310
  Set Exclusion Constraint is a kind of Set Comparison Constraint;
365
311
  Set Exclusion Constraint is mandatory;
366
312
 
367
- Value Constraint Shape is a kind of Constraint Shape;
368
- Role Display has at most one Value Constraint Shape,
369
- Value Constraint Shape is for at most one Role Display;
370
- Value Constraint Shape is for at most one Object Type Shape,
371
- Object Type Shape has Value Constraint Shape;
372
-
373
313
  Value Range is identified by minimum-Bound and maximum-Bound where
374
314
  Value Range has at most one minimum-Bound,
375
315
  Value Range has at most one maximum-Bound;
@@ -378,6 +318,7 @@ Allowed Range is where
378
318
  Value Constraint allows Value Range;
379
319
 
380
320
  Domain Object Type is a kind of Object Type;
321
+ Domain Object Type is independent;
381
322
 
382
323
  Entity Type is a kind of Domain Object Type;
383
324
  Entity Type objectifies at most one Fact Type,
@@ -429,9 +370,12 @@ Component (as Member) belongs to at most one Component (as Parent) [acyclic, str
429
370
  Parent contains Member;
430
371
  Component projects at most one Name;
431
372
  Component has at most one Ordinal rank;
373
+ Component has absolute name;
432
374
 
433
375
  Indicator is a kind of Component;
434
376
  Indicator indicates one Role played;
377
+ Indicator uses at most one false-Value;
378
+ Indicator uses at most one true-Value;
435
379
 
436
380
  Discriminator is a kind of Component;
437
381
  Discriminated Role is where
@@ -440,6 +384,7 @@ Discriminated Role is where
440
384
 
441
385
  Mapping is a kind of Component;
442
386
  Mapping represents one Object Type;
387
+ Mapping uses at most one native- type Name;
443
388
 
444
389
  Composite is identified by Mapping where
445
390
  Mapping projects at most one Composite,
@@ -514,8 +459,8 @@ Composite has at most one primary-Index,
514
459
  Index is primary for at most one Composite;
515
460
  Index is primary for Composite
516
461
  only if Index is unique;
517
- identified Composite has primary Access Path
518
- only if Composite is reached through Access Path;
462
+ Composite has primary Index
463
+ only if Composite is reached through Access Path that is an Index;
519
464
 
520
465
  Index Field is where
521
466
  Access Path for Ordinal field uses one Component,
@@ -550,6 +495,88 @@ Absorption is nested under index Role in Ordinal position
550
495
  if and only if
551
496
  that Absorption uses some Nesting Mode;
552
497
 
498
+ /*
499
+ * Diagrams
500
+ */
501
+ Diagram is identified by Vocabulary and Name where
502
+ Diagram is for one Vocabulary,
503
+ Vocabulary contains Diagram,
504
+ Diagram is called one Name,
505
+ Name is of Diagram;
506
+ ORM Diagram is a kind of Diagram;
507
+
508
+ Shape is identified by Guid where
509
+ Shape has one Guid,
510
+ Guid is of at most one Shape;
511
+ Shape is in one ORM Diagram,
512
+ ORM Diagram includes Shape;
513
+ Shape is at at most one Location;
514
+
515
+ each combination ORM Diagram, Location occurs at most one time in
516
+ Shape is in ORM Diagram,
517
+ Shape is at Location;
518
+
519
+ Fact Type Shape is a kind of Shape;
520
+ Fact Type Shape has at most one Display Role Names Setting;
521
+ Fact Type Shape is for one Fact Type,
522
+ Fact Type has Fact Type Shape;
523
+ Fact Type Shape has at most one Rotation Setting;
524
+
525
+ Object Type Shape is a kind of Shape;
526
+ Object Type Shape is for one Object Type,
527
+ Object Type has Object Type Shape;
528
+ Object Type Shape is expanded;
529
+
530
+ Objectified Fact Type Name Shape is a kind of Shape;
531
+ Objectified Fact Type Name Shape is for one Fact Type Shape,
532
+ Fact Type Shape has at most one Objectified Fact Type Name Shape;
533
+
534
+ Constraint Shape is a kind of Shape;
535
+ Constraint Shape is for one Constraint;
536
+
537
+ Model Note Shape is a kind of Shape;
538
+ Model Note Shape is for one Context Note;
539
+
540
+ Reading Shape is a kind of Shape;
541
+ Fact Type Shape has at most one Reading Shape,
542
+ Reading Shape is for one Fact Type Shape;
543
+ Reading Shape is for one Reading,
544
+ Reading has Reading Shape;
545
+
546
+ Ring Constraint Shape is a kind of Constraint Shape;
547
+ Ring Constraint Shape is attached to one Fact Type Shape;
548
+
549
+ Role Display is where
550
+ Fact Type Shape displays Role in Ordinal position,
551
+ Fact Type Shape displays in Ordinal position one Role;
552
+
553
+ Role Name Shape is a kind of Shape;
554
+ Role Name Shape is for one Role Display,
555
+ Role Display has at most one Role Name Shape;
556
+
557
+ Value Constraint Shape is a kind of Constraint Shape;
558
+ Role Display has at most one Value Constraint Shape,
559
+ Value Constraint Shape is for at most one Role Display;
560
+ Value Constraint Shape is for at most one Object Type Shape,
561
+ Object Type Shape has Value Constraint Shape;
562
+
563
+ Component Shape is a kind of Shape;
564
+ Component Shape is for at most one Component;
565
+ parent- Component Shape contains Component Shape,
566
+ Component Shape is contained in at most one parent- Component Shape;
567
+
568
+ either Constraint Shape is a Ring Constraint Shape or Constraint Shape is a Value Constraint Shape but not both;
569
+ for each Shape exactly one of these holds:
570
+ Shape is an Object Type Shape,
571
+ Shape is a Fact Type Shape,
572
+ Shape is a Constraint Shape,
573
+ Shape is an Objectified Fact Type Name Shape,
574
+ Shape is a Reading Shape,
575
+ Shape is a Role Name Shape,
576
+ Shape is a Model Note Shape,
577
+ Shape is a Component Shape;
578
+ either Value Constraint Shape is for Object Type Shape or Value Constraint Shape is for Role Display but not both;
579
+
553
580
  /*
554
581
  * Constraints:
555
582
  */
@@ -569,7 +596,6 @@ for each Concept exactly one of these holds:
569
596
  Fact is an instance of Concept,
570
597
  Population is an instance of Concept,
571
598
  Query is an instance of Concept;
572
- either Constraint Shape is a Ring Constraint Shape or Constraint Shape is a Value Constraint Shape but not both;
573
599
  for each Constraint exactly one of these holds:
574
600
  Constraint is a Set Constraint,
575
601
  Constraint is a Presence Constraint,
@@ -589,17 +615,8 @@ for each Role Sequence exactly one of these holds:
589
615
  Role Sequence is Ordinal in Set Comparison Constraint;
590
616
  either Set Comparison Constraint is a Set Exclusion Constraint or Set Comparison Constraint is a Set Equality Constraint but not both;
591
617
  either Set Constraint is a Set Comparison Constraint or Set Constraint is a Subset Constraint but not both;
592
- for each Shape exactly one of these holds:
593
- Shape is an Object Type Shape,
594
- Shape is a Fact Type Shape,
595
- Shape is a Constraint Shape,
596
- Shape is an Objectified Fact Type Name Shape,
597
- Shape is a Reading Shape,
598
- Shape is a Role Name Shape,
599
- Shape is a Model Note Shape;
600
618
  either Unit uses coefficient from Ephemera URL or Unit has Coefficient but not both;
601
619
  either Unit is fundamental or Unit is derived from base-Unit but not both;
602
- either Value Constraint Shape is for Object Type Shape or Value Constraint Shape is for Role Display but not both;
603
620
  either Value Constraint allows Value Range or Value Constraint requires matching Regular Expression but not both;
604
621
  either Value Constraint constrains Value Type or Value Constraint applies to Role but not both;
605
622
  for each Mapping at most one of these holds:
@@ -647,9 +664,6 @@ each combination Discriminator, Value occurs one time in
647
664
  each combination Entity Type(1), Type Inheritance occurs at most one time in
648
665
  Entity Type(1) is subtype of super Entity Type(2),
649
666
  Type Inheritance provides identification;
650
- each combination ORM Diagram, Location occurs at most one time in
651
- Shape is in ORM Diagram,
652
- Shape is at Location;
653
667
  each Presence Constraint occurs at least one time in
654
668
  Presence Constraint has min Frequency(2),
655
669
  Presence Constraint has max Frequency(1),
@@ -0,0 +1,273 @@
1
+ #
2
+ # ActiveFacts Vocabulary Metamodel.
3
+ # Data type support for the Metamodel
4
+ #
5
+ # Copyright (c) 2016 Clifford Heath. Read the LICENSE file.
6
+ #
7
+
8
+ module ActiveFacts
9
+ module Metamodel
10
+ class DataType
11
+ TypeNames = %w{
12
+ Boolean
13
+ Integer Real Decimal Money
14
+ Char String Text
15
+ Date Time DateTime Timestamp
16
+ Binary
17
+ }.freeze
18
+
19
+ TypeNames.each_with_index do |name, i|
20
+ DataType.const_set("TYPE_"+name, i)
21
+ end
22
+
23
+ # Alternate names are case-insensitive, and underscore can be literal, or correspond to a space or to nothing
24
+ AlternateNames = {
25
+ TYPE_Boolean =>
26
+ %w{ bit },
27
+ TYPE_Integer =>
28
+ %w{ auto_counter int tiny_int small_int big_int unsigned unsigned_int unsigned_integer signed_int signed_integer},
29
+ TYPE_Real =>
30
+ %w{ float double },
31
+ TYPE_Decimal =>
32
+ %w{ },
33
+ TYPE_Money =>
34
+ %w{ currency },
35
+ TYPE_Char =>
36
+ %w{ character nchar national_character fixed_length_text },
37
+ TYPE_String =>
38
+ %w{ varchar nvarchar national_character_varying variable_length_text },
39
+ TYPE_Text =>
40
+ %w{ large_length_text },
41
+ TYPE_Date =>
42
+ %w{ },
43
+ TYPE_Time =>
44
+ %w{ },
45
+ TYPE_DateTime =>
46
+ %w{ date_time },
47
+ TYPE_Timestamp =>
48
+ %w{ time_stamp auto_time_stamp },
49
+ TYPE_Binary =>
50
+ %w{ guid picture_raw_data variable_length_raw_data },
51
+ }
52
+ TypeParameters = {
53
+ TYPE_Integer => [:length], # Length is the number of bits
54
+ TYPE_Real => [:length], # Length is the number of bits in the mantissa
55
+ TYPE_Decimal => [:precision, :scale], # Precision is the number of significant digits
56
+ TYPE_Money => [:precision, :scale], # Precision is the number of significant digits. Scale is the digits of fractional cents.
57
+ TYPE_Char => [:length, :charset], # Charset is e.g. ascii, latin1, iso8859-1, unicode
58
+ TYPE_String => [:length, :charset],
59
+ TYPE_Text => [:charset],
60
+ TYPE_Binary => [:length, :charset],
61
+ }
62
+
63
+ # A DataType Context class should refine this class.
64
+ # The default context might work for you.
65
+ class Context
66
+ def integer_ranges
67
+ end
68
+
69
+ def default_length data_type, type_name
70
+ end
71
+
72
+ def choose_integer_type min, max
73
+ integer_ranges.detect{|type_name, vmin, vmax, bits| min >= vmin && max <= vmax}
74
+ end
75
+
76
+ def boolean_type
77
+ end
78
+
79
+ def surrogate_type
80
+ end
81
+
82
+ def valid_from_type
83
+ end
84
+ end
85
+
86
+ class DefaultContext < Context
87
+ def integer_ranges
88
+ # A set suitable for Standard SQL:
89
+ [
90
+ ['SMALLINT', -2**15, 2**15-1, 16], # The SQL standard says -10^5..10^5 (less than 16 bits)
91
+ ['INTEGER', -2**31, 2**31-1, 32], # The standard says -10^10..10^10 (more than 32 bits!)
92
+ ['BIGINT', -2**63, 2**63-1, 64], # The standard says -10^19..10^19 (less than 64 bits)
93
+ ]
94
+ end
95
+
96
+ def default_length data_type, type_name
97
+ case data_type
98
+ when TYPE_Real
99
+ 53 # IEEE Double precision floating point
100
+ when TYPE_Integer
101
+ case type_name
102
+ when /([a-z ]|\b)Tiny([a-z ]|\b)/i
103
+ 8
104
+ when /([a-z ]|\b)Small([a-z ]|\b)/i,
105
+ /([a-z ]|\b)Short([a-z ]|\b)/i
106
+ 16
107
+ when /([a-z ]|\b)Big([a-z ]|\b)/i
108
+ 64
109
+ else
110
+ 32
111
+ end
112
+ else
113
+ nil
114
+ end
115
+ end
116
+
117
+ def boolean_type
118
+ 'CHAR'
119
+ end
120
+
121
+ def surrogate_type
122
+ 'BIGINT'
123
+ end
124
+
125
+ def valid_from_type
126
+ 'TIMESTAMP'
127
+ end
128
+ end
129
+
130
+ def self.normalise type_name
131
+ data_type, = type_mapping.detect{|t, names| names.detect{|n| n === type_name}}
132
+ data_type
133
+ end
134
+
135
+ def self.normalise_int_length type_name, length = nil, value_constraint = nil, context = DefaultContext.new
136
+ int_length = length || context.default_length(TYPE_Integer, type_name)
137
+ if int_length
138
+ if value_constraint
139
+ # Pick out the largest maximum and smallest minimum from the ValueConstraint:
140
+ ranges = value_constraint.all_allowed_range_sorted.flat_map{|ar| ar.value_range}
141
+ min = ranges.map(&:minimum_bound).compact.map{|minb| minb.is_inclusive ? minb.value : minb.value-1}.map{|v| v.literal.to_i}.sort[0]
142
+ max = ranges.map(&:maximum_bound).compact.map{|maxb| maxb.is_inclusive ? maxb.value : maxb.value+1}.map{|v| v.literal.to_i}.sort[-1]
143
+ end
144
+
145
+ unsigned = type_name =~ /^unsigned/i
146
+ int_min = unsigned ? 0 : -2**(int_length-1)+1
147
+ min = int_min if !min || length && int_min < min
148
+ # SQL does not have unsigned types.
149
+ # Don't force the next largest type just because the app calls for unsigned:
150
+ int_max = unsigned ? 2**(int_length-1) - 1 : 2**(int_length-1)-1
151
+ max = int_max if !max || length && int_max < max
152
+ end
153
+ best = context.choose_integer_type(min, max)
154
+ unless best || length
155
+ # Use the largest available integer size
156
+ best = context.integer_ranges.last
157
+ end
158
+
159
+ # Use a context-defined integer size if one suits, otherwise the requested size:
160
+ best && [best[0], best[3]] || [ 'int', length ]
161
+ end
162
+
163
+ private
164
+ def self.type_mapping
165
+ if DataType.const_defined?("TypeMapping")
166
+ return TypeMapping
167
+ end
168
+ DataType.const_set("TypeMapping",
169
+ AlternateNames.inject({}) do |h, (t, a)|
170
+ h[t] = [TypeNames[t]]
171
+ a.each do |n|
172
+ h[t] << /^#{n.gsub(/_/, '[ _]?')}$/i
173
+ end
174
+ h
175
+ end
176
+ )
177
+ TypeMapping
178
+ end
179
+
180
+ end
181
+
182
+ class Component
183
+ def in_primary_index
184
+ root.primary_index.all_index_field.detect{|ixf| ixf.component == self}
185
+ end
186
+
187
+ def in_foreign_key
188
+ all_foreign_key_field.detect{|fkf| fkf.foreign_key.source_composite == root}
189
+ end
190
+
191
+ def data_type context = DataType::DefaultContext.new
192
+ case self
193
+ when Indicator
194
+ context.boolean_type
195
+
196
+ when SurrogateKey
197
+ [ context.surrogate_type,
198
+ if in_primary_index and !in_foreign_key
199
+ {auto_assign: true}
200
+ else
201
+ {}
202
+ end.
203
+ merge!({mandatory: path_mandatory})
204
+ ]
205
+
206
+ when ValidFrom
207
+ context.valid_from_type
208
+
209
+ when ValueField, Absorption
210
+ vt = self.object_type
211
+ while vt.is_a?(EntityType)
212
+ rr = vt.preferred_identifier.role_sequence.all_role_ref.single
213
+ raise "Can't produce a column for composite #{inspect}" unless rr
214
+ value_constraint = narrow_value_constraint(value_constraint, rr.role.role_value_constraint)
215
+ vt = rr.role.object_type
216
+ end
217
+ raise "A column can only be produced from a ValueType not a #{vt.class.basename}" unless vt.is_a?(ValueType)
218
+
219
+ if is_a?(Absorption)
220
+ value_constraint = narrow_value_constraint(value_constraint, child_role.role_value_constraint)
221
+ end
222
+
223
+ stype = vt
224
+ begin
225
+ vt = stype
226
+ # REVISIT: Check for length and scale shortening
227
+ length ||= vt.length
228
+ scale ||= vt.scale
229
+ unless parent.parent and parent.foreign_key
230
+ # No need to enforce value constraints that are already enforced by a foreign key
231
+ value_constraint = narrow_value_constraint(value_constraint, vt.value_constraint)
232
+ end
233
+ end while stype = vt.supertype
234
+
235
+ [ vt.name,
236
+ (length ? {length: length} : {}).
237
+ merge!(scale ? {scale: scale} : {}).
238
+ merge!({ auto_assign: (in_primary_index and !in_foreign_key and vt.is_auto_assigned) }).
239
+ merge!({mandatory: path_mandatory}).
240
+ merge!(value_constraint ? {value_constraint: value_constraint} : {})
241
+ ]
242
+
243
+ when Injection
244
+ object_type.name
245
+ else
246
+ raise "Can't make a column from #{component}"
247
+ end
248
+ end
249
+
250
+ def narrow_value_constraint(value_constraint, nested_value_constraint)
251
+ # REVISIT: Need to calculate the constrant narrowing
252
+ return nested_value_constraint || value_constraint
253
+ end
254
+ end
255
+ end
256
+ end
257
+
258
+ if $0 == __FILE__
259
+ D = ActiveFacts::Metamodel::DataType
260
+ D.normalise('Auto Timestamp')
261
+
262
+ class ModContext < D::DefaultContext
263
+ def integer_ranges
264
+ [
265
+ ['BIT', 0, 1, 1],
266
+ ['TINYINT', -2**7, 2**7-1, 8],
267
+ ] +
268
+ super
269
+ end
270
+ end
271
+ puts "Normalising a tiny"
272
+ p D.normalise_int_length('tiny', nil, nil, ModContext.new)
273
+ end