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 +4 -4
- data/.gitignore +1 -0
- data/Rakefile +2 -2
- data/cql/Metamodel.cql +93 -79
- data/lib/activefacts/metamodel/datatypes.rb +273 -0
- data/lib/activefacts/metamodel/extensions.rb +69 -2
- data/lib/activefacts/metamodel/metamodel.rb +32 -23
- data/lib/activefacts/metamodel/version.rb +1 -1
- data/lib/activefacts/support.rb +13 -1
- data/orm/Metamodel.cql.diffs +41 -24
- data/orm/Metamodel.orm +4120 -3621
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e03674ba747b46f6f9ad28824b36f56f6a45fc5
|
4
|
+
data.tar.gz: 0f8eeb054a8cc86237ab65ef2a67ec1b0280dc11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7958a809a59505eeb640cd02f612dc1d1a1ebb299b7eaff248a028fbc19eb5ce401caf1dd86d4c2e1b8e334e30a0452e9b9de88561d72c66f1b494742d41ea34
|
7
|
+
data.tar.gz: b3c17494c56c49883b19a19f20f00aa060cbb8eacee2d24a4590c724a7a7b677621bec3edb55e7f621f49850598e5c18090a21599842c6b9271ad0174739f9fb
|
data/.gitignore
CHANGED
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.
|
33
|
-
system "diff -b -C 1
|
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"
|
data/cql/Metamodel.cql
CHANGED
@@ -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
|
-
|
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
|
75
|
-
|
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
|
-
|
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
|