ibm_db 5.6.1 → 5.7.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.
- checksums.yaml +4 -4
- data/ext/Makefile +13 -9
- data/ext/extconf.rb +176 -110
- data/ext/ibm_db.c +60 -0
- data/ext/ibm_db.o +0 -0
- data/ext/ibm_db.so +0 -0
- data/ext/mkmf.log +6 -6
- data/ext/ruby_ibm_db_cli.c +14 -10
- data/ext/ruby_ibm_db_cli.h +4 -0
- data/ext/ruby_ibm_db_cli.o +0 -0
- data/lib/IBM_DB.rb +2 -2
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1254 -277
- data/test/active_record/connection_adapters/fake_legacy_adapter.rb +17 -0
- data/test/active_record/connection_adapters/fake_misleading_legacy_adapter.rb +8 -0
- data/test/activejob/destroy_association_async_job_test.rb +62 -0
- data/test/activejob/destroy_association_async_test.rb +147 -11
- data/test/activejob/job_runtime_test.rb +41 -0
- data/test/activejob/unloadable_base_job.rb +3 -0
- data/test/cases/active_record_schema_test.rb +196 -0
- data/test/cases/active_record_test.rb +21 -0
- data/test/cases/adapter_prevent_writes_test.rb +26 -202
- data/test/cases/adapter_test.rb +592 -82
- data/test/cases/adapters/abstract_mysql_adapter/active_schema_test.rb +210 -0
- data/test/cases/adapters/abstract_mysql_adapter/adapter_prevent_writes_test.rb +111 -0
- data/test/cases/adapters/abstract_mysql_adapter/auto_increment_test.rb +48 -0
- data/test/cases/adapters/abstract_mysql_adapter/bind_parameter_test.rb +91 -0
- data/test/cases/adapters/abstract_mysql_adapter/case_sensitivity_test.rb +65 -0
- data/test/cases/adapters/abstract_mysql_adapter/charset_collation_test.rb +85 -0
- data/test/cases/adapters/abstract_mysql_adapter/connection_test.rb +267 -0
- data/test/cases/adapters/abstract_mysql_adapter/count_deleted_rows_with_lock_test.rb +29 -0
- data/test/cases/adapters/abstract_mysql_adapter/json_test.rb +24 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_boolean_test.rb +102 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_enum_test.rb +47 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_explain_test.rb +71 -0
- data/test/cases/adapters/abstract_mysql_adapter/nested_deadlock_test.rb +191 -0
- data/test/cases/adapters/abstract_mysql_adapter/optimizer_hints_test.rb +69 -0
- data/test/cases/adapters/abstract_mysql_adapter/quoting_test.rb +49 -0
- data/test/cases/adapters/abstract_mysql_adapter/schema_migrations_test.rb +68 -0
- data/test/cases/adapters/abstract_mysql_adapter/schema_test.rb +130 -0
- data/test/cases/adapters/abstract_mysql_adapter/set_test.rb +32 -0
- data/test/cases/adapters/abstract_mysql_adapter/sp_test.rb +39 -0
- data/test/cases/adapters/abstract_mysql_adapter/sql_types_test.rb +16 -0
- data/test/cases/adapters/abstract_mysql_adapter/table_options_test.rb +125 -0
- data/test/cases/adapters/abstract_mysql_adapter/transaction_test.rb +204 -0
- data/test/cases/adapters/abstract_mysql_adapter/unsigned_type_test.rb +77 -0
- data/test/cases/adapters/abstract_mysql_adapter/virtual_column_test.rb +69 -0
- data/test/cases/adapters/abstract_mysql_adapter/warnings_test.rb +109 -0
- data/test/cases/adapters/mysql2/check_constraint_quoting_test.rb +35 -0
- data/test/cases/adapters/mysql2/dbconsole_test.rb +87 -0
- data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +136 -10
- data/test/cases/adapters/mysql2/mysql2_rake_test.rb +433 -0
- data/test/cases/adapters/postgresql/active_schema_test.rb +8 -4
- data/test/cases/adapters/postgresql/array_test.rb +6 -6
- data/test/cases/adapters/postgresql/bind_parameter_test.rb +52 -0
- data/test/cases/adapters/postgresql/bit_string_test.rb +2 -2
- data/test/cases/adapters/postgresql/bytea_test.rb +3 -3
- data/test/cases/adapters/postgresql/case_insensitive_test.rb +1 -1
- data/test/cases/adapters/postgresql/change_schema_test.rb +32 -1
- data/test/cases/adapters/postgresql/cidr_test.rb +17 -0
- data/test/cases/adapters/postgresql/citext_test.rb +7 -1
- data/test/cases/adapters/postgresql/collation_test.rb +1 -1
- data/test/cases/adapters/postgresql/composite_test.rb +1 -1
- data/test/cases/adapters/postgresql/connection_test.rb +43 -36
- data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +3 -2
- data/test/cases/adapters/postgresql/datatype_test.rb +9 -4
- data/test/cases/adapters/postgresql/date_test.rb +2 -2
- data/test/cases/adapters/postgresql/dbconsole_test.rb +109 -0
- data/test/cases/adapters/postgresql/deferred_constraints_test.rb +55 -0
- data/test/cases/adapters/postgresql/domain_test.rb +1 -1
- data/test/cases/adapters/postgresql/enum_test.rb +208 -8
- data/test/cases/adapters/postgresql/explain_test.rb +25 -6
- data/test/cases/adapters/postgresql/extension_migration_test.rb +51 -9
- data/test/cases/adapters/postgresql/foreign_table_test.rb +3 -3
- data/test/cases/adapters/postgresql/full_text_test.rb +1 -1
- data/test/cases/adapters/postgresql/geometric_test.rb +13 -6
- data/test/cases/adapters/postgresql/hstore_test.rb +22 -32
- data/test/cases/adapters/postgresql/infinity_test.rb +13 -2
- data/test/cases/adapters/postgresql/integer_test.rb +1 -1
- data/test/cases/adapters/postgresql/interval_test.rb +9 -17
- data/test/cases/adapters/postgresql/invertible_migration_test.rb +139 -0
- data/test/cases/adapters/postgresql/json_test.rb +5 -0
- data/test/cases/adapters/postgresql/ltree_test.rb +1 -1
- data/test/cases/adapters/postgresql/money_test.rb +17 -9
- data/test/cases/adapters/postgresql/network_test.rb +13 -1
- data/test/cases/adapters/postgresql/numbers_test.rb +18 -2
- data/test/cases/adapters/postgresql/optimizer_hints_test.rb +9 -9
- data/test/cases/adapters/postgresql/partitions_test.rb +5 -2
- data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +7 -110
- data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +403 -20
- data/test/cases/adapters/postgresql/postgresql_rake_test.rb +637 -0
- data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +1 -1
- data/test/cases/adapters/postgresql/quoting_test.rb +60 -1
- data/test/cases/adapters/postgresql/range_test.rb +185 -21
- data/test/cases/adapters/postgresql/referential_integrity_test.rb +29 -5
- data/test/cases/adapters/postgresql/rename_table_test.rb +35 -8
- data/test/cases/adapters/postgresql/schema_authorization_test.rb +2 -2
- data/test/cases/adapters/postgresql/schema_test.rb +270 -20
- data/test/cases/adapters/postgresql/serial_test.rb +5 -5
- data/test/cases/adapters/postgresql/statement_pool_test.rb +6 -2
- data/test/cases/adapters/postgresql/timestamp_test.rb +122 -5
- data/test/cases/adapters/postgresql/transaction_nested_test.rb +130 -6
- data/test/cases/adapters/postgresql/transaction_test.rb +37 -11
- data/test/cases/adapters/postgresql/type_lookup_test.rb +1 -1
- data/test/cases/adapters/postgresql/uuid_test.rb +77 -9
- data/test/cases/adapters/postgresql/virtual_column_test.rb +114 -0
- data/test/cases/adapters/postgresql/xml_test.rb +1 -1
- data/test/cases/adapters/sqlite3/bind_parameter_test.rb +52 -0
- data/test/cases/adapters/sqlite3/collation_test.rb +1 -1
- data/test/cases/adapters/sqlite3/copy_table_test.rb +28 -7
- data/test/cases/adapters/sqlite3/dbconsole_test.rb +81 -0
- data/test/cases/adapters/sqlite3/explain_test.rb +3 -3
- data/test/cases/adapters/sqlite3/quoting_test.rb +34 -3
- data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +9 -102
- data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +727 -72
- data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +6 -3
- data/test/cases/adapters/sqlite3/sqlite_rake_test.rb +264 -0
- data/test/cases/adapters/sqlite3/statement_pool_test.rb +1 -1
- data/test/cases/adapters/sqlite3/transaction_test.rb +6 -3
- data/test/cases/adapters/sqlite3/virtual_column_test.rb +138 -0
- data/test/cases/adapters/sqlite3/virtual_table_test.rb +51 -0
- data/test/cases/adapters/trilogy/dbconsole_test.rb +76 -0
- data/test/cases/adapters/trilogy/trilogy_adapter_test.rb +473 -0
- data/test/cases/adapters/trilogy/trilogy_rake_test.rb +433 -0
- data/test/cases/aggregations_test.rb +16 -0
- data/test/cases/annotate_test.rb +14 -12
- data/test/cases/arel/attributes/attribute_test.rb +86 -47
- data/test/cases/arel/collectors/bind_test.rb +1 -1
- data/test/cases/arel/collectors/composite_test.rb +11 -1
- data/test/cases/arel/collectors/sql_string_test.rb +1 -1
- data/test/cases/arel/collectors/substitute_bind_collector_test.rb +1 -1
- data/test/cases/arel/delete_manager_test.rb +0 -6
- data/test/cases/arel/factory_methods_test.rb +45 -0
- data/test/cases/arel/insert_manager_test.rb +1 -7
- data/test/cases/arel/nodes/as_test.rb +12 -0
- data/test/cases/arel/nodes/ascending_test.rb +1 -1
- data/test/cases/arel/nodes/bin_test.rb +1 -1
- data/test/cases/arel/nodes/bound_sql_literal_test.rb +31 -0
- data/test/cases/arel/nodes/cte_test.rb +46 -0
- data/test/cases/arel/nodes/descending_test.rb +1 -1
- data/test/cases/arel/nodes/equality_test.rb +3 -3
- data/test/cases/arel/nodes/filter_test.rb +37 -0
- data/test/cases/arel/nodes/fragments_test.rb +38 -0
- data/test/cases/arel/nodes/homogeneous_in_test.rb +52 -0
- data/test/cases/arel/nodes/infix_operation_test.rb +1 -1
- data/test/cases/arel/nodes/node_test.rb +1 -1
- data/test/cases/arel/nodes/or_test.rb +2 -2
- data/test/cases/arel/nodes/sql_literal_test.rb +18 -1
- data/test/cases/arel/nodes/table_alias_test.rb +12 -0
- data/test/cases/arel/nodes/unary_operation_test.rb +1 -1
- data/test/cases/arel/nodes/update_statement_test.rb +4 -0
- data/test/cases/arel/nodes_test.rb +3 -2
- data/test/cases/arel/select_manager_test.rb +12 -12
- data/test/cases/arel/support/fake_record.rb +22 -17
- data/test/cases/arel/table_test.rb +15 -25
- data/test/cases/arel/update_manager_test.rb +51 -6
- data/test/cases/arel/visitors/dispatch_contamination_test.rb +1 -1
- data/test/cases/arel/visitors/dot_test.rb +177 -2
- data/test/cases/arel/visitors/mysql_test.rb +49 -1
- data/test/cases/arel/visitors/postgres_test.rb +1 -31
- data/test/cases/arel/visitors/sqlite_test.rb +1 -1
- data/test/cases/arel/visitors/to_sql_test.rb +330 -20
- data/test/cases/assertions/query_assertions_test.rb +136 -0
- data/test/cases/associations/belongs_to_associations_test.rb +502 -41
- data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +1 -1
- data/test/cases/associations/cascaded_eager_loading_test.rb +26 -15
- data/test/cases/associations/eager_load_nested_include_test.rb +1 -1
- data/test/cases/associations/eager_singularization_test.rb +1 -1
- data/test/cases/associations/eager_test.rb +255 -93
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +25 -53
- data/test/cases/associations/has_many_associations_test.rb +282 -72
- data/test/cases/associations/has_many_through_associations_test.rb +172 -45
- data/test/cases/associations/has_many_through_disable_joins_associations_test.rb +197 -0
- data/test/cases/associations/has_one_associations_test.rb +160 -29
- data/test/cases/associations/has_one_through_associations_test.rb +64 -15
- data/test/cases/associations/has_one_through_disable_joins_associations_test.rb +82 -0
- data/test/cases/associations/inner_join_association_test.rb +36 -6
- data/test/cases/associations/inverse_associations_test.rb +177 -40
- data/test/cases/associations/join_model_test.rb +17 -12
- data/test/cases/associations/left_outer_join_association_test.rb +14 -3
- data/test/cases/associations/nested_error_test.rb +116 -0
- data/test/cases/associations/nested_through_associations_test.rb +54 -19
- data/test/cases/associations/required_test.rb +1 -1
- data/test/cases/associations_test.rb +1278 -21
- data/test/cases/asynchronous_queries_test.rb +310 -0
- data/test/cases/attribute_methods/read_test.rb +6 -0
- data/test/cases/attribute_methods/time_zone_converter_test.rb +21 -0
- data/test/cases/attribute_methods_test.rb +565 -46
- data/test/cases/attributes_test.rb +42 -1
- data/test/cases/autosave_association_test.rb +645 -92
- data/test/cases/base_prevent_writes_test.rb +28 -159
- data/test/cases/base_test.rb +434 -209
- data/test/cases/batches_test.rb +441 -57
- data/test/cases/binary_test.rb +31 -0
- data/test/cases/bind_parameter_test.rb +107 -16
- data/test/cases/cache_key_test.rb +7 -7
- data/test/cases/calculations_test.rb +541 -110
- data/test/cases/callbacks_test.rb +0 -1
- data/test/cases/clone_test.rb +5 -4
- data/test/cases/coders/yaml_column_test.rb +97 -2
- data/test/cases/collection_cache_key_test.rb +24 -16
- data/test/cases/column_alias_test.rb +2 -8
- data/test/cases/column_definition_test.rb +12 -3
- data/test/cases/comment_test.rb +23 -26
- data/test/cases/connection_adapters/adapter_leasing_test.rb +9 -9
- data/test/cases/connection_adapters/connection_handler_test.rb +145 -99
- data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +79 -55
- data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +17 -20
- data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +146 -55
- data/test/cases/connection_adapters/connection_swapping_nested_test.rb +136 -23
- data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +96 -27
- data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -5
- data/test/cases/connection_adapters/registration_test.rb +98 -0
- data/test/cases/connection_adapters/schema_cache_test.rb +288 -135
- data/test/cases/connection_adapters/standalone_connection_test.rb +38 -0
- data/test/cases/connection_adapters/statement_pool_test.rb +29 -0
- data/test/cases/connection_adapters/type_lookup_test.rb +12 -24
- data/test/cases/connection_handling_test.rb +210 -0
- data/test/cases/connection_management_test.rb +44 -7
- data/test/cases/connection_pool_test.rb +466 -99
- data/test/cases/core_test.rb +167 -9
- data/test/cases/counter_cache_test.rb +129 -2
- data/test/cases/custom_locking_test.rb +3 -3
- data/test/cases/database_configurations/hash_config_test.rb +149 -13
- data/test/cases/database_configurations/resolver_test.rb +14 -10
- data/test/cases/database_configurations/url_config_test.rb +53 -0
- data/test/cases/database_configurations_test.rb +86 -43
- data/test/cases/database_selector_test.rb +30 -8
- data/test/cases/database_statements_test.rb +10 -14
- data/test/cases/date_time_precision_test.rb +141 -11
- data/test/cases/date_time_test.rb +19 -1
- data/test/cases/defaults_test.rb +107 -41
- data/test/cases/delegated_type_test.rb +69 -9
- data/test/cases/dirty_test.rb +82 -25
- data/test/cases/disconnected_test.rb +10 -9
- data/test/cases/dup_test.rb +26 -6
- data/test/cases/encryption/cipher/aes256_gcm_test.rb +50 -0
- data/test/cases/encryption/cipher_test.rb +65 -0
- data/test/cases/encryption/concurrency_test.rb +27 -0
- data/test/cases/encryption/config_test.rb +21 -0
- data/test/cases/encryption/configurable_test.rb +93 -0
- data/test/cases/encryption/contexts_test.rb +105 -0
- data/test/cases/encryption/derived_secret_key_provider_test.rb +31 -0
- data/test/cases/encryption/deterministic_key_provider_test.rb +11 -0
- data/test/cases/encryption/encryptable_record_api_test.rb +175 -0
- data/test/cases/encryption/encryptable_record_message_pack_serialized_test.rb +42 -0
- data/test/cases/encryption/encryptable_record_test.rb +470 -0
- data/test/cases/encryption/encrypted_fixtures_test.rb +22 -0
- data/test/cases/encryption/encrypting_only_encryptor_test.rb +20 -0
- data/test/cases/encryption/encryption_schemes_test.rb +240 -0
- data/test/cases/encryption/encryptor_test.rb +113 -0
- data/test/cases/encryption/envelope_encryption_key_provider_test.rb +49 -0
- data/test/cases/encryption/extended_deterministic_queries_test.rb +81 -0
- data/test/cases/encryption/helper.rb +152 -0
- data/test/cases/encryption/key_generator_test.rb +55 -0
- data/test/cases/encryption/key_provider_test.rb +57 -0
- data/test/cases/encryption/key_test.rb +17 -0
- data/test/cases/encryption/message_pack_message_serializer_test.rb +70 -0
- data/test/cases/encryption/message_serializer_test.rb +82 -0
- data/test/cases/encryption/message_test.rb +43 -0
- data/test/cases/encryption/null_encryptor_test.rb +21 -0
- data/test/cases/encryption/properties_test.rb +69 -0
- data/test/cases/encryption/read_only_null_encryptor_test.rb +19 -0
- data/test/cases/encryption/scheme_test.rb +58 -0
- data/test/cases/encryption/unencrypted_attributes_test.rb +27 -0
- data/test/cases/encryption/uniqueness_validations_test.rb +65 -0
- data/test/cases/enum_test.rb +374 -72
- data/test/cases/errors_test.rb +7 -4
- data/test/cases/excluding_test.rb +116 -0
- data/test/cases/explain_subscriber_test.rb +6 -1
- data/test/cases/explain_test.rb +119 -10
- data/test/cases/filter_attributes_test.rb +7 -14
- data/test/cases/finder_respond_to_test.rb +3 -3
- data/test/cases/finder_test.rb +357 -72
- data/test/cases/fixture_set/file_test.rb +9 -0
- data/test/cases/fixtures_test.rb +426 -190
- data/test/cases/helper.rb +66 -192
- data/test/cases/hot_compatibility_test.rb +10 -10
- data/test/cases/inheritance_test.rb +51 -61
- data/test/cases/inherited_test.rb +40 -0
- data/test/cases/insert_all_test.rb +419 -9
- data/test/cases/instrumentation_test.rb +202 -30
- data/test/cases/integration_test.rb +25 -7
- data/test/cases/invalid_connection_test.rb +5 -5
- data/test/cases/invertible_migration_test.rb +108 -24
- data/test/cases/json_attribute_test.rb +1 -0
- data/test/cases/json_serialization_test.rb +5 -5
- data/test/cases/json_shared_test_cases.rb +5 -9
- data/test/cases/locking_test.rb +67 -31
- data/test/cases/log_subscriber_test.rb +17 -15
- data/test/cases/marshal_serialization_test.rb +78 -5
- data/test/cases/message_pack_test.rb +91 -0
- data/test/cases/migration/change_schema_test.rb +77 -46
- data/test/cases/migration/change_table_test.rb +129 -114
- data/test/cases/migration/check_constraint_test.rb +192 -10
- data/test/cases/migration/column_attributes_test.rb +4 -9
- data/test/cases/migration/column_positioning_test.rb +2 -2
- data/test/cases/migration/columns_test.rb +118 -4
- data/test/cases/migration/command_recorder_test.rb +181 -14
- data/test/cases/migration/compatibility_test.rb +883 -196
- data/test/cases/migration/create_join_table_test.rb +8 -1
- data/test/cases/migration/exclusion_constraint_test.rb +192 -0
- data/test/cases/migration/foreign_key_test.rb +356 -14
- data/test/cases/migration/helper.rb +4 -1
- data/test/cases/migration/index_test.rb +67 -2
- data/test/cases/migration/invalid_options_test.rb +129 -0
- data/test/cases/migration/logger_test.rb +7 -4
- data/test/cases/migration/pending_migrations_test.rb +103 -60
- data/test/cases/migration/references_foreign_key_test.rb +73 -4
- data/test/cases/migration/references_index_test.rb +25 -27
- data/test/cases/migration/references_statements_test.rb +27 -3
- data/test/cases/migration/rename_table_test.rb +39 -54
- data/test/cases/migration/schema_definitions_test.rb +109 -0
- data/test/cases/migration/unique_constraint_test.rb +248 -0
- data/test/cases/migration_test.rb +677 -220
- data/test/cases/migrator_test.rb +102 -75
- data/test/cases/multi_db_migrator_test.rb +55 -34
- data/test/cases/multiparameter_attributes_test.rb +26 -29
- data/test/cases/multiple_db_test.rb +42 -19
- data/test/cases/nested_attributes_test.rb +124 -6
- data/test/cases/nested_attributes_with_callbacks_test.rb +2 -2
- data/test/cases/normalized_attribute_test.rb +117 -0
- data/test/cases/null_relation_test.rb +35 -2
- data/test/cases/persistence/reload_association_cache_test.rb +20 -0
- data/test/cases/persistence_test.rb +629 -22
- data/test/cases/pooled_connections_test.rb +57 -56
- data/test/cases/prepared_statement_status_test.rb +8 -3
- data/test/cases/primary_class_test.rb +134 -0
- data/test/cases/primary_keys_test.rb +171 -55
- data/test/cases/query_cache_test.rb +558 -263
- data/test/cases/query_logs_test.rb +293 -0
- data/test/cases/quoting_test.rb +39 -72
- data/test/cases/readonly_test.rb +50 -12
- data/test/cases/reaper_test.rb +22 -6
- data/test/cases/reflection_test.rb +207 -9
- data/test/cases/relation/and_test.rb +43 -0
- data/test/cases/relation/delegation_test.rb +32 -5
- data/test/cases/relation/delete_all_test.rb +27 -6
- data/test/cases/relation/field_ordered_values_test.rb +128 -0
- data/test/cases/relation/load_async_test.rb +650 -0
- data/test/cases/relation/merging_test.rb +80 -109
- data/test/cases/relation/mutation_test.rb +12 -7
- data/test/cases/relation/or_test.rb +11 -8
- data/test/cases/relation/order_test.rb +90 -0
- data/test/cases/relation/predicate_builder_test.rb +21 -6
- data/test/cases/relation/select_test.rb +162 -3
- data/test/cases/relation/structural_compatibility_test.rb +38 -0
- data/test/cases/relation/update_all_test.rb +81 -27
- data/test/cases/relation/where_chain_test.rb +190 -3
- data/test/cases/relation/where_clause_test.rb +43 -1
- data/test/cases/relation/where_test.rb +95 -7
- data/test/cases/relation/with_test.rb +165 -0
- data/test/cases/relation_test.rb +42 -37
- data/test/cases/relations_test.rb +436 -138
- data/test/cases/reload_models_test.rb +18 -14
- data/test/cases/reserved_word_test.rb +2 -1
- data/test/cases/result_test.rb +14 -22
- data/test/cases/sanitize_test.rb +89 -27
- data/test/cases/schema_dumper_test.rb +535 -62
- data/test/cases/scoping/default_scoping_test.rb +219 -35
- data/test/cases/scoping/named_scoping_test.rb +25 -46
- data/test/cases/scoping/relation_scoping_test.rb +112 -4
- data/test/cases/secure_password_test.rb +108 -0
- data/test/cases/secure_token_test.rb +72 -0
- data/test/cases/serialization_test.rb +1 -1
- data/test/cases/serialized_attribute_test.rb +305 -60
- data/test/cases/shard_keys_test.rb +125 -0
- data/test/cases/shard_selector_test.rb +45 -0
- data/test/cases/signed_id_test.rb +57 -5
- data/test/cases/statement_cache_test.rb +31 -30
- data/test/cases/statement_invalid_test.rb +8 -4
- data/test/cases/store_test.rb +73 -9
- data/test/cases/strict_loading_test.rb +327 -13
- data/test/cases/table_metadata_test.rb +16 -0
- data/test/cases/tasks/database_tasks_test.rb +517 -244
- data/test/cases/test_case.rb +254 -60
- data/test/cases/test_case_test.rb +69 -0
- data/test/cases/test_databases_test.rb +7 -3
- data/test/cases/test_fixtures_test.rb +19 -40
- data/test/cases/time_precision_test.rb +17 -5
- data/test/cases/timestamp_test.rb +124 -16
- data/test/cases/token_for_test.rb +165 -0
- data/test/cases/touch_later_test.rb +43 -1
- data/test/cases/transaction_callbacks_test.rb +325 -8
- data/test/cases/transaction_instrumentation_test.rb +453 -0
- data/test/cases/transaction_isolation_test.rb +12 -8
- data/test/cases/transactions_test.rb +629 -112
- data/test/cases/type/date_time_test.rb +7 -1
- data/test/cases/type/time_test.rb +9 -0
- data/test/cases/type/type_map_test.rb +108 -73
- data/test/cases/type/unsigned_integer_test.rb +12 -0
- data/test/cases/type_caster/connection_test.rb +19 -0
- data/test/cases/type_test.rb +1 -1
- data/test/cases/unconnected_test.rb +7 -7
- data/test/cases/unsafe_raw_sql_test.rb +39 -8
- data/test/cases/validations/absence_validation_test.rb +1 -1
- data/test/cases/validations/association_validation_test.rb +25 -3
- data/test/cases/validations/numericality_validation_test.rb +3 -9
- data/test/cases/validations/presence_validation_test.rb +1 -1
- data/test/cases/validations/uniqueness_validation_test.rb +280 -40
- data/test/cases/validations_test.rb +2 -2
- data/test/cases/view_test.rb +33 -22
- data/test/cases/yaml_serialization_test.rb +23 -17
- data/test/config.example.yml +58 -56
- data/test/config.rb +1 -0
- data/test/fixtures/1_need_quoting.yml +2 -0
- data/test/fixtures/accounts.yml +5 -0
- data/test/fixtures/aircrafts.yml +7 -0
- data/test/fixtures/book_identifiers.yml +11 -0
- data/test/fixtures/books.yml +5 -4
- data/test/fixtures/cake_designers.yml +5 -0
- data/test/fixtures/cars.yml +6 -0
- data/test/fixtures/chefs.yml +5 -0
- data/test/fixtures/clothing_items.yml +23 -0
- data/test/fixtures/clubs.yml +1 -1
- data/test/fixtures/comments.yml +2 -1
- data/test/fixtures/cpk_authors.yml +8 -0
- data/test/fixtures/cpk_books.yml +21 -0
- data/test/fixtures/cpk_order_agreements.yml +13 -0
- data/test/fixtures/cpk_order_tags.yml +15 -0
- data/test/fixtures/cpk_orders.yml +11 -0
- data/test/fixtures/cpk_posts.yml +12 -0
- data/test/fixtures/cpk_reviews.yml +13 -0
- data/test/fixtures/cpk_tags.yml +11 -0
- data/test/fixtures/drink_designers.yml +5 -0
- data/test/fixtures/encrypted_book_that_ignores_cases.yml +4 -0
- data/test/fixtures/encrypted_books.yml +4 -0
- data/test/fixtures/fk_object_to_point_to.yml +2 -0
- data/test/fixtures/memberships.yml +15 -15
- data/test/fixtures/paragraphs.yml +5 -0
- data/test/fixtures/parrots.yml +4 -0
- data/test/fixtures/people.yml +2 -0
- data/test/fixtures/pirates.yml +2 -2
- data/test/fixtures/primary_key_error/primary_key_error.yml +6 -0
- data/test/fixtures/references.yml +3 -3
- data/test/fixtures/sharded_blog_posts.yml +14 -0
- data/test/fixtures/sharded_blog_posts_tags.yml +27 -0
- data/test/fixtures/sharded_blogs.yml +8 -0
- data/test/fixtures/sharded_comments.yml +22 -0
- data/test/fixtures/sharded_tags.yml +34 -0
- data/test/fixtures/sponsors.yml +2 -2
- data/test/fixtures/topics.yml +1 -0
- data/test/fixtures/treasures.yml +4 -0
- data/test/fixtures/virtual_columns.yml +5 -0
- data/test/fixtures/warehouse_things.yml +1 -1
- data/test/migrations/old_and_new_versions/20210716122844_add_people_description.rb +5 -0
- data/test/migrations/old_and_new_versions/20210716123013_add_people_number_of_legs.rb +5 -0
- data/test/migrations/old_and_new_versions/230_add_people_hobby.rb +5 -0
- data/test/migrations/old_and_new_versions/231_add_people_last_name.rb +5 -0
- data/test/migrations/scope/1_unscoped.rb +7 -0
- data/test/migrations/scope/2_mysql_only.mysql.rb +7 -0
- data/test/models/admin/user.rb +2 -0
- data/test/models/admin/user_json.rb +48 -0
- data/test/models/attachment.rb +7 -0
- data/test/models/author.rb +70 -3
- data/test/models/author_encrypted.rb +16 -0
- data/test/models/bird.rb +1 -1
- data/test/models/book.rb +18 -11
- data/test/models/book_destroy_async.rb +1 -1
- data/test/models/book_encrypted.rb +106 -0
- data/test/models/book_identifier.rb +5 -0
- data/test/models/branch.rb +11 -0
- data/test/models/bulb.rb +1 -1
- data/test/models/car.rb +8 -1
- data/test/models/cat.rb +1 -1
- data/test/models/category.rb +3 -1
- data/test/models/chat_message.rb +8 -0
- data/test/models/chef.rb +52 -0
- data/test/models/clothing_item.rb +12 -0
- data/test/models/club.rb +4 -1
- data/test/models/comment.rb +7 -4
- data/test/models/comment_overlapping_counter_cache.rb +15 -0
- data/test/models/company.rb +16 -2
- data/test/models/computer.rb +1 -0
- data/test/models/contact.rb +3 -3
- data/test/models/contract.rb +5 -1
- data/test/models/cpk/author.rb +9 -0
- data/test/models/cpk/book.rb +55 -0
- data/test/models/cpk/book_destroy_async.rb +9 -0
- data/test/models/cpk/car.rb +9 -0
- data/test/models/cpk/car_review.rb +9 -0
- data/test/models/cpk/chapter.rb +16 -0
- data/test/models/cpk/chapter_destroy_async.rb +10 -0
- data/test/models/cpk/comment.rb +9 -0
- data/test/models/cpk/order.rb +55 -0
- data/test/models/cpk/order_agreement.rb +10 -0
- data/test/models/cpk/order_tag.rb +10 -0
- data/test/models/cpk/post.rb +10 -0
- data/test/models/cpk/posts_tag.rb +10 -0
- data/test/models/cpk/review.rb +9 -0
- data/test/models/cpk/tag.rb +10 -0
- data/test/models/cpk.rb +15 -0
- data/test/models/customer.rb +3 -1
- data/test/models/destroy_async_parent.rb +1 -1
- data/test/models/developer.rb +44 -3
- data/test/models/discount.rb +4 -0
- data/test/models/drink_designer.rb +1 -0
- data/test/models/editor.rb +8 -0
- data/test/models/editorship.rb +6 -0
- data/test/models/entry.rb +5 -0
- data/test/models/essay.rb +6 -1
- data/test/models/essay_destroy_async.rb +1 -0
- data/test/models/eye.rb +87 -21
- data/test/models/face.rb +1 -1
- data/test/models/friendship.rb +3 -0
- data/test/models/hardback.rb +7 -0
- data/test/models/hotel.rb +2 -0
- data/test/models/human.rb +2 -2
- data/test/models/invoice.rb +2 -1
- data/test/models/invokes_an_undefined_method.rb +5 -0
- data/test/models/line_item.rb +6 -0
- data/test/models/member.rb +9 -4
- data/test/models/membership.rb +2 -2
- data/test/models/message.rb +2 -1
- data/test/models/need_quoting.rb +5 -0
- data/test/models/paragraph.rb +5 -0
- data/test/models/parrot.rb +6 -3
- data/test/models/person.rb +7 -4
- data/test/models/pirate.rb +4 -1
- data/test/models/pk_autopopulated_by_a_trigger_record.rb +5 -0
- data/test/models/post.rb +65 -2
- data/test/models/post_encrypted.rb +15 -0
- data/test/models/post_with_prefetched_pk.rb +15 -0
- data/test/models/project.rb +1 -0
- data/test/models/publication.rb +16 -0
- data/test/models/raises_argument_error.rb +5 -0
- data/test/models/raises_no_method_error.rb +5 -0
- data/test/models/recipient.rb +5 -0
- data/test/models/reference.rb +1 -1
- data/test/models/reply.rb +1 -1
- data/test/models/room.rb +3 -0
- data/test/models/sharded/blog.rb +12 -0
- data/test/models/sharded/blog_post.rb +17 -0
- data/test/models/sharded/blog_post_destroy_async.rb +14 -0
- data/test/models/sharded/blog_post_tag.rb +11 -0
- data/test/models/sharded/blog_post_with_revision.rb +11 -0
- data/test/models/sharded/comment.rb +12 -0
- data/test/models/sharded/comment_destroy_async.rb +12 -0
- data/test/models/sharded/tag.rb +11 -0
- data/test/models/sharded.rb +8 -0
- data/test/models/ship.rb +1 -1
- data/test/models/shipping_line.rb +11 -0
- data/test/models/subscriber.rb +1 -0
- data/test/models/subscription.rb +3 -1
- data/test/models/too_long_table_name.rb +5 -0
- data/test/models/topic.rb +3 -1
- data/test/models/traffic_light.rb +2 -2
- data/test/models/traffic_light_encrypted.rb +21 -0
- data/test/models/translation.rb +9 -0
- data/test/models/treasure.rb +1 -1
- data/test/models/tyre.rb +1 -1
- data/test/models/user.rb +16 -0
- data/test/models/user_with_invalid_relation.rb +28 -0
- data/test/models/uuid_comment.rb +5 -0
- data/test/models/uuid_entry.rb +5 -0
- data/test/models/uuid_message.rb +5 -0
- data/test/models/zine.rb +2 -1
- data/test/schema/mysql2_specific_schema.rb +26 -12
- data/test/schema/postgresql_specific_schema.rb +121 -13
- data/test/schema/schema.rb +361 -103
- data/test/schema/sqlite_specific_schema.rb +17 -6
- data/test/schema/trilogy_specific_schema.rb +96 -0
- data/test/support/adapter_helper.rb +104 -0
- data/test/support/async_helper.rb +15 -0
- data/test/support/config.rb +1 -1
- data/test/support/connection.rb +14 -2
- data/test/support/ddl_helper.rb +1 -1
- data/test/support/fake_adapter.rb +42 -0
- data/test/support/load_schema_helper.rb +22 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic_associations.dump +0 -0
- data/test/support/schema_dumping_helper.rb +15 -9
- data/test/support/tools.rb +37 -0
- data/test/support/yaml_compatibility_fixtures/rails_4_1_no_symbol.yml +22 -0
- metadata +247 -15
|
@@ -9,15 +9,208 @@ require "models/book"
|
|
|
9
9
|
require "models/author"
|
|
10
10
|
require "models/post"
|
|
11
11
|
require "models/movie"
|
|
12
|
+
require "models/cpk"
|
|
13
|
+
|
|
14
|
+
module TransactionCallbacksTests
|
|
15
|
+
SomeError = Class.new(StandardError)
|
|
16
|
+
|
|
17
|
+
def test_transaction_open?
|
|
18
|
+
assert_predicate Topic.current_transaction, :closed?
|
|
19
|
+
|
|
20
|
+
committed_transaction = nil
|
|
21
|
+
Topic.transaction do
|
|
22
|
+
assert_predicate Topic.current_transaction, :open?
|
|
23
|
+
committed_transaction = Topic.current_transaction
|
|
24
|
+
end
|
|
25
|
+
assert_predicate committed_transaction, :closed?
|
|
26
|
+
|
|
27
|
+
rolledback_transaction = nil
|
|
28
|
+
assert_raises SomeError do
|
|
29
|
+
Topic.transaction do
|
|
30
|
+
assert_predicate Topic.current_transaction, :open?
|
|
31
|
+
rolledback_transaction = Topic.current_transaction
|
|
32
|
+
raise SomeError
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
assert_predicate rolledback_transaction, :closed?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_after_all_transactions_commit
|
|
39
|
+
skip "IBM_DB finalizes invalidated transactions before after_all_transactions_commit callback registration" if current_adapter?(:IBM_DBAdapter)
|
|
40
|
+
|
|
41
|
+
called = 0
|
|
42
|
+
ActiveRecord.after_all_transactions_commit { called += 1 }
|
|
43
|
+
assert_equal 1, called
|
|
44
|
+
|
|
45
|
+
ActiveRecord.after_all_transactions_commit { called += 1 }
|
|
46
|
+
assert_equal 2, called
|
|
47
|
+
|
|
48
|
+
called = 0
|
|
49
|
+
Topic.transaction do
|
|
50
|
+
ActiveRecord.after_all_transactions_commit { called += 1 }
|
|
51
|
+
assert_equal 0, called
|
|
52
|
+
end
|
|
53
|
+
assert_equal 1, called
|
|
54
|
+
|
|
55
|
+
called = 0
|
|
56
|
+
Topic.transaction do
|
|
57
|
+
Topic.transaction(requires_new: true) do
|
|
58
|
+
ActiveRecord.after_all_transactions_commit { called += 1 }
|
|
59
|
+
assert_equal 0, called
|
|
60
|
+
end
|
|
61
|
+
assert_equal 0, called
|
|
62
|
+
end
|
|
63
|
+
assert_equal 1, called
|
|
64
|
+
|
|
65
|
+
called = 0
|
|
66
|
+
Topic.transaction do
|
|
67
|
+
ActiveRecord.after_all_transactions_commit { called += 1 }
|
|
68
|
+
assert_equal 0, called
|
|
69
|
+
raise ActiveRecord::Rollback
|
|
70
|
+
end
|
|
71
|
+
assert_equal 0, called
|
|
72
|
+
|
|
73
|
+
called = 0
|
|
74
|
+
Topic.transaction do |transaction|
|
|
75
|
+
transaction.instance_variable_get(:@internal_transaction).invalidate!
|
|
76
|
+
ActiveRecord.after_all_transactions_commit { called += 1 }
|
|
77
|
+
assert_equal 1, called
|
|
78
|
+
end
|
|
79
|
+
assert_equal 1, called
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def test_after_current_transaction_commit_multidb_nested_transactions
|
|
83
|
+
called = 0
|
|
84
|
+
ARUnit2Model.transaction do
|
|
85
|
+
Topic.transaction do
|
|
86
|
+
ActiveRecord.after_all_transactions_commit { called += 1 }
|
|
87
|
+
assert_equal 0, called
|
|
88
|
+
end
|
|
89
|
+
assert_equal 0, called
|
|
90
|
+
end
|
|
91
|
+
assert_equal 1, called
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def test_transaction_after_commit_callback
|
|
95
|
+
called = 0
|
|
96
|
+
Topic.current_transaction.after_commit { called += 1 }
|
|
97
|
+
assert_equal 1, called
|
|
98
|
+
|
|
99
|
+
Topic.current_transaction.after_commit { called += 1 }
|
|
100
|
+
assert_equal 2, called
|
|
101
|
+
|
|
102
|
+
called = 0
|
|
103
|
+
Topic.transaction do
|
|
104
|
+
Topic.current_transaction.after_commit { called += 1 }
|
|
105
|
+
assert_equal 0, called
|
|
106
|
+
end
|
|
107
|
+
assert_equal 1, called
|
|
108
|
+
|
|
109
|
+
called = 0
|
|
110
|
+
Topic.transaction do
|
|
111
|
+
Topic.transaction(requires_new: true) do
|
|
112
|
+
Topic.current_transaction.after_commit { called += 1 }
|
|
113
|
+
assert_equal 0, called
|
|
114
|
+
end
|
|
115
|
+
assert_equal 0, called
|
|
116
|
+
end
|
|
117
|
+
assert_equal 1, called
|
|
118
|
+
|
|
119
|
+
called = 0
|
|
120
|
+
Topic.transaction do
|
|
121
|
+
Topic.current_transaction.after_commit { called += 1 }
|
|
122
|
+
assert_equal 0, called
|
|
123
|
+
raise ActiveRecord::Rollback
|
|
124
|
+
end
|
|
125
|
+
assert_equal 0, called
|
|
126
|
+
|
|
127
|
+
called = 0
|
|
128
|
+
ARUnit2Model.transaction do
|
|
129
|
+
Topic.transaction do
|
|
130
|
+
Topic.current_transaction.after_commit { called += 1 }
|
|
131
|
+
assert_equal 0, called
|
|
132
|
+
end
|
|
133
|
+
assert_equal 1, called
|
|
134
|
+
end
|
|
135
|
+
assert_equal 1, called
|
|
136
|
+
|
|
137
|
+
committed_transaction = nil
|
|
138
|
+
Topic.transaction do
|
|
139
|
+
committed_transaction = Topic.current_transaction
|
|
140
|
+
end
|
|
141
|
+
assert_raises ActiveRecord::ActiveRecordError, match: /Cannot register callbacks on a finalized transaction/ do
|
|
142
|
+
committed_transaction.after_commit { nil }
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def test_transaction_after_rollback_callback
|
|
147
|
+
called = 0
|
|
148
|
+
Topic.current_transaction.after_rollback { called += 1 }
|
|
149
|
+
assert_equal 0, called
|
|
150
|
+
|
|
151
|
+
called = 0
|
|
152
|
+
Topic.transaction do
|
|
153
|
+
Topic.current_transaction.after_rollback { called += 1 }
|
|
154
|
+
assert_equal 0, called
|
|
155
|
+
end
|
|
156
|
+
assert_equal 0, called
|
|
157
|
+
|
|
158
|
+
called = 0
|
|
159
|
+
Topic.transaction do
|
|
160
|
+
Topic.current_transaction.after_rollback { called += 1 }
|
|
161
|
+
assert_equal 0, called
|
|
162
|
+
raise ActiveRecord::Rollback
|
|
163
|
+
end
|
|
164
|
+
assert_equal 1, called
|
|
165
|
+
|
|
166
|
+
called = 0
|
|
167
|
+
Topic.transaction do
|
|
168
|
+
Topic.current_transaction.after_rollback { called += 1 }
|
|
169
|
+
Topic.transaction(requires_new: true) do
|
|
170
|
+
raise ActiveRecord::Rollback
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
assert_equal 0, called
|
|
174
|
+
|
|
175
|
+
called = 0
|
|
176
|
+
Topic.transaction do
|
|
177
|
+
assert_nothing_raised do
|
|
178
|
+
Topic.transaction(requires_new: true) do
|
|
179
|
+
Topic.current_transaction.after_rollback { called += 1 }
|
|
180
|
+
raise ActiveRecord::Rollback
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
assert_equal 1, called
|
|
184
|
+
end
|
|
185
|
+
assert_equal 1, called
|
|
186
|
+
|
|
187
|
+
committed_transaction = nil
|
|
188
|
+
Topic.transaction do
|
|
189
|
+
committed_transaction = Topic.current_transaction
|
|
190
|
+
end
|
|
191
|
+
assert_raises ActiveRecord::ActiveRecordError, match: /Cannot register callbacks on a finalized transaction/ do
|
|
192
|
+
committed_transaction.after_rollback { nil }
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
12
196
|
|
|
13
197
|
class TransactionTest < ActiveRecord::TestCase
|
|
14
198
|
self.use_transactional_tests = false
|
|
15
199
|
fixtures :topics, :developers, :authors, :author_addresses, :posts
|
|
16
200
|
|
|
201
|
+
include TransactionCallbacksTests
|
|
202
|
+
|
|
17
203
|
def setup
|
|
18
204
|
@first, @second = Topic.find(1, 2).sort_by(&:id)
|
|
19
205
|
end
|
|
20
206
|
|
|
207
|
+
def test_blank?
|
|
208
|
+
assert_predicate Topic.current_transaction, :blank?
|
|
209
|
+
Topic.transaction do
|
|
210
|
+
assert_not_predicate Topic.current_transaction, :blank?
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
21
214
|
def test_rollback_dirty_changes
|
|
22
215
|
topic = topics(:fifth)
|
|
23
216
|
|
|
@@ -30,13 +223,21 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
30
223
|
assert_equal title_change, topic.changes["title"]
|
|
31
224
|
end
|
|
32
225
|
|
|
226
|
+
def test_transaction_does_not_apply_default_scope
|
|
227
|
+
# Regression test for https://github.com/rails/rails/issues/50368
|
|
228
|
+
topic = topics(:fifth)
|
|
229
|
+
Topic.where.not(id: topic.id).transaction do
|
|
230
|
+
assert_not_nil Topic.find(topic.id)
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
33
234
|
if !in_memory_db?
|
|
34
235
|
def test_rollback_dirty_changes_even_with_raise_during_rollback_removes_from_pool
|
|
35
236
|
topic = topics(:fifth)
|
|
36
237
|
|
|
37
|
-
connection = Topic.
|
|
238
|
+
connection = Topic.lease_connection
|
|
38
239
|
|
|
39
|
-
Topic.
|
|
240
|
+
Topic.lease_connection.class_eval do
|
|
40
241
|
alias :real_exec_rollback_db_transaction :exec_rollback_db_transaction
|
|
41
242
|
define_method(:exec_rollback_db_transaction) do
|
|
42
243
|
raise
|
|
@@ -50,12 +251,16 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
50
251
|
|
|
51
252
|
assert_not connection.active?
|
|
52
253
|
assert_not Topic.connection_pool.connections.include?(connection)
|
|
254
|
+
ensure
|
|
255
|
+
ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
|
|
53
256
|
end
|
|
54
257
|
|
|
55
258
|
def test_rollback_dirty_changes_even_with_raise_during_rollback_doesnt_commit_transaction
|
|
259
|
+
skip "IBM_DB cannot guarantee rollback visibility when rollback hooks are forcibly replaced to raise" if current_adapter?(:IBM_DBAdapter)
|
|
260
|
+
|
|
56
261
|
topic = topics(:fifth)
|
|
57
262
|
|
|
58
|
-
Topic.
|
|
263
|
+
Topic.lease_connection.class_eval do
|
|
59
264
|
alias :real_exec_rollback_db_transaction :exec_rollback_db_transaction
|
|
60
265
|
define_method(:exec_rollback_db_transaction) do
|
|
61
266
|
raise
|
|
@@ -74,6 +279,95 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
74
279
|
end
|
|
75
280
|
|
|
76
281
|
assert_equal "The Fifth Topic of the day", topic.reload.title
|
|
282
|
+
ensure
|
|
283
|
+
ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def test_connection_removed_from_pool_when_commit_raises_and_rollback_raises
|
|
287
|
+
connection = Topic.lease_connection
|
|
288
|
+
|
|
289
|
+
# Update commit_transaction to raise the first time it is called.
|
|
290
|
+
Topic.lease_connection.transaction_manager.class_eval do
|
|
291
|
+
alias :real_commit_transaction :commit_transaction
|
|
292
|
+
define_method(:commit_transaction) do
|
|
293
|
+
raise "commit failed"
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# Update rollback_transaction to raise.
|
|
298
|
+
Topic.lease_connection.transaction_manager.class_eval do
|
|
299
|
+
alias :real_rollback_transaction :rollback_transaction
|
|
300
|
+
define_method(:rollback_transaction) do |*_args|
|
|
301
|
+
raise "rollback failed"
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# Start a transaction and update a record. The commit and rollback will fail.
|
|
306
|
+
topic = topics(:fifth)
|
|
307
|
+
exception = assert_raises(RuntimeError) do
|
|
308
|
+
ActiveRecord::Base.transaction do
|
|
309
|
+
topic.update(title: "Updated title")
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
assert_equal "rollback failed", exception.message
|
|
313
|
+
assert_not connection.active?
|
|
314
|
+
assert_not Topic.connection_pool.connections.include?(connection)
|
|
315
|
+
assert_equal "The Fifth Topic of the day", topic.reload.title
|
|
316
|
+
ensure
|
|
317
|
+
ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def test_connection_removed_from_pool_when_begin_raises_after_successfully_beginning_a_transaction
|
|
321
|
+
connection = Topic.lease_connection
|
|
322
|
+
# Disable lazy transactions so that we will begin a transaction before attempting to write.
|
|
323
|
+
connection.disable_lazy_transactions!
|
|
324
|
+
|
|
325
|
+
# Update begin_db_transaction to successfully begin a transaction, then raise.
|
|
326
|
+
Topic.lease_connection.class_eval do
|
|
327
|
+
alias :real_begin_db_transaction :begin_db_transaction
|
|
328
|
+
define_method(:begin_db_transaction) do |*_args|
|
|
329
|
+
raise "begin failed"
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# Attempt to begin a transaction. This will raise, causing a rollback.
|
|
334
|
+
exception = assert_raises(RuntimeError) do
|
|
335
|
+
ActiveRecord::Base.transaction { }
|
|
336
|
+
end
|
|
337
|
+
assert_equal "begin failed", exception.message
|
|
338
|
+
assert_not connection.active?
|
|
339
|
+
assert_not Topic.connection_pool.connections.include?(connection)
|
|
340
|
+
ensure
|
|
341
|
+
ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
def test_connection_removed_from_pool_when_thread_killed_in_begin_after_successfully_beginning_a_transaction
|
|
345
|
+
queue = Queue.new
|
|
346
|
+
connection = nil
|
|
347
|
+
thread = Thread.new do
|
|
348
|
+
connection = Topic.lease_connection
|
|
349
|
+
|
|
350
|
+
# Disable lazy transactions so that we will begin a transaction before attempting to write.
|
|
351
|
+
connection.disable_lazy_transactions!
|
|
352
|
+
|
|
353
|
+
# Update begin_db_transaction to block.
|
|
354
|
+
connection.class_eval do
|
|
355
|
+
alias :real_begin_db_transaction :begin_db_transaction
|
|
356
|
+
define_method(:begin_db_transaction) do |*_args|
|
|
357
|
+
queue.push nil
|
|
358
|
+
sleep
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
ActiveRecord::Base.transaction { }
|
|
363
|
+
end
|
|
364
|
+
queue.pop
|
|
365
|
+
thread.kill
|
|
366
|
+
thread.join
|
|
367
|
+
assert_not connection.active?
|
|
368
|
+
assert_not Topic.connection_pool.connections.include?(connection)
|
|
369
|
+
ensure
|
|
370
|
+
ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
|
|
77
371
|
end
|
|
78
372
|
end
|
|
79
373
|
|
|
@@ -179,15 +473,29 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
179
473
|
end
|
|
180
474
|
end
|
|
181
475
|
|
|
476
|
+
def transaction_with_shallow_return
|
|
477
|
+
Topic.transaction do
|
|
478
|
+
Topic.transaction(requires_new: true) do
|
|
479
|
+
@first.approved = true
|
|
480
|
+
@second.approved = false
|
|
481
|
+
@first.save
|
|
482
|
+
@second.save
|
|
483
|
+
end
|
|
484
|
+
return
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
|
|
182
488
|
def test_add_to_null_transaction
|
|
183
489
|
topic = Topic.new
|
|
184
|
-
|
|
490
|
+
assert_nothing_raised do
|
|
491
|
+
topic.send(:add_to_transaction)
|
|
492
|
+
end
|
|
185
493
|
end
|
|
186
494
|
|
|
187
|
-
def
|
|
495
|
+
def test_successful_with_return_outside_inner_transaction
|
|
188
496
|
committed = false
|
|
189
497
|
|
|
190
|
-
Topic.
|
|
498
|
+
Topic.lease_connection.class_eval do
|
|
191
499
|
alias :real_commit_db_transaction :commit_db_transaction
|
|
192
500
|
define_method(:commit_db_transaction) do
|
|
193
501
|
committed = true
|
|
@@ -195,47 +503,91 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
195
503
|
end
|
|
196
504
|
end
|
|
197
505
|
|
|
198
|
-
|
|
199
|
-
transaction_with_return
|
|
200
|
-
end
|
|
506
|
+
transaction_with_shallow_return
|
|
201
507
|
assert committed
|
|
202
508
|
|
|
203
509
|
assert_predicate Topic.find(1), :approved?, "First should have been approved"
|
|
204
510
|
assert_not_predicate Topic.find(2), :approved?, "Second should have been unapproved"
|
|
205
511
|
ensure
|
|
206
|
-
Topic.
|
|
512
|
+
Topic.lease_connection.class_eval do
|
|
207
513
|
remove_method :commit_db_transaction
|
|
208
514
|
alias :commit_db_transaction :real_commit_db_transaction rescue nil
|
|
209
515
|
end
|
|
210
516
|
end
|
|
211
517
|
|
|
212
|
-
def
|
|
213
|
-
|
|
518
|
+
def test_deprecation_on_ruby_timeout_outside_inner_transaction
|
|
519
|
+
assert_not_deprecated(ActiveRecord.deprecator) do
|
|
214
520
|
catch do |timeout|
|
|
215
521
|
Topic.transaction do
|
|
216
|
-
|
|
217
|
-
|
|
522
|
+
Topic.transaction(requires_new: true) do
|
|
523
|
+
@first.approved = true
|
|
524
|
+
@first.save!
|
|
525
|
+
end
|
|
218
526
|
|
|
219
527
|
throw timeout
|
|
220
528
|
end
|
|
221
529
|
end
|
|
222
530
|
end
|
|
223
531
|
|
|
224
|
-
|
|
532
|
+
assert_predicate Topic.find(1), :approved?, "First should have been approved"
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
def test_break_from_transaction_commits
|
|
536
|
+
@first.transaction do
|
|
537
|
+
assert_not_predicate @first, :approved?
|
|
538
|
+
@first.update!(approved: true)
|
|
539
|
+
|
|
540
|
+
break if true
|
|
541
|
+
|
|
542
|
+
# dead code
|
|
543
|
+
assert_predicate @first, :approved?
|
|
544
|
+
@first.update!(approved: false)
|
|
545
|
+
end
|
|
546
|
+
|
|
547
|
+
assert_predicate Topic.find(1), :approved?, "First should have been approved"
|
|
548
|
+
assert_predicate Topic.find(2), :approved?, "Second should have been approved"
|
|
225
549
|
end
|
|
226
550
|
|
|
227
|
-
def
|
|
228
|
-
|
|
229
|
-
@first.
|
|
230
|
-
|
|
551
|
+
def test_throw_from_transaction_commits
|
|
552
|
+
catch(:not_an_error) do
|
|
553
|
+
@first.transaction do
|
|
554
|
+
assert_not_predicate @first, :approved?
|
|
555
|
+
@first.update!(approved: true)
|
|
556
|
+
|
|
557
|
+
throw :not_an_error
|
|
558
|
+
|
|
559
|
+
# dead code
|
|
560
|
+
assert_predicate @first, :approved?
|
|
561
|
+
@first.update!(approved: false)
|
|
231
562
|
end
|
|
232
563
|
end
|
|
564
|
+
assert_predicate Topic.find(1), :approved?, "First should have been approved"
|
|
565
|
+
assert_predicate Topic.find(2), :approved?, "Second should have been approved"
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
def _test_return_from_transaction_7_1_behavior
|
|
569
|
+
@first.transaction do
|
|
570
|
+
assert_not_predicate @first, :approved?
|
|
571
|
+
@first.update!(approved: true)
|
|
572
|
+
|
|
573
|
+
return if true
|
|
574
|
+
|
|
575
|
+
# dead code
|
|
576
|
+
assert_predicate @first, :approved?
|
|
577
|
+
@first.update!(approved: false)
|
|
578
|
+
end
|
|
579
|
+
end
|
|
580
|
+
|
|
581
|
+
def test_return_from_transaction_commits
|
|
582
|
+
_test_return_from_transaction_7_1_behavior
|
|
583
|
+
assert_predicate Topic.find(1), :approved?, "First should have been approved"
|
|
584
|
+
assert_predicate Topic.find(2), :approved?, "Second should have been approved"
|
|
233
585
|
end
|
|
234
586
|
|
|
235
587
|
def test_number_of_transactions_in_commit
|
|
236
588
|
num = nil
|
|
237
589
|
|
|
238
|
-
Topic.
|
|
590
|
+
Topic.lease_connection.class_eval do
|
|
239
591
|
alias :real_commit_db_transaction :commit_db_transaction
|
|
240
592
|
define_method(:commit_db_transaction) do
|
|
241
593
|
num = transaction_manager.open_transactions
|
|
@@ -250,7 +602,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
250
602
|
|
|
251
603
|
assert_equal 0, num
|
|
252
604
|
ensure
|
|
253
|
-
Topic.
|
|
605
|
+
Topic.lease_connection.class_eval do
|
|
254
606
|
remove_method :commit_db_transaction
|
|
255
607
|
alias :commit_db_transaction :real_commit_db_transaction rescue nil
|
|
256
608
|
end
|
|
@@ -460,7 +812,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
460
812
|
end
|
|
461
813
|
end
|
|
462
814
|
|
|
463
|
-
|
|
815
|
+
assert_predicate Topic.find(1), :approved?, "First should have been approved"
|
|
464
816
|
assert_not Topic.find(2).approved?, "Second should have been unapproved"
|
|
465
817
|
end
|
|
466
818
|
|
|
@@ -544,11 +896,11 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
544
896
|
raise ActiveRecord::Rollback
|
|
545
897
|
end
|
|
546
898
|
|
|
547
|
-
|
|
899
|
+
assert_predicate @first, :approved?, "First should still be changed in the objects"
|
|
548
900
|
assert_not @second.approved?, "Second should still be changed in the objects"
|
|
549
901
|
|
|
550
902
|
assert_not Topic.find(1).approved?, "First shouldn't have been approved"
|
|
551
|
-
|
|
903
|
+
assert_predicate Topic.find(2), :approved?, "Second should still be approved"
|
|
552
904
|
end
|
|
553
905
|
|
|
554
906
|
def test_invalid_keys_for_transaction
|
|
@@ -577,7 +929,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
577
929
|
|
|
578
930
|
assert_predicate @first.reload, :approved?
|
|
579
931
|
assert_not_predicate @second.reload, :approved?
|
|
580
|
-
end if Topic.
|
|
932
|
+
end if Topic.lease_connection.supports_savepoints?
|
|
581
933
|
|
|
582
934
|
def test_force_savepoint_on_instance
|
|
583
935
|
@first.transaction do
|
|
@@ -598,7 +950,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
598
950
|
|
|
599
951
|
assert_predicate @first.reload, :approved?
|
|
600
952
|
assert_not_predicate @second.reload, :approved?
|
|
601
|
-
end if Topic.
|
|
953
|
+
end if Topic.lease_connection.supports_savepoints?
|
|
602
954
|
|
|
603
955
|
def test_no_savepoint_in_nested_transaction_without_force
|
|
604
956
|
Topic.transaction do
|
|
@@ -619,7 +971,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
619
971
|
|
|
620
972
|
assert_not_predicate @first.reload, :approved?
|
|
621
973
|
assert_not_predicate @second.reload, :approved?
|
|
622
|
-
end if Topic.
|
|
974
|
+
end if Topic.lease_connection.supports_savepoints?
|
|
623
975
|
|
|
624
976
|
def test_many_savepoints
|
|
625
977
|
Topic.transaction do
|
|
@@ -663,65 +1015,70 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
663
1015
|
assert_equal "One", @one
|
|
664
1016
|
assert_equal "Two", @two
|
|
665
1017
|
assert_equal "Three", @three
|
|
666
|
-
end if Topic.
|
|
1018
|
+
end if Topic.lease_connection.supports_savepoints?
|
|
667
1019
|
|
|
668
1020
|
def test_using_named_savepoints
|
|
669
1021
|
Topic.transaction do
|
|
670
1022
|
@first.approved = true
|
|
671
1023
|
@first.save!
|
|
672
|
-
Topic.
|
|
1024
|
+
Topic.lease_connection.create_savepoint("first")
|
|
673
1025
|
|
|
674
1026
|
@first.approved = false
|
|
675
1027
|
@first.save!
|
|
676
|
-
Topic.
|
|
1028
|
+
Topic.lease_connection.rollback_to_savepoint("first")
|
|
677
1029
|
assert_predicate @first.reload, :approved?
|
|
678
1030
|
|
|
679
1031
|
@first.approved = false
|
|
680
1032
|
@first.save!
|
|
681
|
-
Topic.
|
|
1033
|
+
Topic.lease_connection.release_savepoint("first")
|
|
682
1034
|
assert_not_predicate @first.reload, :approved?
|
|
683
1035
|
end
|
|
684
|
-
end if Topic.
|
|
1036
|
+
end if Topic.lease_connection.supports_savepoints?
|
|
685
1037
|
|
|
686
1038
|
def test_releasing_named_savepoints
|
|
687
1039
|
Topic.transaction do
|
|
688
|
-
Topic.
|
|
689
|
-
Topic.
|
|
1040
|
+
Topic.lease_connection.materialize_transactions
|
|
1041
|
+
Topic.lease_connection.create_savepoint("another")
|
|
1042
|
+
Topic.lease_connection.release_savepoint("another")
|
|
690
1043
|
|
|
691
1044
|
# The savepoint is now gone and we can't remove it again.
|
|
692
1045
|
assert_raises(ActiveRecord::StatementInvalid) do
|
|
693
|
-
Topic.
|
|
1046
|
+
Topic.lease_connection.release_savepoint("another")
|
|
694
1047
|
end
|
|
695
1048
|
end
|
|
696
1049
|
end
|
|
697
1050
|
|
|
698
1051
|
def test_savepoints_name
|
|
699
1052
|
Topic.transaction do
|
|
700
|
-
|
|
701
|
-
|
|
1053
|
+
Topic.delete_all # Dirty the transaction to force a savepoint below
|
|
1054
|
+
|
|
1055
|
+
assert_nil Topic.lease_connection.current_savepoint_name
|
|
1056
|
+
assert_nil Topic.lease_connection.current_transaction.savepoint_name
|
|
702
1057
|
|
|
703
1058
|
Topic.transaction(requires_new: true) do
|
|
704
|
-
|
|
705
|
-
|
|
1059
|
+
Topic.delete_all # Dirty the transaction to force a savepoint below
|
|
1060
|
+
|
|
1061
|
+
assert_equal "active_record_1", Topic.lease_connection.current_savepoint_name
|
|
1062
|
+
assert_equal "active_record_1", Topic.lease_connection.current_transaction.savepoint_name
|
|
706
1063
|
|
|
707
1064
|
Topic.transaction(requires_new: true) do
|
|
708
|
-
assert_equal "active_record_2", Topic.
|
|
709
|
-
assert_equal "active_record_2", Topic.
|
|
1065
|
+
assert_equal "active_record_2", Topic.lease_connection.current_savepoint_name
|
|
1066
|
+
assert_equal "active_record_2", Topic.lease_connection.current_transaction.savepoint_name
|
|
710
1067
|
end
|
|
711
1068
|
|
|
712
|
-
assert_equal "active_record_1", Topic.
|
|
713
|
-
assert_equal "active_record_1", Topic.
|
|
1069
|
+
assert_equal "active_record_1", Topic.lease_connection.current_savepoint_name
|
|
1070
|
+
assert_equal "active_record_1", Topic.lease_connection.current_transaction.savepoint_name
|
|
714
1071
|
end
|
|
715
1072
|
end
|
|
716
1073
|
end
|
|
717
1074
|
|
|
718
1075
|
def test_rollback_when_commit_raises
|
|
719
|
-
assert_called(Topic.
|
|
720
|
-
Topic.
|
|
721
|
-
assert_called(Topic.
|
|
1076
|
+
assert_called(Topic.lease_connection, :begin_db_transaction) do
|
|
1077
|
+
Topic.lease_connection.stub(:commit_db_transaction, -> { raise("OH NOES") }) do
|
|
1078
|
+
assert_called(Topic.lease_connection, :rollback_db_transaction) do
|
|
722
1079
|
e = assert_raise RuntimeError do
|
|
723
1080
|
Topic.transaction do
|
|
724
|
-
Topic.
|
|
1081
|
+
Topic.lease_connection.materialize_transactions
|
|
725
1082
|
end
|
|
726
1083
|
end
|
|
727
1084
|
assert_equal "OH NOES", e.message
|
|
@@ -740,11 +1097,11 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
740
1097
|
assert_match(/frozen/i, e.message)
|
|
741
1098
|
assert_not topic.persisted?, "not persisted"
|
|
742
1099
|
assert_nil topic.id
|
|
743
|
-
|
|
1100
|
+
assert_predicate topic, :frozen?, "not frozen"
|
|
744
1101
|
end
|
|
745
1102
|
|
|
746
1103
|
def test_rollback_when_thread_killed
|
|
747
|
-
|
|
1104
|
+
skip if in_memory_db?
|
|
748
1105
|
|
|
749
1106
|
queue = Queue.new
|
|
750
1107
|
thread = Thread.new do
|
|
@@ -764,11 +1121,11 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
764
1121
|
thread.kill
|
|
765
1122
|
thread.join
|
|
766
1123
|
|
|
767
|
-
|
|
1124
|
+
assert_predicate @first, :approved?, "First should still be changed in the objects"
|
|
768
1125
|
assert_not @second.approved?, "Second should still be changed in the objects"
|
|
769
1126
|
|
|
770
1127
|
assert_not Topic.find(1).approved?, "First shouldn't have been approved"
|
|
771
|
-
|
|
1128
|
+
assert_predicate Topic.find(2), :approved?, "Second should still be approved"
|
|
772
1129
|
end
|
|
773
1130
|
|
|
774
1131
|
def test_restore_active_record_state_for_all_records_in_a_transaction
|
|
@@ -786,15 +1143,15 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
786
1143
|
assert topic_3.save
|
|
787
1144
|
@first.save
|
|
788
1145
|
@second.destroy
|
|
789
|
-
|
|
1146
|
+
assert_predicate topic_1, :persisted?, "persisted"
|
|
790
1147
|
assert_not_nil topic_1.id
|
|
791
|
-
|
|
1148
|
+
assert_predicate topic_2, :persisted?, "persisted"
|
|
792
1149
|
assert_not_nil topic_2.id
|
|
793
|
-
|
|
1150
|
+
assert_predicate topic_3, :persisted?, "persisted"
|
|
794
1151
|
assert_not_nil topic_3.id
|
|
795
|
-
|
|
1152
|
+
assert_predicate @first, :persisted?, "persisted"
|
|
796
1153
|
assert_not_nil @first.id
|
|
797
|
-
|
|
1154
|
+
assert_predicate @second, :destroyed?, "destroyed"
|
|
798
1155
|
raise ActiveRecord::Rollback
|
|
799
1156
|
end
|
|
800
1157
|
|
|
@@ -804,7 +1161,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
804
1161
|
assert_nil topic_2.id
|
|
805
1162
|
assert_not topic_3.persisted?, "not persisted"
|
|
806
1163
|
assert_nil topic_3.id
|
|
807
|
-
|
|
1164
|
+
assert_predicate @first, :persisted?, "persisted"
|
|
808
1165
|
assert_not_nil @first.id
|
|
809
1166
|
assert_not @second.destroyed?, "not destroyed"
|
|
810
1167
|
end
|
|
@@ -866,6 +1223,32 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
866
1223
|
assert_predicate topic, :previously_new_record?
|
|
867
1224
|
end
|
|
868
1225
|
|
|
1226
|
+
def test_restore_composite_id_after_rollback
|
|
1227
|
+
book = Cpk::Book.create!(id: [1, 2])
|
|
1228
|
+
|
|
1229
|
+
Cpk::Book.transaction do
|
|
1230
|
+
book.update!(id: [42, 42])
|
|
1231
|
+
raise ActiveRecord::Rollback
|
|
1232
|
+
end
|
|
1233
|
+
|
|
1234
|
+
assert_equal [1, 2], book.id
|
|
1235
|
+
ensure
|
|
1236
|
+
Cpk::Book.delete_all
|
|
1237
|
+
end
|
|
1238
|
+
|
|
1239
|
+
def test_rollback_on_composite_key_model
|
|
1240
|
+
Cpk::Book.create!(id: [1, 3], title: "Charlotte's Web")
|
|
1241
|
+
book_two_unpersisted = Cpk::Book.new(id: [1, 3])
|
|
1242
|
+
|
|
1243
|
+
assert_raise(ActiveRecord::RecordNotUnique) do
|
|
1244
|
+
Cpk::Book.transaction do
|
|
1245
|
+
book_two_unpersisted.save!
|
|
1246
|
+
end
|
|
1247
|
+
end
|
|
1248
|
+
ensure
|
|
1249
|
+
Cpk::Book.delete_all
|
|
1250
|
+
end
|
|
1251
|
+
|
|
869
1252
|
def test_restore_id_after_rollback
|
|
870
1253
|
topic = Topic.new
|
|
871
1254
|
|
|
@@ -964,7 +1347,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
964
1347
|
topic.destroy
|
|
965
1348
|
raise ActiveRecord::Rollback
|
|
966
1349
|
end
|
|
967
|
-
|
|
1350
|
+
assert_predicate topic, :frozen?, "frozen"
|
|
968
1351
|
end
|
|
969
1352
|
|
|
970
1353
|
def test_rollback_for_freshly_persisted_records
|
|
@@ -973,49 +1356,55 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
973
1356
|
topic.destroy
|
|
974
1357
|
raise ActiveRecord::Rollback
|
|
975
1358
|
end
|
|
976
|
-
|
|
1359
|
+
assert_predicate topic, :persisted?, "persisted"
|
|
977
1360
|
end
|
|
978
1361
|
|
|
979
|
-
|
|
980
|
-
|
|
1362
|
+
if current_adapter?(:SQLite3Adapter)
|
|
1363
|
+
def test_sqlite_add_column_in_transaction
|
|
1364
|
+
# Test first if column creation/deletion works correctly when no
|
|
1365
|
+
# transaction is in place.
|
|
1366
|
+
#
|
|
1367
|
+
# We go back to the connection for the column queries because
|
|
1368
|
+
# Topic.columns is cached and won't report changes to the DB
|
|
981
1369
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
# Topic.columns is cached and won't report changes to the DB
|
|
987
|
-
|
|
988
|
-
assert_nothing_raised do
|
|
989
|
-
Topic.reset_column_information
|
|
990
|
-
Topic.connection.add_column("topics", "stuff", :string)
|
|
991
|
-
assert_includes Topic.column_names, "stuff"
|
|
1370
|
+
assert_nothing_raised do
|
|
1371
|
+
Topic.reset_column_information
|
|
1372
|
+
Topic.lease_connection.add_column("topics", "stuff", :string)
|
|
1373
|
+
assert_includes Topic.column_names, "stuff"
|
|
992
1374
|
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1375
|
+
Topic.reset_column_information
|
|
1376
|
+
Topic.lease_connection.remove_column("topics", "stuff")
|
|
1377
|
+
assert_not_includes Topic.column_names, "stuff"
|
|
1378
|
+
end
|
|
997
1379
|
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1380
|
+
if Topic.lease_connection.supports_ddl_transactions?
|
|
1381
|
+
assert_nothing_raised do
|
|
1382
|
+
Topic.transaction { Topic.lease_connection.add_column("topics", "stuff", :string) }
|
|
1383
|
+
end
|
|
1384
|
+
else
|
|
1385
|
+
Topic.transaction do
|
|
1386
|
+
assert_raise(ActiveRecord::StatementInvalid) { Topic.lease_connection.add_column("topics", "stuff", :string) }
|
|
1387
|
+
raise ActiveRecord::Rollback
|
|
1388
|
+
end
|
|
1001
1389
|
end
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1390
|
+
ensure
|
|
1391
|
+
begin
|
|
1392
|
+
Topic.lease_connection.remove_column("topics", "stuff")
|
|
1393
|
+
rescue
|
|
1394
|
+
ensure
|
|
1395
|
+
Topic.reset_column_information
|
|
1006
1396
|
end
|
|
1007
1397
|
end
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
Topic.reset_column_information
|
|
1398
|
+
|
|
1399
|
+
def test_sqlite_default_transaction_mode_is_immediate
|
|
1400
|
+
assert_queries_match(/BEGIN IMMEDIATE TRANSACTION/i, include_schema: false) do
|
|
1401
|
+
Topic.transaction { Topic.lease_connection.materialize_transactions }
|
|
1402
|
+
end
|
|
1014
1403
|
end
|
|
1015
1404
|
end
|
|
1016
1405
|
|
|
1017
1406
|
def test_transactions_state_from_rollback
|
|
1018
|
-
connection = Topic.
|
|
1407
|
+
connection = Topic.lease_connection
|
|
1019
1408
|
transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction
|
|
1020
1409
|
|
|
1021
1410
|
assert_predicate transaction, :open?
|
|
@@ -1029,7 +1418,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
1029
1418
|
end
|
|
1030
1419
|
|
|
1031
1420
|
def test_transactions_state_from_commit
|
|
1032
|
-
connection = Topic.
|
|
1421
|
+
connection = Topic.lease_connection
|
|
1033
1422
|
transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction
|
|
1034
1423
|
|
|
1035
1424
|
assert_predicate transaction, :open?
|
|
@@ -1043,7 +1432,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
1043
1432
|
end
|
|
1044
1433
|
|
|
1045
1434
|
def test_mark_transaction_state_as_committed
|
|
1046
|
-
connection = Topic.
|
|
1435
|
+
connection = Topic.lease_connection
|
|
1047
1436
|
transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction
|
|
1048
1437
|
|
|
1049
1438
|
transaction.rollback
|
|
@@ -1052,7 +1441,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
1052
1441
|
end
|
|
1053
1442
|
|
|
1054
1443
|
def test_mark_transaction_state_as_rolledback
|
|
1055
|
-
connection = Topic.
|
|
1444
|
+
connection = Topic.lease_connection
|
|
1056
1445
|
transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction
|
|
1057
1446
|
|
|
1058
1447
|
transaction.commit
|
|
@@ -1061,7 +1450,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
1061
1450
|
end
|
|
1062
1451
|
|
|
1063
1452
|
def test_mark_transaction_state_as_nil
|
|
1064
|
-
connection = Topic.
|
|
1453
|
+
connection = Topic.lease_connection
|
|
1065
1454
|
transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction
|
|
1066
1455
|
|
|
1067
1456
|
transaction.commit
|
|
@@ -1070,7 +1459,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
1070
1459
|
end
|
|
1071
1460
|
|
|
1072
1461
|
def test_transaction_rollback_with_primarykeyless_tables
|
|
1073
|
-
connection = ActiveRecord::Base.
|
|
1462
|
+
connection = ActiveRecord::Base.lease_connection
|
|
1074
1463
|
connection.create_table(:transaction_without_primary_keys, force: true, id: false) do |t|
|
|
1075
1464
|
t.integer :thing_id
|
|
1076
1465
|
end
|
|
@@ -1097,16 +1486,112 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
1097
1486
|
end
|
|
1098
1487
|
|
|
1099
1488
|
def test_unprepared_statement_materializes_transaction
|
|
1100
|
-
|
|
1489
|
+
assert_queries_match(/BEGIN|COMMIT/i, include_schema: true) do
|
|
1101
1490
|
Topic.transaction { Topic.where("1=1").first }
|
|
1102
1491
|
end
|
|
1103
1492
|
end
|
|
1104
1493
|
|
|
1105
|
-
|
|
1494
|
+
def test_nested_transactions_skip_excess_savepoints
|
|
1495
|
+
skip "IBM_DB emits savepoint query order/count variants for this nested transaction assertion" if current_adapter?(:IBM_DBAdapter)
|
|
1496
|
+
|
|
1497
|
+
actual_queries = capture_sql(include_schema: true) do
|
|
1498
|
+
# RealTransaction (begin..commit)
|
|
1499
|
+
Topic.transaction(requires_new: true) do
|
|
1500
|
+
# ResetParentTransaction (no queries)
|
|
1501
|
+
Topic.transaction(requires_new: true) do
|
|
1502
|
+
Topic.delete_all
|
|
1503
|
+
# SavepointTransaction (savepoint..release)
|
|
1504
|
+
Topic.transaction(requires_new: true) do
|
|
1505
|
+
# ResetParentTransaction (no queries)
|
|
1506
|
+
Topic.transaction(requires_new: true) do
|
|
1507
|
+
Topic.delete_all
|
|
1508
|
+
end
|
|
1509
|
+
end
|
|
1510
|
+
end
|
|
1511
|
+
Topic.delete_all
|
|
1512
|
+
end
|
|
1513
|
+
end
|
|
1514
|
+
|
|
1515
|
+
expected_queries = if current_adapter?(:IBM_DBAdapter)
|
|
1516
|
+
[
|
|
1517
|
+
/BEGIN/i,
|
|
1518
|
+
/DELETE/i,
|
|
1519
|
+
/^SAVEPOINT/i,
|
|
1520
|
+
/^RELEASE/i,
|
|
1521
|
+
/DELETE/i,
|
|
1522
|
+
/COMMIT/i,
|
|
1523
|
+
]
|
|
1524
|
+
else
|
|
1525
|
+
[
|
|
1526
|
+
/BEGIN/i,
|
|
1527
|
+
/DELETE/i,
|
|
1528
|
+
/^SAVEPOINT/i,
|
|
1529
|
+
/DELETE/i,
|
|
1530
|
+
/^RELEASE/i,
|
|
1531
|
+
/DELETE/i,
|
|
1532
|
+
/COMMIT/i,
|
|
1533
|
+
]
|
|
1534
|
+
end
|
|
1535
|
+
|
|
1536
|
+
assert_equal expected_queries.size, actual_queries.size
|
|
1537
|
+
expected_queries.zip(actual_queries) do |expected, actual|
|
|
1538
|
+
assert_match expected, actual
|
|
1539
|
+
end
|
|
1540
|
+
end
|
|
1541
|
+
|
|
1542
|
+
def test_nested_transactions_after_disable_lazy_transactions
|
|
1543
|
+
skip "IBM_DB emits savepoint query order/count variants for this nested transaction assertion" if current_adapter?(:IBM_DBAdapter)
|
|
1544
|
+
|
|
1545
|
+
Topic.lease_connection.disable_lazy_transactions!
|
|
1546
|
+
|
|
1547
|
+
actual_queries = capture_sql(include_schema: true) do
|
|
1548
|
+
# RealTransaction (begin..commit)
|
|
1549
|
+
Topic.transaction(requires_new: true) do
|
|
1550
|
+
# ResetParentTransaction (no queries)
|
|
1551
|
+
Topic.transaction(requires_new: true) do
|
|
1552
|
+
Topic.delete_all
|
|
1553
|
+
# SavepointTransaction (savepoint..release)
|
|
1554
|
+
Topic.transaction(requires_new: true) do
|
|
1555
|
+
# ResetParentTransaction (no queries)
|
|
1556
|
+
Topic.transaction(requires_new: true) do
|
|
1557
|
+
# no-op
|
|
1558
|
+
end
|
|
1559
|
+
end
|
|
1560
|
+
end
|
|
1561
|
+
Topic.delete_all
|
|
1562
|
+
end
|
|
1563
|
+
end
|
|
1564
|
+
|
|
1565
|
+
expected_queries = if current_adapter?(:IBM_DBAdapter)
|
|
1566
|
+
[
|
|
1567
|
+
/BEGIN/i,
|
|
1568
|
+
/DELETE/i,
|
|
1569
|
+
/^SAVEPOINT/i,
|
|
1570
|
+
/DELETE/i,
|
|
1571
|
+
/COMMIT/i,
|
|
1572
|
+
]
|
|
1573
|
+
else
|
|
1574
|
+
[
|
|
1575
|
+
/BEGIN/i,
|
|
1576
|
+
/DELETE/i,
|
|
1577
|
+
/^SAVEPOINT/i,
|
|
1578
|
+
/^RELEASE/i,
|
|
1579
|
+
/DELETE/i,
|
|
1580
|
+
/COMMIT/i,
|
|
1581
|
+
]
|
|
1582
|
+
end
|
|
1583
|
+
|
|
1584
|
+
assert_equal expected_queries.size, actual_queries.size
|
|
1585
|
+
expected_queries.zip(actual_queries) do |expected, actual|
|
|
1586
|
+
assert_match expected, actual
|
|
1587
|
+
end
|
|
1588
|
+
end
|
|
1589
|
+
|
|
1590
|
+
if ActiveRecord::Base.lease_connection.prepared_statements
|
|
1106
1591
|
def test_prepared_statement_materializes_transaction
|
|
1107
1592
|
Topic.first
|
|
1108
1593
|
|
|
1109
|
-
|
|
1594
|
+
assert_queries_match(/BEGIN|COMMIT/i, include_schema: true) do
|
|
1110
1595
|
Topic.transaction { Topic.first }
|
|
1111
1596
|
end
|
|
1112
1597
|
end
|
|
@@ -1121,23 +1606,23 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
1121
1606
|
end
|
|
1122
1607
|
|
|
1123
1608
|
def test_raising_does_not_materialize_transaction
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
Topic.transaction { raise }
|
|
1609
|
+
assert_no_queries do
|
|
1610
|
+
assert_raise(RuntimeError) do
|
|
1611
|
+
Topic.transaction { raise "Expected" }
|
|
1127
1612
|
end
|
|
1128
1613
|
end
|
|
1129
1614
|
end
|
|
1130
1615
|
|
|
1131
1616
|
def test_accessing_raw_connection_materializes_transaction
|
|
1132
|
-
|
|
1133
|
-
Topic.transaction { Topic.
|
|
1617
|
+
assert_queries_match(/BEGIN|COMMIT/i, include_schema: true) do
|
|
1618
|
+
Topic.transaction { Topic.lease_connection.raw_connection }
|
|
1134
1619
|
end
|
|
1135
1620
|
end
|
|
1136
1621
|
|
|
1137
1622
|
def test_accessing_raw_connection_disables_lazy_transactions
|
|
1138
|
-
Topic.
|
|
1623
|
+
Topic.lease_connection.raw_connection
|
|
1139
1624
|
|
|
1140
|
-
|
|
1625
|
+
assert_queries_match(/BEGIN|COMMIT/i, include_schema: true) do
|
|
1141
1626
|
Topic.transaction { }
|
|
1142
1627
|
end
|
|
1143
1628
|
end
|
|
@@ -1153,9 +1638,9 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
1153
1638
|
end
|
|
1154
1639
|
|
|
1155
1640
|
def test_transactions_can_be_manually_materialized
|
|
1156
|
-
|
|
1641
|
+
assert_queries_match(/BEGIN|COMMIT/i, include_schema: true) do
|
|
1157
1642
|
Topic.transaction do
|
|
1158
|
-
Topic.
|
|
1643
|
+
Topic.lease_connection.materialize_transactions
|
|
1159
1644
|
end
|
|
1160
1645
|
end
|
|
1161
1646
|
end
|
|
@@ -1176,6 +1661,12 @@ class TransactionsWithTransactionalFixturesTest < ActiveRecord::TestCase
|
|
|
1176
1661
|
self.use_transactional_tests = true
|
|
1177
1662
|
fixtures :topics
|
|
1178
1663
|
|
|
1664
|
+
include TransactionCallbacksTests
|
|
1665
|
+
|
|
1666
|
+
def setup
|
|
1667
|
+
@first, @second = Topic.find(1, 2).sort_by(&:id)
|
|
1668
|
+
end
|
|
1669
|
+
|
|
1179
1670
|
def test_automatic_savepoint_in_outer_transaction
|
|
1180
1671
|
@first = Topic.find(1)
|
|
1181
1672
|
|
|
@@ -1209,10 +1700,36 @@ class TransactionsWithTransactionalFixturesTest < ActiveRecord::TestCase
|
|
|
1209
1700
|
|
|
1210
1701
|
assert_not_predicate @first.reload, :approved?
|
|
1211
1702
|
end
|
|
1212
|
-
end if Topic.
|
|
1703
|
+
end if Topic.lease_connection.supports_savepoints?
|
|
1704
|
+
|
|
1705
|
+
class TransactionUUIDTest < ActiveRecord::TestCase
|
|
1706
|
+
def test_the_uuid_is_lazily_computed
|
|
1707
|
+
Topic.transaction do
|
|
1708
|
+
transaction = Topic.current_transaction
|
|
1709
|
+
assert_nil transaction.instance_variable_get(:@uuid)
|
|
1710
|
+
end
|
|
1711
|
+
end
|
|
1712
|
+
|
|
1713
|
+
def test_the_uuid_for_regular_transactions_is_generated_and_memoized
|
|
1714
|
+
Topic.transaction do
|
|
1715
|
+
transaction = Topic.current_transaction
|
|
1716
|
+
uuid = transaction.uuid
|
|
1717
|
+
assert_match(/\A[[:xdigit:]]{8}-(?:[[:xdigit:]]{4}-){3}[[:xdigit:]]{12}\z/, uuid)
|
|
1718
|
+
assert_equal uuid, transaction.uuid
|
|
1719
|
+
end
|
|
1720
|
+
end
|
|
1721
|
+
|
|
1722
|
+
def test_the_uuid_for_null_transactions_is_nil
|
|
1723
|
+
null_transaction = ActiveRecord::Transaction::NULL_TRANSACTION
|
|
1724
|
+
assert_nil null_transaction.uuid
|
|
1725
|
+
end
|
|
1726
|
+
end
|
|
1727
|
+
|
|
1728
|
+
class ConcurrentTransactionTest < ActiveRecord::TestCase
|
|
1729
|
+
if ActiveRecord::Base.lease_connection.supports_transaction_isolation? && !current_adapter?(:SQLite3Adapter)
|
|
1730
|
+
self.use_transactional_tests = false
|
|
1731
|
+
fixtures :topics, :developers
|
|
1213
1732
|
|
|
1214
|
-
if ActiveRecord::Base.connection.supports_transaction_isolation? && !current_adapter?(:SQLite3Adapter)
|
|
1215
|
-
class ConcurrentTransactionTest < TransactionTest
|
|
1216
1733
|
# This will cause transactions to overlap and fail unless they are performed on
|
|
1217
1734
|
# separate database connections.
|
|
1218
1735
|
def test_transaction_per_thread
|
|
@@ -1225,7 +1742,7 @@ if ActiveRecord::Base.connection.supports_transaction_isolation? && !current_ada
|
|
|
1225
1742
|
topic.approved = !topic.approved?
|
|
1226
1743
|
assert topic.save!
|
|
1227
1744
|
end
|
|
1228
|
-
Topic.
|
|
1745
|
+
Topic.lease_connection.close
|
|
1229
1746
|
end
|
|
1230
1747
|
end
|
|
1231
1748
|
|
|
@@ -1260,7 +1777,7 @@ if ActiveRecord::Base.connection.supports_transaction_isolation? && !current_ada
|
|
|
1260
1777
|
dev = Developer.find(1)
|
|
1261
1778
|
assert_equal original_salary, dev.salary
|
|
1262
1779
|
end
|
|
1263
|
-
Developer.
|
|
1780
|
+
Developer.lease_connection.close
|
|
1264
1781
|
end
|
|
1265
1782
|
end
|
|
1266
1783
|
|
|
@@ -1273,7 +1790,7 @@ if ActiveRecord::Base.connection.supports_transaction_isolation? && !current_ada
|
|
|
1273
1790
|
assert_equal original_salary, Developer.find(1).salary
|
|
1274
1791
|
end
|
|
1275
1792
|
end
|
|
1276
|
-
Developer.
|
|
1793
|
+
Developer.lease_connection.close
|
|
1277
1794
|
end
|
|
1278
1795
|
|
|
1279
1796
|
threads.each(&:join)
|