em-pg-client-helper 2.0.3 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
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