masamune 0.17.12 → 0.17.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +3 -3
  3. data/bin/masamune-aws-emr +1 -1
  4. data/bin/masamune-dump +1 -1
  5. data/bin/masamune-hive +1 -1
  6. data/bin/masamune-psql +1 -1
  7. data/bin/masamune-shell +1 -1
  8. data/lib/masamune.rb +1 -1
  9. data/lib/masamune/actions/aws_emr.rb +2 -2
  10. data/lib/masamune/actions/data_flow.rb +10 -10
  11. data/lib/masamune/actions/date_parse.rb +4 -6
  12. data/lib/masamune/actions/execute.rb +3 -3
  13. data/lib/masamune/actions/filesystem.rb +1 -1
  14. data/lib/masamune/actions/hadoop_filesystem.rb +2 -2
  15. data/lib/masamune/actions/hive.rb +5 -5
  16. data/lib/masamune/actions/invoke_parallel.rb +5 -5
  17. data/lib/masamune/actions/postgres.rb +6 -6
  18. data/lib/masamune/actions/postgres_admin.rb +1 -1
  19. data/lib/masamune/actions/s3cmd.rb +3 -3
  20. data/lib/masamune/actions/transform.rb +4 -4
  21. data/lib/masamune/after_initialize_callbacks.rb +4 -4
  22. data/lib/masamune/cached_filesystem.rb +7 -11
  23. data/lib/masamune/commands/aws_emr.rb +12 -12
  24. data/lib/masamune/commands/hadoop_filesystem.rb +8 -8
  25. data/lib/masamune/commands/hadoop_streaming.rb +16 -16
  26. data/lib/masamune/commands/hive.rb +31 -35
  27. data/lib/masamune/commands/postgres.rb +30 -32
  28. data/lib/masamune/commands/postgres_admin.rb +17 -16
  29. data/lib/masamune/commands/postgres_common.rb +1 -1
  30. data/lib/masamune/commands/retry_with_backoff.rb +19 -19
  31. data/lib/masamune/commands/s3cmd.rb +7 -7
  32. data/lib/masamune/commands/shell.rb +25 -38
  33. data/lib/masamune/configuration.rb +8 -9
  34. data/lib/masamune/data_plan/builder.rb +5 -5
  35. data/lib/masamune/data_plan/elem.rb +7 -7
  36. data/lib/masamune/data_plan/engine.rb +12 -15
  37. data/lib/masamune/data_plan/rule.rb +14 -12
  38. data/lib/masamune/data_plan/set.rb +13 -13
  39. data/lib/masamune/environment.rb +3 -3
  40. data/lib/masamune/filesystem.rb +29 -28
  41. data/lib/masamune/helpers/postgres.rb +8 -5
  42. data/lib/masamune/io.rb +2 -2
  43. data/lib/masamune/last_element.rb +3 -3
  44. data/lib/masamune/method_logger.rb +1 -1
  45. data/lib/masamune/schema/catalog.rb +9 -12
  46. data/lib/masamune/schema/column.rb +12 -10
  47. data/lib/masamune/schema/dimension.rb +5 -4
  48. data/lib/masamune/schema/fact.rb +2 -2
  49. data/lib/masamune/schema/map.rb +9 -13
  50. data/lib/masamune/schema/row.rb +3 -2
  51. data/lib/masamune/schema/store.rb +13 -14
  52. data/lib/masamune/schema/table.rb +24 -28
  53. data/lib/masamune/schema/table_reference.rb +7 -7
  54. data/lib/masamune/spec_helper.rb +1 -1
  55. data/lib/masamune/string_format.rb +1 -1
  56. data/lib/masamune/tasks/aws_emr_thor.rb +9 -9
  57. data/lib/masamune/tasks/dump_thor.rb +5 -5
  58. data/lib/masamune/tasks/hive_thor.rb +13 -13
  59. data/lib/masamune/tasks/postgres_thor.rb +8 -8
  60. data/lib/masamune/tasks/shell_thor.rb +3 -3
  61. data/lib/masamune/template.rb +4 -4
  62. data/lib/masamune/thor.rb +26 -25
  63. data/lib/masamune/transform/common/denormalize_table.rb +6 -6
  64. data/lib/masamune/transform/define_table.rb +1 -1
  65. data/lib/masamune/transform/hive/define_table.rb +0 -2
  66. data/lib/masamune/transform/insert_reference_values.rb +1 -1
  67. data/lib/masamune/transform/operator.rb +3 -2
  68. data/lib/masamune/transform/postgres/bulk_upsert.rb +0 -3
  69. data/lib/masamune/transform/postgres/deduplicate_dimension.rb +4 -6
  70. data/lib/masamune/transform/postgres/define_table.rb +2 -2
  71. data/lib/masamune/transform/postgres/insert_reference_values.rb +1 -4
  72. data/lib/masamune/transform/postgres/relabel_dimension.rb +1 -3
  73. data/lib/masamune/transform/postgres/rollup_fact.rb +3 -5
  74. data/lib/masamune/transform/postgres/snapshot_dimension.rb +1 -4
  75. data/lib/masamune/transform/postgres/stage_dimension.rb +8 -10
  76. data/lib/masamune/transform/postgres/stage_fact.rb +15 -14
  77. data/lib/masamune/version.rb +1 -1
  78. data/spec/masamune/actions/aws_emr_spec.rb +8 -8
  79. data/spec/masamune/actions/execute_spec.rb +6 -6
  80. data/spec/masamune/actions/hive_spec.rb +20 -15
  81. data/spec/masamune/actions/postgres_spec.rb +17 -10
  82. data/spec/masamune/after_initialization_callbacks_spec.rb +13 -7
  83. data/spec/masamune/commands/aws_emr_spec.rb +10 -10
  84. data/spec/masamune/commands/hadoop_filesystem_spec.rb +3 -3
  85. data/spec/masamune/commands/hadoop_streaming_spec.rb +4 -4
  86. data/spec/masamune/commands/hive_spec.rb +11 -11
  87. data/spec/masamune/commands/postgres_admin_spec.rb +9 -9
  88. data/spec/masamune/commands/postgres_spec.rb +15 -15
  89. data/spec/masamune/commands/retry_with_backoff_spec.rb +10 -7
  90. data/spec/masamune/commands/s3cmd_spec.rb +3 -3
  91. data/spec/masamune/commands/shell_spec.rb +16 -16
  92. data/spec/masamune/data_plan/builder_spec.rb +22 -19
  93. data/spec/masamune/data_plan/elem_spec.rb +20 -20
  94. data/spec/masamune/data_plan/engine_spec.rb +41 -33
  95. data/spec/masamune/data_plan/rule_spec.rb +19 -19
  96. data/spec/masamune/data_plan/set_spec.rb +8 -6
  97. data/spec/masamune/environment_spec.rb +5 -5
  98. data/spec/masamune/filesystem_spec.rb +87 -87
  99. data/spec/masamune/helpers/postgres_spec.rb +1 -1
  100. data/spec/masamune/rspec/job_fixture_spec.rb +0 -1
  101. data/spec/masamune/schema/catalog_spec.rb +16 -16
  102. data/spec/masamune/schema/column_spec.rb +19 -19
  103. data/spec/masamune/schema/dimension_spec.rb +2 -2
  104. data/spec/masamune/schema/fact_spec.rb +3 -3
  105. data/spec/masamune/schema/map_spec.rb +41 -41
  106. data/spec/masamune/schema/table_spec.rb +16 -16
  107. data/spec/masamune/string_format_spec.rb +7 -7
  108. data/spec/masamune/tasks/dump_thor_spec.rb +6 -6
  109. data/spec/masamune/tasks/hive_thor_spec.rb +2 -2
  110. data/spec/masamune/template_spec.rb +3 -2
  111. data/spec/masamune/thor_spec.rb +8 -8
  112. data/spec/masamune/transform/bulk_upsert.dimension_spec.rb +3 -3
  113. data/spec/masamune/transform/define_table.dimension_spec.rb +3 -3
  114. data/spec/masamune/transform/define_table.fact_spec.rb +5 -5
  115. data/spec/masamune/transform/define_table.table_spec.rb +6 -6
  116. data/spec/masamune/transform/denormalize_table_spec.rb +15 -15
  117. data/spec/masamune/transform/insert_reference_values.dimension_spec.rb +1 -1
  118. data/spec/masamune/transform/load_dimension_spec.rb +1 -1
  119. data/spec/masamune/transform/load_fact_spec.rb +1 -1
  120. data/spec/masamune/transform/rollup_fact_spec.rb +4 -4
  121. data/spec/masamune/transform/stage_dimension_spec.rb +3 -3
  122. data/spec/masamune/transform/stage_fact_spec.rb +4 -4
  123. data/spec/spec_helper.rb +1 -1
  124. data/spec/support/masamune/example_group.rb +2 -2
  125. data/spec/support/masamune/job_example_group.rb +3 -3
  126. data/spec/support/masamune/job_fixture.rb +4 -4
  127. data/spec/support/masamune/mock_command.rb +10 -10
  128. data/spec/support/masamune/mock_delegate.rb +2 -2
  129. data/spec/support/masamune/mock_filesystem.rb +3 -3
  130. data/spec/support/masamune/shared_example_group.rb +14 -16
  131. data/spec/support/masamune/step_example_group.rb +4 -4
  132. data/spec/support/masamune/step_fixture.rb +1 -1
  133. data/spec/support/masamune/task_example_group.rb +1 -1
  134. data/spec/support/masamune/thor_mute.rb +3 -2
  135. data/spec/support/rspec/example/action_example_group.rb +1 -1
  136. data/spec/support/rspec/example/task_example_group.rb +7 -4
  137. data/spec/support/rspec/example/transform_example_group.rb +1 -1
  138. data/spec/support/shared_examples/postgres_common_examples.rb +2 -2
  139. 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
