em-pg-client-helper 2.0.3 → 2.0.4

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: fa2d00ac56931a1fa2d54eca37be26d9f6cdfa9e
4
- data.tar.gz: d7e0a651d95809686a4b33b6d5c51ba57a190995
3
+ metadata.gz: f3bf320941966b1a2de9c01df789aaf6969bd371
4
+ data.tar.gz: a9d7145ae5bc7e361f27659103a9143450c5063c
5
5
  SHA512:
6
- metadata.gz: 1eb59a300393ac2cd90a2f078467be406da140d66fe26811713646341f4f2399405ff4f92312824bf29dd7e4800980ba635f5cf703c3e180ff606f9b2e4cc229
7
- data.tar.gz: 65100f76c02145ec4b4d004ffc9349db69d5dbe16f58e27468047341dc90a53814107607e49dbb27152593c9e6fc8c9163dc1009243f446e93dbe8e45869c7f0
6
+ metadata.gz: 4876c2c54967b115f76f2278158ad59eaa9a9b7a8c86d793d018da553dc620d60d60a4e67897a2903208c486786d0282cc639c03dc8b85da1ce5e3e58834fe00
7
+ data.tar.gz: 1285b6bb57a77d7aeb3876375ccbd52b4d00a2a1db90fc8c868bc74bf9b9945c380d2c5b92a2268058db13aae3f7475747fa51ee343b34630a0d9b258e51eab2
@@ -245,45 +245,55 @@ class PG::EM::Client::Helper::Transaction
245
245
  df.callback(&blk) if blk
246
246
 
247
247
  unique_index_columns_for_table(tbl) do |indexes|
248
- # Guh hand-hacked SQL is fugly... but what I'm doing is so utterly
249
- # niche that Sequel doesn't support it.
250
- q_tbl = usdb.literal(tbl.to_sym)
251
- q_cols = columns.map { |c| usdb.literal(c) }
252
-
253
- # If there are any unique indexes which the set of columns to
254
- # be inserted into *doesn't* completely cover, we need to error
255
- # out, because that will cause no rows (or, at most, one row) to
256
- # be successfully inserted. In *theory*, a unique index with all-but-one
257
- # row inserted *could* work, but that would only work if every value
258
- # inserted was different, but quite frankly, I think that's a wicked
259
- # corner case I'm not going to go *anywhere* near.
260
- #
261
- unless indexes.all? { |i| (i - columns).empty? }
262
- ex = ArgumentError.new("Unique index columns not covered by data columns")
263
- if @autorollback_on_error
264
- df.fail(ex)
265
- rollback(ex)
266
- else
267
- df.fail(ex)
248
+ q = if indexes.empty?
249
+ sequel_sql do |db|
250
+ db[tbl.to_sym].multi_insert_sql(columns, rows)
268
251
  end
269
252
  else
270
- subselect_where = indexes.map do |idx|
271
- "(" + idx.map do |c|
272
- "src.#{usdb.literal(c)}=dst.#{usdb.literal(c)}"
273
- end.join(" AND ") + ")"
274
- end.join(" OR ")
275
-
276
- subselect = "SELECT 1 FROM #{q_tbl} AS dst WHERE #{subselect_where}"
277
-
278
- vals = rows.map do |row|
279
- "(" + row.map { |v| usdb.literal(v) }.join(", ") + ")"
280
- end.join(", ")
281
- q = "INSERT INTO #{q_tbl} (SELECT * FROM (VALUES #{vals}) " +
282
- "AS src (#{q_cols.join(", ")}) WHERE NOT EXISTS (#{subselect}))"
283
- exec(q) do |res|
284
- df.succeed(res.cmd_tuples)
253
+ # Guh hand-hacked SQL is fugly... but what I'm doing is so utterly
254
+ # niche that Sequel doesn't support it.
255
+ q_tbl = usdb.literal(tbl.to_sym)
256
+ q_cols = columns.map { |c| usdb.literal(c) }
257
+
258
+ # If there are any unique indexes which the set of columns to
259
+ # be inserted into *doesn't* completely cover, we need to error
260
+ # out, because that will cause no rows (or, at most, one row) to
261
+ # be successfully inserted. In *theory*, a unique index with all-but-one
262
+ # row inserted *could* work, but that would only work if every value
263
+ # inserted was different, but quite frankly, I think that's a wicked
264
+ # corner case I'm not going to go *anywhere* near.
265
+ #
266
+ unless indexes.all? { |i| (i - columns).empty? }
267
+ ex = ArgumentError.new("Unique index columns not covered by data columns")
268
+ if @autorollback_on_error
269
+ df.fail(ex)
270
+ rollback(ex)
271
+ else
272
+ df.fail(ex)
273
+ end
274
+ else
275
+ subselect_where = indexes.map do |idx|
276
+ "(" + idx.map do |c|
277
+ "src.#{usdb.literal(c)}=dst.#{usdb.literal(c)}"
278
+ end.join(" AND ") + ")"
279
+ end.join(" OR ")
280
+
281
+ subselect = "SELECT 1 FROM #{q_tbl} AS dst WHERE #{subselect_where}"
282
+
283
+ vals = rows.map do |row|
284
+ "(" + row.map { |v| usdb.literal(v) }.join(", ") + ")"
285
+ end.join(", ")
286
+
287
+ "INSERT INTO #{q_tbl} (SELECT * FROM (VALUES #{vals}) " +
288
+ "AS src (#{q_cols.join(", ")}) WHERE NOT EXISTS (#{subselect}))"
285
289
  end
286
290
  end
291
+
292
+ exec(q) do |res|
293
+ df.succeed(res.cmd_tuples)
294
+ end.errback do |ex|
295
+ df.fail(ex)
296
+ end
287
297
  end.errback do |ex|
288
298
  df.fail(ex)
289
299
  end
@@ -41,4 +41,23 @@ describe "PG::EM::Client::Helper#db_bulk_insert" do
41
41
  end.errback { dbl.errback; EM.stop }
42
42
  end
43
43
  end
44
+
45
+ it "inserts multiple records without a UNIQUE index" do
46
+ expect(dbl = double).to receive(:results).with(2)
47
+ expect(dbl).to_not receive(:errback)
48
+
49
+ in_em do
50
+ expect_query("BEGIN")
51
+ expect_unique_indexes_query([])
52
+ expect_query('INSERT INTO "foo" ("bar", "baz") VALUES (1, \'x\'), (3, \'y\')',
53
+ [], 0.001, :succeed, Struct.new(:cmd_tuples).new(2)
54
+ )
55
+ expect_query("COMMIT")
56
+
57
+ db_bulk_insert(mock_conn, "foo", [:bar, :baz], [[1, "x"], [3, "y"]]) do |count|
58
+ dbl.results(count)
59
+ EM.stop
60
+ end.errback { dbl.errback; EM.stop }
61
+ end
62
+ end
44
63
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-pg-client-helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Palmer