activerecord 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- data/CHANGELOG +4928 -3
 - data/README +45 -46
 - data/RUNNING_UNIT_TESTS +8 -11
 - data/Rakefile +247 -0
 - data/install.rb +8 -38
 - data/lib/active_record/aggregations.rb +64 -49
 - data/lib/active_record/associations/association_collection.rb +217 -47
 - data/lib/active_record/associations/association_proxy.rb +159 -0
 - data/lib/active_record/associations/belongs_to_association.rb +56 -0
 - data/lib/active_record/associations/belongs_to_polymorphic_association.rb +50 -0
 - data/lib/active_record/associations/has_and_belongs_to_many_association.rb +155 -37
 - data/lib/active_record/associations/has_many_association.rb +145 -75
 - data/lib/active_record/associations/has_many_through_association.rb +283 -0
 - data/lib/active_record/associations/has_one_association.rb +96 -0
 - data/lib/active_record/associations.rb +1537 -304
 - data/lib/active_record/attribute_methods.rb +328 -0
 - data/lib/active_record/base.rb +2001 -588
 - data/lib/active_record/calculations.rb +269 -0
 - data/lib/active_record/callbacks.rb +169 -165
 - data/lib/active_record/connection_adapters/abstract/connection_specification.rb +308 -0
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +171 -0
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +87 -0
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +69 -0
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +472 -0
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +306 -0
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +125 -279
 - data/lib/active_record/connection_adapters/mysql_adapter.rb +442 -77
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +805 -135
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -0
 - data/lib/active_record/connection_adapters/sqlite_adapter.rb +353 -69
 - data/lib/active_record/fixtures.rb +946 -100
 - data/lib/active_record/locking/optimistic.rb +144 -0
 - data/lib/active_record/locking/pessimistic.rb +77 -0
 - data/lib/active_record/migration.rb +417 -0
 - data/lib/active_record/observer.rb +142 -32
 - data/lib/active_record/query_cache.rb +23 -0
 - data/lib/active_record/reflection.rb +163 -70
 - data/lib/active_record/schema.rb +58 -0
 - data/lib/active_record/schema_dumper.rb +171 -0
 - data/lib/active_record/serialization.rb +98 -0
 - data/lib/active_record/serializers/json_serializer.rb +71 -0
 - data/lib/active_record/serializers/xml_serializer.rb +315 -0
 - data/lib/active_record/timestamp.rb +41 -0
 - data/lib/active_record/transactions.rb +87 -57
 - data/lib/active_record/validations.rb +909 -122
 - data/lib/active_record/vendor/db2.rb +362 -0
 - data/lib/active_record/vendor/mysql.rb +126 -29
 - data/lib/active_record/version.rb +9 -0
 - data/lib/active_record.rb +35 -7
 - data/lib/activerecord.rb +1 -0
 - data/test/aaa_create_tables_test.rb +72 -0
 - data/test/abstract_unit.rb +73 -5
 - data/test/active_schema_test_mysql.rb +43 -0
 - data/test/adapter_test.rb +105 -0
 - data/test/adapter_test_sqlserver.rb +95 -0
 - data/test/aggregations_test.rb +110 -16
 - data/test/all.sh +2 -2
 - data/test/ar_schema_test.rb +33 -0
 - data/test/association_inheritance_reload.rb +14 -0
 - data/test/associations/ar_joins_test.rb +0 -0
 - data/test/associations/callbacks_test.rb +147 -0
 - data/test/associations/cascaded_eager_loading_test.rb +110 -0
 - data/test/associations/eager_singularization_test.rb +145 -0
 - data/test/associations/eager_test.rb +442 -0
 - data/test/associations/extension_test.rb +47 -0
 - data/test/associations/inner_join_association_test.rb +88 -0
 - data/test/associations/join_model_test.rb +553 -0
 - data/test/associations_test.rb +1930 -267
 - data/test/attribute_methods_test.rb +146 -0
 - data/test/base_test.rb +1316 -84
 - data/test/binary_test.rb +32 -0
 - data/test/calculations_test.rb +251 -0
 - data/test/callbacks_test.rb +400 -0
 - data/test/class_inheritable_attributes_test.rb +3 -4
 - data/test/column_alias_test.rb +17 -0
 - data/test/connection_test_firebird.rb +8 -0
 - data/test/connection_test_mysql.rb +30 -0
 - data/test/connections/native_db2/connection.rb +25 -0
 - data/test/connections/native_firebird/connection.rb +26 -0
 - data/test/connections/native_frontbase/connection.rb +27 -0
 - data/test/connections/native_mysql/connection.rb +21 -18
 - data/test/connections/native_openbase/connection.rb +21 -0
 - data/test/connections/native_oracle/connection.rb +27 -0
 - data/test/connections/native_postgresql/connection.rb +17 -18
 - data/test/connections/native_sqlite/connection.rb +17 -16
 - data/test/connections/native_sqlite3/connection.rb +25 -0
 - data/test/connections/native_sqlite3/in_memory_connection.rb +18 -0
 - data/test/connections/native_sybase/connection.rb +23 -0
 - data/test/copy_table_test_sqlite.rb +69 -0
 - data/test/datatype_test_postgresql.rb +203 -0
 - data/test/date_time_test.rb +37 -0
 - data/test/default_test_firebird.rb +16 -0
 - data/test/defaults_test.rb +67 -0
 - data/test/deprecated_finder_test.rb +30 -0
 - data/test/finder_test.rb +607 -32
 - data/test/fixtures/accounts.yml +28 -0
 - data/test/fixtures/all/developers.yml +0 -0
 - data/test/fixtures/all/people.csv +0 -0
 - data/test/fixtures/all/tasks.yml +0 -0
 - data/test/fixtures/author.rb +107 -0
 - data/test/fixtures/author_favorites.yml +4 -0
 - data/test/fixtures/authors.yml +7 -0
 - data/test/fixtures/bad_fixtures/attr_with_numeric_first_char +1 -0
 - data/test/fixtures/bad_fixtures/attr_with_spaces +1 -0
 - data/test/fixtures/bad_fixtures/blank_line +3 -0
 - data/test/fixtures/bad_fixtures/duplicate_attributes +3 -0
 - data/test/fixtures/bad_fixtures/missing_value +1 -0
 - data/test/fixtures/binaries.yml +132 -0
 - data/test/fixtures/binary.rb +2 -0
 - data/test/fixtures/book.rb +4 -0
 - data/test/fixtures/books.yml +7 -0
 - data/test/fixtures/categories/special_categories.yml +9 -0
 - data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
 - data/test/fixtures/categories.yml +14 -0
 - data/test/fixtures/categories_ordered.yml +7 -0
 - data/test/fixtures/categories_posts.yml +23 -0
 - data/test/fixtures/categorization.rb +5 -0
 - data/test/fixtures/categorizations.yml +17 -0
 - data/test/fixtures/category.rb +26 -0
 - data/test/fixtures/citation.rb +6 -0
 - data/test/fixtures/comment.rb +23 -0
 - data/test/fixtures/comments.yml +59 -0
 - data/test/fixtures/companies.yml +55 -0
 - data/test/fixtures/company.rb +81 -4
 - data/test/fixtures/company_in_module.rb +32 -6
 - data/test/fixtures/computer.rb +4 -0
 - data/test/fixtures/computers.yml +4 -0
 - data/test/fixtures/contact.rb +16 -0
 - data/test/fixtures/courses.yml +7 -0
 - data/test/fixtures/customer.rb +28 -3
 - data/test/fixtures/customers.yml +17 -0
 - data/test/fixtures/db_definitions/db2.drop.sql +33 -0
 - data/test/fixtures/db_definitions/db2.sql +235 -0
 - data/test/fixtures/db_definitions/db22.drop.sql +2 -0
 - data/test/fixtures/db_definitions/db22.sql +5 -0
 - data/test/fixtures/db_definitions/firebird.drop.sql +65 -0
 - data/test/fixtures/db_definitions/firebird.sql +310 -0
 - data/test/fixtures/db_definitions/firebird2.drop.sql +2 -0
 - data/test/fixtures/db_definitions/firebird2.sql +6 -0
 - data/test/fixtures/db_definitions/frontbase.drop.sql +33 -0
 - data/test/fixtures/db_definitions/frontbase.sql +273 -0
 - data/test/fixtures/db_definitions/frontbase2.drop.sql +1 -0
 - data/test/fixtures/db_definitions/frontbase2.sql +4 -0
 - data/test/fixtures/db_definitions/openbase.drop.sql +2 -0
 - data/test/fixtures/db_definitions/openbase.sql +318 -0
 - data/test/fixtures/db_definitions/openbase2.drop.sql +2 -0
 - data/test/fixtures/db_definitions/openbase2.sql +7 -0
 - data/test/fixtures/db_definitions/oracle.drop.sql +67 -0
 - data/test/fixtures/db_definitions/oracle.sql +330 -0
 - data/test/fixtures/db_definitions/oracle2.drop.sql +2 -0
 - data/test/fixtures/db_definitions/oracle2.sql +6 -0
 - data/test/fixtures/db_definitions/postgresql.drop.sql +44 -0
 - data/test/fixtures/db_definitions/postgresql.sql +217 -38
 - data/test/fixtures/db_definitions/postgresql2.drop.sql +2 -0
 - data/test/fixtures/db_definitions/postgresql2.sql +2 -2
 - data/test/fixtures/db_definitions/schema.rb +354 -0
 - data/test/fixtures/db_definitions/schema2.rb +11 -0
 - data/test/fixtures/db_definitions/sqlite.drop.sql +33 -0
 - data/test/fixtures/db_definitions/sqlite.sql +139 -5
 - data/test/fixtures/db_definitions/sqlite2.drop.sql +2 -0
 - data/test/fixtures/db_definitions/sqlite2.sql +1 -0
 - data/test/fixtures/db_definitions/sybase.drop.sql +35 -0
 - data/test/fixtures/db_definitions/sybase.sql +222 -0
 - data/test/fixtures/db_definitions/sybase2.drop.sql +4 -0
 - data/test/fixtures/db_definitions/sybase2.sql +5 -0
 - data/test/fixtures/developer.rb +70 -6
 - data/test/fixtures/developers.yml +21 -0
 - data/test/fixtures/developers_projects/david_action_controller +2 -1
 - data/test/fixtures/developers_projects/david_active_record +2 -1
 - data/test/fixtures/developers_projects.yml +17 -0
 - data/test/fixtures/edge.rb +5 -0
 - data/test/fixtures/edges.yml +6 -0
 - data/test/fixtures/entrants.yml +14 -0
 - data/test/fixtures/example.log +1 -0
 - data/test/fixtures/fk_test_has_fk.yml +3 -0
 - data/test/fixtures/fk_test_has_pk.yml +2 -0
 - data/test/fixtures/flowers.jpg +0 -0
 - data/test/fixtures/funny_jokes.yml +10 -0
 - data/test/fixtures/item.rb +7 -0
 - data/test/fixtures/items.yml +4 -0
 - data/test/fixtures/joke.rb +3 -0
 - data/test/fixtures/keyboard.rb +3 -0
 - data/test/fixtures/legacy_thing.rb +3 -0
 - data/test/fixtures/legacy_things.yml +3 -0
 - data/test/fixtures/matey.rb +4 -0
 - data/test/fixtures/mateys.yml +4 -0
 - data/test/fixtures/migrations/1_people_have_last_names.rb +9 -0
 - data/test/fixtures/migrations/2_we_need_reminders.rb +12 -0
 - data/test/fixtures/migrations/3_innocent_jointable.rb +12 -0
 - data/test/fixtures/migrations_with_decimal/1_give_me_big_numbers.rb +15 -0
 - data/test/fixtures/migrations_with_duplicate/1_people_have_last_names.rb +9 -0
 - data/test/fixtures/migrations_with_duplicate/2_we_need_reminders.rb +12 -0
 - data/test/fixtures/migrations_with_duplicate/3_foo.rb +7 -0
 - data/test/fixtures/migrations_with_duplicate/3_innocent_jointable.rb +12 -0
 - data/test/fixtures/migrations_with_missing_versions/1000_people_have_middle_names.rb +9 -0
 - data/test/fixtures/migrations_with_missing_versions/1_people_have_last_names.rb +9 -0
 - data/test/fixtures/migrations_with_missing_versions/3_we_need_reminders.rb +12 -0
 - data/test/fixtures/migrations_with_missing_versions/4_innocent_jointable.rb +12 -0
 - data/test/fixtures/minimalistic.rb +2 -0
 - data/test/fixtures/minimalistics.yml +2 -0
 - data/test/fixtures/mixed_case_monkey.rb +3 -0
 - data/test/fixtures/mixed_case_monkeys.yml +6 -0
 - data/test/fixtures/mixins.yml +29 -0
 - data/test/fixtures/movies.yml +7 -0
 - data/test/fixtures/naked/csv/accounts.csv +1 -0
 - data/test/fixtures/naked/yml/accounts.yml +1 -0
 - data/test/fixtures/naked/yml/companies.yml +1 -0
 - data/test/fixtures/naked/yml/courses.yml +1 -0
 - data/test/fixtures/order.rb +4 -0
 - data/test/fixtures/parrot.rb +13 -0
 - data/test/fixtures/parrots.yml +27 -0
 - data/test/fixtures/parrots_pirates.yml +7 -0
 - data/test/fixtures/people.yml +3 -0
 - data/test/fixtures/person.rb +4 -0
 - data/test/fixtures/pirate.rb +5 -0
 - data/test/fixtures/pirates.yml +9 -0
 - data/test/fixtures/post.rb +59 -0
 - data/test/fixtures/posts.yml +48 -0
 - data/test/fixtures/project.rb +27 -2
 - data/test/fixtures/projects.yml +7 -0
 - data/test/fixtures/reader.rb +4 -0
 - data/test/fixtures/readers.yml +4 -0
 - data/test/fixtures/reply.rb +18 -2
 - data/test/fixtures/reserved_words/distinct.yml +5 -0
 - data/test/fixtures/reserved_words/distincts_selects.yml +11 -0
 - data/test/fixtures/reserved_words/group.yml +14 -0
 - data/test/fixtures/reserved_words/select.yml +8 -0
 - data/test/fixtures/reserved_words/values.yml +7 -0
 - data/test/fixtures/ship.rb +3 -0
 - data/test/fixtures/ships.yml +5 -0
 - data/test/fixtures/subject.rb +4 -0
 - data/test/fixtures/subscriber.rb +4 -3
 - data/test/fixtures/tag.rb +7 -0
 - data/test/fixtures/tagging.rb +10 -0
 - data/test/fixtures/taggings.yml +25 -0
 - data/test/fixtures/tags.yml +7 -0
 - data/test/fixtures/task.rb +3 -0
 - data/test/fixtures/tasks.yml +7 -0
 - data/test/fixtures/topic.rb +20 -3
 - data/test/fixtures/topics.yml +22 -0
 - data/test/fixtures/treasure.rb +4 -0
 - data/test/fixtures/treasures.yml +10 -0
 - data/test/fixtures/vertex.rb +9 -0
 - data/test/fixtures/vertices.yml +4 -0
 - data/test/fixtures_test.rb +574 -8
 - data/test/inheritance_test.rb +113 -27
 - data/test/json_serialization_test.rb +180 -0
 - data/test/lifecycle_test.rb +56 -29
 - data/test/locking_test.rb +273 -0
 - data/test/method_scoping_test.rb +416 -0
 - data/test/migration_test.rb +933 -0
 - data/test/migration_test_firebird.rb +124 -0
 - data/test/mixin_test.rb +95 -0
 - data/test/modules_test.rb +23 -10
 - data/test/multiple_db_test.rb +17 -3
 - data/test/pk_test.rb +59 -15
 - data/test/query_cache_test.rb +104 -0
 - data/test/readonly_test.rb +107 -0
 - data/test/reflection_test.rb +124 -27
 - data/test/reserved_word_test_mysql.rb +177 -0
 - data/test/schema_authorization_test_postgresql.rb +75 -0
 - data/test/schema_dumper_test.rb +131 -0
 - data/test/schema_test_postgresql.rb +64 -0
 - data/test/serialization_test.rb +47 -0
 - data/test/synonym_test_oracle.rb +17 -0
 - data/test/table_name_test_sqlserver.rb +23 -0
 - data/test/threaded_connections_test.rb +48 -0
 - data/test/transactions_test.rb +227 -29
 - data/test/unconnected_test.rb +14 -6
 - data/test/validations_test.rb +1293 -32
 - data/test/xml_serialization_test.rb +202 -0
 - metadata +347 -143
 - data/dev-utils/eval_debugger.rb +0 -9
 - data/examples/associations.rb +0 -87
 - data/examples/shared_setup.rb +0 -15
 - data/examples/validation.rb +0 -88
 - data/lib/active_record/deprecated_associations.rb +0 -70
 - data/lib/active_record/support/class_attribute_accessors.rb +0 -43
 - data/lib/active_record/support/class_inheritable_attributes.rb +0 -37
 - data/lib/active_record/support/clean_logger.rb +0 -10
 - data/lib/active_record/support/inflector.rb +0 -70
 - data/lib/active_record/vendor/simple.rb +0 -702
 - data/lib/active_record/wrappers/yaml_wrapper.rb +0 -15
 - data/lib/active_record/wrappings.rb +0 -59
 - data/rakefile +0 -122
 - data/test/deprecated_associations_test.rb +0 -336
 - data/test/fixtures/accounts/signals37 +0 -3
 - data/test/fixtures/accounts/unknown +0 -2
 - data/test/fixtures/companies/first_client +0 -6
 - data/test/fixtures/companies/first_firm +0 -4
 - data/test/fixtures/companies/second_client +0 -6
 - data/test/fixtures/courses/java +0 -2
 - data/test/fixtures/courses/ruby +0 -2
 - data/test/fixtures/customers/david +0 -6
 - data/test/fixtures/db_definitions/mysql.sql +0 -96
 - data/test/fixtures/db_definitions/mysql2.sql +0 -4
 - data/test/fixtures/developers/david +0 -2
 - data/test/fixtures/developers/jamis +0 -2
 - data/test/fixtures/entrants/first +0 -3
 - data/test/fixtures/entrants/second +0 -3
 - data/test/fixtures/entrants/third +0 -3
 - data/test/fixtures/fixture_database.sqlite +0 -0
 - data/test/fixtures/fixture_database_2.sqlite +0 -0
 - data/test/fixtures/movies/first +0 -2
 - data/test/fixtures/movies/second +0 -2
 - data/test/fixtures/projects/action_controller +0 -2
 - data/test/fixtures/projects/active_record +0 -2
 - data/test/fixtures/topics/first +0 -9
 - data/test/fixtures/topics/second +0 -8
 - data/test/inflector_test.rb +0 -104
 - data/test/thread_safety_test.rb +0 -33
 
