activefacts 0.7.1 → 0.7.2
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.
- data/Manifest.txt +4 -0
- data/examples/CQL/Metamodel.cql +11 -7
- data/lib/activefacts/api/concept.rb +10 -0
- data/lib/activefacts/api/entity.rb +2 -0
- data/lib/activefacts/api/instance_index.rb +71 -0
- data/lib/activefacts/api/role_proxy.rb +70 -0
- data/lib/activefacts/api/role_values.rb +117 -0
- data/lib/activefacts/generate/absorption.rb +20 -30
- data/lib/activefacts/generate/null.rb +1 -0
- data/lib/activefacts/generate/ruby.rb +12 -28
- data/lib/activefacts/generate/sql/server.rb +8 -22
- data/lib/activefacts/generate/text.rb +1 -0
- data/lib/activefacts/input/cql.rb +30 -32
- data/lib/activefacts/input/orm.rb +11 -12
- data/lib/activefacts/persistence.rb +5 -0
- data/lib/activefacts/persistence/columns.rb +28 -21
- data/lib/activefacts/persistence/concept.rb +73 -0
- data/lib/activefacts/persistence/foreignkey.rb +17 -1
- data/lib/activefacts/persistence/index.rb +21 -10
- data/lib/activefacts/persistence/reference.rb +6 -6
- data/lib/activefacts/persistence/tables.rb +8 -5
- data/lib/activefacts/version.rb +1 -1
- data/lib/activefacts/vocabulary/extensions.rb +17 -7
- data/lib/activefacts/vocabulary/metamodel.rb +22 -17
- data/spec/absorption_spec.rb +1 -1
- data/spec/cql_symbol_tables_spec.rb +1 -1
- data/spec/cqldump_spec.rb +8 -8
- data/spec/norma_tables_spec.rb +1 -1
- metadata +7 -3
@@ -31,12 +31,13 @@ module ActiveFacts
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def vocabulary_start(vocabulary)
|
34
|
+
puts "require 'activefacts/api'\n"
|
34
35
|
if @sql
|
35
36
|
require 'activefacts/persistence'
|
37
|
+
puts "require 'activefacts/persistence'\n"
|
36
38
|
@tables = vocabulary.tables
|
37
39
|
end
|
38
|
-
puts "
|
39
|
-
puts "module #{vocabulary.name}\n\n"
|
40
|
+
puts "\nmodule #{vocabulary.name}\n\n"
|
40
41
|
end
|
41
42
|
|
42
43
|
def vocabulary_end
|
@@ -63,7 +64,7 @@ module ActiveFacts
|
|
63
64
|
|
64
65
|
puts " class #{o.name} < #{ruby_type_name}\n" +
|
65
66
|
" value_type #{params}\n"
|
66
|
-
puts " table" if @sql and
|
67
|
+
puts " table" if @sql and o.is_table
|
67
68
|
puts " \# REVISIT: #{o.name} has restricted values\n" if o.value_restriction
|
68
69
|
puts " \# REVISIT: #{o.name} is in units of #{o.unit.name}\n" if o.unit
|
69
70
|
roles_dump(o)
|
@@ -71,9 +72,13 @@ module ActiveFacts
|
|
71
72
|
end
|
72
73
|
|
73
74
|
def subtype_dump(o, supertypes, pi = nil)
|
74
|
-
|
75
|
+
primary_supertype = o && (o.identifying_supertype || o.supertypes[0])
|
76
|
+
secondary_supertypes = o.supertypes-[primary_supertype]
|
77
|
+
|
78
|
+
puts " class #{o.name} < #{ primary_supertype.name }"
|
75
79
|
puts " identified_by #{identified_by(o, pi)}" if pi
|
76
|
-
puts "
|
80
|
+
puts " supertypes "+secondary_supertypes.map(&:name)*", " if secondary_supertypes.size > 0
|
81
|
+
puts " table" if @sql and o.is_table
|
77
82
|
fact_roles_dump(o.fact_type) if o.fact_type
|
78
83
|
roles_dump(o)
|
79
84
|
puts " end\n\n"
|
@@ -83,7 +88,7 @@ module ActiveFacts
|
|
83
88
|
def non_subtype_dump(o, pi)
|
84
89
|
puts " class #{o.name}"
|
85
90
|
puts " identified_by #{identified_by(o, pi)}"
|
86
|
-
puts " table" if @sql and
|
91
|
+
puts " table" if @sql and o.is_table
|
87
92
|
fact_roles_dump(o.fact_type) if o.fact_type
|
88
93
|
roles_dump(o)
|
89
94
|
puts " end\n\n"
|
@@ -107,6 +112,7 @@ module ActiveFacts
|
|
107
112
|
"\n" +
|
108
113
|
secondary_supertypes.map{|sst| " supertype :#{sst.name}"}*"\n" +
|
109
114
|
(pi ? " identified_by #{identified_by(o, pi)}" : "")
|
115
|
+
puts " table" if @sql and o.is_table
|
110
116
|
fact_roles_dump(fact_type)
|
111
117
|
roles_dump(o)
|
112
118
|
puts " end\n\n"
|
@@ -120,32 +126,10 @@ module ActiveFacts
|
|
120
126
|
}*", "
|
121
127
|
end
|
122
128
|
|
123
|
-
def roles_dump(o)
|
124
|
-
@ar_by_role = nil
|
125
|
-
if @sql and @tables.include?(o)
|
126
|
-
ar = o.absorbed_roles
|
127
|
-
@ar_by_role = ar.all_role_ref.inject({}){|h,rr|
|
128
|
-
input_role = (j=rr.all_join_path).size > 0 ? j[0].input_role : rr.role
|
129
|
-
(h[input_role] ||= []) << rr
|
130
|
-
h
|
131
|
-
}
|
132
|
-
#puts ar.all_role_ref.map{|rr| "\t"+rr.describe}*"\n"
|
133
|
-
end
|
134
|
-
super
|
135
|
-
end
|
136
|
-
|
137
129
|
def unary_dump(role, role_name)
|
138
130
|
puts " maybe :"+role_name
|
139
131
|
end
|
140
132
|
|
141
|
-
def role_dump(role)
|
142
|
-
other_role = role.fact_type.all_role.select{|r| r != role}[0] || role
|
143
|
-
if @ar_by_role and @ar_by_role[other_role] and @sql
|
144
|
-
puts " # role #{role.fact_type.describe(role)}: absorbs in through #{preferred_role_name(other_role)}: "+@ar_by_role[other_role].map(&:column_name)*", "
|
145
|
-
end
|
146
|
-
super
|
147
|
-
end
|
148
|
-
|
149
133
|
def binary_dump(role, role_name, role_player, one_to_one = nil, readings = nil, other_role_name = nil, other_method_name = nil)
|
150
134
|
# Find whether we need the name of the other role player, and whether it's defined yet:
|
151
135
|
if role_name.camelcase(true) == role_player.name
|
@@ -116,7 +116,7 @@ module ActiveFacts
|
|
116
116
|
tables_emitted = {}
|
117
117
|
delayed_foreign_keys = []
|
118
118
|
|
119
|
-
@vocabulary.tables.
|
119
|
+
@vocabulary.tables.each do |table|
|
120
120
|
puts "CREATE TABLE #{escape table.name} ("
|
121
121
|
|
122
122
|
pk = table.identifier_columns
|
@@ -127,9 +127,9 @@ module ActiveFacts
|
|
127
127
|
column.references[0].is_simple_reference
|
128
128
|
end
|
129
129
|
|
130
|
-
|
131
|
-
|
132
|
-
|
130
|
+
# We sort the columns here, not in the persistence layer, because it affects
|
131
|
+
# the ordering of columns in an index :-(.
|
132
|
+
columns = table.columns.sort_by { |column| column.name(nil) }.map do |column|
|
133
133
|
name = escape column.name("")
|
134
134
|
padding = " "*(name.size >= ColumnNameMax ? 1 : ColumnNameMax-name.size)
|
135
135
|
type, params, restrictions = column.type
|
@@ -158,22 +158,11 @@ module ActiveFacts
|
|
158
158
|
")"
|
159
159
|
|
160
160
|
inline_fks = []
|
161
|
-
table.foreign_keys.
|
162
|
-
# Put the Foreign keys in a defined order:
|
163
|
-
[ fk.to.name,
|
164
|
-
fk.to_columns.map{|col| col.name(nil).sort},
|
165
|
-
fk.from_columns.map{|col| col.name(nil).sort}
|
166
|
-
]
|
167
|
-
end.each do |fk|
|
168
|
-
# Put the column pairs in a defined order, sorting key pairs by to-name:
|
169
|
-
froms, tos = fk.from_columns.zip(fk.to_columns).sort_by { |pair|
|
170
|
-
pair[1].name(nil)
|
171
|
-
}.transpose
|
172
|
-
|
161
|
+
table.foreign_keys.each do |fk|
|
173
162
|
fk_text = "FOREIGN KEY (" +
|
174
|
-
|
163
|
+
fk.from_columns.map{|column| column.name}*", " +
|
175
164
|
") REFERENCES #{escape fk.to.name} (" +
|
176
|
-
|
165
|
+
fk.to_columns.map{|column| column.name}*", " +
|
177
166
|
")"
|
178
167
|
if !@delay_fks and # We don't want to delay all Fks
|
179
168
|
(tables_emitted[fk.to] or # The target table has been emitted
|
@@ -187,10 +176,7 @@ module ActiveFacts
|
|
187
176
|
indices = table.indices
|
188
177
|
inline_indices = []
|
189
178
|
delayed_indices = []
|
190
|
-
indices.
|
191
|
-
# Put the indices in a defined order:
|
192
|
-
index.columns.map(&:name)
|
193
|
-
end.each do |index|
|
179
|
+
indices.each do |index|
|
194
180
|
next if index.over == table && index.is_primary # Already did the primary keys
|
195
181
|
abbreviated_column_names = index.abbreviated_column_names*""
|
196
182
|
column_names = index.column_names
|
@@ -1,5 +1,3 @@
|
|
1
|
-
#
|
2
|
-
# ActiveFacts Vocabulary Input.
|
3
1
|
# Compile a CQL file into an ActiveFacts vocabulary.
|
4
2
|
#
|
5
3
|
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
@@ -97,15 +95,15 @@ module ActiveFacts
|
|
97
95
|
# Create the base type:
|
98
96
|
base_type = nil
|
99
97
|
if (base_type_name != name)
|
100
|
-
unless base_type = @constellation.ValueType[[@constellation.Name(base_type_name)
|
98
|
+
unless base_type = @constellation.ValueType[[@vocabulary, @constellation.Name(base_type_name)]]
|
101
99
|
#puts "REVISIT: Creating base ValueType #{base_type_name} in #{@vocabulary.inspect}"
|
102
|
-
base_type = @constellation.ValueType(
|
100
|
+
base_type = @constellation.ValueType(@vocabulary, base_type_name)
|
103
101
|
return if base_type_name == name
|
104
102
|
end
|
105
103
|
end
|
106
104
|
|
107
105
|
# Create and initialise the ValueType:
|
108
|
-
vt = @constellation.ValueType(
|
106
|
+
vt = @constellation.ValueType(@vocabulary, name)
|
109
107
|
vt.supertype = base_type if base_type
|
110
108
|
vt.length = length if length
|
111
109
|
vt.scale = scale if scale
|
@@ -120,7 +118,7 @@ module ActiveFacts
|
|
120
118
|
min ? [min.to_s, true] : nil,
|
121
119
|
max ? [max.to_s, true] : nil
|
122
120
|
)
|
123
|
-
ar = @constellation.AllowedRange(
|
121
|
+
ar = @constellation.AllowedRange(vt.value_restriction, v_range)
|
124
122
|
end
|
125
123
|
end
|
126
124
|
end
|
@@ -130,7 +128,7 @@ module ActiveFacts
|
|
130
128
|
debug :entity, "Defining Entity Type #{name}" do
|
131
129
|
# Assert the entity:
|
132
130
|
# If this entity was forward referenced, this won't be a new object, and will subsume its roles
|
133
|
-
entity_type = @constellation.EntityType(
|
131
|
+
entity_type = @constellation.EntityType(@vocabulary, name)
|
134
132
|
|
135
133
|
# Set up its supertypes:
|
136
134
|
supertypes.each do |supertype_name|
|
@@ -162,9 +160,9 @@ module ActiveFacts
|
|
162
160
|
|
163
161
|
# Find or Create an appropriate ValueType called "#{name}#{mode}", of the supertype "#{mode}"
|
164
162
|
vt_name = "#{name}#{mode}"
|
165
|
-
unless vt = @constellation.ValueType[[
|
166
|
-
base_vt = @constellation.ValueType(
|
167
|
-
vt = @constellation.ValueType(
|
163
|
+
unless vt = @constellation.ValueType[[@vocabulary, vt_name]]
|
164
|
+
base_vt = @constellation.ValueType(@vocabulary, mode)
|
165
|
+
vt = @constellation.ValueType(@vocabulary, vt_name, :supertype => base_vt)
|
168
166
|
end
|
169
167
|
end
|
170
168
|
|
@@ -373,7 +371,7 @@ module ActiveFacts
|
|
373
371
|
|
374
372
|
def add_supertype(entity_type, supertype_name, identifying_supertype)
|
375
373
|
debug :supertype, "Supertype #{supertype_name}"
|
376
|
-
supertype = @constellation.EntityType(
|
374
|
+
supertype = @constellation.EntityType(@vocabulary, supertype_name)
|
377
375
|
inheritance_fact = @constellation.TypeInheritance(entity_type, supertype, :fact_type_id => :new)
|
378
376
|
|
379
377
|
# Create a reading:
|
@@ -459,7 +457,7 @@ module ActiveFacts
|
|
459
457
|
|
460
458
|
# The fact type has a name iff it's objectified as an entity type
|
461
459
|
#puts "============= Creating entity #{name} to nominalize fact type #{fact_type.default_reading} ======================" if name
|
462
|
-
fact_type.entity_type = @constellation.EntityType(
|
460
|
+
fact_type.entity_type = @constellation.EntityType(@vocabulary, name) if name
|
463
461
|
|
464
462
|
# Add the identifying PresenceConstraint for this fact type:
|
465
463
|
if fact_type.all_role.size == 1 && !fact_type.entity_type
|
@@ -496,7 +494,7 @@ module ActiveFacts
|
|
496
494
|
# sequences. Each binding that isn't common at this top level
|
497
495
|
# must occur more than once in each group of fact types where
|
498
496
|
# it appears, and it forms a join between those fact types.
|
499
|
-
def
|
497
|
+
def bind_joins_as_role_sequences(readings_list)
|
500
498
|
@symbols = SymbolTable.new(@constellation, @vocabulary)
|
501
499
|
fact_roles_list = []
|
502
500
|
bindings_list = []
|
@@ -520,8 +518,8 @@ module ActiveFacts
|
|
520
518
|
end
|
521
519
|
|
522
520
|
# Each set of binding arrays in the list must share at least one common binding
|
523
|
-
|
524
|
-
common_bindings =
|
521
|
+
bindings_by_join = bindings_list.map{|join| join.flatten}
|
522
|
+
common_bindings = bindings_by_join[1..-1].inject(bindings_by_join[0]) { |c, b| c & b }
|
525
523
|
# Was:
|
526
524
|
# common_bindings = bindings_list.inject(bindings_list[0]) { |common, bindings| common & bindings }
|
527
525
|
raise "Set constraints must have at least one common role between the sets" unless common_bindings.size > 0
|
@@ -533,9 +531,9 @@ module ActiveFacts
|
|
533
531
|
# Each element of a join path is the array of bindings for a fact type invocation.
|
534
532
|
# Each invocation must share a binding (not one of the globally common ones) with
|
535
533
|
# another invocation in that join path.
|
536
|
-
bindings_list.each_with_index do |
|
534
|
+
bindings_list.each_with_index do |join, jpnum|
|
537
535
|
# Check that this bindings array creates a complete join path:
|
538
|
-
|
536
|
+
join.each_with_index do |bindings, i|
|
539
537
|
fact_type_roles = fact_roles_list[jpnum][i]
|
540
538
|
fact_type = fact_type_roles[0].fact_type
|
541
539
|
|
@@ -543,10 +541,10 @@ module ActiveFacts
|
|
543
541
|
# These bindings must be joined to some later fact type by a common binding that isn't a globally-common one:
|
544
542
|
local_bindings = bindings-common_bindings
|
545
543
|
next if local_bindings.size == 0 # No join path is required, as only one fact type is invoked.
|
546
|
-
next if i ==
|
544
|
+
next if i == join.size-1 # We already checked that the last fact type invocation is joined
|
547
545
|
ok = local_bindings.detect do |local_binding|
|
548
546
|
j = i+1
|
549
|
-
|
547
|
+
join[j..-1].detect do |other_bindings|
|
550
548
|
other_fact_type_roles = fact_roles_list[jpnum][j]
|
551
549
|
other_fact_type = other_fact_type_roles[0].fact_type
|
552
550
|
j += 1
|
@@ -568,10 +566,10 @@ module ActiveFacts
|
|
568
566
|
role_sequences = readings_list.map{|r| @constellation.RoleSequence(:new) }
|
569
567
|
common_bindings.each_with_index do |binding, index|
|
570
568
|
role_sequences.each_with_index do |rs, rsi|
|
571
|
-
|
569
|
+
join = bindings_list[rsi]
|
572
570
|
fact_pos = nil
|
573
|
-
join_pos = (0...
|
574
|
-
fact_pos =
|
571
|
+
join_pos = (0...join.size).detect do |i|
|
572
|
+
fact_pos = join[i].index(binding)
|
575
573
|
end
|
576
574
|
@constellation.RoleRef(rs, index).role = fact_roles_list[rsi][join_pos][fact_pos]
|
577
575
|
end
|
@@ -581,7 +579,7 @@ module ActiveFacts
|
|
581
579
|
end
|
582
580
|
|
583
581
|
def subset_constraint(subset_readings, superset_readings)
|
584
|
-
role_sequences =
|
582
|
+
role_sequences = bind_joins_as_role_sequences([subset_readings, superset_readings])
|
585
583
|
|
586
584
|
#puts "subset_constraint:\n\t#{subset_readings.inspect}\n\t#{superset_readings.inspect}"
|
587
585
|
#puts "\t#{role_sequences.map{|rs| rs.describe}.inspect}"
|
@@ -601,7 +599,7 @@ module ActiveFacts
|
|
601
599
|
# Exactly one or at most one, nothing else will do
|
602
600
|
raise "Set comparison constraint must use 'at most' or 'exactly' one" if quantifier[1] != 1
|
603
601
|
|
604
|
-
role_sequences =
|
602
|
+
role_sequences = bind_joins_as_role_sequences(readings_list)
|
605
603
|
|
606
604
|
# Create the constraint:
|
607
605
|
constraint = @constellation.SetExclusionConstraint(:new)
|
@@ -615,7 +613,7 @@ module ActiveFacts
|
|
615
613
|
def equality_constraint(*readings_list)
|
616
614
|
#puts "REVISIT: equality\n\t#{readings_list.map{|rl| rl.inspect}*"\n\tif and only if\n\t"}"
|
617
615
|
|
618
|
-
role_sequences =
|
616
|
+
role_sequences = bind_joins_as_role_sequences(readings_list)
|
619
617
|
|
620
618
|
# Create the constraint:
|
621
619
|
constraint = @constellation.SetEqualityConstraint(:new)
|
@@ -994,7 +992,7 @@ module ActiveFacts
|
|
994
992
|
return nil if roles.size == 0 # Safeguard; this would chuck an exception otherwise
|
995
993
|
roles[0].all_role_ref.each do |role_ref|
|
996
994
|
next if role_ref.role_sequence.all_role_ref.map(&:role) != roles
|
997
|
-
pc = role_ref.role_sequence.all_presence_constraint.
|
995
|
+
pc = role_ref.role_sequence.all_presence_constraint.single # Will return nil if there's more than one.
|
998
996
|
#puts "Existing PresenceConstraint matches those roles!" if pc
|
999
997
|
return pc if pc
|
1000
998
|
end
|
@@ -1018,15 +1016,15 @@ module ActiveFacts
|
|
1018
1016
|
end
|
1019
1017
|
|
1020
1018
|
def concept_by_name(name)
|
1021
|
-
player = @constellation.Concept[[
|
1019
|
+
player = @constellation.Concept[[@vocabulary.identifying_role_values, name]]
|
1022
1020
|
|
1023
1021
|
# REVISIT: Hack to allow facts to refer to standard types that will be imported from standard vocabulary:
|
1024
1022
|
if !player && %w{Date DateAndTime Time}.include?(name)
|
1025
|
-
player = @constellation.ValueType(
|
1023
|
+
player = @constellation.ValueType(@vocabulary.identifying_role_values, name)
|
1026
1024
|
end
|
1027
1025
|
|
1028
1026
|
if (!player && @symbols.allowed_forward[name])
|
1029
|
-
player = @constellation.EntityType(
|
1027
|
+
player = @constellation.EntityType(@vocabulary, name)
|
1030
1028
|
end
|
1031
1029
|
player
|
1032
1030
|
end
|
@@ -1173,15 +1171,15 @@ module ActiveFacts
|
|
1173
1171
|
# return the EntityType or ValueType this name refers to:
|
1174
1172
|
def concept(name, allowed_forward = false)
|
1175
1173
|
# See if the name is a defined concept in this vocabulary:
|
1176
|
-
player = @constellation.Concept[[
|
1174
|
+
player = @constellation.Concept[[virv = @vocabulary.identifying_role_values, name]]
|
1177
1175
|
|
1178
1176
|
# REVISIT: Hack to allow facts to refer to standard types that will be imported from standard vocabulary:
|
1179
1177
|
if !player && %w{Date DateAndTime Time}.include?(name)
|
1180
|
-
player = @constellation.ValueType(
|
1178
|
+
player = @constellation.ValueType(virv, name)
|
1181
1179
|
end
|
1182
1180
|
|
1183
1181
|
if !player && allowed_forward
|
1184
|
-
player = @constellation.EntityType(
|
1182
|
+
player = @constellation.EntityType(@vocabulary, name)
|
1185
1183
|
end
|
1186
1184
|
|
1187
1185
|
player
|
@@ -101,11 +101,11 @@ module ActiveFacts
|
|
101
101
|
entity_types <<
|
102
102
|
@by_id[id] =
|
103
103
|
entity_type =
|
104
|
-
@constellation.EntityType(
|
104
|
+
@constellation.EntityType(@vocabulary, name)
|
105
105
|
independent = x.attributes['IsIndependent']
|
106
106
|
entity_type.is_independent = true if independent && independent == 'true'
|
107
107
|
personal = x.attributes['IsPersonal']
|
108
|
-
entity_type.
|
108
|
+
entity_type.pronoun = 'personal' if personal && personal == 'true'
|
109
109
|
# x_pref = x.elements.to_a("orm:PreferredIdentifier")[0]
|
110
110
|
# if x_pref
|
111
111
|
# pi_id = x_pref.attributes['ref']
|
@@ -139,26 +139,26 @@ module ActiveFacts
|
|
139
139
|
length = 32 if type_name =~ /Integer\Z/ && length.to_i == 0 # Set default integer length
|
140
140
|
|
141
141
|
# REVISIT: Need to handle standard types better here:
|
142
|
-
data_type = type_name != name ? @constellation.ValueType(
|
142
|
+
data_type = type_name != name ? @constellation.ValueType(@vocabulary, type_name) : nil
|
143
143
|
|
144
144
|
# puts "ValueType #{name} is #{id}"
|
145
145
|
value_types <<
|
146
146
|
@by_id[id] =
|
147
|
-
vt = @constellation.ValueType(
|
147
|
+
vt = @constellation.ValueType(@vocabulary, name)
|
148
148
|
vt.supertype = data_type
|
149
149
|
vt.length = length if length
|
150
150
|
vt.scale = scale if scale
|
151
151
|
independent = x.attributes['IsIndependent']
|
152
152
|
vt.is_independent = true if independent && independent == 'true'
|
153
153
|
personal = x.attributes['IsPersonal']
|
154
|
-
vt.
|
154
|
+
vt.pronoun = 'personal' if personal && personal == 'true'
|
155
155
|
|
156
156
|
x_ranges = x.elements.to_a("orm:ValueRestriction/orm:ValueConstraint/orm:ValueRanges/orm:ValueRange")
|
157
157
|
next if x_ranges.size == 0
|
158
158
|
vt.value_restriction = @constellation.ValueRestriction(:new)
|
159
159
|
x_ranges.each{|x_range|
|
160
160
|
v_range = value_range(x_range)
|
161
|
-
ar = @constellation.AllowedRange(
|
161
|
+
ar = @constellation.AllowedRange(vt.value_restriction, v_range)
|
162
162
|
}
|
163
163
|
}
|
164
164
|
end
|
@@ -317,7 +317,7 @@ module ActiveFacts
|
|
317
317
|
#puts "NestedType #{name} is #{id}, nests #{fact_type.fact_type_id}"
|
318
318
|
nested_types <<
|
319
319
|
@by_id[id] =
|
320
|
-
nested_type = @constellation.EntityType(
|
320
|
+
nested_type = @constellation.EntityType(@vocabulary, name)
|
321
321
|
nested_type.fact_type = fact_type
|
322
322
|
end
|
323
323
|
}
|
@@ -390,7 +390,7 @@ module ActiveFacts
|
|
390
390
|
role.role_value_restriction = @constellation.ValueRestriction(:new)
|
391
391
|
x_ranges.each{|x_range|
|
392
392
|
v_range = value_range(x_range)
|
393
|
-
ar = @constellation.AllowedRange(
|
393
|
+
ar = @constellation.AllowedRange(role.role_value_restriction, v_range)
|
394
394
|
}
|
395
395
|
}
|
396
396
|
|
@@ -632,8 +632,8 @@ module ActiveFacts
|
|
632
632
|
# A TypeInheritance fact type has a uniqueness constraint on each role.
|
633
633
|
# If this UC is on the supertype and identifies the subtype, it's preferred:
|
634
634
|
is_supertype_constraint =
|
635
|
-
roles.all_role_ref.
|
636
|
-
(role =
|
635
|
+
(rr = roles.all_role_ref.single) &&
|
636
|
+
(role = rr.role) &&
|
637
637
|
(fact_type = role.fact_type) &&
|
638
638
|
fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance) &&
|
639
639
|
role.concept == fact_type.supertype &&
|
@@ -649,8 +649,7 @@ module ActiveFacts
|
|
649
649
|
pc.is_preferred_identifier = true if pi || unary_identifier || is_supertype_constraint
|
650
650
|
#puts "#{name} covers #{roles.describe} has min=#{pc.min_frequency}, max=1, preferred=#{pc.is_preferred_identifier.inspect}" if emit_special_debug
|
651
651
|
|
652
|
-
#puts roles.
|
653
|
-
#puts pc.verbalise
|
652
|
+
#puts roles.all_role_ref.to_a[0].role.fact_type.describe + " is subject to " + pc.describe if roles.all_role_ref.all?{|r| r.role.fact_type.is_a? ActiveFacts::Metamodel::TypeInheritance }
|
654
653
|
|
655
654
|
(@constraints_by_rs[roles] ||= []) << pc
|
656
655
|
}
|
@@ -3,8 +3,13 @@
|
|
3
3
|
#
|
4
4
|
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
5
5
|
#
|
6
|
+
|
7
|
+
# These files are concerned with calculating a relational schema for a vocabulary:
|
6
8
|
require 'activefacts/persistence/reference'
|
7
9
|
require 'activefacts/persistence/tables'
|
8
10
|
require 'activefacts/persistence/columns'
|
9
11
|
require 'activefacts/persistence/foreignkey'
|
10
12
|
require 'activefacts/persistence/index'
|
13
|
+
|
14
|
+
# These extend the API classes with relational awareness:
|
15
|
+
require 'activefacts/persistence/concept'
|