active_record_upsert 0.10.1 → 0.11.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 +4 -4
- data/Gemfile.rails-6-0 +1 -1
- data/Gemfile.rails-6-1 +1 -1
- data/{Gemfile.rails-5-0 → Gemfile.rails-7-0} +1 -1
- data/README.md +20 -6
- data/active_record_upsert.gemspec +3 -3
- data/lib/active_record_upsert/active_record/persistence.rb +4 -4
- data/lib/active_record_upsert/arel/nodes/insert_statement.rb +0 -39
- data/lib/active_record_upsert/arel/table_extensions.rb +23 -0
- data/lib/active_record_upsert/compatibility/rails60.rb +2 -2
- data/lib/active_record_upsert/compatibility/rails70.rb +59 -0
- data/lib/active_record_upsert/version.rb +1 -1
- data/lib/active_record_upsert.rb +1 -2
- metadata +9 -12
- data/.github/workflows/ci.yml +0 -51
- data/Gemfile.rails-5-1 +0 -5
- data/lib/active_record_upsert/arel/crud.rb +0 -31
- data/lib/active_record_upsert/compatibility/rails50.rb +0 -1
- data/lib/active_record_upsert/compatibility/rails51.rb +0 -65
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 459493128507f8a6ffd12fca94b8270cc93259601b4136c4686ae11f2acd7433
|
|
4
|
+
data.tar.gz: b3c8961297902a34a92d1f947980d4e1829d8e563401f54a7094d110df77fc66
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9007d2d2c1889c6b2742783319b7d0c878cf47d01bee568126984390b8ba73e52384aa84ebff72f1cd0f895a42833a53bf55cfe6339b5a07de0353fe307b1f5c
|
|
7
|
+
data.tar.gz: 8e643c603a776f476a4a0407a5bfa301b0ef8afa726000a32b79fa95a6b036ab04f8360183cf7d33b694912e2577745efbe17418dc572a9a5b6554a757cad864
|
data/Gemfile.rails-6-0
CHANGED
data/Gemfile.rails-6-1
CHANGED
data/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# ActiveRecordUpsert
|
|
6
6
|
|
|
7
|
-
Real upsert for PostgreSQL 9.5+ and Rails 5+ / ActiveRecord 5+. Uses [ON CONFLICT DO UPDATE](http://www.postgresql.org/docs/9.5/static/sql-insert.html).
|
|
7
|
+
Real upsert for PostgreSQL 9.5+ and Rails 5.2+ / ActiveRecord 5.2+. Uses [ON CONFLICT DO UPDATE](http://www.postgresql.org/docs/9.5/static/sql-insert.html).
|
|
8
8
|
|
|
9
9
|
## Main points
|
|
10
10
|
|
|
@@ -15,16 +15,29 @@ Real upsert for PostgreSQL 9.5+ and Rails 5+ / ActiveRecord 5+. Uses [ON CONFLIC
|
|
|
15
15
|
## Prerequisites
|
|
16
16
|
|
|
17
17
|
- PostgreSQL 9.5+ (that's when UPSERT support was added; see Wikipedia's [PostgreSQL Release History](https://en.wikipedia.org/wiki/PostgreSQL#Release_history))
|
|
18
|
-
- ActiveRecord >= 5
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
- For JRuby: No support
|
|
18
|
+
- ActiveRecord >= 5.2
|
|
19
|
+
- Ruby MRI, with the `pg` gem
|
|
20
|
+
- _JRuby is currently not supported_
|
|
22
21
|
|
|
23
22
|
### NB: Releases to avoid
|
|
24
23
|
|
|
25
24
|
Due to a broken build matrix, v0.9.2 and v0.9.3 are incompatible with Rails
|
|
26
25
|
< 5.2.1. [v0.9.4](https://github.com/jesjos/active_record_upsert/releases/tag/v0.9.4) fixed this issue.
|
|
27
26
|
|
|
27
|
+
### Supported Rails versions
|
|
28
|
+
|
|
29
|
+
This library is compatible with all major Rails versions covered by the Rails
|
|
30
|
+
["Severe Security Issues" maintenance policy](https://guides.rubyonrails.org/maintenance_policy.html).
|
|
31
|
+
|
|
32
|
+
### Supported Ruby versions
|
|
33
|
+
|
|
34
|
+
This library may be compatible with older versions of Ruby, however we only run automated
|
|
35
|
+
tests using the
|
|
36
|
+
[officially supported Ruby versions](https://www.ruby-lang.org/en/downloads/branches/).
|
|
37
|
+
|
|
38
|
+
Please note that Ruby 3.1 is not currently tested because it is incompatible with Rails
|
|
39
|
+
`7.0.0`, `6.1.4.4`, `6.0.4.4` and `5.2.6` ([issue](https://github.com/rails/rails/issues/43998)).
|
|
40
|
+
|
|
28
41
|
## Installation
|
|
29
42
|
|
|
30
43
|
Add this line to your application's Gemfile:
|
|
@@ -135,7 +148,7 @@ When a table is defined with a database default for a field, this gotcha can occ
|
|
|
135
148
|
│ id │ integer │ ...
|
|
136
149
|
│ prio │ integer │ 999
|
|
137
150
|
|
|
138
|
-
And `hardwares` has a record with a non-default value for `prio`. Say, the record with `id` 1 has a `prio` of `998`.
|
|
151
|
+
And `hardwares` has a record with a non-default value for `prio`. Say, the record with `id` 1 has a `prio` of `998`.
|
|
139
152
|
|
|
140
153
|
In this situation, upserting like:
|
|
141
154
|
|
|
@@ -242,3 +255,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/jesjos
|
|
|
242
255
|
- Jeff Wallace ([@tjwallace](https://github.com/tjwallace))
|
|
243
256
|
- Kirill Zaitsev ([@Bugagazavr](https://github.com/Bugagazavr))
|
|
244
257
|
- Nick Campbell ([@nickcampbell18](https://github.com/nickcampbell18))
|
|
258
|
+
- Mikhail Doronin ([@misdoro](https://github.com/misdoro))
|
|
@@ -13,14 +13,14 @@ Gem::Specification.new do |spec|
|
|
|
13
13
|
|
|
14
14
|
spec.summary = %q{Real PostgreSQL 9.5+ upserts using ON CONFLICT for ActiveRecord}
|
|
15
15
|
|
|
16
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(bin|test|spec|features)/}) } -
|
|
17
|
-
%w[.gitignore .rspec
|
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(.github|bin|test|spec|features)/}) } -
|
|
17
|
+
%w[.gitignore .rspec Dockerfile Gemfile Gemfile.docker docker-compose.yml]
|
|
18
18
|
spec.bindir = "exe"
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
20
20
|
spec.require_paths = ["lib"]
|
|
21
21
|
|
|
22
22
|
spec.platform = Gem::Platform::RUBY
|
|
23
23
|
|
|
24
|
-
spec.add_runtime_dependency 'activerecord', '>= 5.
|
|
24
|
+
spec.add_runtime_dependency 'activerecord', '>= 5.2', '< 7.1'
|
|
25
25
|
spec.add_runtime_dependency 'pg', '>= 0.18', '< 2.0'
|
|
26
26
|
end
|
|
@@ -18,8 +18,8 @@ module ActiveRecordUpsert
|
|
|
18
18
|
self
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def upsert(
|
|
22
|
-
upsert!(
|
|
21
|
+
def upsert(**kwargs)
|
|
22
|
+
upsert!(**kwargs)
|
|
23
23
|
rescue ::ActiveRecord::RecordInvalid
|
|
24
24
|
false
|
|
25
25
|
end
|
|
@@ -51,8 +51,8 @@ module ActiveRecordUpsert
|
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
def upsert(
|
|
55
|
-
upsert!(
|
|
54
|
+
def upsert(attributes, **kwargs, &block)
|
|
55
|
+
upsert!(attributes, **kwargs, &block)
|
|
56
56
|
rescue ::ActiveRecord::RecordInvalid
|
|
57
57
|
false
|
|
58
58
|
end
|
|
@@ -1,47 +1,8 @@
|
|
|
1
|
-
# module ActiveRecordUpsert
|
|
2
|
-
# module Arel
|
|
3
|
-
# module Nodes
|
|
4
|
-
# module InsertStatementExtensions
|
|
5
|
-
# attr_accessor :on_conflict
|
|
6
|
-
#
|
|
7
|
-
# def initialize
|
|
8
|
-
# @on_conflict = nil
|
|
9
|
-
# super()
|
|
10
|
-
# end
|
|
11
|
-
#
|
|
12
|
-
# def hash
|
|
13
|
-
# [@relation, @columns, @values, @select, @on_conflict].hash
|
|
14
|
-
# end
|
|
15
|
-
#
|
|
16
|
-
# def eql? other
|
|
17
|
-
# self.class == other.class &&
|
|
18
|
-
# self.relation == other.relation &&
|
|
19
|
-
# self.columns == other.columns &&
|
|
20
|
-
# self.select == other.select &&
|
|
21
|
-
# self.values == other.values &&
|
|
22
|
-
# self.on_conflict == other.on_conflict
|
|
23
|
-
# end
|
|
24
|
-
# end
|
|
25
|
-
#
|
|
26
|
-
# ::Arel::Nodes::InsertStatement.prepend(InsertStatementExtensions)
|
|
27
|
-
# end
|
|
28
|
-
# end
|
|
29
|
-
# end
|
|
30
|
-
|
|
31
1
|
module Arel
|
|
32
2
|
module Nodes
|
|
33
3
|
class InsertStatement
|
|
34
4
|
attr_accessor :on_conflict
|
|
35
5
|
|
|
36
|
-
def initialize
|
|
37
|
-
super()
|
|
38
|
-
@relation = nil
|
|
39
|
-
@columns = []
|
|
40
|
-
@values = nil
|
|
41
|
-
@select = nil
|
|
42
|
-
@on_conflict = nil
|
|
43
|
-
end
|
|
44
|
-
|
|
45
6
|
def hash
|
|
46
7
|
[@relation, @columns, @values, @select, @on_conflict].hash
|
|
47
8
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module ActiveRecordUpsert
|
|
2
|
+
module Arel
|
|
3
|
+
module TableExtensions
|
|
4
|
+
def compile_upsert(upsert_keys, upsert_options, upsert_values, insert_values, wheres)
|
|
5
|
+
# Support non-attribute key (like `md5(my_attribute)``)
|
|
6
|
+
target = self[upsert_options.key?(:literal) ? ::Arel::Nodes::SqlLiteral.new(upsert_options[:literal]) : upsert_keys.join(',')]
|
|
7
|
+
on_conflict_do_update = ::Arel::OnConflictDoUpdateManager.new
|
|
8
|
+
|
|
9
|
+
on_conflict_do_update.target = target
|
|
10
|
+
on_conflict_do_update.target_condition = upsert_options[:where]
|
|
11
|
+
on_conflict_do_update.wheres = wheres
|
|
12
|
+
on_conflict_do_update.set(upsert_values)
|
|
13
|
+
|
|
14
|
+
insert_manager = ::Arel::InsertManager.new
|
|
15
|
+
insert_manager.on_conflict = on_conflict_do_update.to_node
|
|
16
|
+
insert_manager.into insert_values.first.first.relation
|
|
17
|
+
insert_manager.insert(insert_values)
|
|
18
|
+
insert_manager
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
::Arel::Table.prepend(TableExtensions)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
module ActiveRecordUpsert
|
|
2
2
|
module ActiveRecord
|
|
3
3
|
module TransactionsExtensions
|
|
4
|
-
def upsert(*args)
|
|
4
|
+
def upsert(*args, **kwargs)
|
|
5
5
|
with_transaction_returning_status { super }
|
|
6
6
|
end
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
module ConnectAdapterExtension
|
|
10
|
-
def upsert(*args)
|
|
10
|
+
def upsert(*args, **kwargs)
|
|
11
11
|
::ActiveRecord::Base.clear_query_caches_for_current_thread
|
|
12
12
|
super
|
|
13
13
|
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module ActiveRecordUpsert
|
|
2
|
+
module ActiveRecord
|
|
3
|
+
module PersistenceExtensions
|
|
4
|
+
module ClassMethods
|
|
5
|
+
def __substitute_values(values, table)
|
|
6
|
+
values.map do |name, value|
|
|
7
|
+
attr = table[name]
|
|
8
|
+
unless ::Arel.arel_node?(value) || value.is_a?(::ActiveModel::Attribute)
|
|
9
|
+
type = type_for_attribute(attr.name)
|
|
10
|
+
value = predicate_builder.build_bind_attribute(attr.name, type.cast(value))
|
|
11
|
+
end
|
|
12
|
+
[attr, value]
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def _upsert_record(existing_attributes, upsert_attributes_names, wheres, opts) # :nodoc:
|
|
17
|
+
upsert_keys = opts[:upsert_keys] || self.upsert_keys || [primary_key]
|
|
18
|
+
upsert_options = opts[:upsert_options] || self.upsert_options
|
|
19
|
+
upsert_attributes_names = upsert_attributes_names - [*upsert_keys, 'created_at']
|
|
20
|
+
|
|
21
|
+
existing_attributes = existing_attributes
|
|
22
|
+
.transform_keys { |name| _prepare_column(name) }
|
|
23
|
+
.reject { |key, _| key.nil? }
|
|
24
|
+
|
|
25
|
+
upsert_attributes_names = upsert_attributes_names
|
|
26
|
+
.map { |name| _prepare_column(name) }
|
|
27
|
+
.compact
|
|
28
|
+
|
|
29
|
+
values_for_upsert = existing_attributes.select { |(name, _value)| upsert_attributes_names.include?(name) }
|
|
30
|
+
|
|
31
|
+
insert_manager = arel_table.compile_upsert(
|
|
32
|
+
upsert_keys,
|
|
33
|
+
upsert_options,
|
|
34
|
+
__substitute_values(values_for_upsert, arel_table),
|
|
35
|
+
__substitute_values(existing_attributes, arel_table),
|
|
36
|
+
wheres
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
connection.upsert(insert_manager, "#{self} Upsert")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
module TransactionsExtensions
|
|
45
|
+
def upsert(*args, **kwargs)
|
|
46
|
+
with_transaction_returning_status { super }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
module ConnectAdapterExtension
|
|
51
|
+
def upsert(*args, **kwargs)
|
|
52
|
+
::ActiveRecord::Base.clear_query_caches_for_current_thread
|
|
53
|
+
super
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(self)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
data/lib/active_record_upsert.rb
CHANGED
|
@@ -13,9 +13,8 @@ require 'active_record_upsert/active_record'
|
|
|
13
13
|
|
|
14
14
|
version = defined?(Rails) ? Rails.version : ActiveRecord.version.to_s
|
|
15
15
|
|
|
16
|
+
require 'active_record_upsert/compatibility/rails70.rb' if version >= '7.0.0' && version < '7.2.0'
|
|
16
17
|
require 'active_record_upsert/compatibility/rails60.rb' if version >= '6.0.0' && version < '6.2.0'
|
|
17
|
-
require 'active_record_upsert/compatibility/rails51.rb' if version >= '5.1.0' && version < '5.2.0'
|
|
18
|
-
require 'active_record_upsert/compatibility/rails50.rb' if version >= '5.0.0' && version < '5.1.0'
|
|
19
18
|
|
|
20
19
|
module ActiveRecordUpsert
|
|
21
20
|
# Your code goes here...
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_record_upsert
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jesper Josefsson
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: exe
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2022-01-07 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activerecord
|
|
@@ -17,20 +17,20 @@ dependencies:
|
|
|
17
17
|
requirements:
|
|
18
18
|
- - ">="
|
|
19
19
|
- !ruby/object:Gem::Version
|
|
20
|
-
version: '5.
|
|
20
|
+
version: '5.2'
|
|
21
21
|
- - "<"
|
|
22
22
|
- !ruby/object:Gem::Version
|
|
23
|
-
version: '
|
|
23
|
+
version: '7.1'
|
|
24
24
|
type: :runtime
|
|
25
25
|
prerelease: false
|
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
|
27
27
|
requirements:
|
|
28
28
|
- - ">="
|
|
29
29
|
- !ruby/object:Gem::Version
|
|
30
|
-
version: '5.
|
|
30
|
+
version: '5.2'
|
|
31
31
|
- - "<"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
33
|
+
version: '7.1'
|
|
34
34
|
- !ruby/object:Gem::Dependency
|
|
35
35
|
name: pg
|
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -59,13 +59,11 @@ executables: []
|
|
|
59
59
|
extensions: []
|
|
60
60
|
extra_rdoc_files: []
|
|
61
61
|
files:
|
|
62
|
-
- ".github/workflows/ci.yml"
|
|
63
62
|
- Gemfile.base
|
|
64
|
-
- Gemfile.rails-5-0
|
|
65
|
-
- Gemfile.rails-5-1
|
|
66
63
|
- Gemfile.rails-5-2
|
|
67
64
|
- Gemfile.rails-6-0
|
|
68
65
|
- Gemfile.rails-6-1
|
|
66
|
+
- Gemfile.rails-7-0
|
|
69
67
|
- Gemfile.rails-master
|
|
70
68
|
- LICENSE
|
|
71
69
|
- README.md
|
|
@@ -79,7 +77,6 @@ files:
|
|
|
79
77
|
- lib/active_record_upsert/active_record/timestamp.rb
|
|
80
78
|
- lib/active_record_upsert/active_record/transactions.rb
|
|
81
79
|
- lib/active_record_upsert/arel.rb
|
|
82
|
-
- lib/active_record_upsert/arel/crud.rb
|
|
83
80
|
- lib/active_record_upsert/arel/insert_manager.rb
|
|
84
81
|
- lib/active_record_upsert/arel/nodes.rb
|
|
85
82
|
- lib/active_record_upsert/arel/nodes/do_nothing.rb
|
|
@@ -89,10 +86,10 @@ files:
|
|
|
89
86
|
- lib/active_record_upsert/arel/nodes/on_conflict.rb
|
|
90
87
|
- lib/active_record_upsert/arel/nodes/on_conflict_action.rb
|
|
91
88
|
- lib/active_record_upsert/arel/on_conflict_do_update_manager.rb
|
|
89
|
+
- lib/active_record_upsert/arel/table_extensions.rb
|
|
92
90
|
- lib/active_record_upsert/arel/visitors/to_sql.rb
|
|
93
|
-
- lib/active_record_upsert/compatibility/rails50.rb
|
|
94
|
-
- lib/active_record_upsert/compatibility/rails51.rb
|
|
95
91
|
- lib/active_record_upsert/compatibility/rails60.rb
|
|
92
|
+
- lib/active_record_upsert/compatibility/rails70.rb
|
|
96
93
|
- lib/active_record_upsert/version.rb
|
|
97
94
|
homepage: https://github.com/jesjos/active_record_upsert/
|
|
98
95
|
licenses:
|
data/.github/workflows/ci.yml
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
pull_request:
|
|
5
|
-
branches: [$default-branches]
|
|
6
|
-
push:
|
|
7
|
-
branches: [$default-branch]
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
test:
|
|
11
|
-
name: Test
|
|
12
|
-
runs-on: ubuntu-latest
|
|
13
|
-
services:
|
|
14
|
-
postgres:
|
|
15
|
-
images: postgres
|
|
16
|
-
env:
|
|
17
|
-
POSTGRES_DB: upsert_test
|
|
18
|
-
POSTGRES_PASSWORD: postgres
|
|
19
|
-
POSTGRES_USER: postgres
|
|
20
|
-
options: >-
|
|
21
|
-
--health-cmd pg_isready
|
|
22
|
-
--health-interval 10s
|
|
23
|
-
--health-timeout 5s
|
|
24
|
-
--health-retries 5
|
|
25
|
-
ports:
|
|
26
|
-
- 5432:5432
|
|
27
|
-
|
|
28
|
-
strategy:
|
|
29
|
-
fail-fast: false
|
|
30
|
-
matrix:
|
|
31
|
-
ruby-version: [2.5.x, 2.6.x, 2.7.x]
|
|
32
|
-
gemfile: [Gemfile, Gemfile.rails-master, Gemfile.rails-6-1, Gemfile.rails-5-2, Gemfile.rails-5-1, Gemfile.rails-5-0]
|
|
33
|
-
|
|
34
|
-
steps:
|
|
35
|
-
- uses: actions/checkout@v2
|
|
36
|
-
|
|
37
|
-
- name: Prepare database
|
|
38
|
-
run: |
|
|
39
|
-
createdb --echo -U $POSTGRES_USER $POSTGRES_DB
|
|
40
|
-
psql -U $POSTGRES_USER $POSTGRES_DB < spec/dummy/db/structure.sql
|
|
41
|
-
|
|
42
|
-
- name: Set up Ruby
|
|
43
|
-
uses: ruby/setup-ruby@v1
|
|
44
|
-
with:
|
|
45
|
-
ruby-version: ${{ matrix.ruby-version }}
|
|
46
|
-
bundler-cache: true
|
|
47
|
-
env:
|
|
48
|
-
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
|
49
|
-
|
|
50
|
-
- name: Run Tests
|
|
51
|
-
run: bundle exec rake spec
|
data/Gemfile.rails-5-1
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# module ActiveRecordUpsert
|
|
2
|
-
# module Arel
|
|
3
|
-
# module CrudExtensions
|
|
4
|
-
# def create_on_conflict_do_update
|
|
5
|
-
# OnConflictDoUpdateManager.new
|
|
6
|
-
# end
|
|
7
|
-
# end
|
|
8
|
-
#
|
|
9
|
-
# ::Arel::Crud.prepend(CrudExtensions)
|
|
10
|
-
# end
|
|
11
|
-
# end
|
|
12
|
-
module Arel
|
|
13
|
-
module Crud
|
|
14
|
-
def compile_upsert(upsert_keys, upsert_options, upsert_values, insert_values, wheres)
|
|
15
|
-
# Support non-attribute key (like `md5(my_attribute)``)
|
|
16
|
-
target = self[upsert_options.key?(:literal) ? ::Arel::Nodes::SqlLiteral.new(upsert_options[:literal]) : upsert_keys.join(',')]
|
|
17
|
-
on_conflict_do_update = OnConflictDoUpdateManager.new
|
|
18
|
-
|
|
19
|
-
on_conflict_do_update.target = target
|
|
20
|
-
on_conflict_do_update.target_condition = upsert_options[:where]
|
|
21
|
-
on_conflict_do_update.wheres = wheres
|
|
22
|
-
on_conflict_do_update.set(upsert_values)
|
|
23
|
-
|
|
24
|
-
insert_manager = create_insert
|
|
25
|
-
insert_manager.on_conflict = on_conflict_do_update.to_node
|
|
26
|
-
insert_manager.into insert_values.first.first.relation
|
|
27
|
-
insert_manager.insert(insert_values)
|
|
28
|
-
insert_manager
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
require_relative 'rails51'
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
module ActiveRecordUpsert
|
|
2
|
-
module ActiveRecord
|
|
3
|
-
module PersistenceExtensions
|
|
4
|
-
def _upsert_record(upsert_attribute_names = changed, arel_condition = nil, opts = {})
|
|
5
|
-
upsert_attribute_names = upsert_attribute_names.map { |name| _prepare_column(name) } & self.class.column_names
|
|
6
|
-
existing_attributes = arel_attributes_with_values_for_create(self.class.column_names)
|
|
7
|
-
values = self.class.unscoped.upsert(existing_attributes, upsert_attribute_names, [arel_condition].compact, opts)
|
|
8
|
-
@new_record = false
|
|
9
|
-
@attributes = self.class.attributes_builder.build_from_database(values.first.to_h)
|
|
10
|
-
changes_applied
|
|
11
|
-
values
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def _prepare_column(name)
|
|
15
|
-
if self.class.reflections.key?(name)
|
|
16
|
-
self.class.reflections[name].foreign_key
|
|
17
|
-
else
|
|
18
|
-
name
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
module RelationExtensions
|
|
24
|
-
def upsert(existing_attributes, upsert_attributes, wheres, opts) # :nodoc:
|
|
25
|
-
substitutes, binds = substitute_values(existing_attributes)
|
|
26
|
-
upsert_keys = opts[:upsert_keys] || self.klass.upsert_keys || [primary_key]
|
|
27
|
-
upsert_options = opts[:upsert_options] || self.klass.upsert_options
|
|
28
|
-
|
|
29
|
-
upsert_attributes = upsert_attributes - [*upsert_keys, 'created_at']
|
|
30
|
-
upsert_keys_filter = ->(o) { upsert_attributes.include?(o.name) }
|
|
31
|
-
|
|
32
|
-
on_conflict_binds = binds.select(&upsert_keys_filter)
|
|
33
|
-
vals_for_upsert = substitutes.select { |s| upsert_keys_filter.call(s.first) }
|
|
34
|
-
|
|
35
|
-
target = arel_table[upsert_options.key?(:literal) ? ::Arel::Nodes::SqlLiteral.new(upsert_options[:literal]) : upsert_keys.join(',')]
|
|
36
|
-
|
|
37
|
-
on_conflict_do_update = ::Arel::OnConflictDoUpdateManager.new
|
|
38
|
-
on_conflict_do_update.target = target
|
|
39
|
-
on_conflict_do_update.target_condition = upsert_options[:where]
|
|
40
|
-
on_conflict_do_update.wheres = wheres
|
|
41
|
-
on_conflict_do_update.set(vals_for_upsert)
|
|
42
|
-
|
|
43
|
-
insert_manager = arel_table.create_insert
|
|
44
|
-
insert_manager.into arel_table
|
|
45
|
-
insert_manager.on_conflict = on_conflict_do_update.to_node
|
|
46
|
-
insert_manager.insert substitutes
|
|
47
|
-
|
|
48
|
-
@klass.connection.upsert(insert_manager, "#{@klass.name} Upsert", binds + on_conflict_binds)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
::ActiveRecord::Relation.include(self)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
module ConnectionAdapters
|
|
55
|
-
module Postgresql
|
|
56
|
-
module DatabaseStatementsExtensions
|
|
57
|
-
def upsert(arel, name = nil, binds = [])
|
|
58
|
-
sql = to_sql(arel, binds)
|
|
59
|
-
exec_upsert(sql, name, binds)
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|