| 
         @@ -1,702 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # :title: Transaction::Simple
         
     | 
| 
       2 
     | 
    
         
            -
            #
         
     | 
| 
       3 
     | 
    
         
            -
            # == Licence
         
     | 
| 
       4 
     | 
    
         
            -
            #
         
     | 
| 
       5 
     | 
    
         
            -
            # Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
       6 
     | 
    
         
            -
            # of this software and associated documentation files (the "Software"), to
         
     | 
| 
       7 
     | 
    
         
            -
            # deal in the Software without restriction, including without limitation the
         
     | 
| 
       8 
     | 
    
         
            -
            # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
         
     | 
| 
       9 
     | 
    
         
            -
            # sell copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
       10 
     | 
    
         
            -
            # furnished to do so, subject to the following conditions:
         
     | 
| 
       11 
     | 
    
         
            -
            #
         
     | 
| 
       12 
     | 
    
         
            -
            # The above copyright notice and this permission notice shall be included in
         
     | 
| 
       13 
     | 
    
         
            -
            # all copies or substantial portions of the Software.
         
     | 
| 
       14 
     | 
    
         
            -
            #
         
     | 
| 
       15 
     | 
    
         
            -
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
       16 
     | 
    
         
            -
            # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
       17 
     | 
    
         
            -
            # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
       18 
     | 
    
         
            -
            # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
       19 
     | 
    
         
            -
            # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
         
     | 
