datashift 0.15.0 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.markdown +91 -55
- data/VERSION +1 -1
- data/datashift.gemspec +8 -23
- data/lib/applications/jexcel_file.rb +1 -2
- data/lib/datashift.rb +34 -15
- data/lib/datashift/column_packer.rb +98 -34
- data/lib/datashift/data_transforms.rb +83 -0
- data/lib/datashift/delimiters.rb +58 -10
- data/lib/datashift/excel_base.rb +123 -0
- data/lib/datashift/exceptions.rb +45 -7
- data/lib/datashift/load_object.rb +25 -0
- data/lib/datashift/mapping_service.rb +91 -0
- data/lib/datashift/method_detail.rb +40 -62
- data/lib/datashift/method_details_manager.rb +18 -2
- data/lib/datashift/method_dictionary.rb +27 -10
- data/lib/datashift/method_mapper.rb +49 -41
- data/lib/datashift/model_mapper.rb +42 -22
- data/lib/datashift/populator.rb +258 -143
- data/lib/datashift/thor_base.rb +38 -0
- data/lib/exporters/csv_exporter.rb +57 -145
- data/lib/exporters/excel_exporter.rb +73 -60
- data/lib/generators/csv_generator.rb +65 -5
- data/lib/generators/generator_base.rb +69 -3
- data/lib/generators/mapping_generator.rb +112 -0
- data/lib/helpers/core_ext/csv_file.rb +33 -0
- data/lib/loaders/csv_loader.rb +41 -39
- data/lib/loaders/excel_loader.rb +130 -116
- data/lib/loaders/loader_base.rb +190 -146
- data/lib/loaders/paperclip/attachment_loader.rb +4 -4
- data/lib/loaders/paperclip/datashift_paperclip.rb +5 -3
- data/lib/loaders/paperclip/image_loading.rb +9 -7
- data/lib/loaders/reporter.rb +17 -8
- data/lib/thor/export.thor +12 -13
- data/lib/thor/generate.thor +1 -9
- data/lib/thor/import.thor +13 -24
- data/lib/thor/mapping.thor +65 -0
- data/spec/Gemfile +13 -11
- data/spec/Gemfile.lock +98 -93
- data/spec/csv_exporter_spec.rb +104 -99
- data/spec/csv_generator_spec.rb +159 -0
- data/spec/csv_loader_spec.rb +197 -16
- data/spec/datashift_spec.rb +9 -0
- data/spec/excel_exporter_spec.rb +149 -58
- data/spec/excel_generator_spec.rb +35 -44
- data/spec/excel_loader_spec.rb +196 -178
- data/spec/excel_spec.rb +8 -5
- data/spec/loader_base_spec.rb +47 -7
- data/spec/mapping_spec.rb +117 -0
- data/spec/method_dictionary_spec.rb +24 -11
- data/spec/method_mapper_spec.rb +5 -7
- data/spec/model_mapper_spec.rb +41 -0
- data/spec/paperclip_loader_spec.rb +3 -6
- data/spec/populator_spec.rb +48 -14
- data/spec/spec_helper.rb +85 -73
- data/spec/thor_spec.rb +40 -5
- metadata +93 -86
- data/lib/applications/excel_base.rb +0 -63
data/lib/datashift/populator.rb
CHANGED
@@ -14,183 +14,287 @@ require 'logging'
|
|
14
14
|
|
15
15
|
module DataShift
|
16
16
|
|
17
|
+
Struct.new("Substitution", :pattern, :replacement)
|
18
|
+
|
17
19
|
class Populator
|
18
|
-
|
20
|
+
|
19
21
|
include DataShift::Logging
|
20
|
-
|
22
|
+
|
21
23
|
def self.insistent_method_list
|
22
24
|
@insistent_method_list ||= [:to_s, :to_i, :to_f, :to_b]
|
23
25
|
end
|
24
|
-
|
26
|
+
|
25
27
|
# When looking up an association, when no field provided, try each of these in turn till a match
|
26
28
|
# i.e find_by_name, find_by_title, find_by_id
|
27
29
|
def self.insistent_find_by_list
|
28
30
|
@insistent_find_by_list ||= [:name, :title, :id]
|
29
31
|
end
|
30
|
-
|
31
|
-
|
32
|
+
|
33
|
+
|
34
|
+
# Default data embedded in column headings - so effectively apply globally
|
35
|
+
# to teh whole column - hence class methods
|
36
|
+
def self.set_header_default_data(operator, data )
|
37
|
+
header_default_data[operator] = data
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.header_default_data
|
41
|
+
@header_default_data ||= {}
|
42
|
+
end
|
43
|
+
|
44
|
+
|
32
45
|
attr_reader :current_value, :original_value_before_override
|
46
|
+
attr_reader :current_col_type
|
47
|
+
|
33
48
|
attr_reader :current_attribute_hash
|
34
49
|
attr_reader :current_method_detail
|
35
|
-
|
36
|
-
def initialize
|
50
|
+
|
51
|
+
def initialize
|
37
52
|
@current_value = nil
|
53
|
+
@current_method_detail = nil
|
38
54
|
@original_value_before_override = nil
|
39
55
|
@current_attribute_hash = {}
|
40
56
|
|
41
57
|
end
|
42
|
-
|
43
|
-
#
|
58
|
+
|
59
|
+
# Convert DSL string forms into a hash
|
60
|
+
# e.g
|
61
|
+
#
|
62
|
+
# "{:name => 'autechre'}" => Hash['name'] = autechre'
|
63
|
+
# "{:cost_price => '13.45', :price => 23, :sale_price => 4.23 }"
|
64
|
+
|
65
|
+
def self.string_to_hash( str )
|
66
|
+
h = {}
|
67
|
+
str.gsub(/[{}:]/,'').split(', ').map do |e|
|
68
|
+
k,v = e.split('=>')
|
69
|
+
|
70
|
+
k.strip!
|
71
|
+
v.strip!
|
72
|
+
|
73
|
+
if( v.match(/['"]/) )
|
74
|
+
h[k] = v.gsub(/["']/, '')
|
75
|
+
elsif( v.match(/^\d+$|^\d*\.\d+$|^\.\d+$/) )
|
76
|
+
h[k] = v.to_f
|
77
|
+
else
|
78
|
+
h[k] = v
|
79
|
+
end
|
80
|
+
h
|
81
|
+
end
|
82
|
+
|
83
|
+
h
|
84
|
+
end
|
85
|
+
|
86
|
+
# Set member variables to hold details, value and optional attributes,
|
87
|
+
# to be set on the 'value' once created
|
44
88
|
#
|
45
89
|
# Check supplied value, validate it, and if required :
|
46
90
|
# set to provided default value
|
47
91
|
# prepend any provided prefixes
|
48
92
|
# add any provided postfixes
|
49
93
|
def prepare_data(method_detail, value)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
@
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
94
|
+
|
95
|
+
raise NilDataSuppliedError.new("No method detail supplied for prepare_data") unless(method_detail)
|
96
|
+
|
97
|
+
begin
|
98
|
+
@prepare_data_const_regexp ||= Regexp.new( Delimiters::attribute_list_start + ".*" + Delimiters::attribute_list_end)
|
99
|
+
|
100
|
+
if( value.is_a? ActiveRecord::Relation ) # Rails 4 - query no longer returns an array
|
101
|
+
@current_value = value.to_a
|
102
|
+
elsif( !DataShift::Guards.jruby? && value.class.ancestors.include?(Spreadsheet::Formula))
|
103
|
+
@current_value = value.value
|
104
|
+
elsif( value.class.ancestors.include?(ActiveRecord::Base) || value.is_a?(Array))
|
105
|
+
@current_value = value
|
106
|
+
else
|
107
|
+
@current_value = value.to_s
|
108
|
+
|
109
|
+
attribute_hash = @current_value.slice!(@prepare_data_const_regexp)
|
110
|
+
|
111
|
+
if(attribute_hash)
|
112
|
+
@current_attribute_hash = Populator::string_to_hash( attribute_hash )
|
113
|
+
logger.info "Populator for #{@current_value} has attributes #{@current_attribute_hash.inspect}"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
@current_attribute_hash ||= {}
|
118
|
+
|
119
|
+
@current_method_detail = method_detail
|
120
|
+
|
121
|
+
@current_col_type = @current_method_detail.col_type
|
122
|
+
|
123
|
+
operator = method_detail.operator
|
124
|
+
|
125
|
+
if(has_override?(operator))
|
126
|
+
override_value(operator) # takes precedence over anything else
|
127
|
+
else
|
128
|
+
# if no value check for a defaults from config, headers
|
129
|
+
if(default_value(operator))
|
130
|
+
@current_value = default_value(operator)
|
131
|
+
elsif(Populator::header_default_data[operator])
|
132
|
+
@current_value = Populator::header_default_data[operator].to_s
|
133
|
+
elsif(Populator::header_default_data[operator])
|
134
|
+
@current_value = Populator::header_default_data[operator].to_s
|
135
|
+
elsif(method_detail.find_by_value)
|
136
|
+
@current_value = method_detail.find_by_value
|
137
|
+
end if(value.nil? || value.to_s.empty?)
|
138
|
+
end
|
139
|
+
|
140
|
+
substitute( operator )
|
141
|
+
|
142
|
+
@current_value = "#{prefix(operator)}#{@current_value}" if(prefix(operator))
|
143
|
+
@current_value = "#{@current_value}#{postfix(operator)}" if(postfix(operator))
|
144
|
+
|
145
|
+
rescue => e
|
146
|
+
logger.error("populator failed to prepare data supplied for operator #{method_detail.operator}")
|
147
|
+
logger.error("populator error: #{e.inspect}")
|
148
|
+
logger.error("populator stacktrace: #{e.backtrace.last}")
|
149
|
+
raise DataProcessingError.new("opulator failed to prepare data #{value} for operator #{method_detail.operator}")
|
69
150
|
end
|
70
|
-
|
71
|
-
@current_value = "#{prefix(operator)}#{@current_value}" if(prefix(operator))
|
72
|
-
@current_value = "#{@current_value}#{postfix(operator)}" if(postfix(operator))
|
73
151
|
|
74
152
|
return @current_value, @current_attribute_hash
|
75
153
|
end
|
76
|
-
|
77
|
-
def assign(method_detail, record, value )
|
78
|
-
|
79
|
-
@current_value = value
|
80
|
-
|
81
|
-
# Rails 4 - not an array any more
|
82
|
-
if( value.is_a? ActiveRecord::Relation )
|
83
|
-
logger.warn("Relation passed rather than value #{value.inspect}")
|
84
|
-
@current_value = value.to_a
|
85
|
-
end
|
86
154
|
|
87
|
-
|
155
|
+
# Main client hook
|
156
|
+
|
157
|
+
def prepare_and_assign(method_detail, record, value)
|
158
|
+
|
159
|
+
prepare_data(method_detail, value)
|
160
|
+
|
161
|
+
assign(record)
|
162
|
+
end
|
163
|
+
|
164
|
+
def assign(record)
|
165
|
+
|
166
|
+
raise NilDataSuppliedError.new("No method detail - cannot assign data") unless(current_method_detail)
|
167
|
+
|
168
|
+
operator = current_method_detail.operator
|
169
|
+
|
170
|
+
logger.debug("Populator assign - [#{current_value}] via #{current_method_detail.operator} (#{current_method_detail.operator_type})")
|
171
|
+
|
172
|
+
if( current_method_detail.operator_for(:belongs_to) )
|
173
|
+
|
174
|
+
insistent_belongs_to(current_method_detail, record, current_value)
|
175
|
+
|
176
|
+
elsif( current_method_detail.operator_for(:has_many) )
|
88
177
|
|
89
|
-
operator = method_detail.operator
|
90
|
-
|
91
|
-
if( method_detail.operator_for(:belongs_to) )
|
92
|
-
|
93
|
-
#puts "DEBUG : BELONGS_TO : #{@name} : #{operator} - Lookup #{@current_value} in DB"
|
94
|
-
insistent_belongs_to(method_detail, record, @current_value)
|
95
|
-
|
96
|
-
elsif( method_detail.operator_for(:has_many) )
|
97
|
-
|
98
|
-
puts "DEBUG : VALUE TYPE [#{value.class.name.include?(operator.classify)}] [#{ModelMapper.class_from_string(value.class.name)}]" unless(value.is_a?(Array))
|
99
|
-
|
100
178
|
# The include? check is best I can come up with right now .. to handle module/namespaces
|
101
179
|
# TODO - can we determine the real class type of an association
|
102
180
|
# e.g given a association taxons, which operator.classify gives us Taxon, but actually it's Spree::Taxon
|
103
181
|
# so how do we get from 'taxons' to Spree::Taxons ? .. check if further info in reflect_on_all_associations
|
104
182
|
|
105
|
-
if(
|
106
|
-
record.send(operator) <<
|
107
|
-
|
108
|
-
|
183
|
+
begin #if(current_value.is_a?(Array) || current_value.class.name.include?(operator.classify))
|
184
|
+
record.send(operator) << current_value
|
185
|
+
rescue => e
|
186
|
+
logger.error e.inspect
|
187
|
+
logger.error "Cannot assign #{current_value.inspect} (#{current_value.class}) to has_many association [#{operator}] "
|
109
188
|
end
|
110
189
|
|
111
|
-
elsif(
|
190
|
+
elsif( current_method_detail.operator_for(:has_one) )
|
112
191
|
|
113
192
|
#puts "DEBUG : HAS_MANY : #{@name} : #{operator}(#{operator_class}) - Lookup #{@current_value} in DB"
|
114
|
-
if(
|
115
|
-
record.send(operator + '=',
|
193
|
+
if(current_value.is_a?(current_method_detail.operator_class))
|
194
|
+
record.send(operator + '=', current_value)
|
116
195
|
else
|
117
|
-
logger.error("ERROR #{
|
196
|
+
logger.error("ERROR #{current_value.class} - Not expected type for has_one #{operator} - cannot assign")
|
118
197
|
# TODO - Not expected type - maybe try to look it up somehow ?"
|
119
|
-
#insistent_has_many(record, @current_value)
|
120
198
|
end
|
121
199
|
|
122
|
-
elsif(
|
123
|
-
#
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
200
|
+
elsif( current_method_detail.operator_for(:assignment) && current_col_type)
|
201
|
+
# 'type_cast' was changed to 'type_cast_from_database'
|
202
|
+
if Rails::VERSION::STRING < '4.2.0'
|
203
|
+
logger.debug("Assign #{current_value} => [#{operator}] (CAST 2 TYPE #{current_col_type.type_cast( current_value ).inspect})")
|
204
|
+
record.send( operator + '=' , current_method_detail.col_type.type_cast( current_value ) )
|
205
|
+
else
|
206
|
+
logger.debug("Assign #{current_value} => [#{operator}] (CAST 2 TYPE #{current_col_type.type_cast_from_database( current_value ).inspect})")
|
207
|
+
record.send( operator + '=' , current_method_detail.col_type.type_cast_from_database( current_value ) )
|
208
|
+
end
|
128
209
|
|
129
|
-
elsif(
|
130
|
-
|
210
|
+
elsif( current_method_detail.operator_for(:assignment) )
|
211
|
+
logger.debug("Brute force assignment of value #{current_value} => [#{operator}]")
|
131
212
|
# brute force case for assignments without a column type (which enables us to do correct type_cast)
|
132
213
|
# so in this case, attempt straightforward assignment then if that fails, basic ops such as to_s, to_i, to_f etc
|
133
|
-
insistent_assignment(record,
|
214
|
+
insistent_assignment(record, current_value, operator)
|
134
215
|
else
|
135
216
|
puts "WARNING: No assignment possible on #{record.inspect} using [#{operator}]"
|
136
217
|
logger.error("WARNING: No assignment possible on #{record.inspect} using [#{operator}]")
|
137
218
|
end
|
138
219
|
end
|
139
|
-
|
220
|
+
|
140
221
|
def insistent_assignment(record, value, operator)
|
141
|
-
|
142
|
-
#puts "DEBUG: RECORD CLASS #{record.class}"
|
222
|
+
|
143
223
|
op = operator + '=' unless(operator.include?('='))
|
144
|
-
|
224
|
+
|
145
225
|
begin
|
146
226
|
record.send(op, value)
|
147
227
|
rescue => e
|
228
|
+
|
148
229
|
Populator::insistent_method_list.each do |f|
|
149
230
|
begin
|
150
231
|
record.send(op, value.send( f) )
|
151
232
|
break
|
152
233
|
rescue => e
|
153
|
-
puts "DEBUG: insistent_assignment: #{e.inspect}"
|
154
234
|
if f == Populator::insistent_method_list.last
|
155
|
-
|
156
|
-
|
235
|
+
logger.error(e.inspect)
|
236
|
+
logger.error("Failed to assign [#{value}] via operator #{operator}")
|
237
|
+
raise "Failed to assign [#{value}] to #{operator}" unless value.nil?
|
157
238
|
end
|
158
239
|
end
|
159
240
|
end
|
160
241
|
end
|
161
242
|
end
|
162
|
-
|
243
|
+
|
163
244
|
# Attempt to find the associated object via id, name, title ....
|
164
245
|
def insistent_belongs_to(method_detail, record, value )
|
165
246
|
|
166
247
|
operator = method_detail.operator
|
167
|
-
|
248
|
+
|
168
249
|
if( value.class == method_detail.operator_class)
|
250
|
+
logger.info("Populator assigning #{value} to belongs_to association #{operator}")
|
169
251
|
record.send(operator) << value
|
170
252
|
else
|
171
253
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
logger.error("
|
182
|
-
|
183
|
-
|
254
|
+
# TODO - DRY all this
|
255
|
+
if(method_detail.find_by_operator)
|
256
|
+
|
257
|
+
item = method_detail.operator_class.where(method_detail.find_by_operator => value).first_or_create
|
258
|
+
|
259
|
+
if(item)
|
260
|
+
logger.info("Populator assigning #{item.inspect} to belongs_to association #{operator}")
|
261
|
+
record.send(operator + '=', item)
|
262
|
+
else
|
263
|
+
logger.error("Could not find or create [#{value}] for belongs_to association [#{operator}]")
|
264
|
+
raise CouldNotAssignAssociation.new "Populator failed to assign [#{value}] to belongs_to association [#{operator}]"
|
265
|
+
end
|
266
|
+
|
267
|
+
else
|
268
|
+
#try the default field names
|
269
|
+
Populator::insistent_find_by_list.each do |x|
|
270
|
+
begin
|
271
|
+
|
272
|
+
next unless method_detail.operator_class.respond_to?("where")
|
273
|
+
|
274
|
+
item = method_detail.operator_class.where(x => value).first_or_create
|
275
|
+
|
276
|
+
if(item)
|
277
|
+
logger.info("Populator assigning #{item.inspect} to belongs_to association #{operator}")
|
278
|
+
record.send(operator + '=', item)
|
279
|
+
break
|
280
|
+
end
|
281
|
+
rescue => e
|
282
|
+
logger.error(e.inspect)
|
283
|
+
logger.error("Failed attempting to find belongs_to for #{method_detail.pp}")
|
284
|
+
if(x == Populator::insistent_method_list.last)
|
285
|
+
raise CouldNotAssignAssociation.new "Populator failed to assign [#{value}] to belongs_to association [#{operator}]" unless value.nil?
|
286
|
+
end
|
184
287
|
end
|
185
288
|
end
|
186
289
|
end
|
290
|
+
|
187
291
|
end
|
188
292
|
end
|
189
|
-
|
293
|
+
|
190
294
|
def assignment( operator, record, value )
|
191
|
-
|
295
|
+
|
192
296
|
op = operator + '=' unless(operator.include?('='))
|
193
|
-
|
297
|
+
|
194
298
|
begin
|
195
299
|
record.send(op, value)
|
196
300
|
rescue => e
|
@@ -199,7 +303,6 @@ module DataShift
|
|
199
303
|
record.send(op, value.send( f) )
|
200
304
|
break
|
201
305
|
rescue => e
|
202
|
-
#puts "DEBUG: insistent_assignment: #{e.inspect}"
|
203
306
|
if f == Populator::insistent_method_list.last
|
204
307
|
puts "I'm sorry I have failed to assign [#{value}] to #{operator}"
|
205
308
|
raise "I'm sorry I have failed to assign [#{value}] to #{operator}" unless value.nil?
|
@@ -208,8 +311,8 @@ module DataShift
|
|
208
311
|
end
|
209
312
|
end
|
210
313
|
end
|
211
|
-
|
212
|
-
|
314
|
+
|
315
|
+
|
213
316
|
# Default values and over rides can be provided in Ruby/YAML ???? config file.
|
214
317
|
#
|
215
318
|
# Format :
|
@@ -224,80 +327,93 @@ module DataShift
|
|
224
327
|
#
|
225
328
|
def configure_from(load_object_class, yaml_file)
|
226
329
|
|
227
|
-
data = YAML::load(
|
228
|
-
|
229
|
-
# TODO - MOVE DEFAULTS TO OWN MODULE
|
230
|
-
|
231
|
-
#
|
232
|
-
|
233
|
-
#unless(@default_data_objects[load_object_class])
|
234
|
-
#
|
235
|
-
# @default_data_objects[load_object_class] = load_object_class.new
|
236
|
-
|
237
|
-
# default_data_object = @default_data_objects[load_object_class]
|
238
|
-
|
239
|
-
|
240
|
-
# default_data_object.instance_eval do
|
241
|
-
# def datashift_defaults=(hash)
|
242
|
-
# @datashift_defaults = hash
|
243
|
-
# end
|
244
|
-
# def datashift_defaults
|
245
|
-
# @datashift_defaults
|
246
|
-
# end
|
247
|
-
#end unless load_object_class.respond_to?(:datashift_defaults)
|
248
|
-
#end
|
249
|
-
|
250
|
-
#puts load_object_class.new.to_yaml
|
251
|
-
|
252
|
-
logger.info("Read Datashift loading config: #{data.inspect}")
|
253
|
-
|
330
|
+
data = YAML::load( ERB.new( IO.read(yaml_file) ).result )
|
331
|
+
|
332
|
+
# TODO - MOVE DEFAULTS TO OWN MODULE
|
333
|
+
|
334
|
+
logger.info("Setting Populator defaults: #{data.inspect}")
|
335
|
+
|
254
336
|
if(data[load_object_class.name])
|
255
|
-
|
256
|
-
logger.info("Assigning defaults and over rides from config")
|
257
|
-
|
337
|
+
|
258
338
|
deflts = data[load_object_class.name]['datashift_defaults']
|
259
339
|
default_values.merge!(deflts) if deflts
|
260
|
-
|
340
|
+
|
341
|
+
logger.info("Set Populator default_values: #{default_values.inspect}")
|
342
|
+
|
261
343
|
ovrides = data[load_object_class.name]['datashift_overrides']
|
262
344
|
override_values.merge!(ovrides) if ovrides
|
345
|
+
logger.info("Set Populator overrides: #{override_values.inspect}")
|
346
|
+
|
347
|
+
subs = data[load_object_class.name]['datashift_substitutions']
|
348
|
+
|
349
|
+
subs.each do |o, sub|
|
350
|
+
# TODO support single array as well as multiple [[..,..], [....]]
|
351
|
+
sub.each { |tuple| set_substitution(o, tuple) }
|
352
|
+
end if(subs)
|
353
|
+
|
263
354
|
end
|
264
|
-
|
265
355
|
|
266
356
|
end
|
267
|
-
|
357
|
+
|
358
|
+
# Set a default value to be used to populate Model.operator
|
359
|
+
# Generally defaults will be used when no value supplied.
|
360
|
+
def set_substitution(operator, value )
|
361
|
+
substitutions[operator] ||= []
|
362
|
+
|
363
|
+
substitutions[operator] << Struct::Substitution.new(value[0], value[1])
|
364
|
+
end
|
365
|
+
|
366
|
+
def substitutions
|
367
|
+
@substitutions ||= {}
|
368
|
+
end
|
369
|
+
|
370
|
+
def substitute( operator )
|
371
|
+
subs = substitutions[operator] || {}
|
372
|
+
|
373
|
+
subs.each do |s|
|
374
|
+
@original_value_before_override = @current_value
|
375
|
+
@current_value = @original_value_before_override.gsub(s.pattern.to_s, s.replacement.to_s)
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
|
268
380
|
# Set a value to be used to populate Model.operator
|
269
381
|
# Generally over-rides will be used regardless of what value caller supplied.
|
270
382
|
def set_override_value( operator, value )
|
271
383
|
override_values[operator] = value
|
272
384
|
end
|
273
|
-
|
385
|
+
|
274
386
|
def override_values
|
275
387
|
@override_values ||= {}
|
276
388
|
end
|
277
|
-
|
389
|
+
|
278
390
|
def override_value( operator )
|
279
391
|
if(override_values[operator])
|
280
392
|
@original_value_before_override = @current_value
|
281
|
-
|
393
|
+
|
282
394
|
@current_value = @override_values[operator]
|
283
395
|
end
|
284
396
|
end
|
285
|
-
|
397
|
+
|
398
|
+
|
399
|
+
def has_override?( operator )
|
400
|
+
return override_values.has_key?(operator)
|
401
|
+
end
|
402
|
+
|
286
403
|
# Set a default value to be used to populate Model.operator
|
287
404
|
# Generally defaults will be used when no value supplied.
|
288
405
|
def set_default_value(operator, value )
|
289
406
|
default_values[operator] = value
|
290
407
|
end
|
291
|
-
|
408
|
+
|
292
409
|
def default_values
|
293
410
|
@default_values ||= {}
|
294
411
|
end
|
295
|
-
|
412
|
+
|
296
413
|
# Return the default value for supplied operator
|
297
414
|
def default_value(operator)
|
298
415
|
default_values[operator]
|
299
416
|
end
|
300
|
-
|
301
417
|
|
302
418
|
def set_prefix( operator, value )
|
303
419
|
prefixes[operator] = value
|
@@ -310,7 +426,7 @@ module DataShift
|
|
310
426
|
def prefixes
|
311
427
|
@prefixes ||= {}
|
312
428
|
end
|
313
|
-
|
429
|
+
|
314
430
|
def set_postfix(operator, value )
|
315
431
|
postfixes[operator] = value
|
316
432
|
end
|
@@ -318,12 +434,11 @@ module DataShift
|
|
318
434
|
def postfix(operator)
|
319
435
|
postfixes[operator]
|
320
436
|
end
|
321
|
-
|
437
|
+
|
322
438
|
def postfixes
|
323
439
|
@postfixes ||= {}
|
324
440
|
end
|
325
|
-
|
326
|
-
|
441
|
+
|
327
442
|
end
|
328
|
-
|
443
|
+
|
329
444
|
end
|