paper_trail-bulk_writes 0.2.0 → 0.3.0

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: d95e8ca4943e9946044920ed171b6ac8b2453d3f6679d7d33d22295de5a5ad0e
4
- data.tar.gz: a23c12b374cbff0625383b6d18f2585480f3aca36f517288a4eb5d4ba054a0e0
3
+ metadata.gz: 5af6edbca4b17762cc0f647c69ee04b52284cd924b826b6a997a65b4b92925ba
4
+ data.tar.gz: 2baef624ade4173c84c5b54252ee67930f625ee1d97d5e2ed70788d75891900e
5
5
  SHA512:
6
- metadata.gz: b33946ae81b24bc77d3f3ef25040e5af6d8605003ab5d8ad37f9638a19e680c48e85aa5ff68589ddbc1b0a507ad6781f4d0b64c1b2c62494f03073f1816b0fc6
7
- data.tar.gz: 5d3bef3c3c4abd5700ca9d1a30d9aae3f4348ce0381f89c20d136e50ba37668172f4b0a0b73ca0c547dfe2372d300a3607b5036e71a88cadef2184b7b0967d44
6
+ metadata.gz: 46b8fe04d97334c518edd7344f1a2b2e0a771bb3a6c524611e3fe47000c627dd3cfda33358c88c1889ff9ec654fb8e7d8fd2c8aa732a76959410ca2a0f85669e
7
+ data.tar.gz: 8b16c7ea07f84084e99f2de9a062e1500e3d018ce024d9d8f48302975a72c9791b3472597d1a51d3b1f72babd7c4187fca3bfb3b11a95c0744ee2aac1da85ccf
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 0.3.0
4
+
5
+ - Added: `audited_insert_all` takes `returning:`, a list of column names, and returns an `ActiveRecord::Result` of those columns in input order, like `insert_all`. Without it, it still returns the ids. Works on MySQL too, by reading the rows back.
6
+
7
+ ## 0.2.0
4
8
 
5
9
  - Fixed: on databases without `INSERT ... RETURNING`, `audited_insert_all` raised `KeyError` when the caller supplied ids typed differently to the column, such as strings out of a CSV or a JSON payload.
6
10
 
data/README.md CHANGED
@@ -60,6 +60,9 @@ Shift.where(id: ids).audited_delete_all
60
60
 
61
61
  # Returns the new ids, in input order. Rows are inserted with insert_all!.
62
62
  Shift.audited_insert_all([{ name: 'a', status: 'draft' }, { name: 'b', status: 'draft' }])
63
+
64
+ # Pass returning: for other columns; returns an ActiveRecord::Result, like insert_all.
65
+ Shift.audited_insert_all(rows, returning: %w[id status])
63
66
  ```
64
67
 
65
68
  Batches default to 1,000 rows:
@@ -5,39 +5,51 @@ module PaperTrail
5
5
  class Insert
6
6
  include Versioned
7
7
 
8
- def initialize(model:, rows:, whodunnit: nil, batch_size: nil)
8
+ def initialize(model:, rows:, whodunnit: nil, batch_size: nil, returning: nil)
9
9
  @model = model
10
10
  @rows = rows
11
11
  @whodunnit = whodunnit
12
12
  @batch_size = batch_size || default_batch_size
13
+ @returning = returning && Array(returning).map(&:to_s)
13
14
  end
14
15
 
15
16
  def call
16
- return [] if rows.empty?
17
+ inserted = insert_all
18
+ return inserted.pluck('id') unless returning
17
19
 
18
- model.transaction { rows.each_slice(batch_size).flat_map { |batch| write(batch) } }
20
+ ActiveRecord::Result.new(returning, inserted.map { |attributes| attributes.values_at(*returning) })
19
21
  end
20
22
 
21
23
  private
22
24
 
23
- attr_reader :model, :rows, :whodunnit, :batch_size
25
+ attr_reader :model, :rows, :whodunnit, :batch_size, :returning
24
26
 
25
27
  def tracked
26
28
  @tracked ||= adapter.tracked(model.column_names) - ['id']
27
29
  end
28
30
 
31
+ def fetched
32
+ @fetched ||= ['id', *tracked] | returning.to_a
33
+ end
34
+
35
+ def insert_all
36
+ return [] if rows.empty?
37
+
38
+ model.transaction { rows.each_slice(batch_size).flat_map { |batch| write(batch) } }
39
+ end
40
+
29
41
  def write(batch)
30
42
  inserted = insert_and_fetch(batch)
31
43
  changed = changed_columns(batch)
32
44
  adapter.insert(inserted.map { |attributes| version_row(attributes, changed) })
33
- inserted.pluck('id')
45
+ inserted
34
46
  end
35
47
 
36
48
  # Databases with RETURNING (Postgres, SQLite 3.35+, MariaDB 10.5+) hand the
37
49
  # inserted rows back.
38
50
  def insert_and_fetch(batch)
39
51
  if model.connection.supports_insert_returning?
40
- model.insert_all!(batch, returning: ['id', *tracked]).to_a
52
+ model.insert_all!(batch, returning: fetched).to_a
41
53
  else
42
54
  supplied = supplied_ids(batch)
43
55
  model.insert_all!(batch)
@@ -70,7 +82,7 @@ module PaperTrail
70
82
  end
71
83
 
72
84
  def fetch_rows(ids)
73
- relation = model.unscoped.where(id: ids).select('id', *tracked)
85
+ relation = model.unscoped.where(id: ids).select(*fetched)
74
86
  by_id = model.connection.select_all(relation).to_a.index_by { |row| row['id'] }
75
87
  ids.map { |id| by_id.fetch(id) }
76
88
  end
@@ -8,8 +8,8 @@ module PaperTrail
8
8
  end
9
9
 
10
10
  module ClassMethods
11
- def audited_insert_all(rows, whodunnit: PaperTrail.request.whodunnit)
12
- Insert.call(model: self, rows: rows, whodunnit: whodunnit)
11
+ def audited_insert_all(rows, whodunnit: PaperTrail.request.whodunnit, returning: nil)
12
+ Insert.call(model: self, rows: rows, whodunnit: whodunnit, returning: returning)
13
13
  end
14
14
 
15
15
  def audited_update_all(attributes:, whodunnit: PaperTrail.request.whodunnit, touch: true)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module PaperTrail
4
4
  module BulkWrites
5
- VERSION = '0.2.0'
5
+ VERSION = '0.3.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paper_trail-bulk_writes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Robinson