activefacts-generators 1.8.3 → 1.9.0
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/activefacts-generators.gemspec +3 -3
- data/lib/activefacts/dependency_analyser.rb +80 -80
- data/lib/activefacts/generators/absorption.rb +1 -1
- data/lib/activefacts/generators/composition.rb +76 -76
- data/lib/activefacts/generators/cql.rb +73 -73
- data/lib/activefacts/generators/diagrams/json.rb +313 -313
- data/lib/activefacts/generators/help.rb +10 -10
- data/lib/activefacts/generators/helpers/inject.rb +5 -5
- data/lib/activefacts/generators/helpers/oo.rb +5 -5
- data/lib/activefacts/generators/helpers/ordered.rb +51 -51
- data/lib/activefacts/generators/html/glossary.rb +241 -241
- data/lib/activefacts/generators/metadata/json.rb +155 -155
- data/lib/activefacts/generators/ruby.rb +4 -4
- data/lib/activefacts/generators/scala.rb +48 -48
- data/lib/activefacts/generators/sql/server.rb +3 -3
- data/lib/activefacts/generators/stats.rb +37 -37
- data/lib/activefacts/generators/traits/datavault.rb +217 -217
- data/lib/activefacts/generators/traits/oo.rb +13 -13
- data/lib/activefacts/generators/traits/ordered.rb +8 -8
- data/lib/activefacts/generators/traits/ruby.rb +145 -145
- data/lib/activefacts/generators/traits/scala.rb +319 -319
- data/lib/activefacts/generators/transform/datavault.rb +282 -282
- metadata +6 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77fbb0671bf67f5f67b0336451403655fac4794e
|
4
|
+
data.tar.gz: 348bb0ec84c18b602abdf882d580840cf1527b31
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ffb7dbcb73660a6e9a6159c6de6b8be0840be93e8c08e1c7c161fb8454745bd7e07e7727198e785955eb5494ad531103f0044b42e7ff95b28d6c05e8f04aea4
|
7
|
+
data.tar.gz: e90f8fc9bed2cb3e6c92e658841661ae0ac154e303defb5decf30ac71ad2a71a1f0a71d798451f02dc27f1855224d24a3c1bce407f57101ddd50a36e03cd7feb
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "activefacts-generators"
|
7
|
-
spec.version = "1.
|
7
|
+
spec.version = "1.9.0"
|
8
8
|
spec.authors = ["Clifford Heath"]
|
9
9
|
spec.email = ["clifford.heath@gmail.com"]
|
10
10
|
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.add_development_dependency "rake", "~> 10.0"
|
21
21
|
spec.add_development_dependency "rspec", "~> 3.3"
|
22
22
|
|
23
|
-
spec.add_runtime_dependency "activefacts-metamodel", "~> 1", ">= 1.
|
23
|
+
spec.add_runtime_dependency "activefacts-metamodel", "~> 1", ">= 1.9.14"
|
24
24
|
spec.add_runtime_dependency "activefacts-rmap", "~> 1", ">= 1.8"
|
25
|
-
spec.add_runtime_dependency "activesupport", "~> 4
|
25
|
+
spec.add_runtime_dependency "activesupport", "~> 4"
|
26
26
|
end
|
@@ -8,32 +8,32 @@ module ActiveFacts
|
|
8
8
|
def analyse_precursors &block
|
9
9
|
@precursors = {}
|
10
10
|
@enumerable.each do |item|
|
11
|
-
|
11
|
+
@precursors[item] = block.call(item)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
15
|
def analyse_precursors_transitive
|
16
16
|
all_precursors = proc do |item|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
p = @precursors[item]
|
18
|
+
all =
|
19
|
+
p + p.map do |precursor|
|
20
|
+
p.include?(precursor) ? [] : all_precursors.call(precursor)
|
21
|
+
end.flatten
|
22
|
+
all.uniq
|
23
|
+
end
|
24
24
|
|
25
25
|
@precursors_transitive = {}
|
26
26
|
@enumerable.each do |item|
|
27
|
-
|
27
|
+
@precursors_transitive[item] = all_precursors.call(item)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
def analyse_followers
|
32
32
|
@followers = Hash.new{|h, k| h[k] = [] }
|
33
33
|
@enumerable.each do |item|
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
@precursors[item].each do |precursor|
|
35
|
+
@followers[precursor] << item
|
36
|
+
end
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -44,11 +44,11 @@ module ActiveFacts
|
|
44
44
|
# A follower is an object with us as a precursor, that has no new precursors of its own
|
45
45
|
@chasers = {}
|
46
46
|
@enumerable.each do |item|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
@chasers[item] =
|
48
|
+
@enumerable.select do |follower|
|
49
|
+
@precursors[follower].include?(item) and
|
50
|
+
(@precursors_transitive[follower] - @precursors_transitive[item] - [item]).size == 0
|
51
|
+
end
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -57,93 +57,93 @@ module ActiveFacts
|
|
57
57
|
emitted = {}
|
58
58
|
pass = 0
|
59
59
|
until emitted.size == @enumerable.size
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
60
|
+
next_items = []
|
61
|
+
blocked =
|
62
|
+
@enumerable.inject({}) do |hash, item|
|
63
|
+
next hash if emitted[item]
|
64
|
+
blockers = item.precursors.select{|precursor| !emitted[precursor]}
|
65
|
+
if blockers.size > 0
|
66
|
+
hash[item] = blockers
|
67
|
+
else
|
68
|
+
next_items << item
|
69
|
+
end
|
70
|
+
hash
|
71
|
+
end
|
72
|
+
return blocked if next_items.size == 0 # Cannot make progress
|
73
|
+
# puts "PASS #{pass += 1}"
|
74
|
+
next_items.each do |item|
|
75
|
+
block.call(item)
|
76
|
+
emitted[item] = true
|
77
|
+
end
|
78
78
|
end
|
79
79
|
nil
|
80
80
|
end
|
81
81
|
|
82
82
|
def each &b
|
83
83
|
if block_given?
|
84
|
-
|
84
|
+
@enumerable.each { |item| yield item}
|
85
85
|
else
|
86
|
-
|
86
|
+
@enumerable
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
90
|
def precursors item = nil, &b
|
91
91
|
analyse_precursors unless @precursors
|
92
92
|
if item
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
93
|
+
if block_given?
|
94
|
+
Array(@precursors[item]).each { |precursor| yield precursor, item }
|
95
|
+
else
|
96
|
+
Array(@precursors[item])
|
97
|
+
end
|
98
98
|
else
|
99
|
-
|
100
|
-
|
101
|
-
|
99
|
+
@enumerable.each do |item|
|
100
|
+
precursors(item, &b)
|
101
|
+
end
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
105
|
def precursors_transitive item, &b
|
106
106
|
analyse_precursors_transitive unless @precursors_transitive
|
107
107
|
if item
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
108
|
+
if block_given?
|
109
|
+
Array(@precursors_transitive[item]).each { |precursor| yield precursor, item }
|
110
|
+
else
|
111
|
+
Array(@precursors_transitive[item])
|
112
|
+
end
|
113
113
|
else
|
114
|
-
|
115
|
-
|
116
|
-
|
114
|
+
@enumerable.each do |item|
|
115
|
+
precursors_transitive(item, &b)
|
116
|
+
end
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
120
|
def followers item = nil, &b
|
121
121
|
analyse_followers unless @followers
|
122
122
|
if item
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
123
|
+
if block_given?
|
124
|
+
Array(@followers[item]).each { |follower| yield follower, item }
|
125
|
+
else
|
126
|
+
Array(@followers[item])
|
127
|
+
end
|
128
128
|
else
|
129
|
-
|
130
|
-
|
131
|
-
|
129
|
+
@enumerable.each do |item|
|
130
|
+
followers(item, &b)
|
131
|
+
end
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
135
|
def chasers item, &b
|
136
136
|
analyse_chasers unless @chasers
|
137
137
|
if item
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
138
|
+
if block_given?
|
139
|
+
Array(@chasers[item]).each { |follower| yield follower, item }
|
140
|
+
else
|
141
|
+
Array(@chasers[item])
|
142
|
+
end
|
143
143
|
else
|
144
|
-
|
145
|
-
|
146
|
-
|
144
|
+
@enumerable.each do |item|
|
145
|
+
follower(item, &b)
|
146
|
+
end
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
@@ -155,23 +155,23 @@ module ActiveFacts
|
|
155
155
|
@total = 0
|
156
156
|
@rank = {}
|
157
157
|
@enumerable.each do |item|
|
158
|
-
|
159
|
-
|
158
|
+
@total +=
|
159
|
+
(@rank[item] = weight.call(item) * 1.0)
|
160
160
|
end
|
161
161
|
# Normalize:
|
162
162
|
@enumerable.each do |item|
|
163
|
-
|
163
|
+
@rank[item] /= @total
|
164
164
|
end
|
165
165
|
|
166
166
|
50.times do |iteration|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
167
|
+
@enumerable.each do |item|
|
168
|
+
links = (precursors(item) + followers(item)).uniq
|
169
|
+
linked_rank = links.map do |l|
|
170
|
+
onward_links = (precursors(l) + followers(l)).uniq || @enumerable.size
|
171
|
+
@rank[l] / onward_links.size
|
172
|
+
end.inject(&:+) || 0
|
173
|
+
@rank[item] = (1.0-damping) + damping*linked_rank
|
174
|
+
end
|
175
175
|
end
|
176
176
|
|
177
177
|
@rank
|
@@ -19,97 +19,97 @@ module ActiveFacts
|
|
19
19
|
include RMap
|
20
20
|
|
21
21
|
def initialize(vocabulary, *options)
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
@vocabulary = vocabulary
|
23
|
+
@vocabulary = @vocabulary.Vocabulary.values[0] if ActiveFacts::API::Constellation === @vocabulary
|
24
|
+
@underscore = options.include?("underscore") ? "_" : ""
|
25
25
|
end
|
26
26
|
|
27
27
|
def puts s
|
28
|
-
|
28
|
+
@out.puts s
|
29
29
|
end
|
30
30
|
|
31
31
|
public
|
32
32
|
def generate(out = $>) #:nodoc:
|
33
|
-
|
33
|
+
@out = out
|
34
34
|
|
35
|
-
|
35
|
+
tables_emitted = {}
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
puts "require '#{@vocabulary.name}'"
|
38
|
+
puts "require 'activefacts/composition'"
|
39
|
+
puts "\n#{@vocabulary.name}_ER = ActiveFacts::Composition.new(#{@vocabulary.name}) do"
|
40
|
+
@vocabulary.tables.each do |table|
|
41
|
+
puts " composite :\"#{table.name.gsub(' ',@underscore)}\" do"
|
42
42
|
|
43
|
-
|
44
|
-
|
43
|
+
pk = table.identifier_columns
|
44
|
+
identity_column = pk[0] if pk[0].is_auto_assigned
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
fk_refs = table.references_from.select{|ref| ref.is_simple_reference }
|
47
|
+
fk_columns = table.columns.select do |column|
|
48
|
+
column.references[0].is_simple_reference
|
49
|
+
end
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
51
|
+
columns =
|
52
|
+
table.columns.map do |column|
|
53
|
+
[column, column.references.map{|r| r.to_names }]
|
54
|
+
end.sort_by do |column, refnames|
|
55
|
+
refnames
|
56
|
+
end
|
57
|
+
previous_flattening = []
|
58
|
+
ref_prefix = []
|
59
|
+
columns.each do |column, refnames|
|
60
|
+
ref_prefix = column.references[0...previous_flattening.size]
|
61
|
+
# Pop back. Not a succinct algorithm, but easy to check
|
62
|
+
while previous_flattening.size > ref_prefix.size
|
63
|
+
previous_flattening.pop
|
64
|
+
puts ' '+' '*previous_flattening.size+"end\n"
|
65
|
+
end
|
66
|
+
while ref_prefix.size > 0 and previous_flattening != ref_prefix
|
67
|
+
previous_flattening.pop
|
68
|
+
ref_prefix.pop
|
69
|
+
puts ' '+' '*previous_flattening.size+"end\n"
|
70
|
+
end
|
71
|
+
loop do
|
72
|
+
ref = column.references[ref_prefix.size]
|
73
|
+
if ref.is_self_value
|
74
|
+
# REVISIT: I think these should be 'insert :value, :as => "XYZ"'
|
75
|
+
role_name = "value".snakecase
|
76
|
+
reading = "Intrinsic value of #{role_name}"
|
77
|
+
elsif ref.is_to_objectified_fact
|
78
|
+
# REVISIT: It's ugly to have to handle these special cases here
|
79
|
+
role_name = ref.to.name.words.snakecase
|
80
|
+
reading = ref.from_role.link_fact_type.default_reading
|
81
|
+
else
|
82
|
+
if ref.is_unary && ref.is_from_objectified_fact && ref != column.references.last
|
83
|
+
# Use the name of the objectification on the path to other absorbed fact types:
|
84
|
+
role_name = ref.to_role.fact_type.entity_type.name.words.snakecase
|
85
|
+
else
|
86
|
+
role_name = ref.to_role.preferred_role_name
|
87
|
+
end
|
88
|
+
# puts ">>>>> #{ref.inspect}: #{role_name} <<<<<<"
|
89
|
+
reading = ref.fact_type.default_reading
|
90
|
+
end
|
91
|
+
if ref == column.references.last
|
92
|
+
# REVISIT: Avoid the "as" here when the value is implied by the role_name:
|
93
|
+
puts ' '+' '*ref_prefix.size+"nest :#{role_name}, :as => \"#{column.name}\"\t\t# #{reading}"
|
94
|
+
break
|
95
|
+
else
|
96
|
+
puts ' '+' '*ref_prefix.size+"flatten :#{role_name} do\t\t# #{reading}"
|
97
|
+
ref_prefix.push ref
|
98
|
+
end
|
99
|
+
end
|
100
|
+
previous_flattening = ref_prefix
|
101
|
+
end
|
102
102
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
103
|
+
while previous_flattening.size > 0
|
104
|
+
previous_flattening.pop
|
105
|
+
puts ' '+' '*previous_flattening.size+"end\n"
|
106
|
+
end
|
107
|
+
puts " end\n\n"
|
108
108
|
|
109
|
-
|
109
|
+
tables_emitted[table] = true
|
110
110
|
|
111
|
-
|
112
|
-
|
111
|
+
end
|
112
|
+
puts "end\n"
|
113
113
|
end
|
114
114
|
|
115
115
|
end
|