ibm_db 5.2.0-x86-mingw32 → 5.3.2-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +9 -0
- data/LICENSE +55 -18
- data/ext/Makefile +15 -13
- data/ext/ibm_db.c +62 -57
- 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 +1463 -1279
- data/lib/ibm_db.so +1 -0
- data/lib/mswin32/rb3x/i386/ruby30/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 +190 -14
@@ -0,0 +1,1145 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../helper"
|
4
|
+
require "ostruct"
|
5
|
+
|
6
|
+
module Arel
|
7
|
+
module Attributes
|
8
|
+
class AttributeTest < Arel::Spec
|
9
|
+
describe "#not_eq" do
|
10
|
+
it "should create a NotEqual node" do
|
11
|
+
relation = Table.new(:users)
|
12
|
+
_(relation[:id].not_eq(10)).must_be_kind_of Nodes::NotEqual
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should generate != in sql" do
|
16
|
+
relation = Table.new(:users)
|
17
|
+
mgr = relation.project relation[:id]
|
18
|
+
mgr.where relation[:id].not_eq(10)
|
19
|
+
_(mgr.to_sql).must_be_like %{
|
20
|
+
SELECT "users"."id" FROM "users" WHERE "users"."id" != 10
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should handle nil" do
|
25
|
+
relation = Table.new(:users)
|
26
|
+
mgr = relation.project relation[:id]
|
27
|
+
mgr.where relation[:id].not_eq(nil)
|
28
|
+
_(mgr.to_sql).must_be_like %{
|
29
|
+
SELECT "users"."id" FROM "users" WHERE "users"."id" IS NOT NULL
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#not_eq_any" do
|
35
|
+
it "should create a Grouping node" do
|
36
|
+
relation = Table.new(:users)
|
37
|
+
_(relation[:id].not_eq_any([1, 2])).must_be_kind_of Nodes::Grouping
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should generate ORs in sql" do
|
41
|
+
relation = Table.new(:users)
|
42
|
+
mgr = relation.project relation[:id]
|
43
|
+
mgr.where relation[:id].not_eq_any([1, 2])
|
44
|
+
_(mgr.to_sql).must_be_like %{
|
45
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" != 1 OR "users"."id" != 2)
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#not_eq_all" do
|
51
|
+
it "should create a Grouping node" do
|
52
|
+
relation = Table.new(:users)
|
53
|
+
_(relation[:id].not_eq_all([1, 2])).must_be_kind_of Nodes::Grouping
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should generate ANDs in sql" do
|
57
|
+
relation = Table.new(:users)
|
58
|
+
mgr = relation.project relation[:id]
|
59
|
+
mgr.where relation[:id].not_eq_all([1, 2])
|
60
|
+
_(mgr.to_sql).must_be_like %{
|
61
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" != 1 AND "users"."id" != 2)
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#gt" do
|
67
|
+
it "should create a GreaterThan node" do
|
68
|
+
relation = Table.new(:users)
|
69
|
+
_(relation[:id].gt(10)).must_be_kind_of Nodes::GreaterThan
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should generate > in sql" do
|
73
|
+
relation = Table.new(:users)
|
74
|
+
mgr = relation.project relation[:id]
|
75
|
+
mgr.where relation[:id].gt(10)
|
76
|
+
_(mgr.to_sql).must_be_like %{
|
77
|
+
SELECT "users"."id" FROM "users" WHERE "users"."id" > 10
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should handle comparing with a subquery" do
|
82
|
+
users = Table.new(:users)
|
83
|
+
|
84
|
+
avg = users.project(users[:karma].average)
|
85
|
+
mgr = users.project(Arel.star).where(users[:karma].gt(avg))
|
86
|
+
|
87
|
+
_(mgr.to_sql).must_be_like %{
|
88
|
+
SELECT * FROM "users" WHERE "users"."karma" > (SELECT AVG("users"."karma") FROM "users")
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should accept various data types." do
|
93
|
+
relation = Table.new(:users)
|
94
|
+
mgr = relation.project relation[:id]
|
95
|
+
mgr.where relation[:name].gt("fake_name")
|
96
|
+
_(mgr.to_sql).must_match %{"users"."name" > 'fake_name'}
|
97
|
+
|
98
|
+
current_time = ::Time.now
|
99
|
+
mgr.where relation[:created_at].gt(current_time)
|
100
|
+
_(mgr.to_sql).must_match %{"users"."created_at" > '#{current_time}'}
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#gt_any" do
|
105
|
+
it "should create a Grouping node" do
|
106
|
+
relation = Table.new(:users)
|
107
|
+
_(relation[:id].gt_any([1, 2])).must_be_kind_of Nodes::Grouping
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should generate ORs in sql" do
|
111
|
+
relation = Table.new(:users)
|
112
|
+
mgr = relation.project relation[:id]
|
113
|
+
mgr.where relation[:id].gt_any([1, 2])
|
114
|
+
_(mgr.to_sql).must_be_like %{
|
115
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" > 1 OR "users"."id" > 2)
|
116
|
+
}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#gt_all" do
|
121
|
+
it "should create a Grouping node" do
|
122
|
+
relation = Table.new(:users)
|
123
|
+
_(relation[:id].gt_all([1, 2])).must_be_kind_of Nodes::Grouping
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should generate ANDs in sql" do
|
127
|
+
relation = Table.new(:users)
|
128
|
+
mgr = relation.project relation[:id]
|
129
|
+
mgr.where relation[:id].gt_all([1, 2])
|
130
|
+
_(mgr.to_sql).must_be_like %{
|
131
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" > 1 AND "users"."id" > 2)
|
132
|
+
}
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "#gteq" do
|
137
|
+
it "should create a GreaterThanOrEqual node" do
|
138
|
+
relation = Table.new(:users)
|
139
|
+
_(relation[:id].gteq(10)).must_be_kind_of Nodes::GreaterThanOrEqual
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should generate >= in sql" do
|
143
|
+
relation = Table.new(:users)
|
144
|
+
mgr = relation.project relation[:id]
|
145
|
+
mgr.where relation[:id].gteq(10)
|
146
|
+
_(mgr.to_sql).must_be_like %{
|
147
|
+
SELECT "users"."id" FROM "users" WHERE "users"."id" >= 10
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should accept various data types." do
|
152
|
+
relation = Table.new(:users)
|
153
|
+
mgr = relation.project relation[:id]
|
154
|
+
mgr.where relation[:name].gteq("fake_name")
|
155
|
+
_(mgr.to_sql).must_match %{"users"."name" >= 'fake_name'}
|
156
|
+
|
157
|
+
current_time = ::Time.now
|
158
|
+
mgr.where relation[:created_at].gteq(current_time)
|
159
|
+
_(mgr.to_sql).must_match %{"users"."created_at" >= '#{current_time}'}
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "#gteq_any" do
|
164
|
+
it "should create a Grouping node" do
|
165
|
+
relation = Table.new(:users)
|
166
|
+
_(relation[:id].gteq_any([1, 2])).must_be_kind_of Nodes::Grouping
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should generate ORs in sql" do
|
170
|
+
relation = Table.new(:users)
|
171
|
+
mgr = relation.project relation[:id]
|
172
|
+
mgr.where relation[:id].gteq_any([1, 2])
|
173
|
+
_(mgr.to_sql).must_be_like %{
|
174
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" >= 1 OR "users"."id" >= 2)
|
175
|
+
}
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe "#gteq_all" do
|
180
|
+
it "should create a Grouping node" do
|
181
|
+
relation = Table.new(:users)
|
182
|
+
_(relation[:id].gteq_all([1, 2])).must_be_kind_of Nodes::Grouping
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should generate ANDs in sql" do
|
186
|
+
relation = Table.new(:users)
|
187
|
+
mgr = relation.project relation[:id]
|
188
|
+
mgr.where relation[:id].gteq_all([1, 2])
|
189
|
+
_(mgr.to_sql).must_be_like %{
|
190
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" >= 1 AND "users"."id" >= 2)
|
191
|
+
}
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe "#lt" do
|
196
|
+
it "should create a LessThan node" do
|
197
|
+
relation = Table.new(:users)
|
198
|
+
_(relation[:id].lt(10)).must_be_kind_of Nodes::LessThan
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should generate < in sql" do
|
202
|
+
relation = Table.new(:users)
|
203
|
+
mgr = relation.project relation[:id]
|
204
|
+
mgr.where relation[:id].lt(10)
|
205
|
+
_(mgr.to_sql).must_be_like %{
|
206
|
+
SELECT "users"."id" FROM "users" WHERE "users"."id" < 10
|
207
|
+
}
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should accept various data types." do
|
211
|
+
relation = Table.new(:users)
|
212
|
+
mgr = relation.project relation[:id]
|
213
|
+
mgr.where relation[:name].lt("fake_name")
|
214
|
+
_(mgr.to_sql).must_match %{"users"."name" < 'fake_name'}
|
215
|
+
|
216
|
+
current_time = ::Time.now
|
217
|
+
mgr.where relation[:created_at].lt(current_time)
|
218
|
+
_(mgr.to_sql).must_match %{"users"."created_at" < '#{current_time}'}
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
describe "#lt_any" do
|
223
|
+
it "should create a Grouping node" do
|
224
|
+
relation = Table.new(:users)
|
225
|
+
_(relation[:id].lt_any([1, 2])).must_be_kind_of Nodes::Grouping
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should generate ORs in sql" do
|
229
|
+
relation = Table.new(:users)
|
230
|
+
mgr = relation.project relation[:id]
|
231
|
+
mgr.where relation[:id].lt_any([1, 2])
|
232
|
+
_(mgr.to_sql).must_be_like %{
|
233
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" < 1 OR "users"."id" < 2)
|
234
|
+
}
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
describe "#lt_all" do
|
239
|
+
it "should create a Grouping node" do
|
240
|
+
relation = Table.new(:users)
|
241
|
+
_(relation[:id].lt_all([1, 2])).must_be_kind_of Nodes::Grouping
|
242
|
+
end
|
243
|
+
|
244
|
+
it "should generate ANDs in sql" do
|
245
|
+
relation = Table.new(:users)
|
246
|
+
mgr = relation.project relation[:id]
|
247
|
+
mgr.where relation[:id].lt_all([1, 2])
|
248
|
+
_(mgr.to_sql).must_be_like %{
|
249
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" < 1 AND "users"."id" < 2)
|
250
|
+
}
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
describe "#lteq" do
|
255
|
+
it "should create a LessThanOrEqual node" do
|
256
|
+
relation = Table.new(:users)
|
257
|
+
_(relation[:id].lteq(10)).must_be_kind_of Nodes::LessThanOrEqual
|
258
|
+
end
|
259
|
+
|
260
|
+
it "should generate <= in sql" do
|
261
|
+
relation = Table.new(:users)
|
262
|
+
mgr = relation.project relation[:id]
|
263
|
+
mgr.where relation[:id].lteq(10)
|
264
|
+
_(mgr.to_sql).must_be_like %{
|
265
|
+
SELECT "users"."id" FROM "users" WHERE "users"."id" <= 10
|
266
|
+
}
|
267
|
+
end
|
268
|
+
|
269
|
+
it "should accept various data types." do
|
270
|
+
relation = Table.new(:users)
|
271
|
+
mgr = relation.project relation[:id]
|
272
|
+
mgr.where relation[:name].lteq("fake_name")
|
273
|
+
_(mgr.to_sql).must_match %{"users"."name" <= 'fake_name'}
|
274
|
+
|
275
|
+
current_time = ::Time.now
|
276
|
+
mgr.where relation[:created_at].lteq(current_time)
|
277
|
+
_(mgr.to_sql).must_match %{"users"."created_at" <= '#{current_time}'}
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
describe "#lteq_any" do
|
282
|
+
it "should create a Grouping node" do
|
283
|
+
relation = Table.new(:users)
|
284
|
+
_(relation[:id].lteq_any([1, 2])).must_be_kind_of Nodes::Grouping
|
285
|
+
end
|
286
|
+
|
287
|
+
it "should generate ORs in sql" do
|
288
|
+
relation = Table.new(:users)
|
289
|
+
mgr = relation.project relation[:id]
|
290
|
+
mgr.where relation[:id].lteq_any([1, 2])
|
291
|
+
_(mgr.to_sql).must_be_like %{
|
292
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" <= 1 OR "users"."id" <= 2)
|
293
|
+
}
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
describe "#lteq_all" do
|
298
|
+
it "should create a Grouping node" do
|
299
|
+
relation = Table.new(:users)
|
300
|
+
_(relation[:id].lteq_all([1, 2])).must_be_kind_of Nodes::Grouping
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should generate ANDs in sql" do
|
304
|
+
relation = Table.new(:users)
|
305
|
+
mgr = relation.project relation[:id]
|
306
|
+
mgr.where relation[:id].lteq_all([1, 2])
|
307
|
+
_(mgr.to_sql).must_be_like %{
|
308
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" <= 1 AND "users"."id" <= 2)
|
309
|
+
}
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
describe "#average" do
|
314
|
+
it "should create a AVG node" do
|
315
|
+
relation = Table.new(:users)
|
316
|
+
_(relation[:id].average).must_be_kind_of Nodes::Avg
|
317
|
+
end
|
318
|
+
|
319
|
+
it "should generate the proper SQL" do
|
320
|
+
relation = Table.new(:users)
|
321
|
+
mgr = relation.project relation[:id].average
|
322
|
+
_(mgr.to_sql).must_be_like %{
|
323
|
+
SELECT AVG("users"."id")
|
324
|
+
FROM "users"
|
325
|
+
}
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
describe "#maximum" do
|
330
|
+
it "should create a MAX node" do
|
331
|
+
relation = Table.new(:users)
|
332
|
+
_(relation[:id].maximum).must_be_kind_of Nodes::Max
|
333
|
+
end
|
334
|
+
|
335
|
+
it "should generate proper SQL" do
|
336
|
+
relation = Table.new(:users)
|
337
|
+
mgr = relation.project relation[:id].maximum
|
338
|
+
_(mgr.to_sql).must_be_like %{
|
339
|
+
SELECT MAX("users"."id")
|
340
|
+
FROM "users"
|
341
|
+
}
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
describe "#minimum" do
|
346
|
+
it "should create a Min node" do
|
347
|
+
relation = Table.new(:users)
|
348
|
+
_(relation[:id].minimum).must_be_kind_of Nodes::Min
|
349
|
+
end
|
350
|
+
|
351
|
+
it "should generate proper SQL" do
|
352
|
+
relation = Table.new(:users)
|
353
|
+
mgr = relation.project relation[:id].minimum
|
354
|
+
_(mgr.to_sql).must_be_like %{
|
355
|
+
SELECT MIN("users"."id")
|
356
|
+
FROM "users"
|
357
|
+
}
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
describe "#sum" do
|
362
|
+
it "should create a SUM node" do
|
363
|
+
relation = Table.new(:users)
|
364
|
+
_(relation[:id].sum).must_be_kind_of Nodes::Sum
|
365
|
+
end
|
366
|
+
|
367
|
+
it "should generate the proper SQL" do
|
368
|
+
relation = Table.new(:users)
|
369
|
+
mgr = relation.project relation[:id].sum
|
370
|
+
_(mgr.to_sql).must_be_like %{
|
371
|
+
SELECT SUM("users"."id")
|
372
|
+
FROM "users"
|
373
|
+
}
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
describe "#count" do
|
378
|
+
it "should return a count node" do
|
379
|
+
relation = Table.new(:users)
|
380
|
+
_(relation[:id].count).must_be_kind_of Nodes::Count
|
381
|
+
end
|
382
|
+
|
383
|
+
it "should take a distinct param" do
|
384
|
+
relation = Table.new(:users)
|
385
|
+
count = relation[:id].count(nil)
|
386
|
+
_(count).must_be_kind_of Nodes::Count
|
387
|
+
_(count.distinct).must_be_nil
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
describe "#eq" do
|
392
|
+
it "should return an equality node" do
|
393
|
+
attribute = Attribute.new nil, nil
|
394
|
+
equality = attribute.eq 1
|
395
|
+
_(equality.left).must_equal attribute
|
396
|
+
_(equality.right.value).must_equal 1
|
397
|
+
_(equality).must_be_kind_of Nodes::Equality
|
398
|
+
end
|
399
|
+
|
400
|
+
it "should generate = in sql" do
|
401
|
+
relation = Table.new(:users)
|
402
|
+
mgr = relation.project relation[:id]
|
403
|
+
mgr.where relation[:id].eq(10)
|
404
|
+
_(mgr.to_sql).must_be_like %{
|
405
|
+
SELECT "users"."id" FROM "users" WHERE "users"."id" = 10
|
406
|
+
}
|
407
|
+
end
|
408
|
+
|
409
|
+
it "should handle nil" do
|
410
|
+
relation = Table.new(:users)
|
411
|
+
mgr = relation.project relation[:id]
|
412
|
+
mgr.where relation[:id].eq(nil)
|
413
|
+
_(mgr.to_sql).must_be_like %{
|
414
|
+
SELECT "users"."id" FROM "users" WHERE "users"."id" IS NULL
|
415
|
+
}
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
describe "#eq_any" do
|
420
|
+
it "should create a Grouping node" do
|
421
|
+
relation = Table.new(:users)
|
422
|
+
_(relation[:id].eq_any([1, 2])).must_be_kind_of Nodes::Grouping
|
423
|
+
end
|
424
|
+
|
425
|
+
it "should generate ORs in sql" do
|
426
|
+
relation = Table.new(:users)
|
427
|
+
mgr = relation.project relation[:id]
|
428
|
+
mgr.where relation[:id].eq_any([1, 2])
|
429
|
+
_(mgr.to_sql).must_be_like %{
|
430
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" = 1 OR "users"."id" = 2)
|
431
|
+
}
|
432
|
+
end
|
433
|
+
|
434
|
+
it "should not eat input" do
|
435
|
+
relation = Table.new(:users)
|
436
|
+
mgr = relation.project relation[:id]
|
437
|
+
values = [1, 2]
|
438
|
+
mgr.where relation[:id].eq_any(values)
|
439
|
+
_(values).must_equal [1, 2]
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
describe "#eq_all" do
|
444
|
+
it "should create a Grouping node" do
|
445
|
+
relation = Table.new(:users)
|
446
|
+
_(relation[:id].eq_all([1, 2])).must_be_kind_of Nodes::Grouping
|
447
|
+
end
|
448
|
+
|
449
|
+
it "should generate ANDs in sql" do
|
450
|
+
relation = Table.new(:users)
|
451
|
+
mgr = relation.project relation[:id]
|
452
|
+
mgr.where relation[:id].eq_all([1, 2])
|
453
|
+
_(mgr.to_sql).must_be_like %{
|
454
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" = 1 AND "users"."id" = 2)
|
455
|
+
}
|
456
|
+
end
|
457
|
+
|
458
|
+
it "should not eat input" do
|
459
|
+
relation = Table.new(:users)
|
460
|
+
mgr = relation.project relation[:id]
|
461
|
+
values = [1, 2]
|
462
|
+
mgr.where relation[:id].eq_all(values)
|
463
|
+
_(values).must_equal [1, 2]
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
describe "#matches" do
|
468
|
+
it "should create a Matches node" do
|
469
|
+
relation = Table.new(:users)
|
470
|
+
_(relation[:name].matches("%bacon%")).must_be_kind_of Nodes::Matches
|
471
|
+
end
|
472
|
+
|
473
|
+
it "should generate LIKE in sql" do
|
474
|
+
relation = Table.new(:users)
|
475
|
+
mgr = relation.project relation[:id]
|
476
|
+
mgr.where relation[:name].matches("%bacon%")
|
477
|
+
_(mgr.to_sql).must_be_like %{
|
478
|
+
SELECT "users"."id" FROM "users" WHERE "users"."name" LIKE '%bacon%'
|
479
|
+
}
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
describe "#matches_any" do
|
484
|
+
it "should create a Grouping node" do
|
485
|
+
relation = Table.new(:users)
|
486
|
+
_(relation[:name].matches_any(["%chunky%", "%bacon%"])).must_be_kind_of Nodes::Grouping
|
487
|
+
end
|
488
|
+
|
489
|
+
it "should generate ORs in sql" do
|
490
|
+
relation = Table.new(:users)
|
491
|
+
mgr = relation.project relation[:id]
|
492
|
+
mgr.where relation[:name].matches_any(["%chunky%", "%bacon%"])
|
493
|
+
_(mgr.to_sql).must_be_like %{
|
494
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."name" LIKE '%chunky%' OR "users"."name" LIKE '%bacon%')
|
495
|
+
}
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
describe "#matches_all" do
|
500
|
+
it "should create a Grouping node" do
|
501
|
+
relation = Table.new(:users)
|
502
|
+
_(relation[:name].matches_all(["%chunky%", "%bacon%"])).must_be_kind_of Nodes::Grouping
|
503
|
+
end
|
504
|
+
|
505
|
+
it "should generate ANDs in sql" do
|
506
|
+
relation = Table.new(:users)
|
507
|
+
mgr = relation.project relation[:id]
|
508
|
+
mgr.where relation[:name].matches_all(["%chunky%", "%bacon%"])
|
509
|
+
_(mgr.to_sql).must_be_like %{
|
510
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."name" LIKE '%chunky%' AND "users"."name" LIKE '%bacon%')
|
511
|
+
}
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
describe "#does_not_match" do
|
516
|
+
it "should create a DoesNotMatch node" do
|
517
|
+
relation = Table.new(:users)
|
518
|
+
_(relation[:name].does_not_match("%bacon%")).must_be_kind_of Nodes::DoesNotMatch
|
519
|
+
end
|
520
|
+
|
521
|
+
it "should generate NOT LIKE in sql" do
|
522
|
+
relation = Table.new(:users)
|
523
|
+
mgr = relation.project relation[:id]
|
524
|
+
mgr.where relation[:name].does_not_match("%bacon%")
|
525
|
+
_(mgr.to_sql).must_be_like %{
|
526
|
+
SELECT "users"."id" FROM "users" WHERE "users"."name" NOT LIKE '%bacon%'
|
527
|
+
}
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
describe "#does_not_match_any" do
|
532
|
+
it "should create a Grouping node" do
|
533
|
+
relation = Table.new(:users)
|
534
|
+
_(relation[:name].does_not_match_any(["%chunky%", "%bacon%"])).must_be_kind_of Nodes::Grouping
|
535
|
+
end
|
536
|
+
|
537
|
+
it "should generate ORs in sql" do
|
538
|
+
relation = Table.new(:users)
|
539
|
+
mgr = relation.project relation[:id]
|
540
|
+
mgr.where relation[:name].does_not_match_any(["%chunky%", "%bacon%"])
|
541
|
+
_(mgr.to_sql).must_be_like %{
|
542
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."name" NOT LIKE '%chunky%' OR "users"."name" NOT LIKE '%bacon%')
|
543
|
+
}
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
describe "#does_not_match_all" do
|
548
|
+
it "should create a Grouping node" do
|
549
|
+
relation = Table.new(:users)
|
550
|
+
_(relation[:name].does_not_match_all(["%chunky%", "%bacon%"])).must_be_kind_of Nodes::Grouping
|
551
|
+
end
|
552
|
+
|
553
|
+
it "should generate ANDs in sql" do
|
554
|
+
relation = Table.new(:users)
|
555
|
+
mgr = relation.project relation[:id]
|
556
|
+
mgr.where relation[:name].does_not_match_all(["%chunky%", "%bacon%"])
|
557
|
+
_(mgr.to_sql).must_be_like %{
|
558
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."name" NOT LIKE '%chunky%' AND "users"."name" NOT LIKE '%bacon%')
|
559
|
+
}
|
560
|
+
end
|
561
|
+
end
|
562
|
+
|
563
|
+
describe "#between" do
|
564
|
+
it "can be constructed with a standard range" do
|
565
|
+
attribute = Attribute.new nil, nil
|
566
|
+
node = attribute.between(1..3)
|
567
|
+
|
568
|
+
_(node).must_equal Nodes::Between.new(
|
569
|
+
attribute,
|
570
|
+
Nodes::And.new([
|
571
|
+
Nodes::Casted.new(1, attribute),
|
572
|
+
Nodes::Casted.new(3, attribute)
|
573
|
+
])
|
574
|
+
)
|
575
|
+
end
|
576
|
+
|
577
|
+
it "can be constructed with a range starting from -Infinity" do
|
578
|
+
attribute = Attribute.new nil, nil
|
579
|
+
node = attribute.between(-::Float::INFINITY..3)
|
580
|
+
|
581
|
+
_(node).must_equal Nodes::LessThanOrEqual.new(
|
582
|
+
attribute,
|
583
|
+
Nodes::Casted.new(3, attribute)
|
584
|
+
)
|
585
|
+
end
|
586
|
+
|
587
|
+
it "can be constructed with a quoted range starting from -Infinity" do
|
588
|
+
attribute = Attribute.new nil, nil
|
589
|
+
node = attribute.between(quoted_range(-::Float::INFINITY, 3, false))
|
590
|
+
|
591
|
+
_(node).must_equal Nodes::LessThanOrEqual.new(
|
592
|
+
attribute,
|
593
|
+
Nodes::Quoted.new(3)
|
594
|
+
)
|
595
|
+
end
|
596
|
+
|
597
|
+
it "can be constructed with an exclusive range starting from -Infinity" do
|
598
|
+
attribute = Attribute.new nil, nil
|
599
|
+
node = attribute.between(-::Float::INFINITY...3)
|
600
|
+
|
601
|
+
_(node).must_equal Nodes::LessThan.new(
|
602
|
+
attribute,
|
603
|
+
Nodes::Casted.new(3, attribute)
|
604
|
+
)
|
605
|
+
end
|
606
|
+
|
607
|
+
it "can be constructed with a quoted exclusive range starting from -Infinity" do
|
608
|
+
attribute = Attribute.new nil, nil
|
609
|
+
node = attribute.between(quoted_range(-::Float::INFINITY, 3, true))
|
610
|
+
|
611
|
+
_(node).must_equal Nodes::LessThan.new(
|
612
|
+
attribute,
|
613
|
+
Nodes::Quoted.new(3)
|
614
|
+
)
|
615
|
+
end
|
616
|
+
|
617
|
+
it "can be constructed with an infinite range" do
|
618
|
+
attribute = Attribute.new nil, nil
|
619
|
+
node = attribute.between(-::Float::INFINITY..::Float::INFINITY)
|
620
|
+
|
621
|
+
_(node).must_equal Nodes::NotIn.new(attribute, [])
|
622
|
+
end
|
623
|
+
|
624
|
+
it "can be constructed with a quoted infinite range" do
|
625
|
+
attribute = Attribute.new nil, nil
|
626
|
+
node = attribute.between(quoted_range(-::Float::INFINITY, ::Float::INFINITY, false))
|
627
|
+
|
628
|
+
_(node).must_equal Nodes::NotIn.new(attribute, [])
|
629
|
+
end
|
630
|
+
|
631
|
+
it "can be constructed with a range ending at Infinity" do
|
632
|
+
attribute = Attribute.new nil, nil
|
633
|
+
node = attribute.between(0..::Float::INFINITY)
|
634
|
+
|
635
|
+
_(node).must_equal Nodes::GreaterThanOrEqual.new(
|
636
|
+
attribute,
|
637
|
+
Nodes::Casted.new(0, attribute)
|
638
|
+
)
|
639
|
+
end
|
640
|
+
|
641
|
+
if RUBY_VERSION >= "2.7"
|
642
|
+
it "can be constructed with a range implicitly starting at Infinity" do
|
643
|
+
attribute = Attribute.new nil, nil
|
644
|
+
node = attribute.between(eval("..0")) # eval for backwards compatibility
|
645
|
+
|
646
|
+
_(node).must_equal Nodes::LessThanOrEqual.new(
|
647
|
+
attribute,
|
648
|
+
Nodes::Casted.new(0, attribute)
|
649
|
+
)
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
653
|
+
if RUBY_VERSION >= "2.6"
|
654
|
+
it "can be constructed with a range implicitly ending at Infinity" do
|
655
|
+
attribute = Attribute.new nil, nil
|
656
|
+
node = attribute.between(eval("0..")) # Use eval for compatibility with Ruby < 2.6 parser
|
657
|
+
|
658
|
+
_(node).must_equal Nodes::GreaterThanOrEqual.new(
|
659
|
+
attribute,
|
660
|
+
Nodes::Casted.new(0, attribute)
|
661
|
+
)
|
662
|
+
end
|
663
|
+
end
|
664
|
+
|
665
|
+
it "can be constructed with a quoted range ending at Infinity" do
|
666
|
+
attribute = Attribute.new nil, nil
|
667
|
+
node = attribute.between(quoted_range(0, ::Float::INFINITY, false))
|
668
|
+
|
669
|
+
_(node).must_equal Nodes::GreaterThanOrEqual.new(
|
670
|
+
attribute,
|
671
|
+
Nodes::Quoted.new(0)
|
672
|
+
)
|
673
|
+
end
|
674
|
+
|
675
|
+
it "can be constructed with an exclusive range" do
|
676
|
+
attribute = Attribute.new nil, nil
|
677
|
+
node = attribute.between(0...3)
|
678
|
+
|
679
|
+
_(node).must_equal Nodes::And.new([
|
680
|
+
Nodes::GreaterThanOrEqual.new(
|
681
|
+
attribute,
|
682
|
+
Nodes::Casted.new(0, attribute)
|
683
|
+
),
|
684
|
+
Nodes::LessThan.new(
|
685
|
+
attribute,
|
686
|
+
Nodes::Casted.new(3, attribute)
|
687
|
+
)
|
688
|
+
])
|
689
|
+
end
|
690
|
+
end
|
691
|
+
|
692
|
+
describe "#in" do
|
693
|
+
it "can be constructed with a subquery" do
|
694
|
+
relation = Table.new(:users)
|
695
|
+
mgr = relation.project relation[:id]
|
696
|
+
mgr.where relation[:name].does_not_match_all(["%chunky%", "%bacon%"])
|
697
|
+
attribute = Attribute.new nil, nil
|
698
|
+
|
699
|
+
node = attribute.in(mgr)
|
700
|
+
|
701
|
+
_(node).must_equal Nodes::In.new(attribute, mgr.ast)
|
702
|
+
end
|
703
|
+
|
704
|
+
it "can be constructed with a list" do
|
705
|
+
attribute = Attribute.new nil, nil
|
706
|
+
node = attribute.in([1, 2, 3])
|
707
|
+
|
708
|
+
_(node).must_equal Nodes::In.new(
|
709
|
+
attribute,
|
710
|
+
[
|
711
|
+
Nodes::Casted.new(1, attribute),
|
712
|
+
Nodes::Casted.new(2, attribute),
|
713
|
+
Nodes::Casted.new(3, attribute),
|
714
|
+
]
|
715
|
+
)
|
716
|
+
end
|
717
|
+
|
718
|
+
it "can be constructed with a random object" do
|
719
|
+
attribute = Attribute.new nil, nil
|
720
|
+
random_object = Object.new
|
721
|
+
node = attribute.in(random_object)
|
722
|
+
|
723
|
+
_(node).must_equal Nodes::In.new(
|
724
|
+
attribute,
|
725
|
+
Nodes::Casted.new(random_object, attribute)
|
726
|
+
)
|
727
|
+
end
|
728
|
+
|
729
|
+
it "should generate IN in sql" do
|
730
|
+
relation = Table.new(:users)
|
731
|
+
mgr = relation.project relation[:id]
|
732
|
+
mgr.where relation[:id].in([1, 2, 3])
|
733
|
+
_(mgr.to_sql).must_be_like %{
|
734
|
+
SELECT "users"."id" FROM "users" WHERE "users"."id" IN (1, 2, 3)
|
735
|
+
}
|
736
|
+
end
|
737
|
+
end
|
738
|
+
|
739
|
+
describe "#in_any" do
|
740
|
+
it "should create a Grouping node" do
|
741
|
+
relation = Table.new(:users)
|
742
|
+
_(relation[:id].in_any([1, 2])).must_be_kind_of Nodes::Grouping
|
743
|
+
end
|
744
|
+
|
745
|
+
it "should generate ORs in sql" do
|
746
|
+
relation = Table.new(:users)
|
747
|
+
mgr = relation.project relation[:id]
|
748
|
+
mgr.where relation[:id].in_any([[1, 2], [3, 4]])
|
749
|
+
_(mgr.to_sql).must_be_like %{
|
750
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" IN (1, 2) OR "users"."id" IN (3, 4))
|
751
|
+
}
|
752
|
+
end
|
753
|
+
end
|
754
|
+
|
755
|
+
describe "#in_all" do
|
756
|
+
it "should create a Grouping node" do
|
757
|
+
relation = Table.new(:users)
|
758
|
+
_(relation[:id].in_all([1, 2])).must_be_kind_of Nodes::Grouping
|
759
|
+
end
|
760
|
+
|
761
|
+
it "should generate ANDs in sql" do
|
762
|
+
relation = Table.new(:users)
|
763
|
+
mgr = relation.project relation[:id]
|
764
|
+
mgr.where relation[:id].in_all([[1, 2], [3, 4]])
|
765
|
+
_(mgr.to_sql).must_be_like %{
|
766
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" IN (1, 2) AND "users"."id" IN (3, 4))
|
767
|
+
}
|
768
|
+
end
|
769
|
+
end
|
770
|
+
|
771
|
+
describe "#not_between" do
|
772
|
+
it "can be constructed with a standard range" do
|
773
|
+
attribute = Attribute.new nil, nil
|
774
|
+
node = attribute.not_between(1..3)
|
775
|
+
|
776
|
+
_(node).must_equal Nodes::Grouping.new(
|
777
|
+
Nodes::Or.new(
|
778
|
+
Nodes::LessThan.new(
|
779
|
+
attribute,
|
780
|
+
Nodes::Casted.new(1, attribute)
|
781
|
+
),
|
782
|
+
Nodes::GreaterThan.new(
|
783
|
+
attribute,
|
784
|
+
Nodes::Casted.new(3, attribute)
|
785
|
+
)
|
786
|
+
)
|
787
|
+
)
|
788
|
+
end
|
789
|
+
|
790
|
+
it "can be constructed with a range starting from -Infinity" do
|
791
|
+
attribute = Attribute.new nil, nil
|
792
|
+
node = attribute.not_between(-::Float::INFINITY..3)
|
793
|
+
|
794
|
+
_(node).must_equal Nodes::GreaterThan.new(
|
795
|
+
attribute,
|
796
|
+
Nodes::Casted.new(3, attribute)
|
797
|
+
)
|
798
|
+
end
|
799
|
+
|
800
|
+
it "can be constructed with a quoted range starting from -Infinity" do
|
801
|
+
attribute = Attribute.new nil, nil
|
802
|
+
node = attribute.not_between(quoted_range(-::Float::INFINITY, 3, false))
|
803
|
+
|
804
|
+
_(node).must_equal Nodes::GreaterThan.new(
|
805
|
+
attribute,
|
806
|
+
Nodes::Quoted.new(3)
|
807
|
+
)
|
808
|
+
end
|
809
|
+
|
810
|
+
it "can be constructed with an exclusive range starting from -Infinity" do
|
811
|
+
attribute = Attribute.new nil, nil
|
812
|
+
node = attribute.not_between(-::Float::INFINITY...3)
|
813
|
+
|
814
|
+
_(node).must_equal Nodes::GreaterThanOrEqual.new(
|
815
|
+
attribute,
|
816
|
+
Nodes::Casted.new(3, attribute)
|
817
|
+
)
|
818
|
+
end
|
819
|
+
|
820
|
+
it "can be constructed with a quoted exclusive range starting from -Infinity" do
|
821
|
+
attribute = Attribute.new nil, nil
|
822
|
+
node = attribute.not_between(quoted_range(-::Float::INFINITY, 3, true))
|
823
|
+
|
824
|
+
_(node).must_equal Nodes::GreaterThanOrEqual.new(
|
825
|
+
attribute,
|
826
|
+
Nodes::Quoted.new(3)
|
827
|
+
)
|
828
|
+
end
|
829
|
+
|
830
|
+
it "can be constructed with an infinite range" do
|
831
|
+
attribute = Attribute.new nil, nil
|
832
|
+
node = attribute.not_between(-::Float::INFINITY..::Float::INFINITY)
|
833
|
+
|
834
|
+
_(node).must_equal Nodes::In.new(attribute, [])
|
835
|
+
end
|
836
|
+
|
837
|
+
it "can be constructed with a quoted infinite range" do
|
838
|
+
attribute = Attribute.new nil, nil
|
839
|
+
node = attribute.not_between(quoted_range(-::Float::INFINITY, ::Float::INFINITY, false))
|
840
|
+
|
841
|
+
_(node).must_equal Nodes::In.new(attribute, [])
|
842
|
+
end
|
843
|
+
|
844
|
+
it "can be constructed with a range ending at Infinity" do
|
845
|
+
attribute = Attribute.new nil, nil
|
846
|
+
node = attribute.not_between(0..::Float::INFINITY)
|
847
|
+
|
848
|
+
_(node).must_equal Nodes::LessThan.new(
|
849
|
+
attribute,
|
850
|
+
Nodes::Casted.new(0, attribute)
|
851
|
+
)
|
852
|
+
end
|
853
|
+
|
854
|
+
if RUBY_VERSION >= "2.7"
|
855
|
+
it "can be constructed with a range implicitly starting at Infinity" do
|
856
|
+
attribute = Attribute.new nil, nil
|
857
|
+
node = attribute.not_between(eval("..0")) # eval for backwards compatibility
|
858
|
+
|
859
|
+
_(node).must_equal Nodes::GreaterThan.new(
|
860
|
+
attribute,
|
861
|
+
Nodes::Casted.new(0, attribute)
|
862
|
+
)
|
863
|
+
end
|
864
|
+
end
|
865
|
+
|
866
|
+
if RUBY_VERSION >= "2.6"
|
867
|
+
it "can be constructed with a range implicitly ending at Infinity" do
|
868
|
+
attribute = Attribute.new nil, nil
|
869
|
+
node = attribute.not_between(eval("0..")) # Use eval for compatibility with Ruby < 2.6 parser
|
870
|
+
|
871
|
+
_(node).must_equal Nodes::LessThan.new(
|
872
|
+
attribute,
|
873
|
+
Nodes::Casted.new(0, attribute)
|
874
|
+
)
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
878
|
+
it "can be constructed with a quoted range ending at Infinity" do
|
879
|
+
attribute = Attribute.new nil, nil
|
880
|
+
node = attribute.not_between(quoted_range(0, ::Float::INFINITY, false))
|
881
|
+
|
882
|
+
_(node).must_equal Nodes::LessThan.new(
|
883
|
+
attribute,
|
884
|
+
Nodes::Quoted.new(0)
|
885
|
+
)
|
886
|
+
end
|
887
|
+
|
888
|
+
it "can be constructed with an exclusive range" do
|
889
|
+
attribute = Attribute.new nil, nil
|
890
|
+
node = attribute.not_between(0...3)
|
891
|
+
|
892
|
+
_(node).must_equal Nodes::Grouping.new(
|
893
|
+
Nodes::Or.new(
|
894
|
+
Nodes::LessThan.new(
|
895
|
+
attribute,
|
896
|
+
Nodes::Casted.new(0, attribute)
|
897
|
+
),
|
898
|
+
Nodes::GreaterThanOrEqual.new(
|
899
|
+
attribute,
|
900
|
+
Nodes::Casted.new(3, attribute)
|
901
|
+
)
|
902
|
+
)
|
903
|
+
)
|
904
|
+
end
|
905
|
+
end
|
906
|
+
|
907
|
+
describe "#not_in" do
|
908
|
+
it "can be constructed with a subquery" do
|
909
|
+
relation = Table.new(:users)
|
910
|
+
mgr = relation.project relation[:id]
|
911
|
+
mgr.where relation[:name].does_not_match_all(["%chunky%", "%bacon%"])
|
912
|
+
attribute = Attribute.new nil, nil
|
913
|
+
|
914
|
+
node = attribute.not_in(mgr)
|
915
|
+
|
916
|
+
_(node).must_equal Nodes::NotIn.new(attribute, mgr.ast)
|
917
|
+
end
|
918
|
+
|
919
|
+
it "can be constructed with a Union" do
|
920
|
+
relation = Table.new(:users)
|
921
|
+
mgr1 = relation.project(relation[:id])
|
922
|
+
mgr2 = relation.project(relation[:id])
|
923
|
+
|
924
|
+
union = mgr1.union(mgr2)
|
925
|
+
node = relation[:id].in(union)
|
926
|
+
_(node.to_sql).must_be_like %{
|
927
|
+
"users"."id" IN (( SELECT "users"."id" FROM "users" UNION SELECT "users"."id" FROM "users" ))
|
928
|
+
}
|
929
|
+
end
|
930
|
+
|
931
|
+
it "can be constructed with a list" do
|
932
|
+
attribute = Attribute.new nil, nil
|
933
|
+
node = attribute.not_in([1, 2, 3])
|
934
|
+
|
935
|
+
_(node).must_equal Nodes::NotIn.new(
|
936
|
+
attribute,
|
937
|
+
[
|
938
|
+
Nodes::Casted.new(1, attribute),
|
939
|
+
Nodes::Casted.new(2, attribute),
|
940
|
+
Nodes::Casted.new(3, attribute),
|
941
|
+
]
|
942
|
+
)
|
943
|
+
end
|
944
|
+
|
945
|
+
it "can be constructed with a random object" do
|
946
|
+
attribute = Attribute.new nil, nil
|
947
|
+
random_object = Object.new
|
948
|
+
node = attribute.not_in(random_object)
|
949
|
+
|
950
|
+
_(node).must_equal Nodes::NotIn.new(
|
951
|
+
attribute,
|
952
|
+
Nodes::Casted.new(random_object, attribute)
|
953
|
+
)
|
954
|
+
end
|
955
|
+
|
956
|
+
it "should generate NOT IN in sql" do
|
957
|
+
relation = Table.new(:users)
|
958
|
+
mgr = relation.project relation[:id]
|
959
|
+
mgr.where relation[:id].not_in([1, 2, 3])
|
960
|
+
_(mgr.to_sql).must_be_like %{
|
961
|
+
SELECT "users"."id" FROM "users" WHERE "users"."id" NOT IN (1, 2, 3)
|
962
|
+
}
|
963
|
+
end
|
964
|
+
end
|
965
|
+
|
966
|
+
describe "#not_in_any" do
|
967
|
+
it "should create a Grouping node" do
|
968
|
+
relation = Table.new(:users)
|
969
|
+
_(relation[:id].not_in_any([1, 2])).must_be_kind_of Nodes::Grouping
|
970
|
+
end
|
971
|
+
|
972
|
+
it "should generate ORs in sql" do
|
973
|
+
relation = Table.new(:users)
|
974
|
+
mgr = relation.project relation[:id]
|
975
|
+
mgr.where relation[:id].not_in_any([[1, 2], [3, 4]])
|
976
|
+
_(mgr.to_sql).must_be_like %{
|
977
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" NOT IN (1, 2) OR "users"."id" NOT IN (3, 4))
|
978
|
+
}
|
979
|
+
end
|
980
|
+
end
|
981
|
+
|
982
|
+
describe "#not_in_all" do
|
983
|
+
it "should create a Grouping node" do
|
984
|
+
relation = Table.new(:users)
|
985
|
+
_(relation[:id].not_in_all([1, 2])).must_be_kind_of Nodes::Grouping
|
986
|
+
end
|
987
|
+
|
988
|
+
it "should generate ANDs in sql" do
|
989
|
+
relation = Table.new(:users)
|
990
|
+
mgr = relation.project relation[:id]
|
991
|
+
mgr.where relation[:id].not_in_all([[1, 2], [3, 4]])
|
992
|
+
_(mgr.to_sql).must_be_like %{
|
993
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" NOT IN (1, 2) AND "users"."id" NOT IN (3, 4))
|
994
|
+
}
|
995
|
+
end
|
996
|
+
end
|
997
|
+
|
998
|
+
describe "#eq_all" do
|
999
|
+
it "should create a Grouping node" do
|
1000
|
+
relation = Table.new(:users)
|
1001
|
+
_(relation[:id].eq_all([1, 2])).must_be_kind_of Nodes::Grouping
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
it "should generate ANDs in sql" do
|
1005
|
+
relation = Table.new(:users)
|
1006
|
+
mgr = relation.project relation[:id]
|
1007
|
+
mgr.where relation[:id].eq_all([1, 2])
|
1008
|
+
_(mgr.to_sql).must_be_like %{
|
1009
|
+
SELECT "users"."id" FROM "users" WHERE ("users"."id" = 1 AND "users"."id" = 2)
|
1010
|
+
}
|
1011
|
+
end
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
describe "#asc" do
|
1015
|
+
it "should create an Ascending node" do
|
1016
|
+
relation = Table.new(:users)
|
1017
|
+
_(relation[:id].asc).must_be_kind_of Nodes::Ascending
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
it "should generate ASC in sql" do
|
1021
|
+
relation = Table.new(:users)
|
1022
|
+
mgr = relation.project relation[:id]
|
1023
|
+
mgr.order relation[:id].asc
|
1024
|
+
_(mgr.to_sql).must_be_like %{
|
1025
|
+
SELECT "users"."id" FROM "users" ORDER BY "users"."id" ASC
|
1026
|
+
}
|
1027
|
+
end
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
describe "#desc" do
|
1031
|
+
it "should create a Descending node" do
|
1032
|
+
relation = Table.new(:users)
|
1033
|
+
_(relation[:id].desc).must_be_kind_of Nodes::Descending
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
it "should generate DESC in sql" do
|
1037
|
+
relation = Table.new(:users)
|
1038
|
+
mgr = relation.project relation[:id]
|
1039
|
+
mgr.order relation[:id].desc
|
1040
|
+
_(mgr.to_sql).must_be_like %{
|
1041
|
+
SELECT "users"."id" FROM "users" ORDER BY "users"."id" DESC
|
1042
|
+
}
|
1043
|
+
end
|
1044
|
+
end
|
1045
|
+
|
1046
|
+
describe "#contains" do
|
1047
|
+
it "should create a Contains node" do
|
1048
|
+
relation = Table.new(:products)
|
1049
|
+
_(relation[:tags].contains(["foo", "bar"])).must_be_kind_of Nodes::Contains
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
it "should generate @> in sql" do
|
1053
|
+
relation = Table.new(:products, type_caster: fake_pg_caster)
|
1054
|
+
mgr = relation.project relation[:id]
|
1055
|
+
mgr.where relation[:tags].contains(["foo", "bar"])
|
1056
|
+
_(mgr.to_sql).must_be_like %{ SELECT "products"."id" FROM "products" WHERE "products"."tags" @> '{foo,bar}' }
|
1057
|
+
end
|
1058
|
+
end
|
1059
|
+
|
1060
|
+
describe "#overlaps" do
|
1061
|
+
it "should create an Overlaps node" do
|
1062
|
+
relation = Table.new(:products)
|
1063
|
+
_(relation[:tags].overlaps(["foo", "bar"])).must_be_kind_of Nodes::Overlaps
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
it "should generate && in sql" do
|
1067
|
+
relation = Table.new(:products, type_caster: fake_pg_caster)
|
1068
|
+
mgr = relation.project relation[:id]
|
1069
|
+
mgr.where relation[:tags].overlaps(["foo", "bar"])
|
1070
|
+
_(mgr.to_sql).must_be_like %{ SELECT "products"."id" FROM "products" WHERE "products"."tags" && '{foo,bar}' }
|
1071
|
+
end
|
1072
|
+
end
|
1073
|
+
|
1074
|
+
describe "equality" do
|
1075
|
+
describe "#to_sql" do
|
1076
|
+
it "should produce sql" do
|
1077
|
+
table = Table.new :users
|
1078
|
+
condition = table["id"].eq 1
|
1079
|
+
_(condition.to_sql).must_equal '"users"."id" = 1'
|
1080
|
+
end
|
1081
|
+
end
|
1082
|
+
end
|
1083
|
+
|
1084
|
+
describe "type casting" do
|
1085
|
+
it "does not type cast by default" do
|
1086
|
+
table = Table.new(:foo)
|
1087
|
+
condition = table["id"].eq("1")
|
1088
|
+
|
1089
|
+
assert_not table.able_to_type_cast?
|
1090
|
+
_(condition.to_sql).must_equal %("foo"."id" = '1')
|
1091
|
+
end
|
1092
|
+
|
1093
|
+
it "type casts when given an explicit caster" do
|
1094
|
+
fake_caster = Object.new
|
1095
|
+
def fake_caster.type_cast_for_database(attr_name, value)
|
1096
|
+
if attr_name == "id"
|
1097
|
+
value.to_i
|
1098
|
+
else
|
1099
|
+
value
|
1100
|
+
end
|
1101
|
+
end
|
1102
|
+
table = Table.new(:foo, type_caster: fake_caster)
|
1103
|
+
condition = table["id"].eq("1").and(table["other_id"].eq("2"))
|
1104
|
+
|
1105
|
+
assert table.able_to_type_cast?
|
1106
|
+
_(condition.to_sql).must_equal %("foo"."id" = 1 AND "foo"."other_id" = '2')
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
it "does not type cast SqlLiteral nodes" do
|
1110
|
+
fake_caster = Object.new
|
1111
|
+
def fake_caster.type_cast_for_database(attr_name, value)
|
1112
|
+
value.to_i
|
1113
|
+
end
|
1114
|
+
table = Table.new(:foo, type_caster: fake_caster)
|
1115
|
+
condition = table["id"].eq(Arel.sql("(select 1)"))
|
1116
|
+
|
1117
|
+
assert table.able_to_type_cast?
|
1118
|
+
_(condition.to_sql).must_equal %("foo"."id" = (select 1))
|
1119
|
+
end
|
1120
|
+
end
|
1121
|
+
|
1122
|
+
private
|
1123
|
+
def quoted_range(begin_val, end_val, exclude)
|
1124
|
+
OpenStruct.new(
|
1125
|
+
begin: Nodes::Quoted.new(begin_val),
|
1126
|
+
end: Nodes::Quoted.new(end_val),
|
1127
|
+
exclude_end?: exclude,
|
1128
|
+
)
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
# Mimic PG::TextDecoder::Array casting
|
1132
|
+
def fake_pg_caster
|
1133
|
+
Object.new.tap do |caster|
|
1134
|
+
def caster.type_cast_for_database(attr_name, value)
|
1135
|
+
if attr_name == "tags"
|
1136
|
+
"{#{value.join(",")}}"
|
1137
|
+
else
|
1138
|
+
value
|
1139
|
+
end
|
1140
|
+
end
|
1141
|
+
end
|
1142
|
+
end
|
1143
|
+
end
|
1144
|
+
end
|
1145
|
+
end
|