activefacts 0.8.9 → 0.8.10

Sign up to get free protection for your applications and to get access to all the features.
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 }.