pdf-labels 1.0.0 → 1.0.1

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.
Files changed (60) hide show
  1. data/History.txt +3 -0
  2. data/Manifest.txt +41 -64
  3. data/README.txt +4 -3
  4. data/lib/pdf_labels.rb +1 -4
  5. data/test/test_pdf_label_page.rb +6 -6
  6. data/vendor/transaction/simple.rb +390 -597
  7. data/vendor/transaction/simple/group.rb +13 -0
  8. data/vendor/transaction/simple/threadsafe.rb +18 -2
  9. data/vendor/transaction/simple/threadsafe/group.rb +13 -0
  10. data/vendor/{xml-mapping → xml}/LICENSE +0 -0
  11. data/vendor/{xml-mapping → xml}/README +0 -0
  12. data/vendor/{xml-mapping/lib/xml → xml}/mapping.rb +0 -0
  13. data/vendor/{xml-mapping/lib/xml → xml}/mapping/base.rb +0 -0
  14. data/vendor/{xml-mapping/lib/xml → xml}/mapping/standard_nodes.rb +0 -0
  15. data/vendor/{xml-mapping/lib/xml → xml}/mapping/version.rb +0 -0
  16. data/vendor/{xml-mapping/lib/xml → xml}/xxpath.rb +0 -0
  17. metadata +46 -71
  18. data/vendor/xml-mapping/ChangeLog +0 -128
  19. data/vendor/xml-mapping/README_XPATH +0 -175
  20. data/vendor/xml-mapping/Rakefile +0 -214
  21. data/vendor/xml-mapping/TODO.txt +0 -32
  22. data/vendor/xml-mapping/doc/xpath_impl_notes.txt +0 -119
  23. data/vendor/xml-mapping/examples/company.rb +0 -34
  24. data/vendor/xml-mapping/examples/company.xml +0 -26
  25. data/vendor/xml-mapping/examples/company_usage.intin.rb +0 -19
  26. data/vendor/xml-mapping/examples/company_usage.intout +0 -39
  27. data/vendor/xml-mapping/examples/order.rb +0 -61
  28. data/vendor/xml-mapping/examples/order.xml +0 -54
  29. data/vendor/xml-mapping/examples/order_signature_enhanced.rb +0 -7
  30. data/vendor/xml-mapping/examples/order_signature_enhanced.xml +0 -9
  31. data/vendor/xml-mapping/examples/order_signature_enhanced_usage.intin.rb +0 -12
  32. data/vendor/xml-mapping/examples/order_signature_enhanced_usage.intout +0 -16
  33. data/vendor/xml-mapping/examples/order_usage.intin.rb +0 -73
  34. data/vendor/xml-mapping/examples/order_usage.intout +0 -147
  35. data/vendor/xml-mapping/examples/time_augm.intin.rb +0 -19
  36. data/vendor/xml-mapping/examples/time_augm.intout +0 -23
  37. data/vendor/xml-mapping/examples/time_node.rb +0 -27
  38. data/vendor/xml-mapping/examples/xpath_create_new.intin.rb +0 -85
  39. data/vendor/xml-mapping/examples/xpath_create_new.intout +0 -181
  40. data/vendor/xml-mapping/examples/xpath_docvsroot.intin.rb +0 -30
  41. data/vendor/xml-mapping/examples/xpath_docvsroot.intout +0 -34
  42. data/vendor/xml-mapping/examples/xpath_ensure_created.intin.rb +0 -62
  43. data/vendor/xml-mapping/examples/xpath_ensure_created.intout +0 -114
  44. data/vendor/xml-mapping/examples/xpath_pathological.intin.rb +0 -42
  45. data/vendor/xml-mapping/examples/xpath_pathological.intout +0 -56
  46. data/vendor/xml-mapping/examples/xpath_usage.intin.rb +0 -51
  47. data/vendor/xml-mapping/examples/xpath_usage.intout +0 -57
  48. data/vendor/xml-mapping/install.rb +0 -40
  49. data/vendor/xml-mapping/test/all_tests.rb +0 -6
  50. data/vendor/xml-mapping/test/company.rb +0 -56
  51. data/vendor/xml-mapping/test/documents_folders.rb +0 -33
  52. data/vendor/xml-mapping/test/fixtures/bookmarks1.xml +0 -24
  53. data/vendor/xml-mapping/test/fixtures/company1.xml +0 -85
  54. data/vendor/xml-mapping/test/fixtures/documents_folders.xml +0 -71
  55. data/vendor/xml-mapping/test/fixtures/documents_folders2.xml +0 -30
  56. data/vendor/xml-mapping/test/multiple_mappings.rb +0 -80
  57. data/vendor/xml-mapping/test/tests_init.rb +0 -2
  58. data/vendor/xml-mapping/test/xml_mapping_adv_test.rb +0 -84
  59. data/vendor/xml-mapping/test/xml_mapping_test.rb +0 -201
  60. data/vendor/xml-mapping/test/xpath_test.rb +0 -273
data/History.txt CHANGED
@@ -6,3 +6,6 @@
6
6
 
7
7
  * PDFLabels library packed for Ruport and general consumption
8
8
 
9
+ == 1.0.1 / 2007-10-17
10
+
11
+ * PDFLabels xml-mapping package is wrong in the vendor directory
data/Manifest.txt CHANGED
@@ -1,8 +1,5 @@
1
1
  History.txt
2
- LICENCE
3
- Manifest.txt
4
- README.txt
5
- Rakefile
2
+ lib
6
3
  lib/alias.rb
7
4
  lib/glabel_template.rb
8
5
  lib/label.rb
@@ -12,6 +9,11 @@ lib/markup.rb
12
9
  lib/pdf_label_page.rb
13
10
  lib/pdf_labels.rb
14
11
  lib/template.rb
12
+ LICENCE
13
+ Manifest.txt
14
+ Rakefile
15
+ README.txt
16
+ templates
15
17
  templates/avery-iso-templates.xml
16
18
  templates/avery-other-templates.xml
17
19
  templates/avery-us-templates.xml
@@ -21,30 +23,39 @@ templates/misc-other-templates.xml
21
23
  templates/misc-us-templates.xml
22
24
  templates/paper-sizes.xml
23
25
  templates/zweckform-iso-templates.xml
26
+ test
24
27
  test/test_pdf_label_page.rb
25
- vendor/color.rb
28
+ vendor
29
+ vendor/color
26
30
  vendor/color/cmyk.rb
27
31
  vendor/color/css.rb
28
32
  vendor/color/grayscale.rb
29
33
  vendor/color/hsl.rb
30
- vendor/color/palette.rb
34
+ vendor/color/palette
31
35
  vendor/color/palette/gimp.rb
32
36
  vendor/color/palette/monocontrast.rb
37
+ vendor/color/palette.rb
38
+ vendor/color/rgb
39
+ vendor/color/rgb/metallic.rb
33
40
  vendor/color/rgb-colors.rb
34
41
  vendor/color/rgb.rb
35
- vendor/color/rgb/metallic.rb
36
42
  vendor/color/yiq.rb
37
- vendor/pdf/charts.rb
43
+ vendor/color.rb
44
+ vendor/pdf
45
+ vendor/pdf/charts
38
46
  vendor/pdf/charts/stddev.rb
47
+ vendor/pdf/charts.rb
48
+ vendor/pdf/fonts
39
49
  vendor/pdf/grid.rb
40
50
  vendor/pdf/math.rb
41
51
  vendor/pdf/pagenumbers.rb
42
52
  vendor/pdf/quickref.rb
43
53
  vendor/pdf/simpletable.rb
44
54
  vendor/pdf/techbook.rb
45
- vendor/pdf/writer.rb
55
+ vendor/pdf/writer
46
56
  vendor/pdf/writer/arc4.rb
47
57
  vendor/pdf/writer/fontmetrics.rb
58
+ vendor/pdf/writer/fonts
48
59
  vendor/pdf/writer/fonts/Courier-Bold.afm
49
60
  vendor/pdf/writer/fonts/Courier-BoldOblique.afm
50
61
  vendor/pdf/writer/fonts/Courier-Oblique.afm
@@ -59,11 +70,13 @@ vendor/pdf/writer/fonts/Times-BoldItalic.afm
59
70
  vendor/pdf/writer/fonts/Times-Italic.afm
