mass_record 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 054417da2bfb6c27e10c6cab4a43749a4e7c5928
4
- data.tar.gz: 2cc23822c8fadd28876fa92ddeedd0d55d020611
3
+ metadata.gz: 5eaa64bad4860bb2f6d3630a437f539b02e94598
4
+ data.tar.gz: c46e691401efbe81bd591d98eceda9166edc1f27
5
5
  SHA512:
6
- metadata.gz: 796999b036af5527ac05d769d037f46ec45d22cca212348fe012dd147e736f047792ef2f98858b8d94a565db16e665127e9f77583c969c6e7243af2f9478892d
7
- data.tar.gz: 03a884f22b6df45f46fe11cc0a192b115a86a22302015abc434792ab89c64faa7037b17e1962755a2f3cc9a715ace191536340bcee17a2d6955c5b236bde2aff
6
+ metadata.gz: 33bfc72ba9cc48048035faa29702ea843fe50e3dcece44c5017c683fd92876bd665a2878c81c6f5d666ccf6e369c850fea9f6015e54b00d31703112ebf96460e
7
+ data.tar.gz: 2c35b274cf2f33e2c5971dadf0d1926679956781a9f192397a48577c1c1cb15ade952f9692f300516d929d85a082c27c95c9953d2feca1c67c133a8819b35bd9
@@ -1,3 +1,3 @@
1
1
  module MassRecord
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/mass_record.rb CHANGED
@@ -9,6 +9,7 @@ module MassRecord
9
9
  self.path[:errored_queries] = "tmp/#{Rails.env}"
10
10
  self.path[:completed_queries] = "tmp/#{Rails.env}"
11
11
 
12
+
12
13
  module Actions
13
14
  path = {}
14
15
  folder_path = "tmp/#{Rails.env}"
@@ -17,6 +18,27 @@ module MassRecord
17
18
  path[:errored_queries] = "#{path[:queries]}/errored"
18
19
  path[:completed_queries] = "#{path[:queries]}/completed"
19
20
 
21
+ class IndividualError < Exception
22
+ attr_accessor :operation,:table,:json_object,:original_exception,:backtrace,:backtrace_locations,:cause,:exception,:message
23
+
24
+ def initialize exception, json_object:nil, operation:nil, table:nil
25
+ self.backtrace = exception.backtrace
26
+ self.backtrace_locations = exception.backtrace_locations
27
+ self.cause = exception.cause
28
+ self.exception = exception.exception
29
+ self.message = exception.message
30
+
31
+ self.original_exception = exception
32
+ self.json_object = json_object
33
+ self.operation = operation
34
+ self.table = table
35
+ end
36
+
37
+ def to_s
38
+ original_exception.to_s
39
+ end
40
+ end
41
+
20
42
  # accepts an array of objects with the option to specify what rails operation to perform
21
43
  def queue_for_quick_query object_array,
22
44
  operation: :save,
