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.
- 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
|