activefacts 1.6.0 → 1.7.1

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 (169) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +14 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +60 -0
  8. data/Rakefile +3 -80
  9. data/activefacts.gemspec +36 -0
  10. data/bin/afgen +4 -2
  11. data/bin/cql +5 -1
  12. data/lib/activefacts.rb +3 -12
  13. data/lib/activefacts/{vocabulary/query_evaluator.rb → query/evaluator.rb} +0 -0
  14. data/lib/activefacts/version.rb +2 -2
  15. metadata +48 -296
  16. data/History.txt +0 -4
  17. data/LICENSE +0 -19
  18. data/Manifest.txt +0 -165
  19. data/README.rdoc +0 -81
  20. data/css/offline.css +0 -3
  21. data/css/orm2.css +0 -124
  22. data/css/print.css +0 -8
  23. data/css/style-print.css +0 -357
  24. data/css/style.css +0 -387
  25. data/download.html +0 -110
  26. data/examples/CQL/Address.cql +0 -44
  27. data/examples/CQL/Blog.cql +0 -54
  28. data/examples/CQL/CompanyDirectorEmployee.cql +0 -56
  29. data/examples/CQL/Death.cql +0 -17
  30. data/examples/CQL/Diplomacy.cql +0 -48
  31. data/examples/CQL/Genealogy.cql +0 -98
  32. data/examples/CQL/Insurance.cql +0 -320
  33. data/examples/CQL/Marriage.cql +0 -18
  34. data/examples/CQL/Metamodel.cql +0 -493
  35. data/examples/CQL/Monogamy.cql +0 -24
  36. data/examples/CQL/MultiInheritance.cql +0 -22
  37. data/examples/CQL/NonRoleId.cql +0 -14
  38. data/examples/CQL/OddIdentifier.cql +0 -18
  39. data/examples/CQL/OilSupply.cql +0 -53
  40. data/examples/CQL/OneToOnes.cql +0 -17
  41. data/examples/CQL/Orienteering.cql +0 -111
  42. data/examples/CQL/PersonPlaysGame.cql +0 -18
  43. data/examples/CQL/RedundantDependency.cql +0 -34
  44. data/examples/CQL/SchoolActivities.cql +0 -33
  45. data/examples/CQL/SeparateSubtype.cql +0 -30
  46. data/examples/CQL/ServiceDirector.cql +0 -276
  47. data/examples/CQL/SimplestUnary.cql +0 -12
  48. data/examples/CQL/Supervision.cql +0 -34
  49. data/examples/CQL/WaiterTips.cql +0 -33
  50. data/examples/CQL/Warehousing.cql +0 -101
  51. data/examples/CQL/WindowInRoomInBldg.cql +0 -28
  52. data/examples/CQL/unit.cql +0 -474
  53. data/examples/index.html +0 -420
  54. data/examples/intro.html +0 -327
  55. data/examples/local.css +0 -24
  56. data/index.html +0 -111
  57. data/lib/activefacts/cql.rb +0 -35
  58. data/lib/activefacts/cql/CQLParser.treetop +0 -158
  59. data/lib/activefacts/cql/Context.treetop +0 -48
  60. data/lib/activefacts/cql/Expressions.treetop +0 -67
  61. data/lib/activefacts/cql/FactTypes.treetop +0 -358
  62. data/lib/activefacts/cql/Language/English.treetop +0 -315
  63. data/lib/activefacts/cql/LexicalRules.treetop +0 -253
  64. data/lib/activefacts/cql/ObjectTypes.treetop +0 -210
  65. data/lib/activefacts/cql/Rakefile +0 -14
  66. data/lib/activefacts/cql/Terms.treetop +0 -183
  67. data/lib/activefacts/cql/ValueTypes.treetop +0 -202
  68. data/lib/activefacts/cql/compiler.rb +0 -156
  69. data/lib/activefacts/cql/compiler/clause.rb +0 -1137
  70. data/lib/activefacts/cql/compiler/constraint.rb +0 -581
  71. data/lib/activefacts/cql/compiler/entity_type.rb +0 -457
  72. data/lib/activefacts/cql/compiler/expression.rb +0 -443
  73. data/lib/activefacts/cql/compiler/fact.rb +0 -390
  74. data/lib/activefacts/cql/compiler/fact_type.rb +0 -421
  75. data/lib/activefacts/cql/compiler/query.rb +0 -106
  76. data/lib/activefacts/cql/compiler/shared.rb +0 -161
  77. data/lib/activefacts/cql/compiler/value_type.rb +0 -174
  78. data/lib/activefacts/cql/nodes.rb +0 -49
  79. data/lib/activefacts/cql/parser.rb +0 -241
  80. data/lib/activefacts/dependency_analyser.rb +0 -182
  81. data/lib/activefacts/generate/absorption.rb +0 -70
  82. data/lib/activefacts/generate/composition.rb +0 -118
  83. data/lib/activefacts/generate/cql.rb +0 -714
  84. data/lib/activefacts/generate/dm.rb +0 -279
  85. data/lib/activefacts/generate/help.rb +0 -64
  86. data/lib/activefacts/generate/helpers/inject.rb +0 -16
  87. data/lib/activefacts/generate/helpers/oo.rb +0 -162
  88. data/lib/activefacts/generate/helpers/ordered.rb +0 -605
  89. data/lib/activefacts/generate/helpers/rails.rb +0 -57
  90. data/lib/activefacts/generate/html/glossary.rb +0 -461
  91. data/lib/activefacts/generate/json.rb +0 -337
  92. data/lib/activefacts/generate/null.rb +0 -32
  93. data/lib/activefacts/generate/rails/models.rb +0 -246
  94. data/lib/activefacts/generate/rails/schema.rb +0 -216
  95. data/lib/activefacts/generate/records.rb +0 -46
  96. data/lib/activefacts/generate/ruby.rb +0 -133
  97. data/lib/activefacts/generate/sql/mysql.rb +0 -280
  98. data/lib/activefacts/generate/sql/server.rb +0 -273
  99. data/lib/activefacts/generate/stats.rb +0 -69
  100. data/lib/activefacts/generate/text.rb +0 -27
  101. data/lib/activefacts/generate/topics.rb +0 -265
  102. data/lib/activefacts/generate/traits/datavault.rb +0 -241
  103. data/lib/activefacts/generate/traits/oo.rb +0 -73
  104. data/lib/activefacts/generate/traits/ordered.rb +0 -33
  105. data/lib/activefacts/generate/traits/ruby.rb +0 -210
  106. data/lib/activefacts/generate/transform/datavault.rb +0 -266
  107. data/lib/activefacts/generate/transform/surrogate.rb +0 -214
  108. data/lib/activefacts/generate/version.rb +0 -26
  109. data/lib/activefacts/input/cql.rb +0 -43
  110. data/lib/activefacts/input/orm.rb +0 -1636
  111. data/lib/activefacts/mapping/rails.rb +0 -132
  112. data/lib/activefacts/persistence.rb +0 -15
  113. data/lib/activefacts/persistence/columns.rb +0 -446
  114. data/lib/activefacts/persistence/foreignkey.rb +0 -187
  115. data/lib/activefacts/persistence/index.rb +0 -240
  116. data/lib/activefacts/persistence/object_type.rb +0 -198
  117. data/lib/activefacts/persistence/reference.rb +0 -434
  118. data/lib/activefacts/persistence/tables.rb +0 -380
  119. data/lib/activefacts/registry.rb +0 -11
  120. data/lib/activefacts/support.rb +0 -132
  121. data/lib/activefacts/vocabulary.rb +0 -9
  122. data/lib/activefacts/vocabulary/extensions.rb +0 -1348
  123. data/lib/activefacts/vocabulary/metamodel.rb +0 -570
  124. data/lib/activefacts/vocabulary/verbaliser.rb +0 -804
  125. data/script/txt2html +0 -71
  126. data/spec/absorption_spec.rb +0 -95
  127. data/spec/cql/comparison_spec.rb +0 -89
  128. data/spec/cql/context_spec.rb +0 -94
  129. data/spec/cql/contractions_spec.rb +0 -224
  130. data/spec/cql/deontic_spec.rb +0 -88
  131. data/spec/cql/entity_type_spec.rb +0 -320
  132. data/spec/cql/expressions_spec.rb +0 -66
  133. data/spec/cql/fact_type_matching_spec.rb +0 -338
  134. data/spec/cql/french_spec.rb +0 -21
  135. data/spec/cql/parser/bad_literals_spec.rb +0 -86
  136. data/spec/cql/parser/constraints_spec.rb +0 -19
  137. data/spec/cql/parser/entity_types_spec.rb +0 -106
  138. data/spec/cql/parser/expressions_spec.rb +0 -199
  139. data/spec/cql/parser/fact_types_spec.rb +0 -44
  140. data/spec/cql/parser/literals_spec.rb +0 -312
  141. data/spec/cql/parser/pragmas_spec.rb +0 -89
  142. data/spec/cql/parser/value_types_spec.rb +0 -42
  143. data/spec/cql/role_matching_spec.rb +0 -148
  144. data/spec/cql/samples_spec.rb +0 -244
  145. data/spec/cql_cql_spec.rb +0 -73
  146. data/spec/cql_dm_spec.rb +0 -136
  147. data/spec/cql_mysql_spec.rb +0 -69
  148. data/spec/cql_parse_spec.rb +0 -34
  149. data/spec/cql_ruby_spec.rb +0 -73
  150. data/spec/cql_sql_spec.rb +0 -72
  151. data/spec/cql_symbol_tables_spec.rb +0 -261
  152. data/spec/cqldump_spec.rb +0 -170
  153. data/spec/helpers/array_matcher.rb +0 -23
  154. data/spec/helpers/ctrl_c_support.rb +0 -52
  155. data/spec/helpers/diff_matcher.rb +0 -39
  156. data/spec/helpers/file_matcher.rb +0 -34
  157. data/spec/helpers/parse_to_ast_matcher.rb +0 -80
  158. data/spec/helpers/string_matcher.rb +0 -30
  159. data/spec/helpers/test_parser.rb +0 -15
  160. data/spec/norma_cql_spec.rb +0 -66
  161. data/spec/norma_ruby_spec.rb +0 -62
  162. data/spec/norma_ruby_sql_spec.rb +0 -107
  163. data/spec/norma_sql_spec.rb +0 -57
  164. data/spec/norma_tables_spec.rb +0 -95
  165. data/spec/ruby_api_spec.rb +0 -23
  166. data/spec/spec_helper.rb +0 -35
  167. data/spec/transform_surrogate_spec.rb +0 -59
  168. data/status.html +0 -138
  169. data/why.html +0 -60
