transaction-simple 1.4.0 → 1.4.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/.gemtest +0 -0
- data/{History.txt → History.rdoc} +16 -19
- data/Licence.rdoc +23 -0
- data/Manifest.txt +7 -6
- data/{Readme.txt → README.rdoc} +55 -40
- data/Rakefile +14 -112
- data/lib/transaction-simple.rb +5 -0
- data/lib/transaction/simple.rb +110 -77
- data/lib/transaction/simple/group.rb +82 -92
- data/lib/transaction/simple/threadsafe.rb +25 -35
- data/lib/transaction/simple/threadsafe/group.rb +9 -19
- data/research/instance_variable_defined.rb +22 -0
- data/research/special-dumpable-string.rb +42 -0
- data/research/special-dumpable.rb +130 -0
- data/test/test_broken_graph.rb +4 -14
- data/test/test_transaction_simple.rb +4 -14
- data/test/test_transaction_simple_group.rb +4 -14
- data/test/test_transaction_simple_threadsafe.rb +4 -14
- metadata +174 -58
- data/Install.txt +0 -21
- data/Licence.txt +0 -25
- data/setup.rb +0 -1585
- data/test/test_all.rb +0 -25
data/.gemtest
ADDED
File without changes
|
@@ -1,4 +1,13 @@
|
|
1
|
-
==
|
1
|
+
== 1.4.0.2 / 2012-06-20
|
2
|
+
* Bookkeeping release that fixes install in scenarios where the RubyGem
|
3
|
+
indicated it had a runtime dependency on hoe. Thanks to Michael Grosser
|
4
|
+
(https://github.com/grosser) for the inspiration.
|
5
|
+
* Marked all files as UTF-8.
|
6
|
+
|
7
|
+
== 1.4.0.1 / 2007-10-01
|
8
|
+
* Fixed a simple bug with the #transaction method handling.
|
9
|
+
|
10
|
+
== 1.4.0 / 2007-02-03
|
2
11
|
|
3
12
|
* Adding a post-rewind hook (#_post_transaction_rewind) so that complex
|
4
13
|
graph objects can correct themselves after rewinding. See the
|
@@ -12,13 +21,13 @@
|
|
12
21
|
- Cleaned up the code a little further.
|
13
22
|
- Changed non-gem installer to setup.rb version 3.4.1.
|
14
23
|
|
15
|
-
==
|
24
|
+
== 1.3.1
|
16
25
|
|
17
26
|
* Explicitly clearing the transaction checkpoint on objects when the
|
18
27
|
last open transaction is committed or aborted.
|
19
28
|
* Fixed up behaviour to remove a lot of #respond_to? calls.
|
20
29
|
|
21
|
-
==
|
30
|
+
== 1.3.0
|
22
31
|
|
23
32
|
* Updated to fix a lot of warnings.
|
24
33
|
* Added a per-transaction-object list of excluded instance variables.
|
@@ -30,16 +39,16 @@
|
|
30
39
|
to an object after a transaction was started would remain.
|
31
40
|
* Reorganised unit tests.
|
32
41
|
|
33
|
-
==
|
42
|
+
== 1.2.0
|
34
43
|
|
35
44
|
* Added a RubyGem.
|
36
45
|
* Added a block form of Transaction::Simple.
|
37
46
|
|
38
|
-
==
|
47
|
+
== 1.1.1
|
39
48
|
|
40
49
|
* Cleaned up some documentation.
|
41
50
|
|
42
|
-
==
|
51
|
+
== 1.1
|
43
52
|
|
44
53
|
* Added Transaction::Simple::ThreadSafe for truly atomic and thread-safe
|
45
54
|
transactions.
|
@@ -50,18 +59,6 @@
|
|
50
59
|
explicitly committing, aborting, or rewinding the intervening
|
51
60
|
transactions.
|
52
61
|
|
53
|
-
==
|
62
|
+
== 1.0
|
54
63
|
|
55
64
|
* Created. Initial release.
|
56
|
-
|
57
|
-
== Copyright
|
58
|
-
Transaction::Simple
|
59
|
-
Simple object transaction support for Ruby
|
60
|
-
http://rubyforge.org/projects/trans-simple/
|
61
|
-
|
62
|
-
Licensed under a MIT-style licence. See Licence.txt in the main
|
63
|
-
distribution for full licensing information.
|
64
|
-
|
65
|
-
Copyright (c) 2003 - 2007 Austin Ziegler
|
66
|
-
|
67
|
-
$Id: History.txt 50 2007-02-03 20:26:19Z austin $
|
data/Licence.rdoc
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
== Licence
|
2
|
+
|
3
|
+
This software is available under the terms of the MIT license.
|
4
|
+
|
5
|
+
* Copyright 2003–2012 Austin Ziegler
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
8
|
+
this software and associated documentation files (the "Software"), to deal in
|
9
|
+
the Software without restriction, including without limitation the rights to
|
10
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
11
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
12
|
+
so, subject to the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
15
|
+
copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
SOFTWARE.
|
data/Manifest.txt
CHANGED
@@ -1,15 +1,16 @@
|
|
1
|
-
History.
|
2
|
-
|
3
|
-
Licence.txt
|
1
|
+
History.rdoc
|
2
|
+
Licence.rdoc
|
4
3
|
Manifest.txt
|
4
|
+
README.rdoc
|
5
5
|
Rakefile
|
6
|
-
|
6
|
+
lib/transaction-simple.rb
|
7
7
|
lib/transaction/simple.rb
|
8
8
|
lib/transaction/simple/group.rb
|
9
9
|
lib/transaction/simple/threadsafe.rb
|
10
10
|
lib/transaction/simple/threadsafe/group.rb
|
11
|
-
|
12
|
-
|
11
|
+
research/instance_variable_defined.rb
|
12
|
+
research/special-dumpable-string.rb
|
13
|
+
research/special-dumpable.rb
|
13
14
|
test/test_broken_graph.rb
|
14
15
|
test/test_transaction_simple.rb
|
15
16
|
test/test_transaction_simple_group.rb
|
data/{Readme.txt → README.rdoc}
RENAMED
@@ -1,43 +1,53 @@
|
|
1
1
|
= Transaction::Simple for Ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
home :: http://trans-simple.rubyforge.org/
|
4
|
+
code :: https://github.com/halostatue/transaction-simple
|
5
|
+
bugs :: https://github.com/halostatue/transaction-simple/issues
|
6
|
+
rdoc :: http://trans-simple.rubyforge.org/
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
== Description
|
9
|
+
|
10
|
+
Transaction::Simple provides a generic way to add active transaction support to
|
11
|
+
objects. The transaction methods added by this module will work with most
|
12
|
+
objects, excluding those that cannot be Marshal-ed (bindings, procedure
|
13
|
+
objects, IO instances, or singleton objects).
|
14
|
+
|
15
|
+
The transactions supported by Transaction::Simple are not associated with any
|
16
|
+
sort of data store. They are "live" transactions occurring in memory on the
|
17
|
+
object itself. This is to allow "test" changes to be made to an object before
|
18
|
+
making the changes permanent.
|
12
19
|
|
13
20
|
Transaction::Simple can handle an "infinite" number of transaction levels
|
14
|
-
(limited only by memory). If I open two transactions, commit the second,
|
15
|
-
|
21
|
+
(limited only by memory). If I open two transactions, commit the second, but
|
22
|
+
abort the first, the object will revert to the original version.
|
16
23
|
|
17
|
-
Transaction::Simple supports "named" transactions, so that multiple levels
|
18
|
-
|
24
|
+
Transaction::Simple supports "named" transactions, so that multiple levels of
|
25
|
+
transactions can be committed, aborted, or rewound by referring to the
|
19
26
|
appropriate name of the transaction. Names may be any object except nil.
|
20
27
|
|
21
|
-
Transaction groups are also supported. A transaction group is an object
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
28
|
+
Transaction groups are also supported. A transaction group is an object wrapper
|
29
|
+
that manages a group of objects as if they were a single object for the purpose
|
30
|
+
of transaction management. All transactions for this group of objects should be
|
31
|
+
performed against the transaction group object, not against individual objects
|
32
|
+
in the group.
|
26
33
|
|
27
34
|
Version 1.4.0 of Transaction::Simple adds a new post-rewind hook so that
|
28
35
|
complex graph objects of the type in tests/tc_broken_graph.rb can correct
|
29
36
|
themselves.
|
30
37
|
|
31
|
-
|
32
|
-
|
33
|
-
Homepage:: http://rubyforge.org/projects/trans-simple/
|
34
|
-
Licence:: MIT-Style; see Licence.txt
|
38
|
+
Version 1.4.0.1 just fixes a simple bug with #transaction method handling
|
39
|
+
during the deprecation warning.
|
35
40
|
|
36
|
-
|
37
|
-
|
41
|
+
Version 1.4.0.2 is a small update for people who use Transaction::Simple in
|
42
|
+
bundler (adding lib/transaction-simple.rb) and other scenarios where having Hoe
|
43
|
+
as a runtime dependency (a bug fixed in Hoe several years ago, but not visible
|
44
|
+
in Transaction::Simple because it has not needed a re-release). All of the
|
45
|
+
files internally have also been marked as UTF-8, ensuring full Ruby 1.9
|
46
|
+
compatibility.
|
38
47
|
|
39
48
|
== Usage
|
40
|
-
|
49
|
+
|
50
|
+
require 'transaction/simple'
|
41
51
|
|
42
52
|
v = "Hello, you." # -> "Hello, you."
|
43
53
|
v.extend(Transaction::Simple) # -> "Hello, you."
|
@@ -65,6 +75,7 @@ Matz for their assistance with this library.
|
|
65
75
|
v.transaction_open? # -> false
|
66
76
|
|
67
77
|
== Named Transaction Usage
|
78
|
+
|
68
79
|
v = "Hello, you." # -> "Hello, you."
|
69
80
|
v.extend(Transaction::Simple) # -> "Hello, you."
|
70
81
|
|
@@ -97,10 +108,11 @@ Matz for their assistance with this library.
|
|
97
108
|
v.transaction_open? # -> false
|
98
109
|
|
99
110
|
== Block Transaction Usage
|
111
|
+
|
100
112
|
v = "Hello, you." # -> "Hello, you."
|
101
113
|
Transaction::Simple.start(v) do |tv|
|
102
|
-
|
103
|
-
|
114
|
+
# v has been extended with Transaction::Simple and an unnamed transaction
|
115
|
+
# has been started.
|
104
116
|
tv.transaction_open? # -> true
|
105
117
|
tv.gsub!(/you/, "world") # -> "Hello, world."
|
106
118
|
|
@@ -108,11 +120,11 @@ Matz for their assistance with this library.
|
|
108
120
|
tv.transaction_open? # -> true
|
109
121
|
|
110
122
|
tv.gsub!(/you/, "HAL") # -> "Hello, HAL."
|
111
|
-
|
112
|
-
|
123
|
+
# The following breaks out of the transaction block after aborting the
|
124
|
+
# transaction.
|
113
125
|
tv.abort_transaction # -> "Hello, you."
|
114
126
|
end
|
115
|
-
|
127
|
+
# v still has Transaction::Simple applied from here on out.
|
116
128
|
v.transaction_open? # -> false
|
117
129
|
|
118
130
|
Transaction::Simple.start(v) do |tv|
|
@@ -121,9 +133,9 @@ Matz for their assistance with this library.
|
|
121
133
|
tv.transaction_open? # -> true
|
122
134
|
tv.gsub!(/you/, "HAL") # -> "Hello, HAL."
|
123
135
|
|
124
|
-
|
125
|
-
|
126
|
-
|
136
|
+
# If #commit_transaction were called without having started a second
|
137
|
+
# transaction, then it would break out of the transaction block after
|
138
|
+
# committing the transaction.
|
127
139
|
tv.commit_transaction # -> "Hello, HAL."
|
128
140
|
tv.transaction_open? # -> true
|
129
141
|
tv.abort_transaction # -> "Hello, you."
|
@@ -131,6 +143,7 @@ Matz for their assistance with this library.
|
|
131
143
|
v.transaction_open? # -> false
|
132
144
|
|
133
145
|
== Transaction Groups
|
146
|
+
|
134
147
|
require 'transaction/simple/group'
|
135
148
|
|
136
149
|
x = "Hello, you."
|
@@ -165,6 +178,7 @@ Matz for their assistance with this library.
|
|
165
178
|
y = -> "And you, too."
|
166
179
|
|
167
180
|
== Thread Safety
|
181
|
+
|
168
182
|
Threadsafe versions of Transaction::Simple and Transaction::Simple::Group
|
169
183
|
exist; these are loaded from 'transaction/simple/threadsafe' and
|
170
184
|
'transaction/simple/threadsafe/group', respectively, and are represented in
|
@@ -172,24 +186,25 @@ Ruby code as Transaction::Simple::ThreadSafe and
|
|
172
186
|
Transaction::Simple::ThreadSafe::Group, respectively.
|
173
187
|
|
174
188
|
== Contraindications
|
189
|
+
|
175
190
|
While Transaction::Simple is very useful, it has limitations that must be
|
176
191
|
understood prior to using it. Transaction::Simple:
|
177
192
|
|
178
193
|
* uses Marshal. Thus, any object which cannot be Marshal-ed cannot use
|
179
|
-
Transaction::Simple. In my experience, this affects singleton objects
|
180
|
-
|
194
|
+
Transaction::Simple. In my experience, this affects singleton objects more
|
195
|
+
often than any other object.
|
181
196
|
* does not manage external resources. Resources external to the object and
|
182
197
|
its instance variables are not managed at all. However, all instance
|
183
|
-
variables and objects "belonging" to those instance variables are
|
184
|
-
|
185
|
-
|
198
|
+
variables and objects "belonging" to those instance variables are managed. If
|
199
|
+
there are object reference counts to be handled, Transaction::Simple will
|
200
|
+
probably cause problems.
|
186
201
|
* is not thread-safe. In the ACID ("atomic, consistent, isolated,
|
187
202
|
durable") test, Transaction::Simple provides consistency and durability, but
|
188
203
|
cannot itself provide isolation. Transactions should be considered "critical
|
189
204
|
sections" in multi-threaded applications. Thread safety of the transaction
|
190
205
|
acquisition and release process itself can be ensured with the thread-safe
|
191
|
-
version, Transaction::Simple::ThreadSafe. With transaction groups, some
|
192
|
-
|
206
|
+
version, Transaction::Simple::ThreadSafe. With transaction groups, some level
|
207
|
+
of atomicity is assured.
|
193
208
|
* does not maintain Object#__id__ values on rewind or abort. This only affects
|
194
209
|
complex self-referential graphs. tests/tc_broken_graph.rb demonstrates this
|
195
210
|
and its mitigation with the new post-rewind hook. #_post_transaction_rewind.
|
@@ -201,4 +216,4 @@ understood prior to using it. Transaction::Simple:
|
|
201
216
|
* Can be a memory hog if you use many levels of transactions on many
|
202
217
|
objects.
|
203
218
|
|
204
|
-
|
219
|
+
:include: Licence.rdoc
|
data/Rakefile
CHANGED
@@ -1,122 +1,24 @@
|
|
1
|
-
|
2
|
-
#--
|
3
|
-
# Transaction::Simple
|
4
|
-
# Simple object transaction support for Ruby
|
5
|
-
# http://rubyforge.org/projects/trans-simple/
|
6
|
-
# Version 1.4.0
|
7
|
-
#
|
8
|
-
# Licensed under a MIT-style licence. See Licence.txt in the main
|
9
|
-
# distribution for full licensing information.
|
10
|
-
#
|
11
|
-
# Copyright (c) 2003 - 2007 Austin Ziegler
|
12
|
-
#
|
13
|
-
# $Id: Rakefile 51 2007-02-03 21:45:27Z austin $
|
14
|
-
#++
|
1
|
+
# -*- ruby encoding: utf-8 -*-
|
15
2
|
|
16
3
|
require 'rubygems'
|
17
4
|
require 'hoe'
|
18
5
|
|
19
|
-
|
6
|
+
Hoe.plugin :doofus
|
7
|
+
Hoe.plugin :gemspec
|
8
|
+
Hoe.plugin :rubyforge
|
9
|
+
Hoe.plugin :git
|
20
10
|
|
21
|
-
|
11
|
+
Hoe.spec 'transaction-simple' do
|
12
|
+
self.rubyforge_name = "trans-simple"
|
22
13
|
|
23
|
-
|
24
|
-
DISTDIR = "transaction-simple-#{TSVER}"
|
25
|
-
TARFILE = "pkg/#{DISTDIR}.tar.gz"
|
26
|
-
MANIFEST = File.read("Manifest.txt").split
|
14
|
+
developer('Austin Ziegler', 'austin@rubyforge.org')
|
27
15
|
|
28
|
-
|
29
|
-
|
30
|
-
# This is a lie becasue I will continue to use Archive::Tar::Minitar.
|
31
|
-
p.need_tar = false
|
32
|
-
# need_zip - Should package create a zipfile? [default: false]
|
16
|
+
self.remote_rdoc_dir = ''
|
17
|
+
self.rsync_args << ' --exclude=statsvn/'
|
33
18
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
p.summary = "Simple object transaction support for Ruby."
|
38
|
-
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
39
|
-
p.description = p.paragraphs_of("Readme.txt", 1..1).join("\n\n")
|
40
|
-
|
41
|
-
p.spec_extras[:required_ruby_version] = ">=1.8.2"
|
42
|
-
p.spec_extras[:extra_rdoc_files] = MANIFEST.grep(/txt$/) -
|
43
|
-
["Manifest.txt"]
|
44
|
-
p.clean_globs << "./**/log"
|
45
|
-
|
46
|
-
# extra_deps - An array of rubygem dependencies.
|
47
|
-
# clean_globs - An array of file patterns to delete on clean.
|
48
|
-
# rdoc_pattern - A regexp to match documentation files against the manifest.
|
49
|
-
# spec_extras - A hash of extra values to set in the gemspec.
|
50
|
-
# test_globs - An array of test file patterns [default: test/**/test_*.rb]
|
51
|
-
|
52
|
-
# bin_files
|
53
|
-
# lib_files
|
54
|
-
# spec
|
55
|
-
# test_files
|
19
|
+
self.history_file = 'History.rdoc'
|
20
|
+
self.readme_file = 'README.rdoc'
|
21
|
+
self.extra_rdoc_files = FileList["*.rdoc"].to_a
|
56
22
|
end
|
57
23
|
|
58
|
-
|
59
|
-
task :tar => [ TARFILE ]
|
60
|
-
file TARFILE => [ :test ] do |t|
|
61
|
-
require 'archive/tar/minitar'
|
62
|
-
require 'zlib'
|
63
|
-
files = MANIFEST.map { |f|
|
64
|
-
fn = File.join(DISTDIR, f)
|
65
|
-
tm = File.stat(f).mtime
|
66
|
-
|
67
|
-
if File.directory?(f)
|
68
|
-
{ :name => fn, :mode => 0755, :dir => true, :mtime => tm }
|
69
|
-
else
|
70
|
-
mode = if f =~ %r{^bin}
|
71
|
-
0755
|
72
|
-
else
|
73
|
-
0644
|
74
|
-
end
|
75
|
-
data = File.read(f)
|
76
|
-
{ :name => fn, :mode => mode, :data => data, :size => data.size,
|
77
|
-
:mtime => tm }
|
78
|
-
end
|
79
|
-
}
|
80
|
-
|
81
|
-
begin
|
82
|
-
unless File.directory?(File.dirname(t.name))
|
83
|
-
require 'fileutils'
|
84
|
-
File.mkdir_p File.dirname(t.name)
|
85
|
-
end
|
86
|
-
tf = File.open(t.name, 'wb')
|
87
|
-
gz = Zlib::GzipWriter.new(tf)
|
88
|
-
tw = Archive::Tar::Minitar::Writer.new(gz)
|
89
|
-
|
90
|
-
files.each do |entry|
|
91
|
-
if entry[:dir]
|
92
|
-
tw.mkdir(entry[:name], entry)
|
93
|
-
else
|
94
|
-
tw.add_file_simple(entry[:name], entry) { |os|
|
95
|
-
os.write(entry[:data])
|
96
|
-
}
|
97
|
-
end
|
98
|
-
end
|
99
|
-
ensure
|
100
|
-
tw.close if tw
|
101
|
-
gz.close if gz
|
102
|
-
end
|
103
|
-
end
|
104
|
-
task :package => [ TARFILE ]
|
105
|
-
|
106
|
-
task :build_manifest do |t|
|
107
|
-
require 'find'
|
108
|
-
|
109
|
-
paths = []
|
110
|
-
Find.find(".") do |path|
|
111
|
-
next if File.directory?(path)
|
112
|
-
next if path =~ /\.svn/
|
113
|
-
next if path =~ %r{/research/}
|
114
|
-
next if path =~ /\.swp$/
|
115
|
-
next if path =~ /~$/
|
116
|
-
paths << path.sub(%r{^\./}, '')
|
117
|
-
end
|
118
|
-
|
119
|
-
File.open("Manifest.txt", "w") do |f|
|
120
|
-
f.puts paths.sort.join("\n")
|
121
|
-
end
|
122
|
-
end
|
24
|
+
# vim: syntax=ruby
|
data/lib/transaction/simple.rb
CHANGED
@@ -1,19 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
#--
|
5
|
-
# Transaction::Simple
|
6
|
-
# Simple object transaction support for Ruby
|
7
|
-
# http://rubyforge.org/projects/trans-simple/
|
8
|
-
# Version 1.4.0
|
9
|
-
#
|
10
|
-
# Licensed under a MIT-style licence. See Licence.txt in the main
|
11
|
-
# distribution for full licensing information.
|
12
|
-
#
|
13
|
-
# Copyright (c) 2003 - 2007 Austin Ziegler
|
14
|
-
#
|
15
|
-
# $Id: simple.rb 50 2007-02-03 20:26:19Z austin $
|
16
|
-
#++
|
1
|
+
# -*- ruby encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# :main: README.rdoc
|
17
4
|
|
18
5
|
# The "Transaction" namespace can be used for additional transaction support
|
19
6
|
# objects and modules.
|
@@ -44,13 +31,19 @@ module Transaction
|
|
44
31
|
:cannot_commit_named_transaction => te % "cannot commit nonexistant transaction %s.",
|
45
32
|
:cannot_start_empty_block_transaction => te % "cannot start a block transaction with no objects.",
|
46
33
|
:cannot_obtain_transaction_lock => te % "cannot obtain transaction lock for #%s.",
|
34
|
+
:transaction => "Transaction",
|
35
|
+
:opened => "open",
|
36
|
+
:closed => "closed",
|
37
|
+
:transaction_name => "Transaction Name",
|
38
|
+
:start_transaction => "Start Transaction",
|
39
|
+
:rewind_transaction => "Rewind Transaction",
|
40
|
+
:commit_transaction => "Commit Transaction",
|
41
|
+
:abort_transaction => "Abort Transaction",
|
47
42
|
}
|
48
43
|
end
|
49
44
|
|
50
|
-
# = Transaction::Simple for Ruby
|
51
|
-
# Simple object transaction support for Ruby
|
52
45
|
module Transaction::Simple
|
53
|
-
TRANSACTION_SIMPLE_VERSION = '1.4.0'
|
46
|
+
VERSION = TRANSACTION_SIMPLE_VERSION = '1.4.0.2'
|
54
47
|
|
55
48
|
class << self
|
56
49
|
# Sets the Transaction::Simple debug object. It must respond to #<<.
|
@@ -66,6 +59,10 @@ module Transaction::Simple
|
|
66
59
|
end
|
67
60
|
end
|
68
61
|
|
62
|
+
# Set to +true+ if you want the checkpoint printed with debugging
|
63
|
+
# messages where it matters.
|
64
|
+
attr_accessor :debug_with_checkpoint
|
65
|
+
|
69
66
|
# Returns +true+ if we are debugging.
|
70
67
|
def debugging?
|
71
68
|
defined? @debugging and @debugging
|
@@ -76,31 +73,70 @@ module Transaction::Simple
|
|
76
73
|
@tdi ||= ""
|
77
74
|
@tdi
|
78
75
|
end
|
76
|
+
|
77
|
+
# Fast debugging.
|
78
|
+
def debug(format, *args)
|
79
|
+
return unless debugging?
|
80
|
+
debug_io << (format % args)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def ___tmessage
|
85
|
+
Transaction::Messages
|
86
|
+
end
|
87
|
+
private :___tmessage
|
88
|
+
|
89
|
+
def ___tdebug(char, format, *args)
|
90
|
+
return unless Transaction::Simple.debugging?
|
91
|
+
if @__transaction_level__ > 0
|
92
|
+
Transaction::Simple.debug "#{char * @__transaction_level__} #{format}", args
|
93
|
+
else
|
94
|
+
Transaction::Simple.debug "#{format}", args
|
95
|
+
end
|
79
96
|
end
|
97
|
+
private :___tdebug
|
98
|
+
|
99
|
+
def ___tdebug_checkpoint
|
100
|
+
return unless Transaction::Simple.debugging?
|
101
|
+
return unless Transaction::Simple.debug_with_checkpoint
|
102
|
+
|
103
|
+
___tdebug '|', '%s', @__transaction_checkpoint__.inspect
|
104
|
+
end
|
105
|
+
private :___tdebug_checkpoint
|
80
106
|
|
81
107
|
# If +name+ is +nil+ (default), then returns +true+ if there is currently
|
82
108
|
# a transaction open. If +name+ is specified, then returns +true+ if there
|
83
109
|
# is currently a transaction known as +name+ open.
|
84
110
|
def transaction_open?(name = nil)
|
85
111
|
defined? @__transaction_checkpoint__ or @__transaction_checkpoint__ = nil
|
112
|
+
|
113
|
+
has_t = nil
|
114
|
+
|
86
115
|
if name.nil?
|
87
|
-
|
88
|
-
return (not @__transaction_checkpoint__.nil?)
|
116
|
+
has_t = (not @__transaction_checkpoint__.nil?)
|
89
117
|
else
|
90
|
-
|
91
|
-
|
118
|
+
has_t = ((not @__transaction_checkpoint__.nil?) and
|
119
|
+
@__transaction_names__.include?(name))
|
92
120
|
end
|
121
|
+
|
122
|
+
___tdebug '>', "%s [%s]", ___tmessage[:transaction], ___tmessage[has_t ? :opened : :closed]
|
123
|
+
|
124
|
+
has_t
|
93
125
|
end
|
94
126
|
|
95
127
|
# Returns the current name of the transaction. Transactions not explicitly
|
96
128
|
# named are named +nil+.
|
97
129
|
def transaction_name
|
98
|
-
raise Transaction::TransactionError,
|
99
|
-
|
100
|
-
|
101
|
-
|
130
|
+
raise Transaction::TransactionError, ___tmessage[:no_transaction_open] if @__transaction_checkpoint__.nil?
|
131
|
+
|
132
|
+
name = @__transaction_names__.last
|
133
|
+
|
134
|
+
___tdebug '|', "%s(%s)", ___tmessage[:transaction_name], name.inspect
|
135
|
+
|
136
|
+
if name.kind_of?(String)
|
137
|
+
name.dup
|
102
138
|
else
|
103
|
-
|
139
|
+
name
|
104
140
|
end
|
105
141
|
end
|
106
142
|
|
@@ -114,17 +150,15 @@ module Transaction::Simple
|
|
114
150
|
|
115
151
|
name = name.dup.freeze if name.kind_of?(String)
|
116
152
|
|
117
|
-
raise Transaction::TransactionError,
|
153
|
+
raise Transaction::TransactionError, ___tmessage[:unique_names] if name and @__transaction_names__.include?(name)
|
118
154
|
|
119
155
|
@__transaction_names__ << name
|
120
156
|
@__transaction_level__ += 1
|
121
157
|
|
122
|
-
|
123
|
-
|
124
|
-
ss = "" unless ss
|
158
|
+
___tdebug '>', "%s(%s)", ___tmessage[:start_transaction], name.inspect
|
159
|
+
___tdebug_checkpoint
|
125
160
|
|
126
|
-
|
127
|
-
end
|
161
|
+
checkpoint = Marshal.dump(self)
|
128
162
|
|
129
163
|
@__transaction_checkpoint__ = Marshal.dump(self)
|
130
164
|
end
|
@@ -185,36 +219,39 @@ module Transaction::Simple
|
|
185
219
|
# parent.abort_transaction
|
186
220
|
# puts parent.valid? # => true
|
187
221
|
def rewind_transaction(name = nil)
|
188
|
-
raise Transaction::TransactionError,
|
222
|
+
raise Transaction::TransactionError, ___tmessage[:cannot_rewind_no_transaction] if @__transaction_checkpoint__.nil?
|
189
223
|
|
190
|
-
# Check to see if we are trying to rewind a transaction that is
|
191
|
-
#
|
224
|
+
# Check to see if we are trying to rewind a transaction that is outside
|
225
|
+
# of the current transaction block.
|
192
226
|
defined? @__transaction_block__ or @__transaction_block__ = nil
|
193
227
|
if @__transaction_block__ and name
|
194
228
|
nix = @__transaction_names__.index(name) + 1
|
195
|
-
raise Transaction::TransactionError,
|
229
|
+
raise Transaction::TransactionError, ___tmessage[:cannot_rewind_transaction_before_block] if nix < @__transaction_block__
|
196
230
|
end
|
197
231
|
|
198
232
|
if name.nil?
|
199
233
|
checkpoint = @__transaction_checkpoint__
|
200
234
|
__rewind_this_transaction
|
201
235
|
@__transaction_checkpoint__ = checkpoint
|
202
|
-
ss = "" if Transaction::Simple.debugging?
|
203
236
|
else
|
204
|
-
raise Transaction::TransactionError,
|
205
|
-
ss = "(#{name})" if Transaction::Simple.debugging?
|
237
|
+
raise Transaction::TransactionError, ___tmessage[:cannot_rewind_named_transaction] % name.inspect unless @__transaction_names__.include?(name)
|
206
238
|
|
207
|
-
while @__transaction_names__
|
239
|
+
while @__transaction_names__.last != name
|
240
|
+
___tdebug_checkpoint
|
208
241
|
@__transaction_checkpoint__ = __rewind_this_transaction
|
209
|
-
|
242
|
+
___tdebug '<', ___tmessage[:rewind_transaction], name
|
210
243
|
@__transaction_level__ -= 1
|
211
244
|
@__transaction_names__.pop
|
212
245
|
end
|
246
|
+
|
213
247
|
checkpoint = @__transaction_checkpoint__
|
214
248
|
__rewind_this_transaction
|
215
249
|
@__transaction_checkpoint__ = checkpoint
|
216
250
|
end
|
217
|
-
|
251
|
+
|
252
|
+
___tdebug '|', "%s(%s)", ___tmessage[:rewind_transaction], name.inspect
|
253
|
+
___tdebug_checkpoint
|
254
|
+
|
218
255
|
self
|
219
256
|
end
|
220
257
|
|
@@ -230,7 +267,7 @@ module Transaction::Simple
|
|
230
267
|
# (Transaction::Simple.start), then the execution of the block will be
|
231
268
|
# halted with +break+ +self+.
|
232
269
|
def abort_transaction(name = nil)
|
233
|
-
raise Transaction::TransactionError,
|
270
|
+
raise Transaction::TransactionError, ___tmessage[:cannot_abort_no_transaction] if @__transaction_checkpoint__.nil?
|
234
271
|
|
235
272
|
# Check to see if we are trying to abort a transaction that is outside
|
236
273
|
# of the current transaction block. Otherwise, raise TransactionAborted
|
@@ -238,8 +275,7 @@ module Transaction::Simple
|
|
238
275
|
defined? @__transaction_block__ or @__transaction_block__ = nil
|
239
276
|
if @__transaction_block__ and name
|
240
277
|
nix = @__transaction_names__.index(name) + 1
|
241
|
-
raise Transaction::TransactionError,
|
242
|
-
|
278
|
+
raise Transaction::TransactionError, ___tmessage[:cannot_abort_transaction_before_block] if nix < @__transaction_block__
|
243
279
|
raise Transaction::TransactionAborted if @__transaction_block__ == nix
|
244
280
|
end
|
245
281
|
|
@@ -248,7 +284,7 @@ module Transaction::Simple
|
|
248
284
|
if name.nil?
|
249
285
|
__abort_transaction(name)
|
250
286
|
else
|
251
|
-
raise Transaction::TransactionError,
|
287
|
+
raise Transaction::TransactionError, ___tmessage[:cannot_abort_named_transaction] % name.inspect unless @__transaction_names__.include?(name)
|
252
288
|
__abort_transaction(name) while @__transaction_names__.include?(name)
|
253
289
|
end
|
254
290
|
|
@@ -262,7 +298,7 @@ module Transaction::Simple
|
|
262
298
|
# then all transactions are closed and committed until the named
|
263
299
|
# transaction is reached.
|
264
300
|
def commit_transaction(name = nil)
|
265
|
-
raise Transaction::TransactionError,
|
301
|
+
raise Transaction::TransactionError, ___tmessage[:cannot_commit_no_transaction] if @__transaction_checkpoint__.nil?
|
266
302
|
@__transaction_block__ ||= nil
|
267
303
|
|
268
304
|
# Check to see if we are trying to commit a transaction that is outside
|
@@ -270,7 +306,7 @@ module Transaction::Simple
|
|
270
306
|
# TransactionCommitted if they are the same.
|
271
307
|
if @__transaction_block__ and name
|
272
308
|
nix = @__transaction_names__.index(name) + 1
|
273
|
-
raise Transaction::TransactionError,
|
309
|
+
raise Transaction::TransactionError, ___tmessage[:cannot_commit_transaction_before_block] if nix < @__transaction_block__
|
274
310
|
|
275
311
|
raise Transaction::TransactionCommitted if @__transaction_block__ == nix
|
276
312
|
end
|
@@ -278,21 +314,23 @@ module Transaction::Simple
|
|
278
314
|
raise Transaction::TransactionCommitted if @__transaction_block__ == @__transaction_level__
|
279
315
|
|
280
316
|
if name.nil?
|
281
|
-
|
317
|
+
___tdebug "<", "%s(%s)", ___tmessage[:commit_transaction], name.inspect
|
282
318
|
__commit_transaction
|
283
|
-
Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} " << "Commit Transaction#{ss}\n" if Transaction::Simple.debugging?
|
284
319
|
else
|
285
|
-
raise Transaction::TransactionError,
|
286
|
-
ss = "(#{name})" if Transaction::Simple.debugging?
|
320
|
+
raise Transaction::TransactionError, ___tmessage[:cannot_commit_named_transaction] % name.inspect unless @__transaction_names__.include?(name)
|
287
321
|
|
288
|
-
while @__transaction_names__
|
289
|
-
|
322
|
+
while @__transaction_names__.last != name
|
323
|
+
___tdebug "<", "%s(%s)", ___tmessage[:commit_transaction], name.inspect
|
290
324
|
__commit_transaction
|
325
|
+
___tdebug_checkpoint
|
291
326
|
end
|
292
|
-
|
327
|
+
|
328
|
+
___tdebug "<", "%s(%s)", ___tmessage[:commit_transaction], name.inspect
|
293
329
|
__commit_transaction
|
294
330
|
end
|
295
331
|
|
332
|
+
___tdebug_checkpoint
|
333
|
+
|
296
334
|
self
|
297
335
|
end
|
298
336
|
|
@@ -317,19 +355,19 @@ module Transaction::Simple
|
|
317
355
|
else nil
|
318
356
|
end
|
319
357
|
|
320
|
-
if
|
321
|
-
warn "The #transaction method has been deprecated. Use #{
|
358
|
+
if _method
|
359
|
+
warn "The #transaction method has been deprecated. Use #{_method} instead."
|
322
360
|
else
|
323
361
|
warn "The #transaction method has been deprecated."
|
324
362
|
end
|
325
363
|
|
326
|
-
case
|
364
|
+
case _method
|
327
365
|
when :transaction_name
|
328
|
-
__send__
|
366
|
+
__send__ _method
|
329
367
|
when nil
|
330
368
|
nil
|
331
369
|
else
|
332
|
-
__send__
|
370
|
+
__send__ _method, name
|
333
371
|
end
|
334
372
|
end
|
335
373
|
|
@@ -344,7 +382,7 @@ module Transaction::Simple
|
|
344
382
|
|
345
383
|
class << self
|
346
384
|
def __common_start(name, vars, &block)
|
347
|
-
raise Transaction::TransactionError,
|
385
|
+
raise Transaction::TransactionError, ___tmessage[:cannot_start_empty_block_transaction] if vars.empty?
|
348
386
|
|
349
387
|
if block
|
350
388
|
begin
|
@@ -414,30 +452,25 @@ module Transaction::Simple
|
|
414
452
|
def __abort_transaction(name = nil) #:nodoc:
|
415
453
|
@__transaction_checkpoint__ = __rewind_this_transaction
|
416
454
|
|
417
|
-
|
418
|
-
|
419
|
-
ss = ""
|
420
|
-
else
|
421
|
-
ss = "(#{name.inspect})"
|
422
|
-
end
|
423
|
-
|
424
|
-
Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} " << "Abort Transaction#{ss}\n"
|
425
|
-
end
|
455
|
+
___tdebug '<', "%s(%s)", ___tmessage[:abort_transaction], name.inspect
|
456
|
+
___tdebug_checkpoint
|
426
457
|
|
427
458
|
@__transaction_level__ -= 1
|
428
459
|
@__transaction_names__.pop
|
460
|
+
|
429
461
|
if @__transaction_level__ < 1
|
430
462
|
@__transaction_level__ = 0
|
431
463
|
@__transaction_names__ = []
|
432
464
|
@__transaction_checkpoint__ = nil
|
433
465
|
end
|
434
466
|
end
|
467
|
+
private :__abort_transaction
|
435
468
|
|
436
469
|
SKIP_TRANSACTION_VARS = %w(@__transaction_checkpoint__ @__transaction_level__)
|
437
470
|
|
438
471
|
def __rewind_this_transaction #:nodoc:
|
439
472
|
defined? @__transaction_checkpoint__ or @__transaction_checkpoint__ = nil
|
440
|
-
raise Transaction::TransactionError,
|
473
|
+
raise Transaction::TransactionError, ___tmessage[:cannot_rewind_no_transaction] if @__transaction_checkpoint__.nil?
|
441
474
|
rr = Marshal.restore(@__transaction_checkpoint__)
|
442
475
|
|
443
476
|
replace(rr) if respond_to?(:replace)
|
@@ -461,10 +494,11 @@ module Transaction::Simple
|
|
461
494
|
$-w = w # 20070203 OH is this very UGLY
|
462
495
|
res
|
463
496
|
end
|
497
|
+
private :__rewind_this_transaction
|
464
498
|
|
465
499
|
def __commit_transaction #:nodoc:
|
466
500
|
defined? @__transaction_checkpoint__ or @__transaction_checkpoint__ = nil
|
467
|
-
raise Transaction::TransactionError,
|
501
|
+
raise Transaction::TransactionError, ___tmessage[:cannot_commit_no_transaction] if @__transaction_checkpoint__.nil?
|
468
502
|
old = Marshal.restore(@__transaction_checkpoint__)
|
469
503
|
w, $-w = $-w, false # 20070203 OH is this very UGLY
|
470
504
|
@__transaction_checkpoint__ = old.instance_variable_get(:@__transaction_checkpoint__)
|
@@ -479,8 +513,7 @@ module Transaction::Simple
|
|
479
513
|
@__transaction_checkpoint__ = nil
|
480
514
|
end
|
481
515
|
end
|
482
|
-
|
483
|
-
private :__abort_transaction
|
484
|
-
private :__rewind_this_transaction
|
485
516
|
private :__commit_transaction
|
486
517
|
end
|
518
|
+
|
519
|
+
# vim: syntax=ruby
|