sequel 4.46.0 → 4.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +210 -0
- data/Rakefile +1 -1
- data/doc/advanced_associations.rdoc +1 -1
- data/doc/opening_databases.rdoc +3 -2
- data/doc/release_notes/4.47.0.txt +56 -0
- data/doc/release_notes/4.48.0.txt +293 -0
- data/doc/release_notes/4.49.0.txt +222 -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 +30 -8
- data/lib/sequel/adapters/jdbc/as400.rb +1 -1
- data/lib/sequel/adapters/jdbc/db2.rb +12 -3
- data/lib/sequel/adapters/jdbc/derby.rb +4 -5
- data/lib/sequel/adapters/jdbc/h2.rb +10 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +46 -20
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +20 -6
- data/lib/sequel/adapters/jdbc.rb +39 -23
- data/lib/sequel/adapters/mock.rb +27 -19
- data/lib/sequel/adapters/mysql.rb +17 -16
- data/lib/sequel/adapters/mysql2.rb +5 -6
- data/lib/sequel/adapters/oracle.rb +5 -9
- data/lib/sequel/adapters/postgres.rb +91 -103
- 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 +79 -25
- data/lib/sequel/adapters/shared/oracle.rb +26 -3
- data/lib/sequel/adapters/shared/postgres.rb +199 -95
- 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/ast_transformer.rb +1 -1
- data/lib/sequel/connection_pool/sharded_single.rb +1 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +1 -1
- data/lib/sequel/connection_pool/single.rb +2 -2
- data/lib/sequel/connection_pool/threaded.rb +2 -2
- data/lib/sequel/connection_pool.rb +9 -2
- data/lib/sequel/core.rb +2 -2
- data/lib/sequel/database/connecting.rb +8 -8
- data/lib/sequel/database/dataset.rb +6 -3
- data/lib/sequel/database/dataset_defaults.rb +14 -1
- 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 +72 -10
- data/lib/sequel/dataset/dataset_module.rb +58 -0
- 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 +22 -11
- data/lib/sequel/dataset.rb +1 -1
- data/lib/sequel/exceptions.rb +8 -0
- data/lib/sequel/extensions/_model_pg_row.rb +5 -2
- data/lib/sequel/extensions/core_extensions.rb +4 -1
- data/lib/sequel/extensions/current_datetime_timestamp.rb +2 -1
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -3
- 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 +11 -8
- data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/null_dataset.rb +1 -0
- 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 +29 -25
- 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/server_block.rb +32 -15
- 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/associations.rb +35 -7
- data/lib/sequel/model/base.rb +113 -87
- data/lib/sequel/model/dataset_module.rb +5 -43
- data/lib/sequel/model/errors.rb +2 -1
- data/lib/sequel/model/inflections.rb +17 -5
- data/lib/sequel/model.rb +26 -58
- data/lib/sequel/plugins/active_model.rb +2 -2
- data/lib/sequel/plugins/association_autoreloading.rb +2 -0
- data/lib/sequel/plugins/association_dependencies.rb +3 -3
- 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 +2 -2
- data/lib/sequel/plugins/boolean_subsets.rb +1 -1
- data/lib/sequel/plugins/caching.rb +19 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +24 -13
- data/lib/sequel/plugins/column_conflicts.rb +7 -2
- data/lib/sequel/plugins/column_select.rb +3 -3
- data/lib/sequel/plugins/composition.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +8 -8
- data/lib/sequel/plugins/dataset_associations.rb +25 -13
- data/lib/sequel/plugins/defaults_setter.rb +13 -1
- 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 +19 -12
- data/lib/sequel/plugins/lazy_attributes.rb +8 -7
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +2 -0
- data/lib/sequel/plugins/modification_detection.rb +3 -0
- data/lib/sequel/plugins/nested_attributes.rb +6 -2
- data/lib/sequel/plugins/pg_array_associations.rb +5 -0
- data/lib/sequel/plugins/pg_row.rb +4 -2
- data/lib/sequel/plugins/pg_typecast_on_load.rb +2 -0
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/plugins/rcte_tree.rb +4 -24
- data/lib/sequel/plugins/serialization.rb +9 -15
- data/lib/sequel/plugins/single_table_inheritance.rb +8 -3
- 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 +4 -2
- data/lib/sequel/plugins/validation_class_methods.rb +5 -6
- data/lib/sequel/plugins/validation_helpers.rb +14 -8
- data/lib/sequel/plugins/xml_serializer.rb +4 -4
- data/lib/sequel/sql.rb +18 -9
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +115 -14
- data/spec/adapters/mssql_spec.rb +4 -4
- data/spec/adapters/mysql_spec.rb +83 -29
- data/spec/adapters/oracle_spec.rb +28 -24
- data/spec/adapters/postgres_spec.rb +40 -24
- data/spec/adapters/sqlanywhere_spec.rb +88 -86
- data/spec/adapters/sqlite_spec.rb +29 -24
- data/spec/bin_spec.rb +7 -1
- data/spec/core/connection_pool_spec.rb +45 -14
- data/spec/core/database_spec.rb +155 -0
- data/spec/core/dataset_spec.rb +219 -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 +106 -19
- data/spec/extensions/column_conflicts_spec.rb +11 -0
- data/spec/extensions/column_select_spec.rb +1 -0
- data/spec/extensions/composition_spec.rb +13 -0
- data/spec/extensions/connection_validator_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +20 -8
- data/spec/extensions/defaults_setter_spec.rb +15 -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/many_through_many_spec.rb +4 -4
- 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/null_dataset_spec.rb +1 -1
- 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/pg_typecast_on_load_spec.rb +11 -9
- 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 +108 -94
- 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/serialization_spec.rb +1 -1
- data/spec/extensions/server_block_spec.rb +7 -0
- data/spec/extensions/single_table_inheritance_spec.rb +17 -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 +10 -5
- data/spec/extensions/whitelist_security_spec.rb +26 -0
- data/spec/integration/associations_test.rb +8 -0
- data/spec/integration/dataset_test.rb +45 -44
- data/spec/integration/model_test.rb +53 -4
- data/spec/integration/plugin_test.rb +28 -4
- 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/association_reflection_spec.rb +43 -1
- data/spec/model/associations_spec.rb +29 -9
- data/spec/model/class_dataset_methods_spec.rb +20 -4
- data/spec/model/dataset_methods_spec.rb +12 -3
- data/spec/model/eager_loading_spec.rb +8 -8
- data/spec/model/model_spec.rb +45 -1
- data/spec/model/plugins_spec.rb +34 -0
- data/spec/model/record_spec.rb +1 -1
- data/spec/spec_config.rb +2 -0
- metadata +11 -4
- data/spec/adapters/firebird_spec.rb +0 -405
- data/spec/adapters/informix_spec.rb +0 -100
|
@@ -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
|
|
@@ -18,6 +18,32 @@ describe "pg_inet extension" do
|
|
|
18
18
|
@db.literal(IPAddr.new('2001:4f8:3:ba:2e0:81ff:fe22:d1f1')).must_equal "'2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128'"
|
|
19
19
|
end unless ipv6_broken
|
|
20
20
|
|
|
21
|
+
deprecated "should set up conversion procs correctly" do
|
|
22
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
23
|
+
cp[869].call("127.0.0.1").must_equal IPAddr.new('127.0.0.1')
|
|
24
|
+
cp[650].call("127.0.0.1").must_equal IPAddr.new('127.0.0.1')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
deprecated "should set up conversion procs for arrays correctly" do
|
|
28
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
29
|
+
cp[1041].call("{127.0.0.1}").must_equal [IPAddr.new('127.0.0.1')]
|
|
30
|
+
cp[651].call("{127.0.0.1}").must_equal [IPAddr.new('127.0.0.1')]
|
|
31
|
+
cp[1040].call("{127.0.0.1}").must_equal ['127.0.0.1']
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should set up conversion procs correctly" do
|
|
35
|
+
cp = @db.conversion_procs
|
|
36
|
+
cp[869].call("127.0.0.1").must_equal IPAddr.new('127.0.0.1')
|
|
37
|
+
cp[650].call("127.0.0.1").must_equal IPAddr.new('127.0.0.1')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should set up conversion procs for arrays correctly" do
|
|
41
|
+
cp = @db.conversion_procs
|
|
42
|
+
cp[1041].call("{127.0.0.1}").must_equal [IPAddr.new('127.0.0.1')]
|
|
43
|
+
cp[651].call("{127.0.0.1}").must_equal [IPAddr.new('127.0.0.1')]
|
|
44
|
+
cp[1040].call("{127.0.0.1}").must_equal ['127.0.0.1']
|
|
45
|
+
end
|
|
46
|
+
|
|
21
47
|
it "should not affect literalization of custom objects" do
|
|
22
48
|
o = Object.new
|
|
23
49
|
def o.sql_literal(ds) 'v' end
|
|
@@ -34,6 +34,26 @@ describe "pg_interval extension" do
|
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
deprecated "should set up conversion procs correctly" do
|
|
38
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
39
|
+
cp[1186].call("1 sec").must_equal ActiveSupport::Duration.new(1, [[:seconds, 1]])
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
deprecated "should set up conversion procs for arrays correctly" do
|
|
43
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
44
|
+
cp[1187].call("{1 sec}").must_equal [ActiveSupport::Duration.new(1, [[:seconds, 1]])]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should set up conversion procs correctly" do
|
|
48
|
+
cp = @db.conversion_procs
|
|
49
|
+
cp[1186].call("1 sec").must_equal ActiveSupport::Duration.new(1, [[:seconds, 1]])
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should set up conversion procs for arrays correctly" do
|
|
53
|
+
cp = @db.conversion_procs
|
|
54
|
+
cp[1187].call("{1 sec}").must_equal [ActiveSupport::Duration.new(1, [[:seconds, 1]])]
|
|
55
|
+
end
|
|
56
|
+
|
|
37
57
|
it "should not affect literalization of custom objects" do
|
|
38
58
|
o = Object.new
|
|
39
59
|
def o.sql_literal(ds) 'v' end
|
|
@@ -17,6 +17,30 @@ describe "pg_json extension" do
|
|
|
17
17
|
@db.extension(:pg_array, :pg_json)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
deprecated "should set up conversion procs correctly" do
|
|
21
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
22
|
+
cp[114].call("{}").must_equal @hc.new({})
|
|
23
|
+
cp[3802].call("{}").must_equal @bhc.new({})
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
deprecated "should set up conversion procs for arrays correctly" do
|
|
27
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
28
|
+
cp[199].call("{[]}").must_equal [@ac.new([])]
|
|
29
|
+
cp[3807].call("{[]}").must_equal [@bac.new([])]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should set up conversion procs correctly" do
|
|
33
|
+
cp = @db.conversion_procs
|
|
34
|
+
cp[114].call("{}").must_equal @hc.new({})
|
|
35
|
+
cp[3802].call("{}").must_equal @bhc.new({})
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should set up conversion procs for arrays correctly" do
|
|
39
|
+
cp = @db.conversion_procs
|
|
40
|
+
cp[199].call("{[]}").must_equal [@ac.new([])]
|
|
41
|
+
cp[3807].call("{[]}").must_equal [@bac.new([])]
|
|
42
|
+
end
|
|
43
|
+
|
|
20
44
|
it "should parse json strings correctly" do
|
|
21
45
|
@m.parse_json('[]').class.must_equal(@ac)
|
|
22
46
|
@m.parse_json('[]').to_a.must_equal []
|