mass_record 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.
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