deimos-ruby 2.1.6 → 2.1.7

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
  SHA256:
3
- metadata.gz: 83e7562bf4350bb2a223a8aaa6c4ad710c2c20741b39a8349132f4bac131100c
4
- data.tar.gz: 5238a10a42512e0588c3295c2aea72888a203012906967f1c9aec71059123db9
3
+ metadata.gz: 3890d253c7d9b137c55d02e1968697b9a2921a8cd57dec3be49b6eb3ea50d670
4
+ data.tar.gz: 4538ffbef398ea60d5fe1f3cd20e30a1fe4e45c00e2369717ea160491554d687
5
5
  SHA512:
6
- metadata.gz: 73bd43e24c3d2ff030ee3e09c572e68f18fb41da135df627d13e8298de2a888c3a69e7a4e7f51d15f6a687c01c26a5858724118dc4ea156033c5ec4fba01be8a
7
- data.tar.gz: cd177bc3f323848882a1a31c9d1bdb526c8e75f21ce10f78361927cd6d9bce3eeb0bc3b30646f3e9f6112bd3dc256d279c91d6519f756c088a2d46e081140fbc
6
+ metadata.gz: 221bf0e05c603dda8f6451d4205ed4ea86f209fe8bdc4d6c43c5ad1a19aff57c9df80f9a82a3c134a31e78b6072eab076d6f3e8594fb8a01f4892857068f9aa0
7
+ data.tar.gz: 41cec49b3a6913617398bf194fd1d8fb65304231b34aca051fad5c37307b2e617b571c220ff95aefec57b2200564a9827bddd37ae80553a8091d784561f0c6d5
data/CHANGELOG.md CHANGED
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## UNRELEASED
9
9
 
10
+ # 2.1.7 - 2025-07-23
11
+
12
+ - Feature: Skip batch_record_list fill_primary_keys! if the primary key has already been filled during consumption
13
+
10
14
  # 2.1.6 - 2025-07-23
11
15
 
12
16
  - Fix: Allows rails to handle querying bulk_import_id when replacing associations for non-string bulk_import_ids
@@ -120,16 +120,16 @@ The following are additional settings that can be added to the `topic` block in
120
120
 
121
121
  ### Consumer Settings
122
122
 
123
- | Config name | Default | Description |
124
- |--------------------------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
125
- | each_message | false | If true, use `consume_message` for each message rather than `consume_batch` for the full batch. |
126
- | reraise_errors | false | Default behavior is to swallow uncaught exceptions and log to the metrics provider. Set this to true to instead raise all errors. Note that raising an error will ensure that the message cannot be processed - if there is a bad message which will always raise that error, your consumer will not be able to proceed past it and will be stuck forever until you fix your code. See also the fatal_error configuration. |
127
- | fatal_error | `proc { false }` | Block taking an exception, payload and metadata and returning true if this should be considered a fatal error and false otherwise. E.g. you can use this to always fail if the database is available. Not needed if reraise_errors is set to true. |
128
- | max_db_batch_size | nil | Maximum limit for batching database calls to reduce the load on the db. |
129
- | bulk_import_id_column | `:bulk_import_id` | Name of the column to use for multi-table imports. |
130
- | replace_associations | true | If false, append to associations in multi-table imports rather than replacing them. |
131
- | bulk_import_id_generator | nil | Block to determine the bulk_import_id generated during bulk consumption. If no block is specified the provided/default block from the consumers configuration will be used. |
132
- | save_associations_first |false|Whether to save associated records of primary class prior to upserting primary records. Foreign key of associated records are assigned to the record class prior to saving the record class
123
+ | Config name | Default | Description |
124
+ |--------------------------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
125
+ | each_message | false | If true, use `consume_message` for each message rather than `consume_batch` for the full batch. |
126
+ | reraise_errors | false | Default behavior is to swallow uncaught exceptions and log to the metrics provider. Set this to true to instead raise all errors. Note that raising an error will ensure that the message cannot be processed - if there is a bad message which will always raise that error, your consumer will not be able to proceed past it and will be stuck forever until you fix your code. See also the fatal_error configuration. |
127
+ | fatal_error | `proc { false }` | Block taking an exception, payload and metadata and returning true if this should be considered a fatal error and false otherwise. E.g. you can use this to always fail if the database is available. Not needed if reraise_errors is set to true. |
128
+ | max_db_batch_size | nil | Maximum limit for batching database calls to reduce the load on the db. |
129
+ | bulk_import_id_column | `:bulk_import_id` | Name of the column to use for multi-table imports. |
130
+ | replace_associations | true | If false, append to associations in multi-table imports rather than replacing them. |
131
+ | bulk_import_id_generator | nil | Block to determine the bulk_import_id generated during bulk consumption. If no block is specified the provided/default block from the consumers configuration will be used. |
132
+ | save_associations_first | false | Whether to save associated records of primary class prior to upserting primary records. Foreign key of associated records are assigned to the record class prior to saving the record class |
133
133
 
