ibm_db 5.2.0-x86-mingw32 → 5.4.0-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 +4 -4
- data/CHANGES +9 -0
- data/LICENSE +55 -18
- data/README +1 -1
- data/debug.log +1 -0
- data/ext/Makefile +28 -24
- data/ext/ibm_db.c +66 -65
- data/ext/ibm_db.o +0 -0
- data/ext/ibm_db.so +0 -0
- data/ext/mkmf.log +26 -24
- data/ext/ruby_ibm_db_cli.c +1 -0
- data/ext/ruby_ibm_db_cli.o +0 -0
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1520 -1282
- data/lib/ibm_db.so +1 -0
- data/lib/mswin32/ibm_db.rb +3 -1
- data/lib/mswin32/rb3x/i386/ruby30/ibm_db.so +0 -0
- data/lib/mswin32/rb3x/i386/ruby31/ibm_db.so +0 -0
- data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
- data/test/activejob/destroy_association_async_test.rb +305 -0
- data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
- data/test/activejob/helper.rb +15 -0
- data/test/assets/schema_dump_5_1.yml +345 -0
- data/test/cases/adapter_prevent_writes_test.rb +334 -0
- data/test/cases/adapter_test.rb +432 -218
- data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
- data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
- data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
- data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
- data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
- data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
- data/test/cases/adapters/mysql2/connection_test.rb +48 -50
- data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
- data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
- data/test/cases/adapters/mysql2/enum_test.rb +32 -11
- data/test/cases/adapters/mysql2/explain_test.rb +13 -11
- data/test/cases/adapters/mysql2/json_test.rb +17 -188
- data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
- data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
- data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
- data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
- data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
- data/test/cases/adapters/mysql2/schema_test.rb +24 -22
- data/test/cases/adapters/mysql2/set_test.rb +32 -0
- data/test/cases/adapters/mysql2/sp_test.rb +10 -8
- data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
- data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
- data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
- data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
- data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
- data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
- data/test/cases/adapters/postgresql/array_test.rb +118 -63
- data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
- data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
- data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
- data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
- data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
- data/test/cases/adapters/postgresql/citext_test.rb +58 -58
- data/test/cases/adapters/postgresql/collation_test.rb +17 -15
- data/test/cases/adapters/postgresql/composite_test.rb +25 -23
- data/test/cases/adapters/postgresql/connection_test.rb +73 -85
- data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
- data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
- data/test/cases/adapters/postgresql/date_test.rb +42 -0
- data/test/cases/adapters/postgresql/domain_test.rb +9 -7
- data/test/cases/adapters/postgresql/enum_test.rb +12 -10
- data/test/cases/adapters/postgresql/explain_test.rb +10 -8
- data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
- data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
- data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
- data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
- data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
- data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
- data/test/cases/adapters/postgresql/integer_test.rb +2 -0
- data/test/cases/adapters/postgresql/interval_test.rb +99 -0
- data/test/cases/adapters/postgresql/json_test.rb +16 -201
- data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
- data/test/cases/adapters/postgresql/money_test.rb +47 -16
- data/test/cases/adapters/postgresql/network_test.rb +36 -28
- data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
- data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
- data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
- data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
- data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
- data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
- data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
- data/test/cases/adapters/postgresql/range_test.rb +406 -292
- data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
- data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
- data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
- data/test/cases/adapters/postgresql/schema_test.rb +207 -91
- data/test/cases/adapters/postgresql/serial_test.rb +9 -7
- data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
- data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
- data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
- data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
- data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
- data/test/cases/adapters/postgresql/utils_test.rb +11 -9
- data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
- data/test/cases/adapters/postgresql/xml_test.rb +10 -14
- data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
- data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
- data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
- data/test/cases/adapters/sqlite3/json_test.rb +29 -0
- data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
- data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
- data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
- data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
- data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
- data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
- data/test/cases/aggregations_test.rb +14 -12
- data/test/cases/annotate_test.rb +46 -0
- data/test/cases/ar_schema_test.rb +153 -86
- data/test/cases/arel/attributes/attribute_test.rb +1145 -0
- data/test/cases/arel/attributes/math_test.rb +83 -0
- data/test/cases/arel/attributes_test.rb +27 -0
- data/test/cases/arel/collectors/bind_test.rb +40 -0
- data/test/cases/arel/collectors/composite_test.rb +47 -0
- data/test/cases/arel/collectors/sql_string_test.rb +41 -0
- data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
- data/test/cases/arel/crud_test.rb +65 -0
- data/test/cases/arel/delete_manager_test.rb +53 -0
- data/test/cases/arel/factory_methods_test.rb +46 -0
- data/test/cases/arel/helper.rb +45 -0
- data/test/cases/arel/insert_manager_test.rb +241 -0
- data/test/cases/arel/nodes/and_test.rb +30 -0
- data/test/cases/arel/nodes/as_test.rb +36 -0
- data/test/cases/arel/nodes/ascending_test.rb +46 -0
- data/test/cases/arel/nodes/bin_test.rb +35 -0
- data/test/cases/arel/nodes/binary_test.rb +29 -0
- data/test/cases/arel/nodes/bind_param_test.rb +22 -0
- data/test/cases/arel/nodes/case_test.rb +96 -0
- data/test/cases/arel/nodes/casted_test.rb +18 -0
- data/test/cases/arel/nodes/comment_test.rb +22 -0
- data/test/cases/arel/nodes/count_test.rb +35 -0
- data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
- data/test/cases/arel/nodes/descending_test.rb +46 -0
- data/test/cases/arel/nodes/distinct_test.rb +21 -0
- data/test/cases/arel/nodes/equality_test.rb +62 -0
- data/test/cases/arel/nodes/extract_test.rb +43 -0
- data/test/cases/arel/nodes/false_test.rb +21 -0
- data/test/cases/arel/nodes/grouping_test.rb +26 -0
- data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
- data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
- data/test/cases/arel/nodes/named_function_test.rb +48 -0
- data/test/cases/arel/nodes/node_test.rb +22 -0
- data/test/cases/arel/nodes/not_test.rb +31 -0
- data/test/cases/arel/nodes/or_test.rb +36 -0
- data/test/cases/arel/nodes/over_test.rb +69 -0
- data/test/cases/arel/nodes/select_core_test.rb +79 -0
- data/test/cases/arel/nodes/select_statement_test.rb +51 -0
- data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
- data/test/cases/arel/nodes/sum_test.rb +35 -0
- data/test/cases/arel/nodes/table_alias_test.rb +29 -0
- data/test/cases/arel/nodes/true_test.rb +21 -0
- data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
- data/test/cases/arel/nodes/update_statement_test.rb +60 -0
- data/test/cases/arel/nodes/window_test.rb +81 -0
- data/test/cases/arel/nodes_test.rb +34 -0
- data/test/cases/arel/select_manager_test.rb +1238 -0
- data/test/cases/arel/support/fake_record.rb +135 -0
- data/test/cases/arel/table_test.rb +216 -0
- data/test/cases/arel/update_manager_test.rb +126 -0
- data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
- data/test/cases/arel/visitors/dot_test.rb +90 -0
- data/test/cases/arel/visitors/mysql_test.rb +157 -0
- data/test/cases/arel/visitors/postgres_test.rb +366 -0
- data/test/cases/arel/visitors/sqlite_test.rb +75 -0
- data/test/cases/arel/visitors/to_sql_test.rb +750 -0
- data/test/cases/associations/belongs_to_associations_test.rb +510 -158
- data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
- data/test/cases/associations/callbacks_test.rb +56 -38
- data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
- data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
- data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
- data/test/cases/associations/eager_singularization_test.rb +21 -21
- data/test/cases/associations/eager_test.rb +559 -415
- data/test/cases/associations/extension_test.rb +18 -12
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
- data/test/cases/associations/has_many_associations_test.rb +1038 -465
- data/test/cases/associations/has_many_through_associations_test.rb +558 -249
- data/test/cases/associations/has_one_associations_test.rb +294 -129
- data/test/cases/associations/has_one_through_associations_test.rb +121 -75
- data/test/cases/associations/inner_join_association_test.rb +114 -38
- data/test/cases/associations/inverse_associations_test.rb +606 -398
- data/test/cases/associations/join_model_test.rb +158 -148
- data/test/cases/associations/left_outer_join_association_test.rb +59 -24
- data/test/cases/associations/nested_through_associations_test.rb +166 -109
- data/test/cases/associations/required_test.rb +35 -10
- data/test/cases/associations_test.rb +241 -110
- data/test/cases/attribute_methods/read_test.rb +11 -11
- data/test/cases/attribute_methods_test.rb +413 -298
- data/test/cases/attributes_test.rb +145 -27
- data/test/cases/autosave_association_test.rb +681 -436
- data/test/cases/base_prevent_writes_test.rb +229 -0
- data/test/cases/base_test.rb +599 -542
- data/test/cases/batches_test.rb +288 -82
- data/test/cases/binary_test.rb +26 -31
- data/test/cases/bind_parameter_test.rb +194 -21
- data/test/cases/boolean_test.rb +52 -0
- data/test/cases/cache_key_test.rb +110 -5
- data/test/cases/calculations_test.rb +740 -177
- data/test/cases/callbacks_test.rb +74 -207
- data/test/cases/clone_test.rb +15 -10
- data/test/cases/coders/json_test.rb +2 -0
- data/test/cases/coders/yaml_column_test.rb +16 -13
- data/test/cases/collection_cache_key_test.rb +177 -20
- data/test/cases/column_alias_test.rb +9 -7
- data/test/cases/column_definition_test.rb +10 -68
- data/test/cases/comment_test.rb +166 -107
- data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
- data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
- data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
- data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
- data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
- data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
- data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
- data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
- data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
- data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
- data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
- data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
- data/test/cases/connection_management_test.rb +13 -11
- data/test/cases/connection_pool_test.rb +316 -83
- data/test/cases/core_test.rb +82 -58
- data/test/cases/counter_cache_test.rb +204 -50
- data/test/cases/custom_locking_test.rb +5 -3
- data/test/cases/database_configurations/hash_config_test.rb +74 -0
- data/test/cases/database_configurations/resolver_test.rb +150 -0
- data/test/cases/database_configurations_test.rb +145 -0
- data/test/cases/database_selector_test.rb +296 -0
- data/test/cases/database_statements_test.rb +18 -16
- data/test/cases/date_test.rb +8 -16
- data/test/cases/date_time_precision_test.rb +100 -78
- data/test/cases/date_time_test.rb +23 -8
- data/test/cases/defaults_test.rb +106 -71
- data/test/cases/delegated_type_test.rb +57 -0
- data/test/cases/dirty_test.rb +419 -223
- data/test/cases/disconnected_test.rb +6 -6
- data/test/cases/dup_test.rb +54 -27
- data/test/cases/enum_test.rb +461 -82
- data/test/cases/errors_test.rb +7 -7
- data/test/cases/explain_subscriber_test.rb +17 -15
- data/test/cases/explain_test.rb +11 -19
- data/test/cases/filter_attributes_test.rb +153 -0
- data/test/cases/finder_respond_to_test.rb +14 -14
- data/test/cases/finder_test.rb +669 -287
- data/test/cases/fixture_set/file_test.rb +34 -38
- data/test/cases/fixtures_test.rb +833 -176
- data/test/cases/forbidden_attributes_protection_test.rb +32 -67
- data/test/cases/habtm_destroy_order_test.rb +25 -25
- data/test/cases/helper.rb +78 -49
- data/test/cases/hot_compatibility_test.rb +33 -32
- data/test/cases/i18n_test.rb +18 -17
- data/test/cases/inheritance_test.rb +180 -115
- data/test/cases/insert_all_test.rb +489 -0
- data/test/cases/instrumentation_test.rb +101 -0
- data/test/cases/integration_test.rb +119 -31
- data/test/cases/invalid_connection_test.rb +18 -16
- data/test/cases/invertible_migration_test.rb +183 -43
- data/test/cases/json_attribute_test.rb +35 -0
- data/test/cases/json_serialization_test.rb +57 -58
- data/test/cases/json_shared_test_cases.rb +290 -0
- data/test/cases/locking_test.rb +413 -119
- data/test/cases/log_subscriber_test.rb +68 -26
- data/test/cases/marshal_serialization_test.rb +39 -0
- data/test/cases/migration/change_schema_test.rb +118 -72
- data/test/cases/migration/change_table_test.rb +138 -30
- data/test/cases/migration/check_constraint_test.rb +162 -0
- data/test/cases/migration/column_attributes_test.rb +45 -35
- data/test/cases/migration/column_positioning_test.rb +18 -6
- data/test/cases/migration/columns_test.rb +93 -77
- data/test/cases/migration/command_recorder_test.rb +121 -34
- data/test/cases/migration/compatibility_test.rb +578 -23
- data/test/cases/migration/create_join_table_test.rb +35 -25
- data/test/cases/migration/foreign_key_test.rb +503 -284
- data/test/cases/migration/helper.rb +4 -3
- data/test/cases/migration/index_test.rb +119 -70
- data/test/cases/migration/logger_test.rb +9 -6
- data/test/cases/migration/pending_migrations_test.rb +88 -34
- data/test/cases/migration/references_foreign_key_test.rb +164 -150
- data/test/cases/migration/references_index_test.rb +38 -19
- data/test/cases/migration/references_statements_test.rb +15 -14
- data/test/cases/migration/rename_table_test.rb +53 -30
- data/test/cases/migration_test.rb +637 -269
- data/test/cases/migrator_test.rb +191 -135
- data/test/cases/mixin_test.rb +7 -11
- data/test/cases/modules_test.rb +36 -34
- data/test/cases/multi_db_migrator_test.rb +223 -0
- data/test/cases/multiparameter_attributes_test.rb +60 -33
- data/test/cases/multiple_db_test.rb +16 -22
- data/test/cases/nested_attributes_test.rb +341 -320
- data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
- data/test/cases/null_relation_test.rb +84 -0
- data/test/cases/numeric_data_test.rb +93 -0
- data/test/cases/persistence_test.rb +361 -269
- data/test/cases/pooled_connections_test.rb +18 -26
- data/test/cases/prepared_statement_status_test.rb +48 -0
- data/test/cases/primary_keys_test.rb +210 -104
- data/test/cases/query_cache_test.rb +610 -141
- data/test/cases/quoting_test.rb +132 -31
- data/test/cases/readonly_test.rb +49 -48
- data/test/cases/reaper_test.rb +146 -32
- data/test/cases/reflection_test.rb +167 -156
- data/test/cases/relation/delegation_test.rb +49 -36
- data/test/cases/relation/delete_all_test.rb +117 -0
- data/test/cases/relation/merging_test.rb +319 -42
- data/test/cases/relation/mutation_test.rb +55 -93
- data/test/cases/relation/or_test.rb +129 -29
- data/test/cases/relation/predicate_builder_test.rb +21 -6
- data/test/cases/relation/record_fetch_warning_test.rb +5 -3
- data/test/cases/relation/select_test.rb +67 -0
- data/test/cases/relation/update_all_test.rb +317 -0
- data/test/cases/relation/where_chain_test.rb +68 -32
- data/test/cases/relation/where_clause_test.rb +136 -61
- data/test/cases/relation/where_test.rb +155 -48
- data/test/cases/relation_test.rb +266 -112
- data/test/cases/relations_test.rb +969 -744
- data/test/cases/reload_models_test.rb +13 -9
- data/test/cases/reserved_word_test.rb +141 -0
- data/test/cases/result_test.rb +68 -17
- data/test/cases/sanitize_test.rb +87 -71
- data/test/cases/schema_dumper_test.rb +221 -128
- data/test/cases/schema_loading_test.rb +3 -2
- data/test/cases/scoping/default_scoping_test.rb +185 -144
- data/test/cases/scoping/named_scoping_test.rb +177 -89
- data/test/cases/scoping/relation_scoping_test.rb +197 -75
- data/test/cases/secure_token_test.rb +18 -3
- data/test/cases/serialization_test.rb +30 -28
- data/test/cases/serialized_attribute_test.rb +133 -42
- data/test/cases/signed_id_test.rb +168 -0
- data/test/cases/statement_cache_test.rb +41 -24
- data/test/cases/statement_invalid_test.rb +42 -0
- data/test/cases/store_test.rb +180 -55
- data/test/cases/strict_loading_test.rb +473 -0
- data/test/cases/suppressor_test.rb +26 -12
- data/test/cases/tasks/database_tasks_test.rb +1258 -194
- data/test/cases/tasks/mysql_rake_test.rb +370 -298
- data/test/cases/tasks/postgresql_rake_test.rb +481 -251
- data/test/cases/tasks/sqlite_rake_test.rb +225 -178
- data/test/cases/test_case.rb +51 -40
- data/test/cases/test_databases_test.rb +79 -0
- data/test/cases/test_fixtures_test.rb +79 -19
- data/test/cases/time_precision_test.rb +98 -76
- data/test/cases/timestamp_test.rb +102 -99
- data/test/cases/touch_later_test.rb +12 -10
- data/test/cases/transaction_callbacks_test.rb +344 -90
- data/test/cases/transaction_isolation_test.rb +12 -12
- data/test/cases/transactions_test.rb +612 -162
- data/test/cases/type/adapter_specific_registry_test.rb +14 -2
- data/test/cases/type/date_time_test.rb +4 -2
- data/test/cases/type/integer_test.rb +4 -2
- data/test/cases/type/string_test.rb +10 -8
- data/test/cases/type/time_test.rb +28 -0
- data/test/cases/type/type_map_test.rb +29 -28
- data/test/cases/type/unsigned_integer_test.rb +19 -0
- data/test/cases/type_test.rb +2 -0
- data/test/cases/types_test.rb +3 -1
- data/test/cases/unconnected_test.rb +14 -1
- data/test/cases/unsafe_raw_sql_test.rb +274 -0
- data/test/cases/validations/absence_validation_test.rb +19 -17
- data/test/cases/validations/association_validation_test.rb +30 -28
- data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
- data/test/cases/validations/i18n_validation_test.rb +22 -21
- data/test/cases/validations/length_validation_test.rb +34 -33
- data/test/cases/validations/numericality_validation_test.rb +181 -0
- data/test/cases/validations/presence_validation_test.rb +21 -19
- data/test/cases/validations/uniqueness_validation_test.rb +156 -86
- data/test/cases/validations_repair_helper.rb +2 -0
- data/test/cases/validations_test.rb +61 -26
- data/test/cases/view_test.rb +122 -116
- data/test/cases/yaml_serialization_test.rb +79 -34
- data/test/config.example.yml +19 -19
- data/test/config.rb +3 -1
- data/test/config.yml +16 -6
- data/test/fixtures/all/namespaced/accounts.yml +2 -0
- data/test/fixtures/author_addresses.yml +1 -8
- data/test/fixtures/authors.yml +1 -7
- data/test/fixtures/binaries.yml +4 -0
- data/test/fixtures/books.yml +9 -2
- data/test/fixtures/categories_posts.yml +3 -0
- data/test/fixtures/citations.yml +5 -0
- data/test/fixtures/comments.yml +7 -0
- data/test/fixtures/companies.yml +5 -0
- data/test/fixtures/computers.yml +2 -0
- data/test/fixtures/customers.yml +10 -1
- data/test/fixtures/developers.yml +1 -1
- data/test/fixtures/essays.yml +10 -0
- data/test/fixtures/faces.yml +3 -3
- data/test/fixtures/humans.yml +5 -0
- data/test/fixtures/interests.yml +7 -7
- data/test/fixtures/memberships.yml +7 -0
- data/test/fixtures/minimalistics.yml +3 -0
- data/test/fixtures/mixed_case_monkeys.yml +2 -2
- data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
- data/test/fixtures/naked/yml/parrots.yml +1 -0
- data/test/fixtures/other_books.yml +26 -0
- data/test/fixtures/other_posts.yml +1 -0
- data/test/fixtures/parrots.yml +7 -1
- data/test/fixtures/pirates.yml +3 -0
- data/test/fixtures/posts.yml +11 -3
- data/test/fixtures/readers.yml +6 -0
- data/test/fixtures/reserved_words/values.yml +2 -2
- data/test/fixtures/sponsors.yml +3 -0
- data/test/fixtures/strict_zines.yml +2 -0
- data/test/fixtures/subscribers.yml +1 -1
- data/test/fixtures/tasks.yml +1 -1
- data/test/fixtures/warehouse-things.yml +3 -0
- data/test/migrations/10_urban/9_add_expressions.rb +2 -0
- data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
- data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
- data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
- data/test/migrations/missing/1_people_have_last_names.rb +2 -0
- data/test/migrations/missing/3_we_need_reminders.rb +2 -0
- data/test/migrations/missing/4_innocent_jointable.rb +3 -1
- data/test/migrations/rename/1_we_need_things.rb +2 -0
- data/test/migrations/rename/2_rename_things.rb +2 -0
- data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
- data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
- data/test/migrations/to_copy2/1_create_articles.rb +2 -0
- data/test/migrations/to_copy2/2_create_comments.rb +3 -1
- data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
- data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
- data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
- data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
- data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
- data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
- data/test/migrations/valid/2_we_need_reminders.rb +2 -0
- data/test/migrations/valid/3_innocent_jointable.rb +3 -1
- data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
- data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
- data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
- data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
- data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
- data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
- data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
- data/test/models/account.rb +46 -0
- data/test/models/admin/account.rb +3 -1
- data/test/models/admin/randomly_named_c1.rb +2 -0
- data/test/models/admin/user.rb +16 -8
- data/test/models/admin.rb +4 -2
- data/test/models/aircraft.rb +3 -1
- data/test/models/arunit2_model.rb +2 -0
- data/test/models/author.rb +153 -102
- data/test/models/auto_id.rb +2 -0
- data/test/models/autoloadable/extra_firm.rb +2 -0
- data/test/models/binary.rb +3 -1
- data/test/models/binary_field.rb +6 -0
- data/test/models/bird.rb +13 -1
- data/test/models/book.rb +14 -4
- data/test/models/book_destroy_async.rb +24 -0
- data/test/models/boolean.rb +5 -0
- data/test/models/bulb.rb +13 -4
- data/test/models/cake_designer.rb +2 -0
- data/test/models/car.rb +17 -10
- data/test/models/carrier.rb +2 -0
- data/test/models/cart.rb +5 -0
- data/test/models/cat.rb +2 -0
- data/test/models/categorization.rb +8 -6
- data/test/models/category.rb +28 -16
- data/test/models/chef.rb +2 -0
- data/test/models/citation.rb +5 -1
- data/test/models/club.rb +13 -10
- data/test/models/college.rb +4 -2
- data/test/models/column.rb +2 -0
- data/test/models/column_name.rb +2 -0
- data/test/models/comment.rb +32 -10
- data/test/models/company.rb +102 -106
- data/test/models/company_in_module.rb +27 -26
- data/test/models/computer.rb +3 -1
- data/test/models/contact.rb +15 -13
- data/test/models/content.rb +5 -3
- data/test/models/contract.rb +21 -3
- data/test/models/country.rb +2 -4
- data/test/models/course.rb +3 -1
- data/test/models/customer.rb +10 -8
- data/test/models/customer_carrier.rb +2 -0
- data/test/models/dashboard.rb +2 -0
- data/test/models/default.rb +2 -0
- data/test/models/department.rb +2 -0
- data/test/models/destroy_async_parent.rb +15 -0
- data/test/models/destroy_async_parent_soft_delete.rb +20 -0
- data/test/models/developer.rb +152 -85
- data/test/models/dl_keyed_belongs_to.rb +13 -0
- data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
- data/test/models/dl_keyed_has_many.rb +5 -0
- data/test/models/dl_keyed_has_many_through.rb +5 -0
- data/test/models/dl_keyed_has_one.rb +5 -0
- data/test/models/dl_keyed_join.rb +10 -0
- data/test/models/dog.rb +2 -0
- data/test/models/dog_lover.rb +2 -0
- data/test/models/doubloon.rb +3 -1
- data/test/models/drink_designer.rb +17 -0
- data/test/models/edge.rb +4 -2
- data/test/models/electron.rb +2 -0
- data/test/models/engine.rb +3 -2
- data/test/models/entrant.rb +2 -0
- data/test/models/entry.rb +5 -0
- data/test/models/essay.rb +6 -3
- data/test/models/essay_destroy_async.rb +12 -0
- data/test/models/event.rb +3 -1
- data/test/models/eye.rb +5 -3
- data/test/models/face.rb +14 -6
- data/test/models/family.rb +6 -0
- data/test/models/family_tree.rb +6 -0
- data/test/models/friendship.rb +5 -3
- data/test/models/frog.rb +8 -0
- data/test/models/guid.rb +3 -1
- data/test/models/guitar.rb +2 -0
- data/test/models/hotel.rb +5 -3
- data/test/models/human.rb +39 -0
- data/test/models/image.rb +3 -1
- data/test/models/interest.rb +14 -3
- data/test/models/invoice.rb +4 -2
- data/test/models/item.rb +3 -1
- data/test/models/job.rb +5 -3
- data/test/models/joke.rb +4 -2
- data/test/models/keyboard.rb +3 -1
- data/test/models/legacy_thing.rb +2 -0
- data/test/models/lesson.rb +2 -0
- data/test/models/line_item.rb +3 -1
- data/test/models/liquid.rb +2 -0
- data/test/models/matey.rb +3 -1
- data/test/models/measurement.rb +4 -0
- data/test/models/member.rb +23 -20
- data/test/models/member_detail.rb +3 -0
- data/test/models/member_type.rb +2 -0
- data/test/models/membership.rb +4 -1
- data/test/models/mentor.rb +3 -1
- data/test/models/message.rb +5 -0
- data/test/models/minimalistic.rb +2 -0
- data/test/models/minivan.rb +3 -2
- data/test/models/mixed_case_monkey.rb +3 -1
- data/test/models/molecule.rb +2 -0
- data/test/models/mouse.rb +6 -0
- data/test/models/movie.rb +2 -0
- data/test/models/node.rb +4 -2
- data/test/models/non_primary_key.rb +2 -0
- data/test/models/notification.rb +2 -0
- data/test/models/numeric_data.rb +12 -0
- data/test/models/order.rb +4 -2
- data/test/models/organization.rb +9 -7
- data/test/models/other_dog.rb +3 -1
- data/test/models/owner.rb +6 -4
- data/test/models/parrot.rb +12 -4
- data/test/models/person.rb +59 -54
- data/test/models/personal_legacy_thing.rb +3 -1
- data/test/models/pet.rb +4 -2
- data/test/models/pet_treasure.rb +2 -0
- data/test/models/pirate.rb +67 -43
- data/test/models/possession.rb +3 -1
- data/test/models/post.rb +184 -86
- data/test/models/price_estimate.rb +11 -1
- data/test/models/professor.rb +3 -1
- data/test/models/project.rb +14 -12
- data/test/models/publisher/article.rb +2 -0
- data/test/models/publisher/magazine.rb +2 -0
- data/test/models/publisher.rb +2 -0
- data/test/models/randomly_named_c1.rb +2 -0
- data/test/models/rating.rb +5 -1
- data/test/models/reader.rb +7 -5
- data/test/models/recipe.rb +2 -0
- data/test/models/record.rb +2 -0
- data/test/models/reference.rb +6 -3
- data/test/models/reply.rb +39 -21
- data/test/models/room.rb +6 -0
- data/test/models/section.rb +6 -0
- data/test/models/seminar.rb +6 -0
- data/test/models/session.rb +6 -0
- data/test/models/ship.rb +12 -9
- data/test/models/ship_part.rb +5 -3
- data/test/models/shop.rb +4 -2
- data/test/models/shop_account.rb +2 -0
- data/test/models/speedometer.rb +2 -0
- data/test/models/sponsor.rb +8 -5
- data/test/models/squeak.rb +6 -0
- data/test/models/strict_zine.rb +7 -0
- data/test/models/string_key_object.rb +2 -0
- data/test/models/student.rb +2 -0
- data/test/models/subscriber.rb +4 -2
- data/test/models/subscription.rb +5 -1
- data/test/models/tag.rb +6 -3
- data/test/models/tagging.rb +13 -6
- data/test/models/task.rb +2 -0
- data/test/models/topic.rb +54 -19
- data/test/models/toy.rb +4 -0
- data/test/models/traffic_light.rb +2 -0
- data/test/models/treasure.rb +5 -3
- data/test/models/treaty.rb +2 -4
- data/test/models/tree.rb +2 -0
- data/test/models/tuning_peg.rb +2 -0
- data/test/models/tyre.rb +2 -0
- data/test/models/user.rb +12 -4
- data/test/models/uuid_child.rb +2 -0
- data/test/models/uuid_item.rb +2 -0
- data/test/models/uuid_parent.rb +2 -0
- data/test/models/vegetables.rb +12 -3
- data/test/models/vertex.rb +6 -4
- data/test/models/warehouse_thing.rb +2 -0
- data/test/models/wheel.rb +3 -1
- data/test/models/without_table.rb +3 -1
- data/test/models/zine.rb +3 -1
- data/test/schema/mysql2_specific_schema.rb +49 -35
- data/test/schema/oracle_specific_schema.rb +13 -15
- data/test/schema/postgresql_specific_schema.rb +51 -40
- data/test/schema/schema.rb +334 -154
- data/test/schema/sqlite_specific_schema.rb +9 -16
- data/test/support/config.rb +26 -26
- data/test/support/connection.rb +14 -8
- data/test/support/connection_helper.rb +3 -1
- data/test/support/ddl_helper.rb +2 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
- data/test/support/schema_dumping_helper.rb +2 -0
- data/test/support/stubs/strong_parameters.rb +40 -0
- data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
- data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
- metadata +192 -14
data/test/cases/locking_test.rb
CHANGED
@@ -1,24 +1,27 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "thread"
|
2
4
|
require "cases/helper"
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
5
|
+
require "models/person"
|
6
|
+
require "models/job"
|
7
|
+
require "models/reader"
|
8
|
+
require "models/ship"
|
9
|
+
require "models/legacy_thing"
|
10
|
+
require "models/personal_legacy_thing"
|
11
|
+
require "models/reference"
|
12
|
+
require "models/string_key_object"
|
13
|
+
require "models/car"
|
14
|
+
require "models/bulb"
|
15
|
+
require "models/engine"
|
16
|
+
require "models/wheel"
|
17
|
+
require "models/treasure"
|
18
|
+
require "models/frog"
|
16
19
|
|
17
20
|
class LockWithoutDefault < ActiveRecord::Base; end
|
18
21
|
|
19
22
|
class LockWithCustomColumnWithoutDefault < ActiveRecord::Base
|
20
23
|
self.table_name = :lock_without_defaults_cust
|
21
|
-
|
24
|
+
column_defaults # to test @column_defaults caching.
|
22
25
|
self.locking_column = :custom_lock_version
|
23
26
|
end
|
24
27
|
|
@@ -33,7 +36,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|
33
36
|
p1 = Person.find(1)
|
34
37
|
assert_equal 0, p1.lock_version
|
35
38
|
|
36
|
-
p1.first_name =
|
39
|
+
p1.first_name = "anika2"
|
37
40
|
p1.save!
|
38
41
|
|
39
42
|
assert_equal 1, p1.lock_version
|
@@ -45,12 +48,12 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|
45
48
|
assert_equal 0, s1.lock_version
|
46
49
|
assert_equal 0, s2.lock_version
|
47
50
|
|
48
|
-
s1.name =
|
51
|
+
s1.name = "updated record"
|
49
52
|
s1.save!
|
50
53
|
assert_equal 1, s1.lock_version
|
51
54
|
assert_equal 0, s2.lock_version
|
52
55
|
|
53
|
-
s2.name =
|
56
|
+
s2.name = "doubly updated record"
|
54
57
|
assert_raise(ActiveRecord::StaleObjectError) { s2.save! }
|
55
58
|
end
|
56
59
|
|
@@ -60,15 +63,15 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|
60
63
|
assert_equal 0, s1.lock_version
|
61
64
|
assert_equal 0, s2.lock_version
|
62
65
|
|
63
|
-
s1.name =
|
66
|
+
s1.name = "updated record"
|
64
67
|
s1.save!
|
65
68
|
assert_equal 1, s1.lock_version
|
66
69
|
assert_equal 0, s2.lock_version
|
67
70
|
assert_raise(ActiveRecord::StaleObjectError) { s2.destroy }
|
68
71
|
|
69
72
|
assert s1.destroy
|
70
|
-
|
71
|
-
|
73
|
+
assert_predicate s1, :frozen?
|
74
|
+
assert_predicate s1, :destroyed?
|
72
75
|
assert_raises(ActiveRecord::RecordNotFound) { StringKeyObject.find("record1") }
|
73
76
|
end
|
74
77
|
|
@@ -78,12 +81,12 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|
78
81
|
assert_equal 0, p1.lock_version
|
79
82
|
assert_equal 0, p2.lock_version
|
80
83
|
|
81
|
-
p1.first_name =
|
84
|
+
p1.first_name = "stu"
|
82
85
|
p1.save!
|
83
86
|
assert_equal 1, p1.lock_version
|
84
87
|
assert_equal 0, p2.lock_version
|
85
88
|
|
86
|
-
p2.first_name =
|
89
|
+
p2.first_name = "sue"
|
87
90
|
assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
|
88
91
|
end
|
89
92
|
|
@@ -94,7 +97,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|
94
97
|
assert_equal 0, p1.lock_version
|
95
98
|
assert_equal 0, p2.lock_version
|
96
99
|
|
97
|
-
p1.first_name =
|
100
|
+
p1.first_name = "stu"
|
98
101
|
p1.save!
|
99
102
|
assert_equal 1, p1.lock_version
|
100
103
|
assert_equal 0, p2.lock_version
|
@@ -102,8 +105,8 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|
102
105
|
assert_raises(ActiveRecord::StaleObjectError) { p2.destroy }
|
103
106
|
|
104
107
|
assert p1.destroy
|
105
|
-
|
106
|
-
|
108
|
+
assert_predicate p1, :frozen?
|
109
|
+
assert_predicate p1, :destroyed?
|
107
110
|
assert_raises(ActiveRecord::RecordNotFound) { Person.find(1) }
|
108
111
|
end
|
109
112
|
|
@@ -113,66 +116,64 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|
113
116
|
assert_equal 0, p1.lock_version
|
114
117
|
assert_equal 0, p2.lock_version
|
115
118
|
|
116
|
-
p1.first_name =
|
119
|
+
p1.first_name = "stu"
|
117
120
|
p1.save!
|
118
121
|
assert_equal 1, p1.lock_version
|
119
122
|
assert_equal 0, p2.lock_version
|
120
123
|
|
121
|
-
p2.first_name =
|
124
|
+
p2.first_name = "sue"
|
122
125
|
assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
|
123
|
-
p2.first_name =
|
126
|
+
p2.first_name = "sue2"
|
124
127
|
assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
|
125
128
|
end
|
126
129
|
|
127
130
|
def test_lock_new
|
128
|
-
p1 = Person.new(:
|
131
|
+
p1 = Person.new(first_name: "anika")
|
129
132
|
assert_equal 0, p1.lock_version
|
130
133
|
|
131
|
-
p1.first_name =
|
134
|
+
p1.first_name = "anika2"
|
132
135
|
p1.save!
|
133
136
|
p2 = Person.find(p1.id)
|
134
137
|
assert_equal 0, p1.lock_version
|
135
138
|
assert_equal 0, p2.lock_version
|
136
139
|
|
137
|
-
p1.first_name =
|
140
|
+
p1.first_name = "anika3"
|
138
141
|
p1.save!
|
139
142
|
assert_equal 1, p1.lock_version
|
140
143
|
assert_equal 0, p2.lock_version
|
141
144
|
|
142
|
-
p2.first_name =
|
145
|
+
p2.first_name = "sue"
|
143
146
|
assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
|
144
147
|
end
|
145
148
|
|
146
149
|
def test_lock_exception_record
|
147
|
-
p1 = Person.new(:
|
150
|
+
p1 = Person.new(first_name: "mira")
|
148
151
|
assert_equal 0, p1.lock_version
|
149
152
|
|
150
|
-
p1.first_name =
|
153
|
+
p1.first_name = "mira2"
|
151
154
|
p1.save!
|
152
155
|
p2 = Person.find(p1.id)
|
153
156
|
assert_equal 0, p1.lock_version
|
154
157
|
assert_equal 0, p2.lock_version
|
155
158
|
|
156
|
-
p1.first_name =
|
159
|
+
p1.first_name = "mira3"
|
157
160
|
p1.save!
|
158
161
|
|
159
|
-
p2.first_name =
|
162
|
+
p2.first_name = "sue"
|
160
163
|
error = assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
|
161
|
-
|
164
|
+
assert_same error.record, p2
|
162
165
|
end
|
163
166
|
|
164
|
-
def
|
165
|
-
p1 = Person.new(:
|
166
|
-
p1.save!
|
167
|
-
p1.lock_version = nil # simulate bad fixture or column with no default
|
167
|
+
def test_lock_new_when_explicitly_passing_nil
|
168
|
+
p1 = Person.new(first_name: "anika", lock_version: nil)
|
168
169
|
p1.save!
|
169
|
-
assert_equal
|
170
|
+
assert_equal 0, p1.lock_version
|
170
171
|
end
|
171
172
|
|
172
|
-
def
|
173
|
-
p1 = Person.new(:
|
173
|
+
def test_lock_new_when_explicitly_passing_value
|
174
|
+
p1 = Person.new(first_name: "Douglas Adams", lock_version: 42)
|
174
175
|
p1.save!
|
175
|
-
assert_equal
|
176
|
+
assert_equal 42, p1.lock_version
|
176
177
|
end
|
177
178
|
|
178
179
|
def test_touch_existing_lock
|
@@ -181,16 +182,73 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|
181
182
|
|
182
183
|
p1.touch
|
183
184
|
assert_equal 1, p1.lock_version
|
185
|
+
assert_not_predicate p1, :changed?, "Changes should have been cleared"
|
186
|
+
assert_predicate p1, :saved_changes?
|
187
|
+
assert_equal ["lock_version", "updated_at"], p1.saved_changes.keys.sort
|
184
188
|
end
|
185
189
|
|
186
190
|
def test_touch_stale_object
|
187
|
-
person = Person.create!(first_name:
|
191
|
+
person = Person.create!(first_name: "Mehmet Emin")
|
188
192
|
stale_person = Person.find(person.id)
|
189
|
-
person.update_attribute(:gender,
|
193
|
+
person.update_attribute(:gender, "M")
|
190
194
|
|
191
195
|
assert_raises(ActiveRecord::StaleObjectError) do
|
192
196
|
stale_person.touch
|
193
197
|
end
|
198
|
+
|
199
|
+
assert_not_predicate stale_person, :saved_changes?
|
200
|
+
end
|
201
|
+
|
202
|
+
def test_update_with_dirty_primary_key
|
203
|
+
assert_raises(ActiveRecord::RecordNotUnique) do
|
204
|
+
person = Person.find(1)
|
205
|
+
person.id = 2
|
206
|
+
person.save!
|
207
|
+
end
|
208
|
+
|
209
|
+
person = Person.find(1)
|
210
|
+
person.id = 42
|
211
|
+
person.save!
|
212
|
+
|
213
|
+
assert Person.find(42)
|
214
|
+
assert_raises(ActiveRecord::RecordNotFound) do
|
215
|
+
Person.find(1)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_delete_with_dirty_primary_key
|
220
|
+
person = Person.find(1)
|
221
|
+
person.id = 2
|
222
|
+
person.delete
|
223
|
+
|
224
|
+
assert Person.find(2)
|
225
|
+
assert_raises(ActiveRecord::RecordNotFound) do
|
226
|
+
Person.find(1)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_destroy_with_dirty_primary_key
|
231
|
+
person = Person.find(1)
|
232
|
+
person.id = 2
|
233
|
+
person.destroy
|
234
|
+
|
235
|
+
assert Person.find(2)
|
236
|
+
assert_raises(ActiveRecord::RecordNotFound) do
|
237
|
+
Person.find(1)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_explicit_update_lock_column_raise_error
|
242
|
+
person = Person.find(1)
|
243
|
+
|
244
|
+
assert_raises(ActiveRecord::StaleObjectError) do
|
245
|
+
person.first_name = "Douglas Adams"
|
246
|
+
person.lock_version = 42
|
247
|
+
|
248
|
+
assert_predicate person, :lock_version_changed?
|
249
|
+
|
250
|
+
person.save
|
251
|
+
end
|
194
252
|
end
|
195
253
|
|
196
254
|
def test_lock_column_name_existing
|
@@ -209,11 +267,11 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|
209
267
|
end
|
210
268
|
|
211
269
|
def test_lock_column_is_mass_assignable
|
212
|
-
p1 = Person.create(:
|
270
|
+
p1 = Person.create(first_name: "bianca")
|
213
271
|
assert_equal 0, p1.lock_version
|
214
272
|
assert_equal p1.lock_version, Person.new(p1.attributes).lock_version
|
215
273
|
|
216
|
-
p1.first_name =
|
274
|
+
p1.first_name = "bianca2"
|
217
275
|
p1.save!
|
218
276
|
assert_equal 1, p1.lock_version
|
219
277
|
assert_equal p1.lock_version, Person.new(p1.attributes).lock_version
|
@@ -221,28 +279,182 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|
221
279
|
|
222
280
|
def test_lock_without_default_sets_version_to_zero
|
223
281
|
t1 = LockWithoutDefault.new
|
282
|
+
|
283
|
+
assert_equal 0, t1.lock_version
|
284
|
+
assert_nil t1.lock_version_before_type_cast
|
285
|
+
|
286
|
+
t1.save!
|
287
|
+
t1.reload
|
288
|
+
|
289
|
+
assert_equal 0, t1.lock_version
|
290
|
+
assert_equal 0, t1.lock_version_before_type_cast
|
291
|
+
end
|
292
|
+
|
293
|
+
def test_touch_existing_lock_without_default_should_work_with_null_in_the_database
|
294
|
+
ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
|
295
|
+
t1 = LockWithoutDefault.last
|
296
|
+
|
297
|
+
assert_equal 0, t1.lock_version
|
298
|
+
assert_nil t1.lock_version_before_type_cast
|
299
|
+
|
300
|
+
t1.touch
|
301
|
+
|
302
|
+
assert_equal 1, t1.lock_version
|
303
|
+
assert_not_predicate t1, :changed?
|
304
|
+
assert_predicate t1, :saved_changes?
|
305
|
+
assert_equal ["lock_version", "updated_at"], t1.saved_changes.keys.sort
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_touch_stale_object_with_lock_without_default
|
309
|
+
t1 = LockWithoutDefault.create!(title: "title1")
|
310
|
+
stale_object = LockWithoutDefault.find(t1.id)
|
311
|
+
|
312
|
+
t1.update!(title: "title2")
|
313
|
+
|
314
|
+
assert_raises(ActiveRecord::StaleObjectError) do
|
315
|
+
stale_object.touch
|
316
|
+
end
|
317
|
+
|
318
|
+
assert_not_predicate stale_object, :saved_changes?
|
319
|
+
end
|
320
|
+
|
321
|
+
def test_lock_without_default_should_work_with_null_in_the_database
|
322
|
+
ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
|
323
|
+
t1 = LockWithoutDefault.last
|
324
|
+
t2 = LockWithoutDefault.find(t1.id)
|
325
|
+
|
326
|
+
assert_equal 0, t1.lock_version
|
327
|
+
assert_nil t1.lock_version_before_type_cast
|
328
|
+
assert_equal 0, t2.lock_version
|
329
|
+
assert_nil t2.lock_version_before_type_cast
|
330
|
+
|
331
|
+
t1.title = "new title1"
|
332
|
+
t2.title = "new title2"
|
333
|
+
|
334
|
+
assert_nothing_raised { t1.save! }
|
335
|
+
assert_equal 1, t1.lock_version
|
336
|
+
assert_equal "new title1", t1.title
|
337
|
+
|
338
|
+
assert_raise(ActiveRecord::StaleObjectError) { t2.save! }
|
339
|
+
assert_equal 0, t2.lock_version
|
340
|
+
assert_equal "new title2", t2.title
|
341
|
+
end
|
342
|
+
|
343
|
+
def test_update_with_lock_version_without_default_should_work_on_dirty_value_before_type_cast
|
344
|
+
ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
|
345
|
+
t1 = LockWithoutDefault.last
|
346
|
+
|
224
347
|
assert_equal 0, t1.lock_version
|
348
|
+
assert_nil t1.lock_version_before_type_cast
|
349
|
+
|
350
|
+
t1.lock_version = t1.lock_version
|
225
351
|
|
226
|
-
t1.save
|
227
|
-
t1 = LockWithoutDefault.find(t1.id)
|
228
352
|
assert_equal 0, t1.lock_version
|
353
|
+
assert_equal 0, t1.lock_version_before_type_cast
|
354
|
+
|
355
|
+
assert_nothing_raised { t1.update!(title: "new title1") }
|
356
|
+
assert_equal 1, t1.lock_version
|
357
|
+
assert_equal "new title1", t1.title
|
358
|
+
end
|
359
|
+
|
360
|
+
def test_destroy_with_lock_version_without_default_should_work_on_dirty_value_before_type_cast
|
361
|
+
ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
|
362
|
+
t1 = LockWithoutDefault.last
|
363
|
+
|
364
|
+
assert_equal 0, t1.lock_version
|
365
|
+
assert_nil t1.lock_version_before_type_cast
|
366
|
+
|
367
|
+
t1.lock_version = t1.lock_version
|
368
|
+
|
369
|
+
assert_equal 0, t1.lock_version
|
370
|
+
assert_equal 0, t1.lock_version_before_type_cast
|
371
|
+
|
372
|
+
assert_nothing_raised { t1.destroy! }
|
373
|
+
assert_predicate t1, :destroyed?
|
374
|
+
end
|
375
|
+
|
376
|
+
def test_lock_without_default_queries_count
|
377
|
+
t1 = LockWithoutDefault.create(title: "title1")
|
378
|
+
|
379
|
+
assert_equal "title1", t1.title
|
380
|
+
assert_equal 0, t1.lock_version
|
381
|
+
|
382
|
+
assert_queries(1) { t1.update(title: "title2") }
|
383
|
+
|
384
|
+
t1.reload
|
385
|
+
assert_equal "title2", t1.title
|
386
|
+
assert_equal 1, t1.lock_version
|
387
|
+
|
388
|
+
t2 = LockWithoutDefault.new(title: "title1")
|
389
|
+
|
390
|
+
assert_queries(1) { t2.save! }
|
391
|
+
|
392
|
+
t2.reload
|
393
|
+
assert_equal "title1", t2.title
|
394
|
+
assert_equal 0, t2.lock_version
|
229
395
|
end
|
230
396
|
|
231
397
|
def test_lock_with_custom_column_without_default_sets_version_to_zero
|
232
398
|
t1 = LockWithCustomColumnWithoutDefault.new
|
399
|
+
|
233
400
|
assert_equal 0, t1.custom_lock_version
|
234
401
|
assert_nil t1.custom_lock_version_before_type_cast
|
235
402
|
|
236
403
|
t1.save!
|
237
404
|
t1.reload
|
405
|
+
|
406
|
+
assert_equal 0, t1.custom_lock_version
|
407
|
+
assert_equal 0, t1.custom_lock_version_before_type_cast
|
408
|
+
end
|
409
|
+
|
410
|
+
def test_lock_with_custom_column_without_default_should_work_with_null_in_the_database
|
411
|
+
ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults_cust(title) VALUES('title1')")
|
412
|
+
|
413
|
+
t1 = LockWithCustomColumnWithoutDefault.last
|
414
|
+
t2 = LockWithCustomColumnWithoutDefault.find(t1.id)
|
415
|
+
|
416
|
+
assert_equal 0, t1.custom_lock_version
|
417
|
+
assert_nil t1.custom_lock_version_before_type_cast
|
418
|
+
assert_equal 0, t2.custom_lock_version
|
419
|
+
assert_nil t2.custom_lock_version_before_type_cast
|
420
|
+
|
421
|
+
t1.title = "new title1"
|
422
|
+
t2.title = "new title2"
|
423
|
+
|
424
|
+
assert_nothing_raised { t1.save! }
|
425
|
+
assert_equal 1, t1.custom_lock_version
|
426
|
+
assert_equal "new title1", t1.title
|
427
|
+
|
428
|
+
assert_raise(ActiveRecord::StaleObjectError) { t2.save! }
|
429
|
+
assert_equal 0, t2.custom_lock_version
|
430
|
+
assert_equal "new title2", t2.title
|
431
|
+
end
|
432
|
+
|
433
|
+
def test_lock_with_custom_column_without_default_queries_count
|
434
|
+
t1 = LockWithCustomColumnWithoutDefault.create(title: "title1")
|
435
|
+
|
436
|
+
assert_equal "title1", t1.title
|
238
437
|
assert_equal 0, t1.custom_lock_version
|
239
|
-
|
438
|
+
|
439
|
+
assert_queries(1) { t1.update(title: "title2") }
|
440
|
+
|
441
|
+
t1.reload
|
442
|
+
assert_equal "title2", t1.title
|
443
|
+
assert_equal 1, t1.custom_lock_version
|
444
|
+
|
445
|
+
t2 = LockWithCustomColumnWithoutDefault.new(title: "title1")
|
446
|
+
|
447
|
+
assert_queries(1) { t2.save! }
|
448
|
+
|
449
|
+
t2.reload
|
450
|
+
assert_equal "title1", t2.title
|
451
|
+
assert_equal 0, t2.custom_lock_version
|
240
452
|
end
|
241
453
|
|
242
454
|
def test_readonly_attributes
|
243
|
-
assert_equal Set.new([
|
455
|
+
assert_equal Set.new([ "name" ]), ReadonlyNameShip.readonly_attributes
|
244
456
|
|
245
|
-
s = ReadonlyNameShip.create(:
|
457
|
+
s = ReadonlyNameShip.create(name: "unchangeable name")
|
246
458
|
s.reload
|
247
459
|
assert_equal "unchangeable name", s.name
|
248
460
|
|
@@ -261,7 +473,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|
261
473
|
# is nothing else being updated.
|
262
474
|
def test_update_without_attributes_does_not_only_update_lock_version
|
263
475
|
assert_nothing_raised do
|
264
|
-
p1 = Person.create!(:
|
476
|
+
p1 = Person.create!(first_name: "anika")
|
265
477
|
lock_version = p1.lock_version
|
266
478
|
p1.save
|
267
479
|
p1.reload
|
@@ -269,30 +481,77 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|
269
481
|
end
|
270
482
|
end
|
271
483
|
|
484
|
+
def test_counter_cache_with_touch_and_lock_version
|
485
|
+
car = Car.create!
|
486
|
+
|
487
|
+
assert_equal 0, car.wheels_count
|
488
|
+
assert_equal 0, car.lock_version
|
489
|
+
|
490
|
+
previously_updated_at = car.updated_at
|
491
|
+
previously_wheels_owned_at = car.wheels_owned_at
|
492
|
+
travel(1.second) do
|
493
|
+
Wheel.create!(wheelable: car)
|
494
|
+
end
|
495
|
+
|
496
|
+
assert_equal 1, car.reload.wheels_count
|
497
|
+
assert_equal 1, car.lock_version
|
498
|
+
assert_operator previously_updated_at, :<, car.updated_at
|
499
|
+
assert_operator previously_wheels_owned_at, :<, car.wheels_owned_at
|
500
|
+
|
501
|
+
previously_updated_at = car.updated_at
|
502
|
+
previously_wheels_owned_at = car.wheels_owned_at
|
503
|
+
travel(2.second) do
|
504
|
+
car.wheels.first.update(size: 42)
|
505
|
+
end
|
506
|
+
|
507
|
+
assert_equal 1, car.reload.wheels_count
|
508
|
+
assert_equal 2, car.lock_version
|
509
|
+
assert_operator previously_updated_at, :<, car.updated_at
|
510
|
+
assert_operator previously_wheels_owned_at, :<, car.wheels_owned_at
|
511
|
+
|
512
|
+
previously_updated_at = car.updated_at
|
513
|
+
previously_wheels_owned_at = car.wheels_owned_at
|
514
|
+
travel(3.second) do
|
515
|
+
car.wheels.first.destroy!
|
516
|
+
end
|
517
|
+
|
518
|
+
assert_equal 0, car.reload.wheels_count
|
519
|
+
assert_equal 3, car.lock_version
|
520
|
+
assert_operator previously_updated_at, :<, car.updated_at
|
521
|
+
assert_operator previously_wheels_owned_at, :<, car.wheels_owned_at
|
522
|
+
|
523
|
+
car.wheels << Wheel.create!
|
524
|
+
assert_equal 1, car.wheels_count
|
525
|
+
assert_equal 4, car.lock_version
|
526
|
+
assert_not car.lock_version_changed?
|
527
|
+
assert_nothing_raised { car.update(name: "herbie") }
|
528
|
+
end
|
529
|
+
|
272
530
|
def test_polymorphic_destroy_with_dependencies_and_lock_version
|
273
531
|
car = Car.create!
|
274
532
|
|
275
|
-
assert_difference
|
276
|
-
car.wheels
|
533
|
+
assert_difference "car.wheels.count" do
|
534
|
+
car.wheels.create
|
277
535
|
end
|
278
|
-
assert_difference
|
536
|
+
assert_difference "car.wheels.count", -1 do
|
279
537
|
car.reload.destroy
|
280
538
|
end
|
281
|
-
|
539
|
+
assert_predicate car, :destroyed?
|
282
540
|
end
|
283
541
|
|
284
542
|
def test_removing_has_and_belongs_to_many_associations_upon_destroy
|
285
|
-
p = RichPerson.create! first_name:
|
543
|
+
p = RichPerson.create! first_name: "Jon"
|
286
544
|
p.treasures.create!
|
287
|
-
|
545
|
+
assert_not_empty p.treasures
|
288
546
|
p.destroy
|
289
|
-
|
290
|
-
|
547
|
+
assert_empty p.treasures
|
548
|
+
assert_empty RichPerson.connection.select_all("SELECT * FROM peoples_treasures WHERE rich_person_id = 1")
|
291
549
|
end
|
292
550
|
|
293
551
|
def test_yaml_dumping_with_lock_column
|
294
552
|
t1 = LockWithoutDefault.new
|
295
|
-
|
553
|
+
payload = YAML.dump(t1)
|
554
|
+
t2 = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(payload) : YAML.load(payload)
|
296
555
|
|
297
556
|
assert_equal t1.attributes, t2.attributes
|
298
557
|
end
|
@@ -306,7 +565,7 @@ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
|
|
306
565
|
# of a test (see test_increment_counter_*).
|
307
566
|
self.use_transactional_tests = false
|
308
567
|
|
309
|
-
{ :
|
568
|
+
{ lock_version: Person, custom_lock_version: LegacyThing }.each do |name, model|
|
310
569
|
define_method("test_increment_counter_updates_#{name}") do
|
311
570
|
counter_test model, 1 do |id|
|
312
571
|
model.increment_counter :test_count, id
|
@@ -321,7 +580,7 @@ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
|
|
321
580
|
|
322
581
|
define_method("test_update_counters_updates_#{name}") do
|
323
582
|
counter_test model, 1 do |id|
|
324
|
-
model.update_counters id, :
|
583
|
+
model.update_counters id, test_count: 1
|
325
584
|
end
|
326
585
|
end
|
327
586
|
end
|
@@ -329,13 +588,13 @@ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
|
|
329
588
|
# See Lighthouse ticket #1966
|
330
589
|
def test_destroy_dependents
|
331
590
|
# Establish dependent relationship between Person and PersonalLegacyThing
|
332
|
-
add_counter_column_to(Person,
|
591
|
+
add_counter_column_to(Person, "personal_legacy_things_count")
|
333
592
|
PersonalLegacyThing.reset_column_information
|
334
593
|
|
335
594
|
# Make sure that counter incrementing doesn't cause problems
|
336
|
-
p1 = Person.new(:
|
595
|
+
p1 = Person.new(first_name: "fjord")
|
337
596
|
p1.save!
|
338
|
-
t = PersonalLegacyThing.new(:
|
597
|
+
t = PersonalLegacyThing.new(person: p1)
|
339
598
|
t.save!
|
340
599
|
p1.reload
|
341
600
|
assert_equal 1, p1.personal_legacy_things_count
|
@@ -344,14 +603,38 @@ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
|
|
344
603
|
assert_raises(ActiveRecord::RecordNotFound) { Person.find(p1.id) }
|
345
604
|
assert_raises(ActiveRecord::RecordNotFound) { PersonalLegacyThing.find(t.id) }
|
346
605
|
ensure
|
347
|
-
remove_counter_column_from(Person,
|
606
|
+
remove_counter_column_from(Person, "personal_legacy_things_count")
|
348
607
|
PersonalLegacyThing.reset_column_information
|
349
608
|
end
|
350
609
|
|
351
|
-
|
610
|
+
def test_destroy_existing_object_with_locking_column_value_null_in_the_database
|
611
|
+
ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
|
612
|
+
t1 = LockWithoutDefault.last
|
613
|
+
|
614
|
+
assert_equal 0, t1.lock_version
|
615
|
+
assert_nil t1.lock_version_before_type_cast
|
616
|
+
|
617
|
+
t1.destroy
|
618
|
+
|
619
|
+
assert_predicate t1, :destroyed?
|
620
|
+
end
|
621
|
+
|
622
|
+
def test_destroy_stale_object
|
623
|
+
t1 = LockWithoutDefault.create!(title: "title1")
|
624
|
+
stale_object = LockWithoutDefault.find(t1.id)
|
625
|
+
|
626
|
+
t1.update!(title: "title2")
|
352
627
|
|
353
|
-
|
354
|
-
|
628
|
+
assert_raises(ActiveRecord::StaleObjectError) do
|
629
|
+
stale_object.destroy!
|
630
|
+
end
|
631
|
+
|
632
|
+
assert_not_predicate stale_object, :destroyed?
|
633
|
+
end
|
634
|
+
|
635
|
+
private
|
636
|
+
def add_counter_column_to(model, col = "test_count")
|
637
|
+
model.connection.add_column model.table_name, col, :integer, null: false, default: 0
|
355
638
|
model.reset_column_information
|
356
639
|
end
|
357
640
|
|
@@ -364,17 +647,16 @@ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
|
|
364
647
|
add_counter_column_to(model)
|
365
648
|
object = model.first
|
366
649
|
assert_equal 0, object.test_count
|
367
|
-
assert_equal 0, object.
|
650
|
+
assert_equal 0, object.public_send(model.locking_column)
|
368
651
|
yield object.id
|
369
652
|
object.reload
|
370
653
|
assert_equal expected_count, object.test_count
|
371
|
-
assert_equal 1, object.
|
654
|
+
assert_equal 1, object.public_send(model.locking_column)
|
372
655
|
ensure
|
373
656
|
remove_counter_column_from(model)
|
374
657
|
end
|
375
658
|
end
|
376
659
|
|
377
|
-
|
378
660
|
# TODO: test against the generated SQL since testing locking behavior itself
|
379
661
|
# is so cumbersome. Will deadlock Ruby threads if the underlying db.execute
|
380
662
|
# blocks, so separate script called by Kernel#system is needed.
|
@@ -411,34 +693,48 @@ unless in_memory_db?
|
|
411
693
|
end
|
412
694
|
end
|
413
695
|
|
414
|
-
|
415
|
-
|
696
|
+
def test_lock_does_not_raise_when_the_object_is_not_dirty
|
697
|
+
person = Person.find 1
|
416
698
|
assert_nothing_raised do
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
699
|
+
person.lock!
|
700
|
+
end
|
701
|
+
end
|
702
|
+
|
703
|
+
def test_lock_raises_when_the_record_is_dirty
|
704
|
+
person = Person.find 1
|
705
|
+
person.first_name = "fooman"
|
706
|
+
assert_raises(RuntimeError) do
|
707
|
+
person.lock!
|
708
|
+
end
|
709
|
+
end
|
710
|
+
|
711
|
+
def test_locking_in_after_save_callback
|
712
|
+
assert_nothing_raised do
|
713
|
+
frog = ::Frog.create(name: "Old Frog")
|
714
|
+
frog.name = "New Frog"
|
715
|
+
assert_not_deprecated do
|
716
|
+
frog.save!
|
422
717
|
end
|
423
718
|
end
|
424
719
|
end
|
425
720
|
|
426
721
|
def test_with_lock_commits_transaction
|
722
|
+
puts "Inside test_with_lock_commits_transaction"
|
427
723
|
person = Person.find 1
|
428
724
|
person.with_lock do
|
429
|
-
person.first_name =
|
725
|
+
person.first_name = "fooman"
|
430
726
|
person.save!
|
431
727
|
end
|
432
|
-
assert_equal
|
728
|
+
assert_equal "fooman", person.reload.first_name
|
433
729
|
end
|
434
730
|
|
435
731
|
def test_with_lock_rolls_back_transaction
|
436
732
|
person = Person.find 1
|
437
733
|
old = person.first_name
|
438
734
|
person.with_lock do
|
439
|
-
person.first_name =
|
735
|
+
person.first_name = "fooman"
|
440
736
|
person.save!
|
441
|
-
raise
|
737
|
+
raise "oops"
|
442
738
|
end rescue nil
|
443
739
|
assert_equal old, person.reload.first_name
|
444
740
|
end
|
@@ -448,46 +744,44 @@ unless in_memory_db?
|
|
448
744
|
Person.transaction do
|
449
745
|
person = Person.find(1)
|
450
746
|
assert_sql(/LIMIT \$?\d FOR SHARE NOWAIT/) do
|
451
|
-
person.lock!(
|
747
|
+
person.lock!("FOR SHARE NOWAIT")
|
452
748
|
end
|
453
749
|
end
|
454
750
|
end
|
455
751
|
end
|
456
752
|
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
end
|
753
|
+
def test_no_locks_no_wait
|
754
|
+
first, second = duel { Person.find 1 }
|
755
|
+
assert first.end > second.end
|
756
|
+
end
|
462
757
|
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
a = Thread.new do
|
468
|
-
t0 = Time.now
|
469
|
-
Person.transaction do
|
470
|
-
yield
|
471
|
-
sleep zzz # block thread 2 for zzz seconds
|
472
|
-
end
|
473
|
-
t1 = Time.now
|
474
|
-
end
|
758
|
+
private
|
759
|
+
def duel(zzz = 5)
|
760
|
+
t0, t1, t2, t3 = nil, nil, nil, nil
|
475
761
|
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
762
|
+
a = Thread.new do
|
763
|
+
t0 = Time.now
|
764
|
+
Person.transaction do
|
765
|
+
yield
|
766
|
+
sleep zzz # block thread 2 for zzz seconds
|
481
767
|
end
|
768
|
+
t1 = Time.now
|
769
|
+
end
|
482
770
|
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
assert t3 > t2
|
489
|
-
[t0.to_f..t1.to_f, t2.to_f..t3.to_f]
|
771
|
+
b = Thread.new do
|
772
|
+
sleep zzz / 2.0 # ensure thread 1 tx starts first
|
773
|
+
t2 = Time.now
|
774
|
+
Person.transaction { yield }
|
775
|
+
t3 = Time.now
|
490
776
|
end
|
491
|
-
|
777
|
+
|
778
|
+
a.join
|
779
|
+
b.join
|
780
|
+
|
781
|
+
assert t1 > t0 + zzz
|
782
|
+
assert t2 > t0
|
783
|
+
assert t3 > t2
|
784
|
+
[t0.to_f..t1.to_f, t2.to_f..t3.to_f]
|
785
|
+
end
|
492
786
|
end
|
493
787
|
end
|