- :path => 's3cmd',
30
- :options => [],
31
- :extra => [],
32
- :block => nil
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, line_no)
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
- block.call
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(:success? => false, :exitstatus => 1)
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) or raise "IO stdin not ready for write in #{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
- while line = @delegate.stdin.gets
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
- while !p_stdin.closed? do
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
- while !p_stderr.eof? do
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
- while !p_stdout.eof? do
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 { |t| t.join }
161
- logger.debug("status: #{t_stdin.value.to_s}")
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; STDOUT.close; STDERR.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 = 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
- self.params.merge! value
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 = {"path" => filesystem.paths}
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(&block)
125
- prev_quiet, self.quiet = quiet, true
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
- def default_config_file=(config_file)
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 or next
37
- target_options = targets_for[name] || targets_anon.shift or next
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.has_key?(:for) }
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
- Proc.new do |engine, rule, _|
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 :path :input
40
- alias :table :input
39
+ alias path input
40
+ alias table input
41
41
 
42
42
  def partition
43
43
  input.split('_').last
44
44
  end
45
- alias :suffix :partition
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 => options}.to_s
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 = Hash.new
35
- @source_rules = Hash.new
36
- @command_rules = Hash.new
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] = Hash.new }
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 { |rule, matcher| matcher.primary? && matcher.matches?(target) }
70
- source_matches = @source_rules.select { |rule, matcher| matcher.matches?(target) }
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
- raise "No rule matches target #{target}"
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, sources|
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 , partition].join('_')
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
- begin
154
+ loop do
155
155
  yield instance
156
156
  instance = instance.next
157
- end while instance.start_time <= stop_time
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
- begin
166
+ loop do
166
167
  yield instance
167
168
  instance = instance.next
168
- end while instance.start_time < stop_time
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 .. -1).each do |i|
224
+ (-window..-1).each do |i|
223
225
  yield instance.prev(i.abs)
224
226
  end
225
227
  yield instance
226
- (1 .. window).each do |i|
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
- Hash.new.tap do |hash|
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 timestamp = matched_data[:timestamp]
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 = self.new
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
- self.each do |elem|
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
- self.each do |elem|
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
- self.each do |elem|
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
- self.each do |target|
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
- self.each do |target|
85
- yield target if set.add?(target) unless target.complete?
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
- self.each do |elem|
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(self.first.targets.rule, to_enum(__method__)) unless block_given?
126
- self.each do |elem|
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(self.first.sources.rule, to_enum(__method__)) unless block_given?
136
- self.each do |elem|
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