after_commit 1.0.2 → 1.0.3
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/lib/after_commit.rb +38 -27
- data/lib/after_commit/connection_adapters.rb +27 -1
- data/test/after_commit_test.rb +34 -7
- data/test/test_helper.rb +4 -0
- metadata +2 -2
data/lib/after_commit.rb
CHANGED
@@ -1,53 +1,64 @@
|
|
1
1
|
module AfterCommit
|
2
2
|
def self.record(connection, record)
|
3
|
-
|
4
|
-
|
5
|
-
Thread.current[:committed_records][connection.object_id] << record
|
3
|
+
prepare_collection :committed_records, connection
|
4
|
+
add_to_collection :committed_records, connection, record
|
6
5
|
end
|
7
6
|
|
8
7
|
def self.record_created(connection, record)
|
9
|
-
|
10
|
-
|
11
|
-
Thread.current[:committed_records_on_create][connection.object_id] << record
|
8
|
+
prepare_collection :committed_records_on_create, connection
|
9
|
+
add_to_collection :committed_records_on_create, connection, record
|
12
10
|
end
|
13
11
|
|
14
12
|
def self.record_updated(connection, record)
|
15
|
-
|
16
|
-
|
17
|
-
Thread.current[:committed_records_on_update][connection.object_id] << record
|
13
|
+
prepare_collection :committed_records_on_update, connection
|
14
|
+
add_to_collection :committed_records_on_update, connection, record
|
18
15
|
end
|
19
16
|
|
20
17
|
def self.record_destroyed(connection, record)
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
prepare_collection :committed_records_on_destroy, connection
|
19
|
+
add_to_collection :committed_records_on_destroy, connection, record
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.records(connection)
|
23
|
+
collection :committed_records, connection
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.created_records(connection)
|
27
|
-
|
28
|
-
Thread.current[:committed_records_on_create][connection.object_id] ||= []
|
27
|
+
collection :committed_records_on_create, connection
|
29
28
|
end
|
30
29
|
|
31
30
|
def self.updated_records(connection)
|
32
|
-
|
33
|
-
Thread.current[:committed_records_on_update][connection.object_id] ||= []
|
31
|
+
collection :committed_records_on_update, connection
|
34
32
|
end
|
35
33
|
|
36
34
|
def self.destroyed_records(connection)
|
37
|
-
|
38
|
-
Thread.current[:committed_records_on_destroy][connection.object_id] ||= []
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.records(connection)
|
42
|
-
Thread.current[:committed_records] ||= {}
|
43
|
-
Thread.current[:committed_records][connection.object_id] ||= []
|
35
|
+
collection :committed_records_on_destroy, connection
|
44
36
|
end
|
45
37
|
|
46
38
|
def self.cleanup(connection)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
39
|
+
[
|
40
|
+
:committed_records,
|
41
|
+
:committed_records_on_create,
|
42
|
+
:committed_records_on_update,
|
43
|
+
:committed_records_on_destroy
|
44
|
+
].each do |collection|
|
45
|
+
Thread.current[collection] ||= {}
|
46
|
+
Thread.current[collection][connection.old_transaction_key] = []
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.prepare_collection(collection, connection)
|
51
|
+
Thread.current[collection] ||= {}
|
52
|
+
Thread.current[collection][connection.unique_transaction_key] ||= []
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.add_to_collection(collection, connection, record)
|
56
|
+
Thread.current[collection][connection.unique_transaction_key] << record
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.collection(collection, connection)
|
60
|
+
Thread.current[collection] ||= {}
|
61
|
+
Thread.current[collection][connection.old_transaction_key] ||= []
|
51
62
|
end
|
52
63
|
end
|
53
64
|
|
@@ -7,7 +7,9 @@ module AfterCommit
|
|
7
7
|
# override it so that after this happens, any records that were saved
|
8
8
|
# or destroyed within this transaction now get their after_commit
|
9
9
|
# callback fired.
|
10
|
-
def commit_db_transaction_with_callback
|
10
|
+
def commit_db_transaction_with_callback
|
11
|
+
increment_transaction_pointer
|
12
|
+
committed = false
|
11
13
|
begin
|
12
14
|
trigger_before_commit_callbacks
|
13
15
|
trigger_before_commit_on_create_callbacks
|
@@ -15,13 +17,17 @@ module AfterCommit
|
|
15
17
|
trigger_before_commit_on_destroy_callbacks
|
16
18
|
|
17
19
|
commit_db_transaction_without_callback
|
20
|
+
committed = true
|
18
21
|
|
19
22
|
trigger_after_commit_callbacks
|
20
23
|
trigger_after_commit_on_create_callbacks
|
21
24
|
trigger_after_commit_on_update_callbacks
|
22
25
|
trigger_after_commit_on_destroy_callbacks
|
26
|
+
rescue
|
27
|
+
rollback_db_transaction unless committed
|
23
28
|
ensure
|
24
29
|
AfterCommit.cleanup(self)
|
30
|
+
decrement_transaction_pointer
|
25
31
|
end
|
26
32
|
end
|
27
33
|
alias_method_chain :commit_db_transaction, :callback
|
@@ -40,6 +46,14 @@ module AfterCommit
|
|
40
46
|
end
|
41
47
|
alias_method_chain :rollback_db_transaction, :callback
|
42
48
|
|
49
|
+
def unique_transaction_key
|
50
|
+
[object_id, transaction_pointer]
|
51
|
+
end
|
52
|
+
|
53
|
+
def old_transaction_key
|
54
|
+
[object_id, transaction_pointer - 1]
|
55
|
+
end
|
56
|
+
|
43
57
|
protected
|
44
58
|
|
45
59
|
def trigger_before_commit_callbacks
|
@@ -134,6 +148,18 @@ module AfterCommit
|
|
134
148
|
end
|
135
149
|
end
|
136
150
|
end
|
151
|
+
|
152
|
+
def transaction_pointer
|
153
|
+
Thread.current[:after_commit_pointer] ||= 0
|
154
|
+
end
|
155
|
+
|
156
|
+
def increment_transaction_pointer
|
157
|
+
Thread.current[:after_commit_pointer] += 1
|
158
|
+
end
|
159
|
+
|
160
|
+
def decrement_transaction_pointer
|
161
|
+
Thread.current[:after_commit_pointer] -= 1
|
162
|
+
end
|
137
163
|
end
|
138
164
|
end
|
139
165
|
end
|
data/test/after_commit_test.rb
CHANGED
@@ -39,6 +39,26 @@ class MockRecord < ActiveRecord::Base
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
class Foo < ActiveRecord::Base
|
43
|
+
attr_reader :creating
|
44
|
+
|
45
|
+
after_commit :create_bar
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def create_bar
|
50
|
+
@creating ||= 0
|
51
|
+
@creating += 1
|
52
|
+
|
53
|
+
raise Exception, 'looping' if @creating > 1
|
54
|
+
Bar.create
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class Bar < ActiveRecord::Base
|
59
|
+
#
|
60
|
+
end
|
61
|
+
|
42
62
|
class UnsavableRecord < ActiveRecord::Base
|
43
63
|
attr_accessor :after_commit_called
|
44
64
|
|
@@ -65,35 +85,42 @@ class AfterCommitTest < Test::Unit::TestCase
|
|
65
85
|
def test_before_commit_on_create_is_called
|
66
86
|
assert_equal true, MockRecord.create!.before_commit_on_create_called
|
67
87
|
end
|
68
|
-
|
88
|
+
|
69
89
|
def test_before_commit_on_update_is_called
|
70
90
|
record = MockRecord.create!
|
71
91
|
record.save
|
72
92
|
assert_equal true, record.before_commit_on_update_called
|
73
93
|
end
|
74
|
-
|
94
|
+
|
75
95
|
def test_before_commit_on_destroy_is_called
|
76
96
|
assert_equal true, MockRecord.create!.destroy.before_commit_on_destroy_called
|
77
97
|
end
|
78
|
-
|
98
|
+
|
79
99
|
def test_after_commit_on_create_is_called
|
80
100
|
assert_equal true, MockRecord.create!.after_commit_on_create_called
|
81
101
|
end
|
82
|
-
|
102
|
+
|
83
103
|
def test_after_commit_on_update_is_called
|
84
104
|
record = MockRecord.create!
|
85
105
|
record.save
|
86
106
|
assert_equal true, record.after_commit_on_update_called
|
87
107
|
end
|
88
|
-
|
108
|
+
|
89
109
|
def test_after_commit_on_destroy_is_called
|
90
110
|
assert_equal true, MockRecord.create!.destroy.after_commit_on_destroy_called
|
91
111
|
end
|
92
|
-
|
112
|
+
|
93
113
|
def test_after_commit_does_not_trigger_when_transaction_rolls_back
|
94
114
|
record = UnsavableRecord.new
|
95
115
|
begin; record.save; rescue; end
|
96
|
-
|
116
|
+
|
97
117
|
assert_equal false, record.after_commit_called
|
98
118
|
end
|
119
|
+
|
120
|
+
def test_two_transactions_are_separate
|
121
|
+
Bar.delete_all
|
122
|
+
foo = Foo.create
|
123
|
+
|
124
|
+
assert_equal 1, foo.creating
|
125
|
+
end
|
99
126
|
end
|
data/test/test_helper.rb
CHANGED
@@ -13,8 +13,12 @@ end
|
|
13
13
|
ActiveRecord::Base.establish_connection({"adapter" => "sqlite3", "database" => 'test.sqlite3'})
|
14
14
|
begin
|
15
15
|
ActiveRecord::Base.connection.execute("drop table mock_records");
|
16
|
+
ActiveRecord::Base.connection.execute("drop table foos");
|
17
|
+
ActiveRecord::Base.connection.execute("drop table bars");
|
16
18
|
rescue
|
17
19
|
end
|
18
20
|
ActiveRecord::Base.connection.execute("create table mock_records(id int)");
|
21
|
+
ActiveRecord::Base.connection.execute("create table foos(id int)");
|
22
|
+
ActiveRecord::Base.connection.execute("create table bars(id int)");
|
19
23
|
|
20
24
|
require 'after_commit'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: after_commit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Muerdter
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2009-11-
|
14
|
+
date: 2009-11-21 00:00:00 +11:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|