activefacts 0.8.9 → 0.8.10

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 (120) hide show
  1. data/.gemtest +0 -0
  2. data/Manifest.txt +28 -33
  3. data/Rakefile +11 -12
  4. data/bin/cql +90 -46
  5. data/examples/CQL/Blog.cql +2 -1
  6. data/examples/CQL/CompanyDirectorEmployee.cql +2 -2
  7. data/examples/CQL/Death.cql +1 -1
  8. data/examples/CQL/Diplomacy.cql +9 -9
  9. data/examples/CQL/Genealogy.cql +3 -2
  10. data/examples/CQL/Insurance.cql +10 -7
  11. data/examples/CQL/JoinEquality.cql +2 -2
  12. data/examples/CQL/Marriage.cql +1 -1
  13. data/examples/CQL/Metamodel.cql +73 -53
  14. data/examples/CQL/MetamodelNext.cql +89 -67
  15. data/examples/CQL/OneToOnes.cql +2 -2
  16. data/examples/CQL/ServiceDirector.cql +10 -5
  17. data/examples/CQL/Supervision.cql +3 -3
  18. data/examples/CQL/Tests.Test5.Load.cql +1 -1
  19. data/examples/CQL/Warehousing.cql +4 -2
  20. data/lib/activefacts/cql/CQLParser.treetop +26 -60
  21. data/lib/activefacts/cql/Context.treetop +12 -2
  22. data/lib/activefacts/cql/Expressions.treetop +14 -30
  23. data/lib/activefacts/cql/FactTypes.treetop +165 -110
  24. data/lib/activefacts/cql/Language/English.treetop +167 -54
  25. data/lib/activefacts/cql/LexicalRules.treetop +16 -2
  26. data/lib/activefacts/cql/{Concepts.treetop → ObjectTypes.treetop} +36 -37
  27. data/lib/activefacts/cql/Terms.treetop +57 -27
  28. data/lib/activefacts/cql/ValueTypes.treetop +39 -13
  29. data/lib/activefacts/cql/compiler.rb +5 -3
  30. data/lib/activefacts/cql/compiler/{reading.rb → clause.rb} +407 -285
  31. data/lib/activefacts/cql/compiler/constraint.rb +178 -275
  32. data/lib/activefacts/cql/compiler/entity_type.rb +73 -64
  33. data/lib/activefacts/cql/compiler/expression.rb +418 -0
  34. data/lib/activefacts/cql/compiler/fact.rb +146 -145
  35. data/lib/activefacts/cql/compiler/fact_type.rb +197 -80
  36. data/lib/activefacts/cql/compiler/join.rb +159 -0
  37. data/lib/activefacts/cql/compiler/shared.rb +51 -23
  38. data/lib/activefacts/cql/compiler/value_type.rb +56 -2
  39. data/lib/activefacts/cql/parser.rb +15 -4
  40. data/lib/activefacts/generate/absorption.rb +7 -7
  41. data/lib/activefacts/generate/cql.rb +100 -37
  42. data/lib/activefacts/generate/oo.rb +28 -51
  43. data/lib/activefacts/generate/ordered.rb +60 -36
  44. data/lib/activefacts/generate/ruby.rb +6 -6
  45. data/lib/activefacts/generate/sql/server.rb +4 -4
  46. data/lib/activefacts/input/orm.rb +71 -53
  47. data/lib/activefacts/persistence.rb +1 -1
  48. data/lib/activefacts/persistence/columns.rb +27 -23
  49. data/lib/activefacts/persistence/foreignkey.rb +6 -6
  50. data/lib/activefacts/persistence/index.rb +17 -17
  51. data/lib/activefacts/persistence/{concept.rb → object_type.rb} +9 -9
  52. data/lib/activefacts/persistence/reference.rb +61 -36
  53. data/lib/activefacts/persistence/tables.rb +61 -59
  54. data/lib/activefacts/support.rb +54 -29
  55. data/lib/activefacts/version.rb +1 -1
  56. data/lib/activefacts/vocabulary/extensions.rb +99 -54
  57. data/lib/activefacts/vocabulary/metamodel.rb +43 -37
  58. data/lib/activefacts/vocabulary/verbaliser.rb +134 -109
  59. data/spec/absorption_spec.rb +8 -8
  60. data/spec/cql/comparison_spec.rb +91 -0
  61. data/spec/cql/contractions_spec.rb +251 -0
  62. data/spec/cql/entity_type_spec.rb +319 -0
  63. data/spec/cql/expressions_spec.rb +63 -0
  64. data/spec/cql/fact_type_matching_spec.rb +283 -0
  65. data/spec/cql/french_spec.rb +21 -0
  66. data/spec/cql/parser/bad_literals_spec.rb +86 -0
  67. data/spec/cql/parser/constraints_spec.rb +19 -0
  68. data/spec/cql/parser/entity_types_spec.rb +106 -0
  69. data/spec/cql/parser/expressions_spec.rb +179 -0
  70. data/spec/cql/parser/fact_types_spec.rb +41 -0
  71. data/spec/cql/parser/literals_spec.rb +312 -0
  72. data/spec/cql/parser/pragmas_spec.rb +89 -0
  73. data/spec/cql/parser/value_types_spec.rb +42 -0
  74. data/spec/cql/role_matching_spec.rb +147 -0
  75. data/spec/cql/samples_spec.rb +9 -9
  76. data/spec/cql_cql_spec.rb +1 -1
  77. data/spec/cql_dm_spec.rb +116 -0
  78. data/spec/cql_mysql_spec.rb +1 -1
  79. data/spec/cql_ruby_spec.rb +1 -1
  80. data/spec/cql_sql_spec.rb +3 -3
  81. data/spec/cql_symbol_tables_spec.rb +30 -30
  82. data/spec/cqldump_spec.rb +4 -4
  83. data/spec/helpers/array_matcher.rb +32 -27
  84. data/spec/helpers/diff_matcher.rb +6 -26
  85. data/spec/helpers/file_matcher.rb +41 -32
  86. data/spec/helpers/parse_to_ast_matcher.rb +76 -0
  87. data/spec/helpers/string_matcher.rb +32 -31
  88. data/spec/norma_cql_spec.rb +1 -1
  89. data/spec/norma_ruby_spec.rb +1 -1
  90. data/spec/norma_ruby_sql_spec.rb +1 -1
  91. data/spec/norma_sql_spec.rb +3 -1
  92. data/spec/norma_tables_spec.rb +1 -1
  93. data/spec/ruby_api_spec.rb +23 -0
  94. data/spec/spec_helper.rb +5 -4
  95. metadata +66 -66
  96. data/examples/CQL/OrienteeringER.cql +0 -58
  97. data/lib/activefacts/api.rb +0 -44
  98. data/lib/activefacts/api/concept.rb +0 -410
  99. data/lib/activefacts/api/constellation.rb +0 -128
  100. data/lib/activefacts/api/entity.rb +0 -256
  101. data/lib/activefacts/api/instance.rb +0 -60
  102. data/lib/activefacts/api/instance_index.rb +0 -80
  103. data/lib/activefacts/api/numeric.rb +0 -167
  104. data/lib/activefacts/api/role.rb +0 -80
  105. data/lib/activefacts/api/role_proxy.rb +0 -70
  106. data/lib/activefacts/api/role_values.rb +0 -117
  107. data/lib/activefacts/api/standard_types.rb +0 -87
  108. data/lib/activefacts/api/support.rb +0 -65
  109. data/lib/activefacts/api/value.rb +0 -135
  110. data/lib/activefacts/api/vocabulary.rb +0 -82
  111. data/spec/api/autocounter.rb +0 -82
  112. data/spec/api/constellation.rb +0 -130
  113. data/spec/api/entity_type.rb +0 -103
  114. data/spec/api/instance.rb +0 -461
  115. data/spec/api/roles.rb +0 -124
  116. data/spec/api/value_type.rb +0 -112
  117. data/spec/api_spec.rb +0 -13
  118. data/spec/cql/matching_spec.rb +0 -517
  119. data/spec/cql/unit_spec.rb +0 -394
  120. data/spec/spec.opts +0 -1