@@ -45,7 +67,9 @@ module MassRecord
45
67
  },synonyms:{
46
68
  insert: [:create, :new, :add, :insert, :post],
47
69
  update: [:update,:edit,:modify,:put,:patch],
48
- select: [:read,:select,:get]
70
+ select: [:read,:select,:get],
71
+ save: [:save],
72
+ delete: [:delete]
49
73
  },folder:{
50
74
  queued:path[:queued_queries],
51
75
  errored:path[:errored_queries],
@@ -82,25 +106,271 @@ module MassRecord
82
106
  errors[:insert] = mass_insert_by_table json_objects.select{|x| synonyms[:insert].include? x[key[:operation]].to_sym.downcase}, key:key
83
107
  elsif synonyms[:update].include? op
84
108
  errors[:update] = mass_update_by_table json_objects.select{|x| synonyms[:update].include? x[key[:operation]].to_sym.downcase}, key:key
85
- elsif op == :save # needs to intelligently determine if the order already exists, insert if not, update if so
109
+ elsif synonyms[:save].include? op # needs to intelligently determine if the order already exists, insert if not, update if so
86
110
  errors[:save] = mass_save_by_table json_objects.select{|x| :save == x[key[:operation]].to_sym.downcase}, key:key
87
- elsif op == :delete
111
+ elsif synonyms[:delete].include? op
88
112
  elsif synonyms[:select].include? op
89
113
  else
90
114
  end
91
115
  end
92
116
 
93
117
  # close database connection
94
- database_connection.close
95
118
 
96
119
  # move to appropriate folder and remove '.processing' from the filename
120
+ errors_present = errors.any?{|op,tables| tables.has_key? :run_time or tables.any?{|table,col_sets| !table.blank?}}
121
+ errored_objects = collect_errored_objects found_in:errors, from:json_objects, key:key, synonyms:synonyms if errors_present
122
+
123
+ individual_errors = errors_present ? (query_per_object errored_objects, key:key, synonyms:synonyms) : []
124
+ database_connection.close
125
+
97
126
  files = Dir.foreach(folder[:queued]).collect{|x| x}.keep_if{|y|y=~/\.json\.processing$/i}
98
- errors_present = errors.any?{|op,h| h.any?{|table,a| a.count > 0 }}
99
127
  files.each{|x| File.rename "#{folder[:queued]}/#{x}","#{errors_present ? folder[:errored] : folder[:completed]}/group_#{file_tag}_#{x.gsub /\.processing$/,''}"}
100
128
 
129
+ individual_errors += collect_run_time_errors found_in:errors
130
+ return individual_errors
131
+ end
132
+
133
+ def collect_run_time_errors found_in:{}, loop_limit:10
134
+ return [] if found_in.blank?
135
+ run_time_errors = []
136
+
137
+ while found_in.is_a? Hash and loop_limit > 0
138
+ loop_limit -= 1
139
+ found_in.each do |k,v|
140
+ if k == :run_time
141
+ run_time_errors << v
142
+ else
143
+ run_time_errors += collect_run_time_errors found_in:v, loop_limit:loop_limit
144
+ end
145
+ end
146
+ end
147
+ return run_time_errors
148
+ end
149
+
150
+ def collect_errored_objects found_in:{}, from:[], key:{}, synonyms:{}
151
+ return [] if found_in.blank? or from.blank?
152
+
153
+ errored_objects = []
154
+
155
+ found_in.each do |operation, tables|
156
+ unless operation == :run_time
157
+ tables.each do |table, column_sets|
158
+ unless table == :run_time
159
+ column_sets.each do |column_set,error|
160
+ unless column_set == :run_time
161
+ if error.is_a? Exception and error.is_a? ActiveRecord::StatementInvalid
162
+ # collect objects by operation, table, and column set
163
+ operation_terms = synonyms[operation.to_sym]
164
+ errored_objects += from.select{|x| table.to_s == x[key[:table]].to_s and operation_terms.include? x[key[:operation]].to_sym and x[key[:object]].keys.sort == column_set.sort}
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
172
+
173
+ return errored_objects
174
+ end
175
+
176
+ def query_per_object objects, key:{}, synonyms:{}
177
+ # get all operations and tables in use
178
+ operations = objects.collect{|x| x[key[:operation]].to_sym}.to_set.to_a
179
+
180
+ # construct queries
181
+ errors = []
182
+ operations.each do |op|
183
+ if synonyms[:insert].include? op
184
+ errors += insert_by_table objects.select{|x| synonyms[:insert].include? x[key[:operation]].to_sym.downcase}, key:key
185
+ elsif synonyms[:update].include? op
186
+ errors += update_by_table objects.select{|x| synonyms[:update].include? x[key[:operation]].to_sym.downcase}, key:key
187
+ elsif synonyms[:save].include? op # needs to intelligently determine if the order already exists, insert if not, update if so
188
+ errors += save_by_table objects.select{|x| :save == x[key[:operation]].to_sym.downcase}, key:key
189
+ elsif synonyms[:delete].include? op
190
+ elsif synonyms[:select].include? op
191
+ else
192
+ end
193
+ end
101
194
  return errors
102
195
  end
103
196
 
197
+ def update_by_table json_objects, key:{}
198
+ begin
199
+ tables = json_objects.collect{|x| x[key[:table]]}.to_set.to_a
200
+
201
+ errors = []
202
+ tables.each do |table|
203
+ hashes = json_objects.select{|o| o[key[:table]] == table}.collect{|x| x[key[:object]]}
204
+ errors += update hashes, into:table
205
+ end
206
+ return errors
207
+ rescue Exception => e
208
+ return ((defined? errors) ? (errors << IndividualError.new(e,operation:"update")) : [IndividualError.new(e,operation:"update")])
209
+ end
210
+ end
211
+
212
+ def sort_save_operations from:nil, for_table:nil, key:{}
213
+ return {} if from.blank? or for_table.blank?
214
+ table = for_table
215
+ hashes = from.select{|o| o[key[:table]] == table}.collect{|x| x[key[:object]]}
216
+ model = table.classify.constantize
217
+ pk = model.primary_key
218
+
219
+ # organize hashes based on whether they exist (based on their primary key(s)) in the table or not
220
+ if pk.is_a? Array
221
+ ids = hashes.reject{|x| pk.any?{|k| x[k].blank?}}.collect{|x| x.select{|k,v| pk.include? k}} # only accept full sets of pk's
222
+ where_clauses = []
223
+ ids.each do |id|
224
+ equivalence_clauses = []
225
+ id.each do |k,v|
226
+ equivalence_clauses << "#{ActiveRecord::Base.connection.quote_column_name k} = #{ActiveRecord::Base.connection.quote(ActiveRecord::Base.connection.type_cast(v, model.column_types[k]))}"
227
+ end
228
+ where_clauses << "(#{equivalence_clauses.join ' and '})"
229
+ end
230
+ existing_id_sets = ActiveRecord::Base.connection.execute("SELECT #{pk.join ', '} FROM #{table} WHERE #{where_clauses.join ' OR '}").collect{|x| Hash[x.map.with_index{|x,i| [pk[i],x]}]}
231
+ insert_hashes = hashes.reject{|h| existing_id_sets.any?{|set| h == h.merge(set)}}
232
+ update_hashes = hashes.select{|h| existing_id_sets.any?{|set| h == h.merge(set)}}
233
+ else
234
+ ids = hashes.reject{|x| x[pk].blank?}.collect{|x| x[pk]} # should not include null values
235
+ existing_ids = ActiveRecord::Base.connection.execute("SELECT #{pk} FROM #{table} WHERE #{pk} in ('#{ids.join "','"}')").collect{|x| x.first.to_s}
236
+ insert_hashes = hashes.reject{|x| existing_ids.include? x[pk].to_s}
237
+ update_hashes = hashes.select{|x| existing_ids.include? x[pk].to_s}
238
+ end
239
+
240
+ return {insert:insert_hashes,update:update_hashes}
241
+ end
242
+
243
+ def save_by_table json_objects, key:{}
244
+ begin
245
+ tables = json_objects.collect{|x| x[key[:table]]}.to_set.to_a
246
+
247
+ errors = []
248
+ tables.each do |table|
249
+ # sort the hashes by operation type
250
+ sorted_hashes = sort_save_operations from:json_objects, for_table:table, key:key
251
+
252
+ # perform the appropriate operations
253
+ model = table.classify.constantize
254
+ errors += update sorted_hashes[:update], into:model unless sorted_hashes[:update].blank?
255
+ errors += insert sorted_hashes[:insert], into:model unless sorted_hashes[:insert].blank?
256
+ end
257
+ return errors
258
+ rescue Exception => e
259
+ return ((defined? errors) ? (errors << IndividualError.new(e,operation:"save")) : [IndividualError.new(e,operation:"save")])
260
+ end
261
+ end
262
+
263
+ def insert_by_table json_objects, key:{}
264
+ begin
265
+ tables = json_objects.collect{|x| x[key[:table]]}.to_set.to_a
266
+
267
+ errors = []
268
+ tables.each do |table|
269
+ hashes = json_objects.select{|o| o[key[:table]] == table}.collect{|x| x[key[:object]]}
270
+ errors += insert hashes, into:table
271
+ end
272
+ return errors
273
+ rescue Exception => e
274
+ return ((defined? errors) ? (errors << IndividualError.new(e,operation:"insert")) : [IndividualError.new(e,operation:"insert")])
275
+ end
276
+ end
277
+
278
+ def sql_for_insert hash, into:nil
279
+ return nil if hash.blank? or into.blank?
280
+ model = into.is_a?(String) ? into.classify.constantize : into
281
+ id_column_name = model.primary_key
282
+ created_at = model.attribute_alias?("created_at") ? model.attribute_alias("created_at") : "created_at"
283
+ updated_at = model.attribute_alias?("updated_at") ? model.attribute_alias("updated_at") : "updated_at"
284
+ t = model.arel_table
285
+
286
+ h = hash.clone # use a copy of hash, so it doesn't change the original data
287
+
288
+ # assemble an individual query
289
+ im = Arel::InsertManager.new(ActiveRecord::Base)
290
+ unless id_column_name.is_a? Array # don't modify the id fields if there are concatenated primary keys
291
+ h.delete id_column_name if model.columns.select{|x| x.name == id_column_name}.first.extra == 'auto_increment' or h[id_column_name].blank?
292
+ end
293
+ h = convert_to_db_format h, model:model, created_at:created_at, updated_at:updated_at
294
+ pairs = h.collect do |k,v|
295
+ [t[k.to_sym],v]
296
+ end
297
+ im.insert pairs
298
+ im.to_sql
299
+ end
300
+
301
+ def sql_for_update hash, into:nil
302
+ return nil if hash.blank? or into.blank?
303
+ model = into.is_a?(String) ? into.classify.constantize : into
304
+ id_column_name = model.primary_key
305
+ created_at = model.attribute_alias?("created_at") ? model.attribute_alias("created_at") : "created_at"
306
+ updated_at = model.attribute_alias?("updated_at") ? model.attribute_alias("updated_at") : "updated_at"
307
+ t = model.arel_table
308
+
309
+ h = hash.clone # use a copy of hash, so it doesn't change the original data
310
+ h = convert_to_db_format h, model:model, created_at:created_at, updated_at:updated_at
311
+
312
+ # assemble an individual query
313
+ um = Arel::UpdateManager.new(ActiveRecord::Base)
314
+ um.where(t[id_column_name.to_sym].eq(h[id_column_name])) unless id_column_name.is_a? Array
315
+ id_column_name.each{|key| um.where t[key.to_sym].eq(h[key])} if id_column_name.is_a? Array
316
+ um.table(t)
317
+ id_column_name.each{|name| h.delete name} if id_column_name.is_a? Array # don't allow modification of the primary keys
318
+ h.delete id_column_name if id_column_name.is_a? String # don't allow modification of the primary keys
319
+ pairs = h.collect do |k,v|
320
+ [t[k.to_sym],v]
321
+ end
322
+ um.set pairs
323
+ um.to_sql
324
+ end
325
+
326
+ def update hashes, into:nil
327
+ begin
328
+ return false if hashes.blank? or into.blank?
329
+ hashes = [hashes] unless hashes.is_a? Array
330
+
331
+ errors = []
332
+ # create an array of single insert queries
333
+ hashes.each do |hash|
334
+ sql = sql_for_insert hash, into:into
335
+
336
+ begin
337
+ query sql
338
+ rescue Exception => e
339
+ puts e.message
340
+ errors << IndividualError.new(e,table:into,operation:"update",json_object:hash)
341
+ end
342
+ end
343
+ return errors
344
+ rescue Exception => e
345
+ return (defined? errors) ? (errors << IndividualError.new(e, table:into, operation:"update")) : [IndividualError.new( e, table:into, operation:"update")]
346
+ end
347
+ end
348
+
349
+ def insert hashes, into:nil
350
+ begin
351
+ return false if hashes.blank? or into.blank?
352
+ hashes = [hashes] unless hashes.is_a? Array
353
+
354
+ errors = []
355
+ # create an array of single insert queries
356
+ hashes.each do |hash|
357
+ sql = sql_for_insert hash, into:into
358
+
359
+ begin
360
+ query sql
361
+ rescue Exception => e
362
+ puts e.message
363
+ errors << IndividualError.new(e,table:into,operation:"insert",json_object:hash)
364
+ end
365
+ end
366
+
367
+ # reparse the queries and execute them
368
+ return errors
369
+ rescue Exception => e
370
+ return (defined? errors) ? (errors << IndividualError.new(e, table:into, operation:"insert")) : [IndividualError.new( e, table:into, operation:"insert")]
371
+ end
372
+ end
373
+
104
374
  def mass_validate objects
105
375
  # TODO: write logic, should return only valid objects
106
376
  return objects
@@ -113,12 +383,14 @@ module MassRecord
113
383
  errors = {}
114
384
  tables.each do |table|
115
385
  hashes = json_objects.select{|o| o[key[:table]] == table}.collect{|x| x[key[:object]]}
116
- errors[table.to_sym] = mass_update hashes, into:table
386
+
387
+ errors[table.to_sym] = {} unless errors[table.to_sym].is_a? Hash
388
+ errors[table.to_sym].merge! mass_update hashes, into:table
117
389
  end
118
390
  return errors
119
391
  rescue Exception => e
120
- return {method:e} unless defined? errors
121
- errors[:method] = e if defined? errors
392
+ return {run_time:e} unless defined? errors
393
+ errors[:run_time] = e if defined? errors
122
394
  return errors
123
395
  end
124
396
  end
@@ -129,40 +401,19 @@ module MassRecord
129
401
 
130
402
  errors = {}
131
403
  tables.each do |table|
132
- hashes = json_objects.select{|o| o[key[:table]] == table}.collect{|x| x[key[:object]]}
133
- model = table.classify.constantize
134
- pk = model.primary_key
135
-
136
- # organize hashes based on whether they exist (based on their primary key(s)) in the table or not
137
- if pk.is_a? Array
138
- ids = hashes.reject{|x| pk.any?{|k| x[k].blank?}}.collect{|x| x.select{|k,v| pk.include? k}} # only accept full sets of pk's
139
- where_clauses = []
140
- ids.each do |id|
141
- equivalence_clauses = []
142
- id.each do |k,v|
143
- equivalence_clauses << "#{ActiveRecord::Base.connection.quote_column_name k} = #{ActiveRecord::Base.connection.quote(ActiveRecord::Base.connection.type_cast(v, model.column_types[k]))}"
144
- end
145
- where_clauses << "(#{equivalence_clauses.join ' and '})"
146
- end
147
- existing_id_sets = ActiveRecord::Base.connection.execute("SELECT #{pk.join ', '} FROM #{table} WHERE #{where_clauses.join ' OR '}").collect{|x| Hash[x.map.with_index{|x,i| [pk[i],x]}]}
148
- insert_hashes = hashes.reject{|h| existing_id_sets.any?{|set| h == h.merge(set)}}
149
- update_hashes = hashes.select{|h| existing_id_sets.any?{|set| h == h.merge(set)}}
150
- else
151
- ids = hashes.reject{|x| x[pk].blank?}.collect{|x| x[pk]} # should not include null values
152
- existing_ids = ActiveRecord::Base.connection.execute("SELECT #{pk} FROM #{table} WHERE #{pk} in ('#{ids.join "','"}')").collect{|x| x.first.to_s}
153
- insert_hashes = hashes.reject{|x| existing_ids.include? x[pk].to_s}
154
- update_hashes = hashes.select{|x| existing_ids.include? x[pk].to_s}
155
- end
404
+ # sort the hashes by operation type
405
+ sorted_hashes = sort_save_operations from:json_objects, for_table:table, key:key
156
406
 
157
407
  # perform the appropriate operations
158
- errors[table.to_sym] = []
159
- errors[table.to_sym] += mass_update update_hashes, into:model unless update_hashes.blank?
160
- errors[table.to_sym] += mass_insert insert_hashes, into:model unless insert_hashes.blank?
161
- end
408
+ model = table.classify.constantize
409
+ errors[table.to_sym] = {}
410
+ errors[table.to_sym].merge! mass_update sorted_hashes[:update], into:model unless sorted_hashes[:update].blank?
411
+ errors[table.to_sym].merge! mass_insert sorted_hashes[:insert], into:model unless sorted_hashes[:insert].blank?
412
+ end
162
413
  return errors
163
414
  rescue Exception => e
164
- return {method:e} unless defined? errors
165
- errors[:method] = e if defined? errors
415
+ return {run_time:e} unless defined? errors
416
+ errors[:run_time] = e if defined? errors
166
417
  return errors
167
418
  end
168
419
  end
@@ -175,8 +426,8 @@ module MassRecord
175
426
  id_column_name = model.primary_key
176
427
  created_at = model.attribute_alias?("created_at") ? model.attribute_alias("created_at") : "created_at"
177
428
  updated_at = model.attribute_alias?("updated_at") ? model.attribute_alias("updated_at") : "updated_at"
178
- solitary_queries = []
179
- t = model.arel_table
429
+ solitary_queries = [] # I think this can be deleted
430
+ t = model.arel_table # I think this can be deleted
180
431
 
181
432
  # organize by unique column sets
182
433
  unique_column_sets = {}
@@ -187,9 +438,9 @@ module MassRecord
187
438
  unique_column_sets[column_set] << hash
188
439
  end
189
440
 
190
- # assemble list of queries (1 for each unique set of columns)
441
+ # assemble and execute queries (1 for each unique set of columns)
191
442
  queries = []
192
-
443
+ errors = {}
193
444
  unique_column_sets.each do |column_set, hash_group|
194
445
  if id_column_name.is_a? Array
195
446
  ids = hash_group.collect{|hash| Hash[id_column_name.map.with_index{|column_name,i| [column_name,hash[column_name]] }]}
@@ -245,25 +496,21 @@ module MassRecord
245
496
  set_columns << "#{column} = CASE #{values.join ' '} END" if id_column_name.is_a? Array
246
497
  end
247
498
 
248
- queries << "#{update} #{set_columns.join ', '} #{where}"
249
- end
250
- # [{"id"=>545, "header"=>"new system","details"=>"ya, it worked"},{"id"=>546, "header"=>"sweet system"},{"id"=>547, "header"=>"THAT system","details"=>"ya, it worked"}]
251
- errors = []
252
- # execute the queries
253
- queries.each do |sql|
254
499
  begin
255
- query sql
500
+ query "#{update} #{set_columns.join ', '} #{where}"
256
501
  rescue Exception => e
257
502
  puts e.message
258
- errors << e
503
+ errors[column_set] = e
259
504
  end
260
- end
505
+ end
506
+
261
507
  return errors
262
508
  rescue Exception => e
263
- return (defined? errors) ? (errors << e) : [e]
509
+ return (defined? errors) ? (errors.merge!({run_time:e})) : {run_time:e}
264
510
  end
265
511
  end
266
512
 
513
+
267
514
  def mass_insert_by_table json_objects, key:{}
268
515
  begin
269
516
  tables = json_objects.collect{|x| x[key[:table]]}.to_set.to_a
@@ -271,12 +518,14 @@ module MassRecord
271
518
  errors = {}
272
519
  tables.each do |table|
273
520
  hashes = json_objects.select{|o| o[key[:table]] == table}.collect{|x| x[key[:object]]}
274
- errors[table.to_sym] = mass_insert hashes, into:table
521
+
522
+ errors[table.to_sym] = {} unless errors[table.to_sym].is_a? Hash
523
+ errors[table.to_sym].merge! mass_insert hashes, into:table
275
524
  end
276
525
  return errors
277
526
  rescue Exception => e
278
- return {method:e} unless defined? errors
279
- errors[:method] = e if defined? errors
527
+ return {run_time:e} unless defined? errors
528
+ errors[:run_time] = e if defined? errors
280
529
  return errors
281
530
  end
282
531
  end
@@ -287,47 +536,36 @@ module MassRecord
287
536
 
288
537
  # create an array of single insert queries
289
538
  model = into.is_a?(String) ? into.classify.constantize : into
290
- id_column_name = model.primary_key
291
- created_at = model.attribute_alias?("created_at") ? model.attribute_alias("created_at") : "created_at"
292
- updated_at = model.attribute_alias?("updated_at") ? model.attribute_alias("updated_at") : "updated_at"
293
- solitary_queries = []
294
- t = model.arel_table
295
-
296
- hashes.each do |h|
297
- im = Arel::InsertManager.new(ActiveRecord::Base)
298
- unless id_column_name.is_a? Array # don't modify the id fields if there are concatenated primary keys
299
- h.delete id_column_name if model.columns.select{|x| x.name == id_column_name}.first.extra == 'auto_increment' or h[id_column_name].blank?
300
- end
301
- h = convert_to_db_format h, model:model, created_at:created_at, updated_at:updated_at
302
- pairs = h.collect do |k,v|
303
- [t[k.to_sym],v]
304
- end
305
- im.insert pairs
306
- solitary_queries << im.to_sql
307
- end
308
-
309
- # group the queries by unique column lists
310
539
  concentrated_queries = {}
311
540
 
312
- solitary_queries.each do |q|
313
- k = q.gsub /\s*VALUES.*$/,''
314
- concentrated_queries[k] = [] unless concentrated_queries.has_key? k and concentrated_queries[k].is_a? Array
315
- concentrated_queries[k] << q.gsub(/^.*VALUES\s*/,'')
541
+ hashes.each do |hash|
542
+ original_key_set = hash.keys.sort
543
+ sql = sql_for_insert hash, into:model
544
+
545
+ # group the queries by unique column lists
546
+ into_clause = sql.gsub /\s*VALUES.*$/,''
547
+ value_clause = sql.gsub(/^.*VALUES\s*/,'')
548
+
549
+ concentrated_queries[original_key_set] = {} unless concentrated_queries[original_key_set].is_a? Hash
550
+ concentrated_queries[original_key_set][:into] = into_clause
551
+ concentrated_queries[original_key_set][:values] = [] unless concentrated_queries[original_key_set][:values].is_a? Array
552
+ concentrated_queries[original_key_set][:values] << value_clause
316
553
  end
317
554
 
318
- errors = []
555
+ errors = {}
556
+
319
557
  # reparse the queries and execute them
320
- concentrated_queries.each do |k,v|
558
+ concentrated_queries.each do |column_set,clauses|
321
559
  begin
322
- query "#{k} VALUES #{v.join(", ")}"
560
+ query "#{clauses[:into]} VALUES #{clauses[:values].join(", ")}"
323
561
  rescue Exception => e
324
562
  puts e.message
325
- errors << e
563
+ errors[column_set] = e
326
564
  end
327
565
  end
328
566
  return errors
329
567
  rescue Exception => e
330
- return (defined? errors) ? (errors << e) : [e]
568
+ return (defined? errors) ? (errors.merge!({run_time:e})) : {run_time:e}
331
569
  end
332
570
  end
333
571
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mass_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Hanna
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-20 00:00:00.000000000 Z
11
+ date: 2014-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -38,7 +38,8 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- description: Makes inserts, updates, deletes, and validations go faster than ActiveRecord
41
+ description: A Ruby on Rails library to help with mass database operations like insert,
42
+ update, save, validations, etc (much faster than typical ActiveRecord Interactions
42
43
  email:
43
44
  - jnathanhdev@gmail.com
44
45
  executables: []
@@ -117,7 +118,8 @@ rubyforge_project:
117
118
  rubygems_version: 2.4.2
118
119
  signing_key:
119
120
  specification_version: 4
120
- summary: Makes inserts, updates, deletes, and validations go faster than ActiveRecord...
121
+ summary: A Ruby on Rails library to help with mass database operations like insert,
122
+ update, save, validations, etc (much faster than typical ActiveRecord Interactions...
121
123
  test_files:
122
124
  - test/dummy/app/assets/javascripts/application.js
123
125
  - test/dummy/app/assets/stylesheets/application.css