60
71
  vendor/pdf/writer/fonts/Times-Roman.afm
61
72
  vendor/pdf/writer/fonts/ZapfDingbats.afm
62
- vendor/pdf/writer/graphics.rb
73
+ vendor/pdf/writer/graphics
63
74
  vendor/pdf/writer/graphics/imageinfo.rb
64
- vendor/pdf/writer/lang.rb
75
+ vendor/pdf/writer/graphics.rb
76
+ vendor/pdf/writer/lang
65
77
  vendor/pdf/writer/lang/en.rb
66
- vendor/pdf/writer/object.rb
78
+ vendor/pdf/writer/lang.rb
79
+ vendor/pdf/writer/object
67
80
  vendor/pdf/writer/object/action.rb
68
81
  vendor/pdf/writer/object/annotation.rb
69
82
  vendor/pdf/writer/object/catalog.rb
@@ -81,61 +94,25 @@ vendor/pdf/writer/object/page.rb
81
94
  vendor/pdf/writer/object/pages.rb
82
95
  vendor/pdf/writer/object/procset.rb
83
96
  vendor/pdf/writer/object/viewerpreferences.rb
97
+ vendor/pdf/writer/object.rb
84
98
  vendor/pdf/writer/ohash.rb
85
99
  vendor/pdf/writer/oreader.rb
86
100
  vendor/pdf/writer/state.rb
87
101
  vendor/pdf/writer/strokestyle.rb
88
- vendor/transaction/simple.rb
102
+ vendor/pdf/writer.rb
103
+ vendor/transaction
104
+ vendor/transaction/simple
89
105
  vendor/transaction/simple/group.rb
90
- vendor/transaction/simple/threadsafe.rb
106
+ vendor/transaction/simple/threadsafe
91
107
  vendor/transaction/simple/threadsafe/group.rb
92
- vendor/xml-mapping/ChangeLog
93
- vendor/xml-mapping/LICENSE
94
- vendor/xml-mapping/README
95
- vendor/xml-mapping/README_XPATH
96
- vendor/xml-mapping/Rakefile
97
- vendor/xml-mapping/TODO.txt
98
- vendor/xml-mapping/doc/xpath_impl_notes.txt
99
- vendor/xml-mapping/examples/company.rb
100
- vendor/xml-mapping/examples/company.xml
101
- vendor/xml-mapping/examples/company_usage.intin.rb
102
- vendor/xml-mapping/examples/company_usage.intout
103
- vendor/xml-mapping/examples/order.rb
104
- vendor/xml-mapping/examples/order.xml
105
- vendor/xml-mapping/examples/order_signature_enhanced.rb
106
- vendor/xml-mapping/examples/order_signature_enhanced.xml
107
- vendor/xml-mapping/examples/order_signature_enhanced_usage.intin.rb
108
- vendor/xml-mapping/examples/order_signature_enhanced_usage.intout
109
- vendor/xml-mapping/examples/order_usage.intin.rb
110
- vendor/xml-mapping/examples/order_usage.intout
111
- vendor/xml-mapping/examples/time_augm.intin.rb
112
- vendor/xml-mapping/examples/time_augm.intout
113
- vendor/xml-mapping/examples/time_node.rb
114
- vendor/xml-mapping/examples/xpath_create_new.intin.rb
115
- vendor/xml-mapping/examples/xpath_create_new.intout
116
- vendor/xml-mapping/examples/xpath_docvsroot.intin.rb
117
- vendor/xml-mapping/examples/xpath_docvsroot.intout
118
- vendor/xml-mapping/examples/xpath_ensure_created.intin.rb
119
- vendor/xml-mapping/examples/xpath_ensure_created.intout
120
- vendor/xml-mapping/examples/xpath_pathological.intin.rb
121
- vendor/xml-mapping/examples/xpath_pathological.intout
122
- vendor/xml-mapping/examples/xpath_usage.intin.rb
123
- vendor/xml-mapping/examples/xpath_usage.intout
124
- vendor/xml-mapping/install.rb
125
- vendor/xml-mapping/lib/xml/mapping.rb
126
- vendor/xml-mapping/lib/xml/mapping/base.rb
127
- vendor/xml-mapping/lib/xml/mapping/standard_nodes.rb
128
- vendor/xml-mapping/lib/xml/mapping/version.rb
129
- vendor/xml-mapping/lib/xml/xxpath.rb
130
- vendor/xml-mapping/test/all_tests.rb
131
- vendor/xml-mapping/test/company.rb
132
- vendor/xml-mapping/test/documents_folders.rb
133
- vendor/xml-mapping/test/fixtures/bookmarks1.xml
134
- vendor/xml-mapping/test/fixtures/company1.xml
135
- vendor/xml-mapping/test/fixtures/documents_folders.xml
136
- vendor/xml-mapping/test/fixtures/documents_folders2.xml
137
- vendor/xml-mapping/test/multiple_mappings.rb
138
- vendor/xml-mapping/test/tests_init.rb
139
- vendor/xml-mapping/test/xml_mapping_adv_test.rb
140
- vendor/xml-mapping/test/xml_mapping_test.rb
141
- vendor/xml-mapping/test/xpath_test.rb
108
+ vendor/transaction/simple/threadsafe.rb
109
+ vendor/transaction/simple.rb
110
+ vendor/xml
111
+ vendor/xml/LICENSE
112
+ vendor/xml/mapping
113
+ vendor/xml/mapping/base.rb
114
+ vendor/xml/mapping/standard_nodes.rb
115
+ vendor/xml/mapping/version.rb
116
+ vendor/xml/mapping.rb
117
+ vendor/xml/xxpath.rb
118
+ vendor/xml/README
data/README.txt CHANGED
@@ -1,6 +1,7 @@
1
- PdfLabels
2
- by Rob Kaufman
3
- http://www.lightning-tree.net
1
+ = PdfLabels
2
+
3
+ * by Rob Kaufman - http://www.lightning-tree.net
4
+ * http://rubyforge.org/projects/pdf-labels/
4
5
 
5
6
  == DESCRIPTION:
6
7
 
data/lib/pdf_labels.rb CHANGED
@@ -1,6 +1,3 @@
1
- #This file just adds the lib directory below it into the load path and
2
- #loads up all the classes in lib via require
3
-
4
1
  class Pdflabels
5
- VERSION = '1.0.0'
2
+ VERSION = '1.0.1'
6
3
  end
@@ -3,7 +3,7 @@ require 'test/unit'
3
3
  require 'pdf_label_page'
4
4
 
5
5
  class TestPDFLabelPage < Test::Unit::TestCase
6
-
6
+ ROOT = File.expand_path(File.dirname(__FILE__) + "/../")
7
7
  def setup
8
8
  end
9
9
 
@@ -35,13 +35,13 @@ class TestPDFLabelPage < Test::Unit::TestCase
35
35
  #TODO other options are possible for pdf_options, we need to test those at some point
36
36
 
37
37
  def test_PDFLabelPage_load_tempalte_set
38
- PDFLabelPage.load_template_set(File.expand_path(File.dirname(__FILE__) + "/../templates/avery-iso-templates.xml"))
38
+ PDFLabelPage.load_template_set("#{ROOT}/templates/avery-iso-templates.xml")
39
39
  #Avery 7160 is found in avery-iso-templates
40
40
  p = PDFLabelPage.new("Avery 7160")
41
41
  assert p
42
42
  assert_equal p.pdf.page_width, 595.28
43
43
  assert_equal p.pdf.page_height, 841.89
44
- PDFLabelPage.load_template_set(File.expand_path(File.dirname(__FILE__) + "/../templates/avery-us-templates.xml"))
44
+ PDFLabelPage.load_template_set("#{ROOT}/templates/avery-us-templates.xml")
45
45
  end
46
46
 
47
47
  def test_PDFLabelPage_all_template_names
@@ -71,7 +71,7 @@ class TestPDFLabelPage < Test::Unit::TestCase
71
71
  p.add_label(:position => 8, :text => "This was added last and has a BIG font", :font_size => 18)
72
72
  p.draw_boxes(false, true)
73
73
  #TODO Anybody out there think of a better way to test this?
