mongoid_retry 0.0.1 → 0.0.2
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.
- data/.travis.yml +4 -1
- data/README.md +2 -3
- data/gemfiles/mongoid-2 +4 -0
- data/lib/mongoid/mongoid_retry.rb +46 -16
- data/lib/mongoid_retry/version.rb +1 -1
- data/mongoid_retry.gemspec +2 -1
- data/spec/spec_helper.rb +8 -4
- data/spec/support/models/thing.rb +7 -2
- metadata +27 -5
data/.travis.yml
CHANGED
data/README.md
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
[](https://travis-ci.org/travisdahlke/mongoid_retry)
|
|
3
2
|
# MongoidRetry
|
|
4
3
|
|
|
5
4
|
Overcome duplicate key errors in MongoDB by catching the exception, finding the existing document, and updating it instead.
|
|
6
|
-
|
|
5
|
+
Compatible with Mongoid 2 and 3.
|
|
7
6
|
|
|
8
7
|
## Installation
|
|
9
8
|
|
data/gemfiles/mongoid-2
ADDED
|
@@ -5,34 +5,64 @@ module Mongoid
|
|
|
5
5
|
|
|
6
6
|
DUPLICATE_KEY_ERROR_CODES = [11000,11001]
|
|
7
7
|
|
|
8
|
+
if Mongoid::VERSION < '3'
|
|
9
|
+
def self.error_message(exception)
|
|
10
|
+
exception.message
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.error_code(exception)
|
|
14
|
+
exception.error_code
|
|
15
|
+
end
|
|
16
|
+
else
|
|
17
|
+
def self.error_message(exception)
|
|
18
|
+
exception.details["err"]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.error_code(exception)
|
|
22
|
+
exception.details["code"]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.is_a_duplicate_key_error?(exception)
|
|
27
|
+
DUPLICATE_KEY_ERROR_CODES.include?(error_code(exception))
|
|
28
|
+
end
|
|
29
|
+
|
|
8
30
|
# Catch a duplicate key error
|
|
9
31
|
def save_and_retry
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
32
|
+
if ::Mongoid::VERSION < '3'
|
|
33
|
+
begin
|
|
34
|
+
safely.save!
|
|
35
|
+
rescue Mongo::OperationFailure => e
|
|
36
|
+
retry_if_duplicate_key_error(e)
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
begin
|
|
40
|
+
with(safe: true).save!
|
|
41
|
+
rescue Moped::Errors::OperationFailure => e
|
|
42
|
+
retry_if_duplicate_key_error(e)
|
|
20
43
|
end
|
|
21
44
|
end
|
|
22
45
|
end
|
|
23
46
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
47
|
+
def retry_if_duplicate_key_error(e)
|
|
48
|
+
if ::Mongoid::MongoidRetry.is_a_duplicate_key_error?(e)
|
|
49
|
+
keys = duplicate_key(e)
|
|
50
|
+
if (duplicate = find_duplicate(keys))
|
|
51
|
+
update_document!(duplicate)
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
raise e
|
|
55
|
+
end
|
|
28
56
|
end
|
|
29
57
|
|
|
58
|
+
private
|
|
59
|
+
|
|
30
60
|
def find_duplicate(keys)
|
|
31
|
-
self.class.
|
|
61
|
+
self.class.where(keys).first
|
|
32
62
|
end
|
|
33
63
|
|
|
34
64
|
def duplicate_key(exception)
|
|
35
|
-
index = exception
|
|
65
|
+
index = ::Mongoid::MongoidRetry.error_message(exception)[/(?<=\.\$)\w*/,0]
|
|
36
66
|
fields = index.split(/\d/).map{|s| s.gsub(/^_|_-?$/,'')}
|
|
37
67
|
fields.inject({}) {|hash, key| hash[key] = send(key) if respond_to?(key); hash}
|
|
38
68
|
end
|
data/mongoid_retry.gemspec
CHANGED
|
@@ -15,7 +15,8 @@ Gem::Specification.new do |gem|
|
|
|
15
15
|
gem.require_paths = ["lib"]
|
|
16
16
|
gem.version = MongoidRetry::VERSION
|
|
17
17
|
|
|
18
|
-
gem.add_runtime_dependency "mongoid", ['
|
|
18
|
+
gem.add_runtime_dependency "mongoid", ['> 2.0']
|
|
19
19
|
gem.add_development_dependency "rspec"
|
|
20
|
+
gem.add_development_dependency "database_cleaner"
|
|
20
21
|
gem.add_development_dependency('rake', ['>= 0.9.2'])
|
|
21
22
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -3,13 +3,17 @@ require 'bundler/setup'
|
|
|
3
3
|
|
|
4
4
|
require 'mongoid'
|
|
5
5
|
require 'mongoid/mongoid_retry'
|
|
6
|
+
require 'database_cleaner'
|
|
6
7
|
|
|
7
8
|
require 'rspec'
|
|
8
9
|
|
|
9
10
|
Mongoid.configure do |config|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
if Mongoid::VERSION >= "3"
|
|
12
|
+
config.connect_to('mongoid_retry_test')
|
|
13
|
+
else
|
|
14
|
+
config.master = Mongo::Connection.new.db('mongoid_retry_test')
|
|
15
|
+
config.allow_dynamic_fields = false
|
|
16
|
+
end
|
|
13
17
|
end
|
|
14
18
|
|
|
15
19
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
|
@@ -17,6 +21,6 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
|
|
17
21
|
RSpec.configure do |config|
|
|
18
22
|
config.mock_with :rspec
|
|
19
23
|
config.after :each do
|
|
20
|
-
|
|
24
|
+
DatabaseCleaner.clean
|
|
21
25
|
end
|
|
22
26
|
end
|
|
@@ -6,6 +6,11 @@ class Thing
|
|
|
6
6
|
field :color
|
|
7
7
|
field :shape
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
if Mongoid::VERSION < '3'
|
|
10
|
+
index :name, unique: true
|
|
11
|
+
index ([[:color, Mongo::ASCENDING], [:shape, Mongo::DESCENDING]]), unique: true
|
|
12
|
+
else
|
|
13
|
+
index({name: 1}, {unique: true})
|
|
14
|
+
index({color: 1, shape: -1}, {unique: true})
|
|
15
|
+
end
|
|
11
16
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mongoid_retry
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.2
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,14 +9,14 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2013-01-30 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: mongoid
|
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
|
17
17
|
none: false
|
|
18
18
|
requirements:
|
|
19
|
-
- -
|
|
19
|
+
- - ! '>'
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
21
|
version: '2.0'
|
|
22
22
|
type: :runtime
|
|
@@ -24,7 +24,7 @@ dependencies:
|
|
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
25
|
none: false
|
|
26
26
|
requirements:
|
|
27
|
-
- -
|
|
27
|
+
- - ! '>'
|
|
28
28
|
- !ruby/object:Gem::Version
|
|
29
29
|
version: '2.0'
|
|
30
30
|
- !ruby/object:Gem::Dependency
|
|
@@ -43,6 +43,22 @@ dependencies:
|
|
|
43
43
|
- - ! '>='
|
|
44
44
|
- !ruby/object:Gem::Version
|
|
45
45
|
version: '0'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: database_cleaner
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
none: false
|
|
50
|
+
requirements:
|
|
51
|
+
- - ! '>='
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ! '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
46
62
|
- !ruby/object:Gem::Dependency
|
|
47
63
|
name: rake
|
|
48
64
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -74,6 +90,7 @@ files:
|
|
|
74
90
|
- LICENSE
|
|
75
91
|
- README.md
|
|
76
92
|
- Rakefile
|
|
93
|
+
- gemfiles/mongoid-2
|
|
77
94
|
- lib/mongoid/mongoid_retry.rb
|
|
78
95
|
- lib/mongoid_retry.rb
|
|
79
96
|
- lib/mongoid_retry/version.rb
|
|
@@ -93,12 +110,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
93
110
|
- - ! '>='
|
|
94
111
|
- !ruby/object:Gem::Version
|
|
95
112
|
version: '0'
|
|
113
|
+
segments:
|
|
114
|
+
- 0
|
|
115
|
+
hash: -909191123557611916
|
|
96
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
117
|
none: false
|
|
98
118
|
requirements:
|
|
99
119
|
- - ! '>='
|
|
100
120
|
- !ruby/object:Gem::Version
|
|
101
121
|
version: '0'
|
|
122
|
+
segments:
|
|
123
|
+
- 0
|
|
124
|
+
hash: -909191123557611916
|
|
102
125
|
requirements: []
|
|
103
126
|
rubyforge_project:
|
|
104
127
|
rubygems_version: 1.8.24
|
|
@@ -109,4 +132,3 @@ test_files:
|
|
|
109
132
|
- spec/retry_spec.rb
|
|
110
133
|
- spec/spec_helper.rb
|
|
111
134
|
- spec/support/models/thing.rb
|
|
112
|
-
has_rdoc:
|