| 
       20 
     | 
    
         
            -
            # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
         
     | 
| 
       21 
     | 
    
         
            -
            # IN THE SOFTWARE.
         
     | 
| 
       22 
     | 
    
         
            -
            #--
         
     | 
| 
       23 
     | 
    
         
            -
            # Transaction::Simple
         
     | 
| 
       24 
     | 
    
         
            -
            #   Simple object transaction support for Ruby
         
     | 
| 
       25 
     | 
    
         
            -
            #   Version 1.11
         
     | 
| 
       26 
     | 
    
         
            -
            #
         
     | 
| 
       27 
     | 
    
         
            -
            # Copyright (c) 2003 Austin Ziegler
         
     | 
| 
       28 
     | 
    
         
            -
            #
         
     | 
| 
       29 
     | 
    
         
            -
            # $Id: simple.rb,v 1.2 2004/08/20 13:56:37 webster132 Exp $
         
     | 
| 
       30 
     | 
    
         
            -
            #
         
     | 
| 
       31 
     | 
    
         
            -
            # ==========================================================================
         
     | 
| 
       32 
     | 
    
         
            -
            # Revision History ::
         
     | 
| 
       33 
     | 
    
         
            -
            # YYYY.MM.DD  Change ID   Developer
         
     | 
| 
       34 
     | 
    
         
            -
            #             Description
         
     | 
| 
       35 
     | 
    
         
            -
            # --------------------------------------------------------------------------
         
     | 
| 
       36 
     | 
    
         
            -
            # 2003.07.29              Austin Ziegler
         
     | 
| 
       37 
     | 
    
         
            -
            #             Added debugging capabilities and VERSION string.
         
     | 
| 
       38 
     | 
    
         
            -
            # 2003.08.21              Austin Ziegler
         
     | 
| 
       39 
     | 
    
         
            -
            #             Added named transactions.
         
     | 
| 
       40 
     | 
    
         
            -
            #
         
     | 
| 
       41 
     | 
    
         
            -
            # ==========================================================================
         
     | 
| 
       42 
     | 
    
         
            -
            #++
         
     | 
| 
       43 
     | 
    
         
            -
            require 'thread'
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
              # The "Transaction" namespace can be used for additional transactional
         
     | 
| 
       46 
     | 
    
         
            -
              # support objects and modules.
         
     | 
| 
       47 
     | 
    
         
            -
            module Transaction
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
                # A standard exception for transactional errors.
         
     | 
| 
       50 
     | 
    
         
            -
              class TransactionError < StandardError; end
         
     | 
| 
       51 
     | 
    
         
            -
                # A standard exception for transactional errors involving the acquisition
         
     | 
| 
       52 
     | 
    
         
            -
                # of locks for Transaction::Simple::ThreadSafe.
         
     | 
| 
       53 
     | 
    
         
            -
              class TransactionThreadError < StandardError; end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                # = Transaction::Simple for Ruby
         
     | 
| 
       56 
     | 
    
         
            -
                # Simple object transaction support for Ruby
         
     | 
| 
       57 
     | 
    
         
            -
                #
         
     | 
| 
       58 
     | 
    
         
            -
                # == Introduction
         
     | 
| 
       59 
     | 
    
         
            -
                #
         
     | 
| 
       60 
     | 
    
         
            -
                # Transaction::Simple provides a generic way to add active transactional
         
     | 
| 
       61 
     | 
    
         
            -
                # support to objects. The transaction methods added by this module will
         
     | 
| 
       62 
     | 
    
         
            -
                # work with most objects, excluding those that cannot be <i>Marshal</i>ed
         
     | 
| 
       63 
     | 
    
         
            -
                # (bindings, procedure objects, IO instances, or singleton objects).
         
     | 
| 
       64 
     | 
    
         
            -
                #
         
     | 
| 
       65 
     | 
    
         
            -
                # The transactions supported by Transaction::Simple are not backed
         
     | 
| 
       66 
     | 
    
         
            -
                # transactions; that is, they have nothing to do with any sort of data
         
     | 
| 
       67 
     | 
    
         
            -
                # store. They are "live" transactions occurring in memory and in the
         
     | 
| 
       68 
     | 
    
         
            -
                # object itself. This is to allow "test" changes to be made to an object
         
     | 
| 
       69 
     | 
    
         
            -
                # before making the changes permanent.
         
     | 
| 
       70 
     | 
    
         
            -
                #
         
     | 
| 
       71 
     | 
    
         
            -
                # Transaction::Simple can handle an "infinite" number of transactional
         
     | 
| 
       72 
     | 
    
         
            -
                # levels (limited only by memory). If I open two transactions, commit the
         
     | 
| 
       73 
     | 
    
         
            -
                # first, but abort the second, the object will revert to the original
         
     | 
| 
       74 
     | 
    
         
            -
                # version.
         
     | 
| 
       75 
     | 
    
         
            -
                # 
         
     | 
| 
       76 
     | 
    
         
            -
                # Transaction::Simple supports "named" transactions, so that multiple
         
     | 
| 
       77 
     | 
    
         
            -
                # levels of transactions can be committed, aborted, or rewound by
         
     | 
| 
       78 
     | 
    
         
            -
                # referring to the appropriate name of the transaction. Names may be any
         
     | 
| 
       79 
     | 
    
         
            -
                # object *except* +nil+.
         
     | 
| 
       80 
     | 
    
         
            -
                #
         
     | 
| 
       81 
     | 
    
         
            -
                # Copyright::   Copyright � 2003 by Austin Ziegler
         
     | 
| 
       82 
     | 
    
         
            -
                # Version::     1.1
         
     | 
| 
       83 
     | 
    
         
            -
                # Licence::     MIT-Style
         
     | 
| 
       84 
     | 
    
         
            -
                #
         
     | 
| 
       85 
     | 
    
         
            -
                # Thanks to David Black for help with the initial concept that led to this
         
     | 
| 
       86 
     | 
    
         
            -
                # library.
         
     | 
| 
       87 
     | 
    
         
            -
                #
         
     | 
| 
       88 
     | 
    
         
            -
                # == Usage
         
     | 
| 
       89 
     | 
    
         
            -
                #   include 'transaction/simple'
         
     | 
| 
       90 
     | 
    
         
            -
                #
         
     | 
| 
       91 
     | 
    
         
            -
                #   v = "Hello, you."               # => "Hello, you."
         
     | 
| 
       92 
     | 
    
         
            -
                #   v.extend(Transaction::Simple)   # => "Hello, you."
         
     | 
| 
       93 
     | 
    
         
            -
                #
         
     | 
| 
       94 
     | 
    
         
            -
                #   v.start_transaction             # => ... (a Marshal string)
         
     | 
| 
       95 
     | 
    
         
            -
                #   v.transaction_open?             # => true
         
     | 
| 
       96 
     | 
    
         
            -
                #   v.gsub!(/you/, "world")         # => "Hello, world."
         
     | 
| 
       97 
     | 
    
         
            -
                #
         
     | 
| 
       98 
     | 
    
         
            -
                #   v.rewind_transaction            # => "Hello, you."
         
     | 
| 
       99 
     | 
    
         
            -
                #   v.transaction_open?             # => true
         
     | 
| 
       100 
     | 
    
         
            -
                #
         
     | 
| 
       101 
     | 
    
         
            -
                #   v.gsub!(/you/, "HAL")           # => "Hello, HAL."
         
     | 
| 
       102 
     | 
    
         
            -
                #   v.abort_transaction             # => "Hello, you."
         
     | 
| 
       103 
     | 
    
         
            -
                #   v.transaction_open?             # => false
         
     | 
| 
       104 
     | 
    
         
            -
                #
         
     | 
| 
       105 
     | 
    
         
            -
                #   v.start_transaction             # => ... (a Marshal string)
         
     | 
| 
       106 
     | 
    
         
            -
                #   v.start_transaction             # => ... (a Marshal string)
         
     | 
| 
       107 
     | 
    
         
            -
                #
         
     | 
| 
       108 
     | 
    
         
            -
                #   v.transaction_open?             # => true
         
     | 
| 
       109 
     | 
    
         
            -
                #   v.gsub!(/you/, "HAL")           # => "Hello, HAL."
         
     | 
| 
       110 
     | 
    
         
            -
                #
         
     | 
| 
       111 
     | 
    
         
            -
                #   v.commit_transaction            # => "Hello, HAL."
         
     | 
| 
       112 
     | 
    
         
            -
                #   v.transaction_open?             # => true
         
     | 
| 
       113 
     | 
    
         
            -
                #   v.abort_transaction             # => "Hello, you."
         
     | 
| 
       114 
     | 
    
         
            -
                #   v.transaction_open?             # => false
         
     | 
| 
       115 
     | 
    
         
            -
                #
         
     | 
| 
       116 
     | 
    
         
            -
                # == Named Transaction Usage
         
     | 
| 
       117 
     | 
    
         
            -
                #   v = "Hello, you."               # => "Hello, you."
         
     | 
| 
       118 
     | 
    
         
            -
                #   v.extend(Transaction::Simple)   # => "Hello, you."
         
     | 
| 
       119 
     | 
    
         
            -
                #   
         
     | 
| 
       120 
     | 
    
         
            -
                #   v.start_transaction(:first)     # => ... (a Marshal string)
         
     | 
| 
       121 
     | 
    
         
            -
                #   v.transaction_open?             # => true
         
     | 
| 
       122 
     | 
    
         
            -
                #   v.transaction_open?(:first)     # => true
         
     | 
| 
       123 
     | 
    
         
            -
                #   v.transaction_open?(:second)    # => false
         
     | 
| 
       124 
     | 
    
         
            -
                #   v.gsub!(/you/, "world")         # => "Hello, world."
         
     | 
| 
       125 
     | 
    
         
            -
                #   
         
     | 
| 
       126 
     | 
    
         
            -
                #   v.start_transaction(:second)    # => ... (a Marshal string)
         
     | 
| 
       127 
     | 
    
         
            -
                #   v.gsub!(/world/, "HAL")         # => "Hello, HAL."
         
     | 
