activefacts-generators 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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +30 -0
- data/Rakefile +6 -0
- data/activefacts-generators.gemspec +26 -0
- data/lib/activefacts/dependency_analyser.rb +182 -0
- data/lib/activefacts/generators/absorption.rb +71 -0
- data/lib/activefacts/generators/composition.rb +119 -0
- data/lib/activefacts/generators/cql.rb +715 -0
- data/lib/activefacts/generators/diagrams/json.rb +340 -0
- data/lib/activefacts/generators/help.rb +64 -0
- data/lib/activefacts/generators/helpers/inject.rb +16 -0
- data/lib/activefacts/generators/helpers/oo.rb +162 -0
- data/lib/activefacts/generators/helpers/ordered.rb +605 -0
- data/lib/activefacts/generators/helpers/rails.rb +57 -0
- data/lib/activefacts/generators/html/glossary.rb +462 -0
- data/lib/activefacts/generators/metadata/json.rb +204 -0
- data/lib/activefacts/generators/null.rb +32 -0
- data/lib/activefacts/generators/rails/models.rb +247 -0
- data/lib/activefacts/generators/rails/schema.rb +217 -0
- data/lib/activefacts/generators/ruby.rb +134 -0
- data/lib/activefacts/generators/sql/mysql.rb +281 -0
- data/lib/activefacts/generators/sql/server.rb +274 -0
- data/lib/activefacts/generators/stats.rb +70 -0
- data/lib/activefacts/generators/text.rb +29 -0
- data/lib/activefacts/generators/traits/datavault.rb +241 -0
- data/lib/activefacts/generators/traits/oo.rb +73 -0
- data/lib/activefacts/generators/traits/ordered.rb +33 -0
- data/lib/activefacts/generators/traits/ruby.rb +210 -0
- data/lib/activefacts/generators/transform/datavault.rb +303 -0
- data/lib/activefacts/generators/transform/surrogate.rb +215 -0
- data/lib/activefacts/registry.rb +11 -0
- metadata +176 -0
@@ -0,0 +1,215 @@
|
|
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/metamodel'
|
8
|
+
require 'activefacts/rmap'
|
9
|
+
require 'activefacts/registry'
|
10
|
+
|
11
|
+
module ActiveFacts
|
12
|
+
module Metamodel
|
13
|
+
class ObjectType
|
14
|
+
|
15
|
+
def 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
|
+
@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
|
+
class ValueType
|
69
|
+
def needs_surrogate
|
70
|
+
!is_auto_assigned
|
71
|
+
end
|
72
|
+
|
73
|
+
def 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
|
+
class EntityType
|
80
|
+
def 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
|
+
raise "failed to find #{name} identifying reference for #{rr.role.object_type.name} in #{references_from.inspect}" unless r
|
92
|
+
r
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def needs_surrogate
|
97
|
+
|
98
|
+
# A recursive proc to replace any reference to an Entity Type by its identifying references:
|
99
|
+
trace :transform_surrogate_expansion, "Expanding key for #{name}"
|
100
|
+
substitute_identifying_refs = proc do |object|
|
101
|
+
if ref = object.absorbed_via
|
102
|
+
# This shouldn't be necessary, but see the absorbed_via comment above.
|
103
|
+
absorbed_into = ref.from
|
104
|
+
trace :transform_surrogate_expansion, "recursing to handle absorption of #{object.name} into #{absorbed_into.name}"
|
105
|
+
[substitute_identifying_refs.call(absorbed_into)]
|
106
|
+
else
|
107
|
+
irf = object.identifying_refs_from
|
108
|
+
trace :transform_surrogate_expansion, "Iterating for #{object.name} over #{irf.inspect}" do
|
109
|
+
irf.each_with_index do |ref, i|
|
110
|
+
next if ref.is_unary
|
111
|
+
next if ref.to_role.object_type.kind_of?(ActiveFacts::Metamodel::ValueType)
|
112
|
+
recurse_to = ref.to_role.object_type
|
113
|
+
|
114
|
+
trace :transform_surrogate_expansion, "#{i}: recursing to expand #{recurse_to.name} key in #{ref}" do
|
115
|
+
irf[i] = substitute_identifying_refs.call(recurse_to)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
irf
|
120
|
+
end
|
121
|
+
end
|
122
|
+
irf = substitute_identifying_refs.call(self)
|
123
|
+
|
124
|
+
trace :transform_surrogate, "Does #{name} need a surrogate? it's identified by #{irf.inspect}" do
|
125
|
+
|
126
|
+
pk_fks = identifying_refs_from.map do |ref|
|
127
|
+
ref.to && ref.to.is_table ? ref.to : nil
|
128
|
+
end
|
129
|
+
|
130
|
+
irf.flatten!
|
131
|
+
|
132
|
+
# Multi-part identifiers are only allowed if:
|
133
|
+
# * each part is a foreign key (i.e. it's a join table),
|
134
|
+
# * there are no other columns (that might require updating) and
|
135
|
+
# * the object is not the target of a foreign key:
|
136
|
+
if irf.size >= 2
|
137
|
+
if pk_fks.include?(nil)
|
138
|
+
trace :transform_surrogate, "#{self.name} needs a surrogate because its multi-part key contains a non-table"
|
139
|
+
return true
|
140
|
+
elsif references_to.size != 0
|
141
|
+
trace :transform_surrogate, "#{self.name} is a join table between #{pk_fks.map(&:name).inspect} but is also an FK target"
|
142
|
+
return true
|
143
|
+
elsif (references_from-identifying_refs_from).size > 0
|
144
|
+
# There are other attributes to worry about
|
145
|
+
return true
|
146
|
+
else
|
147
|
+
trace :transform_surrogate, "#{self.name} is a join table between #{pk_fks.map(&:name).inspect}"
|
148
|
+
return false
|
149
|
+
end
|
150
|
+
return true
|
151
|
+
end
|
152
|
+
|
153
|
+
# Single-part key. It must be an Auto Counter, or we will add a surrogate
|
154
|
+
|
155
|
+
identifying_type = irf[0].to
|
156
|
+
if identifying_type.needs_surrogate
|
157
|
+
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}"
|
158
|
+
return true
|
159
|
+
end
|
160
|
+
|
161
|
+
false
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def inject_surrogate
|
166
|
+
trace :transform_surrogate, "Injecting a surrogate key into #{self.name}"
|
167
|
+
|
168
|
+
# Disable the preferred identifier:
|
169
|
+
pi = preferred_identifier
|
170
|
+
trace :transform_surrogate, "pi for #{name} was '#{pi.describe}'"
|
171
|
+
pi.is_preferred_identifier = false
|
172
|
+
@preferred_identifier = nil # Kill the cache
|
173
|
+
|
174
|
+
add_surrogate
|
175
|
+
|
176
|
+
trace :transform_surrogate, "pi for #{name} is now '#{preferred_identifier.describe}'"
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
module RMap
|
183
|
+
class Column
|
184
|
+
def is_injected_surrogate
|
185
|
+
references.size == 1 and
|
186
|
+
references[0].from_role == references[0].from.injected_surrogate_role
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
module Generators #:nodoc:
|
192
|
+
module Transform #:nodoc:
|
193
|
+
class Surrogate
|
194
|
+
def initialize(vocabulary, *options)
|
195
|
+
@vocabulary = vocabulary
|
196
|
+
end
|
197
|
+
|
198
|
+
def generate(out = $stdout)
|
199
|
+
@out = out
|
200
|
+
injections =
|
201
|
+
@vocabulary.tables.select do |table|
|
202
|
+
table.needs_surrogate
|
203
|
+
end
|
204
|
+
injections.each do |table|
|
205
|
+
table.inject_surrogate
|
206
|
+
end
|
207
|
+
|
208
|
+
@vocabulary.decide_tables
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
ActiveFacts::Registry.generator('transform/surrogate', ActiveFacts::Generators::Transform::Surrogate)
|
metadata
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: activefacts-generators
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.7.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Clifford Heath
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.10.a
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.10.a
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activefacts-metamodel
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.7.0
|
62
|
+
- - "~>"
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '1.7'
|
65
|
+
type: :runtime
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: 1.7.0
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '1.7'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: activefacts-rmap
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 1.7.0
|
82
|
+
- - "~>"
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '1.7'
|
85
|
+
type: :runtime
|
86
|
+
prerelease: false
|
87
|
+
version_requirements: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: 1.7.0
|
92
|
+
- - "~>"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '1.7'
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: activesupport
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
description: Code generators for the ActiveFacts Fact Modeling suite, including the
|
110
|
+
Constellation Query Language
|
111
|
+
email:
|
112
|
+
- clifford.heath@gmail.com
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- ".gitignore"
|
118
|
+
- ".rspec"
|
119
|
+
- ".travis.yml"
|
120
|
+
- Gemfile
|
121
|
+
- LICENSE.txt
|
122
|
+
- README.md
|
123
|
+
- Rakefile
|
124
|
+
- activefacts-generators.gemspec
|
125
|
+
- lib/activefacts/dependency_analyser.rb
|
126
|
+
- lib/activefacts/generators/absorption.rb
|
127
|
+
- lib/activefacts/generators/composition.rb
|
128
|
+
- lib/activefacts/generators/cql.rb
|
129
|
+
- lib/activefacts/generators/diagrams/json.rb
|
130
|
+
- lib/activefacts/generators/help.rb
|
131
|
+
- lib/activefacts/generators/helpers/inject.rb
|
132
|
+
- lib/activefacts/generators/helpers/oo.rb
|
133
|
+
- lib/activefacts/generators/helpers/ordered.rb
|
134
|
+
- lib/activefacts/generators/helpers/rails.rb
|
135
|
+
- lib/activefacts/generators/html/glossary.rb
|
136
|
+
- lib/activefacts/generators/metadata/json.rb
|
137
|
+
- lib/activefacts/generators/null.rb
|
138
|
+
- lib/activefacts/generators/rails/models.rb
|
139
|
+
- lib/activefacts/generators/rails/schema.rb
|
140
|
+
- lib/activefacts/generators/ruby.rb
|
141
|
+
- lib/activefacts/generators/sql/mysql.rb
|
142
|
+
- lib/activefacts/generators/sql/server.rb
|
143
|
+
- lib/activefacts/generators/stats.rb
|
144
|
+
- lib/activefacts/generators/text.rb
|
145
|
+
- lib/activefacts/generators/traits/datavault.rb
|
146
|
+
- lib/activefacts/generators/traits/oo.rb
|
147
|
+
- lib/activefacts/generators/traits/ordered.rb
|
148
|
+
- lib/activefacts/generators/traits/ruby.rb
|
149
|
+
- lib/activefacts/generators/transform/datavault.rb
|
150
|
+
- lib/activefacts/generators/transform/surrogate.rb
|
151
|
+
- lib/activefacts/registry.rb
|
152
|
+
homepage: http://github.com/cjheath/activefacts-generators
|
153
|
+
licenses:
|
154
|
+
- MIT
|
155
|
+
metadata: {}
|
156
|
+
post_install_message:
|
157
|
+
rdoc_options: []
|
158
|
+
require_paths:
|
159
|
+
- lib
|
160
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - ">="
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '0'
|
170
|
+
requirements: []
|
171
|
+
rubyforge_project:
|
172
|
+
rubygems_version: 2.2.2
|
173
|
+
signing_key:
|
174
|
+
specification_version: 4
|
175
|
+
summary: Code Generators for the ActiveFacts suite
|
176
|
+
test_files: []
|