@@ -21,6 +21,7 @@ module ActiveFacts
21
21
  def value_type_end
22
22
  end
23
23
 
24
+ # Dump the roles for an object type (excluding the roles of a fact type which is objectified)
24
25
  def roles_dump(o)
25
26
  o.all_role.
26
27
  select{|role|
@@ -35,12 +36,14 @@ module ActiveFacts
35
36
  end
36
37
 
37
38
  def role_dump(role)
39
+ return if role.fact_type.entity_type
40
+
38
41
  fact_type = role.fact_type
39
42
  if fact_type.all_role.size == 1
40
- unary_dump(role, preferred_role_name(role)) unless fact_type.entity_type
41
- # REVISIT: If the objectified fact type has already been dumped, we'll get nothing.
43
+ unary_dump(role, preferred_role_name(role))
42
44
  return
43
45
  elsif fact_type.all_role.size != 2
46
+ # Shouldn't come here, except perhaps for an invalid model
44
47
  return # ternaries and higher are always objectified
45
48
  end
46
49
 
@@ -50,54 +53,28 @@ module ActiveFacts
50
53
  return
51
54
  end
52
55
 
53
- # Find any uniqueness constraint over this role:
54
- fact_constraints = @presence_constraints_by_fact[fact_type]
55
- #debug "Considering #{fact_constraints.size} fact constraints over fact role #{role.concept.name}"
56
- ucs = fact_constraints.select{|c| c.is_a?(ActiveFacts::Metamodel::PresenceConstraint) && c.max_frequency == 1 }
57
- # Emit "has_one/one_to_one..." only for functional roles here:
58
- #debug "Considering #{ucs.size} unique constraints over role #{role.concept.name}"
59
- unless ucs.find {|c|
60
- c.role_sequence.all_role_ref.map(&:role) == [role]
61
- }
62
- #debug "No uniqueness constraint found for #{role} in #{fact_type}"
63
- return
64
- end
56
+ return unless role.is_functional
57
+
58
+ other_role = fact_type.all_role.select{|r| r != role}[0]
59
+ other_role_name = preferred_role_name(other_role)
60
+ other_player = other_role.object_type
61
+
62
+ # It's a one_to_one if there's a uniqueness constraint on the other role:
63
+ one_to_one = other_role.is_functional
64
+ return if one_to_one &&
65
+ !@object_types_dumped[other_role.object_type]
65
66
 
66
- if fact_type.entity_type
67
- # other_role is a phantom played by the entity type that objectifies this fact type.
68
- # REVISIT: No rolename can be provided for the phantom role, so _as_XYZ doesn't occur
69
- other_player = fact_type.entity_type
70
- return unless @concept_types_dumped[other_player]
71
-
72
- other_role_name = other_player.name.gsub(/ /,'_').snakecase
73
- other_role_method = role.concept.name.gsub(/ /,'_').snakecase
74
- one_to_one = true
75
- else
76
-
77
- other_role = fact_type.all_role.select{|r| r != role}[0]
78
- other_role_name = preferred_role_name(other_role)
79
- other_player = other_role.concept
80
-
81
- # It's a one_to_one if there's a uniqueness constraint on the other role:
82
- one_to_one = ucs.find {|c| c.role_sequence.all_role_ref.map(&:role) == [other_role] }
83
- if one_to_one &&
84
- !@concept_types_dumped[other_role.concept]
85
- #debug "Will dump 1:1 later for #{role} in #{fact_type}"
86
- return
87
- end
88
-
89
- # Find role name:
90
- role_method = preferred_role_name(role)
91
- other_role_method = one_to_one ? role_method : "all_"+role_method
92
- # puts "---"+role.role_name if role.role_name
93
- if other_role_name != other_player.name.gsub(/ /,'_').snakecase and
94
- role_method == role.concept.name.gsub(/ /,'_').snakecase
95
- other_role_method += "_as_#{other_role_name}"
96
- end
67
+ # Find role name:
68
+ role_method = preferred_role_name(role)
69
+ other_role_method = one_to_one ? role_method : "all_"+role_method
70
+ # puts "---"+role.role_name if role.role_name
71
+ if other_role_name != other_player.name.gsub(/ /,'_').snakecase and
72
+ role_method == role.object_type.name.gsub(/ /,'_').snakecase
73
+ other_role_method += "_as_#{other_role_name}"
97
74
  end
98
75
 
99
76
  role_name = role_method
100
- role_name = nil if role_name == role.concept.name.gsub(/ /,'_').snakecase
77
+ role_name = nil if role_name == role.object_type.name.gsub(/ /,'_').snakecase
101
78
 
102
79
  binary_dump(role, other_role_name, other_player, role.is_mandatory, one_to_one, nil, role_name, other_role_method)
103
80
  end
@@ -106,7 +83,7 @@ module ActiveFacts
106
83
  return "" if role.fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
107
84
 
108
85
  if is_for && role.fact_type.entity_type == is_for && role.fact_type.all_role.size == 1
109
- return role.concept.name.gsub(/[- ]/,'_').snakecase
86
+ return role.object_type.name.gsub(/[- ]/,'_').snakecase
110
87
  end
111
88
 
112
89
  # debug "Looking for preferred_role_name of #{describe_fact_type(role.fact_type, role)}"
@@ -121,7 +98,7 @@ module ActiveFacts
121
98
  reading.text.gsub(/ *\{0\} */,'').gsub(/[- ]/,'_').downcase
122
99
  end
123
100
 
124
- # debug "\tleading_adjective=#{(p=preferred_role_ref).leading_adjective}, role_name=#{role.role_name}, role player=#{role.concept.name}, trailing_adjective=#{p.trailing_adjective}"
101
+ # debug "\tleading_adjective=#{(p=preferred_role_ref).leading_adjective}, role_name=#{role.role_name}, role player=#{role.object_type.name}, trailing_adjective=#{p.trailing_adjective}"
125
102
  role_words = []
126
103
  role_name = role.role_name
127
104
  role_name = nil if role_name == ""
@@ -130,7 +107,7 @@ module ActiveFacts
130
107
  la = preferred_role_ref.leading_adjective
131
108
  role_words << la.gsub(/ /,'_') if la && la != "" and !role.role_name
132
109
 
133
- role_words << (role_name || role.concept.name.gsub(/ /,'_'))
110
+ role_words << (role_name || role.object_type.name.gsub(/ /,'_'))
134
111
  # REVISIT: Same when trailing_adjective is a suffix of the role_name
135
112
  ta = preferred_role_ref.trailing_adjective
136
113
  role_words << ta.gsub(/ /,'_') if ta && ta != "" and !role_name
@@ -157,12 +134,12 @@ module ActiveFacts
157
134
  pc.max_frequency == 1
158
135
  }