| 
       128 
     | 
    
         
            -
                #   v.rewind_transaction(:first)    # => "Hello, you."
         
     | 
| 
       129 
     | 
    
         
            -
                #   v.transaction_open?             # => true
         
     | 
| 
       130 
     | 
    
         
            -
                #   v.transaction_open?(:first)     # => true
         
     | 
| 
       131 
     | 
    
         
            -
                #   v.transaction_open?(:second)    # => false
         
     | 
| 
       132 
     | 
    
         
            -
                #   
         
     | 
| 
       133 
     | 
    
         
            -
                #   v.gsub!(/you/, "world")         # => "Hello, world."
         
     | 
| 
       134 
     | 
    
         
            -
                #   v.start_transaction(:second)    # => ... (a Marshal string)
         
     | 
| 
       135 
     | 
    
         
            -
                #   v.gsub!(/world/, "HAL")         # => "Hello, HAL."
         
     | 
| 
       136 
     | 
    
         
            -
                #   v.transaction_name              # => :second
         
     | 
| 
       137 
     | 
    
         
            -
                #   v.abort_transaction(:first)     # => "Hello, you."
         
     | 
| 
       138 
     | 
    
         
            -
                #   v.transaction_open?             # => false
         
     | 
| 
       139 
     | 
    
         
            -
                #   
         
     | 
| 
       140 
     | 
    
         
            -
                #   v.start_transaction(:first)     # => ... (a Marshal string)
         
     | 
| 
       141 
     | 
    
         
            -
                #   v.gsub!(/you/, "world")         # => "Hello, world."
         
     | 
| 
       142 
     | 
    
         
            -
                #   v.start_transaction(:second)    # => ... (a Marshal string)
         
     | 
| 
       143 
     | 
    
         
            -
                #   v.gsub!(/world/, "HAL")         # => "Hello, HAL."
         
     | 
| 
       144 
     | 
    
         
            -
                #   
         
     | 
| 
       145 
     | 
    
         
            -
                #   v.commit_transaction(:first)    # => "Hello, HAL."
         
     | 
| 
       146 
     | 
    
         
            -
                #   v.transaction_open?             # => false
         
     | 
| 
       147 
     | 
    
         
            -
                #
         
     | 
| 
       148 
     | 
    
         
            -
                # == Contraindications
         
     | 
| 
       149 
     | 
    
         
            -
                #
         
     | 
| 
       150 
     | 
    
         
            -
                # While Transaction::Simple is very useful, it has some severe limitations
         
     | 
| 
       151 
     | 
    
         
            -
                # that must be understood. Transaction::Simple:
         
     | 
| 
       152 
     | 
    
         
            -
                #
         
     | 
| 
       153 
     | 
    
         
            -
                # * uses Marshal. Thus, any object which cannot be <i>Marshal</i>ed cannot
         
     | 
| 
       154 
     | 
    
         
            -
                #   use Transaction::Simple.
         
     | 
| 
       155 
     | 
    
         
            -
                # * does not manage resources. Resources external to the object and its
         
     | 
| 
       156 
     | 
    
         
            -
                #   instance variables are not managed at all. However, all instance
         
     | 
| 
       157 
     | 
    
         
            -
                #   variables and objects "belonging" to those instance variables are
         
     | 
| 
       158 
     | 
    
         
            -
                #   managed. If there are object reference counts to be handled,
         
     | 
| 
       159 
     | 
    
         
            -
                #   Transaction::Simple will probably cause problems.
         
     | 
| 
       160 
     | 
    
         
            -
                # * is not inherently thread-safe. In the ACID ("atomic, consistent,
         
     | 
| 
       161 
     | 
    
         
            -
                #   isolated, durable") test, Transaction::Simple provides CD, but it is
         
     | 
| 
       162 
     | 
    
         
            -
                #   up to the user of Transaction::Simple to provide isolation and
         
     | 
| 
       163 
     | 
    
         
            -
                #   atomicity. Transactions should be considered "critical sections" in
         
     | 
| 
       164 
     | 
    
         
            -
                #   multi-threaded applications. If thread safety and atomicity is
         
     | 
| 
       165 
     | 
    
         
            -
                #   absolutely required, use Transaction::Simple::ThreadSafe, which uses a
         
     | 
| 
       166 
     | 
    
         
            -
                #   Mutex object to synchronize the accesses on the object during the
         
     | 
| 
       167 
     | 
    
         
            -
                #   transactional operations.
         
     | 
| 
       168 
     | 
    
         
            -
                # * does not necessarily maintain Object#__id__ values on rewind or abort.
         
     | 
| 
       169 
     | 
    
         
            -
                #   This may change for future versions that will be Ruby 1.8 or better
         
     | 
| 
       170 
     | 
    
         
            -
                #   *only*. Certain objects that support #replace will maintain
         
     | 
| 
       171 
     | 
    
         
            -
                #   Object#__id__.
         
     | 
| 
       172 
     | 
    
         
            -
                # * Can be a memory hog if you use many levels of transactions on many
         
     | 
| 
       173 
     | 
    
         
            -
                #   objects.
         
     | 
| 
       174 
     | 
    
         
            -
                #
         
     | 
| 
       175 
     | 
    
         
            -
              module Simple
         
     | 
| 
       176 
     | 
    
         
            -
                VERSION = '1.1.1.0';
         
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
                  # Sets the Transaction::Simple debug object. It must respond to #<<.
         
     | 
| 
       179 
     | 
    
         
            -
                  # Sets the transaction debug object. Debugging will be performed
         
     | 
| 
       180 
     | 
    
         
            -
                  # automatically if there's a debug object. The generic transaction error
         
     | 
| 
       181 
     | 
    
         
            -
                  # class.
         
     | 
| 
       182 
     | 
    
         
            -
                def self.debug_io=(io)
         
     | 
| 
       183 
     | 
    
         
            -
                  raise TransactionError, "Transaction Error: the transaction debug object must respond to #<<" unless io.respond_to?(:<<)
         
     | 
| 
       184 
     | 
    
         
            -
                  @tdi = io
         
     | 
| 
       185 
     | 
    
         
            -
                end
         
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
                  # Returns the Transaction::Simple debug object. It must respond to #<<.
         
     | 
| 
       188 
     | 
    
         
            -
                def self.debug_io
         
     | 
| 
       189 
     | 
    
         
            -
                  @tdi
         
     | 
| 
       190 
     | 
    
         
            -
                end
         
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
                  # If +name+ is +nil+ (default), then returns +true+ if there is
         
     | 
| 
       193 
     | 
    
         
            -
                  # currently a transaction open.
         
     | 
| 
       194 
     | 
    
         
            -
                  #
         
     | 
| 
       195 
     | 
    
         
            -
                  # If +name+ is specified, then returns +true+ if there is currently a
         
     | 
| 
       196 
     | 
    
         
            -
                  # transaction that responds to +name+ open.
         
     | 
| 
       197 
     | 
    
         
            -
                def transaction_open?(name = nil)
         
     | 
| 
       198 
     | 
    
         
            -
                  if name.nil?
         
     | 
| 
       199 
     | 
    
         
            -
                    Transaction::Simple.debug_io << "Transaction [#{(@__transaction_checkpoint__.nil?) ? 'closed' : 'open'}]\n" unless Transaction::Simple.debug_io.nil?
         
     | 
| 
       200 
     | 
    
         
            -
                    return (not @__transaction_checkpoint__.nil?)
         
     | 
| 
       201 
     | 
    
         
            -
                  else
         
     | 
| 
       202 
     | 
    
         
            -
                    Transaction::Simple.debug_io << "Transaction(#{name.inspect}) [#{(@__transaction_checkpoint__.nil?) ? 'closed' : 'open'}]\n" unless Transaction::Simple.debug_io.nil?
         
     | 
| 
       203 
     | 
    
         
            -
                    return ((not @__transaction_checkpoint__.nil?) and @__transaction_names__.include?(name))
         
     | 
| 
       204 
     | 
    
         
            -
                  end
         
     | 
| 
       205 
     | 
    
         
            -
                end
         
     | 
| 
       206 
     | 
    
         
            -
             
     | 
| 
       207 
     | 
    
         
            -
                  # Returns the current name of the transaction. Transactions not
         
     | 
| 
       208 
     | 
    
         
            -
                  # explicitly named are named +nil+.
         
     | 
| 
       209 
     | 
    
         
            -
                def transaction_name
         
     | 
| 
       210 
     | 
    
         
            -
                  raise TransactionError, "Transaction Error: No transaction open." if @__transaction_checkpoint__.nil?
         
     | 
| 
       211 
     | 
    
         
            -
                  Transaction::Simple.debug_io << "#{'|' * @__transaction_level__} Transaction Name: #{@__transaction_names__[-1].inspect}\n" unless Transaction::Simple.debug_io.nil?
         
     | 
| 
       212 
     | 
    
         
            -
                  @__transaction_names__[-1]
         
     | 
| 
       213 
     | 
    
         
            -
                end
         
     | 
| 
       214 
     | 
    
         
            -
             
     | 
| 
       215 
     | 
    
         
            -
                  # Starts a transaction. Stores the current object state. If a
         
     | 
| 
       216 
     | 
    
         
            -
                  # transaction name is specified, the transaction will be named.
         
     | 
| 
       217 
     | 
    
         
            -
                  # Transaction names must be unique. Transaction names of +nil+ will be
         
     | 
| 
       218 
     | 
    
         
            -
                  # treated as unnamed transactions.
         
     | 
| 
       219 
     | 
    
         
            -
                def start_transaction(name = nil)
         
     | 
| 
       220 
     | 
    
         
            -
                  @__transaction_level__ ||= 0
         
     | 
| 
       221 
     | 
    
         
            -
                  @__transaction_names__ ||= []
         
     | 
| 
       222 
     | 
    
         
            -
             
     | 
| 
       223 
     | 
    
         
            -
                  if name.nil?
         
     | 
| 
       224 
     | 
    
         
            -
                    @__transaction_names__ << nil
         
     | 
| 
       225 
     | 
    
         
            -
                    s = ""
         
     | 
| 
       226 
     | 
    
         
            -
                  else
         
     | 
