sequel 4.47.0 → 4.48.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +134 -0
- data/Rakefile +1 -1
- data/doc/release_notes/4.48.0.txt +293 -0
- data/lib/sequel/adapters/ado/access.rb +2 -1
- data/lib/sequel/adapters/do/postgres.rb +5 -2
- data/lib/sequel/adapters/ibmdb.rb +24 -7
- data/lib/sequel/adapters/jdbc.rb +36 -22
- data/lib/sequel/adapters/jdbc/db2.rb +12 -3
- data/lib/sequel/adapters/jdbc/derby.rb +4 -5
- data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +43 -18
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +11 -4
- data/lib/sequel/adapters/mock.rb +24 -19
- data/lib/sequel/adapters/mysql.rb +17 -16
- data/lib/sequel/adapters/mysql2.rb +4 -5
- data/lib/sequel/adapters/oracle.rb +5 -9
- data/lib/sequel/adapters/postgres.rb +89 -102
- data/lib/sequel/adapters/shared/db2.rb +22 -6
- data/lib/sequel/adapters/shared/mssql.rb +5 -4
- data/lib/sequel/adapters/shared/mysql.rb +75 -24
- data/lib/sequel/adapters/shared/postgres.rb +196 -94
- data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
- data/lib/sequel/adapters/shared/sqlite.rb +72 -82
- data/lib/sequel/adapters/sqlanywhere.rb +4 -1
- data/lib/sequel/adapters/sqlite.rb +5 -3
- data/lib/sequel/adapters/swift/postgres.rb +5 -2
- data/lib/sequel/adapters/tinytds.rb +0 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/adapters/utils/pg_types.rb +2 -76
- data/lib/sequel/core.rb +2 -2
- data/lib/sequel/database/connecting.rb +5 -5
- data/lib/sequel/database/dataset.rb +6 -3
- data/lib/sequel/database/misc.rb +1 -1
- data/lib/sequel/database/query.rb +3 -0
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset/actions.rb +18 -10
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/misc.rb +1 -0
- data/lib/sequel/dataset/prepared_statements.rb +3 -3
- data/lib/sequel/dataset/query.rb +19 -8
- data/lib/sequel/extensions/core_extensions.rb +4 -1
- data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
- data/lib/sequel/extensions/filter_having.rb +2 -0
- data/lib/sequel/extensions/freeze_datasets.rb +2 -0
- data/lib/sequel/extensions/from_block.rb +1 -1
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/hash_aliases.rb +2 -0
- data/lib/sequel/extensions/identifier_mangling.rb +0 -7
- data/lib/sequel/extensions/meta_def.rb +2 -0
- data/lib/sequel/extensions/migration.rb +6 -6
- data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +207 -130
- data/lib/sequel/extensions/pg_hstore.rb +38 -20
- data/lib/sequel/extensions/pg_inet.rb +18 -6
- data/lib/sequel/extensions/pg_interval.rb +19 -12
- data/lib/sequel/extensions/pg_json.rb +25 -14
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/extensions/pg_range.rb +133 -100
- data/lib/sequel/extensions/pg_range_ops.rb +4 -3
- data/lib/sequel/extensions/pg_row.rb +68 -39
- data/lib/sequel/extensions/pg_row_ops.rb +11 -5
- data/lib/sequel/extensions/query_literals.rb +2 -0
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
- data/lib/sequel/extensions/s.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +24 -24
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
- data/lib/sequel/extensions/set_overrides.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +0 -1
- data/lib/sequel/extensions/symbol_aref.rb +0 -4
- data/lib/sequel/model.rb +25 -57
- data/lib/sequel/model/associations.rb +14 -5
- data/lib/sequel/model/base.rb +96 -32
- data/lib/sequel/plugins/association_pks.rb +73 -46
- data/lib/sequel/plugins/association_proxies.rb +1 -1
- data/lib/sequel/plugins/auto_validations.rb +6 -2
- data/lib/sequel/plugins/boolean_readers.rb +1 -1
- data/lib/sequel/plugins/caching.rb +19 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +19 -10
- data/lib/sequel/plugins/column_conflicts.rb +7 -2
- data/lib/sequel/plugins/column_select.rb +1 -1
- data/lib/sequel/plugins/csv_serializer.rb +8 -8
- data/lib/sequel/plugins/defaults_setter.rb +10 -0
- data/lib/sequel/plugins/eager_each.rb +1 -1
- data/lib/sequel/plugins/force_encoding.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +9 -12
- data/lib/sequel/plugins/identifier_columns.rb +2 -0
- data/lib/sequel/plugins/instance_filters.rb +3 -1
- data/lib/sequel/plugins/instance_hooks.rb +17 -9
- data/lib/sequel/plugins/json_serializer.rb +17 -10
- data/lib/sequel/plugins/lazy_attributes.rb +8 -7
- data/lib/sequel/plugins/modification_detection.rb +3 -0
- data/lib/sequel/plugins/nested_attributes.rb +5 -1
- data/lib/sequel/plugins/pg_array_associations.rb +5 -0
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/plugins/rcte_tree.rb +4 -4
- data/lib/sequel/plugins/serialization.rb +3 -10
- data/lib/sequel/plugins/single_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/split_values.rb +6 -5
- data/lib/sequel/plugins/static_cache.rb +31 -25
- data/lib/sequel/plugins/subset_conditions.rb +3 -1
- data/lib/sequel/plugins/table_select.rb +1 -1
- data/lib/sequel/plugins/touch.rb +2 -1
- data/lib/sequel/plugins/validation_class_methods.rb +5 -6
- data/lib/sequel/plugins/validation_helpers.rb +2 -4
- data/lib/sequel/plugins/xml_serializer.rb +4 -4
- data/lib/sequel/sql.rb +2 -2
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +115 -14
- data/spec/adapters/mysql_spec.rb +78 -28
- data/spec/adapters/oracle_spec.rb +24 -24
- data/spec/adapters/postgres_spec.rb +38 -24
- data/spec/adapters/sqlanywhere_spec.rb +88 -86
- data/spec/adapters/sqlite_spec.rb +29 -24
- data/spec/core/connection_pool_spec.rb +17 -0
- data/spec/core/database_spec.rb +6 -0
- data/spec/core/dataset_spec.rb +46 -36
- data/spec/core/schema_spec.rb +16 -0
- data/spec/core/spec_helper.rb +1 -0
- data/spec/core_extensions_spec.rb +6 -2
- data/spec/extensions/active_model_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +34 -2
- data/spec/extensions/auto_literal_strings_spec.rb +5 -1
- data/spec/extensions/auto_validations_spec.rb +2 -0
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +48 -2
- data/spec/extensions/column_conflicts_spec.rb +11 -0
- data/spec/extensions/connection_validator_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +8 -8
- data/spec/extensions/defaults_setter_spec.rb +1 -1
- data/spec/extensions/filter_having_spec.rb +5 -3
- data/spec/extensions/hash_aliases_spec.rb +3 -1
- data/spec/extensions/identifier_columns_spec.rb +3 -1
- data/spec/extensions/implicit_subquery_spec.rb +4 -2
- data/spec/extensions/json_serializer_spec.rb +18 -0
- data/spec/extensions/lazy_attributes_spec.rb +3 -3
- data/spec/extensions/meta_def_spec.rb +9 -0
- data/spec/extensions/migration_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +14 -3
- data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
- data/spec/extensions/pg_array_associations_spec.rb +29 -18
- data/spec/extensions/pg_array_spec.rb +44 -25
- data/spec/extensions/pg_hstore_spec.rb +10 -0
- data/spec/extensions/pg_inet_spec.rb +26 -0
- data/spec/extensions/pg_interval_spec.rb +20 -0
- data/spec/extensions/pg_json_spec.rb +24 -0
- data/spec/extensions/pg_range_spec.rb +98 -14
- data/spec/extensions/pg_row_spec.rb +14 -4
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +3 -1
- data/spec/extensions/schema_dumper_spec.rb +96 -98
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
- data/spec/extensions/single_table_inheritance_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/static_cache_spec.rb +75 -24
- data/spec/extensions/string_agg_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +9 -0
- data/spec/extensions/validation_helpers_spec.rb +9 -3
- data/spec/extensions/whitelist_security_spec.rb +26 -0
- data/spec/integration/dataset_test.rb +45 -44
- data/spec/integration/plugin_test.rb +20 -0
- data/spec/integration/prepared_statement_test.rb +3 -0
- data/spec/integration/schema_test.rb +21 -1
- data/spec/integration/transaction_test.rb +40 -40
- data/spec/model/class_dataset_methods_spec.rb +14 -4
- data/spec/model/dataset_methods_spec.rb +12 -3
- data/spec/model/model_spec.rb +8 -0
- metadata +6 -4
- data/spec/adapters/firebird_spec.rb +0 -405
- data/spec/adapters/informix_spec.rb +0 -100
@@ -1,6 +1,15 @@
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
2
|
|
3
3
|
describe "Sequel::Metaprogramming" do
|
4
|
+
before do
|
5
|
+
deprecated do
|
6
|
+
Sequel.extension :meta_def
|
7
|
+
end
|
8
|
+
end
|
9
|
+
after do
|
10
|
+
Sequel::Metaprogramming.send(:remove_method, :meta_def)
|
11
|
+
end
|
12
|
+
|
4
13
|
it "should add meta_def method to Database, Dataset, and Model classes and instances" do
|
5
14
|
Sequel::Database.meta_def(:foo){1}
|
6
15
|
Sequel::Database.foo.must_equal 1
|
@@ -429,13 +429,13 @@ describe "Sequel::IntegerMigrator" do
|
|
429
429
|
end
|
430
430
|
|
431
431
|
it "should use transactions by default if the database supports transactional ddl" do
|
432
|
-
@db.
|
432
|
+
def @db.supports_transactional_ddl?; true end
|
433
433
|
Sequel::Migrator.apply(@db, "spec/files/transaction_unspecified_migrations")
|
434
434
|
@db.sqls.must_equal ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2", "COMMIT"]
|
435
435
|
end
|
436
436
|
|
437
437
|
it "should respect transaction use on a per migration basis" do
|
438
|
-
@db.
|
438
|
+
def @db.supports_transactional_ddl?; true end
|
439
439
|
Sequel::Migrator.apply(@db, "spec/files/transaction_specified_migrations")
|
440
440
|
@db.sqls.must_equal ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "COMMIT", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2"]
|
441
441
|
end
|
@@ -753,7 +753,7 @@ describe "Sequel::TimestampMigrator" do
|
|
753
753
|
end
|
754
754
|
|
755
755
|
it "should use transactions by default if database supports transactional ddl" do
|
756
|
-
@db.
|
756
|
+
def @db.supports_transactional_ddl?; true end
|
757
757
|
Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_unspecified_migrations")
|
758
758
|
@db.sqls.must_equal ["SELECT NULL AS nil FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL AS nil FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')", "COMMIT"]
|
759
759
|
end
|
@@ -462,7 +462,7 @@ describe "NestedAttributes plugin" do
|
|
462
462
|
ar.set(:albums_attributes=>[{:id=>10, :_delete=>'t'}])
|
463
463
|
end
|
464
464
|
|
465
|
-
|
465
|
+
deprecated "should not raise an Error if an unmatched primary key is given, if the :strict=>false option is used" do
|
466
466
|
@Artist.nested_attributes :albums, :strict=>false
|
467
467
|
al = @Album.load(:id=>10, :name=>'Al')
|
468
468
|
ar = @Artist.load(:id=>20, :name=>'Ar')
|
@@ -492,7 +492,7 @@ describe "NestedAttributes plugin" do
|
|
492
492
|
ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :_delete=>'t'}])
|
493
493
|
end
|
494
494
|
|
495
|
-
|
495
|
+
deprecated "should not raise an Error if an unmatched composite primary key is given, if the :strict=>false option is used" do
|
496
496
|
@Artist.nested_attributes :concerts, :strict=>false
|
497
497
|
ar = @Artist.load(:id=>10, :name=>'Ar')
|
498
498
|
co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
|
@@ -503,6 +503,17 @@ describe "NestedAttributes plugin" do
|
|
503
503
|
@db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 10)"]
|
504
504
|
end
|
505
505
|
|
506
|
+
it "should not raise an Error if an unmatched composite primary key is given, if the :unmatched_pk=>:ignore option is used" do
|
507
|
+
@Artist.nested_attributes :concerts, :unmatched_pk=>:ignore
|
508
|
+
ar = @Artist.load(:id=>10, :name=>'Ar')
|
509
|
+
co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
|
510
|
+
ar.associations[:concerts] = [co]
|
511
|
+
ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-06', :_delete=>'t'}])
|
512
|
+
@db.sqls.must_equal []
|
513
|
+
ar.save
|
514
|
+
@db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 10)"]
|
515
|
+
end
|
516
|
+
|
506
517
|
it "should not save if nested attribute is not valid and should include nested attribute validation errors in the main object's validation errors" do
|
507
518
|
@Artist.class_eval do
|
508
519
|
def validate
|
@@ -604,7 +615,7 @@ describe "NestedAttributes plugin" do
|
|
604
615
|
end
|
605
616
|
|
606
617
|
it "should return objects created/modified in the internal methods" do
|
607
|
-
@Album.nested_attributes :tags, :remove=>true, :
|
618
|
+
@Album.nested_attributes :tags, :remove=>true, :unmatched_pk=>:ignore
|
608
619
|
objs = []
|
609
620
|
@Album.class_eval do
|
610
621
|
define_method(:nested_attributes_create){|*a| objs << [super(*a), :create]}
|
@@ -9,9 +9,11 @@ describe "no_auto_literal_strings extension" do
|
|
9
9
|
proc{@ds.where("a")}.must_raise Sequel::Error
|
10
10
|
proc{@ds.having("a")}.must_raise Sequel::Error
|
11
11
|
proc{@ds.filter("a")}.must_raise Sequel::Error
|
12
|
-
proc{@ds.exclude_where("a")}.must_raise Sequel::Error
|
13
12
|
proc{@ds.exclude_having("a")}.must_raise Sequel::Error
|
14
|
-
|
13
|
+
deprecated do
|
14
|
+
proc{@ds.exclude_where("a")}.must_raise Sequel::Error
|
15
|
+
proc{@ds.and("a")}.must_raise Sequel::Error
|
16
|
+
end
|
15
17
|
proc{@ds.where(:a).or("a")}.must_raise Sequel::Error
|
16
18
|
proc{@ds.first("a")}.must_raise Sequel::Error
|
17
19
|
proc{@ds.order(:a).last("a")}.must_raise Sequel::Error
|
@@ -26,9 +28,11 @@ describe "no_auto_literal_strings extension" do
|
|
26
28
|
@ds.where(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t WHERE (a)'
|
27
29
|
@ds.having(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t HAVING (a)'
|
28
30
|
@ds.filter(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t WHERE (a)'
|
29
|
-
@ds.exclude_where(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t WHERE NOT (a)'
|
30
31
|
@ds.exclude_having(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t HAVING NOT (a)'
|
31
|
-
|
32
|
+
deprecated do
|
33
|
+
@ds.exclude_where(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t WHERE NOT (a)'
|
34
|
+
@ds.and(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t WHERE (a)'
|
35
|
+
end
|
32
36
|
@ds.where(:a).or(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t WHERE (a OR (a))'
|
33
37
|
@ds.first(Sequel.lit("a"))
|
34
38
|
@ds.order(:a).last(Sequel.lit("a"))
|
@@ -2,7 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
2
|
|
3
3
|
describe Sequel::Model, "pg_array_associations" do
|
4
4
|
before do
|
5
|
-
@db = Sequel.mock(:numrows=>1)
|
5
|
+
@db = Sequel.mock(:host=>'postgres', :numrows=>1)
|
6
6
|
@db.extend_datasets{def quote_identifiers?; false end}
|
7
7
|
class ::Artist < Sequel::Model(@db)
|
8
8
|
attr_accessor :yyy
|
@@ -71,7 +71,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
71
71
|
end
|
72
72
|
|
73
73
|
it "should allowing filtering by associations with :conditions" do
|
74
|
-
@c1.filter(:a_tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id = 2)))),
|
74
|
+
@c1.filter(:a_tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id = 2)))), false)"
|
75
75
|
@c2.filter(:a_artists=>@o1).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id = 1))))"
|
76
76
|
end
|
77
77
|
|
@@ -81,7 +81,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
81
81
|
end
|
82
82
|
|
83
83
|
it "should allowing excluding by associations with :conditions" do
|
84
|
-
@c1.exclude(:a_tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id = 2)))),
|
84
|
+
@c1.exclude(:a_tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id = 2)))), false) OR (artists.tag_ids IS NULL))"
|
85
85
|
@c2.exclude(:a_artists=>@o1).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id = 1)))) OR (tags.id IS NULL))"
|
86
86
|
end
|
87
87
|
|
@@ -91,7 +91,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
91
91
|
end
|
92
92
|
|
93
93
|
it "should allowing filtering by multiple associations with :conditions" do
|
94
|
-
@c1.filter(:a_tags=>[@c2.load(:id=>1), @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (1, 2))))),
|
94
|
+
@c1.filter(:a_tags=>[@c2.load(:id=>1), @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (1, 2))))), false)"
|
95
95
|
@c2.filter(:a_artists=>[@c1.load(:id=>7, :tag_ids=>Sequel.pg_array([3, 4])), @c1.load(:id=>8, :tag_ids=>Sequel.pg_array([4, 5]))]).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id IN (7, 8)))))"
|
96
96
|
end
|
97
97
|
|
@@ -101,40 +101,40 @@ describe Sequel::Model, "pg_array_associations" do
|
|
101
101
|
end
|
102
102
|
|
103
103
|
it "should allowing excluding by multiple associations with :conditions" do
|
104
|
-
@c1.exclude(:a_tags=>[@c2.load(:id=>1), @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (1, 2))))),
|
104
|
+
@c1.exclude(:a_tags=>[@c2.load(:id=>1), @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (1, 2))))), false) OR (artists.tag_ids IS NULL))"
|
105
105
|
@c2.exclude(:a_artists=>[@c1.load(:id=>7, :tag_ids=>Sequel.pg_array([3, 4])), @c1.load(:id=>8, :tag_ids=>Sequel.pg_array([4, 5]))]).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id IN (7, 8))))) OR (tags.id IS NULL))"
|
106
106
|
end
|
107
107
|
|
108
108
|
it "should allowing filtering/excluding associations with NULL or empty values" do
|
109
|
-
@c1.filter(:tags=>@c2.new).sql.must_equal 'SELECT * FROM artists WHERE
|
110
|
-
@c1.exclude(:tags=>@c2.new).sql.must_equal 'SELECT * FROM artists WHERE
|
111
|
-
@c2.filter(:artists=>@c1.new).sql.must_equal 'SELECT * FROM tags WHERE
|
112
|
-
@c2.exclude(:artists=>@c1.new).sql.must_equal 'SELECT * FROM tags WHERE
|
109
|
+
@c1.filter(:tags=>@c2.new).sql.must_equal 'SELECT * FROM artists WHERE false'
|
110
|
+
@c1.exclude(:tags=>@c2.new).sql.must_equal 'SELECT * FROM artists WHERE true'
|
111
|
+
@c2.filter(:artists=>@c1.new).sql.must_equal 'SELECT * FROM tags WHERE false'
|
112
|
+
@c2.exclude(:artists=>@c1.new).sql.must_equal 'SELECT * FROM tags WHERE true'
|
113
113
|
|
114
|
-
@c2.filter(:artists=>@c1.load(:tag_ids=>[])).sql.must_equal 'SELECT * FROM tags WHERE
|
115
|
-
@c2.exclude(:artists=>@c1.load(:tag_ids=>[])).sql.must_equal 'SELECT * FROM tags WHERE
|
114
|
+
@c2.filter(:artists=>@c1.load(:tag_ids=>[])).sql.must_equal 'SELECT * FROM tags WHERE false'
|
115
|
+
@c2.exclude(:artists=>@c1.load(:tag_ids=>[])).sql.must_equal 'SELECT * FROM tags WHERE true'
|
116
116
|
|
117
117
|
@c1.filter(:tags=>[@c2.new, @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[2]::integer[])"
|
118
118
|
@c2.filter(:artists=>[@c1.load(:tag_ids=>Sequel.pg_array([3, 4])), @c1.new]).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (3, 4))"
|
119
119
|
end
|
120
120
|
|
121
121
|
it "should allowing filtering by association datasets" do
|
122
|
-
@c1.filter(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE (id = 1))),
|
122
|
+
@c1.filter(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE (id = 1))), false)"
|
123
123
|
@c2.filter(:artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (SELECT unnest(artists.tag_ids) FROM artists WHERE (id = 1)))"
|
124
124
|
end
|
125
125
|
|
126
126
|
it "should allowing filtering by association datasets with :conditions" do
|
127
|
-
@c1.filter(:a_tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (id = 1)))))),
|
127
|
+
@c1.filter(:a_tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (id = 1)))))), false)"
|
128
128
|
@c2.filter(:a_artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id IN (SELECT artists.id FROM artists WHERE (id = 1))))))"
|
129
129
|
end
|
130
130
|
|
131
131
|
it "should allowing excluding by association datasets" do
|
132
|
-
@c1.exclude(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE (id = 1))),
|
132
|
+
@c1.exclude(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE (id = 1))), false) OR (artists.tag_ids IS NULL))"
|
133
133
|
@c2.exclude(:artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (SELECT unnest(artists.tag_ids) FROM artists WHERE (id = 1))) OR (tags.id IS NULL))"
|
134
134
|
end
|
135
135
|
|
136
136
|
it "should allowing excluding by association datasets with :conditions" do
|
137
|
-
@c1.exclude(:a_tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (id = 1)))))),
|
137
|
+
@c1.exclude(:a_tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (id = 1)))))), false) OR (artists.tag_ids IS NULL))"
|
138
138
|
@c2.exclude(:a_artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id IN (SELECT artists.id FROM artists WHERE (id = 1)))))) OR (tags.id IS NULL))"
|
139
139
|
end
|
140
140
|
|
@@ -145,7 +145,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
145
145
|
|
146
146
|
@c1.filter(:tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE (artists.tag_ids[1:2] @> ARRAY[6]::integer[])"
|
147
147
|
@c2.filter(:artists=>@o1).sql.must_equal "SELECT * FROM tags WHERE ((tags.id * 3) IN (3, 6, 9))"
|
148
|
-
@c1.filter(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids[1:2] && (SELECT array_agg((tags.id * 3)) FROM tags WHERE (id = 1))),
|
148
|
+
@c1.filter(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids[1:2] && (SELECT array_agg((tags.id * 3)) FROM tags WHERE (id = 1))), false)"
|
149
149
|
@c2.filter(:artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE ((tags.id * 3) IN (SELECT unnest(artists.tag_ids[1:2]) FROM artists WHERE (id = 1)))"
|
150
150
|
end
|
151
151
|
|
@@ -315,6 +315,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
315
315
|
|
316
316
|
@c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]))
|
317
317
|
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]))
|
318
|
+
@db.sqls
|
318
319
|
|
319
320
|
@o1.tags2.must_equal [@o2]
|
320
321
|
@db.sqls.first.must_match(/SELECT tags\.id, artists\.id AS artists_id, artists\.tag_ids FROM tags LEFT OUTER JOIN artists ON \(artists.tag_ids @> ARRAY\[tags.id\]\) WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
|
@@ -328,6 +329,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
328
329
|
|
329
330
|
@c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]))
|
330
331
|
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :tag_ids=>Sequel.pg_array([1,2,3]))
|
332
|
+
@db.sqls
|
331
333
|
|
332
334
|
a = @c1.eager(:tags2).all
|
333
335
|
sqls = @db.sqls
|
@@ -340,6 +342,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
340
342
|
|
341
343
|
@c2.dataset = @c2.dataset.with_fetch(:id=>2)
|
342
344
|
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]))
|
345
|
+
@db.sqls
|
343
346
|
|
344
347
|
a = @c2.eager(:artists2).all
|
345
348
|
@db.sqls.must_equal ["SELECT * FROM tags", "SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id]) WHERE (artists.tag_ids && ARRAY[2]::integer[])"]
|
@@ -351,6 +354,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
351
354
|
|
352
355
|
it "should respect the :limit option when eager loading" do
|
353
356
|
@c2.dataset = @c2.dataset.with_fetch([{:id=>1},{:id=>2}, {:id=>3}])
|
357
|
+
@db.sqls
|
354
358
|
|
355
359
|
@c1.pg_array_to_many :tags, :clone=>:tags, :limit=>2
|
356
360
|
a = @c1.eager(:tags).all
|
@@ -381,6 +385,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
381
385
|
|
382
386
|
@c2.dataset = @c2.dataset.with_fetch(:id=>2)
|
383
387
|
@c1.dataset = @c1.dataset.with_fetch([{:id=>5, :tag_ids=>Sequel.pg_array([1,2,3])},{:id=>6, :tag_ids=>Sequel.pg_array([2,3])}, {:id=>7, :tag_ids=>Sequel.pg_array([1,2])}])
|
388
|
+
@db.sqls
|
384
389
|
|
385
390
|
@c2.many_to_pg_array :artists, :clone=>:artists, :limit=>2
|
386
391
|
a = @c2.eager(:artists).all
|
@@ -417,6 +422,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
417
422
|
it "should eagerly graph associations" do
|
418
423
|
@c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]))
|
419
424
|
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]))
|
425
|
+
@db.sqls
|
420
426
|
|
421
427
|
a = @c1.eager_graph(:tags).all
|
422
428
|
@db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id])"]
|
@@ -434,6 +440,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
434
440
|
it "should allow cascading of eager graphing for associations of associated models" do
|
435
441
|
@c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]), :tags_0_id=>2)
|
436
442
|
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]), :artists_0_id=>1, :artists_0_tag_ids=>Sequel.pg_array([1,2,3]))
|
443
|
+
@db.sqls
|
437
444
|
|
438
445
|
a = @c1.eager_graph(:tags=>:artists).all
|
439
446
|
@db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id AS tags_id, artists_0.id AS artists_0_id, artists_0.tag_ids AS artists_0_tag_ids FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id]) LEFT OUTER JOIN artists AS artists_0 ON (artists_0.tag_ids @> ARRAY[tags.id])"]
|
@@ -457,6 +464,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
457
464
|
|
458
465
|
@c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]), :tags_0_id=>2)
|
459
466
|
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]), :artists_0_id=>1, :artists_0_tag_ids=>Sequel.pg_array([1,2,3]))
|
467
|
+
@db.sqls
|
460
468
|
|
461
469
|
a = @c1.eager_graph(:tags).all
|
462
470
|
a.must_equal [@o1]
|
@@ -477,6 +485,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
477
485
|
|
478
486
|
@c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1)
|
479
487
|
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :id2=>2, :tag_ids=>Sequel.pg_array([1,2,3]))
|
488
|
+
@db.sqls
|
480
489
|
|
481
490
|
a = @c1.eager_graph(:tags).all
|
482
491
|
@db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id2 FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id])"]
|
@@ -738,15 +747,17 @@ end
|
|
738
747
|
|
739
748
|
describe "Sequel::Model.finalize_associations" do
|
740
749
|
before do
|
741
|
-
|
750
|
+
@db = Sequel.mock(:host=>'postgres', :numrows=>1)
|
751
|
+
class ::Foo < Sequel::Model(@db)
|
742
752
|
plugin :pg_array_associations
|
743
753
|
many_to_pg_array :items
|
744
754
|
end
|
745
|
-
class ::Item < Sequel::Model
|
755
|
+
class ::Item < Sequel::Model(@db)
|
746
756
|
plugin :pg_array_associations
|
747
757
|
pg_array_to_many :foos
|
748
758
|
end
|
749
759
|
[Foo, Item].each(&:finalize_associations)
|
760
|
+
@db.sqls
|
750
761
|
end
|
751
762
|
after do
|
752
763
|
Object.send(:remove_const, :Item)
|
@@ -3,10 +3,10 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
3
3
|
describe "pg_array extension" do
|
4
4
|
before(:all) do
|
5
5
|
Sequel.extension :pg_array
|
6
|
-
@pg_types = Sequel::Postgres::
|
6
|
+
@pg_types = Sequel::Postgres::PG__TYPES.dup # SEQUEL5: Remove
|
7
7
|
end
|
8
8
|
after(:all) do
|
9
|
-
Sequel::Postgres::
|
9
|
+
Sequel::Postgres::PG__TYPES.replace(@pg_types) # SEQUEL5: Remove
|
10
10
|
end
|
11
11
|
|
12
12
|
before do
|
@@ -18,7 +18,7 @@ describe "pg_array extension" do
|
|
18
18
|
end)
|
19
19
|
@db.extension(:pg_array)
|
20
20
|
@m = Sequel::Postgres
|
21
|
-
@converter = @
|
21
|
+
@converter = @db.conversion_procs
|
22
22
|
@db.sqls
|
23
23
|
end
|
24
24
|
|
@@ -34,6 +34,11 @@ describe "pg_array extension" do
|
|
34
34
|
c.call('{a,b}').to_a.must_equal ['a', 'b']
|
35
35
|
end
|
36
36
|
|
37
|
+
it "should preserve encoding when parsing text arrays" do
|
38
|
+
c = @converter[1009]
|
39
|
+
c.call("{a,\u00E4}".encode('ISO-8859-1')).map(&:encoding).must_equal [Encoding::ISO_8859_1, Encoding::ISO_8859_1]
|
40
|
+
end if RUBY_VERSION >= '1.9'
|
41
|
+
|
37
42
|
it "should parse multi-dimensional text arrays" do
|
38
43
|
c = @converter[1009]
|
39
44
|
c.call("{{}}").to_a.must_equal [[]]
|
@@ -256,42 +261,53 @@ describe "pg_array extension" do
|
|
256
261
|
@db.select(Sequel.pg_array([1], :integer).as(:col1)).sql.must_equal 'SELECT ARRAY[1]::integer[] AS col1'
|
257
262
|
end
|
258
263
|
|
259
|
-
|
264
|
+
deprecated "should support registering custom array types" do
|
260
265
|
Sequel::Postgres::PGArray.register('foo')
|
261
266
|
@db.typecast_value(:foo_array, []).class.must_equal(Sequel::Postgres::PGArray)
|
262
267
|
@db.fetch = [{:name=>'id', :db_type=>'foo[]'}]
|
263
268
|
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:foo_array]
|
264
269
|
end
|
265
270
|
|
271
|
+
deprecated "should raise error if register given convertor option and block" do
|
272
|
+
proc{Sequel::Postgres::PGArray.register('foo', :converter=>:to_s.to_proc, &:to_s)}.must_raise Sequel::Error
|
273
|
+
end
|
274
|
+
|
275
|
+
it "should support registering custom array types" do
|
276
|
+
@db.register_array_type('foo')
|
277
|
+
@db.typecast_value(:foo_array, []).class.must_equal(Sequel::Postgres::PGArray)
|
278
|
+
@db.fetch = [{:name=>'id', :db_type=>'foo[]'}]
|
279
|
+
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:foo_array]
|
280
|
+
end
|
281
|
+
|
266
282
|
it "should support registering custom types with :type_symbol option" do
|
267
|
-
|
283
|
+
@db.register_array_type('foo', :type_symbol=>:bar)
|
268
284
|
@db.typecast_value(:bar_array, []).class.must_equal(Sequel::Postgres::PGArray)
|
269
285
|
@db.fetch = [{:name=>'id', :db_type=>'foo[]'}]
|
270
286
|
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:bar_array]
|
271
287
|
end
|
272
288
|
|
273
289
|
it "should support using a block as a custom conversion proc given as block" do
|
274
|
-
|
275
|
-
@
|
290
|
+
@db.register_array_type('foo', :oid=>1234){|s| (s*2).to_i}
|
291
|
+
@db.conversion_procs[1234].call('{1}').must_equal [11]
|
276
292
|
end
|
277
293
|
|
278
294
|
it "should support using a block as a custom conversion proc given as :converter option" do
|
279
|
-
|
280
|
-
@
|
295
|
+
@db.register_array_type('foo', :oid=>1234, :converter=>proc{|s| (s*2).to_i})
|
296
|
+
@db.conversion_procs[1234].call('{1}').must_equal [11]
|
281
297
|
end
|
282
298
|
|
283
299
|
it "should support using an existing scaler conversion proc via the :scalar_oid option" do
|
284
|
-
|
285
|
-
@
|
300
|
+
@db.register_array_type('foo', :oid=>1234, :scalar_oid=>16)
|
301
|
+
@db.conversion_procs[1234].call('{t}').must_equal [true]
|
286
302
|
end
|
287
303
|
|
288
|
-
|
304
|
+
deprecated "should support using a given conversion procs hash via the :type_procs option" do
|
289
305
|
h = {16=>proc{|s| "!#{s}"}}
|
290
306
|
Sequel::Postgres::PGArray.register('foo', :oid=>1234, :scalar_oid=>16, :type_procs=>h)
|
291
307
|
h[1234].call('{t}').must_equal ["!t"]
|
292
308
|
end
|
293
309
|
|
294
|
-
|
310
|
+
deprecated "should support adding methods to the given module via the :typecast_methods_module option" do
|
295
311
|
m = Module.new
|
296
312
|
Sequel::Postgres::PGArray.register('foo15', :scalar_typecast=>:boolean, :typecast_methods_module=>m)
|
297
313
|
@db.typecast_value(:foo15_array, ['t']).must_equal ['t']
|
@@ -300,32 +316,31 @@ describe "pg_array extension" do
|
|
300
316
|
end
|
301
317
|
|
302
318
|
it "should not raise an error if using :scalar_oid option with unexisting scalar conversion proc" do
|
303
|
-
|
304
|
-
|
305
|
-
h[1234].call('{t}').must_equal ["t"]
|
319
|
+
@db.register_array_type('foo', :oid=>1234, :scalar_oid=>0)
|
320
|
+
@db.conversion_procs[1234].call('{t}').must_equal ["t"]
|
306
321
|
end
|
307
322
|
|
308
323
|
it "should raise an error if using :converter option and a block argument" do
|
309
|
-
proc{
|
324
|
+
proc{@db.register_array_type('foo', :converter=>proc{}){}}.must_raise(Sequel::Error)
|
310
325
|
end
|
311
326
|
|
312
327
|
it "should raise an error if using :scalar_oid option and a block argument" do
|
313
|
-
proc{
|
328
|
+
proc{@db.register_array_type('foo', :scalar_oid=>16){}}.must_raise(Sequel::Error)
|
314
329
|
end
|
315
330
|
|
316
331
|
it "should support registering custom types with :oid option" do
|
317
|
-
|
318
|
-
|
332
|
+
@db.register_array_type('foo', :oid=>1)
|
333
|
+
@db.conversion_procs[1].call('{1}').class.must_equal(Sequel::Postgres::PGArray)
|
319
334
|
end
|
320
335
|
|
321
336
|
it "should support registering converters with blocks" do
|
322
|
-
|
323
|
-
|
337
|
+
@db.register_array_type('foo', :oid=>4){|s| s.to_i * 2}
|
338
|
+
@db.conversion_procs[4].call('{{1,2},{3,4}}').must_equal [[2, 4], [6, 8]]
|
324
339
|
end
|
325
340
|
|
326
341
|
it "should support registering custom types with :array_type option" do
|
327
|
-
|
328
|
-
@db.literal(
|
342
|
+
@db.register_array_type('foo', :oid=>3, :array_type=>:blah)
|
343
|
+
@db.literal(@db.conversion_procs[3].call('{}')).must_equal "'{}'::blah[]"
|
329
344
|
end
|
330
345
|
|
331
346
|
it "should not support registering custom array types on a per-Database basis for frozen databases" do
|
@@ -373,9 +388,13 @@ describe "pg_array extension" do
|
|
373
388
|
@db.typecast_value(:banana_array, %w'1 2').must_equal [1,2]
|
374
389
|
end
|
375
390
|
|
391
|
+
it "should set appropriate timestamp conversion procs" do
|
392
|
+
@db.conversion_procs[1185].call('{"2011-10-20 11:12:13"}').must_equal [Time.local(2011, 10, 20, 11, 12, 13)]
|
393
|
+
@db.conversion_procs[1115].call('{"2011-10-20 11:12:13"}').must_equal [Time.local(2011, 10, 20, 11, 12, 13)]
|
394
|
+
end
|
395
|
+
|
376
396
|
it "should set appropriate timestamp conversion procs when adding conversion procs" do
|
377
397
|
@db.fetch = [[{:oid=>2222, :typname=>'foo'}], [{:oid=>2222, :typarray=>2223, :typname=>'foo'}]]
|
378
|
-
@db.reset_conversion_procs
|
379
398
|
@db.add_named_conversion_proc(:foo){|v| v*2}
|
380
399
|
procs = @db.conversion_procs
|
381
400
|
procs[1185].call('{"2011-10-20 11:12:13"}').must_equal [Time.local(2011, 10, 20, 11, 12, 13)]
|
@@ -7,6 +7,7 @@ describe "pg_hstore extension" do
|
|
7
7
|
@db.extend_datasets{def quote_identifiers?; false end}
|
8
8
|
@m = Sequel::Postgres
|
9
9
|
@c = @m::HStore
|
10
|
+
@db.fetch = {:oid=>9999, :typname=>'hstore'}
|
10
11
|
@db.extension :pg_hstore
|
11
12
|
end
|
12
13
|
|
@@ -34,6 +35,15 @@ describe "pg_hstore extension" do
|
|
34
35
|
['\'"a"=>"b","c"=>"d"\'::hstore', '\'"c"=>"d","a"=>"b"\'::hstore'].must_include(@db.literal(Sequel.hstore("a"=>"b","c"=>"d")))
|
35
36
|
end
|
36
37
|
|
38
|
+
it "should register conversion proc correctly" do
|
39
|
+
@db.conversion_procs[9999].call('"a"=>"b"').must_equal('a'=>'b')
|
40
|
+
end
|
41
|
+
|
42
|
+
deprecated "should reregister conversion proc when resetting conversion procs" do
|
43
|
+
@db.reset_conversion_procs
|
44
|
+
@db.conversion_procs[9999].call('"a"=>"b"').must_equal('a'=>'b')
|
45
|
+
end
|
46
|
+
|
37
47
|
it "should have Sequel.hstore method for creating HStore instances" do
|
38
48
|
Sequel.hstore({}).class.must_equal(@c)
|
39
49
|
end
|