sequel 3.21.0 → 3.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +1061 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +103 -63
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +67 -51
- data/doc/advanced_associations.rdoc +189 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +10 -10
- data/doc/dataset_filtering.rdoc +54 -42
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +89 -557
- data/doc/model_hooks.rdoc +80 -29
- data/doc/object_model.rdoc +547 -0
- data/doc/opening_databases.rdoc +114 -53
- data/doc/prepared_statements.rdoc +41 -15
- data/doc/querying.rdoc +137 -56
- data/doc/reflection.rdoc +36 -10
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/release_notes/3.33.0.txt +157 -0
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/release_notes/3.35.0.txt +144 -0
- data/doc/release_notes/3.36.0.txt +245 -0
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/release_notes/3.39.0.txt +237 -0
- data/doc/schema_modification.rdoc +585 -0
- data/doc/sharding.rdoc +99 -8
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +169 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +78 -43
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +2 -61
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +18 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +453 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +56 -0
- data/lib/sequel/adapters/jdbc/derby.rb +325 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +73 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
- data/lib/sequel/adapters/jdbc/progress.rb +21 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
- data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +279 -97
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +125 -222
- data/lib/sequel/adapters/mysql2.rb +65 -56
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +349 -53
- data/lib/sequel/adapters/postgres.rb +368 -138
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +343 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +401 -116
- data/lib/sequel/adapters/shared/mysql.rb +424 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
- data/lib/sequel/adapters/shared/oracle.rb +257 -45
- data/lib/sequel/adapters/shared/postgres.rb +675 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +285 -96
- data/lib/sequel/adapters/sqlite.rb +101 -39
- data/lib/sequel/adapters/swift/mysql.rb +10 -12
- data/lib/sequel/adapters/swift/postgres.rb +13 -79
- data/lib/sequel/adapters/swift/sqlite.rb +9 -6
- data/lib/sequel/adapters/swift.rb +28 -19
- data/lib/sequel/adapters/tinytds.rb +174 -22
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
- data/lib/sequel/adapters/utils/pg_types.rb +81 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +11 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
- data/lib/sequel/connection_pool/single.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +43 -14
- data/lib/sequel/connection_pool.rb +10 -2
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +38 -28
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +63 -2
- data/lib/sequel/database/logging.rb +7 -2
- data/lib/sequel/database/misc.rb +190 -46
- data/lib/sequel/database/query.rb +272 -110
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +300 -67
- data/lib/sequel/dataset/actions.rb +344 -90
- data/lib/sequel/dataset/features.rb +101 -8
- data/lib/sequel/dataset/graph.rb +42 -15
- data/lib/sequel/dataset/misc.rb +52 -25
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +305 -54
- data/lib/sequel/dataset/sql.rb +720 -292
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +83 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +72 -0
- data/lib/sequel/extensions/constraint_validations.rb +451 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
- data/lib/sequel/extensions/eval_inspect.rb +173 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +100 -11
- data/lib/sequel/extensions/named_timezones.rb +9 -0
- data/lib/sequel/extensions/null_dataset.rb +94 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +537 -0
- data/lib/sequel/extensions/pg_array_ops.rb +263 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
- data/lib/sequel/extensions/pg_hstore.rb +313 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
- data/lib/sequel/extensions/pg_inet.rb +113 -0
- data/lib/sequel/extensions/pg_interval.rb +191 -0
- data/lib/sequel/extensions/pg_json.rb +208 -0
- data/lib/sequel/extensions/pg_range.rb +512 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +572 -0
- data/lib/sequel/extensions/pg_row_ops.rb +182 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
- data/lib/sequel/extensions/pretty_table.rb +17 -72
- data/lib/sequel/extensions/query.rb +8 -4
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +282 -76
- data/lib/sequel/extensions/select_remove.rb +39 -0
- data/lib/sequel/extensions/server_block.rb +140 -0
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +8 -110
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
- data/lib/sequel/extensions/to_dot.rb +99 -83
- data/lib/sequel/model/associations.rb +1263 -409
- data/lib/sequel/model/base.rb +624 -171
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +24 -2
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model.rb +30 -11
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +44 -12
- data/lib/sequel/plugins/constraint_validations.rb +198 -0
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +72 -0
- data/lib/sequel/plugins/dirty.rb +214 -0
- data/lib/sequel/plugins/eager_each.rb +59 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +134 -15
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +58 -6
- data/lib/sequel/plugins/list.rb +13 -2
- data/lib/sequel/plugins/many_through_many.rb +103 -51
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +150 -66
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/prepared_statements.rb +167 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +31 -17
- data/lib/sequel/plugins/schema.rb +8 -3
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +29 -3
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/plugins/validation_helpers.rb +55 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +649 -122
- data/lib/sequel/timezones.rb +67 -40
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +194 -66
- data/spec/adapters/mysql_spec.rb +475 -306
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +1982 -325
- data/spec/adapters/spec_helper.rb +9 -6
- data/spec/adapters/sqlite_spec.rb +203 -75
- data/spec/core/connection_pool_spec.rb +218 -93
- data/spec/core/database_spec.rb +956 -522
- data/spec/core/dataset_spec.rb +1631 -1242
- data/spec/core/expression_filters_spec.rb +690 -334
- data/spec/core/mock_adapter_spec.rb +453 -0
- data/spec/core/object_graph_spec.rb +88 -129
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +556 -53
- data/spec/core/spec_helper.rb +7 -48
- data/spec/core_extensions_spec.rb +626 -0
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/arbitrary_servers_spec.rb +110 -0
- data/spec/extensions/association_autoreloading_spec.rb +18 -10
- data/spec/extensions/association_dependencies_spec.rb +15 -25
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/association_proxies_spec.rb +4 -4
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/caching_spec.rb +47 -51
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
- data/spec/extensions/constraint_validations_spec.rb +316 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +88 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/eval_inspect_spec.rb +67 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +97 -128
- data/spec/extensions/identity_map_spec.rb +142 -24
- data/spec/extensions/inflector_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +72 -0
- data/spec/extensions/json_serializer_spec.rb +49 -12
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +49 -40
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +368 -254
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +140 -35
- data/spec/extensions/named_timezones_spec.rb +29 -11
- data/spec/extensions/nested_attributes_spec.rb +268 -89
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +24 -21
- data/spec/extensions/pg_array_ops_spec.rb +112 -0
- data/spec/extensions/pg_array_spec.rb +320 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
- data/spec/extensions/pg_hstore_spec.rb +194 -0
- data/spec/extensions/pg_inet_spec.rb +47 -0
- data/spec/extensions/pg_interval_spec.rb +72 -0
- data/spec/extensions/pg_json_spec.rb +99 -0
- data/spec/extensions/pg_range_ops_spec.rb +56 -0
- data/spec/extensions/pg_range_spec.rb +395 -0
- data/spec/extensions/pg_row_ops_spec.rb +58 -0
- data/spec/extensions/pg_row_plugin_spec.rb +49 -0
- data/spec/extensions/pg_row_spec.rb +323 -0
- data/spec/extensions/pg_statement_cache_spec.rb +208 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +87 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +7 -6
- data/spec/extensions/query_literals_spec.rb +167 -0
- data/spec/extensions/query_spec.rb +9 -3
- data/spec/extensions/rcte_tree_spec.rb +50 -43
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +434 -49
- data/spec/extensions/schema_spec.rb +30 -49
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +86 -48
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/sharding_spec.rb +69 -143
- data/spec/extensions/single_table_inheritance_spec.rb +23 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +34 -67
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/subclasses_spec.rb +14 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +8 -11
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +9 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +58 -67
- data/spec/extensions/validation_helpers_spec.rb +31 -37
- data/spec/extensions/xml_serializer_spec.rb +29 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
- data/spec/integration/associations_test.rb +659 -21
- data/spec/integration/database_test.rb +11 -5
- data/spec/integration/dataset_test.rb +717 -129
- data/spec/integration/eager_loader_test.rb +38 -54
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +604 -147
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +367 -57
- data/spec/integration/spec_helper.rb +42 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +31 -8
- data/spec/model/association_reflection_spec.rb +207 -8
- data/spec/model/associations_spec.rb +1206 -693
- data/spec/model/base_spec.rb +334 -100
- data/spec/model/dataset_methods_spec.rb +45 -27
- data/spec/model/eager_loading_spec.rb +828 -692
- data/spec/model/hooks_spec.rb +355 -67
- data/spec/model/model_spec.rb +251 -179
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +506 -232
- data/spec/model/spec_helper.rb +16 -77
- data/spec/model/validations_spec.rb +38 -2
- data/spec/rcov.opts +2 -0
- metadata +209 -80
- data/spec/core/core_sql_spec.rb +0 -451
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "pg_range extension" do
|
|
4
|
+
before(:all) do
|
|
5
|
+
@pg_types = Sequel::Postgres::PG_TYPES.dup
|
|
6
|
+
end
|
|
7
|
+
after(:all) do
|
|
8
|
+
Sequel::Postgres::PG_TYPES.replace(@pg_types)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
@db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
|
|
13
|
+
@R = Sequel::Postgres::PGRange
|
|
14
|
+
@db.extend_datasets(Module.new{def supports_timestamp_timezones?; false; end; def supports_timestamp_usecs?; false; end})
|
|
15
|
+
@db.extension(:pg_array, :pg_range)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should literalize Range instances to strings correctly" do
|
|
19
|
+
@db.literal(Date.new(2011, 1, 2)...Date.new(2011, 3, 2)).should == "'[2011-01-02,2011-03-02)'"
|
|
20
|
+
@db.literal(Time.local(2011, 1, 2, 10, 20, 30)...Time.local(2011, 2, 3, 10, 20, 30)).should == "'[2011-01-02 10:20:30,2011-02-03 10:20:30)'"
|
|
21
|
+
@db.literal(DateTime.new(2011, 1, 2, 10, 20, 30)...DateTime.new(2011, 2, 3, 10, 20, 30)).should == "'[2011-01-02 10:20:30,2011-02-03 10:20:30)'"
|
|
22
|
+
@db.literal(DateTime.new(2011, 1, 2, 10, 20, 30)...DateTime.new(2011, 2, 3, 10, 20, 30)).should == "'[2011-01-02 10:20:30,2011-02-03 10:20:30)'"
|
|
23
|
+
@db.literal(1..2).should == "'[1,2]'"
|
|
24
|
+
@db.literal(1.0..2.0).should == "'[1.0,2.0]'"
|
|
25
|
+
@db.literal(BigDecimal.new('1.0')..BigDecimal.new('2.0')).should == "'[1.0,2.0]'"
|
|
26
|
+
@db.literal(Sequel.lit('a')..Sequel.lit('z')).should == "'[a,z]'"
|
|
27
|
+
@db.literal(''..'()[]",\\2').should == "'[\"\",\\(\\)\\[\\]\\\"\\,\\\\2]'"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should literalize PGRange instances to strings correctly" do
|
|
31
|
+
@db.literal(@R.new(1, 2)).should == "'[1,2]'"
|
|
32
|
+
@db.literal(@R.new(true, false)).should == "'[true,false]'"
|
|
33
|
+
@db.literal(@R.new(1, 2, :exclude_begin=>true)).should == "'(1,2]'"
|
|
34
|
+
@db.literal(@R.new(1, 2, :exclude_end=>true)).should == "'[1,2)'"
|
|
35
|
+
@db.literal(@R.new(nil, 2)).should == "'[,2]'"
|
|
36
|
+
@db.literal(@R.new(1, nil)).should == "'[1,]'"
|
|
37
|
+
@db.literal(@R.new(1, 2, :db_type=>'int8range')).should == "'[1,2]'::int8range"
|
|
38
|
+
@db.literal(@R.new(nil, nil, :empty=>true)).should == "'empty'"
|
|
39
|
+
@db.literal(@R.new("", 2)).should == "'[\"\",2]'"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should not affect literalization of custom objects" do
|
|
43
|
+
o = Object.new
|
|
44
|
+
def o.sql_literal(ds) 'v' end
|
|
45
|
+
@db.literal(o).should == 'v'
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should support using Range instances as bound variables" do
|
|
49
|
+
@db.bound_variable_arg(1..2, nil).should == "[1,2]"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should support using PGRange instances as bound variables" do
|
|
53
|
+
@db.bound_variable_arg(@R.new(1, 2), nil).should == "[1,2]"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should support using arrays of Range instances as bound variables" do
|
|
57
|
+
@db.bound_variable_arg([1..2,2...3], nil).should == '{"[1,2]","[2,3)"}'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should support using PGRange instances as bound variables" do
|
|
61
|
+
@db.bound_variable_arg([@R.new(1, 2),@R.new(2, 3)], nil).should == '{"[1,2]","[2,3]"}'
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should parse range types from the schema correctly" do
|
|
65
|
+
@db.fetch = [{:name=>'id', :db_type=>'integer'}, {:name=>'i4', :db_type=>'int4range'}, {:name=>'i8', :db_type=>'int8range'}, {:name=>'n', :db_type=>'numrange'}, {:name=>'d', :db_type=>'daterange'}, {:name=>'ts', :db_type=>'tsrange'}, {:name=>'tz', :db_type=>'tstzrange'}]
|
|
66
|
+
@db.schema(:items).map{|e| e[1][:type]}.should == [:integer, :int4range, :int8range, :numrange, :daterange, :tsrange, :tstzrange]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "should parse arrays of range types from the schema correctly" do
|
|
70
|
+
@db.fetch = [{:name=>'id', :db_type=>'integer'}, {:name=>'i4', :db_type=>'int4range[]'}, {:name=>'i8', :db_type=>'int8range[]'}, {:name=>'n', :db_type=>'numrange[]'}, {:name=>'d', :db_type=>'daterange[]'}, {:name=>'ts', :db_type=>'tsrange[]'}, {:name=>'tz', :db_type=>'tstzrange[]'}]
|
|
71
|
+
@db.schema(:items).map{|e| e[1][:type]}.should == [:integer, :int4range_array, :int8range_array, :numrange_array, :daterange_array, :tsrange_array, :tstzrange_array]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe "database typecasting" do
|
|
75
|
+
before do
|
|
76
|
+
@o = @R.new(1, 2, :db_type=>'int4range')
|
|
77
|
+
@o2 = @R.new(1, 2, :db_type=>'int8range')
|
|
78
|
+
@eo = @R.new(nil, nil, :empty=>true, :db_type=>'int4range')
|
|
79
|
+
@eo2 = @R.new(nil, nil, :empty=>true, :db_type=>'int8range')
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should handle multiple range types" do
|
|
83
|
+
%w'int4 int8 num date ts tstz'.each do |i|
|
|
84
|
+
@db.typecast_value(:"#{i}range", @R.new(1, 2, :db_type=>"#{i}range")).should == @R.new(1, 2, :db_type=>"#{i}range")
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should handle multiple array range types" do
|
|
89
|
+
%w'int4 int8 num date ts tstz'.each do |i|
|
|
90
|
+
@db.typecast_value(:"#{i}range_array", [@R.new(1, 2, :db_type=>"#{i}range")]).should be_a_kind_of(Sequel::Postgres::PGArray)
|
|
91
|
+
@db.typecast_value(:"#{i}range_array", [@R.new(1, 2, :db_type=>"#{i}range")]).should == [@R.new(1, 2, :db_type=>"#{i}range")]
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "should return PGRange value as is if they have the same subtype" do
|
|
96
|
+
@db.typecast_value(:int4range, @o).should equal(@o)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "should return new PGRange value as is if they have a different subtype" do
|
|
100
|
+
@db.typecast_value(:int8range, @o).should_not equal(@o)
|
|
101
|
+
@db.typecast_value(:int8range, @o).should == @o2
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "should return new PGRange value as is if they have a different subtype and value is empty" do
|
|
105
|
+
@db.typecast_value(:int8range, @eo).should == @eo2
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "should return new PGRange value if given a Range" do
|
|
109
|
+
@db.typecast_value(:int4range, 1..2).should == @o
|
|
110
|
+
@db.typecast_value(:int4range, 1..2).should_not == @o2
|
|
111
|
+
@db.typecast_value(:int8range, 1..2).should == @o2
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "should parse a string argument as the PostgreSQL output format" do
|
|
115
|
+
@db.typecast_value(:int4range, '[1,2]').should == @o
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "should raise errors for unparsable formats" do
|
|
119
|
+
proc{@db.typecast_value(:int8range, 'foo')}.should raise_error(Sequel::InvalidValue)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "should raise errors for unhandled values" do
|
|
123
|
+
proc{@db.typecast_value(:int4range, 1)}.should raise_error(Sequel::InvalidValue)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "should support registering custom range types" do
|
|
128
|
+
@R.register('foorange')
|
|
129
|
+
@db.typecast_value(:foorange, 1..2).should be_a_kind_of(@R)
|
|
130
|
+
@db.fetch = [{:name=>'id', :db_type=>'foorange'}]
|
|
131
|
+
@db.schema(:items).map{|e| e[1][:type]}.should == [:foorange]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "should support using a block as a custom conversion proc given as block" do
|
|
135
|
+
@R.register('foo2range'){|s| (s*2).to_i}
|
|
136
|
+
@db.typecast_value(:foo2range, '[1,2]').should == (11..22)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "should support using a block as a custom conversion proc given as :converter option" do
|
|
140
|
+
@R.register('foo3range', :converter=>proc{|s| (s*2).to_i})
|
|
141
|
+
@db.typecast_value(:foo3range, '[1,2]').should == (11..22)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "should support using an existing scaler conversion proc via the :subtype_oid option" do
|
|
145
|
+
@R.register('foo4range', :subtype_oid=>16)
|
|
146
|
+
@db.typecast_value(:foo4range, '[t,f]').should == @R.new(true, false, :db_type=>'foo4range')
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "should raise an error if using :subtype_oid option with unexisting scalar conversion proc" do
|
|
150
|
+
proc{@R.register('fooirange', :subtype_oid=>0)}.should raise_error(Sequel::Error)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "should raise an error if using :converter option and a block argument" do
|
|
154
|
+
proc{@R.register('fooirange', :converter=>proc{}){}}.should raise_error(Sequel::Error)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "should raise an error if using :subtype_oid option and a block argument" do
|
|
158
|
+
proc{@R.register('fooirange', :subtype_oid=>16){}}.should raise_error(Sequel::Error)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it "should support registering custom types with :oid option" do
|
|
162
|
+
@R.register('foo5range', :oid=>331)
|
|
163
|
+
Sequel::Postgres::PG_TYPES[331].call('[1,3)').should be_a_kind_of(@R)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
describe "parser" do
|
|
167
|
+
before do
|
|
168
|
+
@p = Sequel::Postgres::PG_TYPES[3904]
|
|
169
|
+
@sp = @R::Parser.new(nil)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "should have db_type method to return the database type string" do
|
|
173
|
+
@p.db_type.should == 'int4range'
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "should have converter method which returns a callable used for conversion" do
|
|
177
|
+
@p.converter.call('1').should == 1
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "should have call parse input string argument into PGRange instance" do
|
|
181
|
+
@p.call('[1,2]').should == @R.new(1, 2, :db_type=>'int4range')
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "should handle empty ranges" do
|
|
185
|
+
@p.call('empty').should == @R.new(nil, nil, :empty=>true, :db_type=>'int4range')
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it "should handle exclusive beginnings and endings" do
|
|
189
|
+
@p.call('(1,3]').should == @R.new(1, 3, :exclude_begin=>true, :db_type=>'int4range')
|
|
190
|
+
@p.call('[1,3)').should == @R.new(1, 3, :exclude_end=>true, :db_type=>'int4range')
|
|
191
|
+
@p.call('(1,3)').should == @R.new(1, 3, :exclude_begin=>true, :exclude_end=>true, :db_type=>'int4range')
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it "should handle unbounded beginnings and endings" do
|
|
195
|
+
@p.call('[,2]').should == @R.new(nil, 2, :db_type=>'int4range')
|
|
196
|
+
@p.call('[1,]').should == @R.new(1, nil, :db_type=>'int4range')
|
|
197
|
+
@p.call('[,]').should == @R.new(nil, nil, :db_type=>'int4range')
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it "should unescape quoted beginnings and endings" do
|
|
201
|
+
@sp.call('["\\\\ \\"","\\" \\\\"]').should == @R.new("\\ \"", "\" \\")
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it "should treat empty quoted string not as unbounded" do
|
|
205
|
+
@sp.call('["","z"]').should == @R.new("", "z")
|
|
206
|
+
@sp.call('["a",""]').should == @R.new("a", "")
|
|
207
|
+
@sp.call('["",""]').should == @R.new("", "")
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it "should set appropriate timestamp range conversion procs when getting conversion procs" do
|
|
212
|
+
procs = @db.conversion_procs
|
|
213
|
+
procs[3908].call('[2011-10-20 11:12:13,2011-10-20 11:12:14]').should == (Time.local(2011, 10, 20, 11, 12, 13)..(Time.local(2011, 10, 20, 11, 12, 14)))
|
|
214
|
+
procs[3910].call('[2011-10-20 11:12:13,2011-10-20 11:12:14]').should == (Time.local(2011, 10, 20, 11, 12, 13)..(Time.local(2011, 10, 20, 11, 12, 14)))
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it "should set appropriate timestamp range array conversion procs when getting conversion procs" do
|
|
218
|
+
procs = @db.conversion_procs
|
|
219
|
+
procs[3909].call('{"[2011-10-20 11:12:13,2011-10-20 11:12:14]"}').should == [Time.local(2011, 10, 20, 11, 12, 13)..Time.local(2011, 10, 20, 11, 12, 14)]
|
|
220
|
+
procs[3911].call('{"[2011-10-20 11:12:13,2011-10-20 11:12:14]"}').should == [Time.local(2011, 10, 20, 11, 12, 13)..Time.local(2011, 10, 20, 11, 12, 14)]
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
describe "a PGRange instance" do
|
|
224
|
+
before do
|
|
225
|
+
@r1 = @R.new(1, 2)
|
|
226
|
+
@r2 = @R.new(3, nil, :exclude_begin=>true, :db_type=>'int4range')
|
|
227
|
+
@r3 = @R.new(nil, 4, :exclude_end=>true, :db_type=>'int8range')
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
it "should have #begin return the beginning of the range" do
|
|
231
|
+
@r1.begin.should == 1
|
|
232
|
+
@r2.begin.should == 3
|
|
233
|
+
@r3.begin.should == nil
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it "should have #end return the end of the range" do
|
|
237
|
+
@r1.end.should == 2
|
|
238
|
+
@r2.end.should == nil
|
|
239
|
+
@r3.end.should == 4
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it "should have #db_type return the range's database type" do
|
|
243
|
+
@r1.db_type.should == nil
|
|
244
|
+
@r2.db_type.should == 'int4range'
|
|
245
|
+
@r3.db_type.should == 'int8range'
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "should be able to be created by Sequel.pg_range" do
|
|
249
|
+
Sequel.pg_range(1..2).should == @r1
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it "should have Sequel.pg_range be able to take a database type" do
|
|
253
|
+
Sequel.pg_range(1..2, :int4range).should == @R.new(1, 2, :db_type=>:int4range)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
it "should have Sequel.pg_range return a PGRange as is" do
|
|
257
|
+
a = Sequel.pg_range(1..2)
|
|
258
|
+
Sequel.pg_range(a).should equal(a)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
it "should have Sequel.pg_range return a new PGRange if the database type differs" do
|
|
262
|
+
a = Sequel.pg_range(1..2, :int4range)
|
|
263
|
+
b = Sequel.pg_range(a, :int8range)
|
|
264
|
+
a.to_range.should == b.to_range
|
|
265
|
+
a.should_not equal(b)
|
|
266
|
+
a.db_type.should == :int4range
|
|
267
|
+
b.db_type.should == :int8range
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it "should have #initialize raise if requesting an empty range with beginning or ending" do
|
|
271
|
+
proc{@R.new(1, nil, :empty=>true)}.should raise_error(Sequel::Error)
|
|
272
|
+
proc{@R.new(nil, 2, :empty=>true)}.should raise_error(Sequel::Error)
|
|
273
|
+
proc{@R.new(nil, nil, :empty=>true, :exclude_begin=>true)}.should raise_error(Sequel::Error)
|
|
274
|
+
proc{@R.new(nil, nil, :empty=>true, :exclude_end=>true)}.should raise_error(Sequel::Error)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
it "should quack like a range" do
|
|
278
|
+
if RUBY_VERSION >= '1.9'
|
|
279
|
+
@r1.cover?(1.5).should be_true
|
|
280
|
+
@r1.cover?(2.5).should be_false
|
|
281
|
+
@r1.first(1).should == [1]
|
|
282
|
+
@r1.last(1).should == [2]
|
|
283
|
+
end
|
|
284
|
+
@r1.to_a.should == [1, 2]
|
|
285
|
+
@r1.first.should == 1
|
|
286
|
+
@r1.last.should == 2
|
|
287
|
+
a = []
|
|
288
|
+
@r1.step{|x| a << x}
|
|
289
|
+
a.should == [1, 2]
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
it "should only consider PGRanges equal if they have the same db_type" do
|
|
293
|
+
@R.new(1, 2, :db_type=>'int4range').should == @R.new(1, 2, :db_type=>'int4range')
|
|
294
|
+
@R.new(1, 2, :db_type=>'int8range').should_not == @R.new(1, 2, :db_type=>'int4range')
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
it "should only consider empty PGRanges equal with other empty PGRanges" do
|
|
298
|
+
@R.new(nil, nil, :empty=>true).should == @R.new(nil, nil, :empty=>true)
|
|
299
|
+
@R.new(nil, nil, :empty=>true).should_not == @R.new(nil, nil)
|
|
300
|
+
@R.new(nil, nil).should_not == @R.new(nil, nil, :empty=>true)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
it "should only consider empty PGRanges equal if they have the same bounds" do
|
|
304
|
+
@R.new(1, 2).should == @R.new(1, 2)
|
|
305
|
+
@R.new(1, 2).should_not == @R.new(1, 3)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
it "should only consider empty PGRanges equal if they have the same bound exclusions" do
|
|
309
|
+
@R.new(1, 2, :exclude_begin=>true).should == @R.new(1, 2, :exclude_begin=>true)
|
|
310
|
+
@R.new(1, 2, :exclude_end=>true).should == @R.new(1, 2, :exclude_end=>true)
|
|
311
|
+
@R.new(1, 2, :exclude_begin=>true).should_not == @R.new(1, 2, :exclude_end=>true)
|
|
312
|
+
@R.new(1, 2, :exclude_end=>true).should_not == @R.new(1, 2, :exclude_begin=>true)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
it "should consider PGRanges equal with a Range they represent" do
|
|
316
|
+
@R.new(1, 2).should == (1..2)
|
|
317
|
+
@R.new(1, 2, :exclude_end=>true).should == (1...2)
|
|
318
|
+
@R.new(1, 3).should_not == (1..2)
|
|
319
|
+
@R.new(1, 2, :exclude_end=>true).should_not == (1..2)
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
it "should not consider a PGRange equal with a Range if it can't be expressed as a range" do
|
|
323
|
+
@R.new(nil, nil).should_not == (1..2)
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
it "should not consider a PGRange equal to other objects" do
|
|
327
|
+
@R.new(nil, nil).should_not == 1
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it "should have #=== be true if given an equal PGRange" do
|
|
331
|
+
@R.new(1, 2).should === @R.new(1, 2)
|
|
332
|
+
@R.new(1, 2).should_not === @R.new(1, 3)
|
|
333
|
+
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
it "should have #=== be true if it would be true for the Range represented by the PGRange" do
|
|
337
|
+
@R.new(1, 2).should === 1.5
|
|
338
|
+
@R.new(1, 2).should_not === 2.5
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
it "should have #=== be false if the PGRange cannot be represented by a Range" do
|
|
342
|
+
@R.new(nil, nil).should_not === 1.5
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
it "should have #empty? indicate whether the range is empty" do
|
|
346
|
+
@R.empty.should be_empty
|
|
347
|
+
@R.new(1, 2).should_not be_empty
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
it "should have #exclude_begin? and #exclude_end indicate whether the beginning or ending of the range is excluded" do
|
|
351
|
+
@r1.exclude_begin?.should be_false
|
|
352
|
+
@r1.exclude_end?.should be_false
|
|
353
|
+
@r2.exclude_begin?.should be_true
|
|
354
|
+
@r2.exclude_end?.should be_false
|
|
355
|
+
@r3.exclude_begin?.should be_false
|
|
356
|
+
@r3.exclude_end?.should be_true
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
it "should have #to_range raise an exception if the PGRange cannot be represented by a Range" do
|
|
360
|
+
proc{@R.new(nil, 1).to_range}.should raise_error(Sequel::Error)
|
|
361
|
+
proc{@R.new(1, nil).to_range}.should raise_error(Sequel::Error)
|
|
362
|
+
proc{@R.new(0, 1, :exclude_begin=>true).to_range}.should raise_error(Sequel::Error)
|
|
363
|
+
proc{@R.empty.to_range}.should raise_error(Sequel::Error)
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
it "should have #to_range return the represented range" do
|
|
367
|
+
@r1.to_range.should == (1..2)
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
it "should have #to_range cache the returned value" do
|
|
371
|
+
@r1.to_range.should equal(@r1.to_range)
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
it "should have #unbounded_begin? and #unbounded_end indicate whether the beginning or ending of the range is unbounded" do
|
|
375
|
+
@r1.unbounded_begin?.should be_false
|
|
376
|
+
@r1.unbounded_end?.should be_false
|
|
377
|
+
@r2.unbounded_begin?.should be_false
|
|
378
|
+
@r2.unbounded_end?.should be_true
|
|
379
|
+
@r3.unbounded_begin?.should be_true
|
|
380
|
+
@r3.unbounded_end?.should be_false
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
it "should have #valid_ruby_range? return true if the PGRange can be represented as a Range" do
|
|
384
|
+
@r1.valid_ruby_range?.should be_true
|
|
385
|
+
@R.new(1, 2, :exclude_end=>true).valid_ruby_range?.should be_true
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
it "should have #valid_ruby_range? return false if the PGRange cannot be represented as a Range" do
|
|
389
|
+
@R.new(nil, 1).valid_ruby_range?.should be_false
|
|
390
|
+
@R.new(1, nil).valid_ruby_range?.should be_false
|
|
391
|
+
@R.new(0, 1, :exclude_begin=>true).valid_ruby_range?.should be_false
|
|
392
|
+
@R.empty.valid_ruby_range?.should be_false
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "Sequel::Postgres::PGRowOp" do
|
|
4
|
+
before do
|
|
5
|
+
@db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
|
|
6
|
+
@a = Sequel.pg_row_op(:a)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "#[] should access members of the composite type" do
|
|
10
|
+
@db.literal(@a[:b]).should == "(a).b"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "#[] should be chainable" do
|
|
14
|
+
@db.literal(@a[:b][:c]).should == "((a).b).c"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "#[] should support array access if not given an identifier" do
|
|
18
|
+
@db.literal(@a[:b][1]).should == "(a).b[1]"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "#[] should be chainable with array access" do
|
|
22
|
+
@db.literal(@a[1][:b]).should == "(a[1]).b"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "#splat should return a splatted argument inside parentheses" do
|
|
26
|
+
@db.literal(@a.splat).should == "(a.*)"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "#splat(type) should return a splatted argument cast to given type" do
|
|
30
|
+
@db.literal(@a.splat(:b)).should == "(a.*)::b"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "#splat should not work on an already accessed composite type" do
|
|
34
|
+
proc{@a[:a].splat(:b)}.should raise_error(Sequel::Error)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "#* should reference all members of the composite type as separate columns if given no arguments" do
|
|
38
|
+
@db.literal(@a.*).should == "(a).*"
|
|
39
|
+
@db.literal(@a[:b].*).should == "((a).b).*"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "#* should use a multiplication operation if any arguments are given" do
|
|
43
|
+
@db.literal(@a.*(1)).should == "(a * 1)"
|
|
44
|
+
@db.literal(@a[:b].*(1)).should == "((a).b * 1)"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "#pg_row should be callable on literal strings" do
|
|
48
|
+
@db.literal(Sequel.lit('a').pg_row[:b]).should == "(a).b"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "#pg_row should be callable on Sequel expressions" do
|
|
52
|
+
@db.literal(Sequel.function(:a).pg_row[:b]).should == "(a()).b"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "Sequel.pg_row should work as well if the pg_row extension is loaded" do
|
|
56
|
+
@db.literal(Sequel.pg_row(Sequel.function(:a))[:b]).should == "(a()).b"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "Sequel::Plugins::PgRow" do
|
|
4
|
+
before(:all) do
|
|
5
|
+
@db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
|
|
6
|
+
@db.extension(:pg_array)
|
|
7
|
+
@c = Class.new(Sequel::Model(@db[:address]))
|
|
8
|
+
@c.columns :street, :city
|
|
9
|
+
@c.db_schema[:street][:type] = :string
|
|
10
|
+
@c.db_schema[:city][:type] = :string
|
|
11
|
+
@db.fetch = [[{:oid=>1098, :typrelid=>2, :typarray=>3}], [{:attname=>'street', :atttypid=>1324}, {:attname=>'city', :atttypid=>1324}]]
|
|
12
|
+
@c.plugin :pg_row
|
|
13
|
+
|
|
14
|
+
@c2 = Class.new(Sequel::Model(@db[:company]))
|
|
15
|
+
@c2.columns :address
|
|
16
|
+
@c2.db_schema[:address].merge!(:type=>:pg_row_address)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should set up a parser for the type that creates a model class" do
|
|
20
|
+
@db.conversion_procs[1098].call('(123 Foo St,Bar City)').should == @c.load(:street=>'123 Foo St', :city=>'Bar City')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should set up type casting for the type" do
|
|
24
|
+
@c2.new(:address=>{'street'=>123, 'city'=>:Bar}).address.should == @c.load(:street=>'123', :city=>'Bar')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should return model instances as is when typecasting to rows" do
|
|
28
|
+
o = @c.load(:street=>'123', :city=>'Bar')
|
|
29
|
+
@c2.new(:address=>o).address.should equal(o)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should handle literalizing model instances" do
|
|
33
|
+
@db.literal(@c.load(:street=>'123 Foo St', :city=>'Bar City')).should == "ROW('123 Foo St', 'Bar City')::address"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should handle model instances in bound variables" do
|
|
37
|
+
@db.bound_variable_arg(1, nil).should == 1
|
|
38
|
+
@db.bound_variable_arg(@c.load(:street=>'123 Foo St', :city=>'Bar City'), nil).should == '("123 Foo St","Bar City")'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should handle model instances in arrays of bound variables" do
|
|
42
|
+
@db.bound_variable_arg(1, nil).should == 1
|
|
43
|
+
@db.bound_variable_arg(Sequel.pg_array([@c.load(:street=>'123 Foo St', :city=>'Bar City')]), nil).should == '{"(\\"123 Foo St\\",\\"Bar City\\")"}'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "should allow inserting just this model value" do
|
|
47
|
+
@c2.insert_sql(@c.load(:street=>'123', :city=>'Bar')).should == "INSERT INTO company VALUES (ROW('123', 'Bar')::address)"
|
|
48
|
+
end
|
|
49
|
+
end
|