ibm_db 4.0.0-x86-mingw32 → 5.0.2-x86-mingw32
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.
- checksums.yaml +5 -5
- data/MANIFEST +14 -14
- data/README +208 -208
- data/ext/Makefile +269 -0
- data/ext/Makefile.nt32 +181 -181
- data/ext/Makefile.nt32.191 +212 -212
- data/ext/extconf.rb +322 -291
- data/ext/gil_release_version +3 -0
- data/ext/ibm_db.c +11879 -11887
- data/ext/mkmf.log +110 -0
- data/ext/ruby_ibm_db.h +241 -241
- data/ext/ruby_ibm_db_cli.c +866 -866
- data/ext/ruby_ibm_db_cli.h +500 -500
- data/ext/unicode_support_version +3 -0
- data/init.rb +41 -41
- data/lib/IBM_DB.rb +27 -27
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3533 -3452
- data/lib/active_record/connection_adapters/ibmdb_adapter.rb +5 -5
- data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
- data/lib/mswin32/ibm_db.rb +90 -90
- data/lib/mswin32/rb2x/i386/ibm_db.so +0 -0
- data/test/active_record/connection_adapters/fake_adapter.rb +49 -49
- data/test/assets/example.log +1 -1
- data/test/assets/test.txt +1 -1
- data/test/cases/adapter_test.rb +351 -351
- data/test/cases/adapters/mysql2/active_schema_test.rb +193 -193
- data/test/cases/adapters/mysql2/bind_parameter_test.rb +50 -50
- data/test/cases/adapters/mysql2/boolean_test.rb +100 -100
- data/test/cases/adapters/mysql2/case_sensitivity_test.rb +63 -63
- data/test/cases/adapters/mysql2/charset_collation_test.rb +54 -54
- data/test/cases/adapters/mysql2/connection_test.rb +210 -210
- data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +45 -45
- data/test/cases/adapters/mysql2/enum_test.rb +26 -26
- data/test/cases/adapters/mysql2/explain_test.rb +21 -21
- data/test/cases/adapters/mysql2/json_test.rb +195 -195
- data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +83 -83
- data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -152
- data/test/cases/adapters/mysql2/schema_migrations_test.rb +59 -59
- data/test/cases/adapters/mysql2/schema_test.rb +126 -126
- data/test/cases/adapters/mysql2/sp_test.rb +36 -36
- data/test/cases/adapters/mysql2/sql_types_test.rb +14 -14
- data/test/cases/adapters/mysql2/table_options_test.rb +42 -42
- data/test/cases/adapters/mysql2/unsigned_type_test.rb +66 -66
- data/test/cases/adapters/postgresql/active_schema_test.rb +98 -98
- data/test/cases/adapters/postgresql/array_test.rb +339 -339
- data/test/cases/adapters/postgresql/bit_string_test.rb +82 -82
- data/test/cases/adapters/postgresql/bytea_test.rb +134 -134
- data/test/cases/adapters/postgresql/case_insensitive_test.rb +26 -26
- data/test/cases/adapters/postgresql/change_schema_test.rb +38 -38
- data/test/cases/adapters/postgresql/cidr_test.rb +25 -25
- data/test/cases/adapters/postgresql/citext_test.rb +78 -78
- data/test/cases/adapters/postgresql/collation_test.rb +53 -53
- data/test/cases/adapters/postgresql/composite_test.rb +132 -132
- data/test/cases/adapters/postgresql/connection_test.rb +257 -257
- data/test/cases/adapters/postgresql/datatype_test.rb +92 -92
- data/test/cases/adapters/postgresql/domain_test.rb +47 -47
- data/test/cases/adapters/postgresql/enum_test.rb +91 -91
- data/test/cases/adapters/postgresql/explain_test.rb +20 -20
- data/test/cases/adapters/postgresql/extension_migration_test.rb +63 -63
- data/test/cases/adapters/postgresql/full_text_test.rb +44 -44
- data/test/cases/adapters/postgresql/geometric_test.rb +378 -378
- data/test/cases/adapters/postgresql/hstore_test.rb +382 -382
- data/test/cases/adapters/postgresql/infinity_test.rb +69 -69
- data/test/cases/adapters/postgresql/integer_test.rb +25 -25
- data/test/cases/adapters/postgresql/json_test.rb +237 -237
- data/test/cases/adapters/postgresql/ltree_test.rb +53 -53
- data/test/cases/adapters/postgresql/money_test.rb +96 -96
- data/test/cases/adapters/postgresql/network_test.rb +94 -94
- data/test/cases/adapters/postgresql/numbers_test.rb +49 -49
- data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +405 -405
- data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -22
- data/test/cases/adapters/postgresql/quoting_test.rb +44 -44
- data/test/cases/adapters/postgresql/range_test.rb +343 -343
- data/test/cases/adapters/postgresql/referential_integrity_test.rb +111 -111
- data/test/cases/adapters/postgresql/rename_table_test.rb +34 -34
- data/test/cases/adapters/postgresql/schema_authorization_test.rb +119 -119
- data/test/cases/adapters/postgresql/schema_test.rb +597 -597
- data/test/cases/adapters/postgresql/serial_test.rb +154 -154
- data/test/cases/adapters/postgresql/statement_pool_test.rb +41 -41
- data/test/cases/adapters/postgresql/timestamp_test.rb +90 -90
- data/test/cases/adapters/postgresql/type_lookup_test.rb +33 -33
- data/test/cases/adapters/postgresql/utils_test.rb +62 -62
- data/test/cases/adapters/postgresql/uuid_test.rb +294 -294
- data/test/cases/adapters/postgresql/xml_test.rb +54 -54
- data/test/cases/adapters/sqlite3/collation_test.rb +53 -53
- data/test/cases/adapters/sqlite3/copy_table_test.rb +98 -98
- data/test/cases/adapters/sqlite3/explain_test.rb +21 -21
- data/test/cases/adapters/sqlite3/quoting_test.rb +101 -101
- data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +441 -441
- data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -24
- data/test/cases/adapters/sqlite3/statement_pool_test.rb +20 -20
- data/test/cases/aggregations_test.rb +168 -168
- data/test/cases/ar_schema_test.rb +146 -146
- data/test/cases/associations/association_scope_test.rb +16 -16
- data/test/cases/associations/belongs_to_associations_test.rb +1141 -1141
- data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +41 -41
- data/test/cases/associations/callbacks_test.rb +190 -190
- data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
- data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
- data/test/cases/associations/eager_load_nested_include_test.rb +126 -126
- data/test/cases/associations/eager_singularization_test.rb +148 -148
- data/test/cases/associations/eager_test.rb +1514 -1514
- data/test/cases/associations/extension_test.rb +87 -87
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +1004 -1004
- data/test/cases/associations/has_many_associations_test.rb +2501 -2501
- data/test/cases/associations/has_many_through_associations_test.rb +1271 -1271
- data/test/cases/associations/has_one_associations_test.rb +707 -707
- data/test/cases/associations/has_one_through_associations_test.rb +383 -383
- data/test/cases/associations/inner_join_association_test.rb +139 -139
- data/test/cases/associations/inverse_associations_test.rb +733 -733
- data/test/cases/associations/join_model_test.rb +777 -777
- data/test/cases/associations/left_outer_join_association_test.rb +88 -88
- data/test/cases/associations/nested_through_associations_test.rb +579 -579
- data/test/cases/associations/required_test.rb +102 -102
- data/test/cases/associations_test.rb +385 -385
- data/test/cases/attribute_decorators_test.rb +126 -125
- data/test/cases/attribute_methods/read_test.rb +60 -60
- data/test/cases/attribute_methods_test.rb +1009 -1009
- data/test/cases/attribute_set_test.rb +270 -270
- data/test/cases/attribute_test.rb +246 -246
- data/test/cases/attributes_test.rb +253 -253
- data/test/cases/autosave_association_test.rb +1708 -1708
- data/test/cases/base_test.rb +1713 -1713
- data/test/cases/batches_test.rb +489 -489
- data/test/cases/binary_test.rb +44 -44
- data/test/cases/bind_parameter_test.rb +110 -110
- data/test/cases/cache_key_test.rb +26 -25
- data/test/cases/calculations_test.rb +798 -798
- data/test/cases/callbacks_test.rb +636 -636
- data/test/cases/clone_test.rb +40 -40
- data/test/cases/coders/json_test.rb +15 -15
- data/test/cases/coders/yaml_column_test.rb +63 -63
- data/test/cases/collection_cache_key_test.rb +115 -115
- data/test/cases/column_alias_test.rb +17 -17
- data/test/cases/column_definition_test.rb +92 -92
- data/test/cases/comment_test.rb +145 -143
- data/test/cases/connection_adapters/adapter_leasing_test.rb +56 -56
- data/test/cases/connection_adapters/connection_handler_test.rb +160 -160
- data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
- data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +255 -255
- data/test/cases/connection_adapters/mysql_type_lookup_test.rb +69 -69
- data/test/cases/connection_adapters/quoting_test.rb +13 -13
- data/test/cases/connection_adapters/schema_cache_test.rb +61 -61
- data/test/cases/connection_adapters/type_lookup_test.rb +118 -118
- data/test/cases/connection_management_test.rb +112 -112
- data/test/cases/connection_pool_test.rb +521 -521
- data/test/cases/connection_specification/resolver_test.rb +131 -131
- data/test/cases/core_test.rb +112 -112
- data/test/cases/counter_cache_test.rb +214 -214
- data/test/cases/custom_locking_test.rb +17 -17
- data/test/cases/database_statements_test.rb +34 -34
- data/test/cases/date_test.rb +44 -44
- data/test/cases/date_time_precision_test.rb +107 -106
- data/test/cases/date_time_test.rb +61 -61
- data/test/cases/defaults_test.rb +219 -218
- data/test/cases/dirty_test.rb +763 -763
- data/test/cases/disconnected_test.rb +30 -30
- data/test/cases/dup_test.rb +157 -157
- data/test/cases/enum_test.rb +444 -444
- data/test/cases/errors_test.rb +16 -16
- data/test/cases/explain_subscriber_test.rb +64 -64
- data/test/cases/explain_test.rb +87 -87
- data/test/cases/finder_respond_to_test.rb +60 -60
- data/test/cases/finder_test.rb +1294 -1294
- data/test/cases/fixture_set/file_test.rb +156 -156
- data/test/cases/fixtures_test.rb +988 -988
- data/test/cases/forbidden_attributes_protection_test.rb +165 -165
- data/test/cases/habtm_destroy_order_test.rb +61 -61
- data/test/cases/helper.rb +204 -204
- data/test/cases/hot_compatibility_test.rb +142 -142
- data/test/cases/i18n_test.rb +45 -45
- data/test/cases/inheritance_test.rb +606 -606
- data/test/cases/integration_test.rb +155 -155
- data/test/cases/invalid_connection_test.rb +24 -24
- data/test/cases/invertible_migration_test.rb +387 -387
- data/test/cases/json_serialization_test.rb +311 -311
- data/test/cases/locking_test.rb +493 -493
- data/test/cases/log_subscriber_test.rb +225 -225
- data/test/cases/migration/change_schema_test.rb +458 -458
- data/test/cases/migration/change_table_test.rb +256 -256
- data/test/cases/migration/column_attributes_test.rb +176 -176
- data/test/cases/migration/column_positioning_test.rb +56 -56
- data/test/cases/migration/columns_test.rb +310 -310
- data/test/cases/migration/command_recorder_test.rb +350 -350
- data/test/cases/migration/compatibility_test.rb +118 -118
- data/test/cases/migration/create_join_table_test.rb +157 -157
- data/test/cases/migration/foreign_key_test.rb +362 -360
- data/test/cases/migration/helper.rb +39 -39
- data/test/cases/migration/index_test.rb +218 -218
- data/test/cases/migration/logger_test.rb +36 -36
- data/test/cases/migration/pending_migrations_test.rb +52 -52
- data/test/cases/migration/references_foreign_key_test.rb +221 -216
- data/test/cases/migration/references_index_test.rb +101 -101
- data/test/cases/migration/references_statements_test.rb +136 -136
- data/test/cases/migration/rename_table_test.rb +93 -93
- data/test/cases/migration_test.rb +1157 -1157
- data/test/cases/migrator_test.rb +471 -470
- data/test/cases/mixin_test.rb +68 -68
- data/test/cases/modules_test.rb +172 -172
- data/test/cases/multiparameter_attributes_test.rb +372 -372
- data/test/cases/multiple_db_test.rb +122 -122
- data/test/cases/nested_attributes_test.rb +1098 -1098
- data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
- data/test/cases/persistence_test.rb +1001 -1001
- data/test/cases/pooled_connections_test.rb +81 -81
- data/test/cases/primary_keys_test.rb +376 -376
- data/test/cases/query_cache_test.rb +446 -446
- data/test/cases/quoting_test.rb +202 -202
- data/test/cases/readonly_test.rb +119 -119
- data/test/cases/reaper_test.rb +85 -85
- data/test/cases/reflection_test.rb +509 -509
- data/test/cases/relation/delegation_test.rb +63 -63
- data/test/cases/relation/merging_test.rb +157 -157
- data/test/cases/relation/mutation_test.rb +183 -183
- data/test/cases/relation/or_test.rb +92 -92
- data/test/cases/relation/predicate_builder_test.rb +16 -16
- data/test/cases/relation/record_fetch_warning_test.rb +40 -40
- data/test/cases/relation/where_chain_test.rb +105 -105
- data/test/cases/relation/where_clause_test.rb +182 -182
- data/test/cases/relation/where_test.rb +322 -322
- data/test/cases/relation_test.rb +328 -328
- data/test/cases/relations_test.rb +2026 -2026
- data/test/cases/reload_models_test.rb +22 -22
- data/test/cases/result_test.rb +90 -90
- data/test/cases/sanitize_test.rb +176 -176
- data/test/cases/schema_dumper_test.rb +457 -457
- data/test/cases/schema_loading_test.rb +52 -52
- data/test/cases/scoping/default_scoping_test.rb +528 -528
- data/test/cases/scoping/named_scoping_test.rb +561 -561
- data/test/cases/scoping/relation_scoping_test.rb +400 -400
- data/test/cases/secure_token_test.rb +32 -32
- data/test/cases/serialization_test.rb +104 -104
- data/test/cases/serialized_attribute_test.rb +364 -364
- data/test/cases/statement_cache_test.rb +136 -136
- data/test/cases/store_test.rb +195 -195
- data/test/cases/suppressor_test.rb +63 -63
- data/test/cases/tasks/database_tasks_test.rb +462 -462
- data/test/cases/tasks/mysql_rake_test.rb +345 -345
- data/test/cases/tasks/postgresql_rake_test.rb +304 -304
- data/test/cases/tasks/sqlite_rake_test.rb +220 -220
- data/test/cases/test_case.rb +131 -131
- data/test/cases/test_fixtures_test.rb +36 -36
- data/test/cases/time_precision_test.rb +103 -102
- data/test/cases/timestamp_test.rb +501 -501
- data/test/cases/touch_later_test.rb +121 -121
- data/test/cases/transaction_callbacks_test.rb +518 -518
- data/test/cases/transaction_isolation_test.rb +106 -106
- data/test/cases/transactions_test.rb +835 -834
- data/test/cases/type/adapter_specific_registry_test.rb +133 -133
- data/test/cases/type/date_time_test.rb +14 -14
- data/test/cases/type/integer_test.rb +27 -27
- data/test/cases/type/string_test.rb +22 -22
- data/test/cases/type/type_map_test.rb +177 -177
- data/test/cases/type_test.rb +39 -39
- data/test/cases/types_test.rb +24 -24
- data/test/cases/unconnected_test.rb +33 -33
- data/test/cases/validations/absence_validation_test.rb +73 -73
- data/test/cases/validations/association_validation_test.rb +97 -97
- data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
- data/test/cases/validations/i18n_validation_test.rb +86 -86
- data/test/cases/validations/length_validation_test.rb +79 -79
- data/test/cases/validations/presence_validation_test.rb +103 -103
- data/test/cases/validations/uniqueness_validation_test.rb +548 -548
- data/test/cases/validations_repair_helper.rb +19 -19
- data/test/cases/validations_test.rb +194 -194
- data/test/cases/view_test.rb +216 -216
- data/test/cases/yaml_serialization_test.rb +121 -121
- data/test/config.example.yml +97 -97
- data/test/config.rb +5 -5
- data/test/connections/native_ibm_db/connection.rb +44 -0
- data/test/fixtures/accounts.yml +29 -29
- data/test/fixtures/admin/accounts.yml +2 -2
- data/test/fixtures/admin/users.yml +10 -10
- data/test/fixtures/author_addresses.yml +17 -17
- data/test/fixtures/author_favorites.yml +3 -3
- data/test/fixtures/authors.yml +23 -23
- data/test/fixtures/bad_posts.yml +9 -9
- data/test/fixtures/binaries.yml +133 -133
- data/test/fixtures/books.yml +31 -31
- data/test/fixtures/bulbs.yml +5 -5
- data/test/fixtures/cars.yml +9 -9
- data/test/fixtures/categories.yml +19 -19
- data/test/fixtures/categories/special_categories.yml +9 -9
- data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
- data/test/fixtures/categories_ordered.yml +7 -7
- data/test/fixtures/categories_posts.yml +31 -31
- data/test/fixtures/categorizations.yml +23 -23
- data/test/fixtures/clubs.yml +8 -8
- data/test/fixtures/collections.yml +3 -3
- data/test/fixtures/colleges.yml +3 -3
- data/test/fixtures/comments.yml +65 -65
- data/test/fixtures/companies.yml +67 -67
- data/test/fixtures/computers.yml +10 -10
- data/test/fixtures/content.yml +3 -3
- data/test/fixtures/content_positions.yml +3 -3
- data/test/fixtures/courses.yml +8 -8
- data/test/fixtures/customers.yml +25 -25
- data/test/fixtures/dashboards.yml +6 -6
- data/test/fixtures/dead_parrots.yml +5 -5
- data/test/fixtures/developers.yml +22 -22
- data/test/fixtures/developers_projects.yml +16 -16
- data/test/fixtures/dog_lovers.yml +7 -7
- data/test/fixtures/dogs.yml +4 -4
- data/test/fixtures/doubloons.yml +3 -3
- data/test/fixtures/edges.yml +5 -5
- data/test/fixtures/entrants.yml +14 -14
- data/test/fixtures/essays.yml +6 -6
- data/test/fixtures/faces.yml +11 -11
- data/test/fixtures/fk_test_has_fk.yml +3 -3
- data/test/fixtures/fk_test_has_pk.yml +1 -1
- data/test/fixtures/friendships.yml +4 -4
- data/test/fixtures/funny_jokes.yml +10 -10
- data/test/fixtures/interests.yml +33 -33
- data/test/fixtures/items.yml +3 -3
- data/test/fixtures/jobs.yml +7 -7
- data/test/fixtures/legacy_things.yml +3 -3
- data/test/fixtures/live_parrots.yml +4 -4
- data/test/fixtures/mateys.yml +4 -4
- data/test/fixtures/member_details.yml +8 -8
- data/test/fixtures/member_types.yml +6 -6
- data/test/fixtures/members.yml +11 -11
- data/test/fixtures/memberships.yml +34 -34
- data/test/fixtures/men.yml +5 -5
- data/test/fixtures/minimalistics.yml +2 -2
- data/test/fixtures/minivans.yml +5 -5
- data/test/fixtures/mixed_case_monkeys.yml +6 -6
- data/test/fixtures/mixins.yml +29 -29
- data/test/fixtures/movies.yml +7 -7
- data/test/fixtures/naked/yml/accounts.yml +1 -1
- data/test/fixtures/naked/yml/companies.yml +1 -1
- data/test/fixtures/naked/yml/courses.yml +1 -1
- data/test/fixtures/naked/yml/parrots.yml +2 -2
- data/test/fixtures/naked/yml/trees.yml +3 -3
- data/test/fixtures/nodes.yml +29 -29
- data/test/fixtures/organizations.yml +5 -5
- data/test/fixtures/other_comments.yml +6 -6
- data/test/fixtures/other_dogs.yml +2 -2
- data/test/fixtures/other_posts.yml +7 -7
- data/test/fixtures/other_topics.yml +42 -42
- data/test/fixtures/owners.yml +9 -9
- data/test/fixtures/parrots.yml +27 -27
- data/test/fixtures/parrots_pirates.yml +7 -7
- data/test/fixtures/people.yml +24 -24
- data/test/fixtures/peoples_treasures.yml +3 -3
- data/test/fixtures/pets.yml +19 -19
- data/test/fixtures/pirates.yml +12 -15
- data/test/fixtures/posts.yml +80 -80
- data/test/fixtures/price_estimates.yml +16 -16
- data/test/fixtures/products.yml +4 -4
- data/test/fixtures/projects.yml +7 -7
- data/test/fixtures/ratings.yml +14 -14
- data/test/fixtures/readers.yml +11 -11
- data/test/fixtures/references.yml +17 -17
- data/test/fixtures/reserved_words/distinct.yml +5 -5
- data/test/fixtures/reserved_words/distinct_select.yml +11 -11
- data/test/fixtures/reserved_words/group.yml +14 -14
- data/test/fixtures/reserved_words/select.yml +8 -8
- data/test/fixtures/reserved_words/values.yml +7 -7
- data/test/fixtures/ships.yml +6 -6
- data/test/fixtures/speedometers.yml +8 -8
- data/test/fixtures/sponsors.yml +12 -12
- data/test/fixtures/string_key_objects.yml +7 -7
- data/test/fixtures/subscribers.yml +10 -10
- data/test/fixtures/subscriptions.yml +12 -12
- data/test/fixtures/taggings.yml +78 -78
- data/test/fixtures/tags.yml +11 -11
- data/test/fixtures/tasks.yml +7 -7
- data/test/fixtures/teapots.yml +3 -3
- data/test/fixtures/to_be_linked/accounts.yml +2 -2
- data/test/fixtures/to_be_linked/users.yml +10 -10
- data/test/fixtures/topics.yml +49 -49
- data/test/fixtures/toys.yml +14 -14
- data/test/fixtures/traffic_lights.yml +9 -9
- data/test/fixtures/treasures.yml +10 -10
- data/test/fixtures/trees.yml +3 -3
- data/test/fixtures/uuid_children.yml +3 -3
- data/test/fixtures/uuid_parents.yml +2 -2
- data/test/fixtures/variants.yml +4 -4
- data/test/fixtures/vegetables.yml +19 -19
- data/test/fixtures/vertices.yml +3 -3
- data/test/fixtures/warehouse_things.yml +2 -2
- data/test/fixtures/zines.yml +5 -5
- data/test/migrations/10_urban/9_add_expressions.rb +11 -11
- data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
- data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
- data/test/migrations/missing/1000_people_have_middle_names.rb +9 -9
- data/test/migrations/missing/1_people_have_last_names.rb +9 -9
- data/test/migrations/missing/3_we_need_reminders.rb +12 -12
- data/test/migrations/missing/4_innocent_jointable.rb +12 -12
- data/test/migrations/rename/1_we_need_things.rb +11 -11
- data/test/migrations/rename/2_rename_things.rb +9 -9
- data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
- data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
- data/test/migrations/to_copy2/1_create_articles.rb +7 -7
- data/test/migrations/to_copy2/2_create_comments.rb +7 -7
- data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
- data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
- data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
- data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
- data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
- data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
- data/test/migrations/valid/2_we_need_reminders.rb +12 -12
- data/test/migrations/valid/3_innocent_jointable.rb +12 -12
- data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
- data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +12 -12
- data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +12 -12
- data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
- data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
- data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
- data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
- data/test/models/admin.rb +5 -5
- data/test/models/admin/account.rb +3 -3
- data/test/models/admin/user.rb +40 -40
- data/test/models/aircraft.rb +5 -5
- data/test/models/arunit2_model.rb +3 -3
- data/test/models/author.rb +209 -209
- data/test/models/auto_id.rb +4 -4
- data/test/models/autoloadable/extra_firm.rb +2 -2
- data/test/models/binary.rb +2 -2
- data/test/models/bird.rb +12 -12
- data/test/models/book.rb +23 -23
- data/test/models/boolean.rb +2 -2
- data/test/models/bulb.rb +52 -52
- data/test/models/cake_designer.rb +3 -3
- data/test/models/car.rb +29 -29
- data/test/models/carrier.rb +2 -2
- data/test/models/cat.rb +10 -10
- data/test/models/categorization.rb +19 -19
- data/test/models/category.rb +35 -35
- data/test/models/chef.rb +8 -8
- data/test/models/citation.rb +3 -3
- data/test/models/club.rb +25 -25
- data/test/models/college.rb +10 -10
- data/test/models/column.rb +3 -3
- data/test/models/column_name.rb +3 -3
- data/test/models/comment.rb +76 -76
- data/test/models/company.rb +230 -230
- data/test/models/company_in_module.rb +98 -98
- data/test/models/computer.rb +3 -3
- data/test/models/contact.rb +41 -41
- data/test/models/content.rb +40 -40
- data/test/models/contract.rb +20 -20
- data/test/models/country.rb +7 -7
- data/test/models/course.rb +6 -6
- data/test/models/customer.rb +83 -83
- data/test/models/customer_carrier.rb +14 -14
- data/test/models/dashboard.rb +3 -3
- data/test/models/default.rb +2 -2
- data/test/models/department.rb +4 -4
- data/test/models/developer.rb +274 -274
- data/test/models/dog.rb +5 -5
- data/test/models/dog_lover.rb +5 -5
- data/test/models/doubloon.rb +12 -12
- data/test/models/drink_designer.rb +3 -3
- data/test/models/edge.rb +5 -5
- data/test/models/electron.rb +5 -5
- data/test/models/engine.rb +4 -4
- data/test/models/entrant.rb +3 -3
- data/test/models/essay.rb +5 -5
- data/test/models/event.rb +3 -3
- data/test/models/eye.rb +37 -37
- data/test/models/face.rb +9 -9
- data/test/models/friendship.rb +6 -6
- data/test/models/guid.rb +2 -2
- data/test/models/guitar.rb +4 -4
- data/test/models/hotel.rb +11 -11
- data/test/models/image.rb +3 -3
- data/test/models/interest.rb +5 -5
- data/test/models/invoice.rb +4 -4
- data/test/models/item.rb +7 -7
- data/test/models/job.rb +7 -7
- data/test/models/joke.rb +7 -7
- data/test/models/keyboard.rb +3 -3
- data/test/models/legacy_thing.rb +3 -3
- data/test/models/lesson.rb +11 -11
- data/test/models/line_item.rb +3 -3
- data/test/models/liquid.rb +4 -4
- data/test/models/man.rb +11 -11
- data/test/models/matey.rb +4 -4
- data/test/models/member.rb +42 -42
- data/test/models/member_detail.rb +8 -8
- data/test/models/member_type.rb +3 -3
- data/test/models/membership.rb +35 -35
- data/test/models/mentor.rb +2 -2
- data/test/models/minimalistic.rb +2 -2
- data/test/models/minivan.rb +9 -9
- data/test/models/mixed_case_monkey.rb +3 -3
- data/test/models/mocktail_designer.rb +2 -2
- data/test/models/molecule.rb +6 -6
- data/test/models/movie.rb +5 -5
- data/test/models/node.rb +5 -5
- data/test/models/non_primary_key.rb +2 -2
- data/test/models/notification.rb +3 -3
- data/test/models/order.rb +4 -4
- data/test/models/organization.rb +14 -14
- data/test/models/other_dog.rb +5 -5
- data/test/models/owner.rb +37 -37
- data/test/models/parrot.rb +28 -28
- data/test/models/person.rb +142 -142
- data/test/models/personal_legacy_thing.rb +4 -4
- data/test/models/pet.rb +18 -18
- data/test/models/pet_treasure.rb +6 -6
- data/test/models/pirate.rb +92 -92
- data/test/models/possession.rb +3 -3
- data/test/models/post.rb +273 -273
- data/test/models/price_estimate.rb +4 -4
- data/test/models/professor.rb +5 -5
- data/test/models/project.rb +40 -40
- data/test/models/publisher.rb +2 -2
- data/test/models/publisher/article.rb +4 -4
- data/test/models/publisher/magazine.rb +3 -3
- data/test/models/rating.rb +4 -4
- data/test/models/reader.rb +23 -23
- data/test/models/recipe.rb +3 -3
- data/test/models/record.rb +2 -2
- data/test/models/reference.rb +22 -22
- data/test/models/reply.rb +61 -61
- data/test/models/ship.rb +39 -39
- data/test/models/ship_part.rb +8 -8
- data/test/models/shop.rb +17 -17
- data/test/models/shop_account.rb +6 -6
- data/test/models/speedometer.rb +6 -6
- data/test/models/sponsor.rb +7 -7
- data/test/models/string_key_object.rb +3 -3
- data/test/models/student.rb +4 -4
- data/test/models/subject.rb +16 -16
- data/test/models/subscriber.rb +8 -8
- data/test/models/subscription.rb +4 -4
- data/test/models/tag.rb +13 -13
- data/test/models/tagging.rb +13 -13
- data/test/models/task.rb +5 -5
- data/test/models/topic.rb +118 -118
- data/test/models/toy.rb +6 -6
- data/test/models/traffic_light.rb +4 -4
- data/test/models/treasure.rb +14 -14
- data/test/models/treaty.rb +7 -7
- data/test/models/tree.rb +3 -3
- data/test/models/tuning_peg.rb +4 -4
- data/test/models/tyre.rb +11 -11
- data/test/models/user.rb +14 -14
- data/test/models/uuid_child.rb +3 -3
- data/test/models/uuid_item.rb +6 -6
- data/test/models/uuid_parent.rb +3 -3
- data/test/models/vegetables.rb +24 -24
- data/test/models/vehicle.rb +6 -6
- data/test/models/vertex.rb +9 -9
- data/test/models/warehouse_thing.rb +5 -5
- data/test/models/wheel.rb +3 -3
- data/test/models/without_table.rb +3 -3
- data/test/models/zine.rb +3 -3
- data/test/schema/i5/ibm_db_specific_schema.rb +137 -0
- data/test/schema/ids/ibm_db_specific_schema.rb +140 -0
- data/test/schema/luw/ibm_db_specific_schema.rb +137 -0
- data/test/schema/mysql2_specific_schema.rb +68 -68
- data/test/schema/oracle_specific_schema.rb +40 -40
- data/test/schema/postgresql_specific_schema.rb +114 -114
- data/test/schema/schema.rb +1057 -1057
- data/test/schema/schema.rb.original +1057 -1057
- data/test/schema/sqlite_specific_schema.rb +18 -18
- data/test/schema/zOS/ibm_db_specific_schema.rb +208 -0
- data/test/support/config.rb +43 -43
- data/test/support/connection.rb +23 -23
- data/test/support/connection_helper.rb +14 -14
- data/test/support/ddl_helper.rb +8 -8
- data/test/support/schema_dumping_helper.rb +20 -20
- data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -22
- data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -182
- metadata +24 -13
- data/test/fixtures/author_addresses.original +0 -11
- data/test/fixtures/authors.original +0 -17
@@ -1,121 +1,121 @@
|
|
1
|
-
require 'cases/helper'
|
2
|
-
require 'models/invoice'
|
3
|
-
require 'models/line_item'
|
4
|
-
require 'models/topic'
|
5
|
-
require 'models/node'
|
6
|
-
require 'models/tree'
|
7
|
-
|
8
|
-
class TouchLaterTest < ActiveRecord::TestCase
|
9
|
-
fixtures :nodes, :trees
|
10
|
-
|
11
|
-
def test_touch_laster_raise_if_non_persisted
|
12
|
-
invoice = Invoice.new
|
13
|
-
Invoice.transaction do
|
14
|
-
assert_not invoice.persisted?
|
15
|
-
assert_raises(ActiveRecord::ActiveRecordError) do
|
16
|
-
invoice.touch_later
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_touch_later_dont_set_dirty_attributes
|
22
|
-
invoice = Invoice.create!
|
23
|
-
invoice.touch_later
|
24
|
-
assert_not invoice.changed?
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_touch_later_respects_no_touching_policy
|
28
|
-
time = Time.now.utc - 25.days
|
29
|
-
topic = Topic.create!(updated_at: time, created_at: time)
|
30
|
-
Topic.no_touching do
|
31
|
-
topic.touch_later
|
32
|
-
end
|
33
|
-
assert_equal time.to_i, topic.updated_at.to_i
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_touch_later_update_the_attributes
|
37
|
-
time = Time.now.utc - 25.days
|
38
|
-
topic = Topic.create!(updated_at: time, created_at: time)
|
39
|
-
assert_equal time.to_i, topic.updated_at.to_i
|
40
|
-
assert_equal time.to_i, topic.created_at.to_i
|
41
|
-
|
42
|
-
Topic.transaction do
|
43
|
-
topic.touch_later(:created_at)
|
44
|
-
assert_not_equal time.to_i, topic.updated_at.to_i
|
45
|
-
assert_not_equal time.to_i, topic.created_at.to_i
|
46
|
-
|
47
|
-
assert_equal time.to_i, topic.reload.updated_at.to_i
|
48
|
-
assert_equal time.to_i, topic.reload.created_at.to_i
|
49
|
-
end
|
50
|
-
assert_not_equal time.to_i, topic.reload.updated_at.to_i
|
51
|
-
assert_not_equal time.to_i, topic.reload.created_at.to_i
|
52
|
-
end
|
53
|
-
|
54
|
-
def test_touch_touches_immediately
|
55
|
-
time = Time.now.utc - 25.days
|
56
|
-
topic = Topic.create!(updated_at: time, created_at: time)
|
57
|
-
assert_equal time.to_i, topic.updated_at.to_i
|
58
|
-
assert_equal time.to_i, topic.created_at.to_i
|
59
|
-
|
60
|
-
Topic.transaction do
|
61
|
-
topic.touch_later(:created_at)
|
62
|
-
topic.touch
|
63
|
-
|
64
|
-
assert_not_equal time, topic.reload.updated_at
|
65
|
-
assert_not_equal time, topic.reload.created_at
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def test_touch_later_an_association_dont_autosave_parent
|
70
|
-
time = Time.now.utc - 25.days
|
71
|
-
line_item = LineItem.create!(amount: 1)
|
72
|
-
invoice = Invoice.create!(line_items: [line_item])
|
73
|
-
invoice.touch(time: time)
|
74
|
-
|
75
|
-
Invoice.transaction do
|
76
|
-
line_item.update(amount: 2)
|
77
|
-
assert_equal time.to_i, invoice.reload.updated_at.to_i
|
78
|
-
end
|
79
|
-
|
80
|
-
assert_not_equal time.to_i, invoice.updated_at.to_i
|
81
|
-
end
|
82
|
-
|
83
|
-
def test_touch_touches_immediately_with_a_custom_time
|
84
|
-
time = (Time.now.utc - 25.days).change(nsec: 0)
|
85
|
-
topic = Topic.create!(updated_at: time, created_at: time)
|
86
|
-
assert_equal time, topic.updated_at
|
87
|
-
assert_equal time, topic.created_at
|
88
|
-
|
89
|
-
Topic.transaction do
|
90
|
-
topic.touch_later(:created_at)
|
91
|
-
time = Time.now.utc - 2.days
|
92
|
-
topic.touch(time: time)
|
93
|
-
|
94
|
-
assert_equal time.to_i, topic.reload.updated_at.to_i
|
95
|
-
assert_equal time.to_i, topic.reload.created_at.to_i
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def test_touch_later_dont_hit_the_db
|
100
|
-
invoice = Invoice.create!
|
101
|
-
assert_queries(0) do
|
102
|
-
invoice.touch_later
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_touching_three_deep
|
107
|
-
previous_tree_updated_at = trees(:root).updated_at
|
108
|
-
previous_grandparent_updated_at = nodes(:grandparent).updated_at
|
109
|
-
previous_parent_updated_at = nodes(:parent_a).updated_at
|
110
|
-
previous_child_updated_at = nodes(:child_one_of_a).updated_at
|
111
|
-
|
112
|
-
travel 5.seconds do
|
113
|
-
Node.create! parent: nodes(:child_one_of_a), tree: trees(:root)
|
114
|
-
end
|
115
|
-
|
116
|
-
assert_not_equal nodes(:child_one_of_a).reload.updated_at, previous_child_updated_at
|
117
|
-
assert_not_equal nodes(:parent_a).reload.updated_at, previous_parent_updated_at
|
118
|
-
assert_not_equal nodes(:grandparent).reload.updated_at, previous_grandparent_updated_at
|
119
|
-
assert_not_equal trees(:root).reload.updated_at, previous_tree_updated_at
|
120
|
-
end
|
121
|
-
end
|
1
|
+
require 'cases/helper'
|
2
|
+
require 'models/invoice'
|
3
|
+
require 'models/line_item'
|
4
|
+
require 'models/topic'
|
5
|
+
require 'models/node'
|
6
|
+
require 'models/tree'
|
7
|
+
|
8
|
+
class TouchLaterTest < ActiveRecord::TestCase
|
9
|
+
fixtures :nodes, :trees
|
10
|
+
|
11
|
+
def test_touch_laster_raise_if_non_persisted
|
12
|
+
invoice = Invoice.new
|
13
|
+
Invoice.transaction do
|
14
|
+
assert_not invoice.persisted?
|
15
|
+
assert_raises(ActiveRecord::ActiveRecordError) do
|
16
|
+
invoice.touch_later
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_touch_later_dont_set_dirty_attributes
|
22
|
+
invoice = Invoice.create!
|
23
|
+
invoice.touch_later
|
24
|
+
assert_not invoice.changed?
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_touch_later_respects_no_touching_policy
|
28
|
+
time = Time.now.utc - 25.days
|
29
|
+
topic = Topic.create!(updated_at: time, created_at: time)
|
30
|
+
Topic.no_touching do
|
31
|
+
topic.touch_later
|
32
|
+
end
|
33
|
+
assert_equal time.to_i, topic.updated_at.to_i
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_touch_later_update_the_attributes
|
37
|
+
time = Time.now.utc - 25.days
|
38
|
+
topic = Topic.create!(updated_at: time, created_at: time)
|
39
|
+
assert_equal time.to_i, topic.updated_at.to_i
|
40
|
+
assert_equal time.to_i, topic.created_at.to_i
|
41
|
+
|
42
|
+
Topic.transaction do
|
43
|
+
topic.touch_later(:created_at)
|
44
|
+
assert_not_equal time.to_i, topic.updated_at.to_i
|
45
|
+
assert_not_equal time.to_i, topic.created_at.to_i
|
46
|
+
|
47
|
+
assert_equal time.to_i, topic.reload.updated_at.to_i
|
48
|
+
assert_equal time.to_i, topic.reload.created_at.to_i
|
49
|
+
end
|
50
|
+
assert_not_equal time.to_i, topic.reload.updated_at.to_i
|
51
|
+
assert_not_equal time.to_i, topic.reload.created_at.to_i
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_touch_touches_immediately
|
55
|
+
time = Time.now.utc - 25.days
|
56
|
+
topic = Topic.create!(updated_at: time, created_at: time)
|
57
|
+
assert_equal time.to_i, topic.updated_at.to_i
|
58
|
+
assert_equal time.to_i, topic.created_at.to_i
|
59
|
+
|
60
|
+
Topic.transaction do
|
61
|
+
topic.touch_later(:created_at)
|
62
|
+
topic.touch
|
63
|
+
|
64
|
+
assert_not_equal time, topic.reload.updated_at
|
65
|
+
assert_not_equal time, topic.reload.created_at
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_touch_later_an_association_dont_autosave_parent
|
70
|
+
time = Time.now.utc - 25.days
|
71
|
+
line_item = LineItem.create!(amount: 1)
|
72
|
+
invoice = Invoice.create!(line_items: [line_item])
|
73
|
+
invoice.touch(time: time)
|
74
|
+
|
75
|
+
Invoice.transaction do
|
76
|
+
line_item.update(amount: 2)
|
77
|
+
assert_equal time.to_i, invoice.reload.updated_at.to_i
|
78
|
+
end
|
79
|
+
|
80
|
+
assert_not_equal time.to_i, invoice.updated_at.to_i
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_touch_touches_immediately_with_a_custom_time
|
84
|
+
time = (Time.now.utc - 25.days).change(nsec: 0)
|
85
|
+
topic = Topic.create!(updated_at: time, created_at: time)
|
86
|
+
assert_equal time, topic.updated_at
|
87
|
+
assert_equal time, topic.created_at
|
88
|
+
|
89
|
+
Topic.transaction do
|
90
|
+
topic.touch_later(:created_at)
|
91
|
+
time = Time.now.utc - 2.days
|
92
|
+
topic.touch(time: time)
|
93
|
+
|
94
|
+
assert_equal time.to_i, topic.reload.updated_at.to_i
|
95
|
+
assert_equal time.to_i, topic.reload.created_at.to_i
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_touch_later_dont_hit_the_db
|
100
|
+
invoice = Invoice.create!
|
101
|
+
assert_queries(0) do
|
102
|
+
invoice.touch_later
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_touching_three_deep
|
107
|
+
previous_tree_updated_at = trees(:root).updated_at
|
108
|
+
previous_grandparent_updated_at = nodes(:grandparent).updated_at
|
109
|
+
previous_parent_updated_at = nodes(:parent_a).updated_at
|
110
|
+
previous_child_updated_at = nodes(:child_one_of_a).updated_at
|
111
|
+
|
112
|
+
travel 5.seconds do
|
113
|
+
Node.create! parent: nodes(:child_one_of_a), tree: trees(:root)
|
114
|
+
end
|
115
|
+
|
116
|
+
assert_not_equal nodes(:child_one_of_a).reload.updated_at, previous_child_updated_at
|
117
|
+
assert_not_equal nodes(:parent_a).reload.updated_at, previous_parent_updated_at
|
118
|
+
assert_not_equal nodes(:grandparent).reload.updated_at, previous_grandparent_updated_at
|
119
|
+
assert_not_equal trees(:root).reload.updated_at, previous_tree_updated_at
|
120
|
+
end
|
121
|
+
end
|
@@ -1,518 +1,518 @@
|
|
1
|
-
require "cases/helper"
|
2
|
-
require 'models/owner'
|
3
|
-
require 'models/pet'
|
4
|
-
require 'models/topic'
|
5
|
-
|
6
|
-
class TransactionCallbacksTest < ActiveRecord::TestCase
|
7
|
-
fixtures :topics, :owners, :pets
|
8
|
-
|
9
|
-
class ReplyWithCallbacks < ActiveRecord::Base
|
10
|
-
self.table_name = :topics
|
11
|
-
|
12
|
-
belongs_to :topic, foreign_key: "parent_id"
|
13
|
-
|
14
|
-
validates_presence_of :content
|
15
|
-
|
16
|
-
after_commit :do_after_commit, on: :create
|
17
|
-
|
18
|
-
attr_accessor :save_on_after_create
|
19
|
-
after_create do
|
20
|
-
self.save! if save_on_after_create
|
21
|
-
end
|
22
|
-
|
23
|
-
def history
|
24
|
-
@history ||= []
|
25
|
-
end
|
26
|
-
|
27
|
-
def do_after_commit
|
28
|
-
history << :commit_on_create
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
class TopicWithCallbacks < ActiveRecord::Base
|
33
|
-
self.table_name = :topics
|
34
|
-
|
35
|
-
has_many :replies, class_name: "ReplyWithCallbacks", foreign_key: "parent_id"
|
36
|
-
|
37
|
-
before_commit { |record| record.do_before_commit(nil) }
|
38
|
-
after_commit { |record| record.do_after_commit(nil) }
|
39
|
-
after_create_commit { |record| record.do_after_commit(:create) }
|
40
|
-
after_update_commit { |record| record.do_after_commit(:update) }
|
41
|
-
after_destroy_commit { |record| record.do_after_commit(:destroy) }
|
42
|
-
after_rollback { |record| record.do_after_rollback(nil) }
|
43
|
-
after_rollback(on: :create) { |record| record.do_after_rollback(:create) }
|
44
|
-
after_rollback(on: :update) { |record| record.do_after_rollback(:update) }
|
45
|
-
after_rollback(on: :destroy) { |record| record.do_after_rollback(:destroy) }
|
46
|
-
|
47
|
-
def history
|
48
|
-
@history ||= []
|
49
|
-
end
|
50
|
-
|
51
|
-
def before_commit_block(on = nil, &block)
|
52
|
-
@before_commit ||= {}
|
53
|
-
@before_commit[on] ||= []
|
54
|
-
@before_commit[on] << block
|
55
|
-
end
|
56
|
-
|
57
|
-
def after_commit_block(on = nil, &block)
|
58
|
-
@after_commit ||= {}
|
59
|
-
@after_commit[on] ||= []
|
60
|
-
@after_commit[on] << block
|
61
|
-
end
|
62
|
-
|
63
|
-
def after_rollback_block(on = nil, &block)
|
64
|
-
@after_rollback ||= {}
|
65
|
-
@after_rollback[on] ||= []
|
66
|
-
@after_rollback[on] << block
|
67
|
-
end
|
68
|
-
|
69
|
-
def do_before_commit(on)
|
70
|
-
blocks = @before_commit[on] if defined?(@before_commit)
|
71
|
-
blocks.each{|b| b.call(self)} if blocks
|
72
|
-
end
|
73
|
-
|
74
|
-
def do_after_commit(on)
|
75
|
-
blocks = @after_commit[on] if defined?(@after_commit)
|
76
|
-
blocks.each{|b| b.call(self)} if blocks
|
77
|
-
end
|
78
|
-
|
79
|
-
def do_after_rollback(on)
|
80
|
-
blocks = @after_rollback[on] if defined?(@after_rollback)
|
81
|
-
blocks.each{|b| b.call(self)} if blocks
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def setup
|
86
|
-
@first = TopicWithCallbacks.find(1)
|
87
|
-
end
|
88
|
-
|
89
|
-
# FIXME: Test behavior, not implementation.
|
90
|
-
def test_before_commit_exception_should_pop_transaction_stack
|
91
|
-
@first.before_commit_block { raise 'better pop this txn from the stack!' }
|
92
|
-
|
93
|
-
original_txn = @first.class.connection.current_transaction
|
94
|
-
|
95
|
-
begin
|
96
|
-
@first.save!
|
97
|
-
fail
|
98
|
-
rescue
|
99
|
-
assert_equal original_txn, @first.class.connection.current_transaction
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def test_call_after_commit_after_transaction_commits
|
104
|
-
@first.after_commit_block{|r| r.history << :after_commit}
|
105
|
-
@first.after_rollback_block{|r| r.history << :after_rollback}
|
106
|
-
|
107
|
-
@first.save!
|
108
|
-
assert_equal [:after_commit], @first.history
|
109
|
-
end
|
110
|
-
|
111
|
-
def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record
|
112
|
-
add_transaction_execution_blocks @first
|
113
|
-
|
114
|
-
@first.save!
|
115
|
-
assert_equal [:commit_on_update], @first.history
|
116
|
-
end
|
117
|
-
|
118
|
-
def test_only_call_after_commit_on_destroy_after_transaction_commits_for_destroyed_record
|
119
|
-
add_transaction_execution_blocks @first
|
120
|
-
|
121
|
-
@first.destroy
|
122
|
-
assert_equal [:commit_on_destroy], @first.history
|
123
|
-
end
|
124
|
-
|
125
|
-
def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record
|
126
|
-
unless current_adapter?(:IBM_DBAdapter)
|
127
|
-
new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
|
128
|
-
else
|
129
|
-
new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Time.now)
|
130
|
-
end
|
131
|
-
add_transaction_execution_blocks new_record
|
132
|
-
|
133
|
-
new_record.save!
|
134
|
-
assert_equal [:commit_on_create], new_record.history
|
135
|
-
end
|
136
|
-
|
137
|
-
def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record_if_create_succeeds_creating_through_association
|
138
|
-
topic = TopicWithCallbacks.create!(:title => "New topic", :written_on => Date.today)
|
139
|
-
reply = topic.replies.create
|
140
|
-
|
141
|
-
assert_equal [], reply.history
|
142
|
-
end
|
143
|
-
|
144
|
-
def test_only_call_after_commit_on_create_and_doesnt_leaky
|
145
|
-
r = ReplyWithCallbacks.new(content: 'foo')
|
146
|
-
r.save_on_after_create = true
|
147
|
-
r.save!
|
148
|
-
r.content = 'bar'
|
149
|
-
r.save!
|
150
|
-
r.save!
|
151
|
-
assert_equal [:commit_on_create], r.history
|
152
|
-
end
|
153
|
-
|
154
|
-
def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record_on_touch
|
155
|
-
add_transaction_execution_blocks @first
|
156
|
-
|
157
|
-
@first.touch
|
158
|
-
assert_equal [:commit_on_update], @first.history
|
159
|
-
end
|
160
|
-
|
161
|
-
def test_only_call_after_commit_on_top_level_transactions
|
162
|
-
@first.after_commit_block{|r| r.history << :after_commit}
|
163
|
-
assert @first.history.empty?
|
164
|
-
|
165
|
-
@first.transaction do
|
166
|
-
@first.transaction(requires_new: true) do
|
167
|
-
@first.touch
|
168
|
-
end
|
169
|
-
assert @first.history.empty?
|
170
|
-
end
|
171
|
-
assert_equal [:after_commit], @first.history
|
172
|
-
end
|
173
|
-
|
174
|
-
def test_call_after_rollback_after_transaction_rollsback
|
175
|
-
@first.after_commit_block{|r| r.history << :after_commit}
|
176
|
-
@first.after_rollback_block{|r| r.history << :after_rollback}
|
177
|
-
|
178
|
-
Topic.transaction do
|
179
|
-
@first.save!
|
180
|
-
raise ActiveRecord::Rollback
|
181
|
-
end
|
182
|
-
|
183
|
-
assert_equal [:after_rollback], @first.history
|
184
|
-
end
|
185
|
-
|
186
|
-
def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record
|
187
|
-
add_transaction_execution_blocks @first
|
188
|
-
|
189
|
-
Topic.transaction do
|
190
|
-
@first.save!
|
191
|
-
raise ActiveRecord::Rollback
|
192
|
-
end
|
193
|
-
|
194
|
-
assert_equal [:rollback_on_update], @first.history
|
195
|
-
end
|
196
|
-
|
197
|
-
def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record_on_touch
|
198
|
-
add_transaction_execution_blocks @first
|
199
|
-
|
200
|
-
Topic.transaction do
|
201
|
-
@first.touch
|
202
|
-
raise ActiveRecord::Rollback
|
203
|
-
end
|
204
|
-
|
205
|
-
assert_equal [:rollback_on_update], @first.history
|
206
|
-
end
|
207
|
-
|
208
|
-
def test_only_call_after_rollback_on_destroy_after_transaction_rollsback_for_destroyed_record
|
209
|
-
add_transaction_execution_blocks @first
|
210
|
-
|
211
|
-
Topic.transaction do
|
212
|
-
@first.destroy
|
213
|
-
raise ActiveRecord::Rollback
|
214
|
-
end
|
215
|
-
|
216
|
-
assert_equal [:rollback_on_destroy], @first.history
|
217
|
-
end
|
218
|
-
|
219
|
-
def test_only_call_after_rollback_on_create_after_transaction_rollsback_for_new_record
|
220
|
-
unless current_adapter?(:IBM_DBAdapter)
|
221
|
-
new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
|
222
|
-
else
|
223
|
-
new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Time.now)
|
224
|
-
end
|
225
|
-
add_transaction_execution_blocks new_record
|
226
|
-
|
227
|
-
Topic.transaction do
|
228
|
-
new_record.save!
|
229
|
-
raise ActiveRecord::Rollback
|
230
|
-
end
|
231
|
-
|
232
|
-
assert_equal [:rollback_on_create], new_record.history
|
233
|
-
end
|
234
|
-
|
235
|
-
def test_call_after_rollback_when_commit_fails
|
236
|
-
@first.after_commit_block { |r| r.history << :after_commit }
|
237
|
-
@first.after_rollback_block { |r| r.history << :after_rollback }
|
238
|
-
|
239
|
-
assert_raises RuntimeError do
|
240
|
-
@first.transaction do
|
241
|
-
tx = @first.class.connection.transaction_manager.current_transaction
|
242
|
-
def tx.commit
|
243
|
-
raise
|
244
|
-
end
|
245
|
-
|
246
|
-
@first.save
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
assert_equal [:after_rollback], @first.history
|
251
|
-
end
|
252
|
-
|
253
|
-
def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint
|
254
|
-
def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
|
255
|
-
def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
|
256
|
-
@first.after_rollback_block{|r| r.rollbacks(1)}
|
257
|
-
@first.after_commit_block{|r| r.commits(1)}
|
258
|
-
|
259
|
-
second = TopicWithCallbacks.find(3)
|
260
|
-
def second.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
|
261
|
-
def second.commits(i=0); @commits ||= 0; @commits += i if i; end
|
262
|
-
second.after_rollback_block{|r| r.rollbacks(1)}
|
263
|
-
second.after_commit_block{|r| r.commits(1)}
|
264
|
-
|
265
|
-
Topic.transaction do
|
266
|
-
@first.save!
|
267
|
-
Topic.transaction(:requires_new => true) do
|
268
|
-
second.save!
|
269
|
-
raise ActiveRecord::Rollback
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
assert_equal 1, @first.commits
|
274
|
-
assert_equal 0, @first.rollbacks
|
275
|
-
assert_equal 0, second.commits
|
276
|
-
assert_equal 1, second.rollbacks
|
277
|
-
end
|
278
|
-
|
279
|
-
def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint_when_release_savepoint_fails
|
280
|
-
def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
|
281
|
-
def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
|
282
|
-
|
283
|
-
@first.after_rollback_block{|r| r.rollbacks(1)}
|
284
|
-
@first.after_commit_block{|r| r.commits(1)}
|
285
|
-
|
286
|
-
Topic.transaction do
|
287
|
-
@first.save
|
288
|
-
Topic.transaction(:requires_new => true) do
|
289
|
-
@first.save!
|
290
|
-
raise ActiveRecord::Rollback
|
291
|
-
end
|
292
|
-
Topic.transaction(:requires_new => true) do
|
293
|
-
@first.save!
|
294
|
-
raise ActiveRecord::Rollback
|
295
|
-
end
|
296
|
-
end
|
297
|
-
|
298
|
-
assert_equal 1, @first.commits
|
299
|
-
assert_equal 2, @first.rollbacks
|
300
|
-
end
|
301
|
-
|
302
|
-
def test_after_commit_callback_should_not_swallow_errors
|
303
|
-
@first.after_commit_block{ fail "boom" }
|
304
|
-
assert_raises(RuntimeError) do
|
305
|
-
Topic.transaction do
|
306
|
-
@first.save!
|
307
|
-
end
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
def test_after_commit_callback_when_raise_should_not_restore_state
|
312
|
-
first = TopicWithCallbacks.new
|
313
|
-
second = TopicWithCallbacks.new
|
314
|
-
first.after_commit_block{ fail "boom" }
|
315
|
-
second.after_commit_block{ fail "boom" }
|
316
|
-
|
317
|
-
begin
|
318
|
-
Topic.transaction do
|
319
|
-
first.save!
|
320
|
-
assert_not_nil first.id
|
321
|
-
second.save!
|
322
|
-
assert_not_nil second.id
|
323
|
-
end
|
324
|
-
rescue
|
325
|
-
end
|
326
|
-
assert_not_nil first.id
|
327
|
-
assert_not_nil second.id
|
328
|
-
assert first.reload
|
329
|
-
end
|
330
|
-
|
331
|
-
def test_after_rollback_callback_should_not_swallow_errors_when_set_to_raise
|
332
|
-
error_class = Class.new(StandardError)
|
333
|
-
@first.after_rollback_block{ raise error_class }
|
334
|
-
assert_raises(error_class) do
|
335
|
-
Topic.transaction do
|
336
|
-
@first.save!
|
337
|
-
raise ActiveRecord::Rollback
|
338
|
-
end
|
339
|
-
end
|
340
|
-
end
|
341
|
-
|
342
|
-
def test_after_rollback_callback_when_raise_should_restore_state
|
343
|
-
error_class = Class.new(StandardError)
|
344
|
-
|
345
|
-
first = TopicWithCallbacks.new
|
346
|
-
second = TopicWithCallbacks.new
|
347
|
-
first.after_rollback_block{ raise error_class }
|
348
|
-
second.after_rollback_block{ raise error_class }
|
349
|
-
|
350
|
-
begin
|
351
|
-
Topic.transaction do
|
352
|
-
first.save!
|
353
|
-
assert_not_nil first.id
|
354
|
-
second.save!
|
355
|
-
assert_not_nil second.id
|
356
|
-
raise ActiveRecord::Rollback
|
357
|
-
end
|
358
|
-
rescue error_class
|
359
|
-
end
|
360
|
-
assert_nil first.id
|
361
|
-
assert_nil second.id
|
362
|
-
end
|
363
|
-
|
364
|
-
def test_after_rollback_callbacks_should_validate_on_condition
|
365
|
-
assert_raise(ArgumentError) { Topic.after_rollback(on: :save) }
|
366
|
-
e = assert_raise(ArgumentError) { Topic.after_rollback(on: 'create') }
|
367
|
-
assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message)
|
368
|
-
end
|
369
|
-
|
370
|
-
def test_after_commit_callbacks_should_validate_on_condition
|
371
|
-
assert_raise(ArgumentError) { Topic.after_commit(on: :save) }
|
372
|
-
e = assert_raise(ArgumentError) { Topic.after_commit(on: 'create') }
|
373
|
-
assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message)
|
374
|
-
end
|
375
|
-
|
376
|
-
def test_saving_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_call_callbacks_on_the_parent_object
|
377
|
-
pet = Pet.first
|
378
|
-
owner = pet.owner
|
379
|
-
flag = false
|
380
|
-
|
381
|
-
owner.on_after_commit do
|
382
|
-
flag = true
|
383
|
-
end
|
384
|
-
|
385
|
-
pet.name = "Fluffy the Third"
|
386
|
-
pet.save
|
387
|
-
|
388
|
-
assert flag
|
389
|
-
end
|
390
|
-
|
391
|
-
private
|
392
|
-
|
393
|
-
def add_transaction_execution_blocks(record)
|
394
|
-
record.after_commit_block(:create) { |r| r.history << :commit_on_create }
|
395
|
-
record.after_commit_block(:update) { |r| r.history << :commit_on_update }
|
396
|
-
record.after_commit_block(:destroy) { |r| r.history << :commit_on_destroy }
|
397
|
-
record.after_rollback_block(:create) { |r| r.history << :rollback_on_create }
|
398
|
-
record.after_rollback_block(:update) { |r| r.history << :rollback_on_update }
|
399
|
-
record.after_rollback_block(:destroy) { |r| r.history << :rollback_on_destroy }
|
400
|
-
end
|
401
|
-
end
|
402
|
-
|
403
|
-
class CallbacksOnMultipleActionsTest < ActiveRecord::TestCase
|
404
|
-
self.use_transactional_tests = false
|
405
|
-
|
406
|
-
class TopicWithCallbacksOnMultipleActions < ActiveRecord::Base
|
407
|
-
self.table_name = :topics
|
408
|
-
|
409
|
-
after_commit(on: [:create, :destroy]) { |record| record.history << :create_and_destroy }
|
410
|
-
after_commit(on: [:create, :update]) { |record| record.history << :create_and_update }
|
411
|
-
after_commit(on: [:update, :destroy]) { |record| record.history << :update_and_destroy }
|
412
|
-
|
413
|
-
before_commit(if: :save_before_commit_history) { |record| record.history << :before_commit }
|
414
|
-
before_commit(if: :update_title) { |record| record.update(title: "before commit title") }
|
415
|
-
|
416
|
-
def clear_history
|
417
|
-
@history = []
|
418
|
-
end
|
419
|
-
|
420
|
-
def history
|
421
|
-
@history ||= []
|
422
|
-
end
|
423
|
-
|
424
|
-
attr_accessor :save_before_commit_history, :update_title
|
425
|
-
end
|
426
|
-
|
427
|
-
def test_after_commit_on_multiple_actions
|
428
|
-
topic = TopicWithCallbacksOnMultipleActions.new
|
429
|
-
topic.save
|
430
|
-
assert_equal [:create_and_update, :create_and_destroy], topic.history
|
431
|
-
|
432
|
-
topic.clear_history
|
433
|
-
topic.approved = true
|
434
|
-
topic.save
|
435
|
-
assert_equal [:update_and_destroy, :create_and_update], topic.history
|
436
|
-
|
437
|
-
topic.clear_history
|
438
|
-
topic.destroy
|
439
|
-
assert_equal [:update_and_destroy, :create_and_destroy], topic.history
|
440
|
-
end
|
441
|
-
|
442
|
-
def test_before_commit_actions
|
443
|
-
topic = TopicWithCallbacksOnMultipleActions.new
|
444
|
-
topic.save_before_commit_history = true
|
445
|
-
topic.save
|
446
|
-
|
447
|
-
assert_equal [:before_commit, :create_and_update, :create_and_destroy], topic.history
|
448
|
-
end
|
449
|
-
|
450
|
-
def test_before_commit_update_in_same_transaction
|
451
|
-
topic = TopicWithCallbacksOnMultipleActions.new
|
452
|
-
topic.update_title = true
|
453
|
-
topic.save
|
454
|
-
|
455
|
-
assert_equal "before commit title", topic.title
|
456
|
-
assert_equal "before commit title", topic.reload.title
|
457
|
-
end
|
458
|
-
end
|
459
|
-
|
460
|
-
|
461
|
-
class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase
|
462
|
-
|
463
|
-
class TopicWithoutTransactionalEnrollmentCallbacks < ActiveRecord::Base
|
464
|
-
self.table_name = :topics
|
465
|
-
|
466
|
-
before_commit_without_transaction_enrollment { |r| r.history << :before_commit }
|
467
|
-
after_commit_without_transaction_enrollment { |r| r.history << :after_commit }
|
468
|
-
after_rollback_without_transaction_enrollment { |r| r.history << :rollback }
|
469
|
-
|
470
|
-
def history
|
471
|
-
@history ||= []
|
472
|
-
end
|
473
|
-
end
|
474
|
-
|
475
|
-
def setup
|
476
|
-
@topic = TopicWithoutTransactionalEnrollmentCallbacks.create!
|
477
|
-
end
|
478
|
-
|
479
|
-
def test_commit_does_not_run_transactions_callbacks_without_enrollment
|
480
|
-
@topic.transaction do
|
481
|
-
@topic.content = 'foo'
|
482
|
-
@topic.save!
|
483
|
-
end
|
484
|
-
assert @topic.history.empty?
|
485
|
-
end
|
486
|
-
|
487
|
-
def test_commit_run_transactions_callbacks_with_explicit_enrollment
|
488
|
-
@topic.transaction do
|
489
|
-
2.times do
|
490
|
-
@topic.content = 'foo'
|
491
|
-
@topic.save!
|
492
|
-
end
|
493
|
-
@topic.class.connection.add_transaction_record(@topic)
|
494
|
-
end
|
495
|
-
assert_equal [:before_commit, :after_commit], @topic.history
|
496
|
-
end
|
497
|
-
|
498
|
-
def test_rollback_does_not_run_transactions_callbacks_without_enrollment
|
499
|
-
@topic.transaction do
|
500
|
-
@topic.content = 'foo'
|
501
|
-
@topic.save!
|
502
|
-
raise ActiveRecord::Rollback
|
503
|
-
end
|
504
|
-
assert @topic.history.empty?
|
505
|
-
end
|
506
|
-
|
507
|
-
def test_rollback_run_transactions_callbacks_with_explicit_enrollment
|
508
|
-
@topic.transaction do
|
509
|
-
2.times do
|
510
|
-
@topic.content = 'foo'
|
511
|
-
@topic.save!
|
512
|
-
end
|
513
|
-
@topic.class.connection.add_transaction_record(@topic)
|
514
|
-
raise ActiveRecord::Rollback
|
515
|
-
end
|
516
|
-
assert_equal [:rollback], @topic.history
|
517
|
-
end
|
518
|
-
end
|
1
|
+
require "cases/helper"
|
2
|
+
require 'models/owner'
|
3
|
+
require 'models/pet'
|
4
|
+
require 'models/topic'
|
5
|
+
|
6
|
+
class TransactionCallbacksTest < ActiveRecord::TestCase
|
7
|
+
fixtures :topics, :owners, :pets
|
8
|
+
|
9
|
+
class ReplyWithCallbacks < ActiveRecord::Base
|
10
|
+
self.table_name = :topics
|
11
|
+
|
12
|
+
belongs_to :topic, foreign_key: "parent_id"
|
13
|
+
|
14
|
+
validates_presence_of :content
|
15
|
+
|
16
|
+
after_commit :do_after_commit, on: :create
|
17
|
+
|
18
|
+
attr_accessor :save_on_after_create
|
19
|
+
after_create do
|
20
|
+
self.save! if save_on_after_create
|
21
|
+
end
|
22
|
+
|
23
|
+
def history
|
24
|
+
@history ||= []
|
25
|
+
end
|
26
|
+
|
27
|
+
def do_after_commit
|
28
|
+
history << :commit_on_create
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class TopicWithCallbacks < ActiveRecord::Base
|
33
|
+
self.table_name = :topics
|
34
|
+
|
35
|
+
has_many :replies, class_name: "ReplyWithCallbacks", foreign_key: "parent_id"
|
36
|
+
|
37
|
+
before_commit { |record| record.do_before_commit(nil) }
|
38
|
+
after_commit { |record| record.do_after_commit(nil) }
|
39
|
+
after_create_commit { |record| record.do_after_commit(:create) }
|
40
|
+
after_update_commit { |record| record.do_after_commit(:update) }
|
41
|
+
after_destroy_commit { |record| record.do_after_commit(:destroy) }
|
42
|
+
after_rollback { |record| record.do_after_rollback(nil) }
|
43
|
+
after_rollback(on: :create) { |record| record.do_after_rollback(:create) }
|
44
|
+
after_rollback(on: :update) { |record| record.do_after_rollback(:update) }
|
45
|
+
after_rollback(on: :destroy) { |record| record.do_after_rollback(:destroy) }
|
46
|
+
|
47
|
+
def history
|
48
|
+
@history ||= []
|
49
|
+
end
|
50
|
+
|
51
|
+
def before_commit_block(on = nil, &block)
|
52
|
+
@before_commit ||= {}
|
53
|
+
@before_commit[on] ||= []
|
54
|
+
@before_commit[on] << block
|
55
|
+
end
|
56
|
+
|
57
|
+
def after_commit_block(on = nil, &block)
|
58
|
+
@after_commit ||= {}
|
59
|
+
@after_commit[on] ||= []
|
60
|
+
@after_commit[on] << block
|
61
|
+
end
|
62
|
+
|
63
|
+
def after_rollback_block(on = nil, &block)
|
64
|
+
@after_rollback ||= {}
|
65
|
+
@after_rollback[on] ||= []
|
66
|
+
@after_rollback[on] << block
|
67
|
+
end
|
68
|
+
|
69
|
+
def do_before_commit(on)
|
70
|
+
blocks = @before_commit[on] if defined?(@before_commit)
|
71
|
+
blocks.each{|b| b.call(self)} if blocks
|
72
|
+
end
|
73
|
+
|
74
|
+
def do_after_commit(on)
|
75
|
+
blocks = @after_commit[on] if defined?(@after_commit)
|
76
|
+
blocks.each{|b| b.call(self)} if blocks
|
77
|
+
end
|
78
|
+
|
79
|
+
def do_after_rollback(on)
|
80
|
+
blocks = @after_rollback[on] if defined?(@after_rollback)
|
81
|
+
blocks.each{|b| b.call(self)} if blocks
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def setup
|
86
|
+
@first = TopicWithCallbacks.find(1)
|
87
|
+
end
|
88
|
+
|
89
|
+
# FIXME: Test behavior, not implementation.
|
90
|
+
def test_before_commit_exception_should_pop_transaction_stack
|
91
|
+
@first.before_commit_block { raise 'better pop this txn from the stack!' }
|
92
|
+
|
93
|
+
original_txn = @first.class.connection.current_transaction
|
94
|
+
|
95
|
+
begin
|
96
|
+
@first.save!
|
97
|
+
fail
|
98
|
+
rescue
|
99
|
+
assert_equal original_txn, @first.class.connection.current_transaction
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_call_after_commit_after_transaction_commits
|
104
|
+
@first.after_commit_block{|r| r.history << :after_commit}
|
105
|
+
@first.after_rollback_block{|r| r.history << :after_rollback}
|
106
|
+
|
107
|
+
@first.save!
|
108
|
+
assert_equal [:after_commit], @first.history
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record
|
112
|
+
add_transaction_execution_blocks @first
|
113
|
+
|
114
|
+
@first.save!
|
115
|
+
assert_equal [:commit_on_update], @first.history
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_only_call_after_commit_on_destroy_after_transaction_commits_for_destroyed_record
|
119
|
+
add_transaction_execution_blocks @first
|
120
|
+
|
121
|
+
@first.destroy
|
122
|
+
assert_equal [:commit_on_destroy], @first.history
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record
|
126
|
+
unless current_adapter?(:IBM_DBAdapter)
|
127
|
+
new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
|
128
|
+
else
|
129
|
+
new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Time.now)
|
130
|
+
end
|
131
|
+
add_transaction_execution_blocks new_record
|
132
|
+
|
133
|
+
new_record.save!
|
134
|
+
assert_equal [:commit_on_create], new_record.history
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record_if_create_succeeds_creating_through_association
|
138
|
+
topic = TopicWithCallbacks.create!(:title => "New topic", :written_on => Date.today)
|
139
|
+
reply = topic.replies.create
|
140
|
+
|
141
|
+
assert_equal [], reply.history
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_only_call_after_commit_on_create_and_doesnt_leaky
|
145
|
+
r = ReplyWithCallbacks.new(content: 'foo')
|
146
|
+
r.save_on_after_create = true
|
147
|
+
r.save!
|
148
|
+
r.content = 'bar'
|
149
|
+
r.save!
|
150
|
+
r.save!
|
151
|
+
assert_equal [:commit_on_create], r.history
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record_on_touch
|
155
|
+
add_transaction_execution_blocks @first
|
156
|
+
|
157
|
+
@first.touch
|
158
|
+
assert_equal [:commit_on_update], @first.history
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_only_call_after_commit_on_top_level_transactions
|
162
|
+
@first.after_commit_block{|r| r.history << :after_commit}
|
163
|
+
assert @first.history.empty?
|
164
|
+
|
165
|
+
@first.transaction do
|
166
|
+
@first.transaction(requires_new: true) do
|
167
|
+
@first.touch
|
168
|
+
end
|
169
|
+
assert @first.history.empty?
|
170
|
+
end
|
171
|
+
assert_equal [:after_commit], @first.history
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_call_after_rollback_after_transaction_rollsback
|
175
|
+
@first.after_commit_block{|r| r.history << :after_commit}
|
176
|
+
@first.after_rollback_block{|r| r.history << :after_rollback}
|
177
|
+
|
178
|
+
Topic.transaction do
|
179
|
+
@first.save!
|
180
|
+
raise ActiveRecord::Rollback
|
181
|
+
end
|
182
|
+
|
183
|
+
assert_equal [:after_rollback], @first.history
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record
|
187
|
+
add_transaction_execution_blocks @first
|
188
|
+
|
189
|
+
Topic.transaction do
|
190
|
+
@first.save!
|
191
|
+
raise ActiveRecord::Rollback
|
192
|
+
end
|
193
|
+
|
194
|
+
assert_equal [:rollback_on_update], @first.history
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record_on_touch
|
198
|
+
add_transaction_execution_blocks @first
|
199
|
+
|
200
|
+
Topic.transaction do
|
201
|
+
@first.touch
|
202
|
+
raise ActiveRecord::Rollback
|
203
|
+
end
|
204
|
+
|
205
|
+
assert_equal [:rollback_on_update], @first.history
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_only_call_after_rollback_on_destroy_after_transaction_rollsback_for_destroyed_record
|
209
|
+
add_transaction_execution_blocks @first
|
210
|
+
|
211
|
+
Topic.transaction do
|
212
|
+
@first.destroy
|
213
|
+
raise ActiveRecord::Rollback
|
214
|
+
end
|
215
|
+
|
216
|
+
assert_equal [:rollback_on_destroy], @first.history
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_only_call_after_rollback_on_create_after_transaction_rollsback_for_new_record
|
220
|
+
unless current_adapter?(:IBM_DBAdapter)
|
221
|
+
new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
|
222
|
+
else
|
223
|
+
new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Time.now)
|
224
|
+
end
|
225
|
+
add_transaction_execution_blocks new_record
|
226
|
+
|
227
|
+
Topic.transaction do
|
228
|
+
new_record.save!
|
229
|
+
raise ActiveRecord::Rollback
|
230
|
+
end
|
231
|
+
|
232
|
+
assert_equal [:rollback_on_create], new_record.history
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_call_after_rollback_when_commit_fails
|
236
|
+
@first.after_commit_block { |r| r.history << :after_commit }
|
237
|
+
@first.after_rollback_block { |r| r.history << :after_rollback }
|
238
|
+
|
239
|
+
assert_raises RuntimeError do
|
240
|
+
@first.transaction do
|
241
|
+
tx = @first.class.connection.transaction_manager.current_transaction
|
242
|
+
def tx.commit
|
243
|
+
raise
|
244
|
+
end
|
245
|
+
|
246
|
+
@first.save
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
assert_equal [:after_rollback], @first.history
|
251
|
+
end
|
252
|
+
|
253
|
+
def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint
|
254
|
+
def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
|
255
|
+
def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
|
256
|
+
@first.after_rollback_block{|r| r.rollbacks(1)}
|
257
|
+
@first.after_commit_block{|r| r.commits(1)}
|
258
|
+
|
259
|
+
second = TopicWithCallbacks.find(3)
|
260
|
+
def second.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
|
261
|
+
def second.commits(i=0); @commits ||= 0; @commits += i if i; end
|
262
|
+
second.after_rollback_block{|r| r.rollbacks(1)}
|
263
|
+
second.after_commit_block{|r| r.commits(1)}
|
264
|
+
|
265
|
+
Topic.transaction do
|
266
|
+
@first.save!
|
267
|
+
Topic.transaction(:requires_new => true) do
|
268
|
+
second.save!
|
269
|
+
raise ActiveRecord::Rollback
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
assert_equal 1, @first.commits
|
274
|
+
assert_equal 0, @first.rollbacks
|
275
|
+
assert_equal 0, second.commits
|
276
|
+
assert_equal 1, second.rollbacks
|
277
|
+
end
|
278
|
+
|
279
|
+
def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint_when_release_savepoint_fails
|
280
|
+
def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
|
281
|
+
def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
|
282
|
+
|
283
|
+
@first.after_rollback_block{|r| r.rollbacks(1)}
|
284
|
+
@first.after_commit_block{|r| r.commits(1)}
|
285
|
+
|
286
|
+
Topic.transaction do
|
287
|
+
@first.save
|
288
|
+
Topic.transaction(:requires_new => true) do
|
289
|
+
@first.save!
|
290
|
+
raise ActiveRecord::Rollback
|
291
|
+
end
|
292
|
+
Topic.transaction(:requires_new => true) do
|
293
|
+
@first.save!
|
294
|
+
raise ActiveRecord::Rollback
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
assert_equal 1, @first.commits
|
299
|
+
assert_equal 2, @first.rollbacks
|
300
|
+
end
|
301
|
+
|
302
|
+
def test_after_commit_callback_should_not_swallow_errors
|
303
|
+
@first.after_commit_block{ fail "boom" }
|
304
|
+
assert_raises(RuntimeError) do
|
305
|
+
Topic.transaction do
|
306
|
+
@first.save!
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
def test_after_commit_callback_when_raise_should_not_restore_state
|
312
|
+
first = TopicWithCallbacks.new
|
313
|
+
second = TopicWithCallbacks.new
|
314
|
+
first.after_commit_block{ fail "boom" }
|
315
|
+
second.after_commit_block{ fail "boom" }
|
316
|
+
|
317
|
+
begin
|
318
|
+
Topic.transaction do
|
319
|
+
first.save!
|
320
|
+
assert_not_nil first.id
|
321
|
+
second.save!
|
322
|
+
assert_not_nil second.id
|
323
|
+
end
|
324
|
+
rescue
|
325
|
+
end
|
326
|
+
assert_not_nil first.id
|
327
|
+
assert_not_nil second.id
|
328
|
+
assert first.reload
|
329
|
+
end
|
330
|
+
|
331
|
+
def test_after_rollback_callback_should_not_swallow_errors_when_set_to_raise
|
332
|
+
error_class = Class.new(StandardError)
|
333
|
+
@first.after_rollback_block{ raise error_class }
|
334
|
+
assert_raises(error_class) do
|
335
|
+
Topic.transaction do
|
336
|
+
@first.save!
|
337
|
+
raise ActiveRecord::Rollback
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
def test_after_rollback_callback_when_raise_should_restore_state
|
343
|
+
error_class = Class.new(StandardError)
|
344
|
+
|
345
|
+
first = TopicWithCallbacks.new
|
346
|
+
second = TopicWithCallbacks.new
|
347
|
+
first.after_rollback_block{ raise error_class }
|
348
|
+
second.after_rollback_block{ raise error_class }
|
349
|
+
|
350
|
+
begin
|
351
|
+
Topic.transaction do
|
352
|
+
first.save!
|
353
|
+
assert_not_nil first.id
|
354
|
+
second.save!
|
355
|
+
assert_not_nil second.id
|
356
|
+
raise ActiveRecord::Rollback
|
357
|
+
end
|
358
|
+
rescue error_class
|
359
|
+
end
|
360
|
+
assert_nil first.id
|
361
|
+
assert_nil second.id
|
362
|
+
end
|
363
|
+
|
364
|
+
def test_after_rollback_callbacks_should_validate_on_condition
|
365
|
+
assert_raise(ArgumentError) { Topic.after_rollback(on: :save) }
|
366
|
+
e = assert_raise(ArgumentError) { Topic.after_rollback(on: 'create') }
|
367
|
+
assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message)
|
368
|
+
end
|
369
|
+
|
370
|
+
def test_after_commit_callbacks_should_validate_on_condition
|
371
|
+
assert_raise(ArgumentError) { Topic.after_commit(on: :save) }
|
372
|
+
e = assert_raise(ArgumentError) { Topic.after_commit(on: 'create') }
|
373
|
+
assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message)
|
374
|
+
end
|
375
|
+
|
376
|
+
def test_saving_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_call_callbacks_on_the_parent_object
|
377
|
+
pet = Pet.first
|
378
|
+
owner = pet.owner
|
379
|
+
flag = false
|
380
|
+
|
381
|
+
owner.on_after_commit do
|
382
|
+
flag = true
|
383
|
+
end
|
384
|
+
|
385
|
+
pet.name = "Fluffy the Third"
|
386
|
+
pet.save
|
387
|
+
|
388
|
+
assert flag
|
389
|
+
end
|
390
|
+
|
391
|
+
private
|
392
|
+
|
393
|
+
def add_transaction_execution_blocks(record)
|
394
|
+
record.after_commit_block(:create) { |r| r.history << :commit_on_create }
|
395
|
+
record.after_commit_block(:update) { |r| r.history << :commit_on_update }
|
396
|
+
record.after_commit_block(:destroy) { |r| r.history << :commit_on_destroy }
|
397
|
+
record.after_rollback_block(:create) { |r| r.history << :rollback_on_create }
|
398
|
+
record.after_rollback_block(:update) { |r| r.history << :rollback_on_update }
|
399
|
+
record.after_rollback_block(:destroy) { |r| r.history << :rollback_on_destroy }
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
class CallbacksOnMultipleActionsTest < ActiveRecord::TestCase
|
404
|
+
self.use_transactional_tests = false
|
405
|
+
|
406
|
+
class TopicWithCallbacksOnMultipleActions < ActiveRecord::Base
|
407
|
+
self.table_name = :topics
|
408
|
+
|
409
|
+
after_commit(on: [:create, :destroy]) { |record| record.history << :create_and_destroy }
|
410
|
+
after_commit(on: [:create, :update]) { |record| record.history << :create_and_update }
|
411
|
+
after_commit(on: [:update, :destroy]) { |record| record.history << :update_and_destroy }
|
412
|
+
|
413
|
+
before_commit(if: :save_before_commit_history) { |record| record.history << :before_commit }
|
414
|
+
before_commit(if: :update_title) { |record| record.update(title: "before commit title") }
|
415
|
+
|
416
|
+
def clear_history
|
417
|
+
@history = []
|
418
|
+
end
|
419
|
+
|
420
|
+
def history
|
421
|
+
@history ||= []
|
422
|
+
end
|
423
|
+
|
424
|
+
attr_accessor :save_before_commit_history, :update_title
|
425
|
+
end
|
426
|
+
|
427
|
+
def test_after_commit_on_multiple_actions
|
428
|
+
topic = TopicWithCallbacksOnMultipleActions.new
|
429
|
+
topic.save
|
430
|
+
assert_equal [:create_and_update, :create_and_destroy], topic.history
|
431
|
+
|
432
|
+
topic.clear_history
|
433
|
+
topic.approved = true
|
434
|
+
topic.save
|
435
|
+
assert_equal [:update_and_destroy, :create_and_update], topic.history
|
436
|
+
|
437
|
+
topic.clear_history
|
438
|
+
topic.destroy
|
439
|
+
assert_equal [:update_and_destroy, :create_and_destroy], topic.history
|
440
|
+
end
|
441
|
+
|
442
|
+
def test_before_commit_actions
|
443
|
+
topic = TopicWithCallbacksOnMultipleActions.new
|
444
|
+
topic.save_before_commit_history = true
|
445
|
+
topic.save
|
446
|
+
|
447
|
+
assert_equal [:before_commit, :create_and_update, :create_and_destroy], topic.history
|
448
|
+
end
|
449
|
+
|
450
|
+
def test_before_commit_update_in_same_transaction
|
451
|
+
topic = TopicWithCallbacksOnMultipleActions.new
|
452
|
+
topic.update_title = true
|
453
|
+
topic.save
|
454
|
+
|
455
|
+
assert_equal "before commit title", topic.title
|
456
|
+
assert_equal "before commit title", topic.reload.title
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
|
461
|
+
class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase
|
462
|
+
|
463
|
+
class TopicWithoutTransactionalEnrollmentCallbacks < ActiveRecord::Base
|
464
|
+
self.table_name = :topics
|
465
|
+
|
466
|
+
before_commit_without_transaction_enrollment { |r| r.history << :before_commit }
|
467
|
+
after_commit_without_transaction_enrollment { |r| r.history << :after_commit }
|
468
|
+
after_rollback_without_transaction_enrollment { |r| r.history << :rollback }
|
469
|
+
|
470
|
+
def history
|
471
|
+
@history ||= []
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
def setup
|
476
|
+
@topic = TopicWithoutTransactionalEnrollmentCallbacks.create!
|
477
|
+
end
|
478
|
+
|
479
|
+
def test_commit_does_not_run_transactions_callbacks_without_enrollment
|
480
|
+
@topic.transaction do
|
481
|
+
@topic.content = 'foo'
|
482
|
+
@topic.save!
|
483
|
+
end
|
484
|
+
assert @topic.history.empty?
|
485
|
+
end
|
486
|
+
|
487
|
+
def test_commit_run_transactions_callbacks_with_explicit_enrollment
|
488
|
+
@topic.transaction do
|
489
|
+
2.times do
|
490
|
+
@topic.content = 'foo'
|
491
|
+
@topic.save!
|
492
|
+
end
|
493
|
+
@topic.class.connection.add_transaction_record(@topic)
|
494
|
+
end
|
495
|
+
assert_equal [:before_commit, :after_commit], @topic.history
|
496
|
+
end
|
497
|
+
|
498
|
+
def test_rollback_does_not_run_transactions_callbacks_without_enrollment
|
499
|
+
@topic.transaction do
|
500
|
+
@topic.content = 'foo'
|
501
|
+
@topic.save!
|
502
|
+
raise ActiveRecord::Rollback
|
503
|
+
end
|
504
|
+
assert @topic.history.empty?
|
505
|
+
end
|
506
|
+
|
507
|
+
def test_rollback_run_transactions_callbacks_with_explicit_enrollment
|
508
|
+
@topic.transaction do
|
509
|
+
2.times do
|
510
|
+
@topic.content = 'foo'
|
511
|
+
@topic.save!
|
512
|
+
end
|
513
|
+
@topic.class.connection.add_transaction_record(@topic)
|
514
|
+
raise ActiveRecord::Rollback
|
515
|
+
end
|
516
|
+
assert_equal [:rollback], @topic.history
|
517
|
+
end
|
518
|
+
end
|