| 
       227 
     | 
    
         
            -
                    raise TransactionError, "Transaction Error: Named transactions must be unique." if @__transaction_names__.include?(name)
         
     | 
| 
       228 
     | 
    
         
            -
                    @__transaction_names__ << name
         
     | 
| 
       229 
     | 
    
         
            -
                    s = "(#{name.inspect})"
         
     | 
| 
       230 
     | 
    
         
            -
                  end
         
     | 
| 
       231 
     | 
    
         
            -
             
     | 
| 
       232 
     | 
    
         
            -
                  @__transaction_level__ += 1
         
     | 
| 
       233 
     | 
    
         
            -
             
     | 
| 
       234 
     | 
    
         
            -
                  Transaction::Simple.debug_io << "#{'>' * @__transaction_level__} Start Transaction#{s}\n" unless Transaction::Simple.debug_io.nil?
         
     | 
| 
       235 
     | 
    
         
            -
             
     | 
| 
       236 
     | 
    
         
            -
                  @__transaction_checkpoint__ = Marshal.dump(self)
         
     | 
| 
       237 
     | 
    
         
            -
                end
         
     | 
| 
       238 
     | 
    
         
            -
             
     | 
| 
       239 
     | 
    
         
            -
                  # Rewinds the transaction. If +name+ is specified, then the intervening
         
     | 
| 
       240 
     | 
    
         
            -
                  # transactions will be aborted and the named transaction will be
         
     | 
| 
       241 
     | 
    
         
            -
                  # rewound. Otherwise, only the current transaction is rewound.
         
     | 
| 
       242 
     | 
    
         
            -
                def rewind_transaction(name = nil)
         
     | 
| 
       243 
     | 
    
         
            -
                  raise TransactionError, "Transaction Error: Cannot rewind. There is no current transaction." if @__transaction_checkpoint__.nil?
         
     | 
| 
       244 
     | 
    
         
            -
                  if name.nil?
         
     | 
| 
       245 
     | 
    
         
            -
                    __rewind_this_transaction
         
     | 
| 
       246 
     | 
    
         
            -
                    s = ""
         
     | 
| 
       247 
     | 
    
         
            -
                  else
         
     | 
| 
       248 
     | 
    
         
            -
                    raise TransactionError, "Transaction Error: Cannot rewind to transaction #{name.inspect} because it does not exist." unless @__transaction_names__.include?(name)
         
     | 
| 
       249 
     | 
    
         
            -
                    s = "(#{name})"
         
     | 
| 
       250 
     | 
    
         
            -
             
     | 
| 
       251 
     | 
    
         
            -
                    while @__transaction_names__[-1] != name
         
     | 
| 
       252 
     | 
    
         
            -
                      @__transaction_checkpoint__ = __rewind_this_transaction
         
     | 
| 
       253 
     | 
    
         
            -
                      Transaction::Simple.debug_io << "#{'|' * @__transaction_level__} Rewind Transaction#{s}\n" unless Transaction::Simple.debug_io.nil?
         
     | 
| 
       254 
     | 
    
         
            -
                      @__transaction_level__ -= 1
         
     | 
| 
       255 
     | 
    
         
            -
                      @__transaction_names__.pop
         
     | 
| 
       256 
     | 
    
         
            -
                    end
         
     | 
| 
       257 
     | 
    
         
            -
                    __rewind_this_transaction
         
     | 
| 
       258 
     | 
    
         
            -
                  end
         
     | 
| 
       259 
     | 
    
         
            -
                  Transaction::Simple.debug_io << "#{'|' * @__transaction_level__} Rewind Transaction#{s}\n" unless Transaction::Simple.debug_io.nil?
         
     | 
| 
       260 
     | 
    
         
            -
                  self
         
     | 
| 
       261 
     | 
    
         
            -
                end
         
     | 
| 
       262 
     | 
    
         
            -
             
     | 
| 
       263 
     | 
    
         
            -
                  # Aborts the transaction. Resets the object state to what it was before
         
     | 
| 
       264 
     | 
    
         
            -
                  # the transaction was started and closes the transaction. If +name+ is
         
     | 
| 
       265 
     | 
    
         
            -
                  # specified, then the intervening transactions and the named transaction
         
     | 
| 
       266 
     | 
    
         
            -
                  # will be aborted. Otherwise, only the current transaction is aborted.
         
     | 
| 
       267 
     | 
    
         
            -
                def abort_transaction(name = nil)
         
     | 
| 
       268 
     | 
    
         
            -
                  raise TransactionError, "Transaction Error: Cannot abort. There is no current transaction." if @__transaction_checkpoint__.nil?
         
     | 
| 
       269 
     | 
    
         
            -
                  if name.nil?
         
     | 
| 
       270 
     | 
    
         
            -
                    __abort_transaction(name)
         
     | 
| 
       271 
     | 
    
         
            -
                  else
         
     | 
| 
       272 
     | 
    
         
            -
                    raise TransactionError, "Transaction Error: Cannot abort nonexistant transaction #{name.inspect}." unless @__transaction_names__.include?(name)
         
     | 
| 
       273 
     | 
    
         
            -
             
     | 
| 
       274 
     | 
    
         
            -
                    __abort_transaction(name) while @__transaction_names__.include?(name)
         
     | 
| 
       275 
     | 
    
         
            -
                  end
         
     | 
| 
       276 
     | 
    
         
            -
                  self
         
     | 
| 
       277 
     | 
    
         
            -
                end
         
     | 
| 
       278 
     | 
    
         
            -
             
     | 
| 
       279 
     | 
    
         
            -
                  # If +name+ is +nil+ (default), the current transaction level is closed
         
     | 
| 
       280 
     | 
    
         
            -
                  # out and the changes are committed.
         
     | 
| 
       281 
     | 
    
         
            -
                  #
         
     | 
| 
       282 
     | 
    
         
            -
                  # If +name+ is specified and +name+ is in the list of named
         
     | 
| 
       283 
     | 
    
         
            -
                  # transactions, then all transactions are closed and committed until the
         
     | 
| 
       284 
     | 
    
         
            -
                  # named transaction is reached.
         
     | 
| 
       285 
     | 
    
         
            -
                def commit_transaction(name = nil)
         
     | 
| 
       286 
     | 
    
         
            -
                  raise TransactionError, "Transaction Error: Cannot commit. There is no current transaction." if @__transaction_checkpoint__.nil?
         
     | 
| 
       287 
     | 
    
         
            -
             
     | 
| 
       288 
     | 
    
         
            -
                  if name.nil?
         
     | 
| 
       289 
     | 
    
         
            -
                    s = ""
         
     | 
| 
       290 
     | 
    
         
            -
                    __commit_transaction
         
     | 
| 
       291 
     | 
    
         
            -
                    Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} Commit Transaction#{s}\n" unless Transaction::Simple.debug_io.nil?
         
     | 
| 
       292 
     | 
    
         
            -
                  else
         
     | 
| 
       293 
     | 
    
         
            -
                    raise TransactionError, "Transaction Error: Cannot commit nonexistant transaction #{name.inspect}." unless @__transaction_names__.include?(name)
         
     | 
| 
       294 
     | 
    
         
            -
                    s = "(#{name})"
         
     | 
| 
       295 
     | 
    
         
            -
             
     | 
| 
       296 
     | 
    
         
            -
                    while @__transaction_names__[-1] != name
         
     | 
| 
       297 
     | 
    
         
            -
                      Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} Commit Transaction#{s}\n" unless Transaction::Simple.debug_io.nil?
         
     | 
| 
       298 
     | 
    
         
            -
                      __commit_transaction
         
     | 
| 
       299 
     | 
    
         
            -
                    end
         
     | 
| 
       300 
     | 
    
         
            -
                    Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} Commit Transaction#{s}\n" unless Transaction::Simple.debug_io.nil?
         
     | 
| 
       301 
     | 
    
         
            -
                    __commit_transaction
         
     | 
| 
       302 
     | 
    
         
            -
                  end
         
     | 
| 
       303 
     | 
    
         
            -
                  self
         
     | 
| 
       304 
     | 
    
         
            -
                end
         
     | 
| 
       305 
     | 
    
         
            -
             
     | 
| 
       306 
     | 
    
         
            -
                  # Alternative method for calling the transaction methods. An optional
         
     | 
| 
       307 
     | 
    
         
            -
                  # name can be specified for named transaction support.
         
     | 
| 
       308 
     | 
    
         
            -
                  #
         
     | 
| 
       309 
     | 
    
         
            -
                  # #transaction(:start)::  #start_transaction
         
     | 
| 
       310 
     | 
    
         
            -
                  # #transaction(:rewind):: #rewind_transaction
         
     | 
| 
       311 
     | 
    
         
            -
                  # #transaction(:abort)::  #abort_transaction
         
     | 
| 
       312 
     | 
    
         
            -
                  # #transaction(:commit):: #commit_transaction
         
     | 
| 
       313 
     | 
    
         
            -
                  # #transaction(:name)::   #transaction_name
         
     | 
| 
       314 
     | 
    
         
            -
                  # #transaction::          #transaction_open?
         
     | 
| 
       315 
     | 
    
         
            -
                def transaction(action = nil, name = nil)
         
     | 
| 
       316 
     | 
    
         
            -
                  case action
         
     | 
| 
       317 
     | 
    
         
            -
                  when :start
         
     | 
| 
       318 
     | 
    
         
            -
                    start_transaction(name)
         
     | 
| 
       319 
     | 
    
         
            -
                  when :rewind
         
     | 
| 
       320 
     | 
    
         
            -
                    rewind_transaction(name)
         
     | 
| 
       321 
     | 
    
         
            -
                  when :abort
         
     | 
| 
       322 
     | 
    
         
            -
                    abort_transaction(name)
         
     | 
| 
       323 
     | 
    
         
            -
                  when :commit
         
     | 
| 
       324 
     | 
    
         
            -
                    commit_transaction(name)
         
     | 
| 
       325 
     | 
    
         
            -
                  when :name
         
     | 
| 
       326 
     | 
    
         
            -
                    transaction_name
         
     | 
| 
       327 
     | 
    
         
            -
                  when nil
         
     | 
| 
       328 
     | 
    
         
            -
                    transaction_open?(name)
         
     | 