74
- p.save_as("../test_add_label_output.pdf")
74
+ p.save_as("#{ROOT}/test_add_label_output.pdf")
75
75
  end
76
76
 
77
77
  def test_add_many_labels
@@ -79,13 +79,13 @@ class TestPDFLabelPage < Test::Unit::TestCase
79
79
  #without positoin, so start at 1
80
80
  p.add_many_labels(:text => "Hello Five Times!", :count => 5)
81
81
  p.add_many_labels(:text => "Hellow four more times, starting at 15", :count => 4, :position => 15)
82
- p.save_as("../test_add_many_label_output.pdf")
82
+ p.save_as("#{ROOT}/test_add_many_label_output.pdf")
83
83
  end
84
84
 
85
85
  def test_draw_boxes
86
86
  p = PDFLabelPage.new("Avery 5366") # label is 2 x 10
87
87
  p.draw_boxes
88
- p.save_as("../test_draw_boxes_output.pdf")
88
+ p.save_as("#{ROOT}/test_draw_boxes_output.pdf")
89
89
  end
90
90
 
91
91
  end
@@ -1,693 +1,486 @@
1
1
  # :title: Transaction::Simple -- Active Object Transaction Support for Ruby
2
- # :main: Transaction::Simple
3
- #
4
- # == Licence
5
- #
6
- # Permission is hereby granted, free of charge, to any person obtaining a
7
- # copy of this software and associated documentation files (the "Software"),
8
- # to deal in the Software without restriction, including without limitation
9
- # the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
- # and/or sell copies of the Software, and to permit persons to whom the
11
- # Software is furnished to do so, subject to the following conditions:
12
- #
13
- # The above copyright notice and this permission notice shall be included in
14
- # all copies or substantial portions of the Software.
15
- #
16
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
- # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
- # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
- # DEALINGS IN THE SOFTWARE.
2
+ # :main: Readme.txt
3
+
23
4
  #--
24
5
  # Transaction::Simple
25
- # Simple object transaction support for Ruby
26
- # Version 1.3.0
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.
27
12
  #
28
- # Copyright (c) 2003 - 2005 Austin Ziegler
13
+ # Copyright (c) 2003 - 2007 Austin Ziegler
29
14
  #
30
- # $Id: simple.rb,v 1.5 2005/05/05 16:16:49 austin Exp $
15
+ # $Id: simple.rb 50 2007-02-03 20:26:19Z austin $
31
16
  #++
32
- # The "Transaction" namespace can be used for additional transaction
33
- # support objects and modules.
17
+
18
+ # The "Transaction" namespace can be used for additional transaction support
19
+ # objects and modules.
34
20
  module Transaction
35
- # A standard exception for transaction errors.
21
+ # A standard exception for transaction errors.
36
22
  class TransactionError < StandardError; end
37
- # The TransactionAborted exception is used to indicate when a
38
- # transaction has been aborted in the block form.
23
+ # The TransactionAborted exception is used to indicate when a transaction
24
+ # has been aborted in the block form.
39
25
  class TransactionAborted < Exception; end
40
- # The TransactionCommitted exception is used to indicate when a
41
- # transaction has been committed in the block form.
26
+ # The TransactionCommitted exception is used to indicate when a
27
+ # transaction has been committed in the block form.
42
28
  class TransactionCommitted < Exception; end
43
29
 
44
30
  te = "Transaction Error: %s"
45
31
 
