masamune 0.17.12 → 0.17.13
Sign up to get free protection for your applications and to get access to all the features.
- 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
|