134
134
  ### Defining Consumers
135
135
 
@@ -52,6 +52,9 @@ module Deimos
52
52
  # records.
53
53
  def fill_primary_keys!
54
54
  primary_col = self.klass.primary_key
55
+
56
+ return if self.batch_records.empty? || self.batch_records.first.send(primary_col).present?
57
+
55
58
  bulk_import_map = self.klass.
56
59
  where(self.bulk_import_column => self.batch_records.map(&:bulk_import_id)).
57
60
  select(primary_col, self.bulk_import_column).
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Deimos
4
- VERSION = '2.1.6'
4
+ VERSION = '2.1.7'
5
5
  end
@@ -251,5 +251,192 @@ RSpec.describe Deimos::ActiveRecordConsume::MassUpdater do
251
251
 
252
252
  end
253
253
 
254
+ context 'with recorded primary_keys' do
255
+ before(:all) do
256
+ ActiveRecord::Base.connection.create_table(:fidgets, force: true, id: false) do |t|
257
+ t.string :test_id, primary_key: true
258
+ t.integer(:some_int)
259
+ t.string(:bulk_import_id)
260
+ t.timestamps
261
+ end
262
+
263
+ ActiveRecord::Base.connection.create_table(:fidget_details, force: true) do |t|
264
+ t.string(:title)
265
+ t.string(:bulk_import_id)
266
+ t.belongs_to(:fidget)
267
+
268
+ t.index(%i(title), unique: true)
269
+ end
270
+
271
+ end
272
+
273
+ after(:all) do
274
+ ActiveRecord::Base.connection.drop_table(:fidgets)
275
+ ActiveRecord::Base.connection.drop_table(:fidget_details)
276
+ end
277
+
278
+ let(:fidget_detail_class) do
279
+ Class.new(ActiveRecord::Base) do
280
+ self.table_name = 'fidget_details'
281
+ belongs_to :fidget
282
+ end
283
+ end
284
+
285
+ let(:fidget_class) do
286
+ Class.new(ActiveRecord::Base) do
287
+ self.table_name = 'fidgets'
288
+ has_one :fidget_detail
289
+ end
290
+ end
291
+
292
+ let(:bulk_id_generator) { proc { SecureRandom.uuid } }
293
+
294
+ let(:key_proc) do
295
+ lambda do |klass|
296
+ case klass.to_s
297
+ when 'Fidget'
298
+ %w(test_id)
299
+ when 'FidgetDetail'
300
+ %w(title)
301
+ else
302
+ raise "Key Columns for #{klass} not defined"
303
+ end
304
+
305
+ end
306
+ end
307
+
308
+ before(:each) do
309
+ stub_const('Fidget', fidget_class)
310
+ stub_const('FidgetDetail', fidget_detail_class)
311
+ Fidget.reset_column_information
312
+ end
313
+
314
+
315
+ let(:batch) do
316
+ Deimos::ActiveRecordConsume::BatchRecordList.new(
317
+ [
318
+ Deimos::ActiveRecordConsume::BatchRecord.new(
319
+ klass: Fidget,
320
+ attributes: { test_id: 'id1', some_int: 5, fidget_detail: { title: 'Title 1' } },
321
+ bulk_import_column: 'bulk_import_id',
322
+ bulk_import_id_generator: bulk_id_generator
323
+ ),
324
+ Deimos::ActiveRecordConsume::BatchRecord.new(
325
+ klass: Fidget,
326
+ attributes: { test_id: 'id2', some_int: 10, fidget_detail: { title: 'Title 2' } },
327
+ bulk_import_column: 'bulk_import_id',
328
+ bulk_import_id_generator: bulk_id_generator
329
+ )
330
+ ]
331
+ )
332
+ end
333
+
334
+ it 'should not backfill the primary key when the primary_key exists' do
335
+ allow(Fidget).to receive(:where).and_call_original
336
+ results = described_class.new(Widget,
337
+ bulk_import_id_generator: bulk_id_generator,
338
+ bulk_import_id_column: 'bulk_import_id',
339
+ key_col_proc: key_proc).mass_update(batch)
340
+ expect(results.count).to eq(2)
341
+ expect(Fidget.count).to eq(2)
342
+ expect(Fidget).not_to have_received(:where).with(:bulk_import_id => [instance_of(String), instance_of(String)])
343
+ end
344
+
345
+ end
346
+
347
+ context 'without recorded primary_keys' do
348
+ before(:all) do
349
+ ActiveRecord::Base.connection.create_table(:fidgets, force: true) do |t|
350
+ t.string(:test_id)
351
+ t.integer(:some_int)
352
+ t.string(:bulk_import_id)
353
+ t.timestamps
354
+ end
355
+
356
+ ActiveRecord::Base.connection.create_table(:fidget_details, force: true) do |t|
357
+ t.string(:title)
358
+ t.string(:bulk_import_id)
359
+ t.belongs_to(:fidget)
360
+
361
+ t.index(%i(title), unique: true)
362
+ end
363
+
364
+ end
365
+
366
+ after(:all) do
367
+ ActiveRecord::Base.connection.drop_table(:fidgets)
368
+ ActiveRecord::Base.connection.drop_table(:fidget_details)
369
+ end
370
+
371
+ let(:fidget_detail_class) do
372
+ Class.new(ActiveRecord::Base) do
373
+ self.table_name = 'fidget_details'
374
+ belongs_to :fidget
375
+ end
376
+ end
377
+
378
+ let(:fidget_class) do
379
+ Class.new(ActiveRecord::Base) do
380
+ self.table_name = 'fidgets'
381
+ has_one :fidget_detail
382
+ end
383
+ end
384
+
385
+ let(:bulk_id_generator) { proc { SecureRandom.uuid } }
386
+
387
+ let(:key_proc) do
388
+ lambda do |klass|
389
+ case klass.to_s
390
+ when 'Fidget'
391
+ %w(id)
392
+ when 'FidgetDetail'
393
+ %w(title)
394
+ else
395
+ raise "Key Columns for #{klass} not defined"
396
+ end
397
+
398
+ end
399
+ end
400
+
401
+ before(:each) do
402
+ stub_const('Fidget', fidget_class)
403
+ stub_const('FidgetDetail', fidget_detail_class)
404
+ Fidget.reset_column_information
405
+ end
406
+
407
+
408
+ let(:batch) do
409
+ Deimos::ActiveRecordConsume::BatchRecordList.new(
410
+ [
411
+ Deimos::ActiveRecordConsume::BatchRecord.new(
412
+ klass: Fidget,
413
+ attributes: { test_id: 'id1', some_int: 5, fidget_detail: { title: 'Title 1' } },
414
+ bulk_import_column: 'bulk_import_id',
415
+ bulk_import_id_generator: bulk_id_generator
416
+ ),
417
+ Deimos::ActiveRecordConsume::BatchRecord.new(
418
+ klass: Fidget,
419
+ attributes: { test_id: 'id2', some_int: 10, fidget_detail: { title: 'Title 2' } },
420
+ bulk_import_column: 'bulk_import_id',
421
+ bulk_import_id_generator: bulk_id_generator
422
+ )
423
+ ]
424
+ )
425
+ end
426
+
427
+ it 'should not backfill the primary key when the primary_key exists' do
428
+ allow(Fidget).to receive(:where).and_call_original
429
+ results = described_class.new(Widget,
430
+ bulk_import_id_generator: bulk_id_generator,
431
+ bulk_import_id_column: 'bulk_import_id',
432
+ key_col_proc: key_proc).mass_update(batch)
433
+ expect(results.count).to eq(2)
434
+ expect(Fidget.count).to eq(2)
435
+ expect(Fidget).to have_received(:where).with(:bulk_import_id => [instance_of(String), instance_of(String)])
436
+ expect(batch.records.map(&:id)).to eq([1,2])
437
+ end
438
+
439
+ end
440
+
254
441
  end
255
442
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deimos-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.6
4
+ version: 2.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Orner