activefacts 1.6.0 → 1.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +21 -0
- data/README.md +60 -0
- data/Rakefile +3 -80
- data/activefacts.gemspec +36 -0
- data/bin/afgen +4 -2
- data/bin/cql +5 -1
- data/lib/activefacts.rb +3 -12
- data/lib/activefacts/{vocabulary/query_evaluator.rb → query/evaluator.rb} +0 -0
- data/lib/activefacts/version.rb +2 -2
- metadata +48 -296
- data/History.txt +0 -4
- data/LICENSE +0 -19
- data/Manifest.txt +0 -165
- data/README.rdoc +0 -81
- data/css/offline.css +0 -3
- data/css/orm2.css +0 -124
- data/css/print.css +0 -8
- data/css/style-print.css +0 -357
- data/css/style.css +0 -387
- data/download.html +0 -110
- data/examples/CQL/Address.cql +0 -44
- data/examples/CQL/Blog.cql +0 -54
- data/examples/CQL/CompanyDirectorEmployee.cql +0 -56
- data/examples/CQL/Death.cql +0 -17
- data/examples/CQL/Diplomacy.cql +0 -48
- data/examples/CQL/Genealogy.cql +0 -98
- data/examples/CQL/Insurance.cql +0 -320
- data/examples/CQL/Marriage.cql +0 -18
- data/examples/CQL/Metamodel.cql +0 -493
- data/examples/CQL/Monogamy.cql +0 -24
- data/examples/CQL/MultiInheritance.cql +0 -22
- data/examples/CQL/NonRoleId.cql +0 -14
- data/examples/CQL/OddIdentifier.cql +0 -18
- data/examples/CQL/OilSupply.cql +0 -53
- data/examples/CQL/OneToOnes.cql +0 -17
- data/examples/CQL/Orienteering.cql +0 -111
- data/examples/CQL/PersonPlaysGame.cql +0 -18
- data/examples/CQL/RedundantDependency.cql +0 -34
- data/examples/CQL/SchoolActivities.cql +0 -33
- data/examples/CQL/SeparateSubtype.cql +0 -30
- data/examples/CQL/ServiceDirector.cql +0 -276
- data/examples/CQL/SimplestUnary.cql +0 -12
- data/examples/CQL/Supervision.cql +0 -34
- data/examples/CQL/WaiterTips.cql +0 -33
- data/examples/CQL/Warehousing.cql +0 -101
- data/examples/CQL/WindowInRoomInBldg.cql +0 -28
- data/examples/CQL/unit.cql +0 -474
- data/examples/index.html +0 -420
- data/examples/intro.html +0 -327
- data/examples/local.css +0 -24
- data/index.html +0 -111
- data/lib/activefacts/cql.rb +0 -35
- data/lib/activefacts/cql/CQLParser.treetop +0 -158
- data/lib/activefacts/cql/Context.treetop +0 -48
- data/lib/activefacts/cql/Expressions.treetop +0 -67
- data/lib/activefacts/cql/FactTypes.treetop +0 -358
- data/lib/activefacts/cql/Language/English.treetop +0 -315
- data/lib/activefacts/cql/LexicalRules.treetop +0 -253
- data/lib/activefacts/cql/ObjectTypes.treetop +0 -210
- data/lib/activefacts/cql/Rakefile +0 -14
- data/lib/activefacts/cql/Terms.treetop +0 -183
- data/lib/activefacts/cql/ValueTypes.treetop +0 -202
- data/lib/activefacts/cql/compiler.rb +0 -156
- data/lib/activefacts/cql/compiler/clause.rb +0 -1137
- data/lib/activefacts/cql/compiler/constraint.rb +0 -581
- data/lib/activefacts/cql/compiler/entity_type.rb +0 -457
- data/lib/activefacts/cql/compiler/expression.rb +0 -443
- data/lib/activefacts/cql/compiler/fact.rb +0 -390
- data/lib/activefacts/cql/compiler/fact_type.rb +0 -421
- data/lib/activefacts/cql/compiler/query.rb +0 -106
- data/lib/activefacts/cql/compiler/shared.rb +0 -161
- data/lib/activefacts/cql/compiler/value_type.rb +0 -174
- data/lib/activefacts/cql/nodes.rb +0 -49
- data/lib/activefacts/cql/parser.rb +0 -241
- data/lib/activefacts/dependency_analyser.rb +0 -182
- data/lib/activefacts/generate/absorption.rb +0 -70
- data/lib/activefacts/generate/composition.rb +0 -118
- data/lib/activefacts/generate/cql.rb +0 -714
- data/lib/activefacts/generate/dm.rb +0 -279
- data/lib/activefacts/generate/help.rb +0 -64
- data/lib/activefacts/generate/helpers/inject.rb +0 -16
- data/lib/activefacts/generate/helpers/oo.rb +0 -162
- data/lib/activefacts/generate/helpers/ordered.rb +0 -605
- data/lib/activefacts/generate/helpers/rails.rb +0 -57
- data/lib/activefacts/generate/html/glossary.rb +0 -461
- data/lib/activefacts/generate/json.rb +0 -337
- data/lib/activefacts/generate/null.rb +0 -32
- data/lib/activefacts/generate/rails/models.rb +0 -246
- data/lib/activefacts/generate/rails/schema.rb +0 -216
- data/lib/activefacts/generate/records.rb +0 -46
- data/lib/activefacts/generate/ruby.rb +0 -133
- data/lib/activefacts/generate/sql/mysql.rb +0 -280
- data/lib/activefacts/generate/sql/server.rb +0 -273
- data/lib/activefacts/generate/stats.rb +0 -69
- data/lib/activefacts/generate/text.rb +0 -27
- data/lib/activefacts/generate/topics.rb +0 -265
- data/lib/activefacts/generate/traits/datavault.rb +0 -241
- data/lib/activefacts/generate/traits/oo.rb +0 -73
- data/lib/activefacts/generate/traits/ordered.rb +0 -33
- data/lib/activefacts/generate/traits/ruby.rb +0 -210
- data/lib/activefacts/generate/transform/datavault.rb +0 -266
- data/lib/activefacts/generate/transform/surrogate.rb +0 -214
- data/lib/activefacts/generate/version.rb +0 -26
- data/lib/activefacts/input/cql.rb +0 -43
- data/lib/activefacts/input/orm.rb +0 -1636
- data/lib/activefacts/mapping/rails.rb +0 -132
- data/lib/activefacts/persistence.rb +0 -15
- data/lib/activefacts/persistence/columns.rb +0 -446
- data/lib/activefacts/persistence/foreignkey.rb +0 -187
- data/lib/activefacts/persistence/index.rb +0 -240
- data/lib/activefacts/persistence/object_type.rb +0 -198
- data/lib/activefacts/persistence/reference.rb +0 -434
- data/lib/activefacts/persistence/tables.rb +0 -380
- data/lib/activefacts/registry.rb +0 -11
- data/lib/activefacts/support.rb +0 -132
- data/lib/activefacts/vocabulary.rb +0 -9
- data/lib/activefacts/vocabulary/extensions.rb +0 -1348
- data/lib/activefacts/vocabulary/metamodel.rb +0 -570
- data/lib/activefacts/vocabulary/verbaliser.rb +0 -804
- data/script/txt2html +0 -71
- data/spec/absorption_spec.rb +0 -95
- data/spec/cql/comparison_spec.rb +0 -89
- data/spec/cql/context_spec.rb +0 -94
- data/spec/cql/contractions_spec.rb +0 -224
- data/spec/cql/deontic_spec.rb +0 -88
- data/spec/cql/entity_type_spec.rb +0 -320
- data/spec/cql/expressions_spec.rb +0 -66
- data/spec/cql/fact_type_matching_spec.rb +0 -338
- data/spec/cql/french_spec.rb +0 -21
- data/spec/cql/parser/bad_literals_spec.rb +0 -86
- data/spec/cql/parser/constraints_spec.rb +0 -19
- data/spec/cql/parser/entity_types_spec.rb +0 -106
- data/spec/cql/parser/expressions_spec.rb +0 -199
- data/spec/cql/parser/fact_types_spec.rb +0 -44
- data/spec/cql/parser/literals_spec.rb +0 -312
- data/spec/cql/parser/pragmas_spec.rb +0 -89
- data/spec/cql/parser/value_types_spec.rb +0 -42
- data/spec/cql/role_matching_spec.rb +0 -148
- data/spec/cql/samples_spec.rb +0 -244
- data/spec/cql_cql_spec.rb +0 -73
- data/spec/cql_dm_spec.rb +0 -136
- data/spec/cql_mysql_spec.rb +0 -69
- data/spec/cql_parse_spec.rb +0 -34
- data/spec/cql_ruby_spec.rb +0 -73
- data/spec/cql_sql_spec.rb +0 -72
- data/spec/cql_symbol_tables_spec.rb +0 -261
- data/spec/cqldump_spec.rb +0 -170
- data/spec/helpers/array_matcher.rb +0 -23
- data/spec/helpers/ctrl_c_support.rb +0 -52
- data/spec/helpers/diff_matcher.rb +0 -39
- data/spec/helpers/file_matcher.rb +0 -34
- data/spec/helpers/parse_to_ast_matcher.rb +0 -80
- data/spec/helpers/string_matcher.rb +0 -30
- data/spec/helpers/test_parser.rb +0 -15
- data/spec/norma_cql_spec.rb +0 -66
- data/spec/norma_ruby_spec.rb +0 -62
- data/spec/norma_ruby_sql_spec.rb +0 -107
- data/spec/norma_sql_spec.rb +0 -57
- data/spec/norma_tables_spec.rb +0 -95
- data/spec/ruby_api_spec.rb +0 -23
- data/spec/spec_helper.rb +0 -35
- data/spec/transform_surrogate_spec.rb +0 -59
- data/status.html +0 -138
- data/why.html +0 -60
@@ -1,279 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# ActiveFacts Generators.
|
3
|
-
# Generate Ruby code for Data Mapper from an ActiveFacts vocabulary.
|
4
|
-
#
|
5
|
-
# A testing strategy:
|
6
|
-
# Generate and load a set of models
|
7
|
-
# call DataMapper::finalize to check they're consistent
|
8
|
-
# call DataMapper::Spec.cleanup_models to delete them again
|
9
|
-
#
|
10
|
-
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
11
|
-
#
|
12
|
-
require 'activefacts/vocabulary'
|
13
|
-
require 'activefacts/persistence'
|
14
|
-
require 'activefacts/generate/helpers/oo'
|
15
|
-
|
16
|
-
module ActiveFacts
|
17
|
-
module Generate
|
18
|
-
class DM < Helpers::OO #:nodoc:
|
19
|
-
# Generate SQL for DataMapper for an ActiveFacts vocabulary.
|
20
|
-
# Invoke as
|
21
|
-
# afgen --dm[=options] <file>.cql
|
22
|
-
# Options:
|
23
|
-
# dir=<mixins directory>
|
24
|
-
# Example:
|
25
|
-
# afgen --dm=dir=app/mixins MyApp.cql
|
26
|
-
include Persistence
|
27
|
-
|
28
|
-
def initialize(vocabulary, *options)
|
29
|
-
@vocabulary = vocabulary
|
30
|
-
@vocabulary = @vocabulary.Vocabulary.values[0] if ActiveFacts::API::Constellation === @vocabulary
|
31
|
-
@mixins = options.grep(/^dir=/)[-1]
|
32
|
-
@mixins && @mixins.sub!(/^dir=/,'')
|
33
|
-
end
|
34
|
-
|
35
|
-
def puts s
|
36
|
-
@out.puts s
|
37
|
-
end
|
38
|
-
|
39
|
-
def model_file(name)
|
40
|
-
@mixins+'/'+name.gsub(/\s/,'')+'.rb'
|
41
|
-
end
|
42
|
-
|
43
|
-
def class_name(name)
|
44
|
-
name.gsub(/\s/,'')
|
45
|
-
end
|
46
|
-
|
47
|
-
def column_name(column)
|
48
|
-
column.name('_').snakecase
|
49
|
-
end
|
50
|
-
|
51
|
-
def symbol_name(name)
|
52
|
-
name.gsub(/\s/,'_').snakecase
|
53
|
-
end
|
54
|
-
|
55
|
-
def new_output(name)
|
56
|
-
return unless @mixins
|
57
|
-
@out.flush
|
58
|
-
@out = File.open(model_file(name), "w")
|
59
|
-
puts "require 'datamapper'\n\n"
|
60
|
-
end
|
61
|
-
|
62
|
-
def key_fields(ref, reverse = false)
|
63
|
-
# Compute and return child_key and parent_key if necessary
|
64
|
-
fk = ref.from.foreign_keys.detect{|k| k.jump_reference == ref}
|
65
|
-
unless fk
|
66
|
-
debugger
|
67
|
-
raise "foreign key not found for #{ref}"
|
68
|
-
end
|
69
|
-
child_key = fk.from_columns.map{|c| column_name(c)}
|
70
|
-
parent_key = fk.to_columns.map{|c| column_name(c)}
|
71
|
-
if child_key != parent_key
|
72
|
-
c, p = *(reverse ? ['parent', 'child'] : ['child', 'parent'])
|
73
|
-
", :#{c}_key => [:#{child_key*', :'}], :#{p}_key => [:#{parent_key*', :'}]"
|
74
|
-
else
|
75
|
-
''
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
public
|
80
|
-
|
81
|
-
def generate(out = $>) #:nodoc:
|
82
|
-
@out = out
|
83
|
-
|
84
|
-
# Calculate the relational absorption:
|
85
|
-
tables = @vocabulary.tables
|
86
|
-
|
87
|
-
# Figure out which ObjectType will be models (tables and their subtypes)
|
88
|
-
models =
|
89
|
-
@vocabulary.all_object_type.sort_by{|o| o.name}.select do |o|
|
90
|
-
next false if o.name =~ /_?ImplicitBooleanValueType/
|
91
|
-
o.is_table || (o.absorbed_via && o.absorbed_via.role_type == :supertype)
|
92
|
-
end
|
93
|
-
is_model = models.inject({}) { |h, m| h[m] = true; h }
|
94
|
-
|
95
|
-
puts "require 'dm-core'"
|
96
|
-
puts "require 'dm-constraints'"
|
97
|
-
puts "\n"
|
98
|
-
|
99
|
-
# Dump tables until all done, subtypes before supertypes:
|
100
|
-
until models.empty?
|
101
|
-
# Choose another object type that we can dump now:
|
102
|
-
o = models.detect do |o|
|
103
|
-
next true if o.is_table
|
104
|
-
next true if a = o.absorbed_via and a.role_type == :supertype and supertype = a.from and !models.include?(supertype)
|
105
|
-
false
|
106
|
-
end
|
107
|
-
models.delete(o)
|
108
|
-
|
109
|
-
supertype = (a = o.absorbed_via and a.role_type == :supertype) ? supertype = a.from : nil
|
110
|
-
if o.is_a?(ActiveFacts::Metamodel::EntityType)
|
111
|
-
if secondary_supertypes = o.supertypes-[supertype] and
|
112
|
-
secondary_supertypes.size > 0 and
|
113
|
-
secondary_supertypes.detect do |sst|
|
114
|
-
sst_ref_facts = sst.preferred_identifier.role_sequence.all_role_ref.map{|rr| rr.role.fact_type}.uniq
|
115
|
-
non_identifying_inheritable_references =
|
116
|
-
sst.references_from.reject do |ref|
|
117
|
-
sst_ref_facts.include?(ref.fact_type)
|
118
|
-
end
|
119
|
-
non_identifying_inheritable_references.size > 0
|
120
|
-
end
|
121
|
-
raise "Cannot map classes like #{o.name} with roles inherited from external supertypes (#{secondary_supertypes.map{|t|t.name}*", "})"
|
122
|
-
end
|
123
|
-
pi = o.preferred_identifier
|
124
|
-
identifying_role_refs = pi.role_sequence.all_role_ref.sort_by{|role_ref| role_ref.ordinal}
|
125
|
-
identifying_facts = ([o.fact_type]+identifying_role_refs.map{|rr| rr.role.fact_type }).compact.uniq
|
126
|
-
else
|
127
|
-
identifying_facts = []
|
128
|
-
end
|
129
|
-
|
130
|
-
# REVISIT: STI fails where the base class is absorbed into another table, like Incident in Insurance for example.
|
131
|
-
# In this case you get the subtype fields absorbed and should not get an STI model.
|
132
|
-
|
133
|
-
puts "class #{class_name(o.name)}#{supertype ? " < #{class_name(supertype.name)}" : ''}"
|
134
|
-
puts " include DataMapper::Resource\n\n" unless supertype
|
135
|
-
|
136
|
-
columns = o.columns
|
137
|
-
o.references_from.sort_by{|r| r.to_s}.each do |ref|
|
138
|
-
# A (set of) columns
|
139
|
-
if !columns
|
140
|
-
# absorbed subtypes didn't have columns populated
|
141
|
-
columns = o.all_columns({})
|
142
|
-
end
|
143
|
-
|
144
|
-
next if [:subtype, :supertype].include?(ref.role_type)
|
145
|
-
# debugger if ref_columns.detect{|c| [:subtype, :supertype].include?(c.references[0].role_type)}
|
146
|
-
ref_columns = columns.select{|c| c.references[0] == ref }
|
147
|
-
# puts " \# #{ref.reading}:"
|
148
|
-
ref_columns.sort_by{|column| column_name(column)}.each do |column|
|
149
|
-
type, params, constraints = column.type
|
150
|
-
length = params[:length]
|
151
|
-
length &&= length.to_i
|
152
|
-
scale = params[:scale]
|
153
|
-
scale &&= scale.to_i
|
154
|
-
type, length = normalise_type(type, length)
|
155
|
-
key = identifying_facts.include?(column.references[0].fact_type) ||
|
156
|
-
(identifying_facts.empty? && ref.is_self_value)
|
157
|
-
cname = column_name(column)
|
158
|
-
required = column.is_mandatory && !key ? ", :required => true" : "" # Key fields are implicitly required
|
159
|
-
if type == 'Serial'
|
160
|
-
if !key || o.preferred_identifier.role_sequence.all_role_ref.size != 1
|
161
|
-
type = 'Integer'
|
162
|
-
else
|
163
|
-
key = false # This is implicit
|
164
|
-
end
|
165
|
-
end
|
166
|
-
$stderr.puts "Warning: non-mandatory key field #{o.name}.#{column.name} is forced to mandatory" if !column.is_mandatory && key
|
167
|
-
puts " property :#{column_name(column)}, #{type}#{length ? ", :length => "+length.to_s : ''}#{required}#{key ? ', :key => true' : ''}\t\# #{column.comment}"
|
168
|
-
end
|
169
|
-
|
170
|
-
if is_model[ref.to]
|
171
|
-
# An association
|
172
|
-
reverse = false
|
173
|
-
association_type =
|
174
|
-
case ref.role_type
|
175
|
-
when :one_one
|
176
|
-
reverse = true
|
177
|
-
"has 1,"
|
178
|
-
when :one_many, :many_one
|
179
|
-
"belongs_to"
|
180
|
-
when :supertype
|
181
|
-
next
|
182
|
-
when :subtype
|
183
|
-
next
|
184
|
-
else
|
185
|
-
raise "role type #{ref.role_type} not handled"
|
186
|
-
end
|
187
|
-
|
188
|
-
association_name = (ref.to_names*'_')
|
189
|
-
model_name = association_name != ref.to.name ? model_name = ", '#{class_name(ref.to.name)}'" : ''
|
190
|
-
comment = o.fact_type ? "#{association_name} is involved in #{o.name}" : ref.reading
|
191
|
-
keys = key_fields(ref, reverse)
|
192
|
-
puts " #{association_type} :#{association_name.downcase}#{model_name}#{keys}\t\# #{comment}"
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
# Emit the "has n," associations
|
197
|
-
# REVISIT: Need to use ActiveSupport to pluralise these names, or disable inflexion somehow.
|
198
|
-
o.references_to.sort_by{|r| [r.to_s, (r.from_role||r.to_role).ordinal] }.each do |ref|
|
199
|
-
next unless is_model[ref.from]
|
200
|
-
constraint = ''
|
201
|
-
association_type =
|
202
|
-
case ref.role_type
|
203
|
-
when :one_one
|
204
|
-
"has 1,"
|
205
|
-
when :many_one, :one_many
|
206
|
-
constraint = ', :constraint => :destroy' # REVISIT: Check mandatory, and use nullify?
|
207
|
-
"has n,"
|
208
|
-
else
|
209
|
-
next
|
210
|
-
end
|
211
|
-
prr = ref.fact_type.preferred_reading.role_sequence.all_role_ref.detect{|rr| rr.role == ref.to_role}
|
212
|
-
association_name = (ref.from_names*'_')
|
213
|
-
if prr && (prr.role.role_name || prr.leading_adjective || prr.trailing_adjective)
|
214
|
-
association_name += "_as_"+symbol_name(ref.to_names*'_')
|
215
|
-
end
|
216
|
-
model_name = association_name != ref.from.name ? model_name = ", '#{class_name(ref.from.name)}'" : ''
|
217
|
-
comment = o.is_a?(ActiveFacts::Metamodel::EntityType) && o.fact_type ? "#{association_name} is involved in #{o.name}" : ref.reading
|
218
|
-
keys = key_fields(ref)
|
219
|
-
|
220
|
-
puts " #{association_type} :#{association_name.downcase}#{model_name}#{keys}\t\# #{comment}"
|
221
|
-
end
|
222
|
-
puts "end\n\n"
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
|
227
|
-
# Return DataMapper type and (modified?) length for the passed base type
|
228
|
-
def normalise_type(type, length)
|
229
|
-
dm_type = case type
|
230
|
-
when /^Auto ?Counter$/
|
231
|
-
'Serial'
|
232
|
-
|
233
|
-
when /^Unsigned ?Integer$/,
|
234
|
-
/^Signed ?Integer$/,
|
235
|
-
/^Unsigned ?Small ?Integer$/,
|
236
|
-
/^Signed ?Small ?Integer$/,
|
237
|
-
/^Unsigned ?Tiny ?Integer$/
|
238
|
-
length = nil
|
239
|
-
'Integer'
|
240
|
-
|
241
|
-
when /^Decimal$/
|
242
|
-
'Decimal'
|
243
|
-
|
244
|
-
when /^Fixed ?Length ?Text$/, /^Char$/
|
245
|
-
'String'
|
246
|
-
when /^Variable ?Length ?Text$/, /^String$/
|
247
|
-
'String'
|
248
|
-
when /^Large ?Length ?Text$/, /^Text$/
|
249
|
-
'Text'
|
250
|
-
|
251
|
-
when /^Date ?And ?Time$/, /^Date ?Time$/
|
252
|
-
'DateTime'
|
253
|
-
when /^Date$/
|
254
|
-
'DateTime'
|
255
|
-
when /^Time$/
|
256
|
-
'DateTime'
|
257
|
-
when /^Auto ?Time ?Stamp$/
|
258
|
-
'DateTime'
|
259
|
-
|
260
|
-
when /^Money$/
|
261
|
-
'Decimal'
|
262
|
-
when /^Picture ?Raw ?Data$/, /^Image$/
|
263
|
-
'String'
|
264
|
-
when /^Variable ?Length ?Raw ?Data$/, /^Blob$/
|
265
|
-
'String'
|
266
|
-
when /^BIT$/
|
267
|
-
'Boolean'
|
268
|
-
else
|
269
|
-
# raise "DataMapper type unknown for standard type #{type}"
|
270
|
-
type
|
271
|
-
end
|
272
|
-
[dm_type, length]
|
273
|
-
end
|
274
|
-
|
275
|
-
end
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
ActiveFacts::Registry.generator('dm', ActiveFacts::Generate::DM)
|
@@ -1,64 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# ActiveFacts Generators.
|
3
|
-
# Provides help for afgen - from afgen --help
|
4
|
-
#
|
5
|
-
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
6
|
-
#
|
7
|
-
require 'activefacts/persistence'
|
8
|
-
|
9
|
-
module ActiveFacts
|
10
|
-
module Generate
|
11
|
-
# Generate nothing from an ActiveFacts vocabulary. This is useful to check the file can be read ok.
|
12
|
-
# Invoke as
|
13
|
-
# afgen --null <file>.cql
|
14
|
-
class HELP
|
15
|
-
private
|
16
|
-
def initialize(vocabulary, *options)
|
17
|
-
generators = $:.
|
18
|
-
map{|path|
|
19
|
-
Dir[path+"/activefacts/generate/**/*.rb"].
|
20
|
-
reject{|p|
|
21
|
-
p =~ %r{/(transform|helpers)/}
|
22
|
-
}.
|
23
|
-
map{|p|
|
24
|
-
p.sub(%r{.*/activefacts/generate/}, '').sub(/\.rb/,'')
|
25
|
-
}
|
26
|
-
}
|
27
|
-
transformers = $:.
|
28
|
-
map{|path|
|
29
|
-
Dir[path+"/activefacts/generate/transform/**/*.rb"].
|
30
|
-
map{|p|
|
31
|
-
p.sub(%r{.*/activefacts/generate/}, '').sub(/\.rb/,'')
|
32
|
-
}
|
33
|
-
}
|
34
|
-
|
35
|
-
puts %Q{
|
36
|
-
Usage: afgen [ --transformer[=options] ... ] [ --generator[=options] ... ] file.inp[=options]
|
37
|
-
options are comma-separated lists. Use =help to get more information.
|
38
|
-
|
39
|
-
Available generators are:
|
40
|
-
#{generators.flatten.uniq.sort.join("\n\t")
|
41
|
-
}
|
42
|
-
|
43
|
-
Available transformers are:
|
44
|
-
#{transformers.flatten.uniq.sort.join("\n\t")
|
45
|
-
}
|
46
|
-
|
47
|
-
inp is the name of a file input handler. Available input handlers are:
|
48
|
-
#{$:.map{|path|
|
49
|
-
Dir[path+"/activefacts/input/**.rb"].map{|p|
|
50
|
-
p.sub(%r{.*/}, '').sub(/\.rb/,'')
|
51
|
-
}
|
52
|
-
}.flatten.uniq.sort.join("\n\t")
|
53
|
-
}
|
54
|
-
}
|
55
|
-
end
|
56
|
-
|
57
|
-
public
|
58
|
-
def generate(out = $>)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
ActiveFacts::Registry.generator('help', ActiveFacts::Generate::HELP)
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require 'activefacts/vocabulary'
|
2
|
-
|
3
|
-
module ActiveFacts
|
4
|
-
module TraitInjector
|
5
|
-
def self.included other
|
6
|
-
overlap = Metamodel.constants & other.constants
|
7
|
-
overlap.each do |const|
|
8
|
-
mix_into = Metamodel.const_get(const)
|
9
|
-
mix_in = other.const_get(const)
|
10
|
-
mix_into.instance_exec {
|
11
|
-
include(mix_in)
|
12
|
-
}
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,162 +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
|
-
require 'activefacts/vocabulary'
|
8
|
-
require 'activefacts/generate/helpers/ordered'
|
9
|
-
require 'activefacts/generate/traits/oo'
|
10
|
-
|
11
|
-
module ActiveFacts
|
12
|
-
module Generate
|
13
|
-
|
14
|
-
module Helpers
|
15
|
-
# Base class for generators of object-oriented class libraries for an ActiveFacts vocabulary.
|
16
|
-
class OO < OrderedDumper #:nodoc:
|
17
|
-
def constraints_dump
|
18
|
-
# Stub, not needed.
|
19
|
-
end
|
20
|
-
|
21
|
-
def value_type_banner
|
22
|
-
end
|
23
|
-
|
24
|
-
def value_type_end
|
25
|
-
end
|
26
|
-
|
27
|
-
def entity_type_dump(o)
|
28
|
-
o.ordered_dumped!
|
29
|
-
pi = o.preferred_identifier
|
30
|
-
|
31
|
-
supers = o.supertypes
|
32
|
-
if (supers.size > 0)
|
33
|
-
# Ignore identification by a supertype:
|
34
|
-
pi = nil if pi && pi.role_sequence.all_role_ref.detect{|rr| rr.role.fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance) }
|
35
|
-
subtype_dump(o, supers, pi)
|
36
|
-
else
|
37
|
-
non_subtype_dump(o, pi)
|
38
|
-
end
|
39
|
-
pi.ordered_dumped! if pi
|
40
|
-
end
|
41
|
-
|
42
|
-
# Dump the roles for an object type (excluding the roles of a fact type which is objectified)
|
43
|
-
def roles_dump(o)
|
44
|
-
o.all_role.
|
45
|
-
select{|role|
|
46
|
-
role.fact_type.all_role.size <= 2 &&
|
47
|
-
!role.fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType)
|
48
|
-
}.
|
49
|
-
sort_by{|role|
|
50
|
-
other_role = role.fact_type.all_role.select{|r2| r2 != role}[0] || role
|
51
|
-
other_role.preferred_role_name(o) + ':' + role.preferred_role_name(other_role.object_type)
|
52
|
-
}.each{|role|
|
53
|
-
role_dump(role)
|
54
|
-
}
|
55
|
-
end
|
56
|
-
|
57
|
-
def role_dump(role)
|
58
|
-
fact_type = role.fact_type
|
59
|
-
if fact_type.all_role.size == 1
|
60
|
-
unary_dump(role, role.preferred_role_name)
|
61
|
-
return
|
62
|
-
end
|
63
|
-
return if role.fact_type.entity_type
|
64
|
-
|
65
|
-
if fact_type.all_role.size != 2
|
66
|
-
# Shouldn't come here, except perhaps for an invalid model
|
67
|
-
return # ternaries and higher are always objectified
|
68
|
-
end
|
69
|
-
|
70
|
-
# REVISIT: TypeInheritance
|
71
|
-
if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
|
72
|
-
# trace "Ignoring role #{role} in #{fact_type}, subtype fact type"
|
73
|
-
# REVISIT: What about secondary subtypes?
|
74
|
-
# REVISIT: What about dumping the relational mapping when using separate tables?
|
75
|
-
return
|
76
|
-
end
|
77
|
-
|
78
|
-
return unless role.is_functional
|
79
|
-
|
80
|
-
other_role = fact_type.all_role.select{|r| r != role}[0]
|
81
|
-
other_role_name = other_role.preferred_role_name
|
82
|
-
other_player = other_role.object_type
|
83
|
-
|
84
|
-
# It's a one_to_one if there's a uniqueness constraint on the other role:
|
85
|
-
one_to_one = other_role.is_functional
|
86
|
-
return if one_to_one &&
|
87
|
-
!other_role.object_type.ordered_dumped
|
88
|
-
|
89
|
-
# Find role name:
|
90
|
-
role_method = role.preferred_role_name
|
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.oo_default_role_name and
|
94
|
-
role_method == role.object_type.oo_default_role_name
|
95
|
-
# debugger
|
96
|
-
other_role_method += "_as_#{other_role_name}"
|
97
|
-
end
|
98
|
-
|
99
|
-
role_name = role_method
|
100
|
-
role_name = nil if role_name == role.object_type.oo_default_role_name
|
101
|
-
|
102
|
-
b = role.ruby_role_definition
|
103
|
-
puts b
|
104
|
-
|
105
|
-
# binary_dump(role, other_role_name, other_player, role.is_mandatory, one_to_one, nil, role_name, other_role_method)
|
106
|
-
end
|
107
|
-
|
108
|
-
def skip_fact_type(f)
|
109
|
-
# REVISIT: There might be constraints we have to merge into the nested entity or subtype. These will come up as un-handled constraints.
|
110
|
-
!f.entity_type ||
|
111
|
-
f.is_a?(ActiveFacts::Metamodel::TypeInheritance)
|
112
|
-
end
|
113
|
-
|
114
|
-
# An objectified fact type has internal roles that are always "has_one":
|
115
|
-
def fact_roles_dump(fact_type)
|
116
|
-
fact_type.all_role.sort_by{|role|
|
117
|
-
role.preferred_role_name(fact_type.entity_type)
|
118
|
-
}.each{|role|
|
119
|
-
role_name = role.preferred_role_name(fact_type.entity_type)
|
120
|
-
one_to_one = role.is_unique
|
121
|
-
as = role_name != role.object_type.oo_default_role_name ? "_as_#{role_name}" : ""
|
122
|
-
# debugger if as != ''
|
123
|
-
raise "Fact #{fact_type.describe} type is not objectified" unless fact_type.entity_type
|
124
|
-
other_role_method = (one_to_one ? "" : "all_") +
|
125
|
-
fact_type.entity_type.oo_default_role_name +
|
126
|
-
as
|
127
|
-
binary_dump(role, role_name, role.object_type, true, one_to_one, nil, nil, other_role_method)
|
128
|
-
}
|
129
|
-
end
|
130
|
-
|
131
|
-
def entity_type_banner
|
132
|
-
end
|
133
|
-
|
134
|
-
def entity_type_group_end
|
135
|
-
end
|
136
|
-
|
137
|
-
def append_ring_to_reading(reading, ring)
|
138
|
-
# REVISIT: trace "Should override append_ring_to_reading"
|
139
|
-
end
|
140
|
-
|
141
|
-
def fact_type_banner
|
142
|
-
end
|
143
|
-
|
144
|
-
def fact_type_end
|
145
|
-
end
|
146
|
-
|
147
|
-
def constraint_banner
|
148
|
-
# trace "Should override constraint_banner"
|
149
|
-
end
|
150
|
-
|
151
|
-
def constraint_end
|
152
|
-
# trace "Should override constraint_end"
|
153
|
-
end
|
154
|
-
|
155
|
-
def constraint_dump(c)
|
156
|
-
# trace "Should override constraint_dump"
|
157
|
-
end
|
158
|
-
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|