activerecord-transactionable 2.0.2 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/.travis.yml +35 -5
- data/Appraisals +25 -25
- data/Gemfile +12 -1
- data/LICENSE +7 -0
- data/README.md +49 -20
- data/Rakefile +3 -3
- data/activerecord-transactionable.gemspec +20 -21
- data/bin/console +3 -3
- data/gemfiles/rails_4_0.gemfile +5 -5
- data/gemfiles/rails_4_1.gemfile +5 -5
- data/gemfiles/rails_4_2.gemfile +5 -5
- data/gemfiles/rails_5_0.gemfile +5 -5
- data/gemfiles/rails_5_1.gemfile +5 -5
- data/gemfiles/rails_5_2.gemfile +9 -0
- data/lib/activerecord/transactionable.rb +40 -38
- data/lib/activerecord/transactionable/result.rb +27 -4
- data/lib/activerecord/transactionable/version.rb +1 -1
- metadata +31 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c72bcd7d394827cc75722f18b5c963b202553a16a5bce5be6163a68f43e9706a
|
4
|
+
data.tar.gz: e55157daee5fba12b52c21db6296895bc794385ad6ee64ce5b10a5ad3c7ca036
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce66e65e7cc433cb3c1ce7137a718a295356ebc21b04a827288f040d4075d145af80ef0d272e7eee0638a69afd761d58ae12e8a7e93cd23c710e8313130e8c14
|
7
|
+
data.tar.gz: 2760e001a9905e5ce35e0c229e28df5a01d013bf23aa93ada9ca674c3ec01a3b993659113e5399a3f8f84c43119dfc419d71db26952f4e16cfce1cbfff184686
|
data/.rubocop.yml
ADDED
data/.travis.yml
CHANGED
@@ -1,20 +1,50 @@
|
|
1
|
-
|
1
|
+
env:
|
2
|
+
global:
|
3
|
+
- JRUBY_OPTS="-Xcli.debug=true --debug"
|
4
|
+
- CC_TEST_REPORTER_ID=3061299ce65bc5627ebbf42e64717c04e393adaa72c1abbc0ea46300d2c2fdb5
|
5
|
+
|
6
|
+
before_script:
|
7
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
8
|
+
- chmod +x ./cc-test-reporter
|
9
|
+
- ./cc-test-reporter before-build
|
10
|
+
|
11
|
+
script:
|
12
|
+
- bundle exec rspec
|
13
|
+
|
14
|
+
after_script:
|
15
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
16
|
+
|
17
|
+
before_install:
|
18
|
+
- gem update --system
|
19
|
+
- gem install bundler
|
20
|
+
|
21
|
+
install:
|
22
|
+
- bundle install
|
23
|
+
|
24
|
+
bundler_args: --no-deployment --jobs 3 --retry 3
|
25
|
+
|
26
|
+
cache: bundler
|
27
|
+
|
2
28
|
language: ruby
|
29
|
+
sudo: false
|
3
30
|
rvm:
|
4
31
|
- ruby-2.1.10
|
5
|
-
- ruby-2.2.
|
6
|
-
- ruby-2.3.
|
7
|
-
- ruby-2.4.
|
32
|
+
- ruby-2.2.10
|
33
|
+
- ruby-2.3.7
|
34
|
+
- ruby-2.4.4
|
35
|
+
- ruby-2.5.1
|
8
36
|
gemfile:
|
9
37
|
- gemfiles/rails_4_0.gemfile
|
10
38
|
- gemfiles/rails_4_1.gemfile
|
11
39
|
- gemfiles/rails_4_2.gemfile
|
12
40
|
- gemfiles/rails_5_0.gemfile
|
13
41
|
- gemfiles/rails_5_1.gemfile
|
42
|
+
- gemfiles/rails_5_2.gemfile
|
14
43
|
matrix:
|
15
44
|
exclude:
|
16
45
|
- rvm: ruby-2.1.10
|
17
46
|
gemfile: gemfiles/rails_5_0.gemfile
|
18
47
|
- rvm: ruby-2.1.10
|
19
48
|
gemfile: gemfiles/rails_5_1.gemfile
|
20
|
-
|
49
|
+
- rvm: ruby-2.1.10
|
50
|
+
gemfile: gemfiles/rails_5_2.gemfile
|
data/Appraisals
CHANGED
@@ -1,34 +1,34 @@
|
|
1
|
-
appraise
|
2
|
-
gem
|
3
|
-
gem
|
4
|
-
gem
|
5
|
-
gem
|
1
|
+
appraise 'rails-4-0' do
|
2
|
+
gem 'activerecord', '~> 4.0.0'
|
3
|
+
gem 'activemodel', '~> 4.0.0'
|
4
|
+
gem 'sqlite3', '~> 1.3'
|
5
|
+
gem 'thor', '~> 0.19.1' # Because of coveralls :(
|
6
6
|
end
|
7
7
|
|
8
|
-
appraise
|
9
|
-
gem
|
10
|
-
gem
|
11
|
-
gem
|
12
|
-
gem
|
8
|
+
appraise 'rails-4-1' do
|
9
|
+
gem 'activerecord', '~> 4.1.0'
|
10
|
+
gem 'activemodel', '~> 4.1.0'
|
11
|
+
gem 'sqlite3', '~> 1.3'
|
12
|
+
gem 'thor', '~> 0.19.1' # Because of coveralls :(
|
13
13
|
end
|
14
14
|
|
15
|
-
appraise
|
16
|
-
gem
|
17
|
-
gem
|
18
|
-
gem
|
19
|
-
gem
|
15
|
+
appraise 'rails-4-2' do
|
16
|
+
gem 'activerecord', '~> 4.2.0'
|
17
|
+
gem 'activemodel', '~> 4.2.0'
|
18
|
+
gem 'sqlite3', '~> 1.3'
|
19
|
+
gem 'thor', '~> 0.19.1' # Because of coveralls :(
|
20
20
|
end
|
21
21
|
|
22
|
-
appraise
|
23
|
-
gem
|
24
|
-
gem
|
25
|
-
gem
|
26
|
-
gem
|
22
|
+
appraise 'rails-5-0' do
|
23
|
+
gem 'activerecord', '~> 5.0.0'
|
24
|
+
gem 'activemodel', '~> 5.0.0'
|
25
|
+
gem 'sqlite3', '~> 1.3'
|
26
|
+
gem 'thor', '~> 0.19.1' # Because of coveralls :(
|
27
27
|
end
|
28
28
|
|
29
|
-
appraise
|
30
|
-
gem
|
31
|
-
gem
|
32
|
-
gem
|
33
|
-
gem
|
29
|
+
appraise 'rails-5-1' do
|
30
|
+
gem 'activerecord', '~> 5.1.0'
|
31
|
+
gem 'activemodel', '~> 5.1.0'
|
32
|
+
gem 'sqlite3', '~> 1.3'
|
33
|
+
gem 'thor', '~> 0.19.1' # Because of coveralls :(
|
34
34
|
end
|
data/Gemfile
CHANGED
@@ -1,7 +1,18 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
|
+
|
5
|
+
group :test do
|
6
|
+
gem 'byebug', '~> 10', platform: :mri, require: false
|
7
|
+
gem 'pry', '~> 0', platform: :mri, require: false
|
8
|
+
gem 'pry-byebug', '~> 3', platform: :mri, require: false
|
9
|
+
gem 'rubocop', '~> 0.59.0'
|
10
|
+
gem 'rubocop-rspec', '~> 1.24.0'
|
11
|
+
gem 'simplecov', '~> 0', require: false
|
12
|
+
end
|
13
|
+
|
3
14
|
# So the gem can run the simple test suite against the raw bundled gems without the complex BUNDLE_GEMFILE setup
|
4
|
-
gem
|
15
|
+
gem 'sqlite3', platforms: [:ruby]
|
5
16
|
|
6
17
|
# Specify your gem's dependencies in activerecord-transactionable.gemspec
|
7
18
|
gemspec
|
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2016 - 2018 Peter H. Boling
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,23 +1,24 @@
|
|
1
1
|
# Activerecord::Transactionable
|
2
2
|
|
3
|
-
Provides a method, `transaction_wrapper` at the class and instance levels that can be used instead of `ActiveRecord#transaction`. Enables you to do transactions properly, including with or without locking.
|
3
|
+
Provides a method, `transaction_wrapper` at the class and instance levels that can be used instead of `ActiveRecord#transaction`. Enables you to do transactions properly, with custom rescues and retry, including with or without locking.
|
4
4
|
|
5
5
|
| Project | Activerecord::Transactionable |
|
6
6
|
|------------------------ | ----------------- |
|
7
7
|
| gem name | activerecord-transactionable |
|
8
|
-
| license | [![License: MIT](https://img.shields.io/badge/License-MIT-
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
| license | [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) |
|
9
|
+
| download rank | [![Total Downloads](https://img.shields.io/gem/rt/activerecord-transactionable.svg)](https://rubygems.org/gems/activerecord-transactionable) [![Daily Downloads](https://img.shields.io/gem/rd/activerecord-transactionable.svg)](https://rubygems.org/gems/activerecord-transactionable) |
|
10
|
+
| version | [![Version](https://img.shields.io/gem/v/activerecord-transactionable.svg)](https://rubygems.org/gems/activerecord-transactionable) |
|
11
|
+
| dependencies | [![Depfu](https://badges.depfu.com/badges/96a4d507f1a61a9368655f60fa3cb70f/count.svg)](https://depfu.com/github/pboling/activerecord-transactionable?project_id=2653) |
|
12
|
+
| continuous integration | [![Build](https://img.shields.io/travis/pboling/activerecord-transactionable.svg)](https://travis-ci.org/pboling/activerecord-transactionable) |
|
13
|
+
| test coverage | [![Test Coverage](https://api.codeclimate.com/v1/badges/41fa99881cfe6d45e7e5/test_coverage)](https://codeclimate.com/github/pboling/activerecord-transactionable/test_coverage) [![Coverage Status](https://coveralls.io/repos/github/pboling/activerecord-transactionable/badge.svg?branch=master)](https://coveralls.io/github/pboling/activerecord-transactionable?branch=master) |
|
14
|
+
| code quality | [![Maintainability](https://api.codeclimate.com/v1/badges/41fa99881cfe6d45e7e5/maintainability)](https://codeclimate.com/github/pboling/activerecord-transactionable/maintainability) |
|
15
|
+
| code triage | [![Open Source Helpers](https://www.codetriage.com/pboling/activerecord-transactionable/badges/users.svg)](https://www.codetriage.com/pboling/activerecord-transactionable) |
|
14
16
|
| inline documenation | [![Inline docs](http://inch-ci.org/github/pboling/activerecord-transactionable.png)](http://inch-ci.org/github/pboling/activerecord-transactionable) |
|
15
|
-
|
|
16
|
-
|
|
17
|
-
| homepage | [https://github.com/pboling/activerecord-transactionable][homepage] |
|
18
|
-
| documentation | [http://rdoc.info/github/pboling/activerecord-transactionable/frames][documentation] |
|
17
|
+
| homepage | [on Github.com][homepage], [on Railsbling.com][blogpage] |
|
18
|
+
| documentation | [on RDoc.info][documentation] |
|
19
19
|
| live chat | [![Join the chat at https://gitter.im/pboling/activerecord-transactionable](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/pboling/activerecord-transactionable?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) |
|
20
|
-
|
|
20
|
+
| expert support | [![Get help on Codementor](https://cdn.codementor.io/badges/get_help_github.svg)](https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github) |
|
21
|
+
| Spread ~♡ⓛⓞⓥⓔ♡~ | [🌍 🌎 🌏](https://about.me/peter.boling), [🍚](https://www.crowdrise.com/helprefugeeswithhopefortomorrowliberia/fundraiser/peterboling), [➕](https://plus.google.com/+PeterBoling/posts), [👼](https://angel.co/peter-boling), [🐛](https://www.topcoder.com/members/pboling/), [:shipit:](http://coderwall.com/pboling), [![Tweet Peter](https://img.shields.io/twitter/follow/galtzo.svg?style=social&label=Follow)](http://twitter.com/galtzo) |
|
21
22
|
|
22
23
|
Useful as an example of correct behavior for wrapping transactions.
|
23
24
|
|
@@ -122,12 +123,6 @@ result # => an instance of Activerecord::Transactionable::Result
|
|
122
123
|
result.success? # => true or false
|
123
124
|
```
|
124
125
|
|
125
|
-
Meanings of `transaction_wrapper` return values:
|
126
|
-
|
127
|
-
* **nil** - ActiveRecord::Rollback was raised, and then caught by the transaction, and not re-raised; the transaction failed.
|
128
|
-
* **false** - An error was raised which was handled by the transaction_wrapper; the transaction failed.
|
129
|
-
* **true** - The transaction was a success.
|
130
|
-
|
131
126
|
## Update Example
|
132
127
|
|
133
128
|
```ruby
|
@@ -206,11 +201,45 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
206
201
|
|
207
202
|
## Contributing
|
208
203
|
|
204
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/pboling/activerecord-transactionable. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
205
|
+
|
206
|
+
## Code of Conduct
|
207
|
+
|
208
|
+
Everyone interacting in the AnonymousActiveRecord project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/pboling/activerecord-transactionable/blob/master/CODE_OF_CONDUCT.md).
|
209
|
+
|
210
|
+
## Versioning
|
211
|
+
|
212
|
+
This library aims to adhere to [Semantic Versioning 2.0.0][semver].
|
213
|
+
Violations of this scheme should be reported as bugs. Specifically,
|
214
|
+
if a minor or patch version is released that breaks backward
|
215
|
+
compatibility, a new version should be immediately released that
|
216
|
+
restores compatibility. Breaking changes to the public API will
|
217
|
+
only be introduced with new major versions.
|
218
|
+
|
219
|
+
As a result of this policy, you can (and should) specify a
|
220
|
+
dependency on this gem using the [Pessimistic Version Constraint][pvc] with two digits of precision.
|
221
|
+
|
222
|
+
For example:
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
spec.add_dependency 'activerecord-transactionable', '~> 2.0'
|
226
|
+
```
|
227
|
+
|
228
|
+
## Contributing
|
229
|
+
|
209
230
|
Bug reports and pull requests are welcome on GitHub at https://github.com/pboling/activerecord-transactionable.
|
210
231
|
|
232
|
+
## License
|
233
|
+
|
234
|
+
* Copyright (c) 2016 - 2018 [Peter H. Boling][peterboling] of [Rails Bling][railsbling]
|
235
|
+
|
236
|
+
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
|
237
|
+
|
238
|
+
[license]: LICENSE
|
211
239
|
[semver]: http://semver.org/
|
212
|
-
[pvc]: http://
|
240
|
+
[pvc]: http://guides.rubygems.org/patterns/#pessimistic-version-constraint
|
213
241
|
[railsbling]: http://www.railsbling.com
|
214
242
|
[peterboling]: http://www.peterboling.com
|
215
243
|
[documentation]: http://rdoc.info/github/pboling/activerecord-transactionable/frames
|
216
|
-
[homepage]: https://github.com/pboling/activerecord-transactionable
|
244
|
+
[homepage]: https://github.com/pboling/activerecord-transactionable/
|
245
|
+
[blogpage]: http://www.railsbling.com/tags/activerecord-transactionable/
|
data/Rakefile
CHANGED
@@ -1,33 +1,32 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'activerecord/transactionable/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
6
|
+
spec.name = 'activerecord-transactionable'
|
8
7
|
spec.version = Activerecord::Transactionable::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.licenses = [
|
8
|
+
spec.authors = ['Peter Boling']
|
9
|
+
spec.email = ['peter.boling@gmail.com']
|
10
|
+
spec.licenses = ['MIT']
|
12
11
|
|
13
|
-
spec.summary =
|
14
|
-
spec.description =
|
15
|
-
spec.homepage =
|
12
|
+
spec.summary = 'Do ActiveRecord transactions the right way.'
|
13
|
+
spec.description = 'Getting transactions right is hard, and this gem makes it easier.'
|
14
|
+
spec.homepage = 'http://www.railsbling.com/tags/activerecord-transactionable'
|
16
15
|
|
17
16
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
-
spec.bindir =
|
17
|
+
spec.bindir = 'exe'
|
19
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
-
spec.require_paths = [
|
21
|
-
spec.required_ruby_version =
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
spec.required_ruby_version = '>= 2.1.0' # Uses named required parameters
|
22
21
|
|
23
|
-
spec.add_dependency
|
24
|
-
spec.add_dependency
|
22
|
+
spec.add_dependency 'activemodel', '>= 4.0.0'
|
23
|
+
spec.add_dependency 'activerecord', '>= 4.0.0'
|
25
24
|
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
30
|
-
spec.add_development_dependency
|
31
|
-
spec.add_development_dependency
|
32
|
-
spec.add_development_dependency
|
25
|
+
spec.add_development_dependency 'appraisal', '~> 2.2'
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.15'
|
27
|
+
spec.add_development_dependency 'coveralls', '~> 0.8'
|
28
|
+
spec.add_development_dependency 'rake', '~> 12.2'
|
29
|
+
spec.add_development_dependency 'rspec', '~> 3.4'
|
30
|
+
spec.add_development_dependency 'thor', '~> 0.19.1'
|
31
|
+
spec.add_development_dependency 'wwtd', '~> 1.3'
|
33
32
|
end
|
data/bin/console
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'activerecord/transactionable'
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +10,5 @@ require "activerecord/transactionable"
|
|
10
10
|
# require "pry"
|
11
11
|
# Pry.start
|
12
12
|
|
13
|
-
require
|
13
|
+
require 'irb'
|
14
14
|
IRB.start
|
data/gemfiles/rails_4_0.gemfile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# This file was generated by Appraisal
|
2
2
|
|
3
|
-
source
|
3
|
+
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
gem
|
6
|
-
gem
|
7
|
-
gem
|
5
|
+
gem 'activemodel', '~> 4.0.0'
|
6
|
+
gem 'activerecord', '~> 4.0.0'
|
7
|
+
gem 'sqlite3', '~> 1.3'
|
8
8
|
|
9
|
-
gemspec path:
|
9
|
+
gemspec path: '../'
|
data/gemfiles/rails_4_1.gemfile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# This file was generated by Appraisal
|
2
2
|
|
3
|
-
source
|
3
|
+
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
gem
|
6
|
-
gem
|
7
|
-
gem
|
5
|
+
gem 'activemodel', '~> 4.1.0'
|
6
|
+
gem 'activerecord', '~> 4.1.0'
|
7
|
+
gem 'sqlite3', '~> 1.3'
|
8
8
|
|
9
|
-
gemspec path:
|
9
|
+
gemspec path: '../'
|
data/gemfiles/rails_4_2.gemfile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# This file was generated by Appraisal
|
2
2
|
|
3
|
-
source
|
3
|
+
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
gem
|
6
|
-
gem
|
7
|
-
gem
|
5
|
+
gem 'activemodel', '~> 4.2.0'
|
6
|
+
gem 'activerecord', '~> 4.2.0'
|
7
|
+
gem 'sqlite3', '~> 1.3'
|
8
8
|
|
9
|
-
gemspec path:
|
9
|
+
gemspec path: '../'
|
data/gemfiles/rails_5_0.gemfile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# This file was generated by Appraisal
|
2
2
|
|
3
|
-
source
|
3
|
+
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
gem
|
6
|
-
gem
|
7
|
-
gem
|
5
|
+
gem 'activemodel', '~> 5.0.0'
|
6
|
+
gem 'activerecord', '~> 5.0.0'
|
7
|
+
gem 'sqlite3', '~> 1.3'
|
8
8
|
|
9
|
-
gemspec path:
|
9
|
+
gemspec path: '../'
|
data/gemfiles/rails_5_1.gemfile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# This file was generated by Appraisal
|
2
2
|
|
3
|
-
source
|
3
|
+
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
gem
|
6
|
-
gem
|
7
|
-
gem
|
5
|
+
gem 'activemodel', '~> 5.1.0'
|
6
|
+
gem 'activerecord', '~> 5.1.0'
|
7
|
+
gem 'sqlite3', '~> 1.3'
|
8
8
|
|
9
|
-
gemspec path:
|
9
|
+
gemspec path: '../'
|
@@ -1,12 +1,12 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'active_model'
|
2
|
+
require 'active_record'
|
3
3
|
# apparently needed for Rails 4.0 compatibility with rspec, when
|
4
4
|
# this gem is loaded before the rails gem by bundler, as will happen when you
|
5
5
|
# keep your Gemfile sorted alphabetically.
|
6
|
-
require
|
6
|
+
require 'active_record/validations'
|
7
7
|
|
8
|
-
require
|
9
|
-
require
|
8
|
+
require 'activerecord/transactionable/version'
|
9
|
+
require 'activerecord/transactionable/result'
|
10
10
|
|
11
11
|
module Activerecord # Note lowercase "r" in Activerecord (different namespace than rails' module)
|
12
12
|
# SRP: Provides an example of correct behavior for wrapping transactions.
|
@@ -15,38 +15,38 @@ module Activerecord # Note lowercase "r" in Activerecord (different namespace th
|
|
15
15
|
module Transactionable
|
16
16
|
extend ActiveSupport::Concern
|
17
17
|
|
18
|
-
DEFAULT_ERRORS_TO_HANDLE_INSIDE_TRANSACTION = []
|
19
|
-
DEFAULT_ERRORS_PREPARE_ON_SELF_INSIDE = []
|
20
|
-
DEFAULT_ERRORS_TO_HANDLE_OUTSIDE_TRANSACTION = [
|
21
|
-
DEFAULT_ERRORS_PREPARE_ON_SELF_OUTSIDE = [
|
18
|
+
DEFAULT_ERRORS_TO_HANDLE_INSIDE_TRANSACTION = [].freeze
|
19
|
+
DEFAULT_ERRORS_PREPARE_ON_SELF_INSIDE = [].freeze
|
20
|
+
DEFAULT_ERRORS_TO_HANDLE_OUTSIDE_TRANSACTION = [ActiveRecord::RecordInvalid].freeze
|
21
|
+
DEFAULT_ERRORS_PREPARE_ON_SELF_OUTSIDE = [ActiveRecord::RecordInvalid].freeze
|
22
22
|
# These errors (and possibly others) will invalidate the transaction (on PostgreSQL and possibly other databases).
|
23
23
|
# This means that if you did rescue them inside a transaction (or a nested transaction) all subsequent queries would fail.
|
24
24
|
ERRORS_TO_DISALLOW_INSIDE_TRANSACTION = [
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
ActiveRecord::RecordInvalid,
|
26
|
+
ActiveRecord::StatementInvalid,
|
27
|
+
ActiveRecord::RecordNotUnique
|
28
28
|
].freeze
|
29
29
|
# http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html#method-i-transaction
|
30
|
-
TRANSACTION_METHOD_ARG_NAMES = [
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
TRANSACTION_METHOD_ARG_NAMES = %i[
|
31
|
+
requires_new
|
32
|
+
isolation
|
33
|
+
joinable
|
34
34
|
].freeze
|
35
35
|
REQUIRES_NEW = TRANSACTION_METHOD_ARG_NAMES[0]
|
36
|
-
INSIDE_TRANSACTION_ERROR_HANDLERS = [
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
INSIDE_TRANSACTION_ERROR_HANDLERS = %i[
|
37
|
+
rescued_errors
|
38
|
+
prepared_errors
|
39
|
+
retriable_errors
|
40
|
+
reraisable_errors
|
41
41
|
].freeze
|
42
|
-
OUTSIDE_TRANSACTION_ERROR_HANDLERS = [
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
OUTSIDE_TRANSACTION_ERROR_HANDLERS = %i[
|
43
|
+
outside_rescued_errors
|
44
|
+
outside_prepared_errors
|
45
|
+
outside_retriable_errors
|
46
|
+
outside_reraisable_errors
|
47
47
|
].freeze
|
48
|
-
INSIDE_CONTEXT =
|
49
|
-
OUTSIDE_CONTEXT =
|
48
|
+
INSIDE_CONTEXT = 'inside'.freeze
|
49
|
+
OUTSIDE_CONTEXT = 'outside'.freeze
|
50
50
|
|
51
51
|
def transaction_wrapper(**args)
|
52
52
|
self.class.transaction_wrapper(object: self, **args) do |is_retry|
|
@@ -64,13 +64,14 @@ module Activerecord # Note lowercase "r" in Activerecord (different namespace th
|
|
64
64
|
if ERRORS_TO_DISALLOW_INSIDE_TRANSACTION.detect { |error| inside_args.values.flatten.uniq.include?(error) }
|
65
65
|
raise ArgumentError, "#{self} should not rescue #{ERRORS_TO_DISALLOW_INSIDE_TRANSACTION.inspect} inside a transaction: #{inside_args.keys.inspect}"
|
66
66
|
end
|
67
|
+
|
67
68
|
transaction_args = extract_args(args, TRANSACTION_METHOD_ARG_NAMES)
|
68
69
|
if transaction_open
|
69
|
-
|
70
|
+
if transaction_args[REQUIRES_NEW]
|
71
|
+
logger.debug("[#{self}.transaction_wrapper] Will start a nested transaction.")
|
72
|
+
else
|
70
73
|
transaction_args[REQUIRES_NEW] = true
|
71
74
|
logger.warn("[#{self}.transaction_wrapper] Opening a nested transaction. Setting require_new: true")
|
72
|
-
else
|
73
|
-
logger.debug("[#{self}.transaction_wrapper] Will start a nested transaction.")
|
74
75
|
end
|
75
76
|
end
|
76
77
|
error_handler_outside_transaction(object: object, transaction_open: transaction_open, **outside_args) do |outside_is_retry|
|
@@ -101,7 +102,8 @@ module Activerecord # Note lowercase "r" in Activerecord (different namespace th
|
|
101
102
|
end
|
102
103
|
end
|
103
104
|
else
|
104
|
-
raise ArgumentError,
|
105
|
+
raise ArgumentError, 'No object to lock!' if lock
|
106
|
+
|
105
107
|
ActiveRecord::Base.transaction(**transaction_args) do
|
106
108
|
error_handler_inside_transaction(object: object, transaction_open: transaction_open, **inside_args) do |is_retry|
|
107
109
|
yield is_retry
|
@@ -124,7 +126,7 @@ module Activerecord # Note lowercase "r" in Activerecord (different namespace th
|
|
124
126
|
reraisable_errors = Array(args[:reraisable_errors])
|
125
127
|
rescued_errors.concat(DEFAULT_ERRORS_TO_HANDLE_INSIDE_TRANSACTION)
|
126
128
|
prepared_errors.concat(DEFAULT_ERRORS_PREPARE_ON_SELF_INSIDE)
|
127
|
-
already_been_added_to_self, needing_added_to_self = rescued_errors.partition {|error_class| prepared_errors.include?(error_class)}
|
129
|
+
already_been_added_to_self, needing_added_to_self = rescued_errors.partition { |error_class| prepared_errors.include?(error_class) }
|
128
130
|
local_context = INSIDE_CONTEXT
|
129
131
|
run_block_with_retry(object, local_context, transaction_open, retriable_errors, reraisable_errors, already_been_added_to_self, needing_added_to_self) do |is_retry|
|
130
132
|
yield is_retry
|
@@ -138,7 +140,7 @@ module Activerecord # Note lowercase "r" in Activerecord (different namespace th
|
|
138
140
|
reraisable_errors = Array(args[:outside_reraisable_errors])
|
139
141
|
rescued_errors.concat(DEFAULT_ERRORS_TO_HANDLE_OUTSIDE_TRANSACTION)
|
140
142
|
prepared_errors.concat(DEFAULT_ERRORS_PREPARE_ON_SELF_OUTSIDE)
|
141
|
-
already_been_added_to_self, needing_added_to_self = rescued_errors.partition {|error_class| prepared_errors.include?(error_class)}
|
143
|
+
already_been_added_to_self, needing_added_to_self = rescued_errors.partition { |error_class| prepared_errors.include?(error_class) }
|
142
144
|
local_context = OUTSIDE_CONTEXT
|
143
145
|
run_block_with_retry(object, local_context, transaction_open, retriable_errors, reraisable_errors, already_been_added_to_self, needing_added_to_self) do |is_retry|
|
144
146
|
yield is_retry
|
@@ -162,7 +164,7 @@ module Activerecord # Note lowercase "r" in Activerecord (different namespace th
|
|
162
164
|
if result.is_a?(Activerecord::Transactionable::Result)
|
163
165
|
result # <= preserve the meaningful return value
|
164
166
|
else
|
165
|
-
Activerecord::Transactionable::Result.new(true) # <= make the return value meaningful. Meaning: transaction succeeded, no errors raised
|
167
|
+
Activerecord::Transactionable::Result.new(true, context: local_context, transaction_open: transaction_open) # <= make the return value meaningful. Meaning: transaction succeeded, no errors raised
|
166
168
|
end
|
167
169
|
rescue *reraisable_errors => error
|
168
170
|
# This has highest precedence because raising is the most critical functionality of a raised error to keep
|
@@ -177,7 +179,7 @@ module Activerecord # Note lowercase "r" in Activerecord (different namespace th
|
|
177
179
|
# To avoid the infinite recursion, we track the retry state
|
178
180
|
if re_try
|
179
181
|
transaction_error_logger(object: object, error: error, additional_message: " [#{transaction_open ? 'nested ' : ''}#{local_context} 2nd attempt]")
|
180
|
-
Activerecord::Transactionable::Result.new(false) # <= make the return value meaningful. Meaning is: transaction failed after two attempts
|
182
|
+
Activerecord::Transactionable::Result.new(false, context: local_context, transaction_open: transaction_open, error: error, type: 'retriable') # <= make the return value meaningful. Meaning is: transaction failed after two attempts
|
181
183
|
else
|
182
184
|
re_try = true
|
183
185
|
# Not adding error to base when retrying, because otherwise the added error may
|
@@ -188,10 +190,10 @@ module Activerecord # Note lowercase "r" in Activerecord (different namespace th
|
|
188
190
|
rescue *already_been_added_to_self => error
|
189
191
|
# ActiveRecord::RecordInvalid, when done correctly, will have already added the error to object.
|
190
192
|
transaction_error_logger(object: nil, error: error, additional_message: " [#{transaction_open ? 'nested ' : ''}#{local_context}]")
|
191
|
-
Activerecord::Transactionable::Result.new(false) # <= make the return value meaningful. Meaning is: transaction failed
|
193
|
+
Activerecord::Transactionable::Result.new(false, context: local_context, transaction_open: transaction_open, error: error, type: 'already_added') # <= make the return value meaningful. Meaning is: transaction failed
|
192
194
|
rescue *needing_added_to_self => error
|
193
195
|
transaction_error_logger(object: object, error: error, additional_message: " [#{transaction_open ? 'nested ' : ''}#{local_context}]")
|
194
|
-
Activerecord::Transactionable::Result.new(false) # <= make the return value meaningful. Meaning is: transaction failed
|
196
|
+
Activerecord::Transactionable::Result.new(false, context: local_context, transaction_open: transaction_open, error: error, type: 'needing_added') # <= make the return value meaningful. Meaning is: transaction failed
|
195
197
|
end
|
196
198
|
end
|
197
199
|
|
@@ -1,18 +1,41 @@
|
|
1
1
|
module Activerecord
|
2
2
|
module Transactionable
|
3
3
|
class Result
|
4
|
-
attr_reader :value
|
5
|
-
def initialize(value)
|
4
|
+
attr_reader :value, :result, :error, :type, :context, :nested
|
5
|
+
def initialize(value, context:, transaction_open:, error: nil, type: nil)
|
6
6
|
@value = value
|
7
|
+
@result = fail? ? 'fail' : 'success'
|
8
|
+
@context = context
|
9
|
+
@nested = transaction_open ? true : false
|
10
|
+
@error = error
|
11
|
+
@type = type
|
7
12
|
end
|
8
|
-
|
13
|
+
|
9
14
|
def fail?
|
10
15
|
value == false
|
11
16
|
end
|
12
|
-
|
17
|
+
|
13
18
|
def success?
|
14
19
|
value == true
|
15
20
|
end
|
21
|
+
|
22
|
+
def to_h
|
23
|
+
diagnostic_data = {
|
24
|
+
result: result,
|
25
|
+
type: type,
|
26
|
+
context: context,
|
27
|
+
nested: nested
|
28
|
+
}
|
29
|
+
diagnostic_data.merge!(
|
30
|
+
error: error.class.to_s,
|
31
|
+
message: error.message,
|
32
|
+
) if error
|
33
|
+
diagnostic_data
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
to_h.to_s
|
38
|
+
end
|
16
39
|
end
|
17
40
|
end
|
18
41
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-transactionable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Boling
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -16,126 +16,126 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 4.0.0
|
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: 4.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activerecord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 4.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 4.0.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: appraisal
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '2.2'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '2.2'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '1.15'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '1.15'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: coveralls
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '0.8'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '0.8'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rake
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '12.2'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '12.2'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: rspec
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
103
|
+
version: '3.4'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
110
|
+
version: '3.4'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: thor
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
117
|
+
version: 0.19.1
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
124
|
+
version: 0.19.1
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
126
|
+
name: wwtd
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
131
|
+
version: '1.3'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
138
|
+
version: '1.3'
|
139
139
|
description: Getting transactions right is hard, and this gem makes it easier.
|
140
140
|
email:
|
141
141
|
- peter.boling@gmail.com
|
@@ -146,9 +146,11 @@ files:
|
|
146
146
|
- ".coveralls.yml"
|
147
147
|
- ".gitignore"
|
148
148
|
- ".rspec"
|
149
|
+
- ".rubocop.yml"
|
149
150
|
- ".travis.yml"
|
150
151
|
- Appraisals
|
151
152
|
- Gemfile
|
153
|
+
- LICENSE
|
152
154
|
- README.md
|
153
155
|
- Rakefile
|
154
156
|
- activerecord-transactionable.gemspec
|
@@ -159,6 +161,7 @@ files:
|
|
159
161
|
- gemfiles/rails_4_2.gemfile
|
160
162
|
- gemfiles/rails_5_0.gemfile
|
161
163
|
- gemfiles/rails_5_1.gemfile
|
164
|
+
- gemfiles/rails_5_2.gemfile
|
162
165
|
- lib/activerecord/transactionable.rb
|
163
166
|
- lib/activerecord/transactionable/result.rb
|
164
167
|
- lib/activerecord/transactionable/version.rb
|
@@ -182,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
182
185
|
version: '0'
|
183
186
|
requirements: []
|
184
187
|
rubyforge_project:
|
185
|
-
rubygems_version: 2.7.
|
188
|
+
rubygems_version: 2.7.7
|
186
189
|
signing_key:
|
187
190
|
specification_version: 4
|
188
191
|
summary: Do ActiveRecord transactions the right way.
|