datashift 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/.document +5 -5
  2. data/Gemfile +28 -25
  3. data/LICENSE.txt +26 -26
  4. data/README.markdown +302 -285
  5. data/README.rdoc +19 -19
  6. data/Rakefile +93 -95
  7. data/VERSION +5 -5
  8. data/datashift.gemspec +162 -178
  9. data/lib/applications/jruby/jexcel_file.rb +396 -396
  10. data/lib/applications/jruby/word.rb +79 -79
  11. data/lib/datashift.rb +152 -113
  12. data/lib/datashift/exceptions.rb +11 -11
  13. data/lib/datashift/file_definitions.rb +353 -353
  14. data/lib/datashift/mapping_file_definitions.rb +87 -87
  15. data/lib/datashift/method_detail.rb +236 -236
  16. data/lib/datashift/method_mapper.rb +256 -256
  17. data/lib/generators/csv_generator.rb +36 -36
  18. data/lib/generators/excel_generator.rb +121 -121
  19. data/lib/generators/generator_base.rb +13 -13
  20. data/lib/helpers/core_ext/to_b.rb +24 -24
  21. data/lib/helpers/spree_helper.rb +131 -131
  22. data/lib/java/poi-3.7/LICENSE +507 -507
  23. data/lib/java/poi-3.7/NOTICE +21 -21
  24. data/lib/java/poi-3.7/RELEASE_NOTES.txt +115 -115
  25. data/lib/loaders/csv_loader.rb +98 -98
  26. data/lib/loaders/excel_loader.rb +154 -149
  27. data/lib/loaders/loader_base.rb +403 -331
  28. data/lib/loaders/spreadsheet_loader.rb +136 -136
  29. data/lib/loaders/spree/image_loader.rb +45 -45
  30. data/lib/loaders/spree/product_loader.rb +224 -224
  31. data/spec/csv_loader_spec.rb +30 -30
  32. data/spec/datashift_spec.rb +26 -26
  33. data/spec/db/migrate/20110803201325_create_test_bed.rb +85 -85
  34. data/spec/excel_generator_spec.rb +78 -78
  35. data/spec/excel_loader_spec.rb +204 -176
  36. data/spec/file_definitions.rb +141 -141
  37. data/spec/fixtures/.~lock.ProjectsSingleCategories.xls# +1 -0
  38. data/spec/fixtures/ProjectsDefaults.yml +29 -0
  39. data/spec/fixtures/config/database.yml +24 -24
  40. data/spec/fixtures/interact_models_db.sqlite +0 -0
  41. data/spec/fixtures/interact_spree_db.sqlite +0 -0
  42. data/spec/fixtures/negative/SpreeProdMiss1Mandatory.csv +4 -4
  43. data/spec/fixtures/negative/SpreeProdMissManyMandatory.csv +4 -4
  44. data/spec/fixtures/spree/SpreeProducts.csv +4 -4
  45. data/spec/fixtures/spree/SpreeProductsMultiColumn.csv +4 -4
  46. data/spec/fixtures/spree/SpreeProductsSimple.csv +4 -4
  47. data/spec/fixtures/spree/SpreeZoneExample.csv +5 -5
  48. data/spec/fixtures/test_model_defs.rb +57 -57
  49. data/spec/loader_spec.rb +120 -120
  50. data/spec/method_mapper_spec.rb +237 -237
  51. data/spec/spec_helper.rb +115 -115
  52. data/spec/spree_generator_spec.rb +64 -64
  53. data/spec/spree_loader_spec.rb +310 -310
  54. data/spec/spree_method_mapping_spec.rb +214 -214
  55. data/tasks/config/seed_fu_product_template.erb +15 -15
  56. data/tasks/config/tidy_config.txt +12 -12
  57. data/tasks/db_tasks.rake +65 -64
  58. data/tasks/excel_generator.rake +78 -78
  59. data/tasks/file_tasks.rake +36 -36
  60. data/tasks/import/csv.rake +49 -49
  61. data/tasks/import/excel.rake +71 -66
  62. data/tasks/spree/image_load.rake +108 -108
  63. data/tasks/spree/product_loader.rake +43 -43
  64. data/tasks/word_to_seedfu.rake +166 -166
  65. data/test/helper.rb +18 -18
  66. data/test/test_interact.rb +7 -7
  67. metadata +7 -38
  68. data/Gemfile.lock +0 -211
  69. data/bin/autospec +0 -16
  70. data/bin/convert_to_should_syntax +0 -16
  71. data/bin/erubis +0 -16
  72. data/bin/htmldiff +0 -16
  73. data/bin/jeweler +0 -16
  74. data/bin/ldiff +0 -16
  75. data/bin/nokogiri +0 -16
  76. data/bin/rackup +0 -16
  77. data/bin/rails +0 -16
  78. data/bin/rake +0 -16
  79. data/bin/rake2thor +0 -16
  80. data/bin/ri +0 -16
  81. data/bin/rspec +0 -16
  82. data/bin/spree +0 -16
  83. data/bin/thor +0 -16
  84. data/bin/tilt +0 -16
  85. data/bin/tt +0 -16