46
- Messages = {
47
- :bad_debug_object =>
48
- te % "the transaction debug object must respond to #<<.",
49
- :unique_names =>
50
- te % "named transactions must be unique.",
51
- :no_transaction_open =>
52
- te % "no transaction open.",
53
- :cannot_rewind_no_transaction =>
54
- te % "cannot rewind; there is no current transaction.",
55
- :cannot_rewind_named_transaction =>
56
- te % "cannot rewind to transaction %s because it does not exist.",
57
- :cannot_rewind_transaction_before_block =>
58
- te % "cannot rewind a transaction started before the execution block.",
59
- :cannot_abort_no_transaction =>
60
- te % "cannot abort; there is no current transaction.",
61
- :cannot_abort_transaction_before_block =>
62
- te % "cannot abort a transaction started before the execution block.",
63
- :cannot_abort_named_transaction =>
64
- te % "cannot abort nonexistant transaction %s.",
65
- :cannot_commit_no_transaction =>
66
- te % "cannot commit; there is no current transaction.",
67
- :cannot_commit_transaction_before_block =>
68
- te % "cannot commit a transaction started before the execution block.",
69
- :cannot_commit_named_transaction =>
70
- te % "cannot commit nonexistant transaction %s.",
71
- :cannot_start_empty_block_transaction =>
72
- te % "cannot start a block transaction with no objects.",
73
- :cannot_obtain_transaction_lock =>
74
- te % "cannot obtain transaction lock for #%s.",
32
+ Messages = { #:nodoc:
33
+ :bad_debug_object => te % "the transaction debug object must respond to #<<.",
34
+ :unique_names => te % "named transactions must be unique.",
35
+ :no_transaction_open => te % "no transaction open.",
36
+ :cannot_rewind_no_transaction => te % "cannot rewind; there is no current transaction.",
37
+ :cannot_rewind_named_transaction => te % "cannot rewind to transaction %s because it does not exist.",
38
+ :cannot_rewind_transaction_before_block => te % "cannot rewind a transaction started before the execution block.",
39
+ :cannot_abort_no_transaction => te % "cannot abort; there is no current transaction.",
40
+ :cannot_abort_transaction_before_block => te % "cannot abort a transaction started before the execution block.",
41
+ :cannot_abort_named_transaction => te % "cannot abort nonexistant transaction %s.",
42
+ :cannot_commit_no_transaction => te % "cannot commit; there is no current transaction.",
43
+ :cannot_commit_transaction_before_block => te % "cannot commit a transaction started before the execution block.",
44
+ :cannot_commit_named_transaction => te % "cannot commit nonexistant transaction %s.",
45
+ :cannot_start_empty_block_transaction => te % "cannot start a block transaction with no objects.",
46
+ :cannot_obtain_transaction_lock => te % "cannot obtain transaction lock for #%s.",
75
47
  }
48
+ end
49
+
50
+ # = Transaction::Simple for Ruby
51
+ # Simple object transaction support for Ruby
52
+ module Transaction::Simple
53
+ TRANSACTION_SIMPLE_VERSION = '1.4.0'
76
54
 
77
- # = Transaction::Simple for Ruby
78
- # Simple object transaction support for Ruby
79
- #
80
- # == Introduction
81
- # Transaction::Simple provides a generic way to add active transaction
82
- # support to objects. The transaction methods added by this module will
83
- # work with most objects, excluding those that cannot be
84
- # <i>Marshal</i>ed (bindings, procedure objects, IO instances, or
85
- # singleton objects).
86
- #
87
- # The transactions supported by Transaction::Simple are not backed
88
- # transactions; they are not associated with any sort of data store.
89
- # They are "live" transactions occurring in memory and in the object
90
- # itself. This is to allow "test" changes to be made to an object
91
- # before making the changes permanent.
92
- #
93
- # Transaction::Simple can handle an "infinite" number of transaction
94
- # levels (limited only by memory). If I open two transactions, commit
95
- # the second, but abort the first, the object will revert to the
96
- # original version.
97
- #
98
- # Transaction::Simple supports "named" transactions, so that multiple
99
- # levels of transactions can be committed, aborted, or rewound by
100
- # referring to the appropriate name of the transaction. Names may be any
101
- # object *except* +nil+. As with Hash keys, String names will be
102
- # duplicated and frozen before using.
103
- #
104
- # Copyright:: Copyright � 2003 - 2005 by Austin Ziegler
105
- # Version:: 1.3.0
106
- # Licence:: MIT-Style
107
- #
108
- # Thanks to David Black for help with the initial concept that led to
109
- # this library.
110
- #
111
- # == Usage
112
- # include 'transaction/simple'
113
- #
114
- # v = "Hello, you." # -> "Hello, you."
115
- # v.extend(Transaction::Simple) # -> "Hello, you."
116
- #
117
- # v.start_transaction # -> ... (a Marshal string)
118
- # v.transaction_open? # -> true
119
- # v.gsub!(/you/, "world") # -> "Hello, world."
120
- #
121
- # v.rewind_transaction # -> "Hello, you."
122
- # v.transaction_open? # -> true
123
- #
124
- # v.gsub!(/you/, "HAL") # -> "Hello, HAL."
125
- # v.abort_transaction # -> "Hello, you."
126
- # v.transaction_open? # -> false
127
- #
128
- # v.start_transaction # -> ... (a Marshal string)
129
- # v.start_transaction # -> ... (a Marshal string)
130
- #
131
- # v.transaction_open? # -> true
132
- # v.gsub!(/you/, "HAL") # -> "Hello, HAL."
133
- #
134
- # v.commit_transaction # -> "Hello, HAL."
135
- # v.transaction_open? # -> true
136
- # v.abort_transaction # -> "Hello, you."
137
- # v.transaction_open? # -> false
138
- #
139
- # == Named Transaction Usage
140
- # v = "Hello, you." # -> "Hello, you."
141
- # v.extend(Transaction::Simple) # -> "Hello, you."
142
- #
143
- # v.start_transaction(:first) # -> ... (a Marshal string)
144
- # v.transaction_open? # -> true
145
- # v.transaction_open?(:first) # -> true
146
- # v.transaction_open?(:second) # -> false
147
- # v.gsub!(/you/, "world") # -> "Hello, world."
148
- #
149
- # v.start_transaction(:second) # -> ... (a Marshal string)
150
- # v.gsub!(/world/, "HAL") # -> "Hello, HAL."
151
- # v.rewind_transaction(:first) # -> "Hello, you."
152
- # v.transaction_open? # -> true
153
- # v.transaction_open?(:first) # -> true
154
- # v.transaction_open?(:second) # -> false
155
- #
156
- # v.gsub!(/you/, "world") # -> "Hello, world."
157
- # v.start_transaction(:second) # -> ... (a Marshal string)
158
- # v.gsub!(/world/, "HAL") # -> "Hello, HAL."
159
- # v.transaction_name # -> :second
160
- # v.abort_transaction(:first) # -> "Hello, you."
161
- # v.transaction_open? # -> false
162
- #
163
- # v.start_transaction(:first) # -> ... (a Marshal string)
164
- # v.gsub!(/you/, "world") # -> "Hello, world."
165
- # v.start_transaction(:second) # -> ... (a Marshal string)
166
- # v.gsub!(/world/, "HAL") # -> "Hello, HAL."
167
- #
168
- # v.commit_transaction(:first) # -> "Hello, HAL."
169
- # v.transaction_open? # -> false
170
- #
171
- # == Block Usage
172
- # v = "Hello, you." # -> "Hello, you."
173
- # Transaction::Simple.start(v) do |tv|
174
- # # v has been extended with Transaction::Simple and an unnamed
175
- # # transaction has been started.
176
- # tv.transaction_open? # -> true
177
- # tv.gsub!(/you/, "world") # -> "Hello, world."
178
- #
179
- # tv.rewind_transaction # -> "Hello, you."
180
- # tv.transaction_open? # -> true
181
- #
182
- # tv.gsub!(/you/, "HAL") # -> "Hello, HAL."
183
- # # The following breaks out of the transaction block after
184
- # # aborting the transaction.
185
- # tv.abort_transaction # -> "Hello, you."
186
- # end
187
- # # v still has Transaction::Simple applied from here on out.
188
- # v.transaction_open? # -> false
189
- #
190
- # Transaction::Simple.start(v) do |tv|
191
- # tv.start_transaction # -> ... (a Marshal string)
192
- #
193
- # tv.transaction_open? # -> true
194
- # tv.gsub!(/you/, "HAL") # -> "Hello, HAL."
195
- #
196
- # # If #commit_transaction were called without having started a
197
- # # second transaction, then it would break out of the transaction
198
- # # block after committing the transaction.
199
- # tv.commit_transaction # -> "Hello, HAL."
200
- # tv.transaction_open? # -> true
201
- # tv.abort_transaction # -> "Hello, you."
202
- # end
203
- # v.transaction_open? # -> false
204
- #
205
- # == Named Transaction Usage
206
- # v = "Hello, you." # -> "Hello, you."
207
- # v.extend(Transaction::Simple) # -> "Hello, you."
208
- #
209
- # v.start_transaction(:first) # -> ... (a Marshal string)
210
- # v.transaction_open? # -> true
211
- # v.transaction_open?(:first) # -> true
212
- # v.transaction_open?(:second) # -> false
213
- # v.gsub!(/you/, "world") # -> "Hello, world."
214
- #
215
- # v.start_transaction(:second) # -> ... (a Marshal string)
216
- # v.gsub!(/world/, "HAL") # -> "Hello, HAL."
217
- # v.rewind_transaction(:first) # -> "Hello, you."
218
- # v.transaction_open? # -> true
219
- # v.transaction_open?(:first) # -> true
220
- # v.transaction_open?(:second) # -> false
221
- #
222
- # v.gsub!(/you/, "world") # -> "Hello, world."
223
- # v.start_transaction(:second) # -> ... (a Marshal string)
224
- # v.gsub!(/world/, "HAL") # -> "Hello, HAL."
225
- # v.transaction_name # -> :second
226
- # v.abort_transaction(:first) # -> "Hello, you."
227
- # v.transaction_open? # -> false
228
- #
229
- # v.start_transaction(:first) # -> ... (a Marshal string)
230
- # v.gsub!(/you/, "world") # -> "Hello, world."
231
- # v.start_transaction(:second) # -> ... (a Marshal string)
232
- # v.gsub!(/world/, "HAL") # -> "Hello, HAL."
233
- #
234
- # v.commit_transaction(:first) # -> "Hello, HAL."
235
- # v.transaction_open? # -> false
236
- #
237
- # == Thread Safety
238
- # Threadsafe version of Transaction::Simple and
239
- # Transaction::Simple::Group exist; these are loaded from
240
- # 'transaction/simple/threadsafe' and
241
- # 'transaction/simple/threadsafe/group', respectively, and are
242
- # represented in Ruby code as Transaction::Simple::ThreadSafe and
243
- # Transaction::Simple::ThreadSafe::Group, respectively.
244
- #
245
- # == Contraindications
246
- # While Transaction::Simple is very useful, it has some severe
247
- # limitations that must be understood. Transaction::Simple:
248
- #
249
- # * uses Marshal. Thus, any object which cannot be <i>Marshal</i>ed
250
- # cannot use Transaction::Simple. In my experience, this affects
251
- # singleton objects more often than any other object. It may be that
252
- # Ruby 2.0 will solve this problem.
253
- # * does not manage resources. Resources external to the object and its
254
- # instance variables are not managed at all. However, all instance
255
- # variables and objects "belonging" to those instance variables are
256
- # managed. If there are object reference counts to be handled,
257
- # Transaction::Simple will probably cause problems.
258
- # * is not inherently thread-safe. In the ACID ("atomic, consistent,
259
- # isolated, durable") test, Transaction::Simple provides CD, but it is
260
- # up to the user of Transaction::Simple to provide isolation and
261
- # atomicity. Transactions should be considered "critical sections" in
262
- # multi-threaded applications. If thread safety and atomicity is
263
- # absolutely required, use Transaction::Simple::ThreadSafe, which uses
264
- # a Mutex object to synchronize the accesses on the object during the
265
- # transaction operations.
266
- # * does not necessarily maintain Object#__id__ values on rewind or
267
- # abort. This may change for future versions that will be Ruby 1.8 or
268
- # better *only*. Certain objects that support #replace will maintain
269
- # Object#__id__.
270
- # * Can be a memory hog if you use many levels of transactions on many
271
- # objects.
272
- #
273
- module Simple
274
- TRANSACTION_SIMPLE_VERSION = '1.3.0'
275
-
276
- # Sets the Transaction::Simple debug object. It must respond to #<<.
277
- # Sets the transaction debug object. Debugging will be performed
278
- # automatically if there's a debug object. The generic transaction
279
- # error class.
280
- def self.debug_io=(io)
55
+ class << self
56
+ # Sets the Transaction::Simple debug object. It must respond to #<<.
57
+ # Debugging will be performed automatically if there's a debug object.
58
+ def debug_io=(io)
281
59
  if io.nil?
282
60
  @tdi = nil
283
61
  @debugging = false
284
62
  else
285
- unless io.respond_to?(:<<)
286
- raise TransactionError, Messages[:bad_debug_object]
287
- end
63
+ raise Transaction::TransactionError, Transaction::Messages[:bad_debug_object] unless io.respond_to?(:<<)
288
64
  @tdi = io
289
65
  @debugging = true
290
66
  end
291
67
  end
292
68
 
293
- # Returns +true+ if we are debugging.
294
- def self.debugging?
295
- @debugging
69
+ # Returns +true+ if we are debugging.
70
+ def debugging?
71
+ defined? @debugging and @debugging
296
72
  end
297
73
 
298
- # Returns the Transaction::Simple debug object. It must respond to
299
- # #<<.
300
- def self.debug_io
74
+ # Returns the Transaction::Simple debug object. It must respond to #<<.
75
+ def debug_io
301
76
  @tdi ||= ""
302
77
  @tdi
303
78
  end
79
+ end
304
80
 
305
- # If +name+ is +nil+ (default), then returns +true+ if there is
306
- # currently a transaction open.
307
- #
308
- # If +name+ is specified, then returns +true+ if there is currently a
309
- # transaction that responds to +name+ open.
310
- def transaction_open?(name = nil)
311
- if name.nil?
312
- if Transaction::Simple.debugging?
313
- Transaction::Simple.debug_io << "Transaction " <<
314
- "[#{(@__transaction_checkpoint__.nil?) ? 'closed' : 'open'}]\n"
315
- end
316
- return (not @__transaction_checkpoint__.nil?)
317
- else
318
- if Transaction::Simple.debugging?
319
- Transaction::Simple.debug_io << "Transaction(#{name.inspect}) " <<
320
- "[#{(@__transaction_checkpoint__.nil?) ? 'closed' : 'open'}]\n"
321
- end
322
- return ((not @__transaction_checkpoint__.nil?) and @__transaction_names__.include?(name))
323
- end
81
+ # If +name+ is +nil+ (default), then returns +true+ if there is currently
82
+ # a transaction open. If +name+ is specified, then returns +true+ if there
83
+ # is currently a transaction known as +name+ open.
84
+ def transaction_open?(name = nil)
85
+ defined? @__transaction_checkpoint__ or @__transaction_checkpoint__ = nil
86
+ if name.nil?
87
+ Transaction::Simple.debug_io << "Transaction " << "[#{(@__transaction_checkpoint__.nil?) ? 'closed' : 'open'}]\n" if Transaction::Simple.debugging?
88
+ return (not @__transaction_checkpoint__.nil?)
89
+ else
90
+ Transaction::Simple.debug_io << "Transaction(#{name.inspect}) " << "[#{(@__transaction_checkpoint__.nil?) ? 'closed' : 'open'}]\n" if Transaction::Simple.debugging?
91
+ return ((not @__transaction_checkpoint__.nil?) and @__transaction_names__.include?(name))
324
92
  end
93
+ end
325
94
 
326
- # Returns the current name of the transaction. Transactions not
327
- # explicitly named are named +nil+.
328
- def transaction_name
329
- if @__transaction_checkpoint__.nil?
330
- raise TransactionError, Messages[:no_transaction_open]
331
- end
332
- if Transaction::Simple.debugging?
333
- Transaction::Simple.debug_io << "#{'|' * @__transaction_level__} " <<
334
- "Transaction Name: #{@__transaction_names__[-1].inspect}\n"
335
- end
336
- if @__transaction_names__[-1].kind_of?(String)
337
- @__transaction_names__[-1].dup
338
- else
339
- @__transaction_names__[-1]
340
- end
95
+ # Returns the current name of the transaction. Transactions not explicitly
96
+ # named are named +nil+.
97
+ def transaction_name
98
+ raise Transaction::TransactionError, Transaction::Messages[:no_transaction_open] if @__transaction_checkpoint__.nil?
99
+ Transaction::Simple.debug_io << "#{'|' * @__transaction_level__} " << "Transaction Name: #{@__transaction_names__[-1].inspect}\n" if Transaction::Simple.debugging?
100
+ if @__transaction_names__[-1].kind_of?(String)
101
+ @__transaction_names__[-1].dup
102
+ else
103
+ @__transaction_names__[-1]
341
104
  end
105
+ end
342
106
 
343
- # Starts a transaction. Stores the current object state. If a
344
- # transaction name is specified, the transaction will be named.
345
- # Transaction names must be unique. Transaction names of +nil+ will be
346
- # treated as unnamed transactions.
347
- def start_transaction(name = nil)
348
- @__transaction_level__ ||= 0
349
- @__transaction_names__ ||= []
107
+ # Starts a transaction. Stores the current object state. If a transaction
108
+ # name is specified, the transaction will be named. Transaction names must
109
+ # be unique. Transaction names of +nil+ will be treated as unnamed
110
+ # transactions.
111
+ def start_transaction(name = nil)
112
+ @__transaction_level__ ||= 0
113
+ @__transaction_names__ ||= []
350
114
 
351
- if name.nil?
352
- @__transaction_names__ << nil
353
- ss = "" if Transaction::Simple.debugging?
354
- else
355
- if @__transaction_names__.include?(name)
356
- raise TransactionError, Messages[:unique_names]
357
- end
358
- name = name.dup.freeze if name.kind_of?(String)
359
- @__transaction_names__ << name
360
- ss = "(#{name.inspect})" if Transaction::Simple.debugging?
361
- end
362
-
363
- @__transaction_level__ += 1
115
+ name = name.dup.freeze if name.kind_of?(String)
364
116
 
365
- if Transaction::Simple.debugging?
366
- Transaction::Simple.debug_io << "#{'>' * @__transaction_level__} " <<
367
- "Start Transaction#{ss}\n"
368
- end
117
+ raise Transaction::TransactionError, Transaction::Messages[:unique_names] if name and @__transaction_names__.include?(name)
369
118
 
370
- @__transaction_checkpoint__ = Marshal.dump(self)
371
- end
119
+ @__transaction_names__ << name
120
+ @__transaction_level__ += 1
372
121
 
373
- # Rewinds the transaction. If +name+ is specified, then the
374
- # intervening transactions will be aborted and the named transaction
375
- # will be rewound. Otherwise, only the current transaction is rewound.
376
- def rewind_transaction(name = nil)
377
- if @__transaction_checkpoint__.nil?
378
- raise TransactionError, Messages[:cannot_rewind_no_transaction]
379
- end
122
+ if Transaction::Simple.debugging?
123
+ ss = "(#{name.inspect})"
124
+ ss = "" unless ss
380
125
 
381
- # Check to see if we are trying to rewind a transaction that is
382
- # outside of the current transaction block.
383
- if @__transaction_block__ and name
384
- nix = @__transaction_names__.index(name) + 1
385
- if nix < @__transaction_block__
386
- raise TransactionError, Messages[:cannot_rewind_transaction_before_block]
387
- end
388
- end
126
+ Transaction::Simple.debug_io << "#{'>' * @__transaction_level__} " << "Start Transaction#{ss}\n"
127
+ end
389
128
 
390
- if name.nil?
391
- __rewind_this_transaction
392
- ss = "" if Transaction::Simple.debugging?
393
- else
394
- unless @__transaction_names__.include?(name)
395
- raise TransactionError, Messages[:cannot_rewind_named_transaction] % name.inspect
396
- end
397
- ss = "(#{name})" if Transaction::Simple.debugging?
129
+ @__transaction_checkpoint__ = Marshal.dump(self)
130
+ end
398
131
 
399
- while @__transaction_names__[-1] != name
400
- @__transaction_checkpoint__ = __rewind_this_transaction
401
- if Transaction::Simple.debugging?
402
- Transaction::Simple.debug_io << "#{'|' * @__transaction_level__} " <<
403
- "Rewind Transaction#{ss}\n"
404
- end
405
- @__transaction_level__ -= 1
406
- @__transaction_names__.pop
407
- end
408
- __rewind_this_transaction
409
- end
410
- if Transaction::Simple.debugging?
411
- Transaction::Simple.debug_io << "#{'|' * @__transaction_level__} " <<
412
- "Rewind Transaction#{ss}\n"
413
- end
414
- self
132
+ # Rewinds the transaction. If +name+ is specified, then the intervening
133
+ # transactions will be aborted and the named transaction will be rewound.
134
+ # Otherwise, only the current transaction is rewound.
135
+ #
136
+ # After each level of transaction is rewound, if the callback method
137
+ # #_post_transaction_rewind is defined, it will be called. It is intended
138
+ # to allow a complex self-referential graph to fix itself. The simplest
139
+ # way to explain this is with an example.
140
+ #
141
+ # class Child
142
+ # attr_accessor :parent
143
+ # end
144
+ #
145
+ # class Parent
146
+ # include Transaction::Simple
147
+ #
148
+ # attr_reader :children
149
+ # def initialize
150
+ # @children = []
151
+ # end
152
+ #
153
+ # def << child
154
+ # child.parent = self
155
+ # @children << child
156
+ # end
157
+ #
158
+ # def valid?
159
+ # @children.all? { |child| child.parent == self }
160
+ # end
161
+ # end
162
+ #
163
+ # parent = Parent.new
164
+ # parent << Child.new
165
+ # parent.start_transaction
166
+ # parent << Child.new
167
+ # parent.abort_transaction
168
+ # puts parent.valid? # => false
169
+ #
170
+ # This problem can be fixed by modifying the Parent class to include the
171
+ # #_post_transaction_rewind callback.
172
+ #
173
+ # class Parent
174
+ # # Reconnect the restored children to me, instead of to the bogus me
175
+ # # that was restored to them by Marshal::load.
176
+ # def _post_transaction_rewind
177
+ # @children.each { |child| child.parent = self }
178
+ # end
179
+ # end
180
+ #
181
+ # parent = Parent.new
182
+ # parent << Child.new
183
+ # parent.start_transaction
184
+ # parent << Child.new
185
+ # parent.abort_transaction
186
+ # puts parent.valid? # => true
187
+ def rewind_transaction(name = nil)
188
+ raise Transaction::TransactionError, Transaction::Messages[:cannot_rewind_no_transaction] if @__transaction_checkpoint__.nil?
189
+
190
+ # Check to see if we are trying to rewind a transaction that is
191
+ # outside of the current transaction block.
192
+ defined? @__transaction_block__ or @__transaction_block__ = nil
193
+ if @__transaction_block__ and name
194
+ nix = @__transaction_names__.index(name) + 1
195
+ raise Transaction::TransactionError, Transaction::Messages[:cannot_rewind_transaction_before_block] if nix < @__transaction_block__
415
196
  end
416
197
 
417
- # Aborts the transaction. Resets the object state to what it was
418
- # before the transaction was started and closes the transaction. If
419
- # +name+ is specified, then the intervening transactions and the named
420
- # transaction will be aborted. Otherwise, only the current transaction
421
- # is aborted.
422
- #
423
- # If the current or named transaction has been started by a block
424
- # (Transaction::Simple.start), then the execution of the block will be
425
- # halted with +break+ +self+.
426
- def abort_transaction(name = nil)
427
- if @__transaction_checkpoint__.nil?
428
- raise TransactionError, Messages[:cannot_abort_no_transaction]
198
+ if name.nil?
199
+ checkpoint = @__transaction_checkpoint__
200
+ __rewind_this_transaction
201
+ @__transaction_checkpoint__ = checkpoint
202
+ ss = "" if Transaction::Simple.debugging?
203
+ else
204
+ raise Transaction::TransactionError, Transaction::Messages[:cannot_rewind_named_transaction] % name.inspect unless @__transaction_names__.include?(name)
205
+ ss = "(#{name})" if Transaction::Simple.debugging?
206
+
207
+ while @__transaction_names__[-1] != name
208
+ @__transaction_checkpoint__ = __rewind_this_transaction
209
+ Transaction::Simple.debug_io << "#{'|' * @__transaction_level__} " << "Rewind Transaction#{ss}\n" if Transaction::Simple.debugging?
210
+ @__transaction_level__ -= 1
211
+ @__transaction_names__.pop
429
212
  end
213
+ checkpoint = @__transaction_checkpoint__
214
+ __rewind_this_transaction
215
+ @__transaction_checkpoint__ = checkpoint
216
+ end
217
+ Transaction::Simple.debug_io << "#{'|' * @__transaction_level__} " << "Rewind Transaction#{ss}\n" if Transaction::Simple.debugging?
218
+ self
219
+ end
430
220
 
431
- # Check to see if we are trying to abort a transaction that is
432
- # outside of the current transaction block. Otherwise, raise
433
- # TransactionAborted if they are the same.
434
- if @__transaction_block__ and name
435
- nix = @__transaction_names__.index(name) + 1
436
- if nix < @__transaction_block__
437
- raise TransactionError, Messages[:cannot_abort_transaction_before_block]
438
- end
439
-
440
- raise TransactionAborted if @__transaction_block__ == nix
441
- end
221
+ # Aborts the transaction. Rewinds the object state to what it was before
222
+ # the transaction was started and closes the transaction. If +name+ is
223
+ # specified, then the intervening transactions and the named transaction
224
+ # will be aborted. Otherwise, only the current transaction is aborted.
225
+ #
226
+ # See #rewind_transaction for information about dealing with complex
227
+ # self-referential object graphs.
228
+ #
229
+ # If the current or named transaction has been started by a block
230
+ # (Transaction::Simple.start), then the execution of the block will be
231
+ # halted with +break+ +self+.
232
+ def abort_transaction(name = nil)
233
+ raise Transaction::TransactionError, Transaction::Messages[:cannot_abort_no_transaction] if @__transaction_checkpoint__.nil?
234
+
235
+ # Check to see if we are trying to abort a transaction that is outside
236
+ # of the current transaction block. Otherwise, raise TransactionAborted
237
+ # if they are the same.
238
+ defined? @__transaction_block__ or @__transaction_block__ = nil
239
+ if @__transaction_block__ and name
240
+ nix = @__transaction_names__.index(name) + 1
241
+ raise Transaction::TransactionError, Transaction::Messages[:cannot_abort_transaction_before_block] if nix < @__transaction_block__
242
+
243
+ raise Transaction::TransactionAborted if @__transaction_block__ == nix
244
+ end
442
245
 
443
- raise TransactionAborted if @__transaction_block__ == @__transaction_level__
246
+ raise Transaction::TransactionAborted if @__transaction_block__ == @__transaction_level__
444
247
 
445
- if name.nil?
446
- __abort_transaction(name)
447
- else
448
- unless @__transaction_names__.include?(name)
449
- raise TransactionError, Messages[:cannot_abort_named_transaction] % name.inspect
450
- end
451
- __abort_transaction(name) while @__transaction_names__.include?(name)
452
- end
453
- self
248
+ if name.nil?
249
+ __abort_transaction(name)
250
+ else
251
+ raise Transaction::TransactionError, Transaction::Messages[:cannot_abort_named_transaction] % name.inspect unless @__transaction_names__.include?(name)
252
+ __abort_transaction(name) while @__transaction_names__.include?(name)
454
253
  end
455
254
 
456
- # If +name+ is +nil+ (default), the current transaction level is
457
- # closed out and the changes are committed.
458
- #
459
- # If +name+ is specified and +name+ is in the list of named
460
- # transactions, then all transactions are closed and committed until
461
- # the named transaction is reached.
462
- def commit_transaction(name = nil)
463
- if @__transaction_checkpoint__.nil?
464
- raise TransactionError, Messages[:cannot_commit_no_transaction]
465
- end
466
- @__transaction_block__ ||= nil
467
-
468
- # Check to see if we are trying to commit a transaction that is
469
- # outside of the current transaction block. Otherwise, raise
470
- # TransactionCommitted if they are the same.
471
- if @__transaction_block__ and name
472
- nix = @__transaction_names__.index(name) + 1
473
- if nix < @__transaction_block__
474
- raise TransactionError, Messages[:cannot_commit_transaction_before_block]
475
- end
255
+ self
256
+ end
476
257
 
477
- raise TransactionCommitted if @__transaction_block__ == nix
478
- end
258
+ # If +name+ is +nil+ (default), the current transaction level is closed
259
+ # out and the changes are committed.
260
+ #
261
+ # If +name+ is specified and +name+ is in the list of named transactions,
262
+ # then all transactions are closed and committed until the named
263
+ # transaction is reached.
264
+ def commit_transaction(name = nil)
265
+ raise Transaction::TransactionError, Transaction::Messages[:cannot_commit_no_transaction] if @__transaction_checkpoint__.nil?
266
+ @__transaction_block__ ||= nil
267
+
268
+ # Check to see if we are trying to commit a transaction that is outside
269
+ # of the current transaction block. Otherwise, raise
270
+ # TransactionCommitted if they are the same.
271
+ if @__transaction_block__ and name
272
+ nix = @__transaction_names__.index(name) + 1
273
+ raise Transaction::TransactionError, Transaction::Messages[:cannot_commit_transaction_before_block] if nix < @__transaction_block__
274
+
275
+ raise Transaction::TransactionCommitted if @__transaction_block__ == nix
276
+ end
479
277
 
480
- raise TransactionCommitted if @__transaction_block__ == @__transaction_level__
278
+ raise Transaction::TransactionCommitted if @__transaction_block__ == @__transaction_level__
481
279
 
482
- if name.nil?
483
- ss = "" if Transaction::Simple.debugging?
484
- __commit_transaction
485
- if Transaction::Simple.debugging?
486
- Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} " <<
487
- "Commit Transaction#{ss}\n"
488
- end
489
- else
490
- unless @__transaction_names__.include?(name)
491
- raise TransactionError, Messages[:cannot_commit_named_transaction] % name.inspect
492
- end
493
- ss = "(#{name})" if Transaction::Simple.debugging?
280
+ if name.nil?
281
+ ss = "" if Transaction::Simple.debugging?
282
+ __commit_transaction
283
+ Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} " << "Commit Transaction#{ss}\n" if Transaction::Simple.debugging?
284
+ else
285
+ raise Transaction::TransactionError, Transaction::Messages[:cannot_commit_named_transaction] % name.inspect unless @__transaction_names__.include?(name)
286
+ ss = "(#{name})" if Transaction::Simple.debugging?
494
287
 
