activefacts-metamodel 1.9.5 → 1.9.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +7 -3
- data/Rakefile +2 -10
- data/activefacts-metamodel.gemspec +4 -2
- data/cql/Metamodel.cql +20 -5
- data/lib/activefacts/metamodel/extensions.rb +141 -9
- data/lib/activefacts/metamodel/metamodel.rb +428 -436
- data/lib/activefacts/metamodel/version.rb +1 -1
- data/lib/activefacts/support.rb +9 -13
- data/orm/Metamodel.csproj +13 -18
- data/orm/Metamodel.orm +4367 -3855
- metadata +26 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b1f0ae97a0a31369e5681e2310eb8deeb663390
|
4
|
+
data.tar.gz: d5cbf6dc32862b3982eb8c2f26aa28fb033d2afe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9031e41a724f5eb9c57aa7aa8f5ea2c8f22d0de1b6c9ea8808b6ebb062b31450cff6f08b8b19b744868fcee2b3f3db8d51cac187a0073292f2d044ee6bb78944
|
7
|
+
data.tar.gz: d9922fc63374fb60f7d553e0251c6d91b0a6dfd1d0c784f17a0c5a4ce03fab7b1e9fa2cf9eb51adb19ba509aa5b9e73524aee4c0bad12f8725e20eb5ff545398
|
data/Gemfile
CHANGED
@@ -2,7 +2,11 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
this_file = File.absolute_path(__FILE__)
|
6
|
+
if this_file =~ %r{\A#{ENV['HOME']}}i
|
7
|
+
dir = File.dirname(File.dirname(this_file))
|
8
|
+
$stderr.puts "Using work area gems in #{dir} from activefacts-metamodel"
|
9
|
+
gem 'activefacts-cql', path: dir+'/cql'
|
10
|
+
gem 'activefacts-compositions', path: dir+'/compositions'
|
11
|
+
gem 'activefacts-api', path: dir+'/api'
|
8
12
|
end
|
data/Rakefile
CHANGED
@@ -36,15 +36,7 @@ end
|
|
36
36
|
desc "Generate new Ruby from the CQL file"
|
37
37
|
task :ruby do
|
38
38
|
system %q{
|
39
|
-
|
40
|
-
|
41
|
-
module ActiveFacts
|
42
|
-
|
43
|
-
3s/:://
|
44
|
-
3,$s/^/ /
|
45
|
-
$a\
|
46
|
-
end
|
47
|
-
' > metamodel.rb
|
39
|
+
schema_compositor --binary --ruby=scope=ActiveFacts cql/Metamodel.cql > metamodel.rb &&
|
40
|
+
diff -ub lib/activefacts/metamodel/metamodel.rb metamodel.rb
|
48
41
|
}
|
49
|
-
system "diff -ub lib/activefacts/metamodel/metamodel.rb metamodel.rb"
|
50
42
|
end
|
@@ -24,6 +24,8 @@ This gem provides the core representations for the Fact Modeling tools of Active
|
|
24
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
25
|
spec.add_development_dependency "rspec", "~> 3.3"
|
26
26
|
|
27
|
-
spec.
|
28
|
-
spec.add_development_dependency "activefacts", "~> 1", "
|
27
|
+
spec.add_development_dependency "activefacts-compositions", ">= 1.9.6" # Needed for schema_compositor to emit Ruby from CQL
|
28
|
+
spec.add_development_dependency "activefacts", "~> 1", ">= 1.8" # Needed to emit CQL from ORM (and check it from CQL)
|
29
|
+
|
30
|
+
spec.add_runtime_dependency "activefacts-api", "~> 1", ">= 1.9.5"
|
29
31
|
end
|
data/cql/Metamodel.cql
CHANGED
@@ -446,11 +446,6 @@ Composite is identified by Mapping where
|
|
446
446
|
Composition contains Composite,
|
447
447
|
Composite belongs to one Composition;
|
448
448
|
|
449
|
-
Scoping is a kind of Mapping;
|
450
|
-
Injection is a kind of Mapping;
|
451
|
-
Value Field is a kind of Injection;
|
452
|
-
Surrogate Key is a kind of Injection;
|
453
|
-
|
454
449
|
Absorption is a kind of Mapping;
|
455
450
|
Absorption traverses to one child-Role;
|
456
451
|
Absorption traverses from one parent-Role;
|
@@ -473,6 +468,26 @@ some Object Type is involved in some Full Absorption that applies to some Absorp
|
|
473
468
|
that Mapping represents that Object Type;
|
474
469
|
*/
|
475
470
|
|
471
|
+
/*
|
472
|
+
* Composition constraint categories
|
473
|
+
*/
|
474
|
+
Leaf Constraint is where
|
475
|
+
Component has leaf-Constraint,
|
476
|
+
Constraint applies to Component;
|
477
|
+
|
478
|
+
Local Constraint is where
|
479
|
+
Composite contains local-Constraint,
|
480
|
+
local-Constraint connects leaves of Composite;
|
481
|
+
|
482
|
+
Spanning Constraint is where
|
483
|
+
Composite has spanning-Constraint,
|
484
|
+
Constraint spans Composite;
|
485
|
+
|
486
|
+
Scoping is a kind of Mapping;
|
487
|
+
Injection is a kind of Mapping;
|
488
|
+
Value Field is a kind of Injection;
|
489
|
+
Surrogate Key is a kind of Injection;
|
490
|
+
|
476
491
|
/* Access Paths */
|
477
492
|
Access Path is identified by Guid where
|
478
493
|
Access Path has one Guid,
|
@@ -334,7 +334,18 @@ module ActiveFacts
|
|
334
334
|
end
|
335
335
|
|
336
336
|
def unary_name
|
337
|
-
fact_type.
|
337
|
+
fact_type.
|
338
|
+
preferred_reading.
|
339
|
+
text.
|
340
|
+
gsub(/(.*)\{[0-9]\}(.*)/) do
|
341
|
+
if $1.empty? or $2.empty?
|
342
|
+
"#{$1} #{$2}"
|
343
|
+
else
|
344
|
+
"#{$1} #{object_type.name} #{$2}"
|
345
|
+
end
|
346
|
+
end.
|
347
|
+
words.
|
348
|
+
titlewords*' '
|
338
349
|
end
|
339
350
|
|
340
351
|
def is_link_role
|
@@ -359,11 +370,26 @@ module ActiveFacts
|
|
359
370
|
nil # raise "counterpart roles are undefined in n-ary fact types"
|
360
371
|
end
|
361
372
|
end
|
373
|
+
|
374
|
+
# return an array of all the constraints on this role (not including ValueConstraint on a ValueType player)
|
375
|
+
def all_constraint
|
376
|
+
(
|
377
|
+
Array(role_value_constraint) +
|
378
|
+
all_role_ref.to_a.flat_map do |rr|
|
379
|
+
rr.role_sequence.all_presence_constraint.to_a +
|
380
|
+
rr.role_sequence.all_subset_constraint_as_superset_role_sequence +
|
381
|
+
rr.role_sequence.all_subset_constraint_as_subset_role_sequence +
|
382
|
+
rr.role_sequence.all_set_comparison_roles.map(&:set_comparison_constraint)
|
383
|
+
end +
|
384
|
+
all_ring_constraint.to_a +
|
385
|
+
all_ring_constraint_as_other_role.to_a
|
386
|
+
).uniq
|
387
|
+
end
|
362
388
|
end
|
363
389
|
|
364
390
|
class RoleRef
|
365
391
|
def describe
|
366
|
-
|
392
|
+
role.name + " in (#{role.fact_type.default_reading})"
|
367
393
|
end
|
368
394
|
|
369
395
|
def preferred_reference
|
@@ -434,7 +460,9 @@ module ActiveFacts
|
|
434
460
|
class RoleSequence
|
435
461
|
def describe(highlighted_role_ref = nil)
|
436
462
|
"("+
|
437
|
-
|
463
|
+
all_role_ref_in_order.map{|rr| rr.role.name + (highlighted_role_ref == rr ? '*' : '') }*", " +
|
464
|
+
" in " +
|
465
|
+
all_role_ref.map(&:role).map(&:fact_type).uniq.map(&:default_reading).map(&:inspect)*', ' +
|
438
466
|
")"
|
439
467
|
end
|
440
468
|
|
@@ -457,6 +485,10 @@ module ActiveFacts
|
|
457
485
|
end
|
458
486
|
|
459
487
|
class ValueType
|
488
|
+
def all_supertype
|
489
|
+
Array(supertype)
|
490
|
+
end
|
491
|
+
|
460
492
|
def supertypes_transitive
|
461
493
|
[self] + (supertype ? supertype.supertypes_transitive : [])
|
462
494
|
end
|
@@ -694,6 +726,10 @@ module ActiveFacts
|
|
694
726
|
}
|
695
727
|
end
|
696
728
|
|
729
|
+
def all_supertype
|
730
|
+
supertypes
|
731
|
+
end
|
732
|
+
|
697
733
|
# An array of all direct subtypes
|
698
734
|
def all_subtype
|
699
735
|
all_type_inheritance_as_supertype.map(&:subtype)
|
@@ -935,6 +971,10 @@ module ActiveFacts
|
|
935
971
|
all_allowed_range.single.to_s
|
936
972
|
end
|
937
973
|
end
|
974
|
+
|
975
|
+
def all_constrained_role
|
976
|
+
Array(role_as_role_value_constraint) # Empty unless it's a role value constraint
|
977
|
+
end
|
938
978
|
end
|
939
979
|
|
940
980
|
class AllowedRange
|
@@ -1009,16 +1049,35 @@ module ActiveFacts
|
|
1009
1049
|
def covers_role role
|
1010
1050
|
role_sequence.all_role_ref.map(&:role).include?(role)
|
1011
1051
|
end
|
1052
|
+
|
1053
|
+
def all_constrained_role
|
1054
|
+
role_sequence.all_role_ref.map(&:role)
|
1055
|
+
end
|
1012
1056
|
end
|
1013
1057
|
|
1014
1058
|
class SubsetConstraint
|
1015
1059
|
def describe
|
1016
1060
|
'SubsetConstraint(' +
|
1017
|
-
subset_role_sequence.describe
|
1018
|
-
'
|
1061
|
+
subset_role_sequence.describe +
|
1062
|
+
' only if ' +
|
1019
1063
|
superset_role_sequence.describe +
|
1020
1064
|
')'
|
1021
1065
|
end
|
1066
|
+
|
1067
|
+
def all_constrained_role
|
1068
|
+
subset_role_sequence.all_role_ref.map(&:role) +
|
1069
|
+
superset_role_sequence.all_role_ref.map(&:role)
|
1070
|
+
end
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
class SetComparisonRoles
|
1074
|
+
def describe
|
1075
|
+
"("+
|
1076
|
+
role_sequence.all_role_ref_in_order.map{|rr| rr.role.name }*", " +
|
1077
|
+
" in " +
|
1078
|
+
role_sequence.all_role_ref.map(&:role).map(&:fact_type).uniq.map(&:default_reading).map(&:inspect)*', ' +
|
1079
|
+
")"
|
1080
|
+
end
|
1022
1081
|
end
|
1023
1082
|
|
1024
1083
|
class SetComparisonConstraint
|
@@ -1033,8 +1092,26 @@ module ActiveFacts
|
|
1033
1092
|
end*',' +
|
1034
1093
|
')'
|
1035
1094
|
end
|
1095
|
+
|
1096
|
+
def all_constrained_role
|
1097
|
+
all_set_comparison_roles.map(&:role_sequence).flat_map(&:all_role_ref).map(&:role).uniq
|
1098
|
+
end
|
1036
1099
|
end
|
1037
1100
|
|
1101
|
+
class SetEqualityConstraint
|
1102
|
+
def describe
|
1103
|
+
all_set_comparison_roles.map(&:describe) * " if and only if "
|
1104
|
+
end
|
1105
|
+
end
|
1106
|
+
|
1107
|
+
class SetExclusionConstraint
|
1108
|
+
def describe
|
1109
|
+
(is_mandatory ? "exactly one of " : "at most one of ") +
|
1110
|
+
all_set_comparison_roles.map(&:describe) * " or "
|
1111
|
+
end
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
|
1038
1115
|
class RingConstraint
|
1039
1116
|
def describe
|
1040
1117
|
'RingConstraint(' +
|
@@ -1044,6 +1121,10 @@ module ActiveFacts
|
|
1044
1121
|
role.fact_type.default_reading +
|
1045
1122
|
')'
|
1046
1123
|
end
|
1124
|
+
|
1125
|
+
def all_constrained_role
|
1126
|
+
[role, other_role]
|
1127
|
+
end
|
1047
1128
|
end
|
1048
1129
|
|
1049
1130
|
class TypeInheritance
|
@@ -1438,16 +1519,19 @@ module ActiveFacts
|
|
1438
1519
|
"Composite #{mapping.inspect}"
|
1439
1520
|
end
|
1440
1521
|
|
1522
|
+
def all_index
|
1523
|
+
all_access_path.
|
1524
|
+
select{|ap| ap.is_a?(Index)}.
|
1525
|
+
sort_by{|ap| [ap.composite_as_primary_index ? 0 : 1] + Array(ap.name)+ap.all_index_field.map(&:inspect) } # REVISIT: Fix hack for stable ordering
|
1526
|
+
end
|
1527
|
+
|
1441
1528
|
def show_trace
|
1442
1529
|
trace :composition, inspect do
|
1443
1530
|
trace :composition?, "Columns" do
|
1444
1531
|
mapping.show_trace
|
1445
1532
|
end
|
1446
1533
|
|
1447
|
-
indices =
|
1448
|
-
all_access_path.
|
1449
|
-
select{|ap| ap.is_a?(Index)}.
|
1450
|
-
sort_by{|ap| [ap.composite_as_primary_index ? 0 : 1] + Array(ap.name)+ap.all_index_field.map(&:inspect) } # REVISIT: Fix hack for stable ordering
|
1534
|
+
indices = all_index
|
1451
1535
|
unless indices.empty?
|
1452
1536
|
trace :composition, "Indices" do
|
1453
1537
|
indices.each do |ap|
|
@@ -1590,6 +1674,14 @@ module ActiveFacts
|
|
1590
1674
|
end
|
1591
1675
|
end
|
1592
1676
|
end
|
1677
|
+
|
1678
|
+
def is_mandatory
|
1679
|
+
true
|
1680
|
+
end
|
1681
|
+
|
1682
|
+
def path_mandatory
|
1683
|
+
true
|
1684
|
+
end
|
1593
1685
|
end
|
1594
1686
|
|
1595
1687
|
class Nesting
|
@@ -1707,6 +1799,22 @@ module ActiveFacts
|
|
1707
1799
|
end
|
1708
1800
|
end
|
1709
1801
|
|
1802
|
+
def all_role
|
1803
|
+
([child_role, parent_role] + all_nesting.map(&:index_role)).flat_map{|role| [role, role.base_role]}.uniq
|
1804
|
+
end
|
1805
|
+
|
1806
|
+
def value_constraints
|
1807
|
+
return [] unless object_type.is_a?(ValueType)
|
1808
|
+
object_type.supertypes_transitive.flat_map{|vt| Array(vt.value_constraint)}
|
1809
|
+
end
|
1810
|
+
|
1811
|
+
def is_mandatory
|
1812
|
+
parent_role.is_mandatory
|
1813
|
+
end
|
1814
|
+
|
1815
|
+
def path_mandatory
|
1816
|
+
is_mandatory && parent.path_mandatory
|
1817
|
+
end
|
1710
1818
|
end
|
1711
1819
|
|
1712
1820
|
class FullAbsorption
|
@@ -1723,6 +1831,14 @@ module ActiveFacts
|
|
1723
1831
|
def show_trace
|
1724
1832
|
trace :composition, "#{ordinal ? "#{ordinal}: " : ''}#{inspect} #{name ? "(as #{name.inspect})" : ''}"
|
1725
1833
|
end
|
1834
|
+
|
1835
|
+
def all_role
|
1836
|
+
[role, role.base_role].uniq
|
1837
|
+
end
|
1838
|
+
|
1839
|
+
def is_mandatory
|
1840
|
+
false
|
1841
|
+
end
|
1726
1842
|
end
|
1727
1843
|
|
1728
1844
|
class Discriminator
|
@@ -1733,6 +1849,10 @@ module ActiveFacts
|
|
1733
1849
|
def show_trace
|
1734
1850
|
trace :composition, "#{ordinal ? "#{ordinal}: " : ''}#{inspect} #{name ? " (as #{name.inspect})" : ''}"
|
1735
1851
|
end
|
1852
|
+
|
1853
|
+
def all_role
|
1854
|
+
all_discriminated_role.map(&:role).flat_map{|role| [role, role.base_role]}.uniq
|
1855
|
+
end
|
1736
1856
|
end
|
1737
1857
|
|
1738
1858
|
class ValueField
|
@@ -1881,6 +2001,18 @@ module ActiveFacts
|
|
1881
2001
|
(parent ? parent.path+[self] : [self])
|
1882
2002
|
end
|
1883
2003
|
|
2004
|
+
def is_mandatory
|
2005
|
+
parent.is_mandatory
|
2006
|
+
end
|
2007
|
+
|
2008
|
+
def path_mandatory
|
2009
|
+
parent.path_mandatory
|
2010
|
+
end
|
2011
|
+
|
2012
|
+
def all_role
|
2013
|
+
[]
|
2014
|
+
end
|
2015
|
+
|
1884
2016
|
def rank_path
|
1885
2017
|
(parent ? parent.rank_path+[ordinal] : [ordinal])
|
1886
2018
|
end
|