gunwale 0.7.0 → 0.8.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: 5c15189abadefbe716a46534ac6b66c672a975a77cbcf0f6edd662da3d0ba461
4
- data.tar.gz: 5033289d98349cef8d77c9cbf0bf4ab73f83547e195fffd36085260cfc172bb9
3
+ metadata.gz: fb303554816e9e55837eaf89cca61e0667f6033a96e10c4c6678f7cbba8c357c
4
+ data.tar.gz: 6739334794d4526a46969b0503b3165687c329fdfee49a5d251aeba57577cfdf
5
5
  SHA512:
6
- metadata.gz: 3192566ce546a6ce436bbc3c7a5967f3a6c644617cdcc29092b3187ffa64506c92044d48ee68083174fb56bd2bf6a97c2b10b6e530fb197e3122bf4af9784357
7
- data.tar.gz: fb223ca48474086274562bf62475f35f60f2797c4c620e993716802fbaf909f569beb4288a240c213757f1d07013292fa2bef6b635087164e86a35513a04fc70
6
+ metadata.gz: cbbb6c14dfcfd6804aae05b903de648e5057f87fafe52125ab47628f721bc4c441b9b7a7f56b799c39dfbe33b3155e1d9f03a4639bc1ae54c4270ca4a9369e51
7
+ data.tar.gz: 19eb9ac64cfda705fda573be5335162cc17f4e2b41b07e0bbe766bfa9816b318043e6e7f9c0f26637a43c3a518ce12cc6007f74f1fbbe7ebb9d5d22cd0d7ebb1
data/db/schema.rb CHANGED
@@ -10,9 +10,9 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema[7.1].define(version: 2017_05_11_160154) do
13
+ ActiveRecord::Schema[8.0].define(version: 2017_05_11_160154) do
14
14
  # These are extensions that must be enabled in order to support this database
15
- enable_extension "plpgsql"
15
+ enable_extension "pg_catalog.plpgsql"
16
16
 
17
17
  create_table "products", force: :cascade do |t|
18
18
  t.string "name", null: false
@@ -22,5 +22,4 @@ ActiveRecord::Schema[7.1].define(version: 2017_05_11_160154) do
22
22
  t.datetime "updated_at", precision: nil, null: false
23
23
  t.index ["rank"], name: "index_products_on_rank", unique: true
24
24
  end
25
-
26
25
  end
data/lib/row_boat/base.rb CHANGED
@@ -8,6 +8,9 @@ module RowBoat
8
8
  class Base
9
9
  InvalidColumnMapping = Class.new(StandardError)
10
10
 
11
+ SENTINEL = :__ROWBOAT_ABSENT__
12
+ private_constant :SENTINEL
13
+
11
14
  attr_reader :csv_source
12
15
 
13
16
  class << self
@@ -110,6 +113,11 @@ module RowBoat
110
113
  def import_rows(rows)
111
114
  import_options = ::RowBoat::Helpers.extract_import_options(merged_options)
112
115
  preprocessed_rows = preprocess_rows(rows)
116
+
117
+ # Prevent "ON CONFLICT ... cannot affect row a second time" by
118
+ # deduplicating input rows on the declared conflict target.
119
+ preprocessed_rows = dedupe_on_conflict_target(preprocessed_rows, import_options)
120
+
113
121
  import_into.import(preprocessed_rows, import_options)
114
122
  end
115
123
 
@@ -300,6 +308,27 @@ module RowBoat
300
308
  end
301
309
  end
302
310
 
311
+ # Deduplicate rows on the activerecord-import conflict target (if any).
312
+ # Keeps the *last* occurrence for deterministic "last write wins" behavior.
313
+ def dedupe_on_conflict_target(rows, import_options)
314
+ return rows if rows.empty?
315
+
316
+ conflict_target = Array(import_options.dig(:on_duplicate_key_update, :conflict_target))
317
+ .map { |k| k.is_a?(Symbol) ? k : k.to_s.to_sym }
318
+ return rows if conflict_target.empty?
319
+
320
+ # If any row is not a Hash-like payload, we can’t safely dedupe.
321
+ return rows unless rows.all? { |r| r.is_a?(Hash) }
322
+
323
+ # Last row wins
324
+ seen = {}
325
+ rows.each do |r|
326
+ key = conflict_target.map { |k| r.key?(k) ? r[k] : SENTINEL }
327
+ seen[key] = r
328
+ end
329
+ seen.values
330
+ end
331
+
303
332
  # @api private
304
333
  # @private
305
334
  def process_import_results(import_results)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RowBoat
4
- VERSION = "0.7.0"
4
+ VERSION = "0.8.0"
5
5
  end
data/row_boat.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency "appraisal", "~> 2.5"
30
30
  spec.add_development_dependency "awesome_print"
31
31
  spec.add_development_dependency "bundler", "~> 2.5.9"
32
- spec.add_development_dependency "database_cleaner", "~> 2.0", ">= 2.0.2"
32
+ spec.add_development_dependency "database_cleaner", "~> 2.1", ">= 2.1.0"
33
33
  spec.add_development_dependency "pg"
34
34
  spec.add_development_dependency "pry"
35
35
  spec.add_development_dependency "pry-doc"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gunwale
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charlton Trezevant
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-01-15 00:00:00.000000000 Z
11
+ date: 2025-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -112,20 +112,20 @@ dependencies:
112
112
  requirements:
113
113
  - - "~>"
114
114
  - !ruby/object:Gem::Version
115
- version: '2.0'
115
+ version: '2.1'
116
116
  - - ">="
117
117
  - !ruby/object:Gem::Version
118
- version: 2.0.2
118
+ version: 2.1.0
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
- version: '2.0'
125
+ version: '2.1'
126
126
  - - ">="
127
127
  - !ruby/object:Gem::Version
128
- version: 2.0.2
128
+ version: 2.1.0
129
129
  - !ruby/object:Gem::Dependency
130
130
  name: pg
131
131
  requirement: !ruby/object:Gem::Requirement
@@ -316,7 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
316
316
  - !ruby/object:Gem::Version
317
317
  version: '0'
318
318
  requirements: []
319
- rubygems_version: 3.5.6
319
+ rubygems_version: 3.4.10
320
320
  signing_key:
321
321
  specification_version: 4
322
322
  summary: Turn the rows of your CSV into rows in your database