495
- while @__transaction_names__[-1] != name
496
- if Transaction::Simple.debugging?
497
- Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} " <<
498
- "Commit Transaction#{ss}\n"
499
- end
500
- __commit_transaction
501
- end
502
- if Transaction::Simple.debugging?
503
- Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} " <<
504
- "Commit Transaction#{ss}\n"
505
- end
288
+ while @__transaction_names__[-1] != name
289
+ Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} " << "Commit Transaction#{ss}\n" if Transaction::Simple.debugging?
506
290
  __commit_transaction
507
291
  end
508
-
509
- self
292
+ Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} " << "Commit Transaction#{ss}\n" if Transaction::Simple.debugging?
293
+ __commit_transaction
510
294
  end
511
295
 
512
- # Alternative method for calling the transaction methods. An optional
513
- # name can be specified for named transaction support.
514
- #
515
- # #transaction(:start):: #start_transaction
516
- # #transaction(:rewind):: #rewind_transaction
517
- # #transaction(:abort):: #abort_transaction
518
- # #transaction(:commit):: #commit_transaction
519
- # #transaction(:name):: #transaction_name
520
- # #transaction:: #transaction_open?
521
- def transaction(action = nil, name = nil)
522
- case action
523
- when :start
524
- start_transaction(name)
525
- when :rewind
526
- rewind_transaction(name)
527
- when :abort
528
- abort_transaction(name)
529
- when :commit
530
- commit_transaction(name)
531
- when :name
532
- transaction_name
533
- when nil
534
- transaction_open?(name)
535
- end
296
+ self
297
+ end
298
+
299
+ # Alternative method for calling the transaction methods. An optional name
300
+ # can be specified for named transaction support. This method is
301
+ # deprecated and will be removed in Transaction::Simple 2.0.
302
+ #
303
+ # #transaction(:start):: #start_transaction
304
+ # #transaction(:rewind):: #rewind_transaction
305
+ # #transaction(:abort):: #abort_transaction
306
+ # #transaction(:commit):: #commit_transaction
307
+ # #transaction(:name):: #transaction_name
308
+ # #transaction:: #transaction_open?
309
+ def transaction(action = nil, name = nil)
310
+ _method = case action
311
+ when :start then :start_transaction
312
+ when :rewind then :rewind_transaction
313
+ when :abort then :abort_transaction
314
+ when :commit then :commit_transaction
315
+ when :name then :transaction_name
316
+ when nil then :transaction_open?
317
+ else nil
318
+ end
319
+
320
+ if method
321
+ warn "The #transaction method has been deprecated. Use #{method} instead."
322
+ else
323
+ warn "The #transaction method has been deprecated."
536
324
  end
