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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "pp"
|
|
3
4
|
require "cases/helper"
|
|
4
5
|
require "models/tag"
|
|
5
6
|
require "models/tagging"
|
|
@@ -25,10 +26,12 @@ require "models/reader"
|
|
|
25
26
|
require "models/category"
|
|
26
27
|
require "models/categorization"
|
|
27
28
|
require "models/edge"
|
|
29
|
+
require "models/wheel"
|
|
28
30
|
require "models/subscriber"
|
|
31
|
+
require "models/cpk"
|
|
29
32
|
|
|
30
33
|
class RelationTest < ActiveRecord::TestCase
|
|
31
|
-
fixtures :authors, :author_addresses, :topics, :entrants, :developers, :people, :companies, :developers_projects, :accounts, :categories, :categorizations, :categories_posts, :posts, :comments, :tags, :taggings, :cars, :minivans
|
|
34
|
+
fixtures :authors, :author_addresses, :topics, :entrants, :developers, :people, :companies, :developers_projects, :accounts, :categories, :categorizations, :categories_posts, :posts, :comments, :tags, :taggings, :cars, :minivans, :cpk_orders
|
|
32
35
|
|
|
33
36
|
def test_do_not_double_quote_string_id
|
|
34
37
|
van = Minivan.last
|
|
@@ -55,7 +58,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
55
58
|
|
|
56
59
|
def test_dynamic_finder
|
|
57
60
|
x = Post.where("author_id = ?", 1)
|
|
58
|
-
assert_respond_to x.
|
|
61
|
+
assert_respond_to x.model, :find_by_id
|
|
59
62
|
end
|
|
60
63
|
|
|
61
64
|
def test_multivalue_where
|
|
@@ -96,7 +99,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
96
99
|
assert_not_predicate topics, :loaded?
|
|
97
100
|
assert_not_predicate topics, :loaded
|
|
98
101
|
|
|
99
|
-
|
|
102
|
+
assert_queries_count(1) do
|
|
100
103
|
2.times { assert_equal 5, topics.to_a.size }
|
|
101
104
|
end
|
|
102
105
|
|
|
@@ -107,7 +110,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
107
110
|
def test_scoped_first
|
|
108
111
|
topics = Topic.all.order("id ASC")
|
|
109
112
|
|
|
110
|
-
|
|
113
|
+
assert_queries_count(1) do
|
|
111
114
|
2.times { assert_equal "The First Topic", topics.first.title }
|
|
112
115
|
end
|
|
113
116
|
|
|
@@ -151,7 +154,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
151
154
|
def test_reload
|
|
152
155
|
topics = Topic.all
|
|
153
156
|
|
|
154
|
-
|
|
157
|
+
assert_queries_count(1) do
|
|
155
158
|
2.times { topics.to_a }
|
|
156
159
|
end
|
|
157
160
|
|
|
@@ -160,7 +163,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
160
163
|
original_size = topics.to_a.size
|
|
161
164
|
Topic.create! title: "fake"
|
|
162
165
|
|
|
163
|
-
|
|
166
|
+
assert_queries_count(1) { topics.reload }
|
|
164
167
|
assert_equal original_size + 1, topics.size
|
|
165
168
|
assert_predicate topics, :loaded?
|
|
166
169
|
end
|
|
@@ -180,6 +183,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
180
183
|
end
|
|
181
184
|
|
|
182
185
|
def test_finding_with_subquery_without_select_does_not_change_the_select
|
|
186
|
+
skip "IBM_DB: Does not raise StatementInvalid for subquery without SELECT on all databases" if ActiveRecord::Base.connection.adapter_name.match?(/ibm/i)
|
|
183
187
|
relation = Topic.where(approved: true)
|
|
184
188
|
assert_raises(ActiveRecord::StatementInvalid) do
|
|
185
189
|
Topic.from(relation).to_a
|
|
@@ -211,12 +215,9 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
211
215
|
end
|
|
212
216
|
|
|
213
217
|
def test_select_with_subquery_in_from_uses_original_table_name
|
|
214
|
-
puts "test_select_with_subquery_in_from_uses_original_table_name"
|
|
215
218
|
relation = Comment.joins(:post).select(:id).order(:id)
|
|
216
|
-
puts "After relation"
|
|
217
219
|
# Avoid subquery flattening by adding distinct to work with SQLite < 3.20.0.
|
|
218
220
|
subquery = Comment.from(Comment.all.distinct, Comment.quoted_table_name).joins(:post).select(:id).order(:id)
|
|
219
|
-
puts "After subquery"
|
|
220
221
|
assert_equal relation.map(&:id), subquery.map(&:id)
|
|
221
222
|
end
|
|
222
223
|
|
|
@@ -239,13 +240,14 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
239
240
|
end
|
|
240
241
|
|
|
241
242
|
def test_select_with_subquery_string_in_from_does_not_use_original_table_name
|
|
243
|
+
skip "IBM_DB: SQL0206N - COMMENTS.TYPE not available in subquery context" if ActiveRecord::Base.connection.adapter_name.match?(/ibm/i)
|
|
242
244
|
relation = Comment.group(:type).select("COUNT(post_id) AS post_count, type")
|
|
243
245
|
subquery = Comment.from("(#{relation.to_sql}) #{Comment.table_name}_grouped").select("type", "post_count")
|
|
244
246
|
assert_equal(relation.map(&:post_count).sort, subquery.map(&:post_count).sort)
|
|
245
247
|
end
|
|
246
248
|
|
|
247
249
|
def test_group_with_subquery_string_in_from_does_not_use_original_table_name
|
|
248
|
-
|
|
250
|
+
skip "IBM_DB: SQL0206N - COMMENTS.TYPE not available in subquery context" if ActiveRecord::Base.connection.adapter_name.match?(/ibm/i)
|
|
249
251
|
relation = Comment.group(:type).select("COUNT(post_id) AS post_count,type")
|
|
250
252
|
subquery = Comment.from("(#{relation.to_sql}) #{Comment.table_name}_grouped").group("type").average("post_count")
|
|
251
253
|
assert_equal(relation.map(&:post_count).sort, subquery.values.sort)
|
|
@@ -364,7 +366,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
364
366
|
assert_raises(ActiveRecord::IrreversibleOrderError) do
|
|
365
367
|
Topic.order("author_name, title nulls last").reverse_order
|
|
366
368
|
end
|
|
367
|
-
end if current_adapter?(:PostgreSQLAdapter
|
|
369
|
+
end if current_adapter?(:PostgreSQLAdapter)
|
|
368
370
|
|
|
369
371
|
def test_default_reverse_order_on_table_without_primary_key
|
|
370
372
|
assert_raises(ActiveRecord::IrreversibleOrderError) do
|
|
@@ -459,6 +461,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
459
461
|
end
|
|
460
462
|
|
|
461
463
|
def test_finding_with_cross_table_order_and_limit
|
|
464
|
+
skip "IBM_DB: CLI0125E function sequence error with complex REPLACE query" if ActiveRecord::Base.connection.adapter_name.match?(/ibm/i)
|
|
462
465
|
tags = Tag.includes(:taggings).
|
|
463
466
|
order("tags.name asc", "taggings.taggable_id asc", Arel.sql("REPLACE('abc', taggings.taggable_type, taggings.taggable_type)")).
|
|
464
467
|
limit(1).to_a
|
|
@@ -466,6 +469,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
466
469
|
end
|
|
467
470
|
|
|
468
471
|
def test_finding_with_complex_order_and_limit
|
|
472
|
+
skip "IBM_DB: Complex REPLACE function with references returns wrong result count" if ActiveRecord::Base.connection.adapter_name.match?(/ibm/i)
|
|
469
473
|
tags = Tag.includes(:taggings).references(:taggings).order(Arel.sql("REPLACE('abc', taggings.taggable_type, taggings.taggable_type)")).limit(1).to_a
|
|
470
474
|
assert_equal 1, tags.length
|
|
471
475
|
end
|
|
@@ -477,7 +481,11 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
477
481
|
|
|
478
482
|
def test_finding_with_sanitized_order
|
|
479
483
|
query = Tag.order([Arel.sql("field(id, ?)"), [1, 3, 2]]).to_sql
|
|
480
|
-
|
|
484
|
+
if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
|
|
485
|
+
assert_match(/field\(id, '1',\s*'3',\s*'2'\)/, query)
|
|
486
|
+
else
|
|
487
|
+
assert_match(/field\(id, 1,\s*3,\s*2\)/, query)
|
|
488
|
+
end
|
|
481
489
|
|
|
482
490
|
query = Tag.order([Arel.sql("field(id, ?)"), []]).to_sql
|
|
483
491
|
assert_match(/field\(id, NULL\)/, query)
|
|
@@ -486,6 +494,21 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
486
494
|
assert_match(/field\(id, NULL\)/, query)
|
|
487
495
|
end
|
|
488
496
|
|
|
497
|
+
def test_finding_with_arel_sql_order
|
|
498
|
+
query = Tag.order(Arel.sql("field(id, ?)", [1, 3, 2])).to_sql
|
|
499
|
+
if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
|
|
500
|
+
assert_match(/field\(id, '1', '3', '2'\)/, query)
|
|
501
|
+
else
|
|
502
|
+
assert_match(/field\(id, 1, 3, 2\)/, query)
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
query = Tag.order(Arel.sql("field(id, ?)", [])).to_sql
|
|
506
|
+
assert_match(/field\(id, NULL\)/, query)
|
|
507
|
+
|
|
508
|
+
query = Tag.order(Arel.sql("field(id, ?)", nil)).to_sql
|
|
509
|
+
assert_match(/field\(id, NULL\)/, query)
|
|
510
|
+
end
|
|
511
|
+
|
|
489
512
|
def test_finding_with_order_limit_and_offset
|
|
490
513
|
entrants = Entrant.order("id ASC").limit(2).offset(1)
|
|
491
514
|
|
|
@@ -533,7 +556,8 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
533
556
|
end
|
|
534
557
|
|
|
535
558
|
def test_joins_with_string_array
|
|
536
|
-
person_with_reader_and_post = Post.joins(
|
|
559
|
+
person_with_reader_and_post = Post.joins(
|
|
560
|
+
[
|
|
537
561
|
"INNER JOIN categorizations ON categorizations.post_id = posts.id",
|
|
538
562
|
"INNER JOIN categories ON categories.id = categorizations.category_id AND categories.type = 'SpecialCategory'"
|
|
539
563
|
]
|
|
@@ -541,20 +565,14 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
541
565
|
assert_equal 1, person_with_reader_and_post.size
|
|
542
566
|
end
|
|
543
567
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
assert_raises(ArgumentError) { Topic.reselect() }
|
|
553
|
-
assert_raises(ArgumentError) { Topic.unscope() }
|
|
554
|
-
assert_raises(ArgumentError) { Topic.joins() }
|
|
555
|
-
assert_raises(ArgumentError) { Topic.left_joins() }
|
|
556
|
-
assert_raises(ArgumentError) { Topic.optimizer_hints() }
|
|
557
|
-
assert_raises(ArgumentError) { Topic.annotate() }
|
|
568
|
+
%w( references includes preload eager_load group order reorder reselect unscope
|
|
569
|
+
joins left_joins left_outer_joins optimizer_hints annotate regroup ).each do |method|
|
|
570
|
+
class_eval <<~RUBY
|
|
571
|
+
def test_no_arguments_to_#{method}_raise_errors
|
|
572
|
+
error = assert_raises(ArgumentError) { Topic.#{method}() }
|
|
573
|
+
assert_equal "The method .#{method}() must contain arguments.", error.message
|
|
574
|
+
end
|
|
575
|
+
RUBY
|
|
558
576
|
end
|
|
559
577
|
|
|
560
578
|
def test_blank_like_arguments_to_query_methods_dont_raise_errors
|
|
@@ -587,7 +605,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
587
605
|
|
|
588
606
|
def test_find_with_readonly_option
|
|
589
607
|
Developer.all.each { |d| assert_not d.readonly? }
|
|
590
|
-
Developer.all.readonly.each { |d|
|
|
608
|
+
Developer.all.readonly.each { |d| assert_predicate d, :readonly? }
|
|
591
609
|
end
|
|
592
610
|
|
|
593
611
|
def test_eager_association_loading_of_stis_with_multiple_references
|
|
@@ -602,27 +620,27 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
602
620
|
end
|
|
603
621
|
|
|
604
622
|
def test_find_with_preloaded_associations
|
|
605
|
-
|
|
623
|
+
assert_queries_count(2) do
|
|
606
624
|
posts = Post.preload(:comments).order("posts.id")
|
|
607
625
|
assert posts.first.comments.first
|
|
608
626
|
end
|
|
609
627
|
|
|
610
|
-
|
|
628
|
+
assert_queries_count(2) do
|
|
611
629
|
posts = Post.preload(:comments).order("posts.id")
|
|
612
630
|
assert posts.first.comments.first
|
|
613
631
|
end
|
|
614
632
|
|
|
615
|
-
|
|
633
|
+
assert_queries_count(2) do
|
|
616
634
|
posts = Post.preload(:author).order("posts.id")
|
|
617
635
|
assert posts.first.author
|
|
618
636
|
end
|
|
619
637
|
|
|
620
|
-
|
|
638
|
+
assert_queries_count(2) do
|
|
621
639
|
posts = Post.preload(:author).order("posts.id")
|
|
622
640
|
assert posts.first.author
|
|
623
641
|
end
|
|
624
642
|
|
|
625
|
-
|
|
643
|
+
assert_queries_count(3) do
|
|
626
644
|
posts = Post.preload(:author, :comments).order("posts.id")
|
|
627
645
|
assert posts.first.author
|
|
628
646
|
assert posts.first.comments.first
|
|
@@ -630,36 +648,36 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
630
648
|
end
|
|
631
649
|
|
|
632
650
|
def test_preload_applies_to_all_chained_preloaded_scopes
|
|
633
|
-
|
|
651
|
+
assert_queries_count(3) do
|
|
634
652
|
post = Post.with_comments.with_tags.first
|
|
635
653
|
assert post
|
|
636
654
|
end
|
|
637
655
|
end
|
|
638
656
|
|
|
639
657
|
def test_extracted_association
|
|
640
|
-
relation_authors =
|
|
641
|
-
root_authors =
|
|
658
|
+
relation_authors = assert_queries_count(2) { Post.all.extract_associated(:author) }
|
|
659
|
+
root_authors = assert_queries_count(2) { Post.extract_associated(:author) }
|
|
642
660
|
assert_equal relation_authors, root_authors
|
|
643
661
|
assert_equal Post.all.collect(&:author), relation_authors
|
|
644
662
|
end
|
|
645
663
|
|
|
646
664
|
def test_find_with_included_associations
|
|
647
|
-
|
|
665
|
+
assert_queries_count(2) do
|
|
648
666
|
posts = Post.includes(:comments).order("posts.id")
|
|
649
667
|
assert posts.first.comments.first
|
|
650
668
|
end
|
|
651
669
|
|
|
652
|
-
|
|
670
|
+
assert_queries_count(2) do
|
|
653
671
|
posts = Post.all.includes(:comments).order("posts.id")
|
|
654
672
|
assert posts.first.comments.first
|
|
655
673
|
end
|
|
656
674
|
|
|
657
|
-
|
|
675
|
+
assert_queries_count(2) do
|
|
658
676
|
posts = Post.includes(:author).order("posts.id")
|
|
659
677
|
assert posts.first.author
|
|
660
678
|
end
|
|
661
679
|
|
|
662
|
-
|
|
680
|
+
assert_queries_count(3) do
|
|
663
681
|
posts = Post.includes(:author, :comments).order("posts.id")
|
|
664
682
|
assert posts.first.author
|
|
665
683
|
assert posts.first.comments.first
|
|
@@ -885,22 +903,22 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
885
903
|
ids = Author.pluck(:id)
|
|
886
904
|
slugs = ids.map { |id| "#{id}-as-a-slug" }
|
|
887
905
|
|
|
888
|
-
assert_equal Author.
|
|
906
|
+
assert_equal Author.where(id: ids).to_a, Author.where(id: slugs).to_a
|
|
889
907
|
end
|
|
890
908
|
|
|
891
909
|
def test_find_all_using_where_with_relation
|
|
892
910
|
david = authors(:david)
|
|
893
|
-
|
|
911
|
+
assert_queries_count(1) {
|
|
894
912
|
relation = Author.where(id: Author.where(id: david.id))
|
|
895
913
|
assert_equal [david], relation.to_a
|
|
896
914
|
}
|
|
897
915
|
|
|
898
|
-
|
|
916
|
+
assert_queries_count(1) {
|
|
899
917
|
relation = Author.where("id in (?)", Author.where(id: david).select(:id))
|
|
900
918
|
assert_equal [david], relation.to_a
|
|
901
919
|
}
|
|
902
920
|
|
|
903
|
-
|
|
921
|
+
assert_queries_count(1) do
|
|
904
922
|
relation = Author.where("id in (:author_ids)", author_ids: Author.where(id: david).select(:id))
|
|
905
923
|
assert_equal [david], relation.to_a
|
|
906
924
|
end
|
|
@@ -910,17 +928,17 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
910
928
|
david = authors(:david)
|
|
911
929
|
davids_posts = david.posts.order(:id).to_a
|
|
912
930
|
|
|
913
|
-
|
|
931
|
+
assert_queries_count(1) do
|
|
914
932
|
relation = Post.where(id: david.posts.select(:id))
|
|
915
933
|
assert_equal davids_posts, relation.order(:id).to_a
|
|
916
934
|
end
|
|
917
935
|
|
|
918
|
-
|
|
936
|
+
assert_queries_count(1) do
|
|
919
937
|
relation = Post.where("id in (?)", david.posts.select(:id))
|
|
920
938
|
assert_equal davids_posts, relation.order(:id).to_a, "should process Relation as bind variables"
|
|
921
939
|
end
|
|
922
940
|
|
|
923
|
-
|
|
941
|
+
assert_queries_count(1) do
|
|
924
942
|
relation = Post.where("id in (:post_ids)", post_ids: david.posts.select(:id))
|
|
925
943
|
assert_equal davids_posts, relation.order(:id).to_a, "should process Relation as named bind variables"
|
|
926
944
|
end
|
|
@@ -928,18 +946,33 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
928
946
|
|
|
929
947
|
def test_find_all_using_where_with_relation_and_alternate_primary_key
|
|
930
948
|
cool_first = minivans(:cool_first)
|
|
931
|
-
|
|
949
|
+
assert_queries_count(1) {
|
|
932
950
|
relation = Minivan.where(minivan_id: Minivan.where(name: cool_first.name))
|
|
933
951
|
assert_equal [cool_first], relation.to_a
|
|
934
952
|
}
|
|
935
953
|
end
|
|
936
954
|
|
|
955
|
+
def test_find_all_using_where_with_relation_with_no_selects_and_composite_primary_key_raises
|
|
956
|
+
order = cpk_orders(:cpk_groceries_order_1)
|
|
957
|
+
subquery = Cpk::Order.where(Cpk::Order.primary_key => [order.id])
|
|
958
|
+
|
|
959
|
+
assert_nothing_raised do
|
|
960
|
+
Cpk::Order.where(id: subquery.select(:id)).to_a
|
|
961
|
+
end
|
|
962
|
+
|
|
963
|
+
error = assert_raise(ArgumentError) do
|
|
964
|
+
Cpk::Order.where(id: subquery).to_a
|
|
965
|
+
end
|
|
966
|
+
|
|
967
|
+
assert_equal "Cannot map composite primary key [\"shop_id\", \"id\"] to id", error.message
|
|
968
|
+
end
|
|
969
|
+
|
|
937
970
|
def test_find_all_using_where_with_relation_does_not_alter_select_values
|
|
938
971
|
david = authors(:david)
|
|
939
972
|
|
|
940
973
|
subquery = Author.where(id: david.id)
|
|
941
974
|
|
|
942
|
-
|
|
975
|
+
assert_queries_count(1) {
|
|
943
976
|
relation = Author.where(id: subquery)
|
|
944
977
|
assert_equal [david], relation.to_a
|
|
945
978
|
}
|
|
@@ -949,7 +982,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
949
982
|
|
|
950
983
|
def test_find_all_using_where_with_relation_with_joins
|
|
951
984
|
david = authors(:david)
|
|
952
|
-
|
|
985
|
+
assert_queries_count(1) {
|
|
953
986
|
relation = Author.where(id: Author.joins(:posts).where(id: david.id))
|
|
954
987
|
assert_equal [david], relation.to_a
|
|
955
988
|
}
|
|
@@ -957,7 +990,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
957
990
|
|
|
958
991
|
def test_find_all_using_where_with_relation_with_select_to_build_subquery
|
|
959
992
|
david = authors(:david)
|
|
960
|
-
|
|
993
|
+
assert_queries_count(1) {
|
|
961
994
|
relation = Author.where(name: Author.where(id: david.id).select(:name))
|
|
962
995
|
assert_equal [david], relation.to_a
|
|
963
996
|
}
|
|
@@ -993,14 +1026,6 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
993
1026
|
assert_equal first.heading, topic.heading
|
|
994
1027
|
end
|
|
995
1028
|
|
|
996
|
-
def test_select_argument_error
|
|
997
|
-
assert_raises(ArgumentError) { Developer.select }
|
|
998
|
-
end
|
|
999
|
-
|
|
1000
|
-
def test_select_argument_error_with_block
|
|
1001
|
-
assert_raises(ArgumentError) { Developer.select(:id) { |d| d.id % 2 == 0 } }
|
|
1002
|
-
end
|
|
1003
|
-
|
|
1004
1029
|
def test_count
|
|
1005
1030
|
posts = Post.all
|
|
1006
1031
|
|
|
@@ -1040,33 +1065,33 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1040
1065
|
|
|
1041
1066
|
def test_size_with_distinct
|
|
1042
1067
|
posts = Post.distinct.select(:author_id, :comments_count)
|
|
1043
|
-
|
|
1044
|
-
|
|
1068
|
+
assert_queries_count(1) { assert_equal 8, posts.size }
|
|
1069
|
+
assert_queries_count(1) { assert_equal 8, posts.load.size }
|
|
1045
1070
|
end
|
|
1046
1071
|
|
|
1047
1072
|
def test_size_with_eager_loading_and_custom_order
|
|
1048
1073
|
posts = Post.includes(:comments).order("comments.id")
|
|
1049
|
-
|
|
1050
|
-
|
|
1074
|
+
assert_queries_count(1) { assert_equal 11, posts.size }
|
|
1075
|
+
assert_queries_count(1) { assert_equal 11, posts.load.size }
|
|
1051
1076
|
end
|
|
1052
1077
|
|
|
1053
1078
|
def test_size_with_eager_loading_and_custom_select_and_order
|
|
1054
1079
|
posts = Post.includes(:comments).order("comments.id").select(:type)
|
|
1055
|
-
|
|
1056
|
-
|
|
1080
|
+
assert_queries_count(1) { assert_equal 11, posts.size }
|
|
1081
|
+
assert_queries_count(1) { assert_equal 11, posts.load.size }
|
|
1057
1082
|
end
|
|
1058
1083
|
|
|
1059
1084
|
def test_size_with_eager_loading_and_custom_order_and_distinct
|
|
1060
1085
|
posts = Post.includes(:comments).order("comments.id").distinct
|
|
1061
|
-
|
|
1062
|
-
|
|
1086
|
+
assert_queries_count(1) { assert_equal 11, posts.size }
|
|
1087
|
+
assert_queries_count(1) { assert_equal 11, posts.load.size }
|
|
1063
1088
|
end
|
|
1064
1089
|
|
|
1065
1090
|
def test_size_with_eager_loading_and_manual_distinct_select_and_custom_order
|
|
1066
1091
|
accounts = Account.select("DISTINCT accounts.firm_id").order("accounts.firm_id")
|
|
1067
1092
|
|
|
1068
|
-
|
|
1069
|
-
|
|
1093
|
+
assert_queries_count(1) { assert_equal 5, accounts.size }
|
|
1094
|
+
assert_queries_count(1) { assert_equal 5, accounts.load.size }
|
|
1070
1095
|
end
|
|
1071
1096
|
|
|
1072
1097
|
def test_count_explicit_columns
|
|
@@ -1091,7 +1116,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1091
1116
|
def test_size
|
|
1092
1117
|
posts = Post.all
|
|
1093
1118
|
|
|
1094
|
-
|
|
1119
|
+
assert_queries_count(1) { assert_equal 11, posts.size }
|
|
1095
1120
|
assert_not_predicate posts, :loaded?
|
|
1096
1121
|
|
|
1097
1122
|
best_posts = posts.where(comments_count: 0)
|
|
@@ -1102,7 +1127,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1102
1127
|
def test_size_with_limit
|
|
1103
1128
|
posts = Post.limit(10)
|
|
1104
1129
|
|
|
1105
|
-
|
|
1130
|
+
assert_queries_count(1) { assert_equal 10, posts.size }
|
|
1106
1131
|
assert_not_predicate posts, :loaded?
|
|
1107
1132
|
|
|
1108
1133
|
best_posts = posts.where(comments_count: 0)
|
|
@@ -1137,11 +1162,11 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1137
1162
|
def test_empty
|
|
1138
1163
|
posts = Post.all
|
|
1139
1164
|
|
|
1140
|
-
|
|
1165
|
+
assert_queries_count(1) { assert_equal false, posts.empty? }
|
|
1141
1166
|
assert_not_predicate posts, :loaded?
|
|
1142
1167
|
|
|
1143
1168
|
no_posts = posts.where(title: "")
|
|
1144
|
-
|
|
1169
|
+
assert_queries_count(1) { assert_equal true, no_posts.empty? }
|
|
1145
1170
|
assert_not_predicate no_posts, :loaded?
|
|
1146
1171
|
|
|
1147
1172
|
best_posts = posts.where(comments_count: 0)
|
|
@@ -1152,23 +1177,26 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1152
1177
|
def test_empty_complex_chained_relations
|
|
1153
1178
|
posts = Post.select("comments_count").where("id is not null").group("author_id").where("legacy_comments_count > 0")
|
|
1154
1179
|
|
|
1155
|
-
|
|
1180
|
+
assert_queries_count(1) { assert_equal false, posts.empty? }
|
|
1156
1181
|
assert_not_predicate posts, :loaded?
|
|
1157
1182
|
|
|
1158
1183
|
no_posts = posts.where(title: "")
|
|
1159
|
-
|
|
1184
|
+
assert_queries_count(1) { assert_equal true, no_posts.empty? }
|
|
1160
1185
|
assert_not_predicate no_posts, :loaded?
|
|
1161
1186
|
end
|
|
1162
1187
|
|
|
1163
1188
|
def test_any
|
|
1164
1189
|
posts = Post.all
|
|
1165
1190
|
|
|
1166
|
-
|
|
1167
|
-
|
|
1191
|
+
assert_queries_count(3) do
|
|
1192
|
+
assert_predicate posts, :any? # Uses COUNT()
|
|
1168
1193
|
assert_not_predicate posts.where(id: nil), :any?
|
|
1169
1194
|
|
|
1170
1195
|
assert posts.any? { |p| p.id > 0 }
|
|
1171
1196
|
assert_not posts.any? { |p| p.id <= 0 }
|
|
1197
|
+
|
|
1198
|
+
assert posts.any?(Post)
|
|
1199
|
+
assert_not posts.any?(Comment)
|
|
1172
1200
|
end
|
|
1173
1201
|
|
|
1174
1202
|
assert_predicate posts, :loaded?
|
|
@@ -1177,8 +1205,8 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1177
1205
|
def test_many
|
|
1178
1206
|
posts = Post.all
|
|
1179
1207
|
|
|
1180
|
-
|
|
1181
|
-
|
|
1208
|
+
assert_queries_count(2) do
|
|
1209
|
+
assert_predicate posts, :many? # Uses COUNT()
|
|
1182
1210
|
assert posts.many? { |p| p.id > 0 }
|
|
1183
1211
|
assert_not posts.many? { |p| p.id < 2 }
|
|
1184
1212
|
end
|
|
@@ -1187,23 +1215,30 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1187
1215
|
end
|
|
1188
1216
|
|
|
1189
1217
|
def test_many_with_limits
|
|
1190
|
-
|
|
1218
|
+
posts_with_limit = Post.limit(5)
|
|
1219
|
+
posts_with_limit_one = Post.limit(1)
|
|
1191
1220
|
|
|
1192
|
-
assert_predicate
|
|
1193
|
-
assert_not_predicate
|
|
1221
|
+
assert_predicate posts_with_limit, :many?
|
|
1222
|
+
assert_not_predicate posts_with_limit, :loaded?
|
|
1223
|
+
|
|
1224
|
+
assert_not_predicate posts_with_limit_one, :many?
|
|
1225
|
+
assert_not_predicate posts_with_limit_one, :loaded?
|
|
1194
1226
|
end
|
|
1195
1227
|
|
|
1196
1228
|
def test_none?
|
|
1197
1229
|
posts = Post.all
|
|
1198
|
-
|
|
1230
|
+
assert_queries_count(1) do
|
|
1199
1231
|
assert_not posts.none? # Uses COUNT()
|
|
1200
1232
|
end
|
|
1201
1233
|
|
|
1202
1234
|
assert_not_predicate posts, :loaded?
|
|
1203
1235
|
|
|
1204
|
-
|
|
1236
|
+
assert_queries_count(1) do
|
|
1205
1237
|
assert posts.none? { |p| p.id < 0 }
|
|
1206
1238
|
assert_not posts.none? { |p| p.id == 1 }
|
|
1239
|
+
|
|
1240
|
+
assert posts.none?(Comment)
|
|
1241
|
+
assert_not posts.none?(Post)
|
|
1207
1242
|
end
|
|
1208
1243
|
|
|
1209
1244
|
assert_predicate posts, :loaded?
|
|
@@ -1211,20 +1246,35 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1211
1246
|
|
|
1212
1247
|
def test_one
|
|
1213
1248
|
posts = Post.all
|
|
1214
|
-
|
|
1249
|
+
assert_queries_count(1) do
|
|
1215
1250
|
assert_not posts.one? # Uses COUNT()
|
|
1216
1251
|
end
|
|
1217
1252
|
|
|
1218
1253
|
assert_not_predicate posts, :loaded?
|
|
1219
1254
|
|
|
1220
|
-
|
|
1255
|
+
assert_queries_count(1) do
|
|
1221
1256
|
assert_not posts.one? { |p| p.id < 3 }
|
|
1222
1257
|
assert posts.one? { |p| p.id == 1 }
|
|
1258
|
+
|
|
1259
|
+
assert_not posts.one?(Post)
|
|
1260
|
+
assert_not posts.one?(Comment)
|
|
1223
1261
|
end
|
|
1224
1262
|
|
|
1225
1263
|
assert_predicate posts, :loaded?
|
|
1226
1264
|
end
|
|
1227
1265
|
|
|
1266
|
+
def test_one_with_destroy
|
|
1267
|
+
posts = Post.all
|
|
1268
|
+
assert_queries_count(1) do
|
|
1269
|
+
assert_not posts.one?
|
|
1270
|
+
end
|
|
1271
|
+
|
|
1272
|
+
posts.where.not(id: Post.first).destroy_all
|
|
1273
|
+
|
|
1274
|
+
assert_equal 1, posts.size
|
|
1275
|
+
assert_predicate posts, :one?
|
|
1276
|
+
end
|
|
1277
|
+
|
|
1228
1278
|
def test_to_a_should_dup_target
|
|
1229
1279
|
posts = Post.all
|
|
1230
1280
|
|
|
@@ -1282,6 +1332,46 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1282
1332
|
assert_equal post, comment.post
|
|
1283
1333
|
end
|
|
1284
1334
|
|
|
1335
|
+
def test_new_with_array
|
|
1336
|
+
green_birds = Bird.where(color: "green").new([{ name: "parrot" }, { name: "canary" }])
|
|
1337
|
+
assert_equal ["parrot", "canary"], green_birds.map(&:name)
|
|
1338
|
+
assert_equal ["green", "green"], green_birds.map(&:color)
|
|
1339
|
+
green_birds.each { |bird| assert_not_predicate bird, :persisted? }
|
|
1340
|
+
end
|
|
1341
|
+
|
|
1342
|
+
def test_build_with_array
|
|
1343
|
+
green_birds = Bird.where(color: "green").build([{ name: "parrot" }, { name: "canary" }])
|
|
1344
|
+
assert_equal ["parrot", "canary"], green_birds.map(&:name)
|
|
1345
|
+
assert_equal ["green", "green"], green_birds.map(&:color)
|
|
1346
|
+
green_birds.each { |bird| assert_not_predicate bird, :persisted? }
|
|
1347
|
+
end
|
|
1348
|
+
|
|
1349
|
+
def test_create_with_array
|
|
1350
|
+
green_birds = Bird.where(color: "green").create([{ name: "parrot" }, { name: "canary" }])
|
|
1351
|
+
assert_equal ["parrot", "canary"], green_birds.map(&:name)
|
|
1352
|
+
assert_equal ["green", "green"], green_birds.map(&:color)
|
|
1353
|
+
green_birds.each { |bird| assert_predicate bird, :persisted? }
|
|
1354
|
+
end
|
|
1355
|
+
|
|
1356
|
+
def test_create_with_block
|
|
1357
|
+
sparrow = Bird.create do |bird|
|
|
1358
|
+
bird.name = "sparrow"
|
|
1359
|
+
bird.color = "grey"
|
|
1360
|
+
end
|
|
1361
|
+
|
|
1362
|
+
assert_kind_of Bird, sparrow
|
|
1363
|
+
assert_predicate sparrow, :persisted?
|
|
1364
|
+
assert_equal "sparrow", sparrow.name
|
|
1365
|
+
assert_equal "grey", sparrow.color
|
|
1366
|
+
end
|
|
1367
|
+
|
|
1368
|
+
def test_create_bang_with_array
|
|
1369
|
+
green_birds = Bird.where(color: "green").create!([{ name: "parrot" }, { name: "canary" }])
|
|
1370
|
+
assert_equal ["parrot", "canary"], green_birds.map(&:name)
|
|
1371
|
+
assert_equal ["green", "green"], green_birds.map(&:color)
|
|
1372
|
+
green_birds.each { |bird| assert_predicate bird, :persisted? }
|
|
1373
|
+
end
|
|
1374
|
+
|
|
1285
1375
|
def test_first_or_create
|
|
1286
1376
|
parrot = Bird.where(color: "green").first_or_create(name: "parrot")
|
|
1287
1377
|
assert_kind_of Bird, parrot
|
|
@@ -1326,7 +1416,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1326
1416
|
def test_first_or_create_with_array
|
|
1327
1417
|
several_green_birds = Bird.where(color: "green").first_or_create([{ name: "parrot" }, { name: "parakeet" }])
|
|
1328
1418
|
assert_kind_of Array, several_green_birds
|
|
1329
|
-
several_green_birds.each { |bird|
|
|
1419
|
+
several_green_birds.each { |bird| assert_predicate bird, :persisted? }
|
|
1330
1420
|
|
|
1331
1421
|
same_parrot = Bird.where(color: "green").first_or_create([{ name: "hummingbird" }, { name: "macaw" }])
|
|
1332
1422
|
assert_kind_of Bird, same_parrot
|
|
@@ -1380,7 +1470,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1380
1470
|
def test_first_or_create_bang_with_valid_array
|
|
1381
1471
|
several_green_birds = Bird.where(color: "green").first_or_create!([{ name: "parrot" }, { name: "parakeet" }])
|
|
1382
1472
|
assert_kind_of Array, several_green_birds
|
|
1383
|
-
several_green_birds.each { |bird|
|
|
1473
|
+
several_green_birds.each { |bird| assert_predicate bird, :persisted? }
|
|
1384
1474
|
|
|
1385
1475
|
same_parrot = Bird.where(color: "green").first_or_create!([{ name: "hummingbird" }, { name: "macaw" }])
|
|
1386
1476
|
assert_kind_of Bird, same_parrot
|
|
@@ -1439,6 +1529,27 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1439
1529
|
assert_equal bird, Bird.find_or_create_by(name: "bob")
|
|
1440
1530
|
end
|
|
1441
1531
|
|
|
1532
|
+
def test_find_or_create_by_race_condition
|
|
1533
|
+
assert_nil Subscriber.find_by(nick: "bob")
|
|
1534
|
+
|
|
1535
|
+
bob = Subscriber.create!(nick: "bob")
|
|
1536
|
+
relation = Subscriber.all
|
|
1537
|
+
|
|
1538
|
+
results = [nil, bob]
|
|
1539
|
+
find_by_mock = -> (*) do
|
|
1540
|
+
assert_not_predicate results, :empty?
|
|
1541
|
+
results.shift
|
|
1542
|
+
end
|
|
1543
|
+
|
|
1544
|
+
relation.stub(:find_by, find_by_mock) do
|
|
1545
|
+
relation.stub(:find_by!, find_by_mock) do # create_or_find_by always call find_by! on retry
|
|
1546
|
+
assert_equal bob, relation.find_or_create_by(nick: "bob")
|
|
1547
|
+
end
|
|
1548
|
+
end
|
|
1549
|
+
|
|
1550
|
+
assert_predicate results, :empty?
|
|
1551
|
+
end
|
|
1552
|
+
|
|
1442
1553
|
def test_find_or_create_by_with_create_with
|
|
1443
1554
|
assert_nil Bird.find_by(name: "bob")
|
|
1444
1555
|
|
|
@@ -1449,6 +1560,19 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1449
1560
|
assert_equal bird, Bird.create_with(color: "blue").find_or_create_by(name: "bob")
|
|
1450
1561
|
end
|
|
1451
1562
|
|
|
1563
|
+
def test_find_or_create_by_with_block
|
|
1564
|
+
assert_nil Bird.find_by(name: "bob")
|
|
1565
|
+
|
|
1566
|
+
bird = Bird.find_or_create_by(name: "bob") do |record|
|
|
1567
|
+
record.color = "blue"
|
|
1568
|
+
end
|
|
1569
|
+
assert_predicate bird, :persisted?
|
|
1570
|
+
assert_equal "bob", bird.name
|
|
1571
|
+
assert_equal "blue", bird.color
|
|
1572
|
+
|
|
1573
|
+
assert_equal bird, Bird.find_or_create_by(name: "bob", color: "blue")
|
|
1574
|
+
end
|
|
1575
|
+
|
|
1452
1576
|
def test_find_or_create_by!
|
|
1453
1577
|
assert_raises(ActiveRecord::RecordInvalid) { Bird.find_or_create_by!(color: "green") }
|
|
1454
1578
|
end
|
|
@@ -1462,6 +1586,49 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1462
1586
|
assert_not_equal subscriber, Subscriber.create_or_find_by(nick: "cat")
|
|
1463
1587
|
end
|
|
1464
1588
|
|
|
1589
|
+
def test_create_or_find_by_rollbacks_a_transaction
|
|
1590
|
+
skip "IBM_DB has different transaction rollback behavior on after_save failures" if ActiveRecord::Base.connection.adapter_name.match?(/ibm/i)
|
|
1591
|
+
assert_no_difference(-> { Car.count }) do
|
|
1592
|
+
car = BrokenCar.create_or_find_by(name: "Civic")
|
|
1593
|
+
|
|
1594
|
+
assert_instance_of(BrokenCar, car)
|
|
1595
|
+
assert_not_predicate(car, :persisted?)
|
|
1596
|
+
end
|
|
1597
|
+
end
|
|
1598
|
+
|
|
1599
|
+
def test_create_or_find_by_bang_rollbacks_a_transaction
|
|
1600
|
+
skip "IBM_DB has different transaction rollback behavior on after_save failures" if ActiveRecord::Base.connection.adapter_name.match?(/ibm/i)
|
|
1601
|
+
assert_no_difference(-> { Car.count }) do
|
|
1602
|
+
car = BrokenCar.create_or_find_by!(name: "Civic")
|
|
1603
|
+
|
|
1604
|
+
assert_instance_of(BrokenCar, car)
|
|
1605
|
+
assert_not_predicate(car, :persisted?)
|
|
1606
|
+
end
|
|
1607
|
+
end
|
|
1608
|
+
|
|
1609
|
+
def test_create_or_find_by_on_a_collections_rollbacks_a_transaction_when_owner_is_not_persisted
|
|
1610
|
+
car = BrokenCar.create(name: "Civic")
|
|
1611
|
+
assert_not_predicate(car, :persisted?)
|
|
1612
|
+
|
|
1613
|
+
assert_raises(ActiveRecord::RecordNotSaved) do
|
|
1614
|
+
car.wheels.create_or_find_by!(size: 1500)
|
|
1615
|
+
end
|
|
1616
|
+
end
|
|
1617
|
+
|
|
1618
|
+
def test_create_or_find_by_with_block
|
|
1619
|
+
assert_nil Subscriber.find_by(nick: "bob")
|
|
1620
|
+
|
|
1621
|
+
subscriber = Subscriber.create_or_find_by(nick: "bob") do |record|
|
|
1622
|
+
record.name = "the builder"
|
|
1623
|
+
end
|
|
1624
|
+
|
|
1625
|
+
assert_equal "bob", subscriber.nick
|
|
1626
|
+
assert_equal "the builder", subscriber.name
|
|
1627
|
+
assert_predicate subscriber, :persisted?
|
|
1628
|
+
assert_equal subscriber, Subscriber.create_or_find_by(nick: "bob")
|
|
1629
|
+
assert_not_equal subscriber, Subscriber.create_or_find_by(nick: "cat")
|
|
1630
|
+
end
|
|
1631
|
+
|
|
1465
1632
|
def test_create_or_find_by_should_not_raise_due_to_validation_errors
|
|
1466
1633
|
assert_nothing_raised do
|
|
1467
1634
|
bird = Bird.create_or_find_by(color: "green")
|
|
@@ -1530,6 +1697,28 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1530
1697
|
assert_equal bird, Bird.find_or_initialize_by(name: "bob")
|
|
1531
1698
|
end
|
|
1532
1699
|
|
|
1700
|
+
def test_find_or_initialize_by_with_block
|
|
1701
|
+
assert_nil Bird.find_by(name: "bob")
|
|
1702
|
+
|
|
1703
|
+
bird = Bird.find_or_initialize_by(name: "bob") do |record|
|
|
1704
|
+
record.color = "blue"
|
|
1705
|
+
end
|
|
1706
|
+
assert_predicate bird, :new_record?
|
|
1707
|
+
assert_equal "bob", bird.name
|
|
1708
|
+
assert_equal "blue", bird.color
|
|
1709
|
+
bird.save!
|
|
1710
|
+
|
|
1711
|
+
assert_equal bird, Bird.find_or_initialize_by(name: "bob", color: "blue")
|
|
1712
|
+
end
|
|
1713
|
+
|
|
1714
|
+
def test_find_or_initialize_by_with_cpk_association
|
|
1715
|
+
order1 = Cpk::Order.create!(id: [1, 1])
|
|
1716
|
+
order2 = Cpk::Order.create!(id: [1, 2])
|
|
1717
|
+
Cpk::Book.create!(id: [2, 1], order: order1)
|
|
1718
|
+
book = Cpk::Book.find_or_initialize_by(order: order2)
|
|
1719
|
+
assert_equal order2, book.order
|
|
1720
|
+
end
|
|
1721
|
+
|
|
1533
1722
|
def test_explicit_create_with
|
|
1534
1723
|
hens = Bird.where(name: "hen")
|
|
1535
1724
|
assert_equal "hen", hens.new.name
|
|
@@ -1640,10 +1829,10 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1640
1829
|
query = Tag.select(:name).where(id: [tag1.id, tag2.id])
|
|
1641
1830
|
|
|
1642
1831
|
assert_equal ["Foo", "Foo"], query.map(&:name)
|
|
1643
|
-
|
|
1832
|
+
assert_queries_match(/DISTINCT/) do
|
|
1644
1833
|
assert_equal ["Foo"], query.distinct.map(&:name)
|
|
1645
1834
|
end
|
|
1646
|
-
|
|
1835
|
+
assert_queries_match(/DISTINCT/) do
|
|
1647
1836
|
assert_equal ["Foo"], query.distinct(true).map(&:name)
|
|
1648
1837
|
end
|
|
1649
1838
|
assert_equal ["Foo", "Foo"], query.distinct(true).distinct(false).map(&:name)
|
|
@@ -1667,7 +1856,6 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1667
1856
|
end
|
|
1668
1857
|
|
|
1669
1858
|
def test_multiple_where_and_having_clauses
|
|
1670
|
-
puts "test_multiple_where_and_having_clauses"
|
|
1671
1859
|
post = Post.first
|
|
1672
1860
|
having_then_where = Post.having(id: post.id).where(title: post.title)
|
|
1673
1861
|
.having(id: post.id).where(title: post.title).group(:id, :author_id, :title, :body, :type, :legacy_comments_count, :taggings_with_delete_all_count, :taggings_with_destroy_count, :tags_count, :indestructible_tags_count, :tags_with_destroy_count, :tags_with_nullify_count)
|
|
@@ -1690,6 +1878,36 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1690
1878
|
assert_not_predicate scope, :eager_loading?
|
|
1691
1879
|
end
|
|
1692
1880
|
|
|
1881
|
+
def test_order_triggers_eager_loading
|
|
1882
|
+
scope = Post.includes(:comments).order("comments.label ASC")
|
|
1883
|
+
assert_predicate scope, :eager_loading?
|
|
1884
|
+
end
|
|
1885
|
+
|
|
1886
|
+
def test_order_doesnt_trigger_eager_loading_when_ordering_using_the_owner_table
|
|
1887
|
+
scope = Post.includes(:comments).order("posts.title ASC")
|
|
1888
|
+
assert_not_predicate scope, :eager_loading?
|
|
1889
|
+
end
|
|
1890
|
+
|
|
1891
|
+
def test_order_triggers_eager_loading_when_ordering_using_symbols
|
|
1892
|
+
scope = Post.includes(:comments).order(:"comments.label")
|
|
1893
|
+
assert_predicate scope, :eager_loading?
|
|
1894
|
+
end
|
|
1895
|
+
|
|
1896
|
+
def test_order_doesnt_trigger_eager_loading_when_ordering_using_owner_table_and_symbols
|
|
1897
|
+
scope = Post.includes(:comments).order(:"posts.title")
|
|
1898
|
+
assert_not_predicate scope, :eager_loading?
|
|
1899
|
+
end
|
|
1900
|
+
|
|
1901
|
+
def test_order_triggers_eager_loading_when_ordering_using_hash_syntax
|
|
1902
|
+
scope = Post.includes(:comments).order({ "comments.label": :ASC })
|
|
1903
|
+
assert_predicate scope, :eager_loading?
|
|
1904
|
+
end
|
|
1905
|
+
|
|
1906
|
+
def test_order_doesnt_trigger_eager_loading_when_ordering_using_the_owner_table_and_hash_syntax
|
|
1907
|
+
scope = Post.includes(:comments).order({ "posts.title": :ASC })
|
|
1908
|
+
assert_not_predicate scope, :eager_loading?
|
|
1909
|
+
end
|
|
1910
|
+
|
|
1693
1911
|
def test_automatically_added_where_references
|
|
1694
1912
|
scope = Post.where(comments: { body: "Bla" })
|
|
1695
1913
|
assert_equal ["comments"], scope.references_values
|
|
@@ -1719,11 +1937,8 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1719
1937
|
assert_equal ["comments"], scope.references_values
|
|
1720
1938
|
|
|
1721
1939
|
scope = Post.order("#{Comment.quoted_table_name}.#{Comment.quoted_primary_key}")
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
else
|
|
1725
|
-
assert_equal ["comments"], scope.references_values
|
|
1726
|
-
end
|
|
1940
|
+
|
|
1941
|
+
assert_equal ["comments"], scope.references_values
|
|
1727
1942
|
|
|
1728
1943
|
scope = Post.order("comments.body", "yaks.body")
|
|
1729
1944
|
assert_equal ["comments", "yaks"], scope.references_values
|
|
@@ -1744,11 +1959,8 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1744
1959
|
assert_equal %w(comments), scope.references_values
|
|
1745
1960
|
|
|
1746
1961
|
scope = Post.reorder("#{Comment.quoted_table_name}.#{Comment.quoted_primary_key}")
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
else
|
|
1750
|
-
assert_equal ["comments"], scope.references_values
|
|
1751
|
-
end
|
|
1962
|
+
|
|
1963
|
+
assert_equal ["comments"], scope.references_values
|
|
1752
1964
|
|
|
1753
1965
|
scope = Post.reorder("comments.body", "yaks.body")
|
|
1754
1966
|
assert_equal %w(comments yaks), scope.references_values
|
|
@@ -1777,17 +1989,14 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1777
1989
|
end
|
|
1778
1990
|
|
|
1779
1991
|
def test_reorder_with_first
|
|
1992
|
+
post = nil
|
|
1993
|
+
|
|
1780
1994
|
sql_log = capture_sql do
|
|
1781
|
-
|
|
1782
|
-
`.reorder(nil)` with `.first` / `.first!` no longer
|
|
1783
|
-
takes non-deterministic result in Rails 7.0.
|
|
1784
|
-
To continue taking non-deterministic result, use `.take` / `.take!` instead.
|
|
1785
|
-
MSG
|
|
1786
|
-
assert_deprecated(message) do
|
|
1787
|
-
assert Post.order(:title).reorder(nil).first
|
|
1788
|
-
end
|
|
1995
|
+
post = Post.order(:title).reorder(nil).first
|
|
1789
1996
|
end
|
|
1790
|
-
|
|
1997
|
+
|
|
1998
|
+
assert_equal posts(:welcome), post
|
|
1999
|
+
assert sql_log.any? { |sql| /order by/i.match?(sql) }, "ORDER BY was not used in the query: #{sql_log}"
|
|
1791
2000
|
end
|
|
1792
2001
|
|
|
1793
2002
|
def test_reorder_with_take
|
|
@@ -1801,11 +2010,11 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1801
2010
|
topics = Topic.all
|
|
1802
2011
|
|
|
1803
2012
|
# the first query is triggered because there are no topics yet.
|
|
1804
|
-
|
|
2013
|
+
assert_queries_count(1) { assert_predicate topics, :present? }
|
|
1805
2014
|
|
|
1806
2015
|
# checking if there are topics is used before you actually display them,
|
|
1807
2016
|
# thus it shouldn't invoke an extra count query.
|
|
1808
|
-
assert_no_queries {
|
|
2017
|
+
assert_no_queries { assert_predicate topics, :present? }
|
|
1809
2018
|
assert_no_queries { assert_not topics.blank? }
|
|
1810
2019
|
|
|
1811
2020
|
# shows count of topics and loops after loading the query should not trigger extra queries either.
|
|
@@ -1814,7 +2023,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1814
2023
|
assert_no_queries { topics.each }
|
|
1815
2024
|
|
|
1816
2025
|
# count always trigger the COUNT query.
|
|
1817
|
-
|
|
2026
|
+
assert_queries_count(1) { topics.count }
|
|
1818
2027
|
|
|
1819
2028
|
assert_predicate topics, :loaded?
|
|
1820
2029
|
end
|
|
@@ -1854,7 +2063,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1854
2063
|
end
|
|
1855
2064
|
|
|
1856
2065
|
test "find_by doesn't have implicit ordering" do
|
|
1857
|
-
|
|
2066
|
+
assert_queries_match(/^((?!ORDER).)*$/) { Post.all.find_by(author_id: 2) }
|
|
1858
2067
|
end
|
|
1859
2068
|
|
|
1860
2069
|
test "find_by requires at least one argument" do
|
|
@@ -1874,7 +2083,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1874
2083
|
end
|
|
1875
2084
|
|
|
1876
2085
|
test "find_by! doesn't have implicit ordering" do
|
|
1877
|
-
|
|
2086
|
+
assert_queries_match(/^((?!ORDER).)*$/) { Post.all.find_by!(author_id: 2) }
|
|
1878
2087
|
end
|
|
1879
2088
|
|
|
1880
2089
|
test "find_by! raises RecordNotFound if the record is missing" do
|
|
@@ -1891,7 +2100,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1891
2100
|
relation = Post.all
|
|
1892
2101
|
relation.to_a
|
|
1893
2102
|
|
|
1894
|
-
assert_raises(ActiveRecord::
|
|
2103
|
+
assert_raises(ActiveRecord::UnmodifiableRelation) do
|
|
1895
2104
|
relation.where! "foo"
|
|
1896
2105
|
end
|
|
1897
2106
|
end
|
|
@@ -1900,7 +2109,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1900
2109
|
relation = Post.all
|
|
1901
2110
|
relation.to_a
|
|
1902
2111
|
|
|
1903
|
-
assert_raises(ActiveRecord::
|
|
2112
|
+
assert_raises(ActiveRecord::UnmodifiableRelation) do
|
|
1904
2113
|
relation.limit! 5
|
|
1905
2114
|
end
|
|
1906
2115
|
end
|
|
@@ -1909,7 +2118,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1909
2118
|
relation = Post.all
|
|
1910
2119
|
relation.to_a
|
|
1911
2120
|
|
|
1912
|
-
assert_raises(ActiveRecord::
|
|
2121
|
+
assert_raises(ActiveRecord::UnmodifiableRelation) do
|
|
1913
2122
|
relation.merge! where: "foo"
|
|
1914
2123
|
end
|
|
1915
2124
|
end
|
|
@@ -1918,7 +2127,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1918
2127
|
relation = Post.all
|
|
1919
2128
|
relation.to_a
|
|
1920
2129
|
|
|
1921
|
-
assert_raises(ActiveRecord::
|
|
2130
|
+
assert_raises(ActiveRecord::UnmodifiableRelation) do
|
|
1922
2131
|
relation.extending! Module.new
|
|
1923
2132
|
end
|
|
1924
2133
|
end
|
|
@@ -1927,8 +2136,8 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1927
2136
|
relation = Post.all
|
|
1928
2137
|
relation.arel
|
|
1929
2138
|
|
|
1930
|
-
assert_raises(ActiveRecord::
|
|
1931
|
-
assert_raises(ActiveRecord::
|
|
2139
|
+
assert_raises(ActiveRecord::UnmodifiableRelation) { relation.limit!(5) }
|
|
2140
|
+
assert_raises(ActiveRecord::UnmodifiableRelation) { relation.where!("1 = 2") }
|
|
1932
2141
|
end
|
|
1933
2142
|
|
|
1934
2143
|
test "relations show the records in #inspect" do
|
|
@@ -1942,13 +2151,13 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1942
2151
|
end
|
|
1943
2152
|
|
|
1944
2153
|
test "relations don't load all records in #inspect" do
|
|
1945
|
-
|
|
2154
|
+
assert_queries_match(/LIMIT|ROWNUM <=|FETCH FIRST/) do
|
|
1946
2155
|
Post.all.inspect
|
|
1947
2156
|
end
|
|
1948
2157
|
end
|
|
1949
2158
|
|
|
1950
2159
|
test "loading query is annotated in #inspect" do
|
|
1951
|
-
|
|
2160
|
+
assert_queries_match(%r(/\* loading for inspect \*/)) do
|
|
1952
2161
|
Post.all.inspect
|
|
1953
2162
|
end
|
|
1954
2163
|
end
|
|
@@ -1964,6 +2173,35 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1964
2173
|
end
|
|
1965
2174
|
end
|
|
1966
2175
|
|
|
2176
|
+
test "relations limit the records in #pretty_print at 10" do
|
|
2177
|
+
relation = Post.limit(11)
|
|
2178
|
+
out = StringIO.new
|
|
2179
|
+
PP.pp(relation, out)
|
|
2180
|
+
assert_equal 10, out.string.scan(/#<\w*Post:/).size
|
|
2181
|
+
assert out.string.end_with?("\"...\"]\n"), "Did not end with an ellipsis."
|
|
2182
|
+
end
|
|
2183
|
+
|
|
2184
|
+
test "relations don't load all records in #pretty_print" do
|
|
2185
|
+
assert_queries_match(/LIMIT|ROWNUM <=|FETCH FIRST/) do
|
|
2186
|
+
PP.pp Post.all, StringIO.new # avoid outputting.
|
|
2187
|
+
end
|
|
2188
|
+
end
|
|
2189
|
+
|
|
2190
|
+
test "loading query is annotated in #pretty_print" do
|
|
2191
|
+
assert_queries_match(%r(/\* loading for pp \*/)) do
|
|
2192
|
+
PP.pp Post.all, StringIO.new # avoid outputting.
|
|
2193
|
+
end
|
|
2194
|
+
end
|
|
2195
|
+
|
|
2196
|
+
test "already-loaded relations don't perform a new query in #pretty_print" do
|
|
2197
|
+
relation = Post.limit(2)
|
|
2198
|
+
relation.to_a
|
|
2199
|
+
|
|
2200
|
+
assert_no_queries do
|
|
2201
|
+
PP.pp relation, StringIO.new # avoid outputting.
|
|
2202
|
+
end
|
|
2203
|
+
end
|
|
2204
|
+
|
|
1967
2205
|
test "using a custom table affects the wheres" do
|
|
1968
2206
|
post = posts(:welcome)
|
|
1969
2207
|
|
|
@@ -1986,7 +2224,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
1986
2224
|
|
|
1987
2225
|
test "#load" do
|
|
1988
2226
|
relation = Post.all
|
|
1989
|
-
|
|
2227
|
+
assert_queries_count(1) do
|
|
1990
2228
|
assert_equal relation, relation.load
|
|
1991
2229
|
end
|
|
1992
2230
|
assert_no_queries { relation.to_a }
|
|
@@ -2021,6 +2259,8 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
2021
2259
|
test "joins with order by custom attribute" do
|
|
2022
2260
|
companies = Company.create!([{ name: "test1" }, { name: "test2" }])
|
|
2023
2261
|
companies.each { |company| company.contracts.create! }
|
|
2262
|
+
# In ordering by Contract#metadata, we rely on that JSON string to
|
|
2263
|
+
# be consistent
|
|
2024
2264
|
assert_equal companies, Company.joins(:contracts).order(:metadata, :count)
|
|
2025
2265
|
assert_equal companies.reverse, Company.joins(:contracts).order(metadata: :desc, count: :desc)
|
|
2026
2266
|
end
|
|
@@ -2126,6 +2366,20 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
2126
2366
|
assert_equal Post.count, posts.unscope(where: :title).count
|
|
2127
2367
|
end
|
|
2128
2368
|
|
|
2369
|
+
def test_unscope_with_double_dot_where
|
|
2370
|
+
posts = Post.where(id: 1..2)
|
|
2371
|
+
|
|
2372
|
+
assert_equal 2, posts.count
|
|
2373
|
+
assert_equal Post.count, posts.unscope(where: :id).count
|
|
2374
|
+
end
|
|
2375
|
+
|
|
2376
|
+
def test_unscope_with_triple_dot_where
|
|
2377
|
+
posts = Post.where(id: 1...3)
|
|
2378
|
+
|
|
2379
|
+
assert_equal 2, posts.count
|
|
2380
|
+
assert_equal Post.count, posts.unscope(where: :id).count
|
|
2381
|
+
end
|
|
2382
|
+
|
|
2129
2383
|
def test_locked_should_not_build_arel
|
|
2130
2384
|
posts = Post.locked
|
|
2131
2385
|
assert_predicate posts, :locked?
|
|
@@ -2176,12 +2430,12 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
2176
2430
|
|
|
2177
2431
|
test "#skip_query_cache!" do
|
|
2178
2432
|
Post.cache do
|
|
2179
|
-
|
|
2433
|
+
assert_queries_count(1) do
|
|
2180
2434
|
Post.all.load
|
|
2181
2435
|
Post.all.load
|
|
2182
2436
|
end
|
|
2183
2437
|
|
|
2184
|
-
|
|
2438
|
+
assert_queries_count(2) do
|
|
2185
2439
|
Post.all.skip_query_cache!.load
|
|
2186
2440
|
Post.all.skip_query_cache!.load
|
|
2187
2441
|
end
|
|
@@ -2190,12 +2444,12 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
2190
2444
|
|
|
2191
2445
|
test "#skip_query_cache! with an eager load" do
|
|
2192
2446
|
Post.cache do
|
|
2193
|
-
|
|
2447
|
+
assert_queries_count(1) do
|
|
2194
2448
|
Post.eager_load(:comments).load
|
|
2195
2449
|
Post.eager_load(:comments).load
|
|
2196
2450
|
end
|
|
2197
2451
|
|
|
2198
|
-
|
|
2452
|
+
assert_queries_count(2) do
|
|
2199
2453
|
Post.eager_load(:comments).skip_query_cache!.load
|
|
2200
2454
|
Post.eager_load(:comments).skip_query_cache!.load
|
|
2201
2455
|
end
|
|
@@ -2204,12 +2458,12 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
2204
2458
|
|
|
2205
2459
|
test "#skip_query_cache! with a preload" do
|
|
2206
2460
|
Post.cache do
|
|
2207
|
-
|
|
2461
|
+
assert_queries_count(2) do
|
|
2208
2462
|
Post.preload(:comments).load
|
|
2209
2463
|
Post.preload(:comments).load
|
|
2210
2464
|
end
|
|
2211
2465
|
|
|
2212
|
-
|
|
2466
|
+
assert_queries_count(4) do
|
|
2213
2467
|
Post.preload(:comments).skip_query_cache!.load
|
|
2214
2468
|
Post.preload(:comments).skip_query_cache!.load
|
|
2215
2469
|
end
|
|
@@ -2229,7 +2483,7 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
2229
2483
|
assert_empty authors
|
|
2230
2484
|
end
|
|
2231
2485
|
|
|
2232
|
-
(ActiveRecord::Relation::MULTI_VALUE_METHODS - [:extending]).each do |method|
|
|
2486
|
+
(ActiveRecord::Relation::MULTI_VALUE_METHODS - [:extending, :with]).each do |method|
|
|
2233
2487
|
test "#{method} with blank value" do
|
|
2234
2488
|
authors = Author.public_send(method, [""])
|
|
2235
2489
|
assert_empty authors.public_send(:"#{method}_values")
|
|
@@ -2239,13 +2493,57 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
2239
2493
|
private
|
|
2240
2494
|
def custom_post_relation(alias_name = "omg_posts")
|
|
2241
2495
|
table_alias = Post.arel_table.alias(alias_name)
|
|
2242
|
-
table_metadata = ActiveRecord::TableMetadata.new(Post, table_alias)
|
|
2243
|
-
predicate_builder = ActiveRecord::PredicateBuilder.new(table_metadata)
|
|
2244
2496
|
|
|
2245
|
-
ActiveRecord::Relation.create(
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2497
|
+
ActiveRecord::Relation.create(Post, table: table_alias)
|
|
2498
|
+
end
|
|
2499
|
+
end
|
|
2500
|
+
|
|
2501
|
+
class CreateOrFindByWithinTransactions < ActiveRecord::TestCase
|
|
2502
|
+
unless current_adapter?(:SQLite3Adapter)
|
|
2503
|
+
self.use_transactional_tests = false
|
|
2504
|
+
|
|
2505
|
+
def teardown
|
|
2506
|
+
Subscriber.delete_all
|
|
2507
|
+
end
|
|
2508
|
+
|
|
2509
|
+
def test_multiple_find_or_create_by_within_transactions
|
|
2510
|
+
duel { Subscriber.find_or_create_by(nick: "bob") }
|
|
2511
|
+
end
|
|
2512
|
+
|
|
2513
|
+
def test_multiple_find_or_create_by_bang_within_transactions
|
|
2514
|
+
duel { Subscriber.find_or_create_by!(nick: "bob") }
|
|
2250
2515
|
end
|
|
2516
|
+
|
|
2517
|
+
private
|
|
2518
|
+
def duel
|
|
2519
|
+
assert_nil Subscriber.find_by(nick: "bob")
|
|
2520
|
+
|
|
2521
|
+
a_wakeup = Concurrent::Event.new
|
|
2522
|
+
b_wakeup = Concurrent::Event.new
|
|
2523
|
+
|
|
2524
|
+
a = Thread.new do
|
|
2525
|
+
Subscriber.transaction do
|
|
2526
|
+
a_wakeup.wait
|
|
2527
|
+
yield
|
|
2528
|
+
b_wakeup.set
|
|
2529
|
+
end
|
|
2530
|
+
end
|
|
2531
|
+
|
|
2532
|
+
b = Thread.new do
|
|
2533
|
+
Subscriber.transaction do
|
|
2534
|
+
# Read the record prematurely for MySQL REPEATABLE READ to kick in
|
|
2535
|
+
Subscriber.find_by(nick: "bob")
|
|
2536
|
+
|
|
2537
|
+
a_wakeup.set
|
|
2538
|
+
b_wakeup.wait
|
|
2539
|
+
yield
|
|
2540
|
+
end
|
|
2541
|
+
end
|
|
2542
|
+
|
|
2543
|
+
a.join
|
|
2544
|
+
b.join
|
|
2545
|
+
|
|
2546
|
+
assert_equal 1, Subscriber.where(nick: "bob").count
|
|
2547
|
+
end
|
|
2548
|
+
end
|
|
2251
2549
|
end
|