159
136
  }
160
- as = role_name != role.concept.name.gsub(/ /,'_').snakecase ? "_as_#{role_name}" : ""
137
+ as = role_name != role.object_type.name.gsub(/ /,'_').snakecase ? "_as_#{role_name}" : ""
161
138
  raise "Fact #{fact_type.describe} type is not objectified" unless fact_type.entity_type
162
139
  other_role_method = (one_to_one ? "" : "all_") +
163
140
  fact_type.entity_type.name.gsub(/ /,'_').snakecase +
164
141
  as
165
- binary_dump(role, role_name, role.concept, true, one_to_one, nil, nil, other_role_method)
142
+ binary_dump(role, role_name, role.object_type, true, one_to_one, nil, nil, other_role_method)
166
143
  }
167
144
  end
168
145
 
@@ -32,7 +32,7 @@ module ActiveFacts
32
32
  vocabulary_start(@vocabulary)
33
33
 
34
34
  build_indices
35
- @concept_types_dumped = {}
35
+ @object_types_dumped = {}
36
36
  @fact_types_dumped = {}
37
37
  units_dump()
38
38
  value_types_dump()
@@ -67,35 +67,46 @@ module ActiveFacts
67
67
  done_banner = false
68
68
  units = @vocabulary.all_unit.to_a.sort_by{|u| u.name.gsub(/ /,'')}