537
325
 
538
- # Allows specific variables to be excluded from transaction support.
539
- # Must be done after extending the object but before starting the
540
- # first transaction on the object.
541
- #
542
- # vv.transaction_exclusions << "@io"
543
- def transaction_exclusions
544
- @transaction_exclusions ||= []
326
+ case method
327
+ when :transaction_name
328
+ __send__ method
329
+ when nil
330
+ nil
331
+ else
332
+ __send__ method, name
545
333
  end
334
+ end
546
335
 
547
- class << self
548
- def __common_start(name, vars, &block)
549
- if vars.empty?
550
- raise TransactionError, Messages[:cannot_start_empty_block_transaction]
551
- end
336
+ # Allows specific variables to be excluded from transaction support. Must
337
+ # be done after extending the object but before starting the first
338
+ # transaction on the object.
339
+ #
340
+ # vv.transaction_exclusions << "@io"
341
+ def transaction_exclusions
342
+ @transaction_exclusions ||= []
343
+ end
552
344
 
553
- if block
554
- begin
555
- vlevel = {}
345
+ class << self
346
+ def __common_start(name, vars, &block)
347
+ raise Transaction::TransactionError, Transaction::Messages[:cannot_start_empty_block_transaction] if vars.empty?
556
348
 
557
- vars.each do |vv|
558
- vv.extend(Transaction::Simple)
559
- vv.start_transaction(name)
560
- vlevel[vv.__id__] = vv.instance_variable_get(:@__transaction_level__)
561
- vv.instance_variable_set(:@__transaction_block__, vlevel[vv.__id__])
562
- end
349
+ if block
350
+ begin
351
+ vlevel = {}
352
+
353
+ vars.each do |vv|
354
+ vv.extend(Transaction::Simple)
355
+ vv.start_transaction(name)
356
+ vlevel[vv.__id__] = vv.instance_variable_get(:@__transaction_level__)
357
+ vv.instance_variable_set(:@__transaction_block__, vlevel[vv.__id__])
358
+ end
563
359
 
