masamune 0.11.5 → 0.11.6
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/lib/masamune/actions/data_flow.rb +17 -14
- data/lib/masamune/data_plan/builder.rb +1 -3
- data/lib/masamune/data_plan/engine.rb +0 -4
- data/lib/masamune/environment.rb +11 -3
- data/lib/masamune/helpers/postgres.rb +1 -1
- data/lib/masamune/thor.rb +12 -0
- data/lib/masamune/transform.rb +1 -0
- data/lib/masamune/transform/denormalize_table.psql.erb +39 -0
- data/lib/masamune/transform/denormalize_table.rb +71 -0
- data/lib/masamune/version.rb +1 -1
- data/spec/masamune/transform/denormalize_table_spec.rb +125 -0
- metadata +22 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16d125ee3baa02af550e3e1be25c02f2e01f3ffa
|
4
|
+
data.tar.gz: 0ed7d28ecc6daaf83699138ac0b4b1acdb8363f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07aa680b40ea443bc1d6609b03c57a988a7d519739db1ce7cbefef54e09f408920b7424e73815f4fb4c0b588a2adec984b35432c220cfdc08bb19bfb0a161879
|
7
|
+
data.tar.gz: 01794b4dca6b07019aa83976ca6e72620e4c8dd3cbb1ff13b59fbc9d941bf7d2cd7ad59c5d2ac009585702d30554d3990b927bbb2b8fc9bda4a9b4569f6d24de
|
@@ -57,6 +57,21 @@ module Masamune::Actions
|
|
57
57
|
Set.new File.read(value).split(/\s+/)
|
58
58
|
end
|
59
59
|
|
60
|
+
def execute(options = {})
|
61
|
+
raise Thor::RequiredArgumentMissingError, "No value provided for required options '--start' or '--at'" unless options[:start] || options[:at] || options[:sources] || options[:targets]
|
62
|
+
raise Thor::MalformattedArgumentError, "Cannot specify both option '--sources' and option '--targets'" if options[:sources] && options[:targets]
|
63
|
+
|
64
|
+
desired_sources = Masamune::DataPlan::Set.new current_command_name, parse_file_type(:sources)
|
65
|
+
desired_targets = Masamune::DataPlan::Set.new current_command_name, parse_file_type(:targets)
|
66
|
+
|
67
|
+
if start_time && stop_time
|
68
|
+
desired_targets.merge engine.targets_for_date_range(current_command_name, start_time, stop_time)
|
69
|
+
end
|
70
|
+
|
71
|
+
engine.prepare(current_command_name, options.merge(sources: desired_sources, targets: desired_targets))
|
72
|
+
engine.execute(current_command_name, options)
|
73
|
+
end
|
74
|
+
|
60
75
|
private
|
61
76
|
|
62
77
|
included do |base|
|
@@ -68,23 +83,11 @@ module Masamune::Actions
|
|
68
83
|
end
|
69
84
|
|
70
85
|
base.after_initialize(:final) do |thor, options|
|
71
|
-
# Only execute this block if DataPlan::Engine is not currently executing
|
72
|
-
next if thor.engine.executing?
|
73
86
|
thor.engine.environment = thor.environment
|
74
87
|
thor.engine.filesystem.environment = thor.environment
|
75
|
-
|
76
|
-
|
77
|
-
raise Thor::MalformattedArgumentError, "Cannot specify both option '--sources' and option '--targets'" if options[:sources] && options[:targets]
|
78
|
-
|
79
|
-
desired_sources = Masamune::DataPlan::Set.new thor.current_command_name, thor.parse_file_type(:sources)
|
80
|
-
desired_targets = Masamune::DataPlan::Set.new thor.current_command_name, thor.parse_file_type(:targets)
|
81
|
-
|
82
|
-
if thor.start_time && thor.stop_time
|
83
|
-
desired_targets.merge thor.engine.targets_for_date_range(thor.current_command_name, thor.start_time, thor.stop_time)
|
88
|
+
thor.environment.with_process_lock(:data_flow_after_initialize) do
|
89
|
+
thor.execute(options)
|
84
90
|
end
|
85
|
-
|
86
|
-
thor.engine.prepare(thor.current_command_name, options.merge(sources: desired_sources, targets: desired_targets))
|
87
|
-
thor.engine.execute(thor.current_command_name, options)
|
88
91
|
exit 0 if thor.top_level?
|
89
92
|
end if defined?(base.after_initialize)
|
90
93
|
end
|
@@ -58,9 +58,7 @@ class Masamune::DataPlan::Builder
|
|
58
58
|
|
59
59
|
def thor_command_wrapper
|
60
60
|
Proc.new do |engine, rule, _|
|
61
|
-
engine.environment.
|
62
|
-
engine.environment.parent.invoke(rule)
|
63
|
-
end
|
61
|
+
engine.environment.parent.invoke(rule)
|
64
62
|
end
|
65
63
|
end
|
66
64
|
end
|
@@ -141,10 +141,6 @@ class Masamune::DataPlan::Engine
|
|
141
141
|
clear!
|
142
142
|
end
|
143
143
|
|
144
|
-
def executing?
|
145
|
-
@current_depth > 0
|
146
|
-
end
|
147
|
-
|
148
144
|
def constrain_max_depth(rule)
|
149
145
|
@current_depth += 1
|
150
146
|
raise "Max depth of #{MAX_DEPTH} exceeded for rule '#{rule}'" if @current_depth > MAX_DEPTH
|
data/lib/masamune/environment.rb
CHANGED
@@ -53,16 +53,18 @@ module Masamune
|
|
53
53
|
@mutex ||= Mutex.new
|
54
54
|
end
|
55
55
|
|
56
|
-
def with_exclusive_lock(name, &block)
|
56
|
+
def with_exclusive_lock(name, options = {}, &block)
|
57
57
|
raise 'filesystem path :run_dir not defined' unless filesystem.has_path?(:run_dir)
|
58
58
|
lock_name = [name, configuration.lock].compact.join(':')
|
59
59
|
logger.debug("acquiring lock '#{lock_name}'")
|
60
60
|
lock_file = lock_file(lock_name)
|
61
|
-
|
61
|
+
lock_mode = File::LOCK_EX
|
62
|
+
lock_mode |= File::LOCK_NB if options[:non_blocking]
|
63
|
+
lock_status = lock_file.flock(lock_mode)
|
62
64
|
if lock_status == 0
|
63
65
|
yield if block_given?
|
64
66
|
else
|
65
|
-
logger.error "acquire lock attempt failed for '#{lock_name}'"
|
67
|
+
logger.error "acquire lock attempt failed for '#{lock_name}'" unless options[:non_blocking]
|
66
68
|
end
|
67
69
|
ensure
|
68
70
|
if lock_file
|
@@ -71,6 +73,12 @@ module Masamune
|
|
71
73
|
end
|
72
74
|
end
|
73
75
|
|
76
|
+
def with_process_lock(name)
|
77
|
+
with_exclusive_lock("#{name}_#{Process.pid}", non_blocking: true) do
|
78
|
+
yield
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
74
82
|
def log_file_template
|
75
83
|
@log_file_template || "#{Time.now.to_i}-#{$$}.log"
|
76
84
|
end
|
data/lib/masamune/thor.rb
CHANGED
@@ -160,6 +160,18 @@ module Masamune
|
|
160
160
|
def top_level?
|
161
161
|
self.current_command_name == ARGV.first
|
162
162
|
end
|
163
|
+
|
164
|
+
def invoke_command(command, *args)
|
165
|
+
environment.with_exclusive_lock(command.name, non_blocking: true) do
|
166
|
+
super
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def invoke(name = nil, *args)
|
171
|
+
environment.with_exclusive_lock(name, non_blocking: top_level?) do
|
172
|
+
super
|
173
|
+
end
|
174
|
+
end
|
163
175
|
end
|
164
176
|
|
165
177
|
private
|
data/lib/masamune/transform.rb
CHANGED
@@ -27,6 +27,7 @@ module Masamune
|
|
27
27
|
require 'masamune/transform/define_table'
|
28
28
|
require 'masamune/transform/define_event_view'
|
29
29
|
require 'masamune/transform/define_schema'
|
30
|
+
require 'masamune/transform/denormalize_table'
|
30
31
|
|
31
32
|
require 'masamune/transform/bulk_upsert'
|
32
33
|
require 'masamune/transform/insert_reference_values'
|
@@ -0,0 +1,39 @@
|
|
1
|
+
-- The MIT License (MIT)
|
2
|
+
--
|
3
|
+
-- Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
|
4
|
+
--
|
5
|
+
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
-- of this software and associated documentation files (the "Software"), to deal
|
7
|
+
-- in the Software without restriction, including without limitation the rights
|
8
|
+
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
-- copies of the Software, and to permit persons to whom the Software is
|
10
|
+
-- furnished to do so, subject to the following conditions:
|
11
|
+
--
|
12
|
+
-- The above copyright notice and this permission notice shall be included in
|
13
|
+
-- all copies or substantial portions of the Software.
|
14
|
+
--
|
15
|
+
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
-- THE SOFTWARE.
|
22
|
+
|
23
|
+
SELECT
|
24
|
+
<%- target.select_columns(columns).each do |column, last| -%>
|
25
|
+
<%= column %><%= ',' unless last %>
|
26
|
+
<%- end -%>
|
27
|
+
FROM
|
28
|
+
<%= target.name %>
|
29
|
+
<%- target.join_conditions(columns).each do |table, condition| -%>
|
30
|
+
JOIN
|
31
|
+
<%= table %>
|
32
|
+
ON
|
33
|
+
<%= condition %>
|
34
|
+
<%- end -%>
|
35
|
+
ORDER BY
|
36
|
+
<%- target.order_by_columns(columns).each do |column, last| -%>
|
37
|
+
<%= column %><%= ',' unless last %>
|
38
|
+
<%- end -%>
|
39
|
+
;
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# The MIT License (MIT)
|
2
|
+
#
|
3
|
+
# Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
module Masamune::Transform
|
24
|
+
module DenormalizeTable
|
25
|
+
extend ActiveSupport::Concern
|
26
|
+
|
27
|
+
def denormalize_table(target, columns = [])
|
28
|
+
Operator.new(__method__, target: target, columns: columns, presenters: { postgres: Postgres })
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
class Postgres < SimpleDelegator
|
34
|
+
include Masamune::LastElement
|
35
|
+
|
36
|
+
def select_columns(column_names)
|
37
|
+
column_names.map do |column_name|
|
38
|
+
next unless column = dereference_column_name(column_name)
|
39
|
+
if column.reference
|
40
|
+
"#{column.foreign_key_name} AS #{column.name}"
|
41
|
+
else
|
42
|
+
column.qualified_name
|
43
|
+
end
|
44
|
+
end.compact
|
45
|
+
end
|
46
|
+
method_with_last_element :select_columns
|
47
|
+
|
48
|
+
def join_conditions(column_names)
|
49
|
+
{}.tap do |conditions|
|
50
|
+
column_names.each do |column_name|
|
51
|
+
next unless column = dereference_column_name(column_name)
|
52
|
+
next unless column.reference
|
53
|
+
adjacent_reference = references[column.reference.id]
|
54
|
+
next unless adjacent_reference
|
55
|
+
adjacent_column = columns[adjacent_reference.foreign_key_name]
|
56
|
+
next unless adjacent_column
|
57
|
+
conditions[column.reference.name] = "#{column.reference.surrogate_key.qualified_name} = #{adjacent_column.qualified_name}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def order_by_columns(column_names)
|
63
|
+
column_names.map do |column_name|
|
64
|
+
next unless column = dereference_column_name(column_name)
|
65
|
+
column.name
|
66
|
+
end.compact
|
67
|
+
end
|
68
|
+
method_with_last_element :order_by_columns
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/masamune/version.rb
CHANGED
@@ -0,0 +1,125 @@
|
|
1
|
+
# The MIT License (MIT)
|
2
|
+
#
|
3
|
+
# Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'spec_helper'
|
24
|
+
|
25
|
+
describe Masamune::Transform::DenormalizeTable do
|
26
|
+
before do
|
27
|
+
catalog.schema :postgres do
|
28
|
+
dimension 'cluster', type: :mini do
|
29
|
+
column 'id', type: :sequence, surrogate_key: true, auto: true
|
30
|
+
column 'name', type: :string
|
31
|
+
|
32
|
+
row name: 'current_database()', attributes: {default: true}
|
33
|
+
end
|
34
|
+
|
35
|
+
dimension 'date', type: :date do
|
36
|
+
column 'date_id', type: :integer, unique: true, index: true, natural_key: true
|
37
|
+
end
|
38
|
+
|
39
|
+
dimension 'tenant', type: :two do
|
40
|
+
column 'tenant_id', type: :integer, index: true, natural_key: true
|
41
|
+
end
|
42
|
+
|
43
|
+
dimension 'user', type: :two do
|
44
|
+
column 'tenant_id', type: :integer, index: true, natural_key: true
|
45
|
+
column 'user_id', type: :integer, index: true, natural_key: true
|
46
|
+
end
|
47
|
+
|
48
|
+
dimension 'user_agent', type: :mini do
|
49
|
+
column 'name', type: :string, unique: true, index: 'shared'
|
50
|
+
column 'version', type: :string, unique: true, index: 'shared', default: 'Unknown'
|
51
|
+
column 'mobile', type: :boolean, unique: true, index: 'shared', default: false
|
52
|
+
column 'description', type: :string, null: true, ignore: true
|
53
|
+
end
|
54
|
+
|
55
|
+
fact 'visits', partition: 'y%Ym%m' do
|
56
|
+
references :cluster
|
57
|
+
references :date
|
58
|
+
references :tenant
|
59
|
+
references :user
|
60
|
+
references :user_agent
|
61
|
+
measure 'total', type: :integer
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
let(:target) { catalog.postgres.visits_fact }
|
67
|
+
let(:columns) do
|
68
|
+
[
|
69
|
+
'date.date_id',
|
70
|
+
'tenant.tenant_id',
|
71
|
+
'user.tenant_id',
|
72
|
+
'user.user_id',
|
73
|
+
'user_agent.name',
|
74
|
+
'user_agent.version',
|
75
|
+
'total',
|
76
|
+
'time_key'
|
77
|
+
]
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'with postgres fact' do
|
81
|
+
subject(:result) { transform.denormalize_table(target, columns).to_s }
|
82
|
+
|
83
|
+
it 'should eq render denormalize_table template' do
|
84
|
+
is_expected.to eq <<-EOS.strip_heredoc
|
85
|
+
SELECT
|
86
|
+
date_dimension.date_id AS date_dimension_date_id,
|
87
|
+
tenant_dimension.tenant_id AS tenant_dimension_tenant_id,
|
88
|
+
user_dimension.tenant_id AS user_dimension_tenant_id,
|
89
|
+
user_dimension.user_id AS user_dimension_user_id,
|
90
|
+
user_agent_type.name AS user_agent_type_name,
|
91
|
+
user_agent_type.version AS user_agent_type_version,
|
92
|
+
visits_fact.total,
|
93
|
+
visits_fact.time_key
|
94
|
+
FROM
|
95
|
+
visits_fact
|
96
|
+
JOIN
|
97
|
+
date_dimension
|
98
|
+
ON
|
99
|
+
date_dimension.id = visits_fact.date_dimension_id
|
100
|
+
JOIN
|
101
|
+
tenant_dimension
|
102
|
+
ON
|
103
|
+
tenant_dimension.id = visits_fact.tenant_dimension_id
|
104
|
+
JOIN
|
105
|
+
user_dimension
|
106
|
+
ON
|
107
|
+
user_dimension.id = visits_fact.user_dimension_id
|
108
|
+
JOIN
|
109
|
+
user_agent_type
|
110
|
+
ON
|
111
|
+
user_agent_type.id = visits_fact.user_agent_type_id
|
112
|
+
ORDER BY
|
113
|
+
date_dimension_date_id,
|
114
|
+
tenant_dimension_tenant_id,
|
115
|
+
user_dimension_tenant_id,
|
116
|
+
user_dimension_user_id,
|
117
|
+
user_agent_type_name,
|
118
|
+
user_agent_type_version,
|
119
|
+
total,
|
120
|
+
time_key
|
121
|
+
;
|
122
|
+
EOS
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: masamune
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Andrews
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -114,14 +114,28 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 0
|
117
|
+
version: '0'
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 0
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rb-readline
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: rake
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -264,6 +278,8 @@ files:
|
|
264
278
|
- lib/masamune/transform/define_table.psql.erb
|
265
279
|
- lib/masamune/transform/define_table.rb
|
266
280
|
- lib/masamune/transform/define_unique.psql.erb
|
281
|
+
- lib/masamune/transform/denormalize_table.psql.erb
|
282
|
+
- lib/masamune/transform/denormalize_table.rb
|
267
283
|
- lib/masamune/transform/insert_reference_values.psql.erb
|
268
284
|
- lib/masamune/transform/insert_reference_values.rb
|
269
285
|
- lib/masamune/transform/load_dimension.rb
|
@@ -339,6 +355,7 @@ files:
|
|
339
355
|
- spec/masamune/transform/define_table.dimension_spec.rb
|
340
356
|
- spec/masamune/transform/define_table.fact_spec.rb
|
341
357
|
- spec/masamune/transform/define_table.table_spec.rb
|
358
|
+
- spec/masamune/transform/denormalize_table_spec.rb
|
342
359
|
- spec/masamune/transform/insert_reference_values.dimension_spec.rb
|
343
360
|
- spec/masamune/transform/insert_reference_values.fact_spec.rb
|
344
361
|
- spec/masamune/transform/load_dimension_spec.rb
|
@@ -442,6 +459,7 @@ test_files:
|
|
442
459
|
- spec/masamune/transform/define_table.dimension_spec.rb
|
443
460
|
- spec/masamune/transform/define_table.fact_spec.rb
|
444
461
|
- spec/masamune/transform/define_table.table_spec.rb
|
462
|
+
- spec/masamune/transform/denormalize_table_spec.rb
|
445
463
|
- spec/masamune/transform/insert_reference_values.dimension_spec.rb
|
446
464
|
- spec/masamune/transform/insert_reference_values.fact_spec.rb
|
447
465
|
- spec/masamune/transform/load_dimension_spec.rb
|