| 
       329 
     | 
    
         
            -
                  end
         
     | 
| 
       330 
     | 
    
         
            -
                end
         
     | 
| 
       331 
     | 
    
         
            -
             
     | 
| 
       332 
     | 
    
         
            -
                def __abort_transaction(name = nil) #:nodoc:
         
     | 
| 
       333 
     | 
    
         
            -
                  @__transaction_checkpoint__ = __rewind_this_transaction
         
     | 
| 
       334 
     | 
    
         
            -
             
     | 
| 
       335 
     | 
    
         
            -
                  if name.nil?
         
     | 
| 
       336 
     | 
    
         
            -
                    s = ""
         
     | 
| 
       337 
     | 
    
         
            -
                  else
         
     | 
| 
       338 
     | 
    
         
            -
                    s = "(#{name.inspect})"
         
     | 
| 
       339 
     | 
    
         
            -
                  end
         
     | 
| 
       340 
     | 
    
         
            -
             
     | 
| 
       341 
     | 
    
         
            -
                  Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} Abort Transaction#{s}\n" unless Transaction::Simple.debug_io.nil?
         
     | 
| 
       342 
     | 
    
         
            -
                  @__transaction_level__ -= 1
         
     | 
| 
       343 
     | 
    
         
            -
                  @__transaction_names__.pop
         
     | 
| 
       344 
     | 
    
         
            -
                  if @__transaction_level__ < 1
         
     | 
| 
       345 
     | 
    
         
            -
                    @__transaction_level__ = 0
         
     | 
| 
       346 
     | 
    
         
            -
                    @__transaction_names__ = []
         
     | 
| 
       347 
     | 
    
         
            -
                  end
         
     | 
| 
       348 
     | 
    
         
            -
                end
         
     | 
| 
       349 
     | 
    
         
            -
             
     | 
| 
       350 
     | 
    
         
            -
                TRANSACTION_CHECKPOINT  = "@__transaction_checkpoint__" #:nodoc:
         
     | 
| 
       351 
     | 
    
         
            -
                SKIP_TRANSACTION_VARS   = [TRANSACTION_CHECKPOINT, "@__transaction_level__"] #:nodoc:
         
     | 
| 
       352 
     | 
    
         
            -
             
     | 
| 
       353 
     | 
    
         
            -
                def __rewind_this_transaction #:nodoc:
         
     | 
| 
       354 
     | 
    
         
            -
                  r = Marshal.restore(@__transaction_checkpoint__)
         
     | 
| 
       355 
     | 
    
         
            -
             
     | 
| 
       356 
     | 
    
         
            -
                  begin
         
     | 
| 
       357 
     | 
    
         
            -
                    self.replace(r) if respond_to?(:replace)
         
     | 
| 
       358 
     | 
    
         
            -
                  rescue
         
     | 
| 
       359 
     | 
    
         
            -
                    nil
         
     | 
| 
       360 
     | 
    
         
            -
                  end
         
     | 
| 
       361 
     | 
    
         
            -
             
     | 
| 
       362 
     | 
    
         
            -
                  r.instance_variables.each do |i|
         
     | 
| 
       363 
     | 
    
         
            -
                    next if SKIP_TRANSACTION_VARS.include?(i)
         
     | 
| 
       364 
     | 
    
         
            -
                    if respond_to?(:instance_variable_get)
         
     | 
| 
       365 
     | 
    
         
            -
                      instance_variable_set(i, r.instance_variable_get(i))
         
     | 
| 
       366 
     | 
    
         
            -
                    else
         
     | 
| 
       367 
     | 
    
         
            -
                      instance_eval(%q|#{i} = r.instance_eval("#{i}")|)
         
     | 
| 
       368 
     | 
    
         
            -
                    end
         
     | 
| 
       369 
     | 
    
         
            -
                  end
         
     | 
| 
       370 
     | 
    
         
            -
             
     | 
| 
       371 
     | 
    
         
            -
                  if respond_to?(:instance_variable_get)
         
     | 
| 
       372 
     | 
    
         
            -
                    return r.instance_variable_get(TRANSACTION_CHECKPOINT)
         
     | 
| 
       373 
     | 
    
         
            -
                  else
         
     | 
| 
       374 
     | 
    
         
            -
                    return r.instance_eval(TRANSACTION_CHECKPOINT)
         
     | 
| 
       375 
     | 
    
         
            -
                  end
         
     | 
| 
       376 
     | 
    
         
            -
                end
         
     | 
| 
       377 
     | 
    
         
            -
             
     | 
| 
       378 
     | 
    
         
            -
                def __commit_transaction #:nodoc:
         
     | 
| 
       379 
     | 
    
         
            -
                  if respond_to?(:instance_variable_get)
         
     | 
| 
       380 
     | 
    
         
            -
                    @__transaction_checkpoint__ = Marshal.restore(@__transaction_checkpoint__).instance_variable_get(TRANSACTION_CHECKPOINT)
         
     | 
| 
       381 
     | 
    
         
            -
                  else
         
     | 
| 
       382 
     | 
    
         
            -
                    @__transaction_checkpoint__ = Marshal.restore(@__transaction_checkpoint__).instance_eval(TRANSACTION_CHECKPOINT)
         
     | 
| 
       383 
     | 
    
         
            -
                  end
         
     | 
| 
       384 
     | 
    
         
            -
             
     | 
| 
       385 
     | 
    
         
            -
                  @__transaction_level__ -= 1
         
     | 
| 
       386 
     | 
    
         
            -
                  @__transaction_names__.pop
         
     | 
| 
       387 
     | 
    
         
            -
                  if @__transaction_level__ < 1
         
     | 
| 
       388 
     | 
    
         
            -
                    @__transaction_level__ = 0
         
     | 
| 
       389 
     | 
    
         
            -
                    @__transaction_names__ = []
         
     | 
| 
       390 
     | 
    
         
            -
                  end
         
     | 
| 
       391 
     | 
    
         
            -
                end
         
     | 
| 
       392 
     | 
    
         
            -
             
     | 
| 
       393 
     | 
    
         
            -
                private :__abort_transaction, :__rewind_this_transaction, :__commit_transaction
         
     | 
| 
       394 
     | 
    
         
            -
             
     | 
| 
       395 
     | 
    
         
            -
                  # = Transaction::Simple::ThreadSafe
         
     | 
| 
       396 
     | 
    
         
            -
                  # Thread-safe simple object transaction support for Ruby.
         
     | 
| 
       397 
     | 
    
         
            -
                  # Transaction::Simple::ThreadSafe is used in the same way as
         
     | 
| 
       398 
     | 
    
         
            -
                  # Transaction::Simple. Transaction::Simple::ThreadSafe uses a Mutex
         
     | 
| 
       399 
     | 
    
         
            -
                  # object to ensure atomicity at the cost of performance in threaded
         
     | 
| 
       400 
     | 
    
         
            -
                  # applications.
         
     | 
| 
       401 
     | 
    
         
            -
                  #
         
     | 
| 
       402 
     | 
    
         
            -
                  # Transaction::Simple::ThreadSafe will not wait to obtain a lock; if the
         
     | 
| 
       403 
     | 
    
         
            -
                  # lock cannot be obtained immediately, a
         
     | 
| 
       404 
     | 
    
         
            -
                  # Transaction::TransactionThreadError will be raised.
         
     | 
| 
       405 
     | 
    
         
            -
                  #
         
     | 
| 
       406 
     | 
    
         
            -
                  # Thanks to Mauricio Fern�ndez for help with getting this part working.
         
     | 
| 
       407 
     | 
    
         
            -
                module ThreadSafe
         
     | 
| 
       408 
     | 
    
         
            -
                  VERSION = '1.1.1.0';
         
     | 
| 
       409 
     | 
    
         
            -
             
     | 
| 
       410 
     | 
    
         
            -
                  include Transaction::Simple
         
     | 
| 
       411 
     | 
    
         
            -
             
     | 
| 
       412 
     | 
    
         
            -
                  SKIP_TRANSACTION_VARS = Transaction::Simple::SKIP_TRANSACTION_VARS.dup #:nodoc:
         
     | 
| 
       413 
     | 
    
         
            -
                  SKIP_TRANSACTION_VARS << "@__transaction_mutex__"
         
     | 
| 
       414 
     | 
    
         
            -
             
     | 
| 
       415 
     | 
    
         
            -
                  Transaction::Simple.instance_methods(false) do |meth|
         
     | 
| 
       416 
     | 
    
         
            -
                    next if meth == "transaction"
         
     | 
| 
       417 
     | 
    
         
            -
                    arg = "(name = nil)" unless meth == "transaction_name"
         
     | 
| 
       418 
     | 
    
         
            -
                    module_eval <<-EOS
         
     | 
| 
       419 
     | 
    
         
            -
                      def #{meth}#{arg}
         
     | 
| 
       420 
     | 
    
         
            -
                        if (@__transaction_mutex__ ||= Mutex.new).try_lock
         
     | 
| 
       421 
     | 
    
         
            -
                          result = super
         
     | 
| 
       422 
     | 
    
         
            -
                          @__transaction_mutex__.unlock
         
     | 
| 
       423 
     | 
    
         
            -
                          return result
         
     | 
| 
       424 
     | 
    
         
            -
                        else
         
     | 
| 
       425 
     | 
    
         
            -
                          raise TransactionThreadError, "Transaction Error: Cannot obtain lock for ##{meth}"
         
     | 
| 
       426 
     | 
    
         
            -
                        end
         
     | 
| 
       427 
     | 
    
         
            -
                      ensure
         
     | 
| 
       428 
     | 
    
         
            -
                        @__transaction_mutex__.unlock
         
     | 
| 
       429 
     | 
    
         
            -
                      end
         
     | 
| 
       430 
     | 
    
         
            -
                    EOS
         
     | 
| 
       431 
     | 
    
         
            -
                  end
         
     | 
| 
       432 
     | 
    
         
            -
                end
         
     | 
| 
       433 
     | 
    
         
            -
              end
         
     | 
| 
       434 
     | 
    
         
            -
            end
         
     | 
| 
       435 
     | 
    
         
            -
             
     | 
| 
       436 
     | 
    
         
            -
            if $0 == __FILE__
         
     | 
| 
       437 
     | 
    
         
            -
              require 'test/unit'
         
     | 
| 
       438 
     | 
    
         
            -
             
     | 
| 
       439 
     | 
    
         
            -
              class Test__Transaction_Simple < Test::Unit::TestCase #:nodoc:
         
     | 
| 
       440 
     | 
    
         
            -
                VALUE = "Now is the time for all good men to come to the aid of their country."
         
     | 
| 
       441 
     | 
    
         
            -
             
     | 
| 
       442 
     | 
    
         
            -
                def setup
         
     | 
| 
       443 
     | 
    
         
            -
                  @value = VALUE.dup
         
     | 
| 
       444 
     | 
    
         
            -
                  @value.extend(Transaction::Simple)
         
     | 
| 
       445 
     | 
    
         
            -
                end
         
     | 
| 
       446 
     | 
    
         
            -
             
     | 
| 
       447 
     | 
    
         
            -
                def test_extended
         
     | 
| 
       448 
     | 
    
         
            -
                  assert_respond_to(@value, :start_transaction)
         
     | 
| 
       449 
     | 
    
         
            -
                end
         
     | 
| 
       450 
     | 
    
         
            -
             
     | 
| 
       451 
     | 
    
         
            -
                def test_started
         
     | 
| 
       452 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       453 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       454 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       455 
     | 
    
         
            -
                end
         
     | 
| 
       456 
     | 
    
         
            -
             
     | 
| 
       457 
     | 
    
         
            -
                def test_rewind
         
     | 
| 
       458 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       459 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.rewind_transaction }
         
     | 
