Class: Masamune::DataPlan::Engine
- Inherits:
-
Object
- Object
- Masamune::DataPlan::Engine
show all
- Includes:
- HasEnvironment
- Defined in:
- lib/masamune/data_plan/engine.rb
Constant Summary
collapse
- MAX_DEPTH =
10
Instance Method Summary
collapse
#environment, #environment=
Constructor Details
#initialize ⇒ Engine
33
34
35
36
37
38
39
40
41
|
# File 'lib/masamune/data_plan/engine.rb', line 33
def initialize
@target_rules = {}
@source_rules = {}
@command_rules = {}
@targets = Hash.new { |set, rule| set[rule] = Masamune::DataPlan::Set.new(@target_rules[rule]) }
@sources = Hash.new { |set, rule| set[rule] = Masamune::DataPlan::Set.new(@source_rules[rule]) }
@set_cache = Hash.new { |cache, level| cache[level] = {} }
@current_depth = 0
end
|
Instance Method Details
#add_command_rule(rule, command) ⇒ Object
63
64
65
|
# File 'lib/masamune/data_plan/engine.rb', line 63
def add_command_rule(rule, command)
@command_rules[rule] = command
end
|
#add_source_rule(rule, source_options = {}) ⇒ Object
55
56
57
|
# File 'lib/masamune/data_plan/engine.rb', line 55
def add_source_rule(rule, source_options = {})
@source_rules[rule] = Masamune::DataPlan::Rule.new(self, rule, :source, source_options)
end
|
#add_target_rule(rule, target_options = {}) ⇒ Object
47
48
49
|
# File 'lib/masamune/data_plan/engine.rb', line 47
def add_target_rule(rule, target_options = {})
@target_rules[rule] = Masamune::DataPlan::Rule.new(self, rule, :target, target_options)
end
|
#clear! ⇒ Object
157
158
159
160
161
|
# File 'lib/masamune/data_plan/engine.rb', line 157
def clear!
@set_cache.clear
filesystem.clear!
environment.postgres_helper.clear!
end
|
#constrain_max_depth(rule) ⇒ Object
149
150
151
152
153
154
155
|
# File 'lib/masamune/data_plan/engine.rb', line 149
def constrain_max_depth(rule)
@current_depth += 1
raise "Max depth of #{MAX_DEPTH} exceeded for rule '#{rule}'" if @current_depth > MAX_DEPTH
yield
ensure
@current_depth -= 1
end
|
#execute(rule, options = {}) ⇒ Object
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
# File 'lib/masamune/data_plan/engine.rb', line 134
def execute(rule, options = {})
return if targets(rule).actionable.empty?
if options.fetch(:resolve, true)
constrain_max_depth(rule) do
sources(rule).group_by { |source| rule_for_target(source.input) }.each do |derived_rule, _sources|
execute(derived_rule, options) if derived_rule != Masamune::DataPlan::Rule::TERMINAL
end
end
end
@command_rules[rule].call(self, rule, options)
clear!
end
|
#filesystem ⇒ Object
43
44
45
|
# File 'lib/masamune/data_plan/engine.rb', line 43
def filesystem
@filesystem ||= Masamune::CachedFilesystem.new(environment.filesystem)
end
|
#get_source_rule(rule) ⇒ Object
59
60
61
|
# File 'lib/masamune/data_plan/engine.rb', line 59
def get_source_rule(rule)
@source_rules[rule]
end
|
#get_target_rule(rule) ⇒ Object
51
52
53
|
# File 'lib/masamune/data_plan/engine.rb', line 51
def get_target_rule(rule)
@target_rules[rule]
end
|
#prepare(rule, options = {}) ⇒ Object
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/masamune/data_plan/engine.rb', line 118
def prepare(rule, options = {})
@targets[rule].merge options.fetch(:targets, [])
@sources[rule].merge options.fetch(:sources, [])
@target_rules[rule].try(:prepare)
@source_rules[rule].try(:prepare)
if options.fetch(:resolve, true)
constrain_max_depth(rule) do
sources(rule).group_by { |source| rule_for_target(source.input) }.each do |derived_rule, sources|
prepare(derived_rule, targets: sources.map(&:input)) if derived_rule != Masamune::DataPlan::Rule::TERMINAL
end
end
end
clear!
end
|
#rule_for_target(target) ⇒ Object
TODO: use constructed reference instead
68
69
70
71
72
73
74
75
76
77
78
79
|
# File 'lib/masamune/data_plan/engine.rb', line 68
def rule_for_target(target)
target_matches = @target_rules.select { |_rule, matcher| matcher.primary? && matcher.matches?(target) }
source_matches = @source_rules.select { |_rule, matcher| matcher.matches?(target) }
if target_matches.empty?
raise "No rule matches target #{target}" if source_matches.empty?
Masamune::DataPlan::Rule::TERMINAL
else
logger.error("Multiple rules match target #{target}") if target_matches.length > 1
target_matches.map(&:first).first
end
end
|
#sources(rule) ⇒ Object
114
115
116
|
# File 'lib/masamune/data_plan/engine.rb', line 114
def sources(rule)
@set_cache[:sources_for_rule][rule] ||= @sources[rule].union(@targets[rule].sources).adjacent
end
|
#sources_for_target(rule, target) ⇒ Object
100
101
102
103
104
105
106
107
108
|
# File 'lib/masamune/data_plan/engine.rb', line 100
def sources_for_target(rule, target)
return Masamune::DataPlan::Set.new(get_source_rule(rule), to_enum(:sources_for_target, rule, target)) unless block_given?
source_template = @source_rules[rule]
target_template = @target_rules[rule]
target_instance = target_template.bind_input(target)
target_template.generate_via_unify(target_instance, source_template).each do |source|
yield source
end
end
|
#targets(rule) ⇒ Object
110
111
112
|
# File 'lib/masamune/data_plan/engine.rb', line 110
def targets(rule)
@set_cache[:targets_for_rule][rule] ||= @targets[rule].union(@sources[rule].targets)
end
|
#targets_for_date_range(rule, start, stop) ⇒ Object
81
82
83
84
85
86
87
88
|
# File 'lib/masamune/data_plan/engine.rb', line 81
def targets_for_date_range(rule, start, stop)
return Masamune::DataPlan::Set.new(get_target_rule(rule), to_enum(:targets_for_date_range, rule, start, stop)) unless block_given?
target_template = @target_rules[rule]
return unless target_template
target_template.generate(start.to_time.utc, stop.to_time.utc).each do |target|
yield target
end
end
|
#targets_for_source(rule, source) ⇒ Object
90
91
92
93
94
95
96
97
98
|
# File 'lib/masamune/data_plan/engine.rb', line 90
def targets_for_source(rule, source)
return Masamune::DataPlan::Set.new(get_target_rule(rule), to_enum(:targets_for_source, rule, source)) unless block_given?
source_template = @source_rules[rule]
target_template = @target_rules[rule]
source_instance = source_template.bind_input(source)
source_template.generate_via_unify(source_instance, target_template).each do |target|
yield target
end
end
|