@@ -1,241 +0,0 @@
1
- #
2
- # ActiveFacts Schema Transform
3
- # Transform a loaded ActiveFacts vocabulary to suit ActiveRecord
4
- #
5
- # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
6
- #
7
- require 'activefacts/generate/helpers/inject'
8
-
9
- module ActiveFacts
10
- module Generate
11
- module DataVaultTraits
12
-
13
- module ObjectType
14
-
15
- def dv_add_surrogate type_name = 'Auto Counter', suffix = 'ID'
16
- # Find or assert the surrogate value type
17
- auto_counter = vocabulary.valid_value_type_name(type_name) ||
18
- constellation.ValueType(:vocabulary => vocabulary, :name => type_name, :concept => :new)
19
-
20
- # Create a subtype to identify this entity type:
21
- vt_name = self.name + ' '+suffix
22
- my_id = @vocabulary.valid_value_type_name(vt_name) ||
23
- constellation.ValueType(:vocabulary => vocabulary, :name => vt_name, :concept => :new, :supertype => auto_counter)
24
-
25
- # Create a fact type
26
- identifying_fact_type = constellation.FactType(:concept => :new)
27
- my_role = constellation.Role(:concept => :new, :fact_type => identifying_fact_type, :ordinal => 0, :object_type => self)
28
- self.injected_surrogate_role = my_role
29
- id_role = constellation.Role(:concept => :new, :fact_type => identifying_fact_type, :ordinal => 1, :object_type => my_id)
30
-
31
- # Create a reading (which needs a RoleSequence)
32
- reading = constellation.Reading(
33
- :fact_type => identifying_fact_type,
34
- :ordinal => 0,
35
- :role_sequence => [:new],
36
- :text => "{0} has {1}"
37
- )
38
- constellation.RoleRef(:role_sequence => reading.role_sequence, :ordinal => 0, :role => my_role)
39
- constellation.RoleRef(:role_sequence => reading.role_sequence, :ordinal => 1, :role => id_role)
40
-
41
- # Create two uniqueness constraints for the one-to-one. Each needs a RoleSequence (two RoleRefs)
42
- one_id = constellation.PresenceConstraint(
43
- :concept => :new,
44
- :vocabulary => vocabulary,
45
- :name => self.name+'HasOne'+suffix,
46
- :role_sequence => [:new],
47
- :is_mandatory => true,
48
- :min_frequency => 1,
49
- :max_frequency => 1,
50
- :is_preferred_identifier => false
51
- )
52
- @constellation.RoleRef(:role_sequence => one_id.role_sequence, :ordinal => 0, :role => my_role)
53
-
54
- one_me = constellation.PresenceConstraint(
55
- :concept => :new,
56
- :vocabulary => vocabulary,
57
- :name => self.name+suffix+'IsOfOne'+self.name,
58
- :role_sequence => [:new],
59
- :is_mandatory => false,
60
- :min_frequency => 0,
61
- :max_frequency => 1,
62
- :is_preferred_identifier => true
63
- )
64
- @constellation.RoleRef(:role_sequence => one_me.role_sequence, :ordinal => 0, :role => id_role)
65
- end
66
- end
67
-
68
- module ValueType
69
- def dv_needs_surrogate
70
- !is_auto_assigned
71
- end
72
-
73
- def dv_inject_surrogate
74
- trace :transform_surrogate, "Adding surrogate ID to Value Type #{name}"
75
- add_surrogate('Auto Counter', 'ID')
76
- end
77
- end
78
-
79
- module EntityType
80
- def dv_identifying_refs_from
81
- pi = preferred_identifier
82
- rrs = pi.role_sequence.all_role_ref
83
-
84
- # REVISIT: This is actually a ref to us, not from
85
- # if absorbed_via
86
- # return [absorbed_via]
87
- # end
88
-
89
- rrs.map do |rr|
90
- r = references_from.detect{|ref| rr.role == ref.to_role }
91
- unless r
92
- debugger
93
- raise "failed to find #{name} identifying reference for #{rr.role.object_type.name} in #{references_from.inspect}"
94
- end
95
- r
96
- end
97
- end
98
-
99
- def dv_needs_surrogate
100
-
101
- # A recursive proc to replace any reference to an Entity Type by its identifying references:
102
- trace :transform_surrogate_expansion, "Expanding key for #{name}"
103
- substitute_identifying_refs = proc do |object|
104
- if ref = object.absorbed_via
105
- # This shouldn't be necessary, but see the absorbed_via comment above.
106
- absorbed_into = ref.from
107
- trace :transform_surrogate_expansion, "recursing to handle absorption of #{object.name} into #{absorbed_into.name}"
108
- [substitute_identifying_refs.call(absorbed_into)]
109
- else
110
- irf = object.dv_identifying_refs_from
111
- trace :transform_surrogate_expansion, "Iterating for #{object.name} over #{irf.inspect}" do
112
- irf.each_with_index do |ref, i|
113
- next if ref.is_unary
114
- next if ref.to_role.object_type.kind_of?(ActiveFacts::Metamodel::ValueType)
115
- recurse_to = ref.to_role.object_type
116
-
117
- trace :transform_surrogate_expansion, "#{i}: recursing to expand #{recurse_to.name} key in #{ref}" do
118
- irf[i] = substitute_identifying_refs.call(recurse_to)
119
- end
120
- end
121
- end
122
- irf
123
- end
124
- end
125
- irf = substitute_identifying_refs.call(self)
126
-
127
- trace :transform_surrogate, "Does #{name} need a surrogate? it's identified by #{irf.inspect}" do
128
-
129
- pk_fks = dv_identifying_refs_from.map do |ref|
130
- ref.to && ref.to.is_table ? ref.to : nil
131
- end
132
-
133
- irf.flatten!
134
-
135
- # Multi-part identifiers are only allowed if:
136
- # * each part is a foreign key (i.e. it's a join table),
137
- # * there are no other columns (that might require updating) and
138
- # * the object is not the target of a foreign key:
139
- if irf.size >= 2
140
- if pk_fks.include?(nil)
141
- trace :transform_surrogate, "#{self.name} needs a surrogate because its multi-part key contains a non-table"
142
- return true
143
- elsif references_to.size != 0
144
- trace :transform_surrogate, "#{self.name} is a join table between #{pk_fks.map(&:name).inspect} but is also an FK target"
145
- return true
146
- elsif (references_from-dv_identifying_refs_from).size > 0
147
- # There are other attributes to worry about
148
- return true
149
- else
150
- trace :transform_surrogate, "#{self.name} is a join table between #{pk_fks.map(&:name).inspect}"
151
- return false
152
- end
153
- return true
154
- end
155
-
156
- # Single-part key. It must be an Auto Counter, or we will add a surrogate
157
-
158
- identifying_type = irf[0].to
159
- if identifying_type.dv_needs_surrogate
160
- trace :transform_surrogate, "#{self.name} needs a surrogate because #{irf[0].to.name} is not an AutoCounter, but #{identifying_type.supertypes_transitive.map(&:name).inspect}"
161
- return true
162
- end
163
-
164
- false
165
- end
166
- end
167
-
168
- def dv_inject_surrogate
169
- trace :transform_surrogate, "Injecting a surrogate key into #{self.name}"
170
-
171
- # Disable the preferred identifier:
172
- pi = preferred_identifier
173
- trace :transform_surrogate, "pi for #{name} was '#{pi.describe}'"
174
- pi.is_preferred_identifier = false
175
- @preferred_identifier = nil # Kill the cache
176
-
177
- dv_add_surrogate
178
-
179
- trace :transform_surrogate, "pi for #{name} is now '#{preferred_identifier.describe}'"
180
- end
181
-
182
- def dv_add_surrogate type_name = 'Auto Counter', suffix = 'ID'
183
- # Find or assert the surrogate value type
184
- auto_counter = vocabulary.valid_value_type_name(type_name) ||
185
- constellation.ValueType(:vocabulary => vocabulary, :name => type_name, :concept => :new)
186
-
187
- # Create a subtype to identify this entity type:
188
- vt_name = self.name + ' '+suffix
189
- my_id = @vocabulary.valid_value_type_name(vt_name) ||
190
- constellation.ValueType(:vocabulary => vocabulary, :name => vt_name, :concept => :new, :supertype => auto_counter)
191
-
192
- # Create a fact type
193
- identifying_fact_type = constellation.FactType(:concept => :new)
194
- my_role = constellation.Role(:concept => :new, :fact_type => identifying_fact_type, :ordinal => 0, :object_type => self)
195
- @injected_surrogate_role = my_role
196
- id_role = constellation.Role(:concept => :new, :fact_type => identifying_fact_type, :ordinal => 1, :object_type => my_id)
197
-
198
- # Create a reading (which needs a RoleSequence)
199
- reading = constellation.Reading(
200
- :fact_type => identifying_fact_type,
201
- :ordinal => 0,
202
- :role_sequence => [:new],
203
- :text => "{0} has {1}"
204
- )
205
- constellation.RoleRef(:role_sequence => reading.role_sequence, :ordinal => 0, :role => my_role)
206
- constellation.RoleRef(:role_sequence => reading.role_sequence, :ordinal => 1, :role => id_role)
207
-
208
- # Create two uniqueness constraints for the one-to-one. Each needs a RoleSequence (two RoleRefs)
209
- one_id = constellation.PresenceConstraint(
210
- :concept => :new,
211
- :vocabulary => vocabulary,
212
- :name => self.name+'HasOne'+suffix,
213
- :role_sequence => [:new],
214
- :is_mandatory => true,
215
- :min_frequency => 1,
216
- :max_frequency => 1,
217
- :is_preferred_identifier => false
218
- )
219
- @constellation.RoleRef(:role_sequence => one_id.role_sequence, :ordinal => 0, :role => my_role)
220
-
221
- one_me = constellation.PresenceConstraint(
222
- :concept => :new,
223
- :vocabulary => vocabulary,
224
- :name => self.name+suffix+'IsOfOne'+self.name,
225
- :role_sequence => [:new],
226
- :is_mandatory => false,
227
- :min_frequency => 0,
228
- :max_frequency => 1,
229
- :is_preferred_identifier => true
230
- )
231
- @constellation.RoleRef(:role_sequence => one_me.role_sequence, :ordinal => 0, :role => id_role)
232
-
233
- return my_id
234
- end
235
-
236
- end
237
-
238
- include ActiveFacts::TraitInjector # Must be last in this module, after all submodules have been defined
239
- end
240
- end
241
- end
@@ -1,73 +0,0 @@
1
- #
2
- # ActiveFacts Generators.
3
- # Base class for generators of class libraries in any object-oriented language that supports the ActiveFacts API.
4
- #
5
- # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
6
- #
7
- module ActiveFacts
8
- module Generate
9
- module OOTraits
10
- module ObjectType
11
- # Map the ObjectType name to an OO class name
12
- def oo_type_name
13
- name.words.capcase
14
- end
15
-
16
- # Map the OO class name to a default role name
17
- def oo_default_role_name
18
- name.words.snakecase
19
- end
20
- end
21
-
22
- module Role
23
- def oo_role_definition
24
- return if fact_type.entity_type
25
-
26
- if fact_type.all_role.size == 1
27
- return " maybe :#{preferred_role_name}\n"
28
- elsif fact_type.all_role.size != 2
29
- # Shouldn't come here, except perhaps for an invalid model
30
- return # ternaries and higher are always objectified
31
- end
32
-
33
- # REVISIT: TypeInheritance
34
- if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
35
- # trace "Ignoring role #{self} in #{fact_type}, subtype fact type"
36
- # REVISIT: What about secondary subtypes?
37
- # REVISIT: What about dumping the relational mapping when using separate tables?
38
- return
39
- end
40
-
41
- return unless is_functional
42
-
43
- counterpart_role = fact_type.all_role.select{|r| r != self}[0]
44
- counterpart_type = counterpart_role.object_type
45
- counterpart_role_name = counterpart_role.preferred_role_name
46
- counterpart_type_default_role_name = counterpart_type.oo_default_role_name
47
-
48
- # It's a one_to_one if there's a uniqueness constraint on the other role:
49
- one_to_one = counterpart_role.is_functional
50
- return if one_to_one &&
51
- false # REVISIT: !@object_types_dumped[counterpart_role.object_type]
52
-
53
- # Find role name:
54
- role_method = preferred_role_name
55
- counterpart_role_method = one_to_one ? role_method : "all_"+role_method
56
- # puts "---"+role.role_name if role.role_name
57
- if counterpart_role_name != counterpart_type.oo_default_role_name and
58
- role_method == self.object_type.oo_default_role_name
59
- # debugger
60
- counterpart_role_method += "_as_#{counterpart_role_name}"
61
- end
62
-
63
- role_name = role_method
64
- role_name = nil if role_name == object_type.oo_default_role_name
65
-
66
- as_binary(counterpart_role_name, counterpart_type, is_mandatory, one_to_one, nil, role_name, counterpart_role_method)
67
- end
68
- end
69
-
70
- include ActiveFacts::TraitInjector # Must be last in this module, after all submodules have been defined
71
- end
72
- end
73
- end
@@ -1,33 +0,0 @@
1
- #
2
- # ActiveFacts Generators.
3
- # Generation support superclass that sequences entity types to avoid forward references.
4
- #
5
- # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
6
- #
7
- module ActiveFacts
8
- module Generate #:nodoc:
9
- module OrderedTraits
10
- module DumpedFlag
11
- attr_reader :ordered_dumped
12
-
13
- def ordered_dumped!
14
- @ordered_dumped = true
15
- end
16
- end
17
-
18
- module ObjectType
19
- include DumpedFlag
20
- end
21
-
22
- module FactType
23
- include DumpedFlag
24
- end
25
-
26
- module Constraint
27
- include DumpedFlag
28
- end
29
-
30
- include ActiveFacts::TraitInjector # Must be last in this module, after all submodules have been defined
31
- end
32
- end
33
- end
@@ -1,210 +0,0 @@
1
- #
2
- # ActiveFacts Generators.
3
- # Generate Ruby classes for the ActiveFacts API from an ActiveFacts vocabulary.
4
- #
5
- # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
6
- #
7
- module ActiveFacts
8
- module Generate
9
- module RubyTraits
10
- module Vocabulary
11
- def prelude
12
- if @mapping == 'sql'
13
- require 'activefacts/persistence'
14
- @tables = self.tables
15
- end
16
-
17
- "require 'activefacts/api'\n" +
18
- (@mapping == 'sql' ? "require 'activefacts/persistence'\n" : '') +
19
- "\nmodule ::#{self.name}\n\n"
20
- end
21
-
22
- def finale
23
- "end"
24
- end
25
- end
26
-
27
- module ObjectType
28
- def absorbed_roles
29
- all_role.
30
- select do |role|
31
- role.fact_type.all_role.size <= 2 &&
32
- !role.fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType)
33
- end.
34
- sort_by do |role|
35
- r = role.fact_type.all_role.select{|r2| r2 != role}[0] || role
36
- r.preferred_role_name(self) + ':' + role.preferred_role_name(r.object_type)
37
- end
38
- end
39
-
40
- # Map the ObjectType name to a Ruby class name
41
- def ruby_type_name
42
- oo_type_name
43
- end
44
-
45
- # Map the Ruby class name to a default role name
46
- def ruby_default_role_name
47
- oo_default_role_name
48
- end
49
-
50
-
51
- def ruby_type_reference
52
- if !ordered_dumped
53
- '"'+name.gsub(/ /,'')+'"'
54
- else
55
- role_reference = name.gsub(/ /,'')
56
- end
57
- end
58
- end
59
-
60
- module Role
61
- def preferred_role_name(is_for = nil, &name_builder)
62
-
63
- if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
64
- # Subtype and Supertype roles default to TitleCase names, and have no role_name to worry about:
65
- return (name_builder || proc {|names| names.titlecase}).call(object_type.name.words)
66
- end
67
-
68
- name_builder ||= proc {|names| names.map(&:downcase)*'_' } # Make snake_case by default
69
-
70
- # Handle an objectified unary role:
71
- if is_for && fact_type.entity_type == is_for && fact_type.all_role.size == 1
72
- return name_builder.call(object_type.name.words)
73
- end
74
-
75
- # trace "Looking for preferred_role_name of #{describe_fact_type(fact_type, self)}"
76
- reading = fact_type.preferred_reading
77
- preferred_role_ref = reading.role_sequence.all_role_ref.detect{|reading_rr|
78
- reading_rr.role == self
79
- }
80
-
81
- if fact_type.all_role.size == 1
82
- return name_builder.call(
83
- role_name ?
84
- role_name.snakewords :
85
- reading.text.gsub(/ *\{0\} */,' ').gsub(/[- ]+/,'_').words
86
- )
87
- end
88
-
89
- if role_name && role_name != ""
90
- role_words = [role_name]
91
- else
92
- role_words = []
93
-
94
- la = preferred_role_ref.leading_adjective
95
- role_words += la.words.snakewords if la && la != ""
96
-
97
- role_words += object_type.name.words.snakewords
98
-
99
- ta = preferred_role_ref.trailing_adjective
100
- role_words += ta.words.snakewords if ta && ta != ""
101
- end
102
-
103
- # n = role_words.map{|w| w.gsub(/([a-z])([A-Z]+)/,'\1_\2').downcase}*"_"
104
- n = role_words*'_'
105
- # trace "\tresult=#{n}"
106
- return name_builder.call(n.gsub(' ','_').split(/_/))
107
- end
108
-
109
- def as_binary(role_name, role_player, mandatory = nil, one_to_one = nil, readings = nil, other_role_name = nil, other_method_name = nil)
110
- ruby_role_name = ":"+role_name.words.snakecase
111
-
112
- # Find whether we need the name of the other role player, and whether it's defined yet:
113
- implied_role_name = role_player.name.gsub(/ /,'').sub(/^[a-z]/) {|i| i.upcase}
114
- if role_name.camelcase != implied_role_name
115
- # Only use Class name if it's not implied by the rolename
116
- role_reference = ":class => "+role_player.ruby_type_reference
117
- end
118
-
119
- other_role_name = ":counterpart => :"+other_role_name.gsub(/ /,'_') if other_role_name
120
-
121
- if vr = role_value_constraint
122
- value_restriction = ":restrict => #{vr}"
123
- end
124
-
125
- options = [
126
- ruby_role_name,
127
- role_reference,
128
- mandatory ? ":mandatory => true" : nil,
129
- readings,
130
- other_role_name,
131
- value_restriction
132
- ].compact
133
-
134
- debugger if ruby_role_name == 'astronomicalobject'
135
-
136
- line = " #{one_to_one ? "one_to_one" : "has_one" } #{options*', '} "
137
- if other_method_name
138
- line += " "*(48-line.length) if line.length < 48
139
- line += "\# See #{role_player.name.gsub(/ /,'')}.#{other_method_name}"
140
- end
141
- line+"\n"
142
- end
143
-
144
- def ruby_role_definition
145
- oo_role_definition
146
- end
147
- end
148
-
149
- module ValueType
150
- def ruby_definition
151
- return if name == "_ImplicitBooleanValueType"
152
-
153
- ruby_length = length && length > 0 ? ":length => #{length}" : nil
154
- ruby_scale = scale && scale > 0 ? ":scale => #{scale}" : nil
155
- params = [ruby_length,ruby_scale].compact * ", "
156
-
157
- base_type = supertype || self
158
- base_type_name = base_type.ruby_type_name
159
- ruby_name = ruby_type_name
160
- if base_type_name == ruby_name
161
- base_type_name = '::'+base_type_name
162
- end
163
-
164
- " class #{ruby_name} < #{base_type_name}\n" +
165
- " value_type #{params}\n" +
166
- #emit_mapping self if is_table
167
- (value_constraint ?
168
- " restrict #{value_constraint.all_allowed_range_sorted.map{|ar| ar.to_s}*", "}\n" :
169
- ""
170
- ) +
171
- (unit ?
172
- " \# REVISIT: #{ruby_name} is in units of #{unit.name}\n" :
173
- ""
174
- ) +
175
- absorbed_roles.map do |role|
176
- role.ruby_role_definition
177
- end.
178
- compact*"" +
179
- " end\n\n"
180
- end
181
- end
182
-
183
- module FactType
184
- # An objectified fact type has internal roles that are always "has_one":
185
- def fact_roles
186
- raise "Fact #{describe} type is not objectified" unless entity_type
187
- all_role.sort_by do |role|
188
- role.preferred_role_name(entity_type)
189
- end.
190
- map do |role|
191
- role_name = role.preferred_role_name(entity_type)
192
- one_to_one = role.all_role_ref.detect{|rr|
193
- rr.role_sequence.all_role_ref.size == 1 &&
194
- rr.role_sequence.all_presence_constraint.detect{|pc|
195
- pc.max_frequency == 1
196
- }
197
- }
198
- counterpart_role_method = (one_to_one ? "" : "all_") +
199
- entity_type.oo_default_role_name +
200
- (role_name != role.object_type.oo_default_role_name ? "_as_#{role_name}" : '')
201
- role.as_binary(role_name, role.object_type, true, one_to_one, nil, nil, counterpart_role_method)
202
- end.
203
- join('')
204
- end
205
- end
206
-
207
- include ActiveFacts::TraitInjector # Must be last in this module, after all submodules have been defined
208
- end
209
- end
210
- end