upsert 2.2.1 → 2.9.9
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 +5 -5
- data/.ruby-version +1 -0
- data/.standard.yml +1 -0
- data/.travis.yml +54 -31
- data/CHANGELOG +9 -0
- data/Gemfile +12 -1
- data/LICENSE +3 -1
- data/README.md +35 -2
- data/Rakefile +7 -1
- data/lib/upsert.rb +49 -7
- data/lib/upsert/column_definition/mysql.rb +2 -2
- data/lib/upsert/column_definition/postgresql.rb +9 -8
- data/lib/upsert/column_definition/sqlite3.rb +3 -3
- data/lib/upsert/connection/Java_ComMysqlJdbc_JDBC4Connection.rb +5 -3
- data/lib/upsert/connection/Java_OrgPostgresqlJdbc_PgConnection.rb +33 -0
- data/lib/upsert/connection/PG_Connection.rb +5 -0
- data/lib/upsert/connection/jdbc.rb +7 -1
- data/lib/upsert/connection/postgresql.rb +2 -3
- data/lib/upsert/merge_function.rb +3 -2
- data/lib/upsert/merge_function/{Java_OrgPostgresqlJdbc4_Jdbc4Connection.rb → Java_OrgPostgresqlJdbc_PgConnection.rb} +2 -2
- data/lib/upsert/merge_function/PG_Connection.rb +1 -1
- data/lib/upsert/merge_function/postgresql.rb +81 -19
- data/lib/upsert/merge_function/sqlite3.rb +10 -0
- data/lib/upsert/version.rb +1 -1
- data/spec/correctness_spec.rb +20 -5
- data/spec/database_functions_spec.rb +6 -2
- data/spec/hstore_spec.rb +53 -38
- data/spec/logger_spec.rb +1 -1
- data/spec/postgresql_spec.rb +81 -3
- data/spec/reserved_words_spec.rb +18 -14
- data/spec/sequel_spec.rb +16 -7
- data/spec/spec_helper.rb +238 -111
- data/spec/speed_spec.rb +3 -33
- data/spec/threaded_spec.rb +35 -12
- data/spec/type_safety_spec.rb +2 -1
- data/travis/run_docker_db.sh +20 -0
- data/upsert-java.gemspec +12 -0
- data/upsert.gemspec +9 -63
- data/upsert.gemspec.common +106 -0
- metadata +37 -44
- data/lib/upsert/connection/Java_OrgPostgresqlJdbc4_Jdbc4Connection.rb +0 -20
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 0d2ed0c63bb4539d42dcf15f20aaabdbca692c9fd5187c06aa76e1b1fc5d9655
|
|
4
|
+
data.tar.gz: 03bbc3ca8ebf200b3552bebe05a1fc13dbea187a023ad996691be02568ce02cb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6c65b45f0d6305bea8c70a2046ccf045bebc29827d6a4d5bd859b3a034d2209e5230abf10f213aa9aebfbee76021c54f2e6bc138917ed280de7273662d4077a4
|
|
7
|
+
data.tar.gz: 486ea504857992b1711b8966d42f9996a14f27078fbe54809ebb4d7a53d18bed80d0f29f68a9992e3a5d6ab8fa3d61a1279375b1bb8efe6bca6453b49a3965a1
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.5.5
|
data/.standard.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ruby_version: 2.2.4
|
data/.travis.yml
CHANGED
|
@@ -1,40 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
dist: trusty
|
|
1
|
+
dist: xenial
|
|
3
2
|
language: ruby
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
-
|
|
7
|
-
addons:
|
|
8
|
-
apt:
|
|
9
|
-
packages:
|
|
10
|
-
# https://github.com/travis-ci/docs-travis-ci-com/pull/743
|
|
11
|
-
- haveged
|
|
12
|
-
- mysql-server-5.6
|
|
13
|
-
- mysql-client-core-5.6
|
|
14
|
-
- mysql-client-5.6
|
|
3
|
+
cache: bundler
|
|
4
|
+
services:
|
|
5
|
+
- docker
|
|
15
6
|
rvm:
|
|
7
|
+
- 2.6
|
|
8
|
+
- 2.5
|
|
9
|
+
- 2.4
|
|
16
10
|
- 2.3
|
|
17
11
|
- 2.2
|
|
18
|
-
-
|
|
19
|
-
- 1.
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
12
|
+
- jruby-9.1.14.0
|
|
13
|
+
- jruby-9.1.17.0
|
|
14
|
+
- jruby-9.2.7.0
|
|
15
|
+
env:
|
|
16
|
+
global:
|
|
17
|
+
- USERNAME=travis
|
|
18
|
+
- PASSWORD=
|
|
19
|
+
- DB_USER=upsert_test
|
|
20
|
+
- DB_PASSWORD=upsert_test
|
|
21
|
+
- DB_NAME=upsert_test
|
|
22
|
+
matrix:
|
|
23
|
+
- DB=postgresql DB_VERSION=postgres:9.4
|
|
24
|
+
- DB=postgresql DB_VERSION=postgres:9.5
|
|
25
|
+
- DB=postgresql DB_VERSION=postgres:9.6
|
|
26
|
+
- DB=postgresql DB_VERSION=postgres:10
|
|
27
|
+
- DB=postgresql DB_VERSION=postgres:11
|
|
28
|
+
- DB=postgresql DB_VERSION=postgres:12
|
|
29
|
+
- DB=postgresql DB_VERSION=postgres:9.4 UNIQUE_CONSTRAINT=true
|
|
30
|
+
- DB=postgresql DB_VERSION=postgres:9.5 UNIQUE_CONSTRAINT=true
|
|
31
|
+
- DB=postgresql DB_VERSION=postgres:9.6 UNIQUE_CONSTRAINT=true
|
|
32
|
+
- DB=postgresql DB_VERSION=postgres:10 UNIQUE_CONSTRAINT=true
|
|
33
|
+
- DB=postgresql DB_VERSION=postgres:11 UNIQUE_CONSTRAINT=true
|
|
34
|
+
- DB=postgresql DB_VERSION=postgres:12 UNIQUE_CONSTRAINT=true
|
|
35
|
+
- DB=mysql DB_VERSION=mysql:5.6
|
|
36
|
+
- DB=mysql DB_VERSION=mysql:5.7
|
|
37
|
+
- DB=mysql DB_VERSION=mysql:8
|
|
23
38
|
matrix:
|
|
39
|
+
exclude:
|
|
40
|
+
- rvm: 2.6
|
|
41
|
+
env: DB=postgresql DB_VERSION=postgres:9.4
|
|
42
|
+
- rvm: 2.6
|
|
43
|
+
env: DB=postgresql DB_VERSION=postgres:9.5
|
|
44
|
+
- rvm: 2.6
|
|
45
|
+
env: DB=postgresql DB_VERSION=postgres:9.4 UNIQUE_CONSTRAINT=true
|
|
46
|
+
- rvm: 2.6
|
|
47
|
+
env: DB=postgresql DB_VERSION=postgres:9.5 UNIQUE_CONSTRAINT=true
|
|
48
|
+
- rvm: jruby-9.2.7
|
|
49
|
+
env: DB=postgresql DB_VERSION=postgres:9.4
|
|
50
|
+
- rvm: jruby-9.2.7
|
|
51
|
+
env: DB=postgresql DB_VERSION=postgres:9.5
|
|
52
|
+
- rvm: jruby-9.2.7
|
|
53
|
+
env: DB=postgresql DB_VERSION=postgres:9.4 UNIQUE_CONSTRAINT=true
|
|
54
|
+
- rvm: jruby-9.2.7
|
|
55
|
+
env: DB=postgresql DB_VERSION=postgres:9.5 UNIQUE_CONSTRAINT=true
|
|
24
56
|
allow_failures:
|
|
25
|
-
-
|
|
26
|
-
env:
|
|
27
|
-
- DB=postgresql PGVERSION=9.4
|
|
28
|
-
- DB=postgresql PGVERSION=9.5
|
|
29
|
-
- DB=postgresql PGVERSION=9.4 UNIQUE_CONSTRAINT=true
|
|
30
|
-
- DB=postgresql PGVERSION=9.5 UNIQUE_CONSTRAINT=true
|
|
31
|
-
- DB=mysql DB_USER=root
|
|
57
|
+
- env: DB=postgresql DB_VERSION=postgres:12
|
|
58
|
+
- env: DB=postgresql DB_VERSION=postgres:12 UNIQUE_CONSTRAINT=true
|
|
32
59
|
before_install:
|
|
33
|
-
-
|
|
34
|
-
# Right now the build-script is properly installing Postgres version. We will need this to test PG 9.6 and up, though
|
|
35
|
-
# - if [ "$DB" = 'postgresql' ]; then sudo ./travis/install_postgres.sh; fi
|
|
36
|
-
- gem update --system
|
|
37
|
-
- gem update bundler
|
|
60
|
+
- ./travis/run_docker_db.sh
|
|
38
61
|
- bundle --version
|
|
39
62
|
- gem --version
|
|
40
|
-
script:
|
|
63
|
+
script: ./travis/run_specs.sh
|
data/CHANGELOG
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
-- no version -- / 2019-06-05
|
|
2
|
+
|
|
3
|
+
* Enhancements
|
|
4
|
+
|
|
5
|
+
* Bump development Ruby version to 2.5 since Ruby 2.2 is no longer supported.
|
|
6
|
+
This should not affect usage of the gem, only local development for people
|
|
7
|
+
working *on* the gem. Ruby 2.2 is also not dropped from Upsert compatibility
|
|
8
|
+
at this time but you should consider upgrading to newer Ruby versions anyway.
|
|
9
|
+
|
|
1
10
|
2.2.1 / 2017-04-20
|
|
2
11
|
|
|
3
12
|
* Bug fixes
|
data/Gemfile
CHANGED
|
@@ -2,4 +2,15 @@ source 'https://rubygems.org'
|
|
|
2
2
|
|
|
3
3
|
# Specify your gem's dependencies in upsert.gemspec
|
|
4
4
|
|
|
5
|
-
gemspec
|
|
5
|
+
gemspec name: RUBY_PLATFORM == "java" ? "upsert-java" : "upsert"
|
|
6
|
+
|
|
7
|
+
case RUBY_PLATFORM
|
|
8
|
+
when "java"
|
|
9
|
+
gem "ffi", platforms: :jruby
|
|
10
|
+
else
|
|
11
|
+
gem "ffi"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
group "test" do
|
|
15
|
+
gem "testmetrics_rspec"
|
|
16
|
+
end
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -123,7 +123,10 @@ See below for details about what SQL MERGE trick (emulation of upsert) is used,
|
|
|
123
123
|
|
|
124
124
|
### Rails / ActiveRecord
|
|
125
125
|
|
|
126
|
-
(
|
|
126
|
+
(Assuming that one of the other three supported drivers is being used under the covers).
|
|
127
|
+
|
|
128
|
+
* add "upsert" to your Gemfile and
|
|
129
|
+
* run bundle install
|
|
127
130
|
|
|
128
131
|
```ruby
|
|
129
132
|
Upsert.new Pet.connection, Pet.table_name
|
|
@@ -232,6 +235,15 @@ require 'pg_hstore'
|
|
|
232
235
|
upsert.row({:name => 'Bill'}, :mydata => {:a => 1, :b => 2})
|
|
233
236
|
```
|
|
234
237
|
|
|
238
|
+
#### PostgreSQL notes
|
|
239
|
+
|
|
240
|
+
- Upsert doesn't do any type casting, so if you attempt to do something like the following:
|
|
241
|
+
`upsert.row({ :name => 'A Name' }, :tag_number => 'bob')`
|
|
242
|
+
you'll get an error which reads something like:
|
|
243
|
+
`invalid input syntax for integer: "bob"`
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
235
247
|
#### Speed
|
|
236
248
|
|
|
237
249
|
From the tests (updated 9/21/12):
|
|
@@ -369,10 +381,31 @@ If you're using MySQL, make sure server/connection timezone is UTC. If you're us
|
|
|
369
381
|
|
|
370
382
|
In general, run some upserts and make sure datetimes get persisted like you expect.
|
|
371
383
|
|
|
384
|
+
### Clearning all library-generated functions
|
|
385
|
+
|
|
386
|
+
Place the following in to a rake task (so you don't globally redefine the `NAME_PREFIX` constant)
|
|
387
|
+
|
|
388
|
+
```ruby
|
|
389
|
+
Upsert::MergeFunction::NAME_PREFIX = "upsert"
|
|
390
|
+
|
|
391
|
+
# ActiveRecord
|
|
392
|
+
Upsert.clear_database_functions(ActiveRecord::Base.connection)
|
|
393
|
+
|
|
394
|
+
# Sequel
|
|
395
|
+
DB.synchronize do |conn|
|
|
396
|
+
Upsert.clear_database_functions(conn)
|
|
397
|
+
end
|
|
398
|
+
```
|
|
399
|
+
|
|
372
400
|
### Doesn't work with transactional fixtures
|
|
373
401
|
|
|
374
402
|
Per https://github.com/seamusabshere/upsert/issues/23 you might have issues if you try to use transactional fixtures and this library.
|
|
375
403
|
|
|
404
|
+
##
|
|
405
|
+
Testmetrics - https://www.testmetrics.app/seamusabshere/upsert
|
|
406
|
+
|
|
376
407
|
## Copyright
|
|
377
408
|
|
|
378
|
-
Copyright
|
|
409
|
+
Copyright 2013-2019 Seamus Abshere
|
|
410
|
+
Copyright 2017-2019 Philip Schalm
|
|
411
|
+
Portions Copyright (c) 2019 The JRuby Team
|
data/Rakefile
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env rake
|
|
2
|
-
require "bundler/
|
|
2
|
+
require "bundler/gem_helper"
|
|
3
|
+
case RUBY_PLATFORM
|
|
4
|
+
when "java"
|
|
5
|
+
Bundler::GemHelper.install_tasks name: "upsert-java"
|
|
6
|
+
else
|
|
7
|
+
Bundler::GemHelper.install_tasks name: "upsert"
|
|
8
|
+
end
|
|
3
9
|
require "rspec/core/rake_task"
|
|
4
10
|
|
|
5
11
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
data/lib/upsert.rb
CHANGED
|
@@ -37,6 +37,31 @@ class Upsert
|
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
+
def mutex_for_row(upsert, row)
|
|
41
|
+
retrieve_mutex(upsert.table_name, row.selector.keys)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def mutex_for_function(upsert, row)
|
|
45
|
+
retrieve_mutex(upsert.table_name, row.selector.keys, row.setter.keys)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# TODO: Rewrite this to use the thread_safe gem, perhaps?
|
|
49
|
+
def retrieve_mutex(*args)
|
|
50
|
+
# ||= isn't an atomic operation
|
|
51
|
+
MUTEX_FOR_PERFORM.synchronize do
|
|
52
|
+
@mutex_cache ||= {}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
@mutex_cache.fetch(args.flatten.join('::')) do |k|
|
|
56
|
+
MUTEX_FOR_PERFORM.synchronize do
|
|
57
|
+
# We still need the ||= because this block could have
|
|
58
|
+
# theoretically been entered simultaneously by two threads
|
|
59
|
+
# but the actual assignment is protected by the mutex
|
|
60
|
+
@mutex_cache[k] ||= Mutex.new
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
40
65
|
# @param [Mysql2::Client,Sqlite3::Database,PG::Connection,#metal] connection A supported database connection.
|
|
41
66
|
#
|
|
42
67
|
# Clear any database functions that may have been created.
|
|
@@ -185,7 +210,7 @@ class Upsert
|
|
|
185
210
|
# @param [Hash] options
|
|
186
211
|
# @option options [TrueClass,FalseClass] :assume_function_exists (true) Assume the function has already been defined correctly by another process.
|
|
187
212
|
def initialize(connection, table_name, options = {})
|
|
188
|
-
@table_name = table_name
|
|
213
|
+
@table_name = self.class.normalize_table_name(table_name)
|
|
189
214
|
metal = Upsert.metal connection
|
|
190
215
|
@flavor = Upsert.flavor metal
|
|
191
216
|
@adapter = Upsert.adapter metal
|
|
@@ -196,7 +221,10 @@ class Upsert
|
|
|
196
221
|
@connection = Connection.const_get(adapter).new self, metal
|
|
197
222
|
@merge_function_class = MergeFunction.const_get adapter
|
|
198
223
|
@merge_function_cache = {}
|
|
199
|
-
@assume_function_exists = options.fetch :assume_function_exists,
|
|
224
|
+
@assume_function_exists = options.fetch :assume_function_exists, @flavor != "Postgresql"
|
|
225
|
+
|
|
226
|
+
@merge_function_mutex = Mutex.new
|
|
227
|
+
@row_mutex = Mutex.new
|
|
200
228
|
end
|
|
201
229
|
|
|
202
230
|
# Upsert a row given a selector and a setter.
|
|
@@ -216,8 +244,10 @@ class Upsert
|
|
|
216
244
|
# upsert.row({:name => 'Pierre'}, :breed => 'tabby')
|
|
217
245
|
def row(selector, setter = {}, options = nil)
|
|
218
246
|
row_object = Row.new(selector, setter, options)
|
|
219
|
-
|
|
220
|
-
|
|
247
|
+
self.class.mutex_for_row(self, row_object).synchronize do
|
|
248
|
+
merge_function(row_object).execute(row_object)
|
|
249
|
+
nil
|
|
250
|
+
end
|
|
221
251
|
end
|
|
222
252
|
|
|
223
253
|
# @private
|
|
@@ -227,16 +257,28 @@ class Upsert
|
|
|
227
257
|
|
|
228
258
|
def merge_function(row)
|
|
229
259
|
cache_key = [row.selector.keys, row.setter.keys]
|
|
230
|
-
|
|
260
|
+
self.class.mutex_for_function(self, row).synchronize do
|
|
261
|
+
@merge_function_cache[cache_key] ||=
|
|
262
|
+
merge_function_class.new(self, row.selector.keys, row.setter.keys, assume_function_exists?)
|
|
263
|
+
end
|
|
231
264
|
end
|
|
232
265
|
|
|
233
266
|
# @private
|
|
234
267
|
def quoted_table_name
|
|
235
|
-
@quoted_table_name ||= connection.quote_ident
|
|
268
|
+
@quoted_table_name ||= table_name.map { |t| connection.quote_ident(t) }.join(".")
|
|
236
269
|
end
|
|
237
270
|
|
|
238
271
|
# @private
|
|
239
272
|
def column_definitions
|
|
240
|
-
@column_definitions ||= ColumnDefinition.const_get(flavor).all connection,
|
|
273
|
+
@column_definitions ||= ColumnDefinition.const_get(flavor).all connection, quoted_table_name
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# @private
|
|
277
|
+
def self.normalize_table_name(table_name)
|
|
278
|
+
if defined?(Sequel) && table_name.is_a?(::Sequel::SQL::QualifiedIdentifier)
|
|
279
|
+
[table_name.table, table_name.column]
|
|
280
|
+
else
|
|
281
|
+
[*table_name].map(&:to_s)
|
|
282
|
+
end
|
|
241
283
|
end
|
|
242
284
|
end
|
|
@@ -3,8 +3,8 @@ class Upsert
|
|
|
3
3
|
# @private
|
|
4
4
|
class Mysql < ColumnDefinition
|
|
5
5
|
class << self
|
|
6
|
-
def all(connection,
|
|
7
|
-
connection.execute("SHOW COLUMNS FROM #{
|
|
6
|
+
def all(connection, quoted_table_name)
|
|
7
|
+
connection.execute("SHOW COLUMNS FROM #{quoted_table_name}").map do |row|
|
|
8
8
|
# {"Field"=>"name", "Type"=>"varchar(255)", "Null"=>"NO", "Key"=>"PRI", "Default"=>nil, "Extra"=>""}
|
|
9
9
|
name = row['Field'] || row['COLUMN_NAME'] || row[:Field] || row[:COLUMN_NAME]
|
|
10
10
|
type = row['Type'] || row['COLUMN_TYPE'] || row[:Type] || row[:COLUMN_TYPE]
|
|
@@ -4,14 +4,14 @@ class Upsert
|
|
|
4
4
|
class Postgresql < ColumnDefinition
|
|
5
5
|
class << self
|
|
6
6
|
# activerecord-3.2.5/lib/active_record/connection_adapters/postgresql_adapter.rb#column_definitions
|
|
7
|
-
def all(connection,
|
|
7
|
+
def all(connection, quoted_table_name)
|
|
8
8
|
res = connection.execute <<-EOS
|
|
9
|
-
SELECT a.attname AS name, format_type(a.atttypid, a.atttypmod) AS sql_type, d.adsrc AS default
|
|
10
|
-
FROM pg_attribute a LEFT JOIN pg_attrdef d
|
|
9
|
+
SELECT a.attname AS name, format_type(a.atttypid, a.atttypmod) AS sql_type, d.adsrc AS default
|
|
10
|
+
FROM pg_attribute a LEFT JOIN pg_attrdef d
|
|
11
11
|
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
|
|
12
|
-
WHERE a.attrelid = '#{
|
|
13
|
-
AND a.attnum > 0 AND NOT a.attisdropped
|
|
14
|
-
EOS
|
|
12
|
+
WHERE a.attrelid = '#{quoted_table_name}'::regclass
|
|
13
|
+
AND a.attnum > 0 AND NOT a.attisdropped
|
|
14
|
+
EOS
|
|
15
15
|
res.map do |row|
|
|
16
16
|
new connection, row['name'], row['sql_type'], row['default']
|
|
17
17
|
end.sort_by do |cd|
|
|
@@ -19,7 +19,7 @@ EOS
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
# NOTE not using this because it can't be indexed
|
|
24
24
|
# def equality(left, right)
|
|
25
25
|
# "#{left} IS NOT DISTINCT FROM #{right}"
|
|
@@ -40,7 +40,8 @@ EOS
|
|
|
40
40
|
if hstore?
|
|
41
41
|
'text'
|
|
42
42
|
else
|
|
43
|
-
|
|
43
|
+
# JDBC uses prepared statements and properly sends date objects (which are otherwise escaped)
|
|
44
|
+
RUBY_PLATFORM == "java" ? sql_type : super
|
|
44
45
|
end
|
|
45
46
|
end
|
|
46
47
|
|
|
@@ -3,9 +3,9 @@ class Upsert
|
|
|
3
3
|
# @private
|
|
4
4
|
class Sqlite3 < ColumnDefinition
|
|
5
5
|
class << self
|
|
6
|
-
def all(connection,
|
|
6
|
+
def all(connection, quoted_table_name)
|
|
7
7
|
# activerecord-3.2.13/lib/active_record/connection_adapters/sqlite_adapter.rb
|
|
8
|
-
connection.execute("PRAGMA table_info(#{
|
|
8
|
+
connection.execute("PRAGMA table_info(#{quoted_table_name})").map do |row|#, 'SCHEMA').to_hash
|
|
9
9
|
if connection.metal.respond_to?(:results_as_hash) and not connection.metal.results_as_hash
|
|
10
10
|
row = {'name' => row[1], 'type' => row[2], 'dflt_value' => row[4]}
|
|
11
11
|
end
|
|
@@ -25,7 +25,7 @@ class Upsert
|
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
def equality(left, right)
|
|
30
30
|
"(#{left} IS #{right} OR (#{left} IS NULL AND #{right} IS NULL))"
|
|
31
31
|
end
|
|
@@ -17,9 +17,11 @@ class Upsert
|
|
|
17
17
|
|
|
18
18
|
def bind_value(v)
|
|
19
19
|
case v
|
|
20
|
-
when
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
when DateTime, Time
|
|
21
|
+
date = v.utc
|
|
22
|
+
java.time.LocalDateTime.of(date.year, date.month, date.day, date.hour, date.min, date.sec, date.nsec)
|
|
23
|
+
when Date
|
|
24
|
+
java.time.LocalDate.of(v.year, v.month, v.day)
|
|
23
25
|
else
|
|
24
26
|
super
|
|
25
27
|
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require_relative "jdbc"
|
|
2
|
+
require_relative "postgresql"
|
|
3
|
+
|
|
4
|
+
class Upsert
|
|
5
|
+
class Connection
|
|
6
|
+
# @private
|
|
7
|
+
class Java_OrgPostgresqlJdbc_PgConnection < Connection
|
|
8
|
+
include Jdbc
|
|
9
|
+
include Postgresql
|
|
10
|
+
|
|
11
|
+
def quote_ident(k)
|
|
12
|
+
DOUBLE_QUOTE + k.to_s.gsub(DOUBLE_QUOTE, '""') + DOUBLE_QUOTE
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def in_transaction?
|
|
16
|
+
# https://github.com/kares/activerecord-jdbc-adapter/commit/4d6e0e0c52d12b0166810dffc9f898141a23bee6
|
|
17
|
+
![0, 4].include?(metal.get_transaction_state)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def bind_value(v)
|
|
21
|
+
case v
|
|
22
|
+
when DateTime, Time
|
|
23
|
+
date = v.utc
|
|
24
|
+
java.time.LocalDateTime.of(date.year, date.month, date.day, date.hour, date.min, date.sec, date.nsec)
|
|
25
|
+
when Date
|
|
26
|
+
java.time.LocalDate.of(v.year, v.month, v.day)
|
|
27
|
+
else
|
|
28
|
+
super
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|