activerecord-rescue_from_duplicate 0.1.6 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +41 -0
- data/.github/workflows/cla.yml +24 -0
- data/README.md +1 -3
- data/activerecord-rescue_from_duplicate.gemspec +1 -1
- data/lib/rescue_from_duplicate/active_record/extension.rb +6 -3
- data/lib/rescue_from_duplicate/active_record/version.rb +1 -1
- data/lib/rescue_from_duplicate/active_record.rb +1 -1
- data/spec/rescue_from_duplicate_spec.rb +9 -1
- data/spec/support/model.rb +2 -2
- metadata +7 -6
- data/.travis.yml +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e6132feb5c01f32d458d37eeccdc5551263280c72040d5718e10d53795d9c98
|
4
|
+
data.tar.gz: 5f9e6a0f3a05e9ced301db7f25f51176292af0fa33f0c9fe3dc3b91f7bceaef3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09bdf44118974354a00a74635d8b3b277f85bb9adf8d1fc48a186699962de82e834fef26ac5dc599a7b039c085eeb30815f900649e7ab0c5a33c4510fa3e5ede'
|
7
|
+
data.tar.gz: 03bc4fe8d528ab693e0619114af9662fecc5dcf914ce41ca5b1c8c98613f9c893afea72e5f6b5de303c7ef50324c9c83da107f807a1d9b54f69a92cfbd96705b
|
@@ -0,0 +1,41 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
name: Ruby ${{ matrix.ruby }}
|
9
|
+
services:
|
10
|
+
postgres:
|
11
|
+
image: postgres
|
12
|
+
env:
|
13
|
+
POSTGRES_USER: "test"
|
14
|
+
POSTGRES_PASSWORD: "test"
|
15
|
+
POSTGRES_DB: "rescue_from_duplicate"
|
16
|
+
ports:
|
17
|
+
- "5432:5432"
|
18
|
+
mysql:
|
19
|
+
image: mysql:8.0
|
20
|
+
env:
|
21
|
+
MYSQL_USER: "test"
|
22
|
+
MYSQL_PASSWORD: "test"
|
23
|
+
MYSQL_ALLOW_EMPTY_PASSWORD: "true"
|
24
|
+
MYSQL_DATABASE: "rescue_from_duplicate"
|
25
|
+
ports:
|
26
|
+
- "3306:3306"
|
27
|
+
strategy:
|
28
|
+
fail-fast: false
|
29
|
+
matrix:
|
30
|
+
ruby: ["3.2"]
|
31
|
+
steps:
|
32
|
+
- name: Check out code
|
33
|
+
uses: actions/checkout@v4
|
34
|
+
- name: Set up Ruby ${{ matrix.ruby }}
|
35
|
+
uses: ruby/setup-ruby@v1
|
36
|
+
with:
|
37
|
+
ruby-version: ${{ matrix.ruby }}
|
38
|
+
bundler-cache: true
|
39
|
+
cache-version: 1
|
40
|
+
- name: Tests
|
41
|
+
run: bundle exec rake
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# .github/workflows/cla.yml
|
2
|
+
name: Contributor License Agreement (CLA)
|
3
|
+
|
4
|
+
on:
|
5
|
+
pull_request_target:
|
6
|
+
types: [opened, synchronize]
|
7
|
+
issue_comment:
|
8
|
+
types: [created]
|
9
|
+
|
10
|
+
jobs:
|
11
|
+
cla:
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
if: |
|
14
|
+
(github.event.issue.pull_request
|
15
|
+
&& !github.event.issue.pull_request.merged_at
|
16
|
+
&& contains(github.event.comment.body, 'signed')
|
17
|
+
)
|
18
|
+
|| (github.event.pull_request && !github.event.pull_request.merged)
|
19
|
+
steps:
|
20
|
+
- uses: Shopify/shopify-cla-action@v1
|
21
|
+
with:
|
22
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
23
|
+
cla-token: ${{ secrets.CLA_TOKEN }}
|
24
|
+
|
data/README.md
CHANGED
@@ -10,8 +10,6 @@ Additionally, a macro allows you to assume that the record will be unique and re
|
|
10
10
|
|
11
11
|
Tested with:
|
12
12
|
|
13
|
-
- ActiveRecord: 3.2, 4.0, 4.1, 4.2, edge
|
14
|
-
- Ruby 1.9.3, 2.0.0, 2.1.2
|
15
13
|
- MySQL, PostgreSQL, Sqlite3
|
16
14
|
|
17
15
|
**Note:**
|
@@ -69,7 +67,7 @@ And then execute:
|
|
69
67
|
Or install it yourself as:
|
70
68
|
|
71
69
|
$ gem install activerecord-rescue_from_duplicate
|
72
|
-
|
70
|
+
|
73
71
|
## Development Setup
|
74
72
|
|
75
73
|
Install:
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "activerecord", ">=
|
21
|
+
spec.add_dependency "activerecord", ">= 7"
|
22
22
|
|
23
23
|
spec.add_development_dependency "bundler"
|
24
24
|
spec.add_development_dependency "rake"
|
@@ -43,11 +43,14 @@ module RescueFromDuplicate::ActiveRecord
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def exception_handler(exception)
|
46
|
+
handlers = self.class._rescue_from_duplicate_handlers
|
47
|
+
return if handlers.empty?
|
48
|
+
|
46
49
|
columns = exception_columns(exception)
|
47
50
|
return unless columns
|
48
51
|
columns = columns.sort
|
49
52
|
|
50
|
-
|
53
|
+
handlers.detect do |handler|
|
51
54
|
handler.rescue? && columns == handler.columns
|
52
55
|
end
|
53
56
|
end
|
@@ -67,7 +70,7 @@ module RescueFromDuplicate::ActiveRecord
|
|
67
70
|
end
|
68
71
|
|
69
72
|
def sqlite3_exception_columns(exception)
|
70
|
-
extract_columns(exception.message[/columns? (.*) (?:is|are) not unique/, 1]) ||
|
73
|
+
extract_columns(exception.message[/columns? (.*) (?:is|are) not unique/, 1]) ||
|
71
74
|
extract_columns(exception.message[/UNIQUE constraint failed: ([^:]*)\:?/, 1])
|
72
75
|
end
|
73
76
|
|
@@ -77,7 +80,7 @@ module RescueFromDuplicate::ActiveRecord
|
|
77
80
|
end
|
78
81
|
|
79
82
|
def other_exception_columns(exception)
|
80
|
-
indexes = self.class.connection.indexes(self.class.table_name)
|
83
|
+
indexes = self.class.connection.schema_cache.indexes(self.class.table_name)
|
81
84
|
indexes.detect{ |i| exception.message.include?(i.name) }.try(:columns) || []
|
82
85
|
end
|
83
86
|
end
|
@@ -16,7 +16,7 @@ module RescueFromDuplicate
|
|
16
16
|
klasses.each do |klass|
|
17
17
|
klass._rescue_from_duplicate_handlers.each do |handler|
|
18
18
|
next unless klass.connection.table_exists?(klass.table_name)
|
19
|
-
unique_indexes = klass.connection.indexes(klass.table_name).select(&:unique)
|
19
|
+
unique_indexes = klass.connection.schema_cache.indexes(klass.table_name).select(&:unique)
|
20
20
|
|
21
21
|
unless unique_indexes.any? { |index| index.columns.map(&:to_s).sort == handler.columns }
|
22
22
|
missing_unique_indexes << MissingUniqueIndex.new(klass, handler.attributes, handler.columns)
|
@@ -7,7 +7,8 @@ shared_examples 'database error rescuing' do
|
|
7
7
|
subject { Rescuable.new }
|
8
8
|
|
9
9
|
before do
|
10
|
-
|
10
|
+
connection = double(schema_cache: double(indexes: [Rescuable.index]))
|
11
|
+
allow(Rescuable).to(receive(:connection).and_return(connection))
|
11
12
|
end
|
12
13
|
|
13
14
|
describe "#create_or_update when the validation fails" do
|
@@ -26,6 +27,13 @@ shared_examples 'database error rescuing' do
|
|
26
27
|
it "raises an exception" do
|
27
28
|
expect { subject.create_or_update }.to raise_error(ActiveRecord::RecordNotUnique)
|
28
29
|
end
|
30
|
+
|
31
|
+
it "doesn't parse the message" do
|
32
|
+
allow(uniqueness_exception).to(
|
33
|
+
receive(:message).and_raise(StandardError, "Message should not have been accessed")
|
34
|
+
)
|
35
|
+
expect { subject.create_or_update }.to raise_error(ActiveRecord::RecordNotUnique)
|
36
|
+
end
|
29
37
|
end
|
30
38
|
end
|
31
39
|
|
data/spec/support/model.rb
CHANGED
@@ -13,7 +13,7 @@ CONNECTIONS = {
|
|
13
13
|
username: "test",
|
14
14
|
password: "test",
|
15
15
|
host: "127.0.0.1",
|
16
|
-
port: "
|
16
|
+
port: "5432",
|
17
17
|
},
|
18
18
|
test_mysql: {
|
19
19
|
adapter: "mysql2",
|
@@ -21,7 +21,7 @@ CONNECTIONS = {
|
|
21
21
|
username: "test",
|
22
22
|
password: "test",
|
23
23
|
host: "127.0.0.1",
|
24
|
-
port: "
|
24
|
+
port: "3306",
|
25
25
|
},
|
26
26
|
}
|
27
27
|
class CreateAllTables < ActiveRecord::Migration[5.2]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-rescue_from_duplicate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guillaume Malette
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '7'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '7'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,9 +143,10 @@ executables: []
|
|
143
143
|
extensions: []
|
144
144
|
extra_rdoc_files: []
|
145
145
|
files:
|
146
|
+
- ".github/workflows/ci.yml"
|
147
|
+
- ".github/workflows/cla.yml"
|
146
148
|
- ".gitignore"
|
147
149
|
- ".rspec"
|
148
|
-
- ".travis.yml"
|
149
150
|
- Gemfile
|
150
151
|
- LICENSE.txt
|
151
152
|
- README.md
|
@@ -186,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
186
187
|
- !ruby/object:Gem::Version
|
187
188
|
version: '0'
|
188
189
|
requirements: []
|
189
|
-
rubygems_version: 3.
|
190
|
+
rubygems_version: 3.4.22
|
190
191
|
signing_key:
|
191
192
|
specification_version: 4
|
192
193
|
summary: Rescue from MySQL and Sqlite duplicate errors when trying to insert records
|
data/.travis.yml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
sudo: false
|
2
|
-
rvm:
|
3
|
-
- '2.5'
|
4
|
-
- '2.6'
|
5
|
-
- '2.7'
|
6
|
-
|
7
|
-
env:
|
8
|
-
- DOCKER_COMPOSE_VERSION=1.20.1
|
9
|
-
|
10
|
-
before_script:
|
11
|
-
- docker-compose --version
|
12
|
-
- docker-compose pull
|
13
|
-
- docker-compose build
|
14
|
-
- docker-compose up --no-start
|
15
|
-
- docker-compose start
|
16
|
-
- sleep 30 # Wait for databases to come online
|
17
|
-
- docker ps
|
18
|
-
|