@@ -1,88 +1,88 @@
1
- # This class provides a value map (hash) from a text mapping file
2
- #
3
- # The map file is a text file of delimeted key -> values pairs
4
- #
5
- # SUPPORTED FILE FORMATS:
6
- #
7
- # 2 column e.g. a,b
8
- # creates a simple hash {a => b)
9
- #
10
- # 3 column e.g. a,b,c
11
- # a,b becomes the key, c is the vaule
12
- # creates a hash { [a,b] => c }
13
- #
14
- # 4 column e.g. a,b,c,d
15
- # a,b becomes the key, c,d the value
16
- # creates a hash { [a,b] => [c,d] }
17
- #
18
- # TODO allow mapping file to be an xml file
19
- #
20
- class ValueMapFromFile < Hash
21
-
22
- def intialize(file_path, delim = ',')
23
- @delegate_to = {}
24
- @delim = delim
25
- load_map(file_path)
26
- end
27
-
28
- def load_map(file_path = nil, delim = ',')
29
- @file = file_path unless file_path.nil?
30
- @delim = delim
31
-
32
- raise ArgumentError.new("Can not read map file: #{@file}") unless File.readable?(@file)
33
-
34
- File.open(@file).each_line do |line|
35
- next unless(line && line.chomp!)
36
-
37
- values = line.split(@delim)
38
-
39
- case values.nitems
40
- when 2 then self.store(values[0], values[1])
41
- when 3 then self.store([values[0], values[1]], values[2])
42
- when 4 then self.store([values[0], values[1]],[values[2], values[3]])
43
- else
44
- raise ArgumentError.new("Bad key,value row in #{@file}: #{values.nitems} number of columns not supported")
45
- end
46
- end
47
-
48
- return self
49
- end
50
- end
51
-
52
-
53
- # Expects file of format [TradeType,LDN_TradeId,HUB_TradeId,LDN_AssetId,HUB_AssetId,LDN_StrutureId,HUB_StructureId,LDN_ProductType,HUB_ProductType]
54
- # Convets in to and araya containing rows [LDN_TradeId, LDN_AssetId, HUB_TradeId, HUB_AssetId]
55
- class AssetMapFromFile < Array
56
-
57
- def intialize(file_path, delim = ',')
58
- @delegate_to = {}
59
- @delim = delim
60
- load_map(file_path)
61
- end
62
-
63
- def load_map(file_path = nil, delim = ',')
64
- @file = file_path unless file_path.nil?
65
- @delim = delim
66
-
67
- raise ArgumentError.new("Can not read asset map file: #{@file}") unless File.readable?(@file)
68
-
69
- File.open(@file).each_line do |line|
70
- next unless(line && line.chomp!)
71
- # skip the header row
72
- next if line.include?('TradeType')
73
-
74
- values = line.split(@delim)
75
-
76
- self.push(Array[values[1], values[3], values[2], values[4]])
77
- end
78
-
79
- return self
80
- end
81
-
82
- def write_map(file_path = nil, delim = ',')
83
- mapfile = File.open( file_path, 'w')
84
-
85
- self.each{|row| mapfile.write(row.join(delim)+"\n")}
86
- end
87
-
1
+ # This class provides a value map (hash) from a text mapping file
2
+ #
3
+ # The map file is a text file of delimeted key -> values pairs
4
+ #
5
+ # SUPPORTED FILE FORMATS:
6
+ #
7
+ # 2 column e.g. a,b
8
+ # creates a simple hash {a => b)
9
+ #
10
+ # 3 column e.g. a,b,c
11
+ # a,b becomes the key, c is the vaule
12
+ # creates a hash { [a,b] => c }
13
+ #
14
+ # 4 column e.g. a,b,c,d
15
+ # a,b becomes the key, c,d the value
16
+ # creates a hash { [a,b] => [c,d] }
17
+ #
18
+ # TODO allow mapping file to be an xml file
19
+ #
20
+ class ValueMapFromFile < Hash
21
+
22
+ def intialize(file_path, delim = ',')
23
+ @delegate_to = {}
24
+ @delim = delim
25
+ load_map(file_path)
26
+ end
27
+
28
+ def load_map(file_path = nil, delim = ',')
29
+ @file = file_path unless file_path.nil?
30
+ @delim = delim
31
+
32
+ raise ArgumentError.new("Can not read map file: #{@file}") unless File.readable?(@file)
33
+
34
+ File.open(@file).each_line do |line|
35
+ next unless(line && line.chomp!)
36
+
37
+ values = line.split(@delim)
38
+
39
+ case values.nitems
40
+ when 2 then self.store(values[0], values[1])
41
+ when 3 then self.store([values[0], values[1]], values[2])
42
+ when 4 then self.store([values[0], values[1]],[values[2], values[3]])
43
+ else
44
+ raise ArgumentError.new("Bad key,value row in #{@file}: #{values.nitems} number of columns not supported")
45
+ end
46
+ end
47
+
48
+ return self
49
+ end
50
+ end
51
+
52
+
53
+ # Expects file of format [TradeType,LDN_TradeId,HUB_TradeId,LDN_AssetId,HUB_AssetId,LDN_StrutureId,HUB_StructureId,LDN_ProductType,HUB_ProductType]
54
+ # Convets in to and araya containing rows [LDN_TradeId, LDN_AssetId, HUB_TradeId, HUB_AssetId]
55
+ class AssetMapFromFile < Array
56
+
57
+ def intialize(file_path, delim = ',')
58
+ @delegate_to = {}
59
+ @delim = delim
60
+ load_map(file_path)
61
+ end
62
+
63
+ def load_map(file_path = nil, delim = ',')
64
+ @file = file_path unless file_path.nil?
65
+ @delim = delim
66
+
67
+ raise ArgumentError.new("Can not read asset map file: #{@file}") unless File.readable?(@file)
68
+
69
+ File.open(@file).each_line do |line|
70
+ next unless(line && line.chomp!)
71
+ # skip the header row
72
+ next if line.include?('TradeType')
73
+
74
+ values = line.split(@delim)
75
+
76
+ self.push(Array[values[1], values[3], values[2], values[4]])
77
+ end
78
+
79
+ return self
80
+ end
81
+
82
+ def write_map(file_path = nil, delim = ',')
83
+ mapfile = File.open( file_path, 'w')
84
+
85
+ self.each{|row| mapfile.write(row.join(delim)+"\n")}
86
+ end
87
+
88
88
  end