69
69
  while units.size > 0
70
- if !done_banner
71
- done_banner = true
72
- units_banner
73
- end
74
70
  i = 0
75
71
  while i < units.size
76
72
  unit = units[i]
77
73
  i += 1
74
+
78
75
  # Skip this one if the precursors haven't yet been dumped:
79
76
  next if unit.all_derivation_as_derived_unit.detect{|d| units.include?(d.base_unit) }
80
77
 
81
- unit_dump(unit)
78
+ # Even if we skip, we're done with this unit
82
79
  units.delete(unit)
83
80
  i -= 1
81
+
82
+ # Skip value-type derived units
83
+ next if unit.name =~ /\^/
84
+
85
+ # Don't dump fundamental units which have normal derived units, they are implied:
86
+ next if unit.is_fundamental &&
87
+ unit.all_derivation_as_base_unit.detect{|d| d.derived_unit.name !~ /\^/}
88
+
89
+ if !done_banner
90
+ done_banner = true
91
+ units_banner
92
+ end
93
+ unit_dump(unit)
84
94
  end
85
95
  end
96
+ units_end if done_banner
86
97
  end
87
98
 
88
99
  def value_types_dump
89
100
  done_banner = false
90
101
  @value_type_dumped = {}
91
- @vocabulary.all_concept.sort_by{|o| o.name.gsub(/ /,'')}.each{|o|
102
+ @vocabulary.all_object_type.sort_by{|o| o.name.gsub(/ /,'')}.each{|o|
92
103
  next unless o.is_a?(ActiveFacts::Metamodel::ValueType)
93
104
 
94
105
  value_type_banner unless done_banner
95
106
  done_banner = true
96
107
 
97
108
  value_type_chain_dump(o)
98
- @concept_types_dumped[o] = true
109
+ @object_types_dumped[o] = true
99
110
  }
100
111
  value_type_end if done_banner
101
112
  end
@@ -116,7 +127,7 @@ module ActiveFacts
116
127
  @precursors, @followers = *build_entity_dependencies
117
128
 
118
129
  done_banner = false
119
- sorted = @vocabulary.all_concept.select{|o|
130
+ sorted = @vocabulary.all_object_type.select{|o|
120
131
  o.is_a?(ActiveFacts::Metamodel::EntityType) # and !o.fact_type
121
132
  }.sort_by{|o| o.name.gsub(/ /,'')}
122
133
  panic = nil
@@ -124,7 +135,7 @@ module ActiveFacts
124
135
  count_this_pass = 0
125
136
  skipped_this_pass = 0
126
137
  sorted.each{|o|
127
- next if @concept_types_dumped[o] # Already done
138
+ next if @object_types_dumped[o] # Already done
128
139
 
129
140
  # Can we do this yet?
130
141
  if (o != panic and # We don't *have* to do it (panic mode)
@@ -160,7 +171,7 @@ module ActiveFacts
160
171
  if panic # We were already panicing... what to do now?
161
172
  # This won't happen again unless the above code is changed to decide it can't dump "panic".
162
173
  raise "Unresolvable cycle of forward references: " +
163
- (bad = sorted.select{|o| EntityType === o && !@concept_types_dumped[o]}).map{|o| o.name }.inspect +
174
+ (bad = sorted.select{|o| EntityType === o && !@object_types_dumped[o]}).map{|o| o.name }.inspect +
164
175
  ":\n\t" + bad.map{|o|
165
176
  o.name +
166
177
  ": " +
@@ -170,10 +181,10 @@ module ActiveFacts
170
181
  # Find the object that has the most followers and no fwd-ref'd supertypes:
171
182
  # This selection might be better if we allow PI roles to be fwd-ref'd...
172
183
  panic = sorted.
173
- select{|o| !@concept_types_dumped[o] }.
184
+ select{|o| !@object_types_dumped[o] }.
174
185
  sort_by{|o|
175
186
  f = @followers[o] || [];
176
- o.supertypes.detect{|s| !@concept_types_dumped[s] } ? 0 : -f.size
187
+ o.supertypes.detect{|s| !@object_types_dumped[s] } ? 0 : -f.size
177
188
  }[0]
178
189
  # debug "Panic mode, selected #{panic.name} next"
179
190
  end
@@ -185,7 +196,7 @@ module ActiveFacts
185
196
  end
186
197
 
187
198
  def entity_type_dump(o)
188
- @concept_types_dumped[o] = true
199
+ @object_types_dumped[o] = true
189
200
  pi = o.preferred_identifier
190
201
 
191
202
  supers = o.supertypes
@@ -210,7 +221,6 @@ module ActiveFacts
210
221
  identifying_facts = ([o.fact_type]+identifying_role_refs.map{|rr| rr.role.fact_type }).compact.uniq
211
222
 
212
223
  identification = identified_by_roles_and_facts(o, identifying_role_refs, identifying_facts)
213
- #identifying_facts.each{|f| @fact_types_dumped[f] = true }
214
224
 
215
225
  identification
216
226
  end
@@ -222,20 +232,20 @@ module ActiveFacts
222
232
 
223
233
  def describe_roles(roles, highlight = nil)
224
234
  "("+
225
- roles.map{|role| role.concept.name + (role == highlight ? "*" : "")}*", "+
235
+ roles.map{|role| role.object_type.name + (role == highlight ? "*" : "")}*", "+
226
236
  ")"
227
237
  end
228
238
 
229
239
  def describe_role_sequence(role_sequence)
230
240
  "("+
231
- role_sequence.all_role_ref.map{|role_ref| role_ref.role.concept.name }*", "+
241
+ role_sequence.all_role_ref.map{|role_ref| role_ref.role.object_type.name }*", "+
232
242
  ")"
233
243
  end
234
244
 
235
245
  # This returns an array of two hash tables each keyed by an EntityType.
236
246
  # The values of each hash entry are the precursors and followers (respectively) of that entity.
237
247
  def build_entity_dependencies
238
- @vocabulary.all_concept.inject([{},{}]) { |a, o|
248
+ @vocabulary.all_object_type.inject([{},{}]) { |a, o|
239
249
  if o.is_a?(ActiveFacts::Metamodel::EntityType)
240
250
  precursor = a[0]
241
251
  follower = a[1]
@@ -244,7 +254,7 @@ module ActiveFacts
244
254
  if pi
245
255
  pi.role_sequence.all_role_ref.each{|rr|
246
256
  role = rr.role
247
- player = role.concept
257
+ player = role.object_type
248
258
  # REVISIT: If we decide to emit value types on demand, need to remove this:
249
259
  next unless player.is_a?(ActiveFacts::Metamodel::EntityType)
250
260
  # player is a precursor of o
@@ -254,9 +264,9 @@ module ActiveFacts
254
264
  end
255
265
  if o.fact_type
256
266
  o.fact_type.all_role.each do |role|
257
- next unless role.concept.is_a?(ActiveFacts::Metamodel::EntityType)
258
- (precursor[o] ||= []) << role.concept
259
- (follower[role.concept] ||= []) << o
267
+ next unless role.object_type.is_a?(ActiveFacts::Metamodel::EntityType)
268
+ (precursor[o] ||= []) << role.object_type
269
+ (follower[role.object_type] ||= []) << o
260
270
  end
261
271
  end
262
272
 
@@ -289,9 +299,10 @@ module ActiveFacts
289
299
  # The fact type hasn't already been dumped but all its role players have
290
300
  !@fact_types_dumped[fact_type] &&
291
301
  !fact_type.is_a?(ActiveFacts::Metamodel::ImplicitFactType) &&
292
- !fact_type.all_role.detect{|r| !@concept_types_dumped[r.concept] } &&
293
- !fact_type.entity_type
294
- # !(fact_type.entity_type && (p = @precursors[fact_type.entity_type]) && p.size > 0)
302
+ !fact_type.all_role.detect{|r| !@object_types_dumped[r.object_type] } &&
303
+ !fact_type.entity_type &&
304
+ derivation_precursors_complete(fact_type)
305
+ # REVISIT: A derived fact type must not be dumped before its joined fact types have
295
306
  }.sort_by{|fact_type|
296
307
  fact_type_key(fact_type)
297
308
  }.each{|fact_type|
@@ -303,12 +314,22 @@ module ActiveFacts
303
314
  end while progress
304
315
  end
305
316
 
317
+ def derivation_precursors_complete(fact_type)
318
+ pr = fact_type.preferred_reading
319
+ return true unless jr = pr.role_sequence.all_role_ref.to_a[0].join_role
320
+ join = jr.join_node.join
321
+ return false if join.all_join_step.detect{|js| !@fact_types_dumped[js.fact_type] }
322
+ return false if join.all_join_node.detect{|jn| !@object_types_dumped[jn.object_type] }
323
+ true
324
+ end
325
+
306
326
  def skip_fact_type(f)
307
327
  # REVISIT: There might be constraints we have to merge into the nested entity or subtype.
308
328
  # These will come up as un-handled constraints:
309
329
  pcs = @presence_constraints_by_fact[f]
310
- f.is_a?(ActiveFacts::Metamodel::TypeInheritance) ||
311
- (pcs && pcs.size > 0 && !pcs.detect{|c| !@constraints_used[c] })
330
+ return true if f.is_a?(ActiveFacts::Metamodel::TypeInheritance)
331
+ return false if f.entity_type && !@object_types_dumped[f.entity_type]
332
+ pcs && pcs.size > 0 && !pcs.detect{|c| !@constraints_used[c] }
312
333
  end
313
334
 
314
335
  # Dump one fact type.
@@ -341,7 +362,7 @@ module ActiveFacts
341
362
  # REVISIT: Go through the residual constraints and re-process appropriate readings to show them
342
363
 
343
364
  @fact_types_dumped[fact_type] = true
344
- @concept_types_dumped[fact_type.entity_type] = true if fact_type.entity_type
365
+ @object_types_dumped[fact_type.entity_type] = true if fact_type.entity_type
345
366
  end
346
367
 
347
368
  # Dump fact types.
@@ -360,7 +381,7 @@ module ActiveFacts
360
381
  !fact_type.is_a?(ActiveFacts::Metamodel::ImplicitFactType) and
361
382
  !@fact_types_dumped[fact_type] and
362
383
  !skip_fact_type(fact_type) and
363
- !fact_type.all_role.detect{|r| r.concept.is_a?(ActiveFacts::Metamodel::EntityType) }
384
+ !fact_type.all_role.detect{|r| r.object_type.is_a?(ActiveFacts::Metamodel::EntityType) }
364
385
  }.sort_by{|fact_id|
365
386
  fact_type = fact_collection[fact_id]
366
387
  fact_type_key(fact_type)
@@ -380,7 +401,7 @@ module ActiveFacts
380
401
  fact_type_key(fact_type)
381
402
  }.each{|fact_type|
382
403
  next if @fact_types_dumped[fact_type]
383
- # debug "Not dumped #{fact_type.verbalise}(#{fact_type.all_role.map{|r| r.concept.name}*", "})"
404
+ # debug "Not dumped #{fact_type.verbalise}(#{fact_type.all_role.map{|r| r.object_type.name}*", "})"
384
405
  fact_type_banner unless done_banner
385
406
  done_banner = true
386
407
  fact_type_dump_with_dependents(fact_type)
@@ -412,17 +433,17 @@ module ActiveFacts
412
433
  pr.role_sequence.
413
434
  all_role_ref.
414
435
  sort_by{|role_ref| role_ref.ordinal}.
415
- map{|role_ref| [ role_ref.leading_adjective, role_ref.role.concept.name, role_ref.trailing_adjective ].compact*"-" } +
436
+ map{|role_ref| [ role_ref.leading_adjective, role_ref.role.object_type.name, role_ref.trailing_adjective ].compact*"-" } +
416
437
  [pr.text]
417
438
  else
418
- fact_type.all_role.map{|role| role.concept.name }
439
+ fact_type.all_role.map{|role| role.object_type.name }
419
440
  end
420
441
 
421
442
  (fact_type.entity_type ? [fact_type.entity_type.name] : [""]) + role_names
422
443
  end
423
444
 
424
445
  def role_ref_key(role_ref)
425
- [ role_ref.leading_adjective, role_ref.role.concept.name, role_ref.trailing_adjective ].compact*"-" +
446
+ [ role_ref.leading_adjective, role_ref.role.object_type.name, role_ref.trailing_adjective ].compact*"-" +
426
447
  " in " +
427
448
  role_ref.role.fact_type.preferred_reading.expand
428
449
  end
@@ -432,8 +453,8 @@ module ActiveFacts
432
453
  when ActiveFacts::Metamodel::RingConstraint
433
454
  [ 1,
434
455
  c.ring_type,
435
- c.role.concept.name,
436
- c.other_role.concept.name,
456
+ c.role.object_type.name,
457
+ c.other_role.object_type.name,
437
458
  c.name||""
438
459
  ]
439
460
  when ActiveFacts::Metamodel::SetExclusionConstraint
@@ -499,7 +520,7 @@ module ActiveFacts
499
520
 
500
521
  # Skip presence constraints on value types:
501
522
  # next if ActiveFacts::PresenceConstraint === c &&
502
- # ActiveFacts::ValueType === c.concept
523
+ # ActiveFacts::ValueType === c.object_type
503
524
  constraint_dump(c)
504
525
  end
505
526
  constraint_end if heading
@@ -516,6 +537,9 @@ module ActiveFacts
516
537
  def units_banner
517
538
  end
518
539
 
540
+ def units_end
541
+ end
542
+
519
543
  def unit_dump unit
520
544
  end
521
545
 
@@ -145,11 +145,11 @@ module ActiveFacts
145
145
 
146
146
  def binary_dump(role, role_name, role_player, mandatory = nil, one_to_one = nil, readings = nil, other_role_name = nil, other_method_name = nil)
147
147
  # Find whether we need the name of the other role player, and whether it's defined yet:
148
- if role_name.camelcase(true) == role_player.name.gsub(/ /,'').sub(/^[a-z]/) {|i| i.upcase}
148
+ if role_name.camelcase == role_player.name.gsub(/ /,'').sub(/^[a-z]/) {|i| i.upcase}
149
149
  # Don't use Class name if implied by rolename
150
150
  role_reference = nil
151
151
  else
152
- role_reference = ":class => "+concept_reference(role_player)
152
+ role_reference = ":class => "+object_type_reference(role_player)
153
153
  end
154
154
  other_role_name = ":counterpart => :"+other_role_name.gsub(/ /,'_') if other_role_name
155
155
 
@@ -167,11 +167,11 @@ module ActiveFacts
167
167
  #puts " \# REVISIT: #{other_role_name} has values restricted to #{role.role_value_constraint}\n" if role.role_value_constraint
168
168
  end
169
169
 
170
- def concept_reference concept
171
- if !@concept_types_dumped[concept]
172
- '"'+concept.name.gsub(/ /,'')+'"'
170
+ def object_type_reference object_type
171
+ if !@object_types_dumped[object_type]
172
+ '"'+object_type.name.gsub(/ /,'')+'"'
173
173
  else
174
- role_reference = concept.name.gsub(/ /,'')
174
+ role_reference = object_type.name.gsub(/ /,'')
175
175
  end
176
176
  end
177
177
 
@@ -134,7 +134,7 @@ module ActiveFacts
134
134
  delayed_foreign_keys = []
135
135
 
136
136
  @vocabulary.tables.each do |table|
137
- puts "CREATE TABLE #{escape table.name(@underscore).gsub(' ',@underscore)} ("
137
+ puts "CREATE TABLE #{escape table.name.gsub(' ',@underscore)} ("
138
138
 
139
139
  pk = table.identifier_columns
140
140
  identity_column = pk[0] if pk.size == 1 && pk[0].is_auto_assigned
@@ -178,7 +178,7 @@ module ActiveFacts
178
178
  table.foreign_keys.each do |fk|
179
179
  fk_text = "FOREIGN KEY (" +
180
180
  fk.from_columns.map{|column| column.name(@underscore)}*", " +
181
- ") REFERENCES #{escape fk.to.name(@underscore).gsub(' ',@underscore)} (" +
181
+ ") REFERENCES #{escape fk.to.name.gsub(' ',@underscore)} (" +
182
182
  fk.to_columns.map{|column| column.name(@underscore)}*", " +
183
183
  ")"
184
184
  if !@delay_fks and # We don't want to delay all Fks
@@ -186,7 +186,7 @@ module ActiveFacts
186
186
  fk.to == table && !fk.to_columns.detect{|column| !column.is_mandatory}) # The reference columns already have the required indexes
187
187
  inline_fks << fk_text
188
188
  else
189
- delayed_foreign_keys << ("ALTER TABLE #{escape fk.from.name(@underscore).gsub(' ',@underscore)}\n\tADD " + fk_text)
189
+ delayed_foreign_keys << ("ALTER TABLE #{escape fk.from.name.gsub(' ',@underscore)}\n\tADD " + fk_text)
190
190
  end
191
191
  end
192
192
 
@@ -204,7 +204,7 @@ module ActiveFacts
204
204
  view_name = escape "#{index.view_name}_#{abbreviated_column_names}"
205
205
  delayed_indices <<
206
206
  %Q{CREATE VIEW dbo.#{view_name} (#{column_name_list}) WITH SCHEMABINDING AS
207
- \tSELECT #{column_name_list} FROM dbo.#{escape index.on.name(@underscore).gsub(' ',@underscore)}
207
+ \tSELECT #{column_name_list} FROM dbo.#{escape index.on.name.gsub(' ',@underscore)}
208
208
  \tWHERE\t#{
209
209
  index.columns.
210
210
  select{|column| !column.is_mandatory }.