| 
       460 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       461 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       462 
     | 
    
         
            -
                  assert_nothing_raised { @value.gsub!(/men/, 'women') }
         
     | 
| 
       463 
     | 
    
         
            -
                  assert_not_equal(VALUE, @value)
         
     | 
| 
       464 
     | 
    
         
            -
                  assert_nothing_raised { @value.rewind_transaction }
         
     | 
| 
       465 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       466 
     | 
    
         
            -
                  assert_equal(VALUE, @value)
         
     | 
| 
       467 
     | 
    
         
            -
                end
         
     | 
| 
       468 
     | 
    
         
            -
             
     | 
| 
       469 
     | 
    
         
            -
                def test_abort
         
     | 
| 
       470 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       471 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.abort_transaction }
         
     | 
| 
       472 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       473 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       474 
     | 
    
         
            -
                  assert_nothing_raised { @value.gsub!(/men/, 'women') }
         
     | 
| 
       475 
     | 
    
         
            -
                  assert_not_equal(VALUE, @value)
         
     | 
| 
       476 
     | 
    
         
            -
                  assert_nothing_raised { @value.abort_transaction }
         
     | 
| 
       477 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       478 
     | 
    
         
            -
                  assert_equal(VALUE, @value)
         
     | 
| 
       479 
     | 
    
         
            -
                end
         
     | 
| 
       480 
     | 
    
         
            -
             
     | 
| 
       481 
     | 
    
         
            -
                def test_commit
         
     | 
| 
       482 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       483 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.commit_transaction }
         
     | 
| 
       484 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       485 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       486 
     | 
    
         
            -
                  assert_nothing_raised { @value.gsub!(/men/, 'women') }
         
     | 
| 
       487 
     | 
    
         
            -
                  assert_not_equal(VALUE, @value)
         
     | 
| 
       488 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       489 
     | 
    
         
            -
                  assert_nothing_raised { @value.commit_transaction }
         
     | 
| 
       490 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       491 
     | 
    
         
            -
                  assert_not_equal(VALUE, @value)
         
     | 
| 
       492 
     | 
    
         
            -
                end
         
     | 
| 
       493 
     | 
    
         
            -
             
     | 
| 
       494 
     | 
    
         
            -
                def test_multilevel
         
     | 
| 
       495 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       496 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       497 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       498 
     | 
    
         
            -
                  assert_nothing_raised { @value.gsub!(/men/, 'women') }
         
     | 
| 
       499 
     | 
    
         
            -
                  assert_equal(VALUE.gsub(/men/, 'women'), @value)
         
     | 
| 
       500 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       501 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       502 
     | 
    
         
            -
                  assert_nothing_raised { @value.gsub!(/country/, 'nation-state') }
         
     | 
| 
       503 
     | 
    
         
            -
                  assert_nothing_raised { @value.commit_transaction }
         
     | 
| 
       504 
     | 
    
         
            -
                  assert_equal(VALUE.gsub(/men/, 'women').gsub(/country/, 'nation-state'), @value)
         
     | 
| 
       505 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       506 
     | 
    
         
            -
                  assert_nothing_raised { @value.abort_transaction }
         
     | 
| 
       507 
     | 
    
         
            -
                  assert_equal(VALUE, @value)
         
     | 
| 
       508 
     | 
    
         
            -
                end
         
     | 
| 
       509 
     | 
    
         
            -
             
     | 
| 
       510 
     | 
    
         
            -
                def test_multilevel_named
         
     | 
| 
       511 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       512 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.transaction_name }
         
     | 
| 
       513 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction(:first) } # 1
         
     | 
| 
       514 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.start_transaction(:first) }
         
     | 
| 
       515 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       516 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?(:first))
         
     | 
| 
       517 
     | 
    
         
            -
                  assert_equal(:first, @value.transaction_name)
         
     | 
| 
       518 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction } # 2
         
     | 
| 
       519 
     | 
    
         
            -
                  assert_not_equal(:first, @value.transaction_name)
         
     | 
| 
       520 
     | 
    
         
            -
                  assert_equal(nil, @value.transaction_name)
         
     | 
| 
       521 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.abort_transaction(:second) }
         
     | 
| 
       522 
     | 
    
         
            -
                  assert_nothing_raised { @value.abort_transaction(:first) }
         
     | 
| 
       523 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       524 
     | 
    
         
            -
                  assert_nothing_raised do
         
     | 
| 
       525 
     | 
    
         
            -
                    @value.start_transaction(:first)
         
     | 
| 
       526 
     | 
    
         
            -
                    @value.gsub!(/men/, 'women')
         
     | 
| 
       527 
     | 
    
         
            -
                    @value.start_transaction(:second)
         
     | 
| 
       528 
     | 
    
         
            -
                    @value.gsub!(/women/, 'people')
         
     | 
| 
       529 
     | 
    
         
            -
                    @value.start_transaction
         
     | 
| 
       530 
     | 
    
         
            -
                    @value.gsub!(/people/, 'sentients')
         
     | 
| 
       531 
     | 
    
         
            -
                  end
         
     | 
| 
       532 
     | 
    
         
            -
                  assert_nothing_raised { @value.abort_transaction(:second) }
         
     | 
| 
       533 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?(:first))
         
     | 
| 
       534 
     | 
    
         
            -
                  assert_equal(VALUE.gsub(/men/, 'women'), @value)
         
     | 
| 
       535 
     | 
    
         
            -
                  assert_nothing_raised do
         
     | 
| 
       536 
     | 
    
         
            -
                    @value.start_transaction(:second)
         
     | 
| 
       537 
     | 
    
         
            -
                    @value.gsub!(/women/, 'people')
         
     | 
| 
       538 
     | 
    
         
            -
                    @value.start_transaction
         
     | 
| 
       539 
     | 
    
         
            -
                    @value.gsub!(/people/, 'sentients')
         
     | 
| 
       540 
     | 
    
         
            -
                  end
         
     | 
| 
       541 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.rewind_transaction(:foo) }
         
     | 
| 
       542 
     | 
    
         
            -
                  assert_nothing_raised { @value.rewind_transaction(:second) }
         
     | 
| 
       543 
     | 
    
         
            -
                  assert_equal(VALUE.gsub(/men/, 'women'), @value)
         
     | 
| 
       544 
     | 
    
         
            -
                  assert_nothing_raised do
         
     | 
| 
       545 
     | 
    
         
            -
                    @value.gsub!(/women/, 'people')
         
     | 
| 
       546 
     | 
    
         
            -
                    @value.start_transaction
         
     | 
| 
       547 
     | 
    
         
            -
                    @value.gsub!(/people/, 'sentients')
         
     | 
| 
       548 
     | 
    
         
            -
                  end
         
     | 
| 
       549 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.commit_transaction(:foo) }
         
     | 
| 
       550 
     | 
    
         
            -
                  assert_nothing_raised { @value.commit_transaction(:first) }
         
     | 
| 
       551 
     | 
    
         
            -
                  assert_equal(VALUE.gsub(/men/, 'sentients'), @value)
         
     | 
| 
       552 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       553 
     | 
    
         
            -
                end
         
     | 
| 
       554 
     | 
    
         
            -
             
     | 
| 
       555 
     | 
    
         
            -
                def test_array
         
     | 
| 
       556 
     | 
    
         
            -
                  assert_nothing_raised do
         
     | 
| 
       557 
     | 
    
         
            -
                    @orig = ["first", "second", "third"]
         
     | 
| 
       558 
     | 
    
         
            -
                    @value = ["first", "second", "third"]
         
     | 
| 
       559 
     | 
    
         
            -
                    @value.extend(Transaction::Simple)
         
     | 
| 
       560 
     | 
    
         
            -
                  end
         
     | 
| 
       561 
     | 
    
         
            -
                  assert_equal(@orig, @value)
         
     | 
| 
       562 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       563 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       564 
     | 
    
         
            -
                  assert_nothing_raised { @value[1].gsub!(/second/, "fourth") }
         
     | 
| 
       565 
     | 
    
         
            -
                  assert_not_equal(@orig, @value)
         
     | 
| 
       566 
     | 
    
         
            -
                  assert_nothing_raised { @value.abort_transaction }
         
     | 
| 
       567 
     | 
    
         
            -
                  assert_equal(@orig, @value)
         
     | 
| 
       568 
     | 
    
         
            -
                end
         
     | 
| 
       569 
     | 
    
         
            -
              end
         
     | 
| 
       570 
     | 
    
         
            -
             
     | 
| 
       571 
     | 
    
         
            -
              class Test__Transaction_Simple_ThreadSafe < Test::Unit::TestCase #:nodoc:
         
     | 
