masamune 0.17.12 → 0.17.13
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/Rakefile +3 -3
- data/bin/masamune-aws-emr +1 -1
- data/bin/masamune-dump +1 -1
- data/bin/masamune-hive +1 -1
- data/bin/masamune-psql +1 -1
- data/bin/masamune-shell +1 -1
- data/lib/masamune.rb +1 -1
- data/lib/masamune/actions/aws_emr.rb +2 -2
- data/lib/masamune/actions/data_flow.rb +10 -10
- data/lib/masamune/actions/date_parse.rb +4 -6
- data/lib/masamune/actions/execute.rb +3 -3
- data/lib/masamune/actions/filesystem.rb +1 -1
- data/lib/masamune/actions/hadoop_filesystem.rb +2 -2
- data/lib/masamune/actions/hive.rb +5 -5
- data/lib/masamune/actions/invoke_parallel.rb +5 -5
- data/lib/masamune/actions/postgres.rb +6 -6
- data/lib/masamune/actions/postgres_admin.rb +1 -1
- data/lib/masamune/actions/s3cmd.rb +3 -3
- data/lib/masamune/actions/transform.rb +4 -4
- data/lib/masamune/after_initialize_callbacks.rb +4 -4
- data/lib/masamune/cached_filesystem.rb +7 -11
- data/lib/masamune/commands/aws_emr.rb +12 -12
- data/lib/masamune/commands/hadoop_filesystem.rb +8 -8
- data/lib/masamune/commands/hadoop_streaming.rb +16 -16
- data/lib/masamune/commands/hive.rb +31 -35
- data/lib/masamune/commands/postgres.rb +30 -32
- data/lib/masamune/commands/postgres_admin.rb +17 -16
- data/lib/masamune/commands/postgres_common.rb +1 -1
- data/lib/masamune/commands/retry_with_backoff.rb +19 -19
- data/lib/masamune/commands/s3cmd.rb +7 -7
- data/lib/masamune/commands/shell.rb +25 -38
- data/lib/masamune/configuration.rb +8 -9
- data/lib/masamune/data_plan/builder.rb +5 -5
- data/lib/masamune/data_plan/elem.rb +7 -7
- data/lib/masamune/data_plan/engine.rb +12 -15
- data/lib/masamune/data_plan/rule.rb +14 -12
- data/lib/masamune/data_plan/set.rb +13 -13
- data/lib/masamune/environment.rb +3 -3
- data/lib/masamune/filesystem.rb +29 -28
- data/lib/masamune/helpers/postgres.rb +8 -5
- data/lib/masamune/io.rb +2 -2
- data/lib/masamune/last_element.rb +3 -3
- data/lib/masamune/method_logger.rb +1 -1
- data/lib/masamune/schema/catalog.rb +9 -12
- data/lib/masamune/schema/column.rb +12 -10
- data/lib/masamune/schema/dimension.rb +5 -4
- data/lib/masamune/schema/fact.rb +2 -2
- data/lib/masamune/schema/map.rb +9 -13
- data/lib/masamune/schema/row.rb +3 -2
- data/lib/masamune/schema/store.rb +13 -14
- data/lib/masamune/schema/table.rb +24 -28
- data/lib/masamune/schema/table_reference.rb +7 -7
- data/lib/masamune/spec_helper.rb +1 -1
- data/lib/masamune/string_format.rb +1 -1
- data/lib/masamune/tasks/aws_emr_thor.rb +9 -9
- data/lib/masamune/tasks/dump_thor.rb +5 -5
- data/lib/masamune/tasks/hive_thor.rb +13 -13
- data/lib/masamune/tasks/postgres_thor.rb +8 -8
- data/lib/masamune/tasks/shell_thor.rb +3 -3
- data/lib/masamune/template.rb +4 -4
- data/lib/masamune/thor.rb +26 -25
- data/lib/masamune/transform/common/denormalize_table.rb +6 -6
- data/lib/masamune/transform/define_table.rb +1 -1
- data/lib/masamune/transform/hive/define_table.rb +0 -2
- data/lib/masamune/transform/insert_reference_values.rb +1 -1
- data/lib/masamune/transform/operator.rb +3 -2
- data/lib/masamune/transform/postgres/bulk_upsert.rb +0 -3
- data/lib/masamune/transform/postgres/deduplicate_dimension.rb +4 -6
- data/lib/masamune/transform/postgres/define_table.rb +2 -2
- data/lib/masamune/transform/postgres/insert_reference_values.rb +1 -4
- data/lib/masamune/transform/postgres/relabel_dimension.rb +1 -3
- data/lib/masamune/transform/postgres/rollup_fact.rb +3 -5
- data/lib/masamune/transform/postgres/snapshot_dimension.rb +1 -4
- data/lib/masamune/transform/postgres/stage_dimension.rb +8 -10
- data/lib/masamune/transform/postgres/stage_fact.rb +15 -14
- data/lib/masamune/version.rb +1 -1
- data/spec/masamune/actions/aws_emr_spec.rb +8 -8
- data/spec/masamune/actions/execute_spec.rb +6 -6
- data/spec/masamune/actions/hive_spec.rb +20 -15
- data/spec/masamune/actions/postgres_spec.rb +17 -10
- data/spec/masamune/after_initialization_callbacks_spec.rb +13 -7
- data/spec/masamune/commands/aws_emr_spec.rb +10 -10
- data/spec/masamune/commands/hadoop_filesystem_spec.rb +3 -3
- data/spec/masamune/commands/hadoop_streaming_spec.rb +4 -4
- data/spec/masamune/commands/hive_spec.rb +11 -11
- data/spec/masamune/commands/postgres_admin_spec.rb +9 -9
- data/spec/masamune/commands/postgres_spec.rb +15 -15
- data/spec/masamune/commands/retry_with_backoff_spec.rb +10 -7
- data/spec/masamune/commands/s3cmd_spec.rb +3 -3
- data/spec/masamune/commands/shell_spec.rb +16 -16
- data/spec/masamune/data_plan/builder_spec.rb +22 -19
- data/spec/masamune/data_plan/elem_spec.rb +20 -20
- data/spec/masamune/data_plan/engine_spec.rb +41 -33
- data/spec/masamune/data_plan/rule_spec.rb +19 -19
- data/spec/masamune/data_plan/set_spec.rb +8 -6
- data/spec/masamune/environment_spec.rb +5 -5
- data/spec/masamune/filesystem_spec.rb +87 -87
- data/spec/masamune/helpers/postgres_spec.rb +1 -1
- data/spec/masamune/rspec/job_fixture_spec.rb +0 -1
- data/spec/masamune/schema/catalog_spec.rb +16 -16
- data/spec/masamune/schema/column_spec.rb +19 -19
- data/spec/masamune/schema/dimension_spec.rb +2 -2
- data/spec/masamune/schema/fact_spec.rb +3 -3
- data/spec/masamune/schema/map_spec.rb +41 -41
- data/spec/masamune/schema/table_spec.rb +16 -16
- data/spec/masamune/string_format_spec.rb +7 -7
- data/spec/masamune/tasks/dump_thor_spec.rb +6 -6
- data/spec/masamune/tasks/hive_thor_spec.rb +2 -2
- data/spec/masamune/template_spec.rb +3 -2
- data/spec/masamune/thor_spec.rb +8 -8
- data/spec/masamune/transform/bulk_upsert.dimension_spec.rb +3 -3
- data/spec/masamune/transform/define_table.dimension_spec.rb +3 -3
- data/spec/masamune/transform/define_table.fact_spec.rb +5 -5
- data/spec/masamune/transform/define_table.table_spec.rb +6 -6
- data/spec/masamune/transform/denormalize_table_spec.rb +15 -15
- data/spec/masamune/transform/insert_reference_values.dimension_spec.rb +1 -1
- data/spec/masamune/transform/load_dimension_spec.rb +1 -1
- data/spec/masamune/transform/load_fact_spec.rb +1 -1
- data/spec/masamune/transform/rollup_fact_spec.rb +4 -4
- data/spec/masamune/transform/stage_dimension_spec.rb +3 -3
- data/spec/masamune/transform/stage_fact_spec.rb +4 -4
- data/spec/spec_helper.rb +1 -1
- data/spec/support/masamune/example_group.rb +2 -2
- data/spec/support/masamune/job_example_group.rb +3 -3
- data/spec/support/masamune/job_fixture.rb +4 -4
- data/spec/support/masamune/mock_command.rb +10 -10
- data/spec/support/masamune/mock_delegate.rb +2 -2
- data/spec/support/masamune/mock_filesystem.rb +3 -3
- data/spec/support/masamune/shared_example_group.rb +14 -16
- data/spec/support/masamune/step_example_group.rb +4 -4
- data/spec/support/masamune/step_fixture.rb +1 -1
- data/spec/support/masamune/task_example_group.rb +1 -1
- data/spec/support/masamune/thor_mute.rb +3 -2
- data/spec/support/rspec/example/action_example_group.rb +1 -1
- data/spec/support/rspec/example/task_example_group.rb +7 -4
- data/spec/support/rspec/example/transform_example_group.rb +1 -1
- data/spec/support/shared_examples/postgres_common_examples.rb +2 -2
- metadata +16 -2
@@ -25,12 +25,12 @@ require 'delegate'
|
|
25
25
|
module Masamune::Commands
|
26
26
|
class S3Cmd < SimpleDelegator
|
27
27
|
DEFAULT_ATTRIBUTES =
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
{
|
29
|
+
path: 's3cmd',
|
30
|
+
options: [],
|
31
|
+
extra: [],
|
32
|
+
block: nil
|
33
|
+
}.freeze
|
34
34
|
|
35
35
|
def initialize(delegate, attrs = {})
|
36
36
|
super delegate
|
@@ -47,7 +47,7 @@ module Masamune::Commands
|
|
47
47
|
args.flatten
|
48
48
|
end
|
49
49
|
|
50
|
-
def handle_stdout(line,
|
50
|
+
def handle_stdout(line, _line_no)
|
51
51
|
@block.call(line) if @block
|
52
52
|
end
|
53
53
|
|
@@ -57,30 +57,22 @@ module Masamune::Commands
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def before_execute
|
60
|
-
if configuration.verbose
|
61
|
-
trace(command_args)
|
62
|
-
end
|
60
|
+
trace(command_args) if configuration.verbose
|
63
61
|
|
64
|
-
if @delegate.respond_to?(:before_execute)
|
65
|
-
@delegate.before_execute
|
66
|
-
end
|
62
|
+
@delegate.before_execute if @delegate.respond_to?(:before_execute)
|
67
63
|
end
|
68
64
|
|
69
65
|
def after_execute
|
70
|
-
if @delegate.respond_to?(:after_execute)
|
71
|
-
@delegate.after_execute
|
72
|
-
end
|
66
|
+
@delegate.after_execute if @delegate.respond_to?(:after_execute)
|
73
67
|
end
|
74
68
|
|
75
69
|
def around_execute(&block)
|
76
|
-
if configuration.dry_run && !safe
|
77
|
-
return OpenStruct.new(:success? => true)
|
78
|
-
end
|
70
|
+
return OpenStruct.new(success?: true) if configuration.dry_run && !safe
|
79
71
|
|
80
72
|
if @delegate.respond_to?(:around_execute)
|
81
73
|
@delegate.around_execute(&block)
|
82
74
|
else
|
83
|
-
|
75
|
+
yield
|
84
76
|
end
|
85
77
|
end
|
86
78
|
|
@@ -101,7 +93,7 @@ module Masamune::Commands
|
|
101
93
|
end
|
102
94
|
|
103
95
|
def execute
|
104
|
-
status = OpenStruct.new(
|
96
|
+
status = OpenStruct.new(success?: false, exitstatus: 1)
|
105
97
|
|
106
98
|
before_execute
|
107
99
|
status = around_execute do
|
@@ -109,9 +101,7 @@ module Masamune::Commands
|
|
109
101
|
end
|
110
102
|
after_execute
|
111
103
|
|
112
|
-
unless status.success?
|
113
|
-
handle_failure(exit_code(status))
|
114
|
-
end
|
104
|
+
handle_failure(exit_code(status)) unless status.success?
|
115
105
|
status
|
116
106
|
rescue Interrupt
|
117
107
|
handle_failure(SIGINT_EXIT_STATUS)
|
@@ -123,42 +113,39 @@ module Masamune::Commands
|
|
123
113
|
logger.debug("execute: #{command_info}")
|
124
114
|
|
125
115
|
Open3.popen3(command_env, *command_args) do |p_stdin, p_stdout, p_stderr, t_stdin|
|
126
|
-
p_stdin.wait_writable(PIPE_TIMEOUT)
|
116
|
+
p_stdin.wait_writable(PIPE_TIMEOUT) || raise("IO stdin not ready for write in #{PIPE_TIMEOUT}")
|
127
117
|
|
128
|
-
Thread.new
|
118
|
+
Thread.new do
|
129
119
|
if @delegate.respond_to?(:stdin)
|
130
120
|
@delegate.stdin.rewind
|
131
|
-
|
121
|
+
until @delegate.stdin.eof?
|
122
|
+
line = @delegate.stdin.gets
|
132
123
|
trace(line.chomp)
|
133
124
|
p_stdin.puts line
|
134
125
|
p_stdin.flush
|
135
126
|
end
|
136
127
|
else
|
137
|
-
|
128
|
+
until p_stdin.closed?
|
138
129
|
input = Readline.readline('', true).strip
|
139
130
|
p_stdin.puts input
|
140
131
|
p_stdin.flush
|
141
132
|
end
|
142
133
|
end
|
143
134
|
p_stdin.close unless p_stdin.closed?
|
144
|
-
|
135
|
+
end
|
145
136
|
|
146
|
-
t_stderr = Thread.new
|
147
|
-
|
148
|
-
handle_stderr(p_stderr)
|
149
|
-
end
|
137
|
+
t_stderr = Thread.new do
|
138
|
+
handle_stderr(p_stderr) until p_stderr.eof?
|
150
139
|
p_stderr.close unless p_stderr.closed?
|
151
|
-
|
140
|
+
end
|
152
141
|
|
153
|
-
t_stdout = Thread.new
|
154
|
-
|
155
|
-
handle_stdout(p_stdout)
|
156
|
-
end
|
142
|
+
t_stdout = Thread.new do
|
143
|
+
handle_stdout(p_stdout) until p_stdout.eof?
|
157
144
|
p_stdout.close unless p_stdout.closed?
|
158
|
-
|
145
|
+
end
|
159
146
|
|
160
|
-
[t_stderr, t_stdout, t_stdin].compact.each
|
161
|
-
logger.debug("status: #{t_stdin.value
|
147
|
+
[t_stderr, t_stdout, t_stdin].compact.each(&:join)
|
148
|
+
logger.debug("status: #{t_stdin.value}")
|
162
149
|
t_stdin.value
|
163
150
|
end
|
164
151
|
end
|
@@ -186,9 +173,7 @@ module Masamune::Commands
|
|
186
173
|
end
|
187
174
|
|
188
175
|
def handle_failure(status)
|
189
|
-
if @delegate.respond_to?(:handle_failure)
|
190
|
-
@delegate.handle_failure(status)
|
191
|
-
end
|
176
|
+
@delegate.handle_failure(status) if @delegate.respond_to?(:handle_failure)
|
192
177
|
raise failure_message(status) if fail_fast
|
193
178
|
end
|
194
179
|
|
@@ -208,7 +193,9 @@ module Masamune::Commands
|
|
208
193
|
end
|
209
194
|
|
210
195
|
def detach
|
211
|
-
STDIN.close
|
196
|
+
STDIN.close
|
197
|
+
STDOUT.close
|
198
|
+
STDERR.close
|
212
199
|
end
|
213
200
|
|
214
201
|
def command_info
|
@@ -42,7 +42,7 @@ class Masamune::Configuration
|
|
42
42
|
attr_accessor :backoff
|
43
43
|
attr_accessor :params
|
44
44
|
|
45
|
-
COMMANDS = %w(aws_emr hive hadoop_streaming hadoop_filesystem s3cmd postgres postgres_admin)
|
45
|
+
COMMANDS = %w(aws_emr hive hadoop_streaming hadoop_filesystem s3cmd postgres postgres_admin).freeze
|
46
46
|
COMMANDS.each do |command|
|
47
47
|
attr_accessor command
|
48
48
|
define_method(command) do
|
@@ -51,7 +51,7 @@ class Masamune::Configuration
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def initialize(environment)
|
54
|
-
self.environment
|
54
|
+
self.environment = environment
|
55
55
|
self.quiet = false
|
56
56
|
self.verbose = false
|
57
57
|
self.debug = false
|
@@ -76,7 +76,7 @@ class Masamune::Configuration
|
|
76
76
|
load_paths(value)
|
77
77
|
elsif command == 'params'
|
78
78
|
raise ArgumentError, 'params section must only contain key value pairs' unless value.is_a?(Hash)
|
79
|
-
|
79
|
+
params.merge! value
|
80
80
|
end
|
81
81
|
end
|
82
82
|
logger.debug("Loaded configuration #{config_file}")
|
@@ -97,7 +97,7 @@ class Masamune::Configuration
|
|
97
97
|
|
98
98
|
def to_s
|
99
99
|
io = StringIO.new
|
100
|
-
rep = {
|
100
|
+
rep = { 'path' => filesystem.paths }
|
101
101
|
COMMANDS.each do |command|
|
102
102
|
rep[command] = send(command)
|
103
103
|
end
|
@@ -121,8 +121,9 @@ class Masamune::Configuration
|
|
121
121
|
|
122
122
|
def_delegators :filesystem, :add_path, :get_path
|
123
123
|
|
124
|
-
def with_quiet
|
125
|
-
prev_quiet
|
124
|
+
def with_quiet
|
125
|
+
prev_quiet = quiet
|
126
|
+
self.quiet = true
|
126
127
|
yield
|
127
128
|
ensure
|
128
129
|
self.quiet = prev_quiet
|
@@ -135,9 +136,7 @@ class Masamune::Configuration
|
|
135
136
|
end
|
136
137
|
|
137
138
|
class << self
|
138
|
-
|
139
|
-
@default_config_file = config_file
|
140
|
-
end
|
139
|
+
attr_writer :default_config_file
|
141
140
|
|
142
141
|
def default_config_file
|
143
142
|
@default_config_file ||= File.join(File.expand_path('../../../', __FILE__), 'config', 'masamune.yml.erb')
|
@@ -33,8 +33,8 @@ class Masamune::DataPlan::Builder
|
|
33
33
|
commands.each do |name|
|
34
34
|
command_name = "#{namespaces.shift}:#{name}"
|
35
35
|
|
36
|
-
source_options = sources_for[name] || sources_anon.shift
|
37
|
-
target_options = targets_for[name] || targets_anon.shift
|
36
|
+
(source_options = sources_for[name] || sources_anon.shift) || next
|
37
|
+
(target_options = targets_for[name] || targets_anon.shift) || next
|
38
38
|
next if source_options[:skip] || target_options[:skip]
|
39
39
|
|
40
40
|
engine.add_source_rule(command_name, source_options)
|
@@ -48,16 +48,16 @@ class Masamune::DataPlan::Builder
|
|
48
48
|
private
|
49
49
|
|
50
50
|
def partition_by_for(annotations)
|
51
|
-
with_for, anon = annotations.partition { |opts| opts.
|
51
|
+
with_for, anon = annotations.partition { |opts| opts.key?(:for) }
|
52
52
|
decl = {}
|
53
53
|
with_for.each do |opts|
|
54
|
-
decl[opts[:for]] = opts.reject { |k,_| k == :for }
|
54
|
+
decl[opts[:for]] = opts.reject { |k, _| k == :for }
|
55
55
|
end
|
56
56
|
[decl, anon]
|
57
57
|
end
|
58
58
|
|
59
59
|
def thor_command_wrapper
|
60
|
-
|
60
|
+
proc do |engine, rule, _|
|
61
61
|
engine.environment.parent.invoke(rule)
|
62
62
|
end
|
63
63
|
end
|
@@ -36,13 +36,13 @@ class Masamune::DataPlan::Elem
|
|
36
36
|
def input
|
37
37
|
@input ||= start_time.strftime(strftime_format)
|
38
38
|
end
|
39
|
-
alias
|
40
|
-
alias
|
39
|
+
alias path input
|
40
|
+
alias table input
|
41
41
|
|
42
42
|
def partition
|
43
43
|
input.split('_').last
|
44
44
|
end
|
45
|
-
alias
|
45
|
+
alias suffix partition
|
46
46
|
|
47
47
|
def exists?
|
48
48
|
if rule.for_path?
|
@@ -140,11 +140,11 @@ class Masamune::DataPlan::Elem
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def next(i = 1)
|
143
|
-
self.class.new(@rule, start_time.advance(@rule.time_step => +1*i), @options)
|
143
|
+
self.class.new(@rule, start_time.advance(@rule.time_step => +1 * i), @options)
|
144
144
|
end
|
145
145
|
|
146
146
|
def prev(i = 1)
|
147
|
-
self.class.new(@rule, start_time.advance(@rule.time_step => -1*i), @options)
|
147
|
+
self.class.new(@rule, start_time.advance(@rule.time_step => -1 * i), @options)
|
148
148
|
end
|
149
149
|
|
150
150
|
def round(grain)
|
@@ -163,7 +163,7 @@ class Masamune::DataPlan::Elem
|
|
163
163
|
uniq_constraint.hash
|
164
164
|
end
|
165
165
|
|
166
|
-
# FIXME should consider stop_time for correctness
|
166
|
+
# FIXME: should consider stop_time for correctness
|
167
167
|
def <=>(other)
|
168
168
|
if start_time < other.start_time
|
169
169
|
1
|
@@ -175,7 +175,7 @@ class Masamune::DataPlan::Elem
|
|
175
175
|
end
|
176
176
|
|
177
177
|
def inspect
|
178
|
-
{rule: rule, input: input, start_date: start_time.to_s, stop_date: stop_time.to_s, :options
|
178
|
+
{ rule: rule, input: input, start_date: start_time.to_s, stop_date: stop_time.to_s, options: options }.to_s
|
179
179
|
end
|
180
180
|
|
181
181
|
protected
|
@@ -31,12 +31,12 @@ class Masamune::DataPlan::Engine
|
|
31
31
|
include Masamune::HasEnvironment
|
32
32
|
|
33
33
|
def initialize
|
34
|
-
@target_rules =
|
35
|
-
@source_rules =
|
36
|
-
@command_rules =
|
37
|
-
@targets = Hash.new { |set,rule| set[rule] = Masamune::DataPlan::Set.new(@target_rules[rule]) }
|
38
|
-
@sources = Hash.new { |set,rule| set[rule] = Masamune::DataPlan::Set.new(@source_rules[rule]) }
|
39
|
-
@set_cache = Hash.new { |cache,level| cache[level] =
|
34
|
+
@target_rules = {}
|
35
|
+
@source_rules = {}
|
36
|
+
@command_rules = {}
|
37
|
+
@targets = Hash.new { |set, rule| set[rule] = Masamune::DataPlan::Set.new(@target_rules[rule]) }
|
38
|
+
@sources = Hash.new { |set, rule| set[rule] = Masamune::DataPlan::Set.new(@source_rules[rule]) }
|
39
|
+
@set_cache = Hash.new { |cache, level| cache[level] = {} }
|
40
40
|
@current_depth = 0
|
41
41
|
end
|
42
42
|
|
@@ -64,17 +64,14 @@ class Masamune::DataPlan::Engine
|
|
64
64
|
@command_rules[rule] = command
|
65
65
|
end
|
66
66
|
|
67
|
-
# TODO use constructed reference instead
|
67
|
+
# TODO: use constructed reference instead
|
68
68
|
def rule_for_target(target)
|
69
|
-
target_matches = @target_rules.select { |
|
70
|
-
source_matches = @source_rules.select { |
|
69
|
+
target_matches = @target_rules.select { |_rule, matcher| matcher.primary? && matcher.matches?(target) }
|
70
|
+
source_matches = @source_rules.select { |_rule, matcher| matcher.matches?(target) }
|
71
71
|
|
72
72
|
if target_matches.empty?
|
73
|
-
if source_matches.empty?
|
74
|
-
|
75
|
-
else
|
76
|
-
Masamune::DataPlan::Rule::TERMINAL
|
77
|
-
end
|
73
|
+
raise "No rule matches target #{target}" if source_matches.empty?
|
74
|
+
Masamune::DataPlan::Rule::TERMINAL
|
78
75
|
else
|
79
76
|
logger.error("Multiple rules match target #{target}") if target_matches.length > 1
|
80
77
|
target_matches.map(&:first).first
|
@@ -136,7 +133,7 @@ class Masamune::DataPlan::Engine
|
|
136
133
|
return if targets(rule).actionable.empty?
|
137
134
|
|
138
135
|
constrain_max_depth(rule) do
|
139
|
-
sources(rule).group_by { |source| rule_for_target(source.input) }.each do |derived_rule,
|
136
|
+
sources(rule).group_by { |source| rule_for_target(source.input) }.each do |derived_rule, _sources|
|
140
137
|
execute(derived_rule, options) if derived_rule != Masamune::DataPlan::Rule::TERMINAL
|
141
138
|
end
|
142
139
|
end if options.fetch(:resolve, true)
|
@@ -97,7 +97,7 @@ class Masamune::DataPlan::Rule
|
|
97
97
|
if for_path?
|
98
98
|
engine.filesystem.eval_path(path)
|
99
99
|
elsif for_table_with_partition?
|
100
|
-
[table
|
100
|
+
[table, partition].join('_')
|
101
101
|
elsif for_table?
|
102
102
|
table
|
103
103
|
end.to_s
|
@@ -151,10 +151,11 @@ class Masamune::DataPlan::Rule
|
|
151
151
|
return Set.new(to_enum(:generate, start_time, stop_time)) unless block_given?
|
152
152
|
instance = bind_date_or_time(start_time)
|
153
153
|
|
154
|
-
|
154
|
+
loop do
|
155
155
|
yield instance
|
156
156
|
instance = instance.next
|
157
|
-
|
157
|
+
break unless instance.start_time <= stop_time
|
158
|
+
end
|
158
159
|
end
|
159
160
|
|
160
161
|
def generate_via_unify(elem, rule)
|
@@ -162,10 +163,11 @@ class Masamune::DataPlan::Rule
|
|
162
163
|
instance = unify(elem, rule)
|
163
164
|
|
164
165
|
stop_time = instance.start_time.advance(time_step => 1)
|
165
|
-
|
166
|
+
loop do
|
166
167
|
yield instance
|
167
168
|
instance = instance.next
|
168
|
-
|
169
|
+
break unless instance.start_time < stop_time
|
170
|
+
end
|
169
171
|
end
|
170
172
|
|
171
173
|
def tz
|
@@ -219,17 +221,17 @@ class Masamune::DataPlan::Rule
|
|
219
221
|
|
220
222
|
def adjacent_matches(instance)
|
221
223
|
return Set.new(to_enum(:adjacent_matches, instance)) unless block_given?
|
222
|
-
(-window
|
224
|
+
(-window..-1).each do |i|
|
223
225
|
yield instance.prev(i.abs)
|
224
226
|
end
|
225
227
|
yield instance
|
226
|
-
(1
|
228
|
+
(1..window).each do |i|
|
227
229
|
yield instance.next(i)
|
228
230
|
end
|
229
231
|
end
|
230
232
|
|
231
233
|
def inspect
|
232
|
-
{type: type, pattern: pattern, options: options}.to_s
|
234
|
+
{ type: type, pattern: pattern, options: options }.to_s
|
233
235
|
end
|
234
236
|
|
235
237
|
def strftime_format
|
@@ -296,7 +298,7 @@ class Masamune::DataPlan::Rule
|
|
296
298
|
|
297
299
|
def match_data_hash(match_data = nil)
|
298
300
|
return unless match_data.present?
|
299
|
-
|
301
|
+
{}.tap do |hash|
|
300
302
|
match_data.names.map(&:to_sym).each do |key|
|
301
303
|
hash[key] = match_data[key.to_sym]
|
302
304
|
end
|
@@ -304,8 +306,8 @@ class Masamune::DataPlan::Rule
|
|
304
306
|
end
|
305
307
|
|
306
308
|
def matched_date(matched_data)
|
307
|
-
if
|
308
|
-
Time.at(timestamp.to_i).to_datetime
|
309
|
+
if matched_data[:timestamp]
|
310
|
+
Time.at(matched_data[:timestamp].to_i).to_datetime
|
309
311
|
else
|
310
312
|
DateTime.new(*matched_data.values_at(:year, :month, :day, :hour).compact.map(&:to_i))
|
311
313
|
end
|
@@ -316,6 +318,6 @@ class Masamune::DataPlan::Rule
|
|
316
318
|
end
|
317
319
|
|
318
320
|
def options_for_elem
|
319
|
-
@options.reject { |k,_| [:path, :table].include?(k) }
|
321
|
+
@options.reject { |k, _| [:path, :table].include?(k) }
|
320
322
|
end
|
321
323
|
end
|
@@ -23,7 +23,7 @@
|
|
23
23
|
require 'set'
|
24
24
|
|
25
25
|
class Masamune::DataPlan::Set < Set
|
26
|
-
EMPTY =
|
26
|
+
EMPTY = new
|
27
27
|
|
28
28
|
attr_reader :rule
|
29
29
|
|
@@ -46,14 +46,14 @@ class Masamune::DataPlan::Set < Set
|
|
46
46
|
|
47
47
|
def missing
|
48
48
|
return self.class.new(rule, to_enum(__method__)) unless block_given?
|
49
|
-
|
49
|
+
each do |elem|
|
50
50
|
yield elem if elem.explode.none?
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
54
|
def existing
|
55
55
|
return self.class.new(rule, to_enum(__method__)) unless block_given?
|
56
|
-
|
56
|
+
each do |elem|
|
57
57
|
elem.explode.each do |new_elem|
|
58
58
|
yield new_elem
|
59
59
|
end
|
@@ -62,7 +62,7 @@ class Masamune::DataPlan::Set < Set
|
|
62
62
|
|
63
63
|
def adjacent
|
64
64
|
return self.class.new(rule, to_enum(__method__)) unless block_given?
|
65
|
-
|
65
|
+
each do |elem|
|
66
66
|
@rule.adjacent_matches(elem).each do |adj_elem|
|
67
67
|
yield adj_elem
|
68
68
|
end
|
@@ -72,7 +72,7 @@ class Masamune::DataPlan::Set < Set
|
|
72
72
|
def stale
|
73
73
|
return Masamune::DataPlan::Set::EMPTY if empty? || @rule.for_sources?
|
74
74
|
return self.class.new(rule, to_enum(__method__)) unless block_given?
|
75
|
-
|
75
|
+
each do |target|
|
76
76
|
yield target if target.sources.existing.any? { |source| target_stale?(source, target) }
|
77
77
|
end
|
78
78
|
end
|
@@ -81,8 +81,8 @@ class Masamune::DataPlan::Set < Set
|
|
81
81
|
return Masamune::DataPlan::Set::EMPTY if empty? || @rule.for_sources?
|
82
82
|
return self.class.new(rule, to_enum(__method__)) unless block_given?
|
83
83
|
set = Set.new
|
84
|
-
|
85
|
-
yield target
|
84
|
+
each do |target|
|
85
|
+
yield target unless target.complete? || !set.add?(target)
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
@@ -110,11 +110,11 @@ class Masamune::DataPlan::Set < Set
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
113
|
-
# TODO detect & warn or correct if coarser grain set is incomplete
|
113
|
+
# TODO: detect & warn or correct if coarser grain set is incomplete
|
114
114
|
def with_grain(grain)
|
115
115
|
return self.class.new(rule.round(grain), to_enum(:with_grain, grain)) unless block_given?
|
116
116
|
seen = Set.new
|
117
|
-
|
117
|
+
each do |elem|
|
118
118
|
granular_elem = elem.round(grain)
|
119
119
|
yield granular_elem if seen.add?(granular_elem)
|
120
120
|
end
|
@@ -122,8 +122,8 @@ class Masamune::DataPlan::Set < Set
|
|
122
122
|
|
123
123
|
def targets
|
124
124
|
return Masamune::DataPlan::Set::EMPTY if empty? || @rule.for_targets?
|
125
|
-
return self.class.new(
|
126
|
-
|
125
|
+
return self.class.new(first.targets.rule, to_enum(__method__)) unless block_given?
|
126
|
+
each do |elem|
|
127
127
|
elem.targets do |target|
|
128
128
|
yield target
|
129
129
|
end
|
@@ -132,8 +132,8 @@ class Masamune::DataPlan::Set < Set
|
|
132
132
|
|
133
133
|
def sources
|
134
134
|
return Masamune::DataPlan::Set::EMPTY if empty? || @rule.for_sources?
|
135
|
-
return self.class.new(
|
136
|
-
|
135
|
+
return self.class.new(first.sources.rule, to_enum(__method__)) unless block_given?
|
136
|
+
each do |elem|
|
137
137
|
elem.sources do |source|
|
138
138
|
yield source
|
139
139
|
end
|