sequel 4.49.0 → 5.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +130 -0
- data/README.rdoc +195 -136
- data/Rakefile +26 -42
- data/bin/sequel +6 -9
- data/doc/advanced_associations.rdoc +91 -168
- data/doc/association_basics.rdoc +197 -274
- data/doc/bin_sequel.rdoc +5 -3
- data/doc/cheat_sheet.rdoc +66 -43
- data/doc/code_order.rdoc +1 -8
- data/doc/core_extensions.rdoc +81 -56
- data/doc/dataset_basics.rdoc +8 -17
- data/doc/dataset_filtering.rdoc +81 -86
- data/doc/extensions.rdoc +3 -10
- data/doc/mass_assignment.rdoc +73 -30
- data/doc/migration.rdoc +19 -36
- data/doc/model_dataset_method_design.rdoc +14 -17
- data/doc/model_hooks.rdoc +15 -25
- data/doc/model_plugins.rdoc +10 -10
- data/doc/mssql_stored_procedures.rdoc +3 -3
- data/doc/object_model.rdoc +52 -70
- data/doc/opening_databases.rdoc +39 -32
- data/doc/postgresql.rdoc +48 -38
- data/doc/prepared_statements.rdoc +27 -22
- data/doc/querying.rdoc +173 -150
- data/doc/reflection.rdoc +5 -6
- data/doc/release_notes/5.0.0.txt +159 -0
- data/doc/release_notes/5.1.0.txt +31 -0
- data/doc/release_notes/5.2.0.txt +33 -0
- data/doc/release_notes/5.3.0.txt +121 -0
- data/doc/schema_modification.rdoc +78 -64
- data/doc/security.rdoc +97 -88
- data/doc/sharding.rdoc +43 -30
- data/doc/sql.rdoc +53 -65
- data/doc/testing.rdoc +4 -5
- data/doc/thread_safety.rdoc +2 -4
- data/doc/transactions.rdoc +18 -17
- data/doc/validations.rdoc +48 -45
- data/doc/virtual_rows.rdoc +87 -115
- data/lib/sequel/adapters/ado/access.rb +7 -13
- data/lib/sequel/adapters/ado/mssql.rb +2 -9
- data/lib/sequel/adapters/ado.rb +9 -25
- data/lib/sequel/adapters/amalgalite.rb +3 -18
- data/lib/sequel/adapters/ibmdb.rb +9 -45
- data/lib/sequel/adapters/jdbc/db2.rb +8 -37
- data/lib/sequel/adapters/jdbc/derby.rb +4 -50
- data/lib/sequel/adapters/jdbc/h2.rb +6 -26
- data/lib/sequel/adapters/jdbc/hsqldb.rb +2 -27
- data/lib/sequel/adapters/jdbc/jtds.rb +2 -9
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -11
- data/lib/sequel/adapters/jdbc/mysql.rb +11 -15
- data/lib/sequel/adapters/jdbc/oracle.rb +4 -26
- data/lib/sequel/adapters/jdbc/postgresql.rb +23 -33
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +4 -17
- data/lib/sequel/adapters/jdbc/sqlite.rb +1 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -13
- data/lib/sequel/adapters/jdbc/transactions.rb +1 -14
- data/lib/sequel/adapters/jdbc.rb +18 -74
- data/lib/sequel/adapters/mock.rb +4 -30
- data/lib/sequel/adapters/mysql.rb +7 -44
- data/lib/sequel/adapters/mysql2.rb +5 -23
- data/lib/sequel/adapters/odbc/db2.rb +1 -1
- data/lib/sequel/adapters/odbc/mssql.rb +4 -12
- data/lib/sequel/adapters/odbc/oracle.rb +1 -1
- data/lib/sequel/adapters/odbc.rb +0 -19
- data/lib/sequel/adapters/oracle.rb +8 -13
- data/lib/sequel/adapters/postgres.rb +28 -150
- data/lib/sequel/adapters/postgresql.rb +1 -1
- data/lib/sequel/adapters/shared/access.rb +11 -51
- data/lib/sequel/adapters/shared/db2.rb +3 -61
- data/lib/sequel/adapters/shared/mssql.rb +21 -157
- data/lib/sequel/adapters/shared/mysql.rb +61 -227
- data/lib/sequel/adapters/shared/oracle.rb +13 -41
- data/lib/sequel/adapters/shared/postgres.rb +58 -264
- data/lib/sequel/adapters/shared/sqlanywhere.rb +4 -96
- data/lib/sequel/adapters/shared/sqlite.rb +22 -101
- data/lib/sequel/adapters/sqlanywhere.rb +4 -23
- data/lib/sequel/adapters/sqlite.rb +2 -19
- data/lib/sequel/adapters/tinytds.rb +5 -15
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +4 -4
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +3 -6
- data/lib/sequel/adapters/utils/replace.rb +0 -5
- data/lib/sequel/adapters/utils/stored_procedures.rb +0 -2
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +2 -0
- data/lib/sequel/ast_transformer.rb +3 -94
- data/lib/sequel/connection_pool/sharded_single.rb +1 -4
- data/lib/sequel/connection_pool/sharded_threaded.rb +97 -95
- data/lib/sequel/connection_pool/single.rb +0 -2
- data/lib/sequel/connection_pool/threaded.rb +94 -110
- data/lib/sequel/connection_pool.rb +38 -28
- data/lib/sequel/core.rb +42 -101
- data/lib/sequel/database/connecting.rb +23 -60
- data/lib/sequel/database/dataset.rb +6 -9
- data/lib/sequel/database/dataset_defaults.rb +4 -48
- data/lib/sequel/database/features.rb +5 -4
- data/lib/sequel/database/logging.rb +2 -9
- data/lib/sequel/database/misc.rb +36 -55
- data/lib/sequel/database/query.rb +8 -13
- data/lib/sequel/database/schema_generator.rb +93 -64
- data/lib/sequel/database/schema_methods.rb +61 -79
- data/lib/sequel/database/transactions.rb +4 -24
- data/lib/sequel/database.rb +12 -2
- data/lib/sequel/dataset/actions.rb +57 -107
- data/lib/sequel/dataset/dataset_module.rb +4 -16
- data/lib/sequel/dataset/features.rb +35 -30
- data/lib/sequel/dataset/graph.rb +40 -49
- data/lib/sequel/dataset/misc.rb +12 -37
- data/lib/sequel/dataset/placeholder_literalizer.rb +4 -4
- data/lib/sequel/dataset/prepared_statements.rb +23 -51
- data/lib/sequel/dataset/query.rb +91 -161
- data/lib/sequel/dataset/sql.rb +33 -225
- data/lib/sequel/dataset.rb +18 -10
- data/lib/sequel/deprecated.rb +18 -27
- data/lib/sequel/exceptions.rb +1 -17
- data/lib/sequel/extensions/_model_pg_row.rb +0 -7
- data/lib/sequel/extensions/_pretty_table.rb +1 -3
- data/lib/sequel/extensions/arbitrary_servers.rb +10 -10
- data/lib/sequel/extensions/connection_expiration.rb +1 -1
- data/lib/sequel/extensions/connection_validator.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +11 -11
- data/lib/sequel/extensions/core_extensions.rb +39 -49
- data/lib/sequel/extensions/core_refinements.rb +39 -45
- data/lib/sequel/extensions/current_datetime_timestamp.rb +0 -4
- data/lib/sequel/extensions/date_arithmetic.rb +7 -7
- data/lib/sequel/extensions/duplicate_columns_handler.rb +12 -9
- data/lib/sequel/extensions/empty_array_consider_nulls.rb +2 -2
- data/lib/sequel/extensions/eval_inspect.rb +4 -11
- data/lib/sequel/extensions/freeze_datasets.rb +1 -69
- data/lib/sequel/extensions/from_block.rb +1 -35
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/identifier_mangling.rb +9 -19
- data/lib/sequel/extensions/implicit_subquery.rb +2 -2
- data/lib/sequel/extensions/inflector.rb +4 -4
- data/lib/sequel/extensions/migration.rb +27 -43
- data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -84
- data/lib/sequel/extensions/null_dataset.rb +2 -8
- data/lib/sequel/extensions/pagination.rb +1 -17
- data/lib/sequel/extensions/pg_array.rb +20 -189
- data/lib/sequel/extensions/pg_extended_date_support.rb +230 -0
- data/lib/sequel/extensions/pg_hstore.rb +11 -50
- data/lib/sequel/extensions/pg_hstore_ops.rb +2 -2
- data/lib/sequel/extensions/pg_inet.rb +3 -16
- data/lib/sequel/extensions/pg_interval.rb +1 -20
- data/lib/sequel/extensions/pg_json.rb +7 -27
- data/lib/sequel/extensions/pg_loose_count.rb +1 -1
- data/lib/sequel/extensions/pg_range.rb +6 -121
- data/lib/sequel/extensions/pg_range_ops.rb +1 -3
- data/lib/sequel/extensions/pg_row.rb +5 -77
- data/lib/sequel/extensions/pg_row_ops.rb +2 -13
- data/lib/sequel/extensions/query.rb +3 -4
- data/lib/sequel/extensions/round_timestamps.rb +0 -6
- data/lib/sequel/extensions/schema_dumper.rb +13 -13
- data/lib/sequel/extensions/select_remove.rb +3 -3
- data/lib/sequel/extensions/split_array_nil.rb +2 -2
- data/lib/sequel/extensions/sql_comments.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +11 -8
- data/lib/sequel/extensions/symbol_aref.rb +6 -20
- data/lib/sequel/extensions/synchronize_sql.rb +45 -0
- data/lib/sequel/model/associations.rb +129 -131
- data/lib/sequel/model/base.rb +133 -731
- data/lib/sequel/model/default_inflections.rb +1 -1
- data/lib/sequel/model/errors.rb +0 -3
- data/lib/sequel/model/exceptions.rb +2 -6
- data/lib/sequel/model/inflections.rb +1 -26
- data/lib/sequel/model/plugins.rb +1 -0
- data/lib/sequel/model.rb +27 -62
- data/lib/sequel/plugins/active_model.rb +2 -5
- data/lib/sequel/plugins/association_dependencies.rb +15 -15
- data/lib/sequel/plugins/association_pks.rb +14 -28
- data/lib/sequel/plugins/association_proxies.rb +6 -7
- data/lib/sequel/plugins/auto_validations.rb +4 -4
- data/lib/sequel/plugins/before_after_save.rb +0 -43
- data/lib/sequel/plugins/blacklist_security.rb +9 -8
- data/lib/sequel/plugins/boolean_readers.rb +3 -3
- data/lib/sequel/plugins/boolean_subsets.rb +2 -2
- data/lib/sequel/plugins/caching.rb +5 -5
- data/lib/sequel/plugins/class_table_inheritance.rb +71 -102
- data/lib/sequel/plugins/column_conflicts.rb +2 -2
- data/lib/sequel/plugins/column_select.rb +2 -2
- data/lib/sequel/plugins/composition.rb +15 -24
- data/lib/sequel/plugins/constraint_validations.rb +4 -3
- data/lib/sequel/plugins/csv_serializer.rb +13 -20
- data/lib/sequel/plugins/dataset_associations.rb +2 -2
- data/lib/sequel/plugins/def_dataset_method.rb +5 -5
- data/lib/sequel/plugins/defaults_setter.rb +1 -1
- data/lib/sequel/plugins/delay_add_association.rb +1 -1
- data/lib/sequel/plugins/finder.rb +16 -10
- data/lib/sequel/plugins/force_encoding.rb +1 -7
- data/lib/sequel/plugins/hook_class_methods.rb +4 -106
- data/lib/sequel/plugins/input_transformer.rb +10 -11
- data/lib/sequel/plugins/insert_returning_select.rb +1 -9
- data/lib/sequel/plugins/instance_filters.rb +5 -5
- data/lib/sequel/plugins/instance_hooks.rb +7 -52
- data/lib/sequel/plugins/inverted_subsets.rb +3 -1
- data/lib/sequel/plugins/json_serializer.rb +19 -19
- data/lib/sequel/plugins/lazy_attributes.rb +1 -10
- data/lib/sequel/plugins/list.rb +6 -6
- data/lib/sequel/plugins/many_through_many.rb +11 -8
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +3 -3
- data/lib/sequel/plugins/nested_attributes.rb +18 -31
- data/lib/sequel/plugins/optimistic_locking.rb +3 -3
- data/lib/sequel/plugins/pg_array_associations.rb +8 -2
- data/lib/sequel/plugins/pg_row.rb +2 -11
- data/lib/sequel/plugins/prepared_statements.rb +13 -66
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +7 -7
- data/lib/sequel/plugins/serialization.rb +15 -33
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +2 -8
- data/lib/sequel/plugins/single_table_inheritance.rb +10 -13
- data/lib/sequel/plugins/skip_create_refresh.rb +3 -3
- data/lib/sequel/plugins/static_cache.rb +8 -9
- data/lib/sequel/plugins/string_stripper.rb +3 -3
- data/lib/sequel/plugins/subclasses.rb +1 -1
- data/lib/sequel/plugins/subset_conditions.rb +2 -2
- data/lib/sequel/plugins/table_select.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
- data/lib/sequel/plugins/timestamps.rb +6 -7
- data/lib/sequel/plugins/touch.rb +4 -8
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +2 -2
- data/lib/sequel/plugins/unlimited_update.rb +1 -7
- data/lib/sequel/plugins/update_or_create.rb +3 -3
- data/lib/sequel/plugins/update_refresh.rb +3 -3
- data/lib/sequel/plugins/uuid.rb +7 -11
- data/lib/sequel/plugins/validation_class_methods.rb +10 -9
- data/lib/sequel/plugins/validation_contexts.rb +4 -4
- data/lib/sequel/plugins/validation_helpers.rb +26 -25
- data/lib/sequel/plugins/whitelist_security.rb +13 -9
- data/lib/sequel/plugins/xml_serializer.rb +24 -25
- data/lib/sequel/sql.rb +145 -276
- data/lib/sequel/timezones.rb +8 -23
- data/lib/sequel/version.rb +2 -2
- data/lib/sequel.rb +1 -1
- data/spec/adapter_spec.rb +1 -1
- data/spec/adapters/db2_spec.rb +2 -103
- data/spec/adapters/mssql_spec.rb +89 -68
- data/spec/adapters/mysql_spec.rb +111 -478
- data/spec/adapters/oracle_spec.rb +1 -9
- data/spec/adapters/postgres_spec.rb +459 -664
- data/spec/adapters/spec_helper.rb +12 -31
- data/spec/adapters/sqlanywhere_spec.rb +2 -77
- data/spec/adapters/sqlite_spec.rb +8 -146
- data/spec/bin_spec.rb +11 -16
- data/spec/core/connection_pool_spec.rb +173 -74
- data/spec/core/database_spec.rb +96 -244
- data/spec/core/dataset_spec.rb +99 -414
- data/spec/core/deprecated_spec.rb +3 -3
- data/spec/core/expression_filters_spec.rb +37 -144
- data/spec/core/mock_adapter_spec.rb +241 -4
- data/spec/core/object_graph_spec.rb +11 -60
- data/spec/core/placeholder_literalizer_spec.rb +1 -14
- data/spec/core/schema_generator_spec.rb +51 -40
- data/spec/core/schema_spec.rb +88 -77
- data/spec/core/spec_helper.rb +6 -24
- data/spec/core/version_spec.rb +1 -1
- data/spec/core_extensions_spec.rb +7 -83
- data/spec/core_model_spec.rb +2 -2
- data/spec/deprecation_helper.rb +2 -14
- data/spec/extensions/accessed_columns_spec.rb +1 -1
- data/spec/extensions/active_model_spec.rb +3 -3
- data/spec/extensions/after_initialize_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +2 -2
- data/spec/extensions/association_dependencies_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +30 -92
- data/spec/extensions/association_proxies_spec.rb +1 -1
- data/spec/extensions/auto_literal_strings_spec.rb +1 -12
- data/spec/extensions/auto_validations_spec.rb +1 -1
- data/spec/extensions/blacklist_security_spec.rb +1 -1
- data/spec/extensions/blank_spec.rb +1 -1
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/caching_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +53 -1118
- data/spec/extensions/column_conflicts_spec.rb +1 -1
- data/spec/extensions/column_select_spec.rb +4 -4
- data/spec/extensions/columns_introspection_spec.rb +1 -1
- data/spec/extensions/columns_updated_spec.rb +1 -1
- data/spec/extensions/composition_spec.rb +8 -30
- data/spec/extensions/connection_expiration_spec.rb +3 -3
- data/spec/extensions/connection_validator_spec.rb +3 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +1 -1
- data/spec/extensions/constraint_validations_spec.rb +1 -1
- data/spec/extensions/core_refinements_spec.rb +1 -3
- data/spec/extensions/csv_serializer_spec.rb +4 -9
- data/spec/extensions/current_datetime_timestamp_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +2 -1
- data/spec/extensions/dataset_source_alias_spec.rb +1 -1
- data/spec/extensions/date_arithmetic_spec.rb +3 -3
- data/spec/extensions/def_dataset_method_spec.rb +1 -1
- data/spec/extensions/defaults_setter_spec.rb +2 -2
- data/spec/extensions/delay_add_association_spec.rb +8 -9
- data/spec/extensions/dirty_spec.rb +1 -1
- data/spec/extensions/duplicate_columns_handler_spec.rb +1 -1
- data/spec/extensions/eager_each_spec.rb +2 -2
- data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
- data/spec/extensions/error_splitter_spec.rb +1 -1
- data/spec/extensions/error_sql_spec.rb +1 -1
- data/spec/extensions/eval_inspect_spec.rb +1 -1
- data/spec/extensions/finder_spec.rb +1 -1
- data/spec/extensions/force_encoding_spec.rb +2 -5
- data/spec/extensions/freeze_datasets_spec.rb +1 -1
- data/spec/extensions/graph_each_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +1 -194
- data/spec/extensions/identifier_mangling_spec.rb +17 -170
- data/spec/extensions/implicit_subquery_spec.rb +1 -5
- data/spec/extensions/inflector_spec.rb +1 -1
- data/spec/extensions/input_transformer_spec.rb +7 -2
- data/spec/extensions/insert_returning_select_spec.rb +1 -1
- data/spec/extensions/instance_filters_spec.rb +1 -1
- data/spec/extensions/instance_hooks_spec.rb +1 -95
- data/spec/extensions/inverted_subsets_spec.rb +1 -1
- data/spec/extensions/json_serializer_spec.rb +1 -1
- data/spec/extensions/lazy_attributes_spec.rb +1 -7
- data/spec/extensions/list_spec.rb +5 -6
- data/spec/extensions/looser_typecasting_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +25 -33
- data/spec/extensions/migration_spec.rb +12 -2
- data/spec/extensions/modification_detection_spec.rb +1 -1
- data/spec/extensions/mssql_optimistic_locking_spec.rb +1 -1
- data/spec/extensions/named_timezones_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +1 -29
- data/spec/extensions/null_dataset_spec.rb +1 -11
- data/spec/extensions/optimistic_locking_spec.rb +2 -2
- data/spec/extensions/pagination_spec.rb +1 -1
- data/spec/extensions/pg_array_associations_spec.rb +22 -26
- data/spec/extensions/pg_array_ops_spec.rb +1 -1
- data/spec/extensions/pg_array_spec.rb +3 -48
- data/spec/extensions/pg_enum_spec.rb +1 -1
- data/spec/extensions/pg_extended_date_support_spec.rb +122 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +1 -1
- data/spec/extensions/pg_hstore_spec.rb +22 -31
- data/spec/extensions/pg_inet_ops_spec.rb +1 -1
- data/spec/extensions/pg_inet_spec.rb +1 -14
- data/spec/extensions/pg_interval_spec.rb +3 -13
- data/spec/extensions/pg_json_ops_spec.rb +1 -1
- data/spec/extensions/pg_json_spec.rb +1 -13
- data/spec/extensions/pg_loose_count_spec.rb +1 -1
- data/spec/extensions/pg_range_ops_spec.rb +1 -1
- data/spec/extensions/pg_range_spec.rb +3 -88
- data/spec/extensions/pg_row_ops_spec.rb +1 -1
- data/spec/extensions/pg_row_plugin_spec.rb +1 -1
- data/spec/extensions/pg_row_spec.rb +1 -44
- data/spec/extensions/pg_static_cache_updater_spec.rb +1 -1
- data/spec/extensions/prepared_statements_safe_spec.rb +7 -7
- data/spec/extensions/prepared_statements_spec.rb +13 -48
- data/spec/extensions/pretty_table_spec.rb +40 -9
- data/spec/extensions/query_spec.rb +1 -12
- data/spec/extensions/rcte_tree_spec.rb +23 -34
- data/spec/extensions/round_timestamps_spec.rb +1 -5
- data/spec/extensions/s_spec.rb +1 -1
- data/spec/extensions/schema_caching_spec.rb +1 -1
- data/spec/extensions/schema_dumper_spec.rb +43 -32
- data/spec/extensions/select_remove_spec.rb +1 -1
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +1 -1
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
- data/spec/extensions/serialization_spec.rb +5 -17
- data/spec/extensions/server_block_spec.rb +1 -1
- data/spec/extensions/server_logging_spec.rb +2 -2
- data/spec/extensions/sharding_spec.rb +1 -1
- data/spec/extensions/shared_caching_spec.rb +1 -28
- data/spec/extensions/single_table_inheritance_spec.rb +2 -5
- data/spec/extensions/singular_table_names_spec.rb +1 -1
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +5 -27
- data/spec/extensions/split_array_nil_spec.rb +1 -1
- data/spec/extensions/split_values_spec.rb +1 -1
- data/spec/extensions/sql_comments_spec.rb +1 -1
- data/spec/extensions/sql_expr_spec.rb +1 -1
- data/spec/extensions/static_cache_spec.rb +1 -1
- data/spec/extensions/string_agg_spec.rb +2 -2
- data/spec/extensions/string_date_time_spec.rb +1 -1
- data/spec/extensions/string_stripper_spec.rb +1 -1
- data/spec/extensions/subclasses_spec.rb +1 -1
- data/spec/extensions/subset_conditions_spec.rb +1 -1
- data/spec/extensions/symbol_aref_refinement_spec.rb +1 -1
- data/spec/extensions/symbol_as_refinement_spec.rb +1 -1
- data/spec/extensions/synchronize_sql_spec.rb +124 -0
- data/spec/extensions/table_select_spec.rb +4 -4
- data/spec/extensions/tactical_eager_loading_spec.rb +1 -6
- data/spec/extensions/thread_local_timezones_spec.rb +1 -1
- data/spec/extensions/timestamps_spec.rb +5 -7
- data/spec/extensions/to_dot_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +1 -1
- data/spec/extensions/tree_spec.rb +1 -1
- data/spec/extensions/typecast_on_load_spec.rb +1 -1
- data/spec/extensions/unlimited_update_spec.rb +1 -1
- data/spec/extensions/update_or_create_spec.rb +12 -16
- data/spec/extensions/update_primary_key_spec.rb +4 -3
- data/spec/extensions/update_refresh_spec.rb +1 -1
- data/spec/extensions/uuid_spec.rb +10 -13
- data/spec/extensions/validate_associated_spec.rb +1 -1
- data/spec/extensions/validation_class_methods_spec.rb +3 -3
- data/spec/extensions/validation_contexts_spec.rb +1 -1
- data/spec/extensions/validation_helpers_spec.rb +10 -44
- data/spec/extensions/whitelist_security_spec.rb +5 -5
- data/spec/extensions/xml_serializer_spec.rb +8 -13
- data/spec/guards_helper.rb +2 -1
- data/spec/integration/associations_test.rb +1 -23
- data/spec/integration/database_test.rb +7 -7
- data/spec/integration/dataset_test.rb +12 -47
- data/spec/integration/eager_loader_test.rb +1 -1
- data/spec/integration/migrator_test.rb +1 -1
- data/spec/integration/model_test.rb +4 -82
- data/spec/integration/plugin_test.rb +7 -23
- data/spec/integration/prepared_statement_test.rb +8 -88
- data/spec/integration/schema_test.rb +10 -10
- data/spec/integration/spec_helper.rb +17 -21
- data/spec/integration/timezone_test.rb +5 -5
- data/spec/integration/transaction_test.rb +3 -55
- data/spec/integration/type_test.rb +9 -9
- data/spec/model/association_reflection_spec.rb +24 -9
- data/spec/model/associations_spec.rb +124 -303
- data/spec/model/base_spec.rb +43 -137
- data/spec/model/class_dataset_methods_spec.rb +2 -20
- data/spec/model/dataset_methods_spec.rb +1 -20
- data/spec/model/eager_loading_spec.rb +48 -17
- data/spec/model/hooks_spec.rb +5 -300
- data/spec/model/inflector_spec.rb +1 -1
- data/spec/model/model_spec.rb +29 -339
- data/spec/model/plugins_spec.rb +2 -16
- data/spec/model/record_spec.rb +33 -129
- data/spec/model/spec_helper.rb +5 -15
- data/spec/model/validations_spec.rb +1 -1
- data/spec/sequel_warning.rb +1 -12
- metadata +19 -65
- data/doc/active_record.rdoc +0 -927
- data/lib/sequel/adapters/cubrid.rb +0 -160
- data/lib/sequel/adapters/do/mysql.rb +0 -69
- data/lib/sequel/adapters/do/postgres.rb +0 -46
- data/lib/sequel/adapters/do/sqlite3.rb +0 -41
- data/lib/sequel/adapters/do.rb +0 -166
- data/lib/sequel/adapters/jdbc/as400.rb +0 -92
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -65
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -37
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -34
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -34
- data/lib/sequel/adapters/odbc/progress.rb +0 -12
- data/lib/sequel/adapters/shared/cubrid.rb +0 -245
- data/lib/sequel/adapters/shared/firebird.rb +0 -261
- data/lib/sequel/adapters/shared/informix.rb +0 -63
- data/lib/sequel/adapters/shared/progress.rb +0 -40
- data/lib/sequel/adapters/swift/mysql.rb +0 -50
- data/lib/sequel/adapters/swift/postgres.rb +0 -49
- data/lib/sequel/adapters/swift/sqlite.rb +0 -48
- data/lib/sequel/adapters/swift.rb +0 -169
- data/lib/sequel/adapters/utils/pg_types.rb +0 -4
- data/lib/sequel/dataset/mutation.rb +0 -98
- data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +0 -117
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -8
- data/lib/sequel/extensions/filter_having.rb +0 -65
- data/lib/sequel/extensions/hash_aliases.rb +0 -51
- data/lib/sequel/extensions/meta_def.rb +0 -37
- data/lib/sequel/extensions/query_literals.rb +0 -86
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -26
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -133
- data/lib/sequel/extensions/set_overrides.rb +0 -82
- data/lib/sequel/no_core_ext.rb +0 -4
- data/lib/sequel/plugins/association_autoreloading.rb +0 -11
- data/lib/sequel/plugins/identifier_columns.rb +0 -49
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -11
- data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -90
- data/lib/sequel/plugins/prepared_statements_associations.rb +0 -137
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -71
- data/lib/sequel/plugins/schema.rb +0 -84
- data/lib/sequel/plugins/scissors.rb +0 -37
- data/spec/core/dataset_mutation_spec.rb +0 -253
- data/spec/extensions/_deprecated_identifier_mangling_spec.rb +0 -314
- data/spec/extensions/before_after_save_spec.rb +0 -40
- data/spec/extensions/filter_having_spec.rb +0 -42
- data/spec/extensions/from_block_spec.rb +0 -21
- data/spec/extensions/hash_aliases_spec.rb +0 -26
- data/spec/extensions/identifier_columns_spec.rb +0 -19
- data/spec/extensions/meta_def_spec.rb +0 -35
- data/spec/extensions/no_auto_literal_strings_spec.rb +0 -69
- data/spec/extensions/pg_typecast_on_load_spec.rb +0 -70
- data/spec/extensions/prepared_statements_associations_spec.rb +0 -212
- data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -40
- data/spec/extensions/query_literals_spec.rb +0 -185
- data/spec/extensions/schema_spec.rb +0 -123
- data/spec/extensions/scissors_spec.rb +0 -27
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -118
- data/spec/extensions/set_overrides_spec.rb +0 -75
@@ -1,31 +1,21 @@
|
|
1
1
|
SEQUEL_ADAPTER_TEST = :postgres
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'spec_helper'
|
4
4
|
|
5
5
|
uses_pg = Sequel::Postgres::USES_PG if DB.adapter_scheme == :postgres
|
6
6
|
uses_pg_or_jdbc = uses_pg || DB.adapter_scheme == :jdbc
|
7
|
-
# SEQUEL5: Remove native handling
|
8
7
|
|
9
|
-
|
10
|
-
(@sqls ||= [])
|
11
|
-
end
|
12
|
-
logger = Object.new
|
13
|
-
def logger.method_missing(m, msg)
|
14
|
-
DB.sqls << msg
|
15
|
-
end
|
16
|
-
DB.loggers << logger
|
17
|
-
|
18
|
-
DB.extension :pg_array, :pg_hstore, :pg_range, :pg_row, :pg_inet, :pg_json, :pg_enum
|
8
|
+
DB.extension :pg_array, :pg_range, :pg_row, :pg_inet, :pg_json, :pg_enum
|
19
9
|
begin
|
20
10
|
DB.extension :pg_interval
|
21
11
|
rescue LoadError
|
22
12
|
end
|
13
|
+
DB.extension :pg_hstore if DB.type_supported?('hstore')
|
23
14
|
|
24
15
|
describe "PostgreSQL", '#create_table' do
|
25
16
|
before do
|
26
17
|
@db = DB
|
27
18
|
@db.test_connection
|
28
|
-
DB.sqls.clear
|
29
19
|
end
|
30
20
|
after do
|
31
21
|
@db.drop_table?(:tmp_dolls, :unlogged_dolls)
|
@@ -33,9 +23,9 @@ describe "PostgreSQL", '#create_table' do
|
|
33
23
|
|
34
24
|
it "should create a temporary table" do
|
35
25
|
@db.create_table(:tmp_dolls, :temp => true){text :name}
|
36
|
-
|
37
|
-
|
38
|
-
|
26
|
+
@db.table_exists?(:tmp_dolls).must_equal true
|
27
|
+
@db.disconnect
|
28
|
+
@db.table_exists?(:tmp_dolls).must_equal false
|
39
29
|
end
|
40
30
|
|
41
31
|
it "temporary table should support :on_commit option" do
|
@@ -80,9 +70,6 @@ describe "PostgreSQL", '#create_table' do
|
|
80
70
|
|
81
71
|
it "should create an unlogged table" do
|
82
72
|
@db.create_table(:unlogged_dolls, :unlogged => true){text :name}
|
83
|
-
check_sqls do
|
84
|
-
@db.sqls.must_equal ['CREATE UNLOGGED TABLE "unlogged_dolls" ("name" text)']
|
85
|
-
end
|
86
73
|
end
|
87
74
|
|
88
75
|
it "should create a table inheriting from another table" do
|
@@ -238,14 +225,6 @@ describe "PostgreSQL", 'INSERT ON CONFLICT' do
|
|
238
225
|
@ds.insert_conflict(:constraint=>:ic_test_a_uidx, :update=>{:b=>6}, :update_where=>{Sequel[:ic_test][:b]=>4}).insert(1, 3, 4).must_be_nil
|
239
226
|
@ds.all.must_equal [{:a=>1, :b=>5, :c=>5, :c_is_unique=>false}]
|
240
227
|
end
|
241
|
-
|
242
|
-
it "Dataset#insert_conflict should respect expressions in the target argument" do
|
243
|
-
@ds.insert_conflict(:target=>:a).insert_sql(1, 2, 3).must_equal "INSERT INTO \"ic_test\" VALUES (1, 2, 3) ON CONFLICT (\"a\") DO NOTHING"
|
244
|
-
@ds.insert_conflict(:target=>:c, :conflict_where=>{:c_is_unique=>true}).insert_sql(1, 2, 3).must_equal "INSERT INTO \"ic_test\" VALUES (1, 2, 3) ON CONFLICT (\"c\") WHERE (\"c_is_unique\" IS TRUE) DO NOTHING"
|
245
|
-
@ds.insert_conflict(:target=>[:b, :c]).insert_sql(1, 2, 3).must_equal "INSERT INTO \"ic_test\" VALUES (1, 2, 3) ON CONFLICT (\"b\", \"c\") DO NOTHING"
|
246
|
-
@ds.insert_conflict(:target=>[:b, Sequel.function(:round, :c)]).insert_sql(1, 2, 3).must_equal "INSERT INTO \"ic_test\" VALUES (1, 2, 3) ON CONFLICT (\"b\", round(\"c\")) DO NOTHING"
|
247
|
-
@ds.insert_conflict(:target=>[:b, Sequel.virtual_row{|o| o.round(:c)}]).insert_sql(1, 2, 3).must_equal "INSERT INTO \"ic_test\" VALUES (1, 2, 3) ON CONFLICT (\"b\", round(\"c\")) DO NOTHING"
|
248
|
-
end
|
249
228
|
end if DB.server_version >= 90500
|
250
229
|
|
251
230
|
describe "A PostgreSQL database" do
|
@@ -340,7 +319,7 @@ describe "A PostgreSQL database" do
|
|
340
319
|
@db.get(Sequel.cast('10 20', :int2vector)).wont_equal 10
|
341
320
|
end
|
342
321
|
|
343
|
-
|
322
|
+
it "should not typecast the money type incorrectly" do
|
344
323
|
@db.get(Sequel.cast('10.01', :money)).wont_equal 0
|
345
324
|
end
|
346
325
|
|
@@ -368,13 +347,6 @@ describe "A PostgreSQL database" do
|
|
368
347
|
Sequel.connect(DB.opts.merge(:notice_receiver=>proc{|r| a = r.result_error_message})){|db| db.do("BEGIN\nRAISE WARNING 'foo';\nEND;")}
|
369
348
|
a.must_equal "WARNING: foo\n"
|
370
349
|
end if uses_pg && DB.server_version >= 90000
|
371
|
-
|
372
|
-
# These only test the SQL created, because a true test using file_fdw or postgres_fdw
|
373
|
-
# requires superuser permissions, and you should not be running the tests as a superuser.
|
374
|
-
it "should support creating and dropping foreign tables" do
|
375
|
-
DB.send(:create_table_sql, :t, DB.create_table_generator{Integer :a}, :foreign=>:f, :options=>{:o=>1}).must_equal 'CREATE FOREIGN TABLE "t" ("a" integer) SERVER "f" OPTIONS (o \'1\')'
|
376
|
-
DB.send(:drop_table_sql, :t, :foreign=>true).must_equal 'DROP FOREIGN TABLE "t"'
|
377
|
-
end
|
378
350
|
end
|
379
351
|
|
380
352
|
describe "A PostgreSQL database with domain types" do
|
@@ -407,7 +379,6 @@ describe "A PostgreSQL dataset" do
|
|
407
379
|
end
|
408
380
|
before do
|
409
381
|
@d.delete
|
410
|
-
@db.sqls.clear
|
411
382
|
end
|
412
383
|
after do
|
413
384
|
@db.drop_table?(:atest)
|
@@ -416,35 +387,6 @@ describe "A PostgreSQL dataset" do
|
|
416
387
|
@db.drop_table?(:test)
|
417
388
|
end
|
418
389
|
|
419
|
-
it "should quote columns and tables using double quotes if quoting identifiers" do
|
420
|
-
check_sqls do
|
421
|
-
@d.select(:name).sql.must_equal 'SELECT "name" FROM "test"'
|
422
|
-
@d.select(Sequel.lit('COUNT(*)')).sql.must_equal 'SELECT COUNT(*) FROM "test"'
|
423
|
-
@d.select(Sequel.function(:max, :value)).sql.must_equal 'SELECT max("value") FROM "test"'
|
424
|
-
@d.select(Sequel.function(:NOW)).sql.must_equal 'SELECT NOW() FROM "test"'
|
425
|
-
@d.select(Sequel.function(:max, Sequel[:items][:value])).sql.must_equal 'SELECT max("items"."value") FROM "test"'
|
426
|
-
@d.order(Sequel.desc(:name)).sql.must_equal 'SELECT * FROM "test" ORDER BY "name" DESC'
|
427
|
-
@d.select(Sequel.lit('test.name AS item_name')).sql.must_equal 'SELECT test.name AS item_name FROM "test"'
|
428
|
-
@d.select(Sequel.lit('"name"')).sql.must_equal 'SELECT "name" FROM "test"'
|
429
|
-
@d.select(Sequel.lit('max(test."name") AS "max_name"')).sql.must_equal 'SELECT max(test."name") AS "max_name" FROM "test"'
|
430
|
-
@d.insert_sql(:x => :y).must_match(/\AINSERT INTO "test" \("x"\) VALUES \("y"\)( RETURNING NULL)?\z/)
|
431
|
-
|
432
|
-
@d.select(Sequel.function(:test, :abc, 'hello')).sql.must_equal "SELECT test(\"abc\", 'hello') FROM \"test\""
|
433
|
-
@d.select(Sequel.function(:test, Sequel[:abc][:def], 'hello')).sql.must_equal "SELECT test(\"abc\".\"def\", 'hello') FROM \"test\""
|
434
|
-
@d.select(Sequel.function(:test, Sequel[:abc][:def], 'hello').as(:x2)).sql.must_equal "SELECT test(\"abc\".\"def\", 'hello') AS \"x2\" FROM \"test\""
|
435
|
-
@d.insert_sql(:value => 333).must_match(/\AINSERT INTO "test" \("value"\) VALUES \(333\)( RETURNING NULL)?\z/)
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
|
-
it "should quote fields correctly when reversing the order if quoting identifiers" do
|
440
|
-
check_sqls do
|
441
|
-
@d.reverse_order(:name).sql.must_equal 'SELECT * FROM "test" ORDER BY "name" DESC'
|
442
|
-
@d.reverse_order(Sequel.desc(:name)).sql.must_equal 'SELECT * FROM "test" ORDER BY "name" ASC'
|
443
|
-
@d.reverse_order(:name, Sequel.desc(:test)).sql.must_equal 'SELECT * FROM "test" ORDER BY "name" DESC, "test" ASC'
|
444
|
-
@d.reverse_order(Sequel.desc(:name), :test).sql.must_equal 'SELECT * FROM "test" ORDER BY "name" ASC, "test" DESC'
|
445
|
-
end
|
446
|
-
end
|
447
|
-
|
448
390
|
it "should support regexps" do
|
449
391
|
@d.insert(:name => 'abc', :value => 1)
|
450
392
|
@d.insert(:name => 'bcd', :value => 2)
|
@@ -591,27 +533,13 @@ describe "A PostgreSQL dataset" do
|
|
591
533
|
@db.transaction(:synchronous=>true){}
|
592
534
|
@db.transaction(:synchronous=>:off){}
|
593
535
|
@db.transaction(:synchronous=>false){}
|
594
|
-
@db.sqls.grep(/synchronous/).must_equal ["SET LOCAL synchronous_commit = on", "SET LOCAL synchronous_commit = on", "SET LOCAL synchronous_commit = off", "SET LOCAL synchronous_commit = off"]
|
595
536
|
|
596
|
-
@db.sqls.clear
|
597
537
|
@db.transaction(:synchronous=>nil){}
|
598
|
-
check_sqls do
|
599
|
-
@db.sqls.must_equal ['BEGIN', 'COMMIT']
|
600
|
-
end
|
601
|
-
|
602
538
|
if @db.server_version >= 90100
|
603
|
-
@db.sqls.clear
|
604
539
|
@db.transaction(:synchronous=>:local){}
|
605
|
-
check_sqls do
|
606
|
-
@db.sqls.grep(/synchronous/).must_equal ["SET LOCAL synchronous_commit = local"]
|
607
|
-
end
|
608
540
|
|
609
541
|
if @db.server_version >= 90200
|
610
|
-
@db.sqls.clear
|
611
542
|
@db.transaction(:synchronous=>:remote_write){}
|
612
|
-
check_sqls do
|
613
|
-
@db.sqls.grep(/synchronous/).must_equal ["SET LOCAL synchronous_commit = remote_write"]
|
614
|
-
end
|
615
543
|
end
|
616
544
|
end
|
617
545
|
end
|
@@ -621,7 +549,6 @@ describe "A PostgreSQL dataset" do
|
|
621
549
|
@db.transaction(:read_only=>false){}
|
622
550
|
@db.transaction(:isolation=>:serializable, :read_only=>true){}
|
623
551
|
@db.transaction(:isolation=>:serializable, :read_only=>false){}
|
624
|
-
@db.sqls.grep(/READ/).must_equal ["SET TRANSACTION READ ONLY", "SET TRANSACTION READ WRITE", "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY", "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE READ WRITE"]
|
625
552
|
end
|
626
553
|
|
627
554
|
it "should have #transaction support deferrable transactions" do
|
@@ -631,43 +558,38 @@ describe "A PostgreSQL dataset" do
|
|
631
558
|
@db.transaction(:deferrable=>false, :read_only=>false){}
|
632
559
|
@db.transaction(:isolation=>:serializable, :deferrable=>true, :read_only=>true){}
|
633
560
|
@db.transaction(:isolation=>:serializable, :deferrable=>false, :read_only=>false){}
|
634
|
-
@db.sqls.grep(/DEF/).must_equal ["SET TRANSACTION DEFERRABLE", "SET TRANSACTION NOT DEFERRABLE", "SET TRANSACTION READ ONLY DEFERRABLE", "SET TRANSACTION READ WRITE NOT DEFERRABLE", "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY DEFERRABLE", "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE READ WRITE NOT DEFERRABLE"]
|
635
561
|
end if DB.server_version >= 90100
|
636
562
|
|
637
563
|
it "should support creating indexes concurrently" do
|
638
564
|
@db.add_index :test, [:name, :value], :concurrently=>true
|
639
|
-
check_sqls do
|
640
|
-
@db.sqls.must_equal ['CREATE INDEX CONCURRENTLY "test_name_value_index" ON "test" ("name", "value")']
|
641
|
-
end
|
642
565
|
end
|
643
566
|
|
644
567
|
it "should support dropping indexes only if they already exist" do
|
568
|
+
proc{@db.drop_index :test, [:name, :value], :name=>'tnv1'}.must_raise Sequel::DatabaseError
|
569
|
+
@db.drop_index :test, [:name, :value], :if_exists=>true, :name=>'tnv1'
|
645
570
|
@db.add_index :test, [:name, :value], :name=>'tnv1'
|
646
|
-
@db.sqls.clear
|
647
571
|
@db.drop_index :test, [:name, :value], :if_exists=>true, :name=>'tnv1'
|
648
|
-
check_sqls do
|
649
|
-
@db.sqls.must_equal ['DROP INDEX IF EXISTS "tnv1"']
|
650
|
-
end
|
651
572
|
end
|
652
573
|
|
653
574
|
it "should support CASCADE when dropping indexes" do
|
654
|
-
@db.add_index :test, [:name, :value], :name=>'tnv2'
|
655
|
-
@db.
|
575
|
+
@db.add_index :test, [:name, :value], :name=>'tnv2', :unique=>true
|
576
|
+
@db.create_table(:atest){text :name; integer :value; foreign_key [:name, :value], :test, :key=>[:name, :value]}
|
577
|
+
@db.foreign_key_list(:atest).length.must_equal 1
|
656
578
|
@db.drop_index :test, [:name, :value], :cascade=>true, :name=>'tnv2'
|
657
|
-
|
658
|
-
@db.sqls.must_equal ['DROP INDEX "tnv2" CASCADE']
|
659
|
-
end
|
579
|
+
@db.foreign_key_list(:atest).length.must_equal 0
|
660
580
|
end
|
661
581
|
|
662
582
|
it "should support dropping indexes concurrently" do
|
663
583
|
@db.add_index :test, [:name, :value], :name=>'tnv2'
|
664
|
-
@db.sqls.clear
|
665
584
|
@db.drop_index :test, [:name, :value], :concurrently=>true, :name=>'tnv2'
|
666
|
-
check_sqls do
|
667
|
-
@db.sqls.must_equal ['DROP INDEX CONCURRENTLY "tnv2"']
|
668
|
-
end
|
669
585
|
end if DB.server_version >= 90200
|
670
586
|
|
587
|
+
it "should support creating indexes only if they do not exist" do
|
588
|
+
@db.add_index :test, [:name, :value], :name=>'tnv3'
|
589
|
+
proc{@db.add_index :test, [:name, :value], :name=>'tnv3'}.must_raise Sequel::DatabaseError
|
590
|
+
@db.add_index :test, [:name, :value], :if_not_exists=>true, :name=>'tnv3'
|
591
|
+
end if DB.server_version >= 90500
|
592
|
+
|
671
593
|
it "#lock should lock table if inside a transaction" do
|
672
594
|
@db.transaction{@d.lock('EXCLUSIVE'); @d.insert(:name=>'a')}
|
673
595
|
end
|
@@ -790,18 +712,19 @@ describe "A PostgreSQL dataset with a timestamp field" do
|
|
790
712
|
DateTime :time
|
791
713
|
end
|
792
714
|
@d = @db[:test3]
|
715
|
+
@db.extension :pg_extended_date_support
|
793
716
|
end
|
794
717
|
before do
|
795
718
|
@d.delete
|
796
719
|
end
|
797
720
|
after do
|
798
|
-
@db.convert_infinite_timestamps = false
|
721
|
+
@db.convert_infinite_timestamps = false
|
799
722
|
end
|
800
723
|
after(:all) do
|
801
724
|
@db.drop_table?(:test3)
|
802
725
|
end
|
803
726
|
|
804
|
-
|
727
|
+
it "should store milliseconds in time fields for Time objects" do
|
805
728
|
t = Time.now
|
806
729
|
@d.insert(:time=>t)
|
807
730
|
t2 = @d.get(:time)
|
@@ -810,7 +733,7 @@ describe "A PostgreSQL dataset with a timestamp field" do
|
|
810
733
|
(t2.is_a?(Time) ? t2.usec : t2.strftime('%N').to_i/1000).must_equal t.usec
|
811
734
|
end
|
812
735
|
|
813
|
-
|
736
|
+
it "should store milliseconds in time fields for DateTime objects" do
|
814
737
|
t = DateTime.now
|
815
738
|
@d.insert(:time=>t)
|
816
739
|
t2 = @d.get(:time)
|
@@ -819,76 +742,130 @@ describe "A PostgreSQL dataset with a timestamp field" do
|
|
819
742
|
(t2.is_a?(Time) ? t2.usec : t2.strftime('%N').to_i/1000).must_equal t.strftime('%N').to_i/1000
|
820
743
|
end
|
821
744
|
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
@db
|
829
|
-
@db.
|
830
|
-
|
831
|
-
|
832
|
-
@db
|
833
|
-
@db.
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
745
|
+
it "should handle BC times and dates" do
|
746
|
+
d = Date.new(-1234, 2, 3)
|
747
|
+
@db.get(Sequel.cast(d, Date)).must_equal d
|
748
|
+
begin
|
749
|
+
Sequel.default_timezone = :utc
|
750
|
+
t = Time.at(-100000000000).utc + 0.5
|
751
|
+
@db.get(Sequel.cast(t, Time)).must_equal t
|
752
|
+
@db.get(Sequel.cast(t, :timestamptz)).must_equal t
|
753
|
+
Sequel.datetime_class = DateTime
|
754
|
+
dt = DateTime.new(-1234, 2, 3, 10, 20, Rational(30, 20))
|
755
|
+
@db.get(Sequel.cast(dt, DateTime)).must_equal dt
|
756
|
+
@db.get(Sequel.cast(dt, :timestamptz)).must_equal dt
|
757
|
+
ensure
|
758
|
+
Sequel.datetime_class = Time
|
759
|
+
Sequel.default_timezone = nil
|
760
|
+
end
|
761
|
+
end
|
762
|
+
|
763
|
+
it "should handle infinite timestamps if convert_infinite_timestamps is set" do
|
764
|
+
@d.insert(:time=>Sequel.cast('infinity', DateTime))
|
765
|
+
@db.convert_infinite_timestamps = :nil
|
766
|
+
@db[:test3].get(:time).must_be_nil
|
767
|
+
@db.convert_infinite_timestamps = :string
|
768
|
+
@db[:test3].get(:time).must_equal 'infinity'
|
769
|
+
@db.convert_infinite_timestamps = :float
|
770
|
+
@db[:test3].get(:time).must_equal 1.0/0.0
|
771
|
+
@db.convert_infinite_timestamps = 'nil'
|
772
|
+
@db[:test3].get(:time).must_be_nil
|
773
|
+
@db.convert_infinite_timestamps = 'string'
|
774
|
+
@db[:test3].get(:time).must_equal 'infinity'
|
775
|
+
@db.convert_infinite_timestamps = 'date'
|
776
|
+
@db[:test3].get(:time).must_equal Date::Infinity.new
|
777
|
+
@db.convert_infinite_timestamps = 'float'
|
778
|
+
@db[:test3].get(:time).must_equal 1.0/0.0
|
779
|
+
@db.convert_infinite_timestamps = 't'
|
780
|
+
@db[:test3].get(:time).must_equal 1.0/0.0
|
781
|
+
@db.convert_infinite_timestamps = true
|
782
|
+
@db[:test3].get(:time).must_equal 1.0/0.0
|
783
|
+
@db.convert_infinite_timestamps = 'f'
|
784
|
+
proc{@db[:test3].get(:time)}.must_raise ArgumentError, Sequel::InvalidValue
|
785
|
+
@db.convert_infinite_timestamps = nil
|
786
|
+
proc{@db[:test3].get(:time)}.must_raise ArgumentError, Sequel::InvalidValue
|
787
|
+
@db.convert_infinite_timestamps = false
|
788
|
+
proc{@db[:test3].get(:time)}.must_raise ArgumentError, Sequel::InvalidValue
|
789
|
+
|
790
|
+
@d.update(:time=>Sequel.cast('-infinity', DateTime))
|
791
|
+
@db.convert_infinite_timestamps = :nil
|
792
|
+
@db[:test3].get(:time).must_be_nil
|
793
|
+
@db.convert_infinite_timestamps = :string
|
794
|
+
@db[:test3].get(:time).must_equal '-infinity'
|
795
|
+
@db.convert_infinite_timestamps = :date
|
796
|
+
@db[:test3].get(:time).must_equal -Date::Infinity.new
|
797
|
+
@db.convert_infinite_timestamps = :float
|
798
|
+
@db[:test3].get(:time).must_equal(-1.0/0.0)
|
799
|
+
end
|
800
|
+
|
801
|
+
it "should handle infinite dates if convert_infinite_timestamps is set" do
|
802
|
+
@d.insert(:time=>Sequel.cast('infinity', DateTime))
|
803
|
+
@db.convert_infinite_timestamps = :nil
|
804
|
+
@db[:test3].get(Sequel.cast(:time, Date)).must_be_nil
|
805
|
+
@db.convert_infinite_timestamps = :string
|
806
|
+
@db[:test3].get(Sequel.cast(:time, Date)).must_equal 'infinity'
|
807
|
+
@db.convert_infinite_timestamps = :float
|
808
|
+
@db[:test3].get(Sequel.cast(:time, Date)).must_equal 1.0/0.0
|
809
|
+
@db.convert_infinite_timestamps = 'nil'
|
810
|
+
@db[:test3].get(Sequel.cast(:time, Date)).must_be_nil
|
811
|
+
@db.convert_infinite_timestamps = 'string'
|
812
|
+
@db[:test3].get(Sequel.cast(:time, Date)).must_equal 'infinity'
|
813
|
+
@db.convert_infinite_timestamps = 'float'
|
814
|
+
@db[:test3].get(Sequel.cast(:time, Date)).must_equal 1.0/0.0
|
815
|
+
@db.convert_infinite_timestamps = 't'
|
816
|
+
@db[:test3].get(Sequel.cast(:time, Date)).must_equal 1.0/0.0
|
817
|
+
@db.convert_infinite_timestamps = true
|
818
|
+
@db[:test3].get(Sequel.cast(:time, Date)).must_equal 1.0/0.0
|
819
|
+
@db.convert_infinite_timestamps = 'f'
|
820
|
+
proc{@db[:test3].get(Sequel.cast(:time, Date))}.must_raise ArgumentError, Sequel::InvalidValue
|
821
|
+
@db.convert_infinite_timestamps = nil
|
822
|
+
proc{@db[:test3].get(Sequel.cast(:time, Date))}.must_raise ArgumentError, Sequel::InvalidValue
|
823
|
+
@db.convert_infinite_timestamps = false
|
824
|
+
proc{@db[:test3].get(Sequel.cast(:time, Date))}.must_raise ArgumentError, Sequel::InvalidValue
|
825
|
+
|
826
|
+
@d.update(:time=>Sequel.cast('-infinity', DateTime))
|
827
|
+
@db.convert_infinite_timestamps = :nil
|
828
|
+
@db[:test3].get(Sequel.cast(:time, Date)).must_be_nil
|
829
|
+
@db.convert_infinite_timestamps = :string
|
830
|
+
@db[:test3].get(Sequel.cast(:time, Date)).must_equal '-infinity'
|
831
|
+
@db.convert_infinite_timestamps = :float
|
832
|
+
@db[:test3].get(Sequel.cast(:time, Date)).must_equal(-1.0/0.0)
|
833
|
+
end
|
834
|
+
|
835
|
+
it "should handle conversions from infinite strings/floats in models" do
|
836
|
+
c = Class.new(Sequel::Model(:test3))
|
837
|
+
@db.convert_infinite_timestamps = :float
|
838
|
+
c.new(:time=>'infinity').time.must_equal 'infinity'
|
839
|
+
c.new(:time=>'-infinity').time.must_equal '-infinity'
|
840
|
+
c.new(:time=>1.0/0.0).time.must_equal 1.0/0.0
|
841
|
+
c.new(:time=>-1.0/0.0).time.must_equal(-1.0/0.0)
|
842
|
+
end
|
843
|
+
|
844
|
+
it "should handle infinite dates if convert_infinite_timestamps is set" do
|
845
|
+
@d.insert(:date=>Sequel.cast('infinity', Date))
|
846
|
+
@db.convert_infinite_timestamps = :nil
|
847
|
+
@db[:test3].get(:date).must_be_nil
|
848
|
+
@db.convert_infinite_timestamps = :string
|
849
|
+
@db[:test3].get(:date).must_equal 'infinity'
|
850
|
+
@db.convert_infinite_timestamps = :float
|
851
|
+
@db[:test3].get(:date).must_equal 1.0/0.0
|
852
|
+
|
853
|
+
@d.update(:date=>Sequel.cast('-infinity', :timestamp))
|
854
|
+
@db.convert_infinite_timestamps = :nil
|
855
|
+
@db[:test3].get(:date).must_be_nil
|
856
|
+
@db.convert_infinite_timestamps = :string
|
857
|
+
@db[:test3].get(:date).must_equal '-infinity'
|
858
|
+
@db.convert_infinite_timestamps = :float
|
859
|
+
@db[:test3].get(:date).must_equal(-1.0/0.0)
|
860
|
+
end
|
861
|
+
|
862
|
+
it "should handle conversions from infinite strings/floats in models" do
|
863
|
+
c = Class.new(Sequel::Model(:test3))
|
864
|
+
@db.convert_infinite_timestamps = :float
|
865
|
+
c.new(:date=>'infinity').date.must_equal 'infinity'
|
866
|
+
c.new(:date=>'-infinity').date.must_equal '-infinity'
|
867
|
+
c.new(:date=>1.0/0.0).date.must_equal 1.0/0.0
|
868
|
+
c.new(:date=>-1.0/0.0).date.must_equal(-1.0/0.0)
|
892
869
|
end
|
893
870
|
|
894
871
|
it "explain and analyze should not raise errors" do
|
@@ -952,7 +929,6 @@ describe "A PostgreSQL database" do
|
|
952
929
|
before do
|
953
930
|
@db = DB
|
954
931
|
@db.drop_table?(:posts)
|
955
|
-
@db.sqls.clear
|
956
932
|
end
|
957
933
|
after do
|
958
934
|
@db.drop_table?(:posts)
|
@@ -985,12 +961,7 @@ describe "A PostgreSQL database" do
|
|
985
961
|
|
986
962
|
it "should support opclass specification" do
|
987
963
|
@db.create_table(:posts){text :title; text :body; integer :user_id; index(:user_id, :opclass => :int4_ops, :type => :btree)}
|
988
|
-
|
989
|
-
@db.sqls.must_equal [
|
990
|
-
'CREATE TABLE "posts" ("title" text, "body" text, "user_id" integer)',
|
991
|
-
'CREATE INDEX "posts_user_id_index" ON "posts" USING btree ("user_id" int4_ops)'
|
992
|
-
]
|
993
|
-
end
|
964
|
+
proc{@db.create_table(:posts){text :title; text :body; integer :user_id; index(:user_id, :opclass => :bogus_opclass, :type => :btree)}}.must_raise Sequel::DatabaseError
|
994
965
|
end
|
995
966
|
|
996
967
|
it "should support fulltext indexes and searching" do
|
@@ -1035,52 +1006,25 @@ describe "A PostgreSQL database" do
|
|
1035
1006
|
|
1036
1007
|
it "should support spatial indexes" do
|
1037
1008
|
@db.create_table(:posts){box :geom; spatial_index [:geom]}
|
1038
|
-
check_sqls do
|
1039
|
-
@db.sqls.must_equal [
|
1040
|
-
'CREATE TABLE "posts" ("geom" box)',
|
1041
|
-
'CREATE INDEX "posts_geom_index" ON "posts" USING gist ("geom")'
|
1042
|
-
]
|
1043
|
-
end
|
1044
1009
|
end
|
1045
1010
|
|
1046
1011
|
it "should support indexes with index type" do
|
1047
1012
|
@db.create_table(:posts){point :p; index :p, :type => 'gist'}
|
1048
|
-
check_sqls do
|
1049
|
-
@db.sqls.must_equal [
|
1050
|
-
'CREATE TABLE "posts" ("p" point)',
|
1051
|
-
'CREATE INDEX "posts_p_index" ON "posts" USING gist ("p")'
|
1052
|
-
]
|
1053
|
-
end
|
1054
1013
|
end
|
1055
1014
|
|
1056
1015
|
it "should support unique indexes with index type" do
|
1057
|
-
@db.create_table(:posts){varchar :title, :size => 5; index :title, :type => 'btree', :unique => true}
|
1058
|
-
|
1059
|
-
|
1060
|
-
'CREATE TABLE "posts" ("title" varchar(5))',
|
1061
|
-
'CREATE UNIQUE INDEX "posts_title_index" ON "posts" USING btree ("title")'
|
1062
|
-
]
|
1063
|
-
end
|
1016
|
+
@db.create_table(:posts){varchar :title, :size => 5; index :title, :type => 'btree', :unique => true, :name=>:post_index_foo}
|
1017
|
+
@db.indexes(:posts).length.must_equal 1
|
1018
|
+
@db.indexes(:posts)[:post_index_foo][:unique].must_equal true
|
1064
1019
|
end
|
1065
1020
|
|
1066
1021
|
it "should support partial indexes" do
|
1067
1022
|
@db.create_table(:posts){varchar :title, :size => 5; index :title, :where => {:title => '5'}}
|
1068
|
-
check_sqls do
|
1069
|
-
@db.sqls.must_equal [
|
1070
|
-
'CREATE TABLE "posts" ("title" varchar(5))',
|
1071
|
-
'CREATE INDEX "posts_title_index" ON "posts" ("title") WHERE ("title" = \'5\')'
|
1072
|
-
]
|
1073
|
-
end
|
1074
1023
|
end
|
1075
1024
|
|
1076
|
-
it "should support identifiers for table names
|
1077
|
-
@db.create_table(Sequel::SQL::Identifier.new(:posts)){varchar :title, :size => 5; index :title
|
1078
|
-
|
1079
|
-
@db.sqls.must_equal [
|
1080
|
-
'CREATE TABLE "posts" ("title" varchar(5))',
|
1081
|
-
'CREATE INDEX "posts_title_index" ON "posts" ("title") WHERE ("title" = \'5\')'
|
1082
|
-
]
|
1083
|
-
end
|
1025
|
+
it "should support identifiers for table names when creating indexes" do
|
1026
|
+
@db.create_table(Sequel::SQL::Identifier.new(:posts)){varchar :title, :size => 5; index :title}
|
1027
|
+
@db.indexes(:posts).length.must_equal 1
|
1084
1028
|
end
|
1085
1029
|
|
1086
1030
|
it "should support renaming tables" do
|
@@ -1100,7 +1044,6 @@ describe "Postgres::Dataset#import" do
|
|
1100
1044
|
before do
|
1101
1045
|
@db = DB
|
1102
1046
|
@db.create_table!(:test){primary_key :x; Integer :y}
|
1103
|
-
@db.sqls.clear
|
1104
1047
|
@ds = @db[:test]
|
1105
1048
|
end
|
1106
1049
|
after do
|
@@ -1109,9 +1052,6 @@ describe "Postgres::Dataset#import" do
|
|
1109
1052
|
|
1110
1053
|
it "#import should a single insert statement" do
|
1111
1054
|
@ds.import([:x, :y], [[1, 2], [3, 4]])
|
1112
|
-
check_sqls do
|
1113
|
-
@db.sqls.must_equal ['BEGIN', 'INSERT INTO "test" ("x", "y") VALUES (1, 2), (3, 4)', 'COMMIT']
|
1114
|
-
end
|
1115
1055
|
@ds.all.must_equal [{:x=>1, :y=>2}, {:x=>3, :y=>4}]
|
1116
1056
|
end
|
1117
1057
|
|
@@ -1135,7 +1075,6 @@ describe "Postgres::Dataset#insert" do
|
|
1135
1075
|
before do
|
1136
1076
|
@db = DB
|
1137
1077
|
@db.create_table!(:test5){primary_key :xid; Integer :value}
|
1138
|
-
@db.sqls.clear
|
1139
1078
|
@ds = @db[:test5]
|
1140
1079
|
end
|
1141
1080
|
after do
|
@@ -1153,11 +1092,8 @@ describe "Postgres::Dataset#insert" do
|
|
1153
1092
|
@ds.all.must_equal [{:xid=>1, :value=>10}]
|
1154
1093
|
end
|
1155
1094
|
|
1156
|
-
it "should
|
1095
|
+
it "should have insert return primary key value" do
|
1157
1096
|
@ds.insert(:value=>10).must_equal 1
|
1158
|
-
check_sqls do
|
1159
|
-
@db.sqls.last.must_equal 'INSERT INTO "test5" ("value") VALUES (10) RETURNING "xid"'
|
1160
|
-
end
|
1161
1097
|
end
|
1162
1098
|
|
1163
1099
|
it "should have insert_select insert the record and return the inserted record" do
|
@@ -1234,7 +1170,7 @@ describe "Postgres::Database schema qualified tables" do
|
|
1234
1170
|
@db.create_table(Sequel[:schema_test][:domains]){integer :i}
|
1235
1171
|
sch = @db.schema(Sequel[:schema_test][:domains])
|
1236
1172
|
cs = sch.map{|x| x.first}
|
1237
|
-
cs.
|
1173
|
+
cs.first.must_equal :i
|
1238
1174
|
cs.wont_include(:data_type)
|
1239
1175
|
end
|
1240
1176
|
|
@@ -1243,7 +1179,7 @@ describe "Postgres::Database schema qualified tables" do
|
|
1243
1179
|
@db.create_table(Sequel[:schema_test][:domains]){integer :i}
|
1244
1180
|
sch = @db.schema(:domains, :schema=>:schema_test)
|
1245
1181
|
cs = sch.map{|x| x.first}
|
1246
|
-
cs.
|
1182
|
+
cs.first.must_equal :i
|
1247
1183
|
cs.wont_include(:d)
|
1248
1184
|
@db.drop_table(:domains)
|
1249
1185
|
end
|
@@ -1519,19 +1455,19 @@ if DB.server_version >= 80300
|
|
1519
1455
|
it "should search by indexed column" do
|
1520
1456
|
record = {:title => "oopsla conference", :body => "test"}
|
1521
1457
|
@ds.insert(record)
|
1522
|
-
@ds.full_text_search(:title, "oopsla").all.
|
1458
|
+
@ds.full_text_search(:title, "oopsla").all.must_equal [record]
|
1523
1459
|
end
|
1524
1460
|
|
1525
1461
|
it "should join multiple coumns with spaces to search by last words in row" do
|
1526
1462
|
record = {:title => "multiple words", :body => "are easy to search"}
|
1527
1463
|
@ds.insert(record)
|
1528
|
-
@ds.full_text_search([:title, :body], "words").all.
|
1464
|
+
@ds.full_text_search([:title, :body], "words").all.must_equal [record]
|
1529
1465
|
end
|
1530
1466
|
|
1531
1467
|
it "should return rows with a NULL in one column if a match in another column" do
|
1532
1468
|
record = {:title => "multiple words", :body =>nil}
|
1533
1469
|
@ds.insert(record)
|
1534
|
-
@ds.full_text_search([:title, :body], "words").all.
|
1470
|
+
@ds.full_text_search([:title, :body], "words").all.must_equal [record]
|
1535
1471
|
end
|
1536
1472
|
end
|
1537
1473
|
end
|
@@ -1580,47 +1516,34 @@ describe "Postgres::Database functions, languages, schemas, and triggers" do
|
|
1580
1516
|
|
1581
1517
|
it "#create_function and #drop_function should create and drop functions" do
|
1582
1518
|
proc{@d['SELECT tf()'].all}.must_raise(Sequel::DatabaseError)
|
1583
|
-
|
1584
|
-
@d.send(:create_function_sql, *args).must_match(/\A\s*CREATE FUNCTION tf\(\)\s+RETURNS integer\s+LANGUAGE SQL\s+AS 'SELECT 1'\s*\z/)
|
1585
|
-
@d.create_function(*args)
|
1519
|
+
@d.create_function('tf', 'SELECT 1', :returns=>:integer)
|
1586
1520
|
@d['SELECT tf()'].all.must_equal [{:tf=>1}]
|
1587
|
-
@d.send(:drop_function_sql, 'tf').must_equal 'DROP FUNCTION tf()'
|
1588
1521
|
@d.drop_function('tf')
|
1589
1522
|
proc{@d['SELECT tf()'].all}.must_raise(Sequel::DatabaseError)
|
1590
1523
|
end
|
1591
1524
|
|
1592
1525
|
it "#create_function and #drop_function should support options" do
|
1593
1526
|
args = ['tf', 'SELECT $1 + $2', {:args=>[[:integer, :a], :integer], :replace=>true, :returns=>:integer, :language=>'SQL', :behavior=>:immutable, :strict=>true, :security_definer=>true, :cost=>2, :set=>{:search_path => 'public'}}]
|
1594
|
-
@d.send(:create_function_sql,*args).must_match(/\A\s*CREATE OR REPLACE FUNCTION tf\(a integer, integer\)\s+RETURNS integer\s+LANGUAGE SQL\s+IMMUTABLE\s+STRICT\s+SECURITY DEFINER\s+COST 2\s+SET search_path = public\s+AS 'SELECT \$1 \+ \$2'\s*\z/)
|
1595
1527
|
@d.create_function(*args)
|
1596
1528
|
# Make sure replace works
|
1597
1529
|
@d.create_function(*args)
|
1598
1530
|
@d['SELECT tf(1, 2)'].all.must_equal [{:tf=>3}]
|
1599
1531
|
args = ['tf', {:if_exists=>true, :cascade=>true, :args=>[[:integer, :a], :integer]}]
|
1600
|
-
@d.send(:drop_function_sql,*args).must_equal 'DROP FUNCTION IF EXISTS tf(a integer, integer) CASCADE'
|
1601
1532
|
@d.drop_function(*args)
|
1602
1533
|
# Make sure if exists works
|
1603
1534
|
@d.drop_function(*args)
|
1604
1535
|
end
|
1605
1536
|
|
1606
1537
|
it "#create_language and #drop_language should create and drop languages" do
|
1607
|
-
@d.send(:create_language_sql, :plpgsql).must_equal 'CREATE LANGUAGE plpgsql'
|
1608
1538
|
@d.create_language(:plpgsql, :replace=>true) if @d.server_version < 90000
|
1609
1539
|
proc{@d.create_language(:plpgsql)}.must_raise(Sequel::DatabaseError)
|
1610
|
-
@d.send(:drop_language_sql, :plpgsql).must_equal 'DROP LANGUAGE plpgsql'
|
1611
1540
|
@d.drop_language(:plpgsql) if @d.server_version < 90000
|
1612
1541
|
proc{@d.drop_language(:plpgsql)}.must_raise(Sequel::DatabaseError) if @d.server_version < 90000
|
1613
|
-
@d.send(:create_language_sql, :plpgsql, :replace=>true, :trusted=>true, :handler=>:a, :validator=>:b).must_equal(@d.server_version >= 90000 ? 'CREATE OR REPLACE TRUSTED LANGUAGE plpgsql HANDLER a VALIDATOR b' : 'CREATE TRUSTED LANGUAGE plpgsql HANDLER a VALIDATOR b')
|
1614
|
-
@d.send(:drop_language_sql, :plpgsql, :if_exists=>true, :cascade=>true).must_equal 'DROP LANGUAGE IF EXISTS plpgsql CASCADE'
|
1615
1542
|
# Make sure if exists works
|
1616
1543
|
@d.drop_language(:plpgsql, :if_exists=>true, :cascade=>true) if @d.server_version < 90000
|
1617
1544
|
end
|
1618
1545
|
|
1619
1546
|
it "#create_schema and #drop_schema should create and drop schemas" do
|
1620
|
-
@d.send(:create_schema_sql, :sequel).must_equal 'CREATE SCHEMA "sequel"'
|
1621
|
-
@d.send(:create_schema_sql, :sequel, :if_not_exists=>true, :owner=>:foo).must_equal 'CREATE SCHEMA IF NOT EXISTS "sequel" AUTHORIZATION "foo"'
|
1622
|
-
@d.send(:drop_schema_sql, :sequel).must_equal 'DROP SCHEMA "sequel"'
|
1623
|
-
@d.send(:drop_schema_sql, :sequel, :if_exists=>true, :cascade=>true).must_equal 'DROP SCHEMA IF EXISTS "sequel" CASCADE'
|
1624
1547
|
@d.create_schema(:sequel)
|
1625
1548
|
@d.create_schema(:sequel, :if_not_exists=>true) if @d.server_version >= 90300
|
1626
1549
|
@d.create_table(Sequel[:sequel][:test]){Integer :a}
|
@@ -1630,7 +1553,6 @@ describe "Postgres::Database functions, languages, schemas, and triggers" do
|
|
1630
1553
|
it "#create_trigger and #drop_trigger should create and drop triggers" do
|
1631
1554
|
@d.create_language(:plpgsql) if @d.server_version < 90000
|
1632
1555
|
@d.create_function(:tf, 'BEGIN IF NEW.value IS NULL THEN RAISE EXCEPTION \'Blah\'; END IF; RETURN NEW; END;', :language=>:plpgsql, :returns=>:trigger)
|
1633
|
-
@d.send(:create_trigger_sql, :test, :identity, :tf, :each_row=>true).must_equal 'CREATE TRIGGER identity BEFORE INSERT OR UPDATE OR DELETE ON "test" FOR EACH ROW EXECUTE PROCEDURE tf()'
|
1634
1556
|
@d.create_table(:test){String :name; Integer :value}
|
1635
1557
|
@d.create_trigger(:test, :identity, :tf, :each_row=>true)
|
1636
1558
|
@d[:test].insert(:name=>'a', :value=>1)
|
@@ -1639,15 +1561,11 @@ describe "Postgres::Database functions, languages, schemas, and triggers" do
|
|
1639
1561
|
@d[:test].filter(:name=>'a').all.must_equal [{:name=>'a', :value=>1}]
|
1640
1562
|
@d[:test].filter(:name=>'a').update(:value=>3)
|
1641
1563
|
@d[:test].filter(:name=>'a').all.must_equal [{:name=>'a', :value=>3}]
|
1642
|
-
@d.send(:drop_trigger_sql, :test, :identity).must_equal 'DROP TRIGGER identity ON "test"'
|
1643
1564
|
@d.drop_trigger(:test, :identity)
|
1644
|
-
@d.send(:create_trigger_sql, :test, :identity, :tf, :after=>true, :events=>:insert, :args=>[1, 'a']).must_equal 'CREATE TRIGGER identity AFTER INSERT ON "test" EXECUTE PROCEDURE tf(1, \'a\')'
|
1645
|
-
@d.send(:drop_trigger_sql, :test, :identity, :if_exists=>true, :cascade=>true).must_equal 'DROP TRIGGER IF EXISTS identity ON "test" CASCADE'
|
1646
1565
|
# Make sure if exists works
|
1647
1566
|
@d.drop_trigger(:test, :identity, :if_exists=>true, :cascade=>true)
|
1648
1567
|
|
1649
1568
|
if @d.supports_trigger_conditions?
|
1650
|
-
@d.send(:create_trigger_sql, :test, :identity, :tf, :each_row=>true, :when=> {Sequel[:new][:name] => 'b'}).must_equal %q{CREATE TRIGGER identity BEFORE INSERT OR UPDATE OR DELETE ON "test" FOR EACH ROW WHEN ("new"."name" = 'b') EXECUTE PROCEDURE tf()}
|
1651
1569
|
@d.create_trigger(:test, :identity, :tf, :each_row=>true, :events => :update, :when=> {Sequel[:new][:name] => 'b'})
|
1652
1570
|
@d[:test].filter(:name=>'a').update(:value=>nil)
|
1653
1571
|
@d[:test].filter(:name=>'a').all.must_equal [{:name=>'a', :value=>nil}]
|
@@ -1663,7 +1581,6 @@ if DB.adapter_scheme == :postgres
|
|
1663
1581
|
before(:all) do
|
1664
1582
|
@db = DB
|
1665
1583
|
@db.create_table!(:test_cursor){Integer :x}
|
1666
|
-
@db.sqls.clear
|
1667
1584
|
@ds = @db[:test_cursor]
|
1668
1585
|
@db.transaction{1001.times{|i| @ds.insert(i)}}
|
1669
1586
|
end
|
@@ -1687,23 +1604,19 @@ if DB.adapter_scheme == :postgres
|
|
1687
1604
|
end
|
1688
1605
|
|
1689
1606
|
it "should respect the :rows_per_fetch option" do
|
1690
|
-
|
1607
|
+
i = 0
|
1608
|
+
@ds = @ds.with_extend{define_method(:execute){|*a, &block| i+=1; super(*a, &block);}}
|
1691
1609
|
@ds.use_cursor.all
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
end
|
1610
|
+
i.must_equal 2
|
1611
|
+
|
1612
|
+
i = 0
|
1696
1613
|
@ds.use_cursor(:rows_per_fetch=>100).all
|
1697
|
-
|
1698
|
-
@db.sqls.length.must_equal 15
|
1699
|
-
end
|
1614
|
+
i.must_equal 11
|
1700
1615
|
end
|
1701
1616
|
|
1702
1617
|
it "should respect the :hold=>true option for creating the cursor WITH HOLD and not using a transaction" do
|
1703
1618
|
@ds.use_cursor.each{@db.in_transaction?.must_equal true}
|
1704
|
-
check_sqls{@db.sqls.any?{|s| s =~ /WITH HOLD/}.must_equal false}
|
1705
1619
|
@ds.use_cursor(:hold=>true).each{@db.in_transaction?.must_equal false}
|
1706
|
-
check_sqls{@db.sqls.any?{|s| s =~ /WITH HOLD/}.must_equal true}
|
1707
1620
|
end
|
1708
1621
|
|
1709
1622
|
it "should support updating individual rows based on a cursor" do
|
@@ -1777,39 +1690,6 @@ if DB.adapter_scheme == :postgres
|
|
1777
1690
|
@db[:foo].get(:bar).must_equal 'foo'.reverse
|
1778
1691
|
end
|
1779
1692
|
end
|
1780
|
-
|
1781
|
-
describe "Postgres::PG_NAMED_TYPES" do
|
1782
|
-
before(:all) do
|
1783
|
-
deprecated do
|
1784
|
-
@db = DB
|
1785
|
-
@cp = @db.conversion_procs.dup
|
1786
|
-
@db.conversion_procs.delete(1013)
|
1787
|
-
Sequel::Postgres::PG_NAMED_TYPES[:oidvector] = lambda{|v| v.reverse}
|
1788
|
-
@db.reset_conversion_procs
|
1789
|
-
@db.register_array_type('oidvector')
|
1790
|
-
end
|
1791
|
-
end
|
1792
|
-
after(:all) do
|
1793
|
-
deprecated do
|
1794
|
-
Sequel::Postgres::PG_NAMED_TYPES.delete(:oidvector)
|
1795
|
-
@db.conversion_procs.replace(@cp)
|
1796
|
-
@db.drop_table?(:foo)
|
1797
|
-
@db.drop_enum(:foo_enum) rescue nil
|
1798
|
-
end
|
1799
|
-
end
|
1800
|
-
|
1801
|
-
deprecated "should look up conversion procs by name" do
|
1802
|
-
@db.create_table!(:foo){oidvector :bar}
|
1803
|
-
@db[:foo].insert(Sequel.cast('21', :oidvector))
|
1804
|
-
@db[:foo].get(:bar).must_equal '12'
|
1805
|
-
end
|
1806
|
-
|
1807
|
-
deprecated "should handle array types of named types" do
|
1808
|
-
@db.create_table!(:foo){column :bar, 'oidvector[]'}
|
1809
|
-
@db[:foo].insert(Sequel.pg_array(['21'], :oidvector))
|
1810
|
-
@db[:foo].get(:bar).must_equal ['12']
|
1811
|
-
end
|
1812
|
-
end
|
1813
1693
|
end
|
1814
1694
|
|
1815
1695
|
if uses_pg_or_jdbc && DB.server_version >= 90000
|
@@ -1892,6 +1772,31 @@ if uses_pg_or_jdbc && DB.server_version >= 90000
|
|
1892
1772
|
end
|
1893
1773
|
end
|
1894
1774
|
|
1775
|
+
describe "Postgres::Database#copy_into using UTF-8 encoding" do
|
1776
|
+
before(:all) do
|
1777
|
+
@db = DB
|
1778
|
+
@db.create_table!(:test_copy){String :t}
|
1779
|
+
@ds = @db[:test_copy].order(:t)
|
1780
|
+
end
|
1781
|
+
before do
|
1782
|
+
@db[:test_copy].delete
|
1783
|
+
end
|
1784
|
+
after(:all) do
|
1785
|
+
@db.drop_table?(:test_copy)
|
1786
|
+
end
|
1787
|
+
|
1788
|
+
it "should work with UTF-8 characters using the :data option" do
|
1789
|
+
@db.copy_into(:test_copy, :data=>(["\u00E4\n"]*2))
|
1790
|
+
@ds.select_map([:t]).map{|a| a.map{|s| s.force_encoding('UTF-8')}}.must_equal([["\u00E4"]] * 2)
|
1791
|
+
end
|
1792
|
+
|
1793
|
+
it "should work with UTF-8 characters using a block" do
|
1794
|
+
buf = (["\u00E4\n"]*2)
|
1795
|
+
@db.copy_into(:test_copy){buf.shift}
|
1796
|
+
@ds.select_map([:t]).map{|a| a.map{|s| s.force_encoding('UTF-8')}}.must_equal([["\u00E4"]] * 2)
|
1797
|
+
end
|
1798
|
+
end
|
1799
|
+
|
1895
1800
|
describe "Postgres::Database#copy_table" do
|
1896
1801
|
before(:all) do
|
1897
1802
|
@db = DB
|
@@ -1972,7 +1877,6 @@ if uses_pg_or_jdbc && DB.server_version >= 90000
|
|
1972
1877
|
e.wrapped_exception.must_be_kind_of ArgumentError
|
1973
1878
|
e.message.must_include "foo"
|
1974
1879
|
end
|
1975
|
-
|
1976
1880
|
end
|
1977
1881
|
end
|
1978
1882
|
|
@@ -2076,56 +1980,35 @@ describe 'PostgreSQL special float handling' do
|
|
2076
1980
|
before do
|
2077
1981
|
@db = DB
|
2078
1982
|
@db.create_table!(:test5){Float :value}
|
2079
|
-
@db.sqls.clear
|
2080
1983
|
@ds = @db[:test5]
|
2081
1984
|
end
|
2082
1985
|
after do
|
2083
1986
|
@db.drop_table?(:test5)
|
2084
1987
|
end
|
2085
1988
|
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
end
|
2091
|
-
|
2092
|
-
it 'should quote +Infinity' do
|
2093
|
-
inf = 1.0/0.0
|
2094
|
-
@ds.insert_sql(:value => inf).must_equal %q{INSERT INTO "test5" ("value") VALUES ('Infinity')}
|
2095
|
-
end
|
2096
|
-
|
2097
|
-
it 'should quote -Infinity' do
|
2098
|
-
inf = -1.0/0.0
|
2099
|
-
@ds.insert_sql(:value => inf).must_equal %q{INSERT INTO "test5" ("value") VALUES ('-Infinity')}
|
2100
|
-
end
|
1989
|
+
it 'inserts NaN' do
|
1990
|
+
nan = 0.0/0.0
|
1991
|
+
@ds.insert(:value=>nan)
|
1992
|
+
@ds.all[0][:value].nan?.must_equal true
|
2101
1993
|
end
|
2102
1994
|
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
end
|
2109
|
-
|
2110
|
-
it 'inserts +Infinity' do
|
2111
|
-
inf = 1.0/0.0
|
2112
|
-
@ds.insert(:value=>inf)
|
2113
|
-
@ds.all[0][:value].infinite?.must_be :>, 0
|
2114
|
-
end
|
1995
|
+
it 'inserts +Infinity' do
|
1996
|
+
inf = 1.0/0.0
|
1997
|
+
@ds.insert(:value=>inf)
|
1998
|
+
@ds.all[0][:value].infinite?.must_be :>, 0
|
1999
|
+
end
|
2115
2000
|
|
2116
|
-
|
2117
|
-
|
2118
|
-
|
2119
|
-
|
2120
|
-
end
|
2001
|
+
it 'inserts -Infinity' do
|
2002
|
+
inf = -1.0/0.0
|
2003
|
+
@ds.insert(:value=>inf)
|
2004
|
+
@ds.all[0][:value].infinite?.must_be :<, 0
|
2121
2005
|
end
|
2122
|
-
end
|
2006
|
+
end if DB.adapter_scheme == :postgres
|
2123
2007
|
|
2124
2008
|
describe 'PostgreSQL array handling' do
|
2125
2009
|
before(:all) do
|
2126
2010
|
@db = DB
|
2127
2011
|
@ds = @db[:items]
|
2128
|
-
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
2129
2012
|
@tp = lambda{@db.schema(:items).map{|a| a.last[:type]}}
|
2130
2013
|
end
|
2131
2014
|
after do
|
@@ -2144,27 +2027,23 @@ describe 'PostgreSQL array handling' do
|
|
2144
2027
|
@ds.insert(Sequel.pg_array([1], :int2), Sequel.pg_array([nil, 2], :int4), Sequel.pg_array([3, nil], :int8), Sequel.pg_array([4, nil, 4.5], :real), Sequel.pg_array([5, nil, 5.5], "double precision"))
|
2145
2028
|
@ds.count.must_equal 1
|
2146
2029
|
rs = @ds.all
|
2147
|
-
|
2148
|
-
|
2149
|
-
|
2150
|
-
|
2151
|
-
|
2152
|
-
|
2153
|
-
@ds.all.must_equal rs
|
2154
|
-
end
|
2030
|
+
rs.must_equal [{:i2=>[1], :i4=>[nil, 2], :i8=>[3, nil], :r=>[4.0, nil, 4.5], :dp=>[5.0, nil, 5.5]}]
|
2031
|
+
rs.first.values.each{|v| v.class.must_equal(Sequel::Postgres::PGArray)}
|
2032
|
+
rs.first.values.each{|v| v.to_a.must_be_kind_of(Array)}
|
2033
|
+
@ds.delete
|
2034
|
+
@ds.insert(rs.first)
|
2035
|
+
@ds.all.must_equal rs
|
2155
2036
|
|
2156
2037
|
@ds.delete
|
2157
2038
|
@ds.insert(Sequel.pg_array([[1], [2]], :int2), Sequel.pg_array([[nil, 2], [3, 4]], :int4), Sequel.pg_array([[3, nil], [nil, nil]], :int8), Sequel.pg_array([[4, nil], [nil, 4.5]], :real), Sequel.pg_array([[5, nil], [nil, 5.5]], "double precision"))
|
2158
2039
|
|
2159
2040
|
rs = @ds.all
|
2160
|
-
|
2161
|
-
|
2162
|
-
|
2163
|
-
|
2164
|
-
|
2165
|
-
|
2166
|
-
@ds.all.must_equal rs
|
2167
|
-
end
|
2041
|
+
rs.must_equal [{:i2=>[[1], [2]], :i4=>[[nil, 2], [3, 4]], :i8=>[[3, nil], [nil, nil]], :r=>[[4, nil], [nil, 4.5]], :dp=>[[5, nil], [nil, 5.5]]}]
|
2042
|
+
rs.first.values.each{|v| v.class.must_equal(Sequel::Postgres::PGArray)}
|
2043
|
+
rs.first.values.each{|v| v.to_a.must_be_kind_of(Array)}
|
2044
|
+
@ds.delete
|
2045
|
+
@ds.insert(rs.first)
|
2046
|
+
@ds.all.must_equal rs
|
2168
2047
|
end
|
2169
2048
|
|
2170
2049
|
it 'insert and retrieve decimal arrays' do
|
@@ -2175,26 +2054,22 @@ describe 'PostgreSQL array handling' do
|
|
2175
2054
|
@ds.insert(Sequel.pg_array([BigDecimal.new('1.000000000000000000001'), nil, BigDecimal.new('1')], :numeric))
|
2176
2055
|
@ds.count.must_equal 1
|
2177
2056
|
rs = @ds.all
|
2178
|
-
|
2179
|
-
|
2180
|
-
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2184
|
-
@ds.all.must_equal rs
|
2185
|
-
end
|
2057
|
+
rs.must_equal [{:n=>[BigDecimal.new('1.000000000000000000001'), nil, BigDecimal.new('1')]}]
|
2058
|
+
rs.first.values.each{|v| v.class.must_equal(Sequel::Postgres::PGArray)}
|
2059
|
+
rs.first.values.each{|v| v.to_a.must_be_kind_of(Array)}
|
2060
|
+
@ds.delete
|
2061
|
+
@ds.insert(rs.first)
|
2062
|
+
@ds.all.must_equal rs
|
2186
2063
|
|
2187
2064
|
@ds.delete
|
2188
2065
|
@ds.insert(Sequel.pg_array([[BigDecimal.new('1.0000000000000000000000000000001'), nil], [nil, BigDecimal.new('1')]], :numeric))
|
2189
2066
|
rs = @ds.all
|
2190
|
-
|
2191
|
-
|
2192
|
-
|
2193
|
-
|
2194
|
-
|
2195
|
-
|
2196
|
-
@ds.all.must_equal rs
|
2197
|
-
end
|
2067
|
+
rs.must_equal [{:n=>[[BigDecimal.new('1.0000000000000000000000000000001'), nil], [nil, BigDecimal.new('1')]]}]
|
2068
|
+
rs.first.values.each{|v| v.class.must_equal(Sequel::Postgres::PGArray)}
|
2069
|
+
rs.first.values.each{|v| v.to_a.must_be_kind_of(Array)}
|
2070
|
+
@ds.delete
|
2071
|
+
@ds.insert(rs.first)
|
2072
|
+
@ds.all.must_equal rs
|
2198
2073
|
end
|
2199
2074
|
|
2200
2075
|
it 'insert and retrieve string arrays' do
|
@@ -2207,26 +2082,22 @@ describe 'PostgreSQL array handling' do
|
|
2207
2082
|
@ds.insert(Sequel.pg_array(['a', nil, 'NULL', 'b"\'c'], 'char(4)'), Sequel.pg_array(['a', nil, 'NULL', 'b"\'c', '', ''], :varchar), Sequel.pg_array(['a', nil, 'NULL', 'b"\'c'], :text))
|
2208
2083
|
@ds.count.must_equal 1
|
2209
2084
|
rs = @ds.all
|
2210
|
-
|
2211
|
-
|
2212
|
-
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
@ds.all.must_equal rs
|
2217
|
-
end
|
2085
|
+
rs.must_equal [{:c=>['a ', nil, 'NULL', 'b"\'c'], :vc=>['a', nil, 'NULL', 'b"\'c', '', ''], :t=>['a', nil, 'NULL', 'b"\'c']}]
|
2086
|
+
rs.first.values.each{|v| v.class.must_equal(Sequel::Postgres::PGArray)}
|
2087
|
+
rs.first.values.each{|v| v.to_a.must_be_kind_of(Array)}
|
2088
|
+
@ds.delete
|
2089
|
+
@ds.insert(rs.first)
|
2090
|
+
@ds.all.must_equal rs
|
2218
2091
|
|
2219
2092
|
@ds.delete
|
2220
2093
|
@ds.insert(Sequel.pg_array([[['a'], [nil]], [['NULL'], ['b"\'c']]], 'char(4)'), Sequel.pg_array([[['a[],\\[\\]\\,\\""NULL",'], ['']], [['NULL'], ['b"\'c']]], :varchar), Sequel.pg_array([[['a'], [nil]], [['NULL'], ['b"\'c']]], :text))
|
2221
2094
|
rs = @ds.all
|
2222
|
-
|
2223
|
-
|
2224
|
-
|
2225
|
-
|
2226
|
-
|
2227
|
-
|
2228
|
-
@ds.all.must_equal rs
|
2229
|
-
end
|
2095
|
+
rs.must_equal [{:c=>[[['a '], [nil]], [['NULL'], ['b"\'c']]], :vc=>[[['a[],\\[\\]\\,\\""NULL",'], ['']], [['NULL'], ['b"\'c']]], :t=>[[['a'], [nil]], [['NULL'], ['b"\'c']]]}]
|
2096
|
+
rs.first.values.each{|v| v.class.must_equal(Sequel::Postgres::PGArray)}
|
2097
|
+
rs.first.values.each{|v| v.to_a.must_be_kind_of(Array)}
|
2098
|
+
@ds.delete
|
2099
|
+
@ds.insert(rs.first)
|
2100
|
+
@ds.all.must_equal rs
|
2230
2101
|
end
|
2231
2102
|
|
2232
2103
|
it 'insert and retrieve arrays of other types' do
|
@@ -2246,14 +2117,12 @@ describe 'PostgreSQL array handling' do
|
|
2246
2117
|
@ds.insert(Sequel.pg_array([true, false], :bool), Sequel.pg_array([d, nil], :date), Sequel.pg_array([t, nil], :time), Sequel.pg_array([ts, nil], :timestamp), Sequel.pg_array([ts, nil], :timestamptz))
|
2247
2118
|
@ds.count.must_equal 1
|
2248
2119
|
rs = @ds.all
|
2249
|
-
|
2250
|
-
|
2251
|
-
|
2252
|
-
|
2253
|
-
|
2254
|
-
|
2255
|
-
@ds.all.must_equal rs
|
2256
|
-
end
|
2120
|
+
rs.must_equal [{:b=>[true, false], :d=>[d, nil], :t=>[t, nil], :ts=>[ts, nil], :tstz=>[ts, nil]}]
|
2121
|
+
rs.first.values.each{|v| v.class.must_equal(Sequel::Postgres::PGArray)}
|
2122
|
+
rs.first.values.each{|v| v.to_a.must_be_kind_of(Array)}
|
2123
|
+
@ds.delete
|
2124
|
+
@ds.insert(rs.first)
|
2125
|
+
@ds.all.must_equal rs
|
2257
2126
|
|
2258
2127
|
@db.create_table!(:items) do
|
2259
2128
|
column :ba, 'bytea[]'
|
@@ -2263,15 +2132,13 @@ describe 'PostgreSQL array handling' do
|
|
2263
2132
|
@tp.call.must_equal [:blob_array, :time_timezone_array, :oid_array]
|
2264
2133
|
@ds.insert(Sequel.pg_array([Sequel.blob("a\0"), nil], :bytea), Sequel.pg_array([t, nil], :timetz), Sequel.pg_array([1, 2, 3], :oid))
|
2265
2134
|
@ds.count.must_equal 1
|
2266
|
-
|
2267
|
-
|
2268
|
-
|
2269
|
-
|
2270
|
-
|
2271
|
-
|
2272
|
-
|
2273
|
-
@ds.all.must_equal rs
|
2274
|
-
end
|
2135
|
+
rs = @ds.all
|
2136
|
+
rs.must_equal [{:ba=>[Sequel.blob("a\0"), nil], :tz=>[t, nil], :o=>[1, 2, 3]}]
|
2137
|
+
rs.first.values.each{|v| v.class.must_equal(Sequel::Postgres::PGArray)}
|
2138
|
+
rs.first.values.each{|v| v.to_a.must_be_kind_of(Array)}
|
2139
|
+
@ds.delete
|
2140
|
+
@ds.insert(rs.first)
|
2141
|
+
@ds.all.must_equal rs
|
2275
2142
|
|
2276
2143
|
@db.create_table!(:items) do
|
2277
2144
|
column :x, 'xml[]'
|
@@ -2295,21 +2162,19 @@ describe 'PostgreSQL array handling' do
|
|
2295
2162
|
Sequel.pg_array(['N'], :name),
|
2296
2163
|
Sequel.pg_array(['1 2'], :oidvector))
|
2297
2164
|
@ds.count.must_equal 1
|
2298
|
-
|
2299
|
-
|
2300
|
-
|
2301
|
-
|
2302
|
-
|
2303
|
-
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2308
|
-
|
2309
|
-
|
2310
|
-
|
2311
|
-
@ds.all.must_equal rs
|
2312
|
-
end
|
2165
|
+
rs = @ds.all
|
2166
|
+
r = rs.first
|
2167
|
+
m = r.delete(:m)
|
2168
|
+
m.class.must_equal(Sequel::Postgres::PGArray)
|
2169
|
+
m.to_a.must_be_kind_of(Array)
|
2170
|
+
m.first.must_be_kind_of(String)
|
2171
|
+
r.must_be(:==, :x=>['<a></a>'], :b=>['1'], :vb=>['10'], :u=>['c0f24910-39e7-11e4-916c-0800200c9a66'], :xi=>['12'], :c=>['12'], :n=>['N'], :o=>['1 2'])
|
2172
|
+
rs.first.values.each{|v| v.class.must_equal(Sequel::Postgres::PGArray)}
|
2173
|
+
rs.first.values.each{|v| v.to_a.must_be_kind_of(Array)}
|
2174
|
+
r[:m] = m
|
2175
|
+
@ds.delete
|
2176
|
+
@ds.insert(r)
|
2177
|
+
@ds.all.must_equal rs
|
2313
2178
|
end
|
2314
2179
|
|
2315
2180
|
it 'insert and retrieve empty arrays' do
|
@@ -2318,15 +2183,13 @@ describe 'PostgreSQL array handling' do
|
|
2318
2183
|
end
|
2319
2184
|
@ds.insert(:n=>Sequel.pg_array([], :integer))
|
2320
2185
|
@ds.count.must_equal 1
|
2321
|
-
|
2322
|
-
|
2323
|
-
|
2324
|
-
|
2325
|
-
|
2326
|
-
|
2327
|
-
|
2328
|
-
@ds.all.must_equal rs
|
2329
|
-
end
|
2186
|
+
rs = @ds.all
|
2187
|
+
rs.must_equal [{:n=>[]}]
|
2188
|
+
rs.first.values.each{|v| v.class.must_equal(Sequel::Postgres::PGArray)}
|
2189
|
+
rs.first.values.each{|v| v.to_a.must_be_kind_of(Array)}
|
2190
|
+
@ds.delete
|
2191
|
+
@ds.insert(rs.first)
|
2192
|
+
@ds.all.must_equal rs
|
2330
2193
|
end
|
2331
2194
|
|
2332
2195
|
it 'convert ruby array :default values' do
|
@@ -2335,15 +2198,13 @@ describe 'PostgreSQL array handling' do
|
|
2335
2198
|
end
|
2336
2199
|
@ds.insert
|
2337
2200
|
@ds.count.must_equal 1
|
2338
|
-
|
2339
|
-
|
2340
|
-
|
2341
|
-
|
2342
|
-
|
2343
|
-
|
2344
|
-
|
2345
|
-
@ds.all.must_equal rs
|
2346
|
-
end
|
2201
|
+
rs = @ds.all
|
2202
|
+
rs.must_equal [{:n=>[]}]
|
2203
|
+
rs.first.values.each{|v| v.class.must_equal(Sequel::Postgres::PGArray)}
|
2204
|
+
rs.first.values.each{|v| v.to_a.must_be_kind_of(Array)}
|
2205
|
+
@ds.delete
|
2206
|
+
@ds.insert(rs.first)
|
2207
|
+
@ds.all.must_equal rs
|
2347
2208
|
end
|
2348
2209
|
|
2349
2210
|
it 'insert and retrieve custom array types' do
|
@@ -2372,14 +2233,12 @@ describe 'PostgreSQL array handling' do
|
|
2372
2233
|
@ds.insert(Sequel.pg_array([int2v], :int2vector))
|
2373
2234
|
@ds.count.must_equal 1
|
2374
2235
|
rs = @ds.all
|
2375
|
-
|
2376
|
-
|
2377
|
-
|
2378
|
-
|
2379
|
-
|
2380
|
-
|
2381
|
-
@ds.all.must_equal rs
|
2382
|
-
end
|
2236
|
+
rs.must_equal [{:b=>[int2v]}]
|
2237
|
+
rs.first.values.each{|v| v.class.must_equal(Sequel::Postgres::PGArray)}
|
2238
|
+
rs.first.values.each{|v| v.to_a.must_be_kind_of(Array)}
|
2239
|
+
@ds.delete
|
2240
|
+
@ds.insert(rs.first)
|
2241
|
+
@ds.all.must_equal rs
|
2383
2242
|
end
|
2384
2243
|
|
2385
2244
|
it 'retrieve arrays with explicit bounds' do
|
@@ -2475,7 +2334,6 @@ describe 'PostgreSQL array handling' do
|
|
2475
2334
|
column :t, 'text[]'
|
2476
2335
|
end
|
2477
2336
|
c = Class.new(Sequel::Model(@db[:items]))
|
2478
|
-
c.plugin :pg_typecast_on_load, :i, :f, :d, :t unless @native
|
2479
2337
|
h = {:i=>[1,2, nil], :f=>[[1, 2.5], [3, 4.5]], :d=>[1, BigDecimal.new('1.000000000000000000001')], :t=>[%w'a b c', ['NULL', nil, '1']]}
|
2480
2338
|
o = c.create(h)
|
2481
2339
|
o.i.must_equal [1, 2, nil]
|
@@ -2494,7 +2352,6 @@ describe 'PostgreSQL array handling' do
|
|
2494
2352
|
column :t, 'varchar[]'
|
2495
2353
|
end
|
2496
2354
|
c = Class.new(Sequel::Model(@db[:items]))
|
2497
|
-
c.plugin :pg_typecast_on_load, :i, :f, :d, :t unless @native
|
2498
2355
|
o = c.create(:i=>[1,2, nil], :f=>[[1, 2.5], [3, 4.5]], :d=>[1, BigDecimal.new('1.000000000000000000001')], :t=>[%w'a b c', ['NULL', nil, '1']])
|
2499
2356
|
o.i.must_equal [1, 2, nil]
|
2500
2357
|
o.f.must_equal [[1, 2.5], [3, 4.5]]
|
@@ -2572,11 +2429,9 @@ describe 'PostgreSQL array handling' do
|
|
2572
2429
|
@ds.from{Sequel.pg_array([1,2,3]).op.unnest([4,5,6], [7,8]).as(:t1, [:a, :b, :c])}.select_order_map([:a, :b, :c]).must_equal [[1, 4, 7], [2, 5, 8], [3, 6, nil]]
|
2573
2430
|
end
|
2574
2431
|
|
2575
|
-
|
2576
|
-
|
2577
|
-
|
2578
|
-
@ds.get(Sequel.pg_array(:i).concat(:i2)).must_equal [1, 2, 3, 2, 1]
|
2579
|
-
end
|
2432
|
+
@ds.get(Sequel.pg_array(:i).push(4)).must_equal [1, 2, 3, 4]
|
2433
|
+
@ds.get(Sequel.pg_array(:i).unshift(4)).must_equal [4, 1, 2, 3]
|
2434
|
+
@ds.get(Sequel.pg_array(:i).concat(:i2)).must_equal [1, 2, 3, 2, 1]
|
2580
2435
|
|
2581
2436
|
if @db.type_supported?(:hstore)
|
2582
2437
|
Sequel.extension :pg_hstore_ops
|
@@ -2591,7 +2446,6 @@ describe 'PostgreSQL hstore handling' do
|
|
2591
2446
|
@db = DB
|
2592
2447
|
@ds = @db[:items]
|
2593
2448
|
@h = {'a'=>'b', 'c'=>nil, 'd'=>'NULL', 'e'=>'\\\\" \\\' ,=>'}
|
2594
|
-
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
2595
2449
|
end
|
2596
2450
|
after do
|
2597
2451
|
@db.drop_table?(:items)
|
@@ -2603,17 +2457,15 @@ describe 'PostgreSQL hstore handling' do
|
|
2603
2457
|
end
|
2604
2458
|
@ds.insert(Sequel.hstore(@h))
|
2605
2459
|
@ds.count.must_equal 1
|
2606
|
-
|
2607
|
-
|
2608
|
-
|
2609
|
-
|
2610
|
-
|
2611
|
-
|
2612
|
-
|
2613
|
-
|
2614
|
-
|
2615
|
-
@ds.all.must_equal rs
|
2616
|
-
end
|
2460
|
+
rs = @ds.all
|
2461
|
+
v = rs.first[:h]
|
2462
|
+
v.must_equal @h
|
2463
|
+
v.class.must_equal(Sequel::Postgres::HStore)
|
2464
|
+
v.to_hash.must_be_kind_of(Hash)
|
2465
|
+
v.to_hash.must_equal @h
|
2466
|
+
@ds.delete
|
2467
|
+
@ds.insert(rs.first)
|
2468
|
+
@ds.all.must_equal rs
|
2617
2469
|
end
|
2618
2470
|
|
2619
2471
|
it 'insert and retrieve hstore[] values' do
|
@@ -2622,16 +2474,14 @@ describe 'PostgreSQL hstore handling' do
|
|
2622
2474
|
end
|
2623
2475
|
@ds.insert(Sequel.pg_array([Sequel.hstore(@h)], :hstore))
|
2624
2476
|
@ds.count.must_equal 1
|
2625
|
-
|
2626
|
-
|
2627
|
-
|
2628
|
-
|
2629
|
-
|
2630
|
-
|
2631
|
-
|
2632
|
-
|
2633
|
-
@ds.all.must_equal rs
|
2634
|
-
end
|
2477
|
+
rs = @ds.all
|
2478
|
+
v = rs.first[:h].first
|
2479
|
+
v.class.must_equal(Sequel::Postgres::HStore)
|
2480
|
+
v.to_hash.must_be_kind_of(Hash)
|
2481
|
+
v.to_hash.must_equal @h
|
2482
|
+
@ds.delete
|
2483
|
+
@ds.insert(rs.first)
|
2484
|
+
@ds.all.must_equal rs
|
2635
2485
|
end
|
2636
2486
|
|
2637
2487
|
it 'use hstore in bound variables' do
|
@@ -2673,7 +2523,6 @@ describe 'PostgreSQL hstore handling' do
|
|
2673
2523
|
end
|
2674
2524
|
Sequel.extension :pg_hstore_ops
|
2675
2525
|
c.plugin :many_through_many
|
2676
|
-
c.plugin :pg_typecast_on_load, :h unless @native
|
2677
2526
|
|
2678
2527
|
h = {'item_id'=>"2", 'left_item_id'=>"1"}
|
2679
2528
|
o2 = c.create(:id=>2)
|
@@ -2836,7 +2685,6 @@ describe 'PostgreSQL json type' do
|
|
2836
2685
|
@ds = @db[:items]
|
2837
2686
|
@a = [1, 2, {'a'=>'b'}, 3.0]
|
2838
2687
|
@h = {'a'=>'b', '1'=>[3, 4, 5]}
|
2839
|
-
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
2840
2688
|
end
|
2841
2689
|
after do
|
2842
2690
|
@db.drop_table?(:items)
|
@@ -2855,32 +2703,28 @@ describe 'PostgreSQL json type' do
|
|
2855
2703
|
@db.create_table!(:items){column :j, json_type}
|
2856
2704
|
@ds.insert(pg_json.call(@h))
|
2857
2705
|
@ds.count.must_equal 1
|
2858
|
-
|
2859
|
-
|
2860
|
-
|
2861
|
-
|
2862
|
-
|
2863
|
-
|
2864
|
-
|
2865
|
-
|
2866
|
-
|
2867
|
-
@ds.all.must_equal rs
|
2868
|
-
end
|
2706
|
+
rs = @ds.all
|
2707
|
+
v = rs.first[:j]
|
2708
|
+
v.class.must_equal(hash_class)
|
2709
|
+
v.to_hash.must_be_kind_of(Hash)
|
2710
|
+
v.must_equal @h
|
2711
|
+
v.to_hash.must_equal @h
|
2712
|
+
@ds.delete
|
2713
|
+
@ds.insert(rs.first)
|
2714
|
+
@ds.all.must_equal rs
|
2869
2715
|
|
2870
2716
|
@ds.delete
|
2871
2717
|
@ds.insert(pg_json.call(@a))
|
2872
2718
|
@ds.count.must_equal 1
|
2873
|
-
|
2874
|
-
|
2875
|
-
|
2876
|
-
|
2877
|
-
|
2878
|
-
|
2879
|
-
|
2880
|
-
|
2881
|
-
|
2882
|
-
@ds.all.must_equal rs
|
2883
|
-
end
|
2719
|
+
rs = @ds.all
|
2720
|
+
v = rs.first[:j]
|
2721
|
+
v.class.must_equal(array_class)
|
2722
|
+
v.to_a.must_be_kind_of(Array)
|
2723
|
+
v.must_equal @a
|
2724
|
+
v.to_a.must_equal @a
|
2725
|
+
@ds.delete
|
2726
|
+
@ds.insert(rs.first)
|
2727
|
+
@ds.all.must_equal rs
|
2884
2728
|
end
|
2885
2729
|
|
2886
2730
|
it 'insert and retrieve json[] values' do
|
@@ -2888,17 +2732,15 @@ describe 'PostgreSQL json type' do
|
|
2888
2732
|
j = Sequel.pg_array([pg_json.call('a'=>1), pg_json.call(['b', 2])])
|
2889
2733
|
@ds.insert(j)
|
2890
2734
|
@ds.count.must_equal 1
|
2891
|
-
|
2892
|
-
|
2893
|
-
|
2894
|
-
|
2895
|
-
|
2896
|
-
|
2897
|
-
|
2898
|
-
|
2899
|
-
|
2900
|
-
@ds.all.must_equal rs
|
2901
|
-
end
|
2735
|
+
rs = @ds.all
|
2736
|
+
v = rs.first[:j]
|
2737
|
+
v.class.must_equal(Sequel::Postgres::PGArray)
|
2738
|
+
v.to_a.must_be_kind_of(Array)
|
2739
|
+
v.must_equal j
|
2740
|
+
v.to_a.must_equal j
|
2741
|
+
@ds.delete
|
2742
|
+
@ds.insert(rs.first)
|
2743
|
+
@ds.all.must_equal rs
|
2902
2744
|
end
|
2903
2745
|
|
2904
2746
|
it 'with models' do
|
@@ -2907,7 +2749,6 @@ describe 'PostgreSQL json type' do
|
|
2907
2749
|
column :h, json_type
|
2908
2750
|
end
|
2909
2751
|
c = Class.new(Sequel::Model(@db[:items]))
|
2910
|
-
c.plugin :pg_typecast_on_load, :h unless @native
|
2911
2752
|
c.create(:h=>pg_json.call(@h)).h.must_equal @h
|
2912
2753
|
c.create(:h=>pg_json.call(@a)).h.must_equal @a
|
2913
2754
|
end
|
@@ -3039,7 +2880,6 @@ describe 'PostgreSQL inet/cidr types' do
|
|
3039
2880
|
@ipv6 = IPAddr.new(@v6)
|
3040
2881
|
@ipv6nm = IPAddr.new(@v6nm)
|
3041
2882
|
end
|
3042
|
-
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
3043
2883
|
end
|
3044
2884
|
after do
|
3045
2885
|
@db.drop_table?(:items)
|
@@ -3049,51 +2889,45 @@ describe 'PostgreSQL inet/cidr types' do
|
|
3049
2889
|
@db.create_table!(:items){inet :i; cidr :c}
|
3050
2890
|
@ds.insert(@ipv4, @ipv4nm)
|
3051
2891
|
@ds.count.must_equal 1
|
3052
|
-
|
2892
|
+
rs = @ds.all
|
2893
|
+
rs.first[:i].must_equal @ipv4
|
2894
|
+
rs.first[:c].must_equal @ipv4nm
|
2895
|
+
rs.first[:i].must_be_kind_of(IPAddr)
|
2896
|
+
rs.first[:c].must_be_kind_of(IPAddr)
|
2897
|
+
@ds.delete
|
2898
|
+
@ds.insert(rs.first)
|
2899
|
+
@ds.all.must_equal rs
|
2900
|
+
|
2901
|
+
unless ipv6_broken
|
2902
|
+
@ds.delete
|
2903
|
+
@ds.insert(@ipv6, @ipv6nm)
|
2904
|
+
@ds.count.must_equal 1
|
3053
2905
|
rs = @ds.all
|
3054
|
-
rs.first[:
|
3055
|
-
rs.first[:
|
2906
|
+
rs.first[:j]
|
2907
|
+
rs.first[:i].must_equal @ipv6
|
2908
|
+
rs.first[:c].must_equal @ipv6nm
|
3056
2909
|
rs.first[:i].must_be_kind_of(IPAddr)
|
3057
2910
|
rs.first[:c].must_be_kind_of(IPAddr)
|
3058
2911
|
@ds.delete
|
3059
2912
|
@ds.insert(rs.first)
|
3060
2913
|
@ds.all.must_equal rs
|
3061
2914
|
end
|
3062
|
-
|
3063
|
-
unless ipv6_broken
|
3064
|
-
@ds.delete
|
3065
|
-
@ds.insert(@ipv6, @ipv6nm)
|
3066
|
-
@ds.count.must_equal 1
|
3067
|
-
if @native
|
3068
|
-
rs = @ds.all
|
3069
|
-
rs.first[:j]
|
3070
|
-
rs.first[:i].must_equal @ipv6
|
3071
|
-
rs.first[:c].must_equal @ipv6nm
|
3072
|
-
rs.first[:i].must_be_kind_of(IPAddr)
|
3073
|
-
rs.first[:c].must_be_kind_of(IPAddr)
|
3074
|
-
@ds.delete
|
3075
|
-
@ds.insert(rs.first)
|
3076
|
-
@ds.all.must_equal rs
|
3077
|
-
end
|
3078
|
-
end
|
3079
2915
|
end
|
3080
2916
|
|
3081
2917
|
it 'insert and retrieve inet/cidr/macaddr array values' do
|
3082
2918
|
@db.create_table!(:items){column :i, 'inet[]'; column :c, 'cidr[]'; column :m, 'macaddr[]'}
|
3083
2919
|
@ds.insert(Sequel.pg_array([@ipv4], 'inet'), Sequel.pg_array([@ipv4nm], 'cidr'), Sequel.pg_array(['12:34:56:78:90:ab'], 'macaddr'))
|
3084
2920
|
@ds.count.must_equal 1
|
3085
|
-
|
3086
|
-
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
|
3092
|
-
|
3093
|
-
|
3094
|
-
|
3095
|
-
@ds.all.must_equal rs
|
3096
|
-
end
|
2921
|
+
rs = @ds.all
|
2922
|
+
rs.first.values.all?{|c| c.is_a?(Sequel::Postgres::PGArray)}.must_equal true
|
2923
|
+
rs.first[:i].first.must_equal @ipv4
|
2924
|
+
rs.first[:c].first.must_equal @ipv4nm
|
2925
|
+
rs.first[:m].first.must_equal '12:34:56:78:90:ab'
|
2926
|
+
rs.first[:i].first.must_be_kind_of(IPAddr)
|
2927
|
+
rs.first[:c].first.must_be_kind_of(IPAddr)
|
2928
|
+
@ds.delete
|
2929
|
+
@ds.insert(rs.first)
|
2930
|
+
@ds.all.must_equal rs
|
3097
2931
|
end
|
3098
2932
|
|
3099
2933
|
it 'use ipaddr in bound variables' do
|
@@ -3129,7 +2963,6 @@ describe 'PostgreSQL inet/cidr types' do
|
|
3129
2963
|
cidr :c
|
3130
2964
|
end
|
3131
2965
|
c = Class.new(Sequel::Model(@db[:items]))
|
3132
|
-
c.plugin :pg_typecast_on_load, :i, :c unless @native
|
3133
2966
|
c.create(:i=>@v4, :c=>@v4nm).values.values_at(:i, :c).must_equal [@ipv4, @ipv4nm]
|
3134
2967
|
unless ipv6_broken
|
3135
2968
|
c.create(:i=>@ipv6, :c=>@ipv6nm).values.values_at(:i, :c).must_equal [@ipv6, @ipv6nm]
|
@@ -3211,7 +3044,6 @@ describe 'PostgreSQL range types' do
|
|
3211
3044
|
@r.each{|k, v| @ra[k] = Sequel.pg_array([v], @map[k])}
|
3212
3045
|
@r.each{|k, v| @pgr[k] = Sequel.pg_range(v)}
|
3213
3046
|
@r.each{|k, v| @pgra[k] = Sequel.pg_array([Sequel.pg_range(v)], @map[k])}
|
3214
|
-
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
3215
3047
|
end
|
3216
3048
|
after do
|
3217
3049
|
@db.drop_table?(:items)
|
@@ -3224,19 +3056,17 @@ describe 'PostgreSQL range types' do
|
|
3224
3056
|
input.each{|k, v| h[k] = Sequel.cast(v, @map[k])}
|
3225
3057
|
@ds.insert(h)
|
3226
3058
|
@ds.count.must_equal 1
|
3227
|
-
|
3228
|
-
|
3229
|
-
|
3230
|
-
|
3231
|
-
|
3232
|
-
|
3233
|
-
v.to_range.must_equal @r[k]
|
3234
|
-
end
|
3235
|
-
@ds.delete
|
3236
|
-
@ds.insert(rs.first)
|
3237
|
-
@ds.all.must_equal rs
|
3059
|
+
rs = @ds.all
|
3060
|
+
rs.first.each do |k, v|
|
3061
|
+
v.class.must_equal(Sequel::Postgres::PGRange)
|
3062
|
+
v.to_range.must_be_kind_of(Range)
|
3063
|
+
v.must_be :==, @r[k]
|
3064
|
+
v.to_range.must_equal @r[k]
|
3238
3065
|
end
|
3239
3066
|
@ds.delete
|
3067
|
+
@ds.insert(rs.first)
|
3068
|
+
@ds.all.must_equal rs
|
3069
|
+
@ds.delete
|
3240
3070
|
end
|
3241
3071
|
end
|
3242
3072
|
|
@@ -3245,21 +3075,19 @@ describe 'PostgreSQL range types' do
|
|
3245
3075
|
[@ra, @pgra].each do |input|
|
3246
3076
|
@ds.insert(input)
|
3247
3077
|
@ds.count.must_equal 1
|
3248
|
-
|
3249
|
-
|
3250
|
-
|
3251
|
-
|
3252
|
-
|
3253
|
-
|
3254
|
-
|
3255
|
-
|
3256
|
-
v.first.must_be :==, @r[k]
|
3257
|
-
end
|
3258
|
-
@ds.delete
|
3259
|
-
@ds.insert(rs.first)
|
3260
|
-
@ds.all.must_equal rs
|
3078
|
+
rs = @ds.all
|
3079
|
+
rs.first.each do |k, v|
|
3080
|
+
v.class.must_equal(Sequel::Postgres::PGArray)
|
3081
|
+
v.to_a.must_be_kind_of(Array)
|
3082
|
+
v.first.class.must_equal(Sequel::Postgres::PGRange)
|
3083
|
+
v.first.to_range.must_be_kind_of(Range)
|
3084
|
+
v.must_be :==, @ra[k].to_a
|
3085
|
+
v.first.must_be :==, @r[k]
|
3261
3086
|
end
|
3262
3087
|
@ds.delete
|
3088
|
+
@ds.insert(rs.first)
|
3089
|
+
@ds.all.must_equal rs
|
3090
|
+
@ds.delete
|
3263
3091
|
end
|
3264
3092
|
end
|
3265
3093
|
|
@@ -3288,14 +3116,12 @@ describe 'PostgreSQL range types' do
|
|
3288
3116
|
it 'with models' do
|
3289
3117
|
@db.create_table!(:items){primary_key :id; int4range :i4; int8range :i8; numrange :n; daterange :d; tsrange :t; tstzrange :tz}
|
3290
3118
|
c = Class.new(Sequel::Model(@db[:items]))
|
3291
|
-
c.plugin :pg_typecast_on_load, :i4, :i8, :n, :d, :t, :tz unless @native
|
3292
3119
|
v = c.create(@r).values
|
3293
3120
|
v.delete(:id)
|
3294
3121
|
v.must_be :==, @r
|
3295
3122
|
|
3296
3123
|
@db.create_table!(:items){primary_key :id; column :i4, 'int4range[]'; column :i8, 'int8range[]'; column :n, 'numrange[]'; column :d, 'daterange[]'; column :t, 'tsrange[]'; column :tz, 'tstzrange[]'}
|
3297
3124
|
c = Class.new(Sequel::Model(@db[:items]))
|
3298
|
-
c.plugin :pg_typecast_on_load, :i4, :i8, :n, :d, :t, :tz unless @native
|
3299
3125
|
v = c.create(@ra).values
|
3300
3126
|
v.delete(:id)
|
3301
3127
|
v.each{|k,v1| v1.must_be :==, @ra[k].to_a}
|
@@ -3304,10 +3130,8 @@ describe 'PostgreSQL range types' do
|
|
3304
3130
|
it 'works with current_datetime_timestamp extension' do
|
3305
3131
|
ds = @db.dataset.extension(:current_datetime_timestamp)
|
3306
3132
|
tsr = ds.get(Sequel.pg_range(ds.current_datetime..ds.current_datetime, :tstzrange))
|
3307
|
-
|
3308
|
-
|
3309
|
-
tsr.end.must_be_kind_of Time
|
3310
|
-
end
|
3133
|
+
tsr.begin.must_be_kind_of Time
|
3134
|
+
tsr.end.must_be_kind_of Time
|
3311
3135
|
end
|
3312
3136
|
|
3313
3137
|
it 'operations/functions with pg_range_ops' do
|
@@ -3384,10 +3208,6 @@ describe 'PostgreSQL interval types' do
|
|
3384
3208
|
before(:all) do
|
3385
3209
|
@db = DB
|
3386
3210
|
@ds = @db[:items]
|
3387
|
-
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
3388
|
-
end
|
3389
|
-
after(:all) do
|
3390
|
-
Sequel::Postgres::PG__TYPES.delete(1186) # SEQUEL5: Remove
|
3391
3211
|
end
|
3392
3212
|
after do
|
3393
3213
|
@db.drop_table?(:items)
|
@@ -3417,16 +3237,14 @@ describe 'PostgreSQL interval types' do
|
|
3417
3237
|
].each do |instr, outstr, value, parts|
|
3418
3238
|
@ds.insert(instr)
|
3419
3239
|
@ds.count.must_equal 1
|
3420
|
-
|
3421
|
-
|
3422
|
-
|
3423
|
-
|
3424
|
-
|
3425
|
-
|
3426
|
-
|
3427
|
-
|
3428
|
-
@ds.all.must_equal rs
|
3429
|
-
end
|
3240
|
+
@ds.get(Sequel.cast(:i, String)).must_equal outstr
|
3241
|
+
rs = @ds.all
|
3242
|
+
rs.first[:i].is_a?(ActiveSupport::Duration).must_equal true
|
3243
|
+
rs.first[:i].must_equal ActiveSupport::Duration.new(value, parts)
|
3244
|
+
rs.first[:i].parts.sort_by{|k,v| k.to_s}.reject{|k,v| v == 0}.must_equal parts.sort_by{|k,v| k.to_s}
|
3245
|
+
@ds.delete
|
3246
|
+
@ds.insert(rs.first)
|
3247
|
+
@ds.all.must_equal rs
|
3430
3248
|
@ds.delete
|
3431
3249
|
end
|
3432
3250
|
end
|
@@ -3435,16 +3253,14 @@ describe 'PostgreSQL interval types' do
|
|
3435
3253
|
@db.create_table!(:items){column :i, 'interval[]'}
|
3436
3254
|
@ds.insert(Sequel.pg_array(['1 year 2 months 3 weeks 4 days 5 hours 6 minutes 7 seconds'], 'interval'))
|
3437
3255
|
@ds.count.must_equal 1
|
3438
|
-
|
3439
|
-
|
3440
|
-
|
3441
|
-
|
3442
|
-
|
3443
|
-
|
3444
|
-
|
3445
|
-
|
3446
|
-
@ds.all.must_equal rs
|
3447
|
-
end
|
3256
|
+
rs = @ds.all
|
3257
|
+
rs.first[:i].is_a?(Sequel::Postgres::PGArray).must_equal true
|
3258
|
+
rs.first[:i].first.is_a?(ActiveSupport::Duration).must_equal true
|
3259
|
+
rs.first[:i].first.must_equal ActiveSupport::Duration.new(31557600 + 2*86400*30 + 3*86400*7 + 4*86400 + 5*3600 + 6*60 + 7, [[:years, 1], [:months, 2], [:days, 25], [:seconds, 18367]])
|
3260
|
+
rs.first[:i].first.parts.sort_by{|k,v| k.to_s}.must_equal [[:years, 1], [:months, 2], [:days, 25], [:seconds, 18367]].sort_by{|k,v| k.to_s}
|
3261
|
+
@ds.delete
|
3262
|
+
@ds.insert(rs.first)
|
3263
|
+
@ds.all.must_equal rs
|
3448
3264
|
end
|
3449
3265
|
|
3450
3266
|
it 'use intervals in bound variables' do
|
@@ -3472,7 +3288,6 @@ describe 'PostgreSQL interval types' do
|
|
3472
3288
|
interval :i
|
3473
3289
|
end
|
3474
3290
|
c = Class.new(Sequel::Model(@db[:items]))
|
3475
|
-
c.plugin :pg_typecast_on_load, :i, :c unless @native
|
3476
3291
|
v = c.create(:i=>'1 year 2 mons 25 days 05:06:07').i
|
3477
3292
|
v.is_a?(ActiveSupport::Duration).must_equal true
|
3478
3293
|
v.must_equal ActiveSupport::Duration.new(31557600 + 2*86400*30 + 3*86400*7 + 4*86400 + 5*3600 + 6*60 + 7, [[:years, 1], [:months, 2], [:days, 25], [:seconds, 18367]])
|
@@ -3504,8 +3319,6 @@ describe 'PostgreSQL row-valued/composite types' do
|
|
3504
3319
|
@db.register_row_type(Sequel.qualify(:public, :person))
|
3505
3320
|
@db.register_row_type(Sequel[:public][:company])
|
3506
3321
|
@new_oids = @db.conversion_procs.keys - oids
|
3507
|
-
|
3508
|
-
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
3509
3322
|
end
|
3510
3323
|
after(:all) do
|
3511
3324
|
@new_oids.each{|oid| @db.conversion_procs.delete(oid)}
|
@@ -3519,22 +3332,20 @@ describe 'PostgreSQL row-valued/composite types' do
|
|
3519
3332
|
it 'insert and retrieve row types' do
|
3520
3333
|
@ds.insert(:id=>1, :address=>Sequel.pg_row(['123 Sesame St', 'Somewhere', '12345']))
|
3521
3334
|
@ds.count.must_equal 1
|
3522
|
-
|
3523
|
-
|
3524
|
-
|
3525
|
-
|
3526
|
-
|
3527
|
-
|
3528
|
-
|
3529
|
-
|
3530
|
-
|
3531
|
-
@ds.all.must_equal rs
|
3335
|
+
# Single row valued type
|
3336
|
+
rs = @ds.all
|
3337
|
+
v = rs.first[:address]
|
3338
|
+
v.class.superclass.must_equal(Sequel::Postgres::PGRow::HashRow)
|
3339
|
+
v.to_hash.must_be_kind_of(Hash)
|
3340
|
+
v.to_hash.must_equal(:street=>'123 Sesame St', :city=>'Somewhere', :zip=>'12345')
|
3341
|
+
@ds.delete
|
3342
|
+
@ds.insert(rs.first)
|
3343
|
+
@ds.all.must_equal rs
|
3532
3344
|
|
3533
|
-
|
3534
|
-
|
3535
|
-
|
3536
|
-
|
3537
|
-
end
|
3345
|
+
# Nested row value type
|
3346
|
+
p = @ds.get(:person)
|
3347
|
+
p[:id].must_equal 1
|
3348
|
+
p[:address].must_equal v
|
3538
3349
|
end
|
3539
3350
|
|
3540
3351
|
it 'insert and retrieve row types containing domains' do
|
@@ -3559,19 +3370,17 @@ describe 'PostgreSQL row-valued/composite types' do
|
|
3559
3370
|
@ds = @db[:company]
|
3560
3371
|
@ds.insert(:id=>1, :employees=>Sequel.pg_array([@db.row_type(:person, [1, Sequel.pg_row(['123 Sesame St', 'Somewhere', '12345'])])]))
|
3561
3372
|
@ds.count.must_equal 1
|
3562
|
-
|
3563
|
-
|
3564
|
-
|
3565
|
-
|
3566
|
-
|
3567
|
-
|
3568
|
-
|
3569
|
-
|
3570
|
-
|
3571
|
-
|
3572
|
-
|
3573
|
-
@ds.get(:company).must_equal v
|
3574
|
-
end
|
3373
|
+
v = @ds.get(:company)
|
3374
|
+
v.class.superclass.must_equal(Sequel::Postgres::PGRow::HashRow)
|
3375
|
+
v.to_hash.must_be_kind_of(Hash)
|
3376
|
+
v[:id].must_equal 1
|
3377
|
+
employees = v[:employees]
|
3378
|
+
employees.class.must_equal(Sequel::Postgres::PGArray)
|
3379
|
+
employees.to_a.must_be_kind_of(Array)
|
3380
|
+
employees.must_equal [{:id=>1, :address=>{:street=>'123 Sesame St', :city=>'Somewhere', :zip=>'12345'}}]
|
3381
|
+
@ds.delete
|
3382
|
+
@ds.insert(v[:id], v[:employees])
|
3383
|
+
@ds.get(:company).must_equal v
|
3575
3384
|
end
|
3576
3385
|
|
3577
3386
|
it 'use row types in bound variables' do
|
@@ -3606,11 +3415,9 @@ describe 'PostgreSQL row-valued/composite types' do
|
|
3606
3415
|
@ds = @db[:company]
|
3607
3416
|
@ds.insert(:id=>1, :employees=>Sequel.pg_array([@db.row_type(:person, [1, Sequel.pg_row(['123 Sesame St', 'Somewhere', '12345'])])]))
|
3608
3417
|
@ds.get(Sequel.pg_row(:company)[:id]).must_equal 1
|
3609
|
-
|
3610
|
-
|
3611
|
-
|
3612
|
-
@ds.get(Sequel.pg_row(:company)[:employees][1][:address]).must_equal(:street=>'123 Sesame St', :city=>'Somewhere', :zip=>'12345')
|
3613
|
-
end
|
3418
|
+
@ds.get(Sequel.pg_row(:company)[:employees]).must_equal [{:id=>1, :address=>{:street=>'123 Sesame St', :city=>'Somewhere', :zip=>'12345'}}]
|
3419
|
+
@ds.get(Sequel.pg_row(:company)[:employees][1]).must_equal(:id=>1, :address=>{:street=>'123 Sesame St', :city=>'Somewhere', :zip=>'12345'})
|
3420
|
+
@ds.get(Sequel.pg_row(:company)[:employees][1][:address]).must_equal(:street=>'123 Sesame St', :city=>'Somewhere', :zip=>'12345')
|
3614
3421
|
@ds.get(Sequel.pg_row(:company)[:employees][1][:id]).must_equal 1
|
3615
3422
|
@ds.get(Sequel.pg_row(:company)[:employees][1][:address][:street]).must_equal '123 Sesame St'
|
3616
3423
|
@ds.get(Sequel.pg_row(:company)[:employees][1][:address][:city]).must_equal 'Somewhere'
|
@@ -3635,22 +3442,18 @@ describe 'PostgreSQL row-valued/composite types' do
|
|
3635
3442
|
@db[:b].select(Sequel.pg_row(:b)[:a]).first.must_equal(:a=>2)
|
3636
3443
|
@db[:b].select(Sequel.pg_row(:b).splat[:a]).first.must_equal(:a=>1)
|
3637
3444
|
|
3638
|
-
|
3639
|
-
|
3640
|
-
|
3641
|
-
@db[:b].select(Sequel.pg_row(:b).splat(:b)).first.must_equal(:b=>{:a=>1, :b=>{:a=>2}})
|
3642
|
-
end
|
3445
|
+
@db[:b].select(:b).first.must_equal(:b=>{:a=>2})
|
3446
|
+
@db[:b].select(Sequel.pg_row(:b).splat).first.must_equal(:a=>1, :b=>{:a=>2})
|
3447
|
+
@db[:b].select(Sequel.pg_row(:b).splat(:b)).first.must_equal(:b=>{:a=>1, :b=>{:a=>2}})
|
3643
3448
|
end
|
3644
3449
|
|
3645
3450
|
it "* should expand the table type into separate columns" do
|
3646
3451
|
ds = @db[:b].select(Sequel.pg_row(:b).splat(:b)).from_self(:alias=>:t)
|
3647
|
-
|
3648
|
-
|
3649
|
-
|
3650
|
-
|
3651
|
-
|
3652
|
-
ds.select(Sequel.pg_row(Sequel[:t][:b])[:b]).first.must_equal(:b=>{:a=>2})
|
3653
|
-
end
|
3452
|
+
ds.first.must_equal(:b=>{:a=>1, :b=>{:a=>2}})
|
3453
|
+
ds.select(Sequel.pg_row(:b).*).first.must_equal(:a=>1, :b=>{:a=>2})
|
3454
|
+
ds.select(Sequel.pg_row(:b)[:b]).first.must_equal(:b=>{:a=>2})
|
3455
|
+
ds.select(Sequel.pg_row(Sequel[:t][:b]).*).first.must_equal(:a=>1, :b=>{:a=>2})
|
3456
|
+
ds.select(Sequel.pg_row(Sequel[:t][:b])[:b]).first.must_equal(:b=>{:a=>2})
|
3654
3457
|
ds.select(Sequel.pg_row(:b)[:a]).first.must_equal(:a=>1)
|
3655
3458
|
ds.select(Sequel.pg_row(Sequel[:t][:b])[:a]).first.must_equal(:a=>1)
|
3656
3459
|
end
|
@@ -3679,41 +3482,37 @@ describe 'PostgreSQL row-valued/composite types' do
|
|
3679
3482
|
it 'insert and retrieve row types as model objects' do
|
3680
3483
|
@ds.insert(:id=>1, :address=>@a)
|
3681
3484
|
@ds.count.must_equal 1
|
3682
|
-
|
3683
|
-
|
3684
|
-
|
3685
|
-
|
3686
|
-
|
3687
|
-
|
3688
|
-
|
3689
|
-
|
3690
|
-
|
3691
|
-
|
3692
|
-
|
3693
|
-
|
3694
|
-
|
3695
|
-
|
3696
|
-
|
3697
|
-
p.address.must_equal @a
|
3698
|
-
end
|
3485
|
+
# Single row valued type
|
3486
|
+
rs = @ds.all
|
3487
|
+
v = rs.first[:address]
|
3488
|
+
v.must_be_kind_of(Address)
|
3489
|
+
v.must_equal @a
|
3490
|
+
@ds.delete
|
3491
|
+
@ds.insert(rs.first)
|
3492
|
+
@ds.all.must_equal rs
|
3493
|
+
|
3494
|
+
# Nested row value type
|
3495
|
+
p = @ds.get(:person)
|
3496
|
+
p.must_be_kind_of(Person)
|
3497
|
+
p.id.must_equal 1
|
3498
|
+
p.address.must_be_kind_of(Address)
|
3499
|
+
p.address.must_equal @a
|
3699
3500
|
end
|
3700
3501
|
|
3701
3502
|
it 'insert and retrieve arrays of row types as model objects' do
|
3702
3503
|
@ds = @db[:company]
|
3703
3504
|
@ds.insert(:id=>1, :employees=>@es)
|
3704
3505
|
@ds.count.must_equal 1
|
3705
|
-
|
3706
|
-
|
3707
|
-
|
3708
|
-
|
3709
|
-
|
3710
|
-
|
3711
|
-
|
3712
|
-
|
3713
|
-
|
3714
|
-
|
3715
|
-
@ds.get(:company).must_equal v
|
3716
|
-
end
|
3506
|
+
v = @ds.get(:company)
|
3507
|
+
v.must_be_kind_of(Company)
|
3508
|
+
v.id.must_equal 1
|
3509
|
+
employees = v[:employees]
|
3510
|
+
employees.class.must_equal(Sequel::Postgres::PGArray)
|
3511
|
+
employees.to_a.must_be_kind_of(Array)
|
3512
|
+
employees.must_equal @es
|
3513
|
+
@ds.delete
|
3514
|
+
@ds.insert(v.id, v.employees)
|
3515
|
+
@ds.get(:company).must_equal v
|
3717
3516
|
end
|
3718
3517
|
|
3719
3518
|
it 'use model objects in bound variables' do
|
@@ -3732,7 +3531,6 @@ describe 'PostgreSQL row-valued/composite types' do
|
|
3732
3531
|
end if uses_pg_or_jdbc
|
3733
3532
|
|
3734
3533
|
it 'model typecasting' do
|
3735
|
-
Person.plugin :pg_typecast_on_load, :address unless @native
|
3736
3534
|
a = Address.new(:street=>'123 Sesame St', :city=>'Somewhere', :zip=>'12345')
|
3737
3535
|
o = Person.create(:id=>1, :address=>['123 Sesame St', 'Somewhere', '12345'])
|
3738
3536
|
o.address.must_equal a
|
@@ -3741,7 +3539,6 @@ describe 'PostgreSQL row-valued/composite types' do
|
|
3741
3539
|
o = Person.create(:id=>1, :address=>a)
|
3742
3540
|
o.address.must_equal a
|
3743
3541
|
|
3744
|
-
Company.plugin :pg_typecast_on_load, :employees unless @native
|
3745
3542
|
e = Person.new(:id=>1, :address=>a)
|
3746
3543
|
o = Company.create(:id=>1, :employees=>[{:id=>1, :address=>{:street=>'123 Sesame St', :city=>'Somewhere', :zip=>'12345'}}])
|
3747
3544
|
o.employees.must_equal [e]
|
@@ -3838,8 +3635,6 @@ end
|
|
3838
3635
|
|
3839
3636
|
describe "PostgreSQL stored procedures for datasets" do
|
3840
3637
|
before do
|
3841
|
-
require 'sequel/adapters/utils/stored_procedures'
|
3842
|
-
|
3843
3638
|
@db = DB
|
3844
3639
|
@db.create_table!(:items) do
|
3845
3640
|
primary_key :id
|