datashift 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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