@@ -1,237 +1,237 @@
1
- # Copyright:: (c) Autotelik Media Ltd 2011
2
- # Author :: Tom Statter
3
- # Date :: Aug 2010
4
- # License:: MIT
5
- #
6
- # Details:: This class provides info and access to the individual population methods
7
- # on an AR model. Populated by, and coupled with MethodMapper,
8
- # which does the model interrogation work and stores sets of MethodDetails.
9
- #
10
- # Enables 'loaders' to iterate over the MethodMapper results set,
11
- # and assign values to AR object, without knowing anything about that receiving object.
12
- #
13
- require 'to_b'
14
-
15
- module DataShift
16
-
17
- class MethodDetail
18
-
19
- def self.type_enum
20
- @type_enum ||= Set[:assignment, :belongs_to, :has_one, :has_many]
21
- @type_enum
22
- end
23
-
24
- # When looking up an association, try each of these in turn till a match
25
- # i.e find_by_name .. find_by_title and so on, lastly try the raw id
26
- @@insistent_find_by_list ||= [:name, :title, :id]
27
-
28
- # Name is the raw, client supplied name
29
- attr_reader :name, :col_type, :current_value
30
-
31
- attr_reader :operator, :operator_type
32
-
33
- # Store the raw (client supplied) name against the active record klass(model), operator and types
34
- # col_types can typically be derived from klass.columns - set of ActiveRecord::ConnectionAdapters::Column
35
-
36
- def initialize(client_name, klass, operator, type, col_types = {} )
37
- @klass, @name = klass, client_name
38
-
39
- if( MethodDetail::type_enum.member?(type.to_sym) )
40
- @operator_type = type
41
- else
42
- raise "Bad operator Type #{type} passed to Method Detail"
43
- end
44
-
45
- @operator = operator
46
-
47
- # Note : Not all assignments will currently have a column type, for example
48
- # those that are derived from a delegate_belongs_to
49
- if(col_types.empty?)
50
- @col_type = klass.columns.find{ |col| col.name == operator }
51
- else
52
- @col_type = col_types[operator]
53
- end
54
- end
55
-
56
-
57
- # Return the actual operator's name for supplied method type
58
- # where type one of :assignment, :has_one, :belongs_to, :has_many etc
59
- def operator_for( type )
60
- return operator if(@operator_type == type)
61
- nil
62
- end
63
-
64
- def operator?(name)
65
- operator == name
66
- end
67
-
68
- # Return the operator's expected class name, if can be derived, else nil
69
- def operator_class_name()
70
- @operator_class_name ||= if(operator_for(:has_many) || operator_for(:belongs_to) || operator_for(:has_one))
71
- begin
72
- Kernel.const_get(operator.classify)
73
- operator.classify
74
- rescue; ""; end
75
-
76
- elsif(@col_type)
77
- @col_type.type.to_s.classify
78
- else
79
- ""
80
- end
81
-
82
- @operator_class_name
83
- end
84
-
85
- # Return the operator's expected class, if can be derived, else nil
86
- def operator_class()
87
- @operator_class ||= if(operator_for(:has_many) || operator_for(:belongs_to) || operator_for(:has_one))
88
- begin
89
- Kernel.const_get(operator.classify)
90
- rescue; ""; end
91
-
92
- elsif(@col_type)
93
- begin
94
- Kernel.const_get(@col_type.type.to_s.classify)
95
- rescue; nil; end
96
- else
97
- nil
98
- end
99
-
100
- @operator_class
101
- end
102
-
103
-
104
- def assign(record, value )
105
-
106
- @current_value = value
107
-
108
- puts "WARNING nil value supplied for Column [#{@name}]" if(@current_value.nil?)
109
-
110
- if( operator_for(:belongs_to) )
111
-
112
- #puts "DEBUG : BELONGS_TO : #{@name} : #{operator} - Lookup #{@current_value} in DB"
113
- insistent_belongs_to(record, @current_value)
114
-
115
- elsif( operator_for(:has_many) )
116
-
117
- #puts "DEBUG : HAS_MANY : #{@name} : #{operator}(#{operator_class}) - Lookup #{@current_value} in DB"
118
- if(value.is_a?(Array) || value.is_a?(operator_class))
119
- record.send(operator) << value
120
- else
121
- puts "ERROR #{value.class} - Not expected type for has_many #{operator} - cannot assign"
122
- # TODO - Not expected type - maybe try to look it up somehow ?"
123
- #insistent_has_many(record, @current_value)
124
- end
125
-
126
- elsif( operator_for(:has_one) )
127
-
128
- #puts "DEBUG : HAS_MANY : #{@name} : #{operator}(#{operator_class}) - Lookup #{@current_value} in DB"
129
- if(value.is_a?(operator_class))
130
- record.send(operator + '=', value)
131
- else
132
- puts "ERROR #{value.class} - Not expected type for has_one #{operator} - cannot assign"
133
- # TODO - Not expected type - maybe try to look it up somehow ?"
134
- #insistent_has_many(record, @current_value)
135
- end
136
-
137
- elsif( operator_for(:assignment) && @col_type )
138
- #puts "DEBUG : COl TYPE defined for #{@name} : #{@assignment} => #{@current_value} #{@col_type.type}"
139
- #puts "DEBUG : COl TYPE CAST: #{@current_value} => #{@col_type.type_cast( @current_value ).inspect}"
140
- record.send( operator + '=' , @col_type.type_cast( @current_value ) )
141
-
142
- #puts "DEBUG : MethodDetails Assignment RESULT: #{record.send(operator)}"
143
-
144
- elsif( operator_for(:assignment) )
145
- #puts "DEBUG : Brute force assignment of value #{@current_value} supplied for Column [#{@name}]"
146
- # brute force case for assignments without a column type (which enables us to do correct type_cast)
147
- # so in this case, attempt straightforward assignment then if that fails, basic ops such as to_s, to_i, to_f etc
148
- insistent_assignment(record, @current_value)
149
- else
150
- puts "WARNING: No operator found for assignment on #{self.inspect} for Column [#{@name}]"
151
- end
152
- end
153
-
154
- def pp
155
- "#{@name} => #{operator}"
156
- end
157
-
158
-
159
- def self.insistent_method_list
160
- @insistent_method_list ||= [:to_s, :to_i, :to_f, :to_b]
161
- @insistent_method_list
162
- end
163
-
164
- private
165
-
166
- # Attempt to find the associated object via id, name, title ....
167
- def insistent_belongs_to( record, value )
168
-
169
- if( value.class == operator_class)
170
- record.send(operator) << value
171
- else
172
-
173
- @@insistent_find_by_list.each do |x|
174
- begin
175
- next unless operator_class.respond_to?( "find_by_#{x}" )
176
- item = operator_class.send( "find_by_#{x}", value)
177
- if(item)
178
- record.send(operator + '=', item)
179
- break
180
- end
181
- rescue => e
182
- puts "ERROR: #{e.inspect}"
183
- if(x == MethodDetail::insistent_method_list.last)
184
- raise "I'm sorry I have failed to assign [#{value}] to #{@assignment}" unless value.nil?
185
- end
186
- end
187
- end
188
- end
189
- end
190
-
191
- # Attempt to find the associated object via id, name, title ....
192
- def insistent_has_many( record, value )
193
-
194
- if( value.class == operator_class)
195
- record.send(operator) << value
196
- else
197
- @@insistent_find_by_list.each do |x|
198
- begin
199
- item = operator_class.send( "find_by_#{x}", value)
200
- if(item)
201
- record.send(operator) << item
202
- break
203
- end
204
- rescue => e
205
- puts "ERROR: #{e.inspect}"
206
- if(x == MethodDetail::insistent_method_list.last)
207
- raise "I'm sorry I have failed to assign [#{value}] to #{operator}" unless value.nil?
208
- end
209
- end
210
- end
211
- end
212
- end
213
-
214
- def insistent_assignment( record, value )
215
- #puts "DEBUG: RECORD CLASS #{record.class}"
216
- op = operator + '='
217
-
218
- begin
219
- record.send(op, value)
220
- rescue => e
221
- MethodDetail::insistent_method_list.each do |f|
222
- begin
223
- record.send(op, value.send( f) )
224
- break
225
- rescue => e
226
- #puts "DEBUG: insistent_assignment: #{e.inspect}"
227
- if f == MethodDetail::insistent_method_list.last
228
- puts "I'm sorry I have failed to assign [#{value}] to #{operator}"
229
- raise "I'm sorry I have failed to assign [#{value}] to #{operator}" unless value.nil?
230
- end
231
- end
232
- end
233
- end
234
- end
235
- end
236
-
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Aug 2010
4
+ # License:: MIT
5
+ #
6
+ # Details:: This class provides info and access to the individual population methods
7
+ # on an AR model. Populated by, and coupled with MethodMapper,
8
+ # which does the model interrogation work and stores sets of MethodDetails.
9
+ #
10
+ # Enables 'loaders' to iterate over the MethodMapper results set,
11
+ # and assign values to AR object, without knowing anything about that receiving object.
12
+ #
13
+ require 'to_b'
14
+
15
+ module DataShift
16
+
17
+ class MethodDetail
18
+
19
+ def self.type_enum
20
+ @type_enum ||= Set[:assignment, :belongs_to, :has_one, :has_many]
21
+ @type_enum
22
+ end
23
+
24
+ # When looking up an association, try each of these in turn till a match
25
+ # i.e find_by_name .. find_by_title and so on, lastly try the raw id
26
+ @@insistent_find_by_list ||= [:name, :title, :id]
27
+
28
+ # Name is the raw, client supplied name
29
+ attr_reader :name, :col_type, :current_value
30
+
31
+ attr_reader :operator, :operator_type
32
+
33
+ # Store the raw (client supplied) name against the active record klass(model), operator and types
34
+ # col_types can typically be derived from klass.columns - set of ActiveRecord::ConnectionAdapters::Column
35
+
36
+ def initialize(client_name, klass, operator, type, col_types = {} )
37
+ @klass, @name = klass, client_name
38
+
39
+ if( MethodDetail::type_enum.member?(type.to_sym) )
40
+ @operator_type = type
41
+ else
42
+ raise "Bad operator Type #{type} passed to Method Detail"
43
+ end
44
+
45
+ @operator = operator
46
+
47
+ # Note : Not all assignments will currently have a column type, for example
48
+ # those that are derived from a delegate_belongs_to
49
+ if(col_types.empty?)
50
+ @col_type = klass.columns.find{ |col| col.name == operator }
51
+ else
52
+ @col_type = col_types[operator]
53
+ end
54
+ end
55
+
56
+
57
+ # Return the actual operator's name for supplied method type
58
+ # where type one of :assignment, :has_one, :belongs_to, :has_many etc
59
+ def operator_for( type )
60
+ return operator if(@operator_type == type)
61
+ nil
62
+ end
63
+
64
+ def operator?(name)
65
+ operator == name
66
+ end
67
+
68
+ # Return the operator's expected class name, if can be derived, else nil
69
+ def operator_class_name()
70
+ @operator_class_name ||= if(operator_for(:has_many) || operator_for(:belongs_to) || operator_for(:has_one))
71
+ begin
72
+ Kernel.const_get(operator.classify)
73
+ operator.classify
74
+ rescue; ""; end
75
+
76
+ elsif(@col_type)
77
+ @col_type.type.to_s.classify
78
+ else
79
+ ""
80
+ end
81
+
82
+ @operator_class_name
83
+ end
84
+
85
+ # Return the operator's expected class, if can be derived, else nil
86
+ def operator_class()
87
+ @operator_class ||= if(operator_for(:has_many) || operator_for(:belongs_to) || operator_for(:has_one))
88
+ begin
89
+ Kernel.const_get(operator.classify)
90
+ rescue; ""; end
91
+
92
+ elsif(@col_type)
93
+ begin
94
+ Kernel.const_get(@col_type.type.to_s.classify)
95
+ rescue; nil; end
96
+ else
97
+ nil
98
+ end
99
+
100
+ @operator_class
101
+ end
102
+
103
+
104
+ def assign(record, value )
105
+
106
+ @current_value = value
107
+
108
+ # logger.info("WARNING nil value supplied for Column [#{@name}]") if(@current_value.nil?)
109
+
110
+ if( operator_for(:belongs_to) )
111
+
112
+ #puts "DEBUG : BELONGS_TO : #{@name} : #{operator} - Lookup #{@current_value} in DB"
113
+ insistent_belongs_to(record, @current_value)
114
+
115
+ elsif( operator_for(:has_many) )
116
+
117
+ #puts "DEBUG : HAS_MANY : #{@name} : #{operator}(#{operator_class}) - Lookup #{@current_value} in DB"
118
+ if(value.is_a?(Array) || value.is_a?(operator_class))
119
+ record.send(operator) << value
120
+ else
121
+ puts "ERROR #{value.class} - Not expected type for has_many #{operator} - cannot assign"
122
+ # TODO - Not expected type - maybe try to look it up somehow ?"
123
+ #insistent_has_many(record, @current_value)
124
+ end
125
+
126
+ elsif( operator_for(:has_one) )
127
+
128
+ #puts "DEBUG : HAS_MANY : #{@name} : #{operator}(#{operator_class}) - Lookup #{@current_value} in DB"
129
+ if(value.is_a?(operator_class))
130
+ record.send(operator + '=', value)
131
+ else
132
+ puts "ERROR #{value.class} - Not expected type for has_one #{operator} - cannot assign"
133
+ # TODO - Not expected type - maybe try to look it up somehow ?"
134
+ #insistent_has_many(record, @current_value)
135
+ end
136
+
137
+ elsif( operator_for(:assignment) && @col_type )
138
+ #puts "DEBUG : COl TYPE defined for #{@name} : #{@assignment} => #{@current_value} #{@col_type.type}"
139
+ #puts "DEBUG : COl TYPE CAST: #{@current_value} => #{@col_type.type_cast( @current_value ).inspect}"
140
+ record.send( operator + '=' , @col_type.type_cast( @current_value ) )
141
+
142
+ #puts "DEBUG : MethodDetails Assignment RESULT: #{record.send(operator)}"
143
+
144
+ elsif( operator_for(:assignment) )
145
+ #puts "DEBUG : Brute force assignment of value #{@current_value} supplied for Column [#{@name}]"
146
+ # brute force case for assignments without a column type (which enables us to do correct type_cast)
147
+ # so in this case, attempt straightforward assignment then if that fails, basic ops such as to_s, to_i, to_f etc
148
+ insistent_assignment(record, @current_value)
149
+ else
150
+ puts "WARNING: No operator found for assignment on #{self.inspect} for Column [#{@name}]"
151
+ end
152
+ end
153
+
154
+ def pp
155
+ "#{@name} => #{operator}"
156
+ end
157
+
158
+
159
+ def self.insistent_method_list
160
+ @insistent_method_list ||= [:to_s, :to_i, :to_f, :to_b]
161
+ @insistent_method_list
162
+ end
163
+
164
+ private
165
+
166
+ # Attempt to find the associated object via id, name, title ....
167
+ def insistent_belongs_to( record, value )
168
+
169
+ if( value.class == operator_class)
170
+ record.send(operator) << value
171
+ else
172
+
173
+ @@insistent_find_by_list.each do |x|
174
+ begin
175
+ next unless operator_class.respond_to?( "find_by_#{x}" )
176
+ item = operator_class.send( "find_by_#{x}", value)
177
+ if(item)
178
+ record.send(operator + '=', item)
179
+ break
180
+ end
181
+ rescue => e
182
+ puts "ERROR: #{e.inspect}"
183
+ if(x == MethodDetail::insistent_method_list.last)
184
+ raise "I'm sorry I have failed to assign [#{value}] to #{@assignment}" unless value.nil?
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
190
+
191
+ # Attempt to find the associated object via id, name, title ....
192
+ def insistent_has_many( record, value )
193
+
194
+ if( value.class == operator_class)
195
+ record.send(operator) << value
196
+ else
197
+ @@insistent_find_by_list.each do |x|
198
+ begin
199
+ item = operator_class.send( "find_by_#{x}", value)
200
+ if(item)
201
+ record.send(operator) << item
202
+ break
203
+ end
204
+ rescue => e
205
+ puts "ERROR: #{e.inspect}"
206
+ if(x == MethodDetail::insistent_method_list.last)
207
+ raise "I'm sorry I have failed to assign [#{value}] to #{operator}" unless value.nil?
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
213
+
214
+ def insistent_assignment( record, value )
215
+ #puts "DEBUG: RECORD CLASS #{record.class}"
216
+ op = operator + '='
217
+
218
+ begin
219
+ record.send(op, value)
220
+ rescue => e
221
+ MethodDetail::insistent_method_list.each do |f|
222
+ begin
223
+ record.send(op, value.send( f) )
224
+ break
225
+ rescue => e
226
+ #puts "DEBUG: insistent_assignment: #{e.inspect}"
227
+ if f == MethodDetail::insistent_method_list.last
228
+ puts "I'm sorry I have failed to assign [#{value}] to #{operator}"
229
+ raise "I'm sorry I have failed to assign [#{value}] to #{operator}" unless value.nil?
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
236
+
237
237
  end