| 
       572 
     | 
    
         
            -
                VALUE = "Now is the time for all good men to come to the aid of their country."
         
     | 
| 
       573 
     | 
    
         
            -
             
     | 
| 
       574 
     | 
    
         
            -
                def setup
         
     | 
| 
       575 
     | 
    
         
            -
                  @value = VALUE.dup
         
     | 
| 
       576 
     | 
    
         
            -
                  @value.extend(Transaction::Simple::ThreadSafe)
         
     | 
| 
       577 
     | 
    
         
            -
                end
         
     | 
| 
       578 
     | 
    
         
            -
             
     | 
| 
       579 
     | 
    
         
            -
                def test_extended
         
     | 
| 
       580 
     | 
    
         
            -
                  assert_respond_to(@value, :start_transaction)
         
     | 
| 
       581 
     | 
    
         
            -
                end
         
     | 
| 
       582 
     | 
    
         
            -
             
     | 
| 
       583 
     | 
    
         
            -
                def test_started
         
     | 
| 
       584 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       585 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       586 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       587 
     | 
    
         
            -
                end
         
     | 
| 
       588 
     | 
    
         
            -
             
     | 
| 
       589 
     | 
    
         
            -
                def test_rewind
         
     | 
| 
       590 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       591 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.rewind_transaction }
         
     | 
| 
       592 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       593 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       594 
     | 
    
         
            -
                  assert_nothing_raised { @value.gsub!(/men/, 'women') }
         
     | 
| 
       595 
     | 
    
         
            -
                  assert_not_equal(VALUE, @value)
         
     | 
| 
       596 
     | 
    
         
            -
                  assert_nothing_raised { @value.rewind_transaction }
         
     | 
| 
       597 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       598 
     | 
    
         
            -
                  assert_equal(VALUE, @value)
         
     | 
| 
       599 
     | 
    
         
            -
                end
         
     | 
| 
       600 
     | 
    
         
            -
             
     | 
| 
       601 
     | 
    
         
            -
                def test_abort
         
     | 
| 
       602 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       603 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.abort_transaction }
         
     | 
| 
       604 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       605 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       606 
     | 
    
         
            -
                  assert_nothing_raised { @value.gsub!(/men/, 'women') }
         
     | 
| 
       607 
     | 
    
         
            -
                  assert_not_equal(VALUE, @value)
         
     | 
| 
       608 
     | 
    
         
            -
                  assert_nothing_raised { @value.abort_transaction }
         
     | 
| 
       609 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       610 
     | 
    
         
            -
                  assert_equal(VALUE, @value)
         
     | 
| 
       611 
     | 
    
         
            -
                end
         
     | 
| 
       612 
     | 
    
         
            -
             
     | 
| 
       613 
     | 
    
         
            -
                def test_commit
         
     | 
| 
       614 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       615 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.commit_transaction }
         
     | 
| 
       616 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       617 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       618 
     | 
    
         
            -
                  assert_nothing_raised { @value.gsub!(/men/, 'women') }
         
     | 
| 
       619 
     | 
    
         
            -
                  assert_not_equal(VALUE, @value)
         
     | 
| 
       620 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       621 
     | 
    
         
            -
                  assert_nothing_raised { @value.commit_transaction }
         
     | 
| 
       622 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       623 
     | 
    
         
            -
                  assert_not_equal(VALUE, @value)
         
     | 
| 
       624 
     | 
    
         
            -
                end
         
     | 
| 
       625 
     | 
    
         
            -
             
     | 
| 
       626 
     | 
    
         
            -
                def test_multilevel
         
     | 
| 
       627 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       628 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       629 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       630 
     | 
    
         
            -
                  assert_nothing_raised { @value.gsub!(/men/, 'women') }
         
     | 
| 
       631 
     | 
    
         
            -
                  assert_equal(VALUE.gsub(/men/, 'women'), @value)
         
     | 
| 
       632 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       633 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       634 
     | 
    
         
            -
                  assert_nothing_raised { @value.gsub!(/country/, 'nation-state') }
         
     | 
| 
       635 
     | 
    
         
            -
                  assert_nothing_raised { @value.commit_transaction }
         
     | 
| 
       636 
     | 
    
         
            -
                  assert_equal(VALUE.gsub(/men/, 'women').gsub(/country/, 'nation-state'), @value)
         
     | 
| 
       637 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       638 
     | 
    
         
            -
                  assert_nothing_raised { @value.abort_transaction }
         
     | 
| 
       639 
     | 
    
         
            -
                  assert_equal(VALUE, @value)
         
     | 
| 
       640 
     | 
    
         
            -
                end
         
     | 
| 
       641 
     | 
    
         
            -
             
     | 
| 
       642 
     | 
    
         
            -
                def test_multilevel_named
         
     | 
| 
       643 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       644 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.transaction_name }
         
     | 
| 
       645 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction(:first) } # 1
         
     | 
| 
       646 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.start_transaction(:first) }
         
     | 
| 
       647 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       648 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?(:first))
         
     | 
| 
       649 
     | 
    
         
            -
                  assert_equal(:first, @value.transaction_name)
         
     | 
| 
       650 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction } # 2
         
     | 
| 
       651 
     | 
    
         
            -
                  assert_not_equal(:first, @value.transaction_name)
         
     | 
| 
       652 
     | 
    
         
            -
                  assert_equal(nil, @value.transaction_name)
         
     | 
| 
       653 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.abort_transaction(:second) }
         
     | 
| 
       654 
     | 
    
         
            -
                  assert_nothing_raised { @value.abort_transaction(:first) }
         
     | 
| 
       655 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       656 
     | 
    
         
            -
                  assert_nothing_raised do
         
     | 
| 
       657 
     | 
    
         
            -
                    @value.start_transaction(:first)
         
     | 
| 
       658 
     | 
    
         
            -
                    @value.gsub!(/men/, 'women')
         
     | 
| 
       659 
     | 
    
         
            -
                    @value.start_transaction(:second)
         
     | 
| 
       660 
     | 
    
         
            -
                    @value.gsub!(/women/, 'people')
         
     | 
| 
       661 
     | 
    
         
            -
                    @value.start_transaction
         
     | 
| 
       662 
     | 
    
         
            -
                    @value.gsub!(/people/, 'sentients')
         
     | 
| 
       663 
     | 
    
         
            -
                  end
         
     | 
| 
       664 
     | 
    
         
            -
                  assert_nothing_raised { @value.abort_transaction(:second) }
         
     | 
| 
       665 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?(:first))
         
     | 
| 
       666 
     | 
    
         
            -
                  assert_equal(VALUE.gsub(/men/, 'women'), @value)
         
     | 
| 
       667 
     | 
    
         
            -
                  assert_nothing_raised do
         
     | 
| 
       668 
     | 
    
         
            -
                    @value.start_transaction(:second)
         
     | 
| 
       669 
     | 
    
         
            -
                    @value.gsub!(/women/, 'people')
         
     | 
| 
       670 
     | 
    
         
            -
                    @value.start_transaction
         
     | 
| 
       671 
     | 
    
         
            -
                    @value.gsub!(/people/, 'sentients')
         
     | 
| 
       672 
     | 
    
         
            -
                  end
         
     | 
| 
       673 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.rewind_transaction(:foo) }
         
     | 
| 
       674 
     | 
    
         
            -
                  assert_nothing_raised { @value.rewind_transaction(:second) }
         
     | 
| 
       675 
     | 
    
         
            -
                  assert_equal(VALUE.gsub(/men/, 'women'), @value)
         
     | 
| 
       676 
     | 
    
         
            -
                  assert_nothing_raised do
         
     | 
| 
       677 
     | 
    
         
            -
                    @value.gsub!(/women/, 'people')
         
     | 
| 
       678 
     | 
    
         
            -
                    @value.start_transaction
         
     | 
| 
       679 
     | 
    
         
            -
                    @value.gsub!(/people/, 'sentients')
         
     | 
| 
       680 
     | 
    
         
            -
                  end
         
     | 
| 
       681 
     | 
    
         
            -
                  assert_raises(Transaction::TransactionError) { @value.commit_transaction(:foo) }
         
     | 
| 
       682 
     | 
    
         
            -
                  assert_nothing_raised { @value.commit_transaction(:first) }
         
     | 
| 
       683 
     | 
    
         
            -
                  assert_equal(VALUE.gsub(/men/, 'sentients'), @value)
         
     | 
| 
       684 
     | 
    
         
            -
                  assert_equal(false, @value.transaction_open?)
         
     | 
| 
       685 
     | 
    
         
            -
                end
         
     | 
| 
       686 
     | 
    
         
            -
             
     | 
| 
       687 
     | 
    
         
            -
                def test_array
         
     | 
| 
       688 
     | 
    
         
            -
                  assert_nothing_raised do
         
     | 
| 
       689 
     | 
    
         
            -
                    @orig = ["first", "second", "third"]
         
     | 
| 
       690 
     | 
    
         
            -
                    @value = ["first", "second", "third"]
         
     | 
| 
       691 
     | 
    
         
            -
                    @value.extend(Transaction::Simple::ThreadSafe)
         
     | 
| 
       692 
     | 
    
         
            -
                  end
         
     | 
| 
       693 
     | 
    
         
            -
                  assert_equal(@orig, @value)
         
     | 
| 
       694 
     | 
    
         
            -
                  assert_nothing_raised { @value.start_transaction }
         
     | 
| 
       695 
     | 
    
         
            -
                  assert_equal(true, @value.transaction_open?)
         
     | 
| 
       696 
     | 
    
         
            -
                  assert_nothing_raised { @value[1].gsub!(/second/, "fourth") }
         
     | 
| 
       697 
     | 
    
         
            -
                  assert_not_equal(@orig, @value)
         
     | 
| 
       698 
     | 
    
         
            -
                  assert_nothing_raised { @value.abort_transaction }
         
     | 
| 
       699 
     | 
    
         
            -
                  assert_equal(@orig, @value)
         
     | 
| 
       700 
     | 
    
         
            -
                end
         
     | 
| 
       701 
     | 
    
         
            -
              end
         
     | 
| 
       702 
     | 
    
         
            -
            end
         
     |