564
- yield(*vars)
565
- rescue TransactionAborted
566
- vars.each do |vv|
567
- if name.nil? and vv.transaction_open?
568
- loop do
569
- tlevel = vv.instance_variable_get(:@__transaction_level__) || -1
570
- vv.instance_variable_set(:@__transaction_block__, -1)
571
- break if tlevel < vlevel[vv.__id__]
572
- vv.abort_transaction if vv.transaction_open?
573
- end
574
- elsif vv.transaction_open?(name)
360
+ yield(*vars)
361
+ rescue Transaction::TransactionAborted
362
+ vars.each do |vv|
363
+ if name.nil? and vv.transaction_open?
364
+ loop do
365
+ tlevel = vv.instance_variable_get(:@__transaction_level__) || -1
575
366
  vv.instance_variable_set(:@__transaction_block__, -1)
576
- vv.abort_transaction(name)
367
+ break if tlevel < vlevel[vv.__id__]
368
+ vv.abort_transaction if vv.transaction_open?
577
369
  end
370
+ elsif vv.transaction_open?(name)
371
+ vv.instance_variable_set(:@__transaction_block__, -1)
372
+ vv.abort_transaction(name)
578
373
  end
579
- rescue TransactionCommitted
580
- nil
581
- ensure
582
- vars.each do |vv|
583
- if name.nil? and vv.transaction_open?
584
- loop do
585
- tlevel = vv.instance_variable_get(:@__transaction_level__) || -1
586
- break if tlevel < vlevel[vv.__id__]
587
- vv.instance_variable_set(:@__transaction_block__, -1)
588
- vv.commit_transaction if vv.transaction_open?
589
- end
590
- elsif vv.transaction_open?(name)
374
+ end
375
+ rescue Transaction::TransactionCommitted
376
+ nil
377
+ ensure
378
+ vars.each do |vv|
379
+ if name.nil? and vv.transaction_open?
380
+ loop do
381
+ tlevel = vv.instance_variable_get(:@__transaction_level__) || -1
382
+ break if tlevel < vlevel[vv.__id__]
591
383
  vv.instance_variable_set(:@__transaction_block__, -1)
