ar_after_transaction 0.1.1 → 0.2.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.
- data/Gemfile +10 -8
- data/Gemfile.lock +11 -5
- data/Rakefile +9 -6
- data/Readme.md +30 -21
- data/VERSION +1 -1
- data/ar_after_transaction.gemspec +5 -6
- data/lib/ar_after_transaction.rb +14 -14
- data/spec/ar_after_transaction_spec.rb +23 -2
- data/spec/spec_helper.rb +1 -23
- metadata +16 -9
data/Gemfile
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
source
|
|
1
|
+
source :rubygems
|
|
2
2
|
|
|
3
|
-
gem '
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
gem '
|
|
7
|
-
gem '
|
|
8
|
-
gem '
|
|
9
|
-
gem '
|
|
3
|
+
gem 'activerecord', '~>2', :require => 'active_record'
|
|
4
|
+
|
|
5
|
+
group :dev do
|
|
6
|
+
gem 'rake'
|
|
7
|
+
gem 'rspec', '~>2'
|
|
8
|
+
gem 'jeweler'
|
|
9
|
+
gem 'mysql'
|
|
10
|
+
gem 'activesupport', :require => 'active_support'
|
|
11
|
+
end
|
data/Gemfile.lock
CHANGED
|
@@ -4,6 +4,7 @@ GEM
|
|
|
4
4
|
activerecord (2.3.9)
|
|
5
5
|
activesupport (= 2.3.9)
|
|
6
6
|
activesupport (2.3.9)
|
|
7
|
+
diff-lcs (1.1.2)
|
|
7
8
|
gemcutter (0.6.1)
|
|
8
9
|
git (1.2.5)
|
|
9
10
|
jeweler (1.4.0)
|
|
@@ -13,19 +14,24 @@ GEM
|
|
|
13
14
|
json_pure (1.4.6)
|
|
14
15
|
mysql (2.8.1)
|
|
15
16
|
rake (0.8.7)
|
|
16
|
-
rspec (
|
|
17
|
+
rspec (2.5.0)
|
|
18
|
+
rspec-core (~> 2.5.0)
|
|
19
|
+
rspec-expectations (~> 2.5.0)
|
|
20
|
+
rspec-mocks (~> 2.5.0)
|
|
21
|
+
rspec-core (2.5.1)
|
|
22
|
+
rspec-expectations (2.5.0)
|
|
23
|
+
diff-lcs (~> 1.1.2)
|
|
24
|
+
rspec-mocks (2.5.0)
|
|
17
25
|
rubyforge (2.0.4)
|
|
18
26
|
json_pure (>= 1.1.7)
|
|
19
|
-
sqlite3-ruby (1.3.1)
|
|
20
27
|
|
|
21
28
|
PLATFORMS
|
|
22
29
|
ruby
|
|
23
30
|
|
|
24
31
|
DEPENDENCIES
|
|
25
|
-
activerecord
|
|
32
|
+
activerecord (~> 2)
|
|
26
33
|
activesupport
|
|
27
34
|
jeweler
|
|
28
35
|
mysql
|
|
29
36
|
rake
|
|
30
|
-
rspec (~>
|
|
31
|
-
sqlite3-ruby
|
|
37
|
+
rspec (~> 2)
|
data/Rakefile
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
+
require 'rspec/core/rake_task'
|
|
2
|
+
|
|
1
3
|
task :default => :spec
|
|
2
|
-
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
RSpec::Core::RakeTask.new do |t|
|
|
6
|
+
t.rspec_opts = ['--color']
|
|
7
|
+
end
|
|
4
8
|
|
|
5
9
|
begin
|
|
6
10
|
require 'jeweler'
|
|
7
|
-
project_name = 'ar_after_transaction'
|
|
8
11
|
Jeweler::Tasks.new do |gem|
|
|
9
|
-
gem.name =
|
|
12
|
+
gem.name = 'ar_after_transaction'
|
|
10
13
|
gem.summary = "Execute irreversible actions only when transactions are not rolled back"
|
|
11
|
-
gem.email = "
|
|
12
|
-
gem.homepage = "http://github.com/grosser/#{
|
|
14
|
+
gem.email = "michael@grosser.it"
|
|
15
|
+
gem.homepage = "http://github.com/grosser/#{gem.name}"
|
|
13
16
|
gem.authors = ["Michael Grosser"]
|
|
14
17
|
gem.add_dependency ['activerecord']
|
|
15
18
|
end
|
data/Readme.md
CHANGED
|
@@ -2,7 +2,16 @@ Do something only after the currently open transactions have finished.
|
|
|
2
2
|
|
|
3
3
|
Normally everything gets rolled back when a transaction fails, but you cannot roll back sending an email or adding a job to Resque.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Install
|
|
6
|
+
=======
|
|
7
|
+
rails plugin install git://github.com/grosser/ar_after_transaction
|
|
8
|
+
or
|
|
9
|
+
gem install ar_after_transaction
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
Usage
|
|
13
|
+
=====
|
|
14
|
+
### just-in-time callbacks
|
|
6
15
|
class User
|
|
7
16
|
after_create :do_stuff, :oops
|
|
8
17
|
|
|
@@ -18,7 +27,7 @@ Its great for just-in-time callbacks:
|
|
|
18
27
|
end
|
|
19
28
|
end
|
|
20
29
|
|
|
21
|
-
|
|
30
|
+
### General 'this should be rolled back when in a transaction' code like jobs
|
|
22
31
|
|
|
23
32
|
class Resque
|
|
24
33
|
def revertable_enqueue(*args)
|
|
@@ -27,25 +36,26 @@ Or general 'this should be rolled back when in a transaction code like jobs:
|
|
|
27
36
|
end
|
|
28
37
|
end
|
|
29
38
|
end
|
|
30
|
-
|
|
31
|
-
Alternative: after_commit hook in Rails 3, can replace the first usage:
|
|
32
|
-
|
|
33
|
-
class User
|
|
34
|
-
after_commit :send_an_email :on=>:create
|
|
35
|
-
ater_create :do_stuff, :oops
|
|
36
|
-
...
|
|
37
|
-
end
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
### When not in a transaction
|
|
41
|
+
after_transaction will perform the given block immediately
|
|
40
42
|
|
|
43
|
+
### Transactional fixtures <-> normally_open_transactions
|
|
44
|
+
after_transaction assumes zero open transactions.<br/>
|
|
45
|
+
If you use transactional fixtures you should change it in test mode.
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
# config/environments/test.rb
|
|
48
|
+
config.after_initialize do
|
|
49
|
+
ActiveRecord::Base.normally_open_transactions = 1
|
|
50
|
+
end
|
|
44
51
|
|
|
45
|
-
|
|
46
|
-
=====
|
|
47
|
-
- find out if we are in test mode with or without transactions (atm assumes depth of 1 for 'test' env)
|
|
52
|
+
### Rails 3: after_commit hook can replace the first usage example:
|
|
48
53
|
|
|
54
|
+
class User
|
|
55
|
+
after_commit :send_an_email :on=>:create
|
|
56
|
+
after_create :do_stuff, :oops
|
|
57
|
+
...
|
|
58
|
+
end
|
|
49
59
|
|
|
50
60
|
Authors
|
|
51
61
|
=======
|
|
@@ -53,9 +63,8 @@ Authors
|
|
|
53
63
|
|
|
54
64
|
### [Contributors](http://github.com/grosser/ar_after_transaction/contributors)
|
|
55
65
|
- [Bogdan Gusiev](http://gusiev.com)
|
|
66
|
+
- [Benedikt Deicke](http://blog.synatic.net)
|
|
56
67
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
Hereby placed under public domain, do what you want, just do not hold me accountable...
|
|
61
|
-
|
|
68
|
+
[Michael Grosser](http://grosser.it)<br/>
|
|
69
|
+
michael@grosser.it<br/>
|
|
70
|
+
Hereby placed under public domain, do what you want, just do not hold me accountable...
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.2.0
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = %q{ar_after_transaction}
|
|
8
|
-
s.version = "0.
|
|
8
|
+
s.version = "0.2.0"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Michael Grosser"]
|
|
12
|
-
s.date = %q{
|
|
13
|
-
s.email = %q{
|
|
12
|
+
s.date = %q{2011-02-15}
|
|
13
|
+
s.email = %q{michael@grosser.it}
|
|
14
14
|
s.files = [
|
|
15
15
|
"Gemfile",
|
|
16
16
|
"Gemfile.lock",
|
|
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
|
|
|
27
27
|
s.homepage = %q{http://github.com/grosser/ar_after_transaction}
|
|
28
28
|
s.rdoc_options = ["--charset=UTF-8"]
|
|
29
29
|
s.require_paths = ["lib"]
|
|
30
|
-
s.rubygems_version = %q{1.
|
|
30
|
+
s.rubygems_version = %q{1.4.2}
|
|
31
31
|
s.summary = %q{Execute irreversible actions only when transactions are not rolled back}
|
|
32
32
|
s.test_files = [
|
|
33
33
|
"spec/setup_database.rb",
|
|
@@ -36,10 +36,9 @@ Gem::Specification.new do |s|
|
|
|
36
36
|
]
|
|
37
37
|
|
|
38
38
|
if s.respond_to? :specification_version then
|
|
39
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
40
39
|
s.specification_version = 3
|
|
41
40
|
|
|
42
|
-
if Gem::Version.new(Gem::
|
|
41
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
43
42
|
s.add_runtime_dependency(%q<activerecord>, [">= 0"])
|
|
44
43
|
else
|
|
45
44
|
s.add_dependency(%q<activerecord>, [">= 0"])
|
data/lib/ar_after_transaction.rb
CHANGED
|
@@ -5,18 +5,14 @@ module ARAfterTransaction
|
|
|
5
5
|
|
|
6
6
|
def self.included(base)
|
|
7
7
|
base.extend(ClassMethods)
|
|
8
|
-
|
|
9
|
-
class << base
|
|
10
|
-
alias_method_chain :transaction, :callbacks
|
|
11
|
-
end
|
|
12
8
|
end
|
|
13
9
|
|
|
14
10
|
module ClassMethods
|
|
15
|
-
@@
|
|
11
|
+
@@after_transaction_callbacks = []
|
|
16
12
|
|
|
17
|
-
def
|
|
13
|
+
def transaction(&block)
|
|
18
14
|
clean = true
|
|
19
|
-
|
|
15
|
+
super(&block)
|
|
20
16
|
rescue Exception
|
|
21
17
|
clean = false
|
|
22
18
|
raise
|
|
@@ -29,25 +25,29 @@ module ARAfterTransaction
|
|
|
29
25
|
|
|
30
26
|
def after_transaction(&block)
|
|
31
27
|
if transactions_open?
|
|
32
|
-
@@
|
|
28
|
+
@@after_transaction_callbacks << block
|
|
33
29
|
else
|
|
34
30
|
yield
|
|
35
31
|
end
|
|
36
32
|
end
|
|
37
33
|
|
|
34
|
+
def normally_open_transactions
|
|
35
|
+
@normally_open_transactions ||= 0
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def normally_open_transactions=(value)
|
|
39
|
+
@normally_open_transactions = value
|
|
40
|
+
end
|
|
41
|
+
|
|
38
42
|
private
|
|
39
43
|
|
|
40
44
|
def transactions_open?
|
|
41
45
|
connection.open_transactions > normally_open_transactions
|
|
42
46
|
end
|
|
43
47
|
|
|
44
|
-
def normally_open_transactions
|
|
45
|
-
Rails.env.test? ? 1 : 0
|
|
46
|
-
end
|
|
47
|
-
|
|
48
48
|
def delete_after_transaction_callbacks
|
|
49
|
-
result = @@
|
|
50
|
-
@@
|
|
49
|
+
result = @@after_transaction_callbacks
|
|
50
|
+
@@after_transaction_callbacks = []
|
|
51
51
|
result
|
|
52
52
|
end
|
|
53
53
|
end
|
|
@@ -33,7 +33,7 @@ end
|
|
|
33
33
|
|
|
34
34
|
describe ARAfterTransaction do
|
|
35
35
|
before do
|
|
36
|
-
|
|
36
|
+
User.normally_open_transactions = nil
|
|
37
37
|
User.send(:transactions_open?).should == false
|
|
38
38
|
User.test_stack.clear
|
|
39
39
|
User.test_callbacks.clear
|
|
@@ -57,6 +57,16 @@ describe ARAfterTransaction do
|
|
|
57
57
|
User.test_stack.should == [:normal]
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
+
it "clears transation callbacks when transaction fails" do
|
|
61
|
+
User.test_callbacks = [:do_after, :do_normal, :oops]
|
|
62
|
+
lambda{
|
|
63
|
+
User.create!
|
|
64
|
+
}.should raise_error(AnExpectedError)
|
|
65
|
+
User.test_callbacks = [:do_normal]
|
|
66
|
+
User.create!
|
|
67
|
+
User.test_stack.should == [:normal, :normal]
|
|
68
|
+
end
|
|
69
|
+
|
|
60
70
|
it "executes when no transaction is open" do
|
|
61
71
|
user = User.new
|
|
62
72
|
user.do_after
|
|
@@ -65,7 +75,7 @@ describe ARAfterTransaction do
|
|
|
65
75
|
end
|
|
66
76
|
|
|
67
77
|
it "executes when open transactions are normal" do
|
|
68
|
-
|
|
78
|
+
User.normally_open_transactions = 1
|
|
69
79
|
User.test_callbacks = [:do_after, :do_normal]
|
|
70
80
|
User.create!
|
|
71
81
|
User.test_stack.should == [:after, :normal]
|
|
@@ -88,4 +98,15 @@ describe ARAfterTransaction do
|
|
|
88
98
|
}.should raise_error(AnExpectedError)
|
|
89
99
|
User.test_stack.should == [:normal, :normal]
|
|
90
100
|
end
|
|
101
|
+
|
|
102
|
+
describe :normally_open_transactions do
|
|
103
|
+
it "uses 0 by default" do
|
|
104
|
+
User.normally_open_transactions.should == 0
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "can set normally open transactions" do
|
|
108
|
+
User.normally_open_transactions = 5
|
|
109
|
+
User.normally_open_transactions.should == 5
|
|
110
|
+
end
|
|
111
|
+
end
|
|
91
112
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,26 +1,4 @@
|
|
|
1
1
|
require 'rubygems'
|
|
2
2
|
$LOAD_PATH << "lib"
|
|
3
3
|
require "init"
|
|
4
|
-
require "spec/setup_database"
|
|
5
|
-
|
|
6
|
-
class FakeEnv
|
|
7
|
-
def initialize(env)
|
|
8
|
-
@env = env
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def test?
|
|
12
|
-
@env == 'test'
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
module Rails
|
|
17
|
-
def self.env
|
|
18
|
-
@@env
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def self.env=(env)
|
|
22
|
-
@@env = FakeEnv.new(env)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
self.env = 'development'
|
|
26
|
-
end
|
|
4
|
+
require "spec/setup_database"
|
metadata
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ar_after_transaction
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
|
|
4
|
+
hash: 23
|
|
5
|
+
prerelease:
|
|
5
6
|
segments:
|
|
6
7
|
- 0
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
version: 0.
|
|
8
|
+
- 2
|
|
9
|
+
- 0
|
|
10
|
+
version: 0.2.0
|
|
10
11
|
platform: ruby
|
|
11
12
|
authors:
|
|
12
13
|
- Michael Grosser
|
|
@@ -14,23 +15,25 @@ autorequire:
|
|
|
14
15
|
bindir: bin
|
|
15
16
|
cert_chain: []
|
|
16
17
|
|
|
17
|
-
date:
|
|
18
|
+
date: 2011-02-15 00:00:00 +01:00
|
|
18
19
|
default_executable:
|
|
19
20
|
dependencies:
|
|
20
21
|
- !ruby/object:Gem::Dependency
|
|
21
22
|
requirement: &id001 !ruby/object:Gem::Requirement
|
|
23
|
+
none: false
|
|
22
24
|
requirements:
|
|
23
25
|
- - ">="
|
|
24
26
|
- !ruby/object:Gem::Version
|
|
27
|
+
hash: 3
|
|
25
28
|
segments:
|
|
26
29
|
- 0
|
|
27
30
|
version: "0"
|
|
28
|
-
type: :runtime
|
|
29
|
-
version_requirements: *id001
|
|
30
31
|
prerelease: false
|
|
32
|
+
version_requirements: *id001
|
|
33
|
+
type: :runtime
|
|
31
34
|
name: activerecord
|
|
32
35
|
description:
|
|
33
|
-
email:
|
|
36
|
+
email: michael@grosser.it
|
|
34
37
|
executables: []
|
|
35
38
|
|
|
36
39
|
extensions: []
|
|
@@ -59,23 +62,27 @@ rdoc_options:
|
|
|
59
62
|
require_paths:
|
|
60
63
|
- lib
|
|
61
64
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
|
+
none: false
|
|
62
66
|
requirements:
|
|
63
67
|
- - ">="
|
|
64
68
|
- !ruby/object:Gem::Version
|
|
69
|
+
hash: 3
|
|
65
70
|
segments:
|
|
66
71
|
- 0
|
|
67
72
|
version: "0"
|
|
68
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
|
+
none: false
|
|
69
75
|
requirements:
|
|
70
76
|
- - ">="
|
|
71
77
|
- !ruby/object:Gem::Version
|
|
78
|
+
hash: 3
|
|
72
79
|
segments:
|
|
73
80
|
- 0
|
|
74
81
|
version: "0"
|
|
75
82
|
requirements: []
|
|
76
83
|
|
|
77
84
|
rubyforge_project:
|
|
78
|
-
rubygems_version: 1.
|
|
85
|
+
rubygems_version: 1.4.2
|
|
79
86
|
signing_key:
|
|
80
87
|
specification_version: 3
|
|
81
88
|
summary: Execute irreversible actions only when transactions are not rolled back
|