592
- vv.commit_transaction(name)
384
+ vv.commit_transaction if vv.transaction_open?
593
385
  end
386
+ elsif vv.transaction_open?(name)
387
+ vv.instance_variable_set(:@__transaction_block__, -1)
388
+ vv.commit_transaction(name)
594
389
  end
595
390
  end
596
- else
597
- vars.each do |vv|
598
- vv.extend(Transaction::Simple)
599
- vv.start_transaction(name)
600
- end
391
+ end
392
+ else
393
+ vars.each do |vv|
394
+ vv.extend(Transaction::Simple)
395
+ vv.start_transaction(name)
601
396
  end
602
397
  end
603
- private :__common_start
398
+ end
399
+ private :__common_start
604
400
 
605
- def start_named(name, *vars, &block)
606
- __common_start(name, vars, &block)
607
- end
401
+ # Start a named transaction in a block. The transaction will auto-commit
402
+ # when the block finishes.
403
+ def start_named(name, *vars, &block)
404
+ __common_start(name, vars, &block)
405
+ end
608
406
 
609
- def start(*vars, &block)
610
- __common_start(nil, vars, &block)
611
- end
407
+ # Start a named transaction in a block. The transaction will auto-commit
408
+ # when the block finishes.
409
+ def start(*vars, &block)
410
+ __common_start(nil, vars, &block)
612
411
  end
412
+ end
613
413
 
614
- def __abort_transaction(name = nil) #:nodoc:
615
- @__transaction_checkpoint__ = __rewind_this_transaction
414
+ def __abort_transaction(name = nil) #:nodoc:
415
+ @__transaction_checkpoint__ = __rewind_this_transaction
616
416
 
417
+ if Transaction::Simple.debugging?
617
418
  if name.nil?
618
- ss = "" if Transaction::Simple.debugging?
419
+ ss = ""
619
420
  else
620
- ss = "(#{name.inspect})" if Transaction::Simple.debugging?
421
+ ss = "(#{name.inspect})"
621
422
  end
622
423
 
623
- if Transaction::Simple.debugging?
624
- Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} " <<
625
- "Abort Transaction#{ss}\n"
626
- end
627
- @__transaction_level__ -= 1
628
- @__transaction_names__.pop
629
- if @__transaction_level__ < 1
630
- @__transaction_level__ = 0
631
- @__transaction_names__ = []
632
- end
424
+ Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} " << "Abort Transaction#{ss}\n"
633
425
  end
634
426
 
635
- TRANSACTION_CHECKPOINT = "@__transaction_checkpoint__" #:nodoc:
636
- SKIP_TRANSACTION_VARS = [TRANSACTION_CHECKPOINT, "@__transaction_level__"] #:nodoc:
427
+ @__transaction_level__ -= 1
428
+ @__transaction_names__.pop
429
+ if @__transaction_level__ < 1
430
+ @__transaction_level__ = 0
431
+ @__transaction_names__ = []
432
+ @__transaction_checkpoint__ = nil
433
+ end
434
+ end
637
435
 
638
- def __rewind_this_transaction #:nodoc:
639
- rr = Marshal.restore(@__transaction_checkpoint__)
436
+ SKIP_TRANSACTION_VARS = %w(@__transaction_checkpoint__ @__transaction_level__)
640
437
 
641
- begin
642
- self.replace(rr) if respond_to?(:replace)
643
- rescue
644
- nil
645
- end
438
+ def __rewind_this_transaction #:nodoc:
439
+ defined? @__transaction_checkpoint__ or @__transaction_checkpoint__ = nil
440
+ raise Transaction::TransactionError, Transaction::Messages[:cannot_rewind_no_transaction] if @__transaction_checkpoint__.nil?
441
+ rr = Marshal.restore(@__transaction_checkpoint__)
646
442
 
647
- rr.instance_variables.each do |vv|
648
- next if SKIP_TRANSACTION_VARS.include?(vv)
649
- next if self.transaction_exclusions.include?(vv)
650
- if respond_to?(:instance_variable_get)
651
- instance_variable_set(vv, rr.instance_variable_get(vv))
652
- else
653
- instance_eval(%q|#{vv} = rr.instance_eval("#{vv}")|)
654
- end
655
- end
443
+ replace(rr) if respond_to?(:replace)
656
444
 
657
- new_ivar = instance_variables - rr.instance_variables - SKIP_TRANSACTION_VARS
658
- new_ivar.each do |vv|
659
- if respond_to?(:instance_variable_set)
660
- instance_variable_set(vv, nil)
661
- else
662
- instance_eval(%q|#{vv} = nil|)
663
- end
664
- end
445
+ iv = rr.instance_variables - SKIP_TRANSACTION_VARS - self.transaction_exclusions
446
+ iv.each do |vv|
447
+ next if self.transaction_exclusions.include?(vv)
665
448
 
666
- if respond_to?(:instance_variable_get)
667
- rr.instance_variable_get(TRANSACTION_CHECKPOINT)
668
- else
669
- rr.instance_eval(TRANSACTION_CHECKPOINT)
670
- end
449
+ instance_variable_set(vv, rr.instance_variable_get(vv))
671
450
  end
672
451
 
673
- def __commit_transaction #:nodoc:
674
- if respond_to?(:instance_variable_get)
675
- @__transaction_checkpoint__ = Marshal.restore(@__transaction_checkpoint__).instance_variable_get(TRANSACTION_CHECKPOINT)
676
- else
677
- @__transaction_checkpoint__ = Marshal.restore(@__transaction_checkpoint__).instance_eval(TRANSACTION_CHECKPOINT)
678
- end
452
+ rest = instance_variables - rr.instance_variables - SKIP_TRANSACTION_VARS - self.transaction_exclusions
453
+ rest.each do |vv|
454
+ remove_instance_variable(vv)
455
+ end
679
456
 
680
- @__transaction_level__ -= 1
681
- @__transaction_names__.pop
457
+ _post_transaction_rewind if respond_to?(:_post_transaction_rewind)
682
458
 
683
- if @__transaction_level__ < 1
684
- @__transaction_level__ = 0
685
- @__transaction_names__ = []
686
- end
687
- end
459
+ w, $-w = $-w, false # 20070203 OH is this very UGLY
460
+ res = rr.instance_variable_get(:@__transaction_checkpoint__)
461
+ $-w = w # 20070203 OH is this very UGLY
462
+ res
463
+ end
688
464
 
689
- private :__abort_transaction
690
- private :__rewind_this_transaction
691
- private :__commit_transaction
465
+ def __commit_transaction #:nodoc:
466
+ defined? @__transaction_checkpoint__ or @__transaction_checkpoint__ = nil
467
+ raise Transaction::TransactionError, Transaction::Messages[:cannot_commit_no_transaction] if @__transaction_checkpoint__.nil?
468
+ old = Marshal.restore(@__transaction_checkpoint__)
469
+ w, $-w = $-w, false # 20070203 OH is this very UGLY
470
+ @__transaction_checkpoint__ = old.instance_variable_get(:@__transaction_checkpoint__)
471
+ $-w = w # 20070203 OH is this very UGLY
472
+
473
+ @__transaction_level__ -= 1
474
+ @__transaction_names__.pop
475
+
476
+ if @__transaction_level__ < 1
477
+ @__transaction_level__ = 0
478
+ @__transaction_names__ = []
479
+ @__transaction_checkpoint__ = nil
480
+ end
692
481
  end
482
+
483
+ private :__abort_transaction
484
+ private :__rewind_this_transaction
485
+ private :__commit_transaction
693
486
  end