sequel 3.46.0 → 3.47.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +96 -0
- data/Rakefile +7 -1
- data/bin/sequel +6 -4
- data/doc/active_record.rdoc +1 -1
- data/doc/advanced_associations.rdoc +14 -35
- data/doc/association_basics.rdoc +66 -4
- data/doc/migration.rdoc +4 -0
- data/doc/opening_databases.rdoc +6 -0
- data/doc/postgresql.rdoc +302 -0
- data/doc/release_notes/3.47.0.txt +270 -0
- data/doc/security.rdoc +6 -0
- data/lib/sequel/adapters/ibmdb.rb +9 -9
- data/lib/sequel/adapters/jdbc.rb +22 -7
- data/lib/sequel/adapters/jdbc/postgresql.rb +7 -2
- data/lib/sequel/adapters/mock.rb +2 -0
- data/lib/sequel/adapters/postgres.rb +44 -13
- data/lib/sequel/adapters/shared/mssql.rb +1 -1
- data/lib/sequel/adapters/shared/mysql.rb +2 -2
- data/lib/sequel/adapters/shared/postgres.rb +94 -55
- data/lib/sequel/adapters/shared/sqlite.rb +3 -1
- data/lib/sequel/adapters/sqlite.rb +2 -2
- data/lib/sequel/adapters/utils/pg_types.rb +1 -14
- data/lib/sequel/adapters/utils/split_alter_table.rb +3 -3
- data/lib/sequel/connection_pool/threaded.rb +1 -1
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database/connecting.rb +2 -2
- data/lib/sequel/database/features.rb +5 -0
- data/lib/sequel/database/misc.rb +47 -5
- data/lib/sequel/database/query.rb +2 -2
- data/lib/sequel/dataset/actions.rb +4 -2
- data/lib/sequel/dataset/misc.rb +1 -1
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/dataset/query.rb +8 -6
- data/lib/sequel/dataset/sql.rb +8 -6
- data/lib/sequel/extensions/constraint_validations.rb +5 -2
- data/lib/sequel/extensions/migration.rb +10 -8
- data/lib/sequel/extensions/pagination.rb +3 -0
- data/lib/sequel/extensions/pg_array.rb +85 -25
- data/lib/sequel/extensions/pg_hstore.rb +8 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +4 -1
- data/lib/sequel/extensions/pg_inet.rb +16 -13
- data/lib/sequel/extensions/pg_interval.rb +6 -2
- data/lib/sequel/extensions/pg_json.rb +18 -11
- data/lib/sequel/extensions/pg_range.rb +17 -2
- data/lib/sequel/extensions/pg_range_ops.rb +7 -5
- data/lib/sequel/extensions/pg_row.rb +29 -12
- data/lib/sequel/extensions/pretty_table.rb +3 -0
- data/lib/sequel/extensions/query.rb +3 -0
- data/lib/sequel/extensions/schema_caching.rb +2 -0
- data/lib/sequel/extensions/schema_dumper.rb +3 -1
- data/lib/sequel/extensions/select_remove.rb +3 -0
- data/lib/sequel/model.rb +8 -2
- data/lib/sequel/model/associations.rb +39 -27
- data/lib/sequel/model/base.rb +99 -38
- data/lib/sequel/model/plugins.rb +25 -0
- data/lib/sequel/plugins/association_autoreloading.rb +27 -22
- data/lib/sequel/plugins/association_dependencies.rb +1 -7
- data/lib/sequel/plugins/auto_validations.rb +110 -0
- data/lib/sequel/plugins/boolean_readers.rb +1 -6
- data/lib/sequel/plugins/caching.rb +6 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +1 -0
- data/lib/sequel/plugins/composition.rb +14 -7
- data/lib/sequel/plugins/constraint_validations.rb +2 -13
- data/lib/sequel/plugins/defaults_setter.rb +1 -6
- data/lib/sequel/plugins/dirty.rb +8 -0
- data/lib/sequel/plugins/error_splitter.rb +54 -0
- data/lib/sequel/plugins/force_encoding.rb +1 -5
- data/lib/sequel/plugins/hook_class_methods.rb +1 -6
- data/lib/sequel/plugins/input_transformer.rb +79 -0
- data/lib/sequel/plugins/instance_filters.rb +7 -1
- data/lib/sequel/plugins/instance_hooks.rb +7 -1
- data/lib/sequel/plugins/json_serializer.rb +5 -10
- data/lib/sequel/plugins/lazy_attributes.rb +20 -7
- data/lib/sequel/plugins/list.rb +1 -6
- data/lib/sequel/plugins/many_through_many.rb +1 -2
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +23 -39
- data/lib/sequel/plugins/optimistic_locking.rb +1 -5
- data/lib/sequel/plugins/pg_row.rb +4 -2
- data/lib/sequel/plugins/pg_typecast_on_load.rb +3 -7
- data/lib/sequel/plugins/prepared_statements.rb +1 -5
- data/lib/sequel/plugins/prepared_statements_safe.rb +2 -11
- data/lib/sequel/plugins/rcte_tree.rb +2 -2
- data/lib/sequel/plugins/serialization.rb +11 -13
- data/lib/sequel/plugins/serialization_modification_detection.rb +13 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/static_cache.rb +67 -19
- data/lib/sequel/plugins/string_stripper.rb +7 -27
- data/lib/sequel/plugins/subclasses.rb +3 -5
- data/lib/sequel/plugins/tactical_eager_loading.rb +2 -2
- data/lib/sequel/plugins/timestamps.rb +2 -7
- data/lib/sequel/plugins/touch.rb +5 -8
- data/lib/sequel/plugins/tree.rb +1 -6
- data/lib/sequel/plugins/typecast_on_load.rb +1 -5
- data/lib/sequel/plugins/update_primary_key.rb +26 -14
- data/lib/sequel/plugins/validation_class_methods.rb +31 -16
- data/lib/sequel/plugins/validation_helpers.rb +50 -26
- data/lib/sequel/plugins/xml_serializer.rb +3 -6
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +131 -15
- data/spec/adapters/sqlite_spec.rb +1 -1
- data/spec/core/connection_pool_spec.rb +16 -17
- data/spec/core/database_spec.rb +111 -40
- data/spec/core/dataset_spec.rb +65 -74
- data/spec/core/expression_filters_spec.rb +6 -5
- data/spec/core/object_graph_spec.rb +0 -1
- data/spec/core/schema_spec.rb +23 -23
- data/spec/core/spec_helper.rb +5 -1
- data/spec/extensions/association_dependencies_spec.rb +1 -1
- data/spec/extensions/association_proxies_spec.rb +1 -1
- data/spec/extensions/auto_validations_spec.rb +90 -0
- data/spec/extensions/caching_spec.rb +6 -0
- data/spec/extensions/class_table_inheritance_spec.rb +8 -1
- data/spec/extensions/composition_spec.rb +12 -5
- data/spec/extensions/constraint_validations_spec.rb +4 -4
- data/spec/extensions/core_refinements_spec.rb +29 -79
- data/spec/extensions/dirty_spec.rb +14 -0
- data/spec/extensions/error_splitter_spec.rb +18 -0
- data/spec/extensions/identity_map_spec.rb +0 -1
- data/spec/extensions/input_transformer_spec.rb +54 -0
- data/spec/extensions/instance_filters_spec.rb +6 -0
- data/spec/extensions/instance_hooks_spec.rb +12 -1
- data/spec/extensions/json_serializer_spec.rb +0 -1
- data/spec/extensions/lazy_attributes_spec.rb +64 -55
- data/spec/extensions/looser_typecasting_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +3 -4
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +53 -15
- data/spec/extensions/migration_spec.rb +16 -0
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/pg_array_spec.rb +48 -1
- data/spec/extensions/pg_hstore_ops_spec.rb +10 -2
- data/spec/extensions/pg_hstore_spec.rb +5 -0
- data/spec/extensions/pg_inet_spec.rb +5 -0
- data/spec/extensions/pg_interval_spec.rb +7 -3
- data/spec/extensions/pg_json_spec.rb +6 -1
- data/spec/extensions/pg_range_ops_spec.rb +4 -1
- data/spec/extensions/pg_range_spec.rb +5 -0
- data/spec/extensions/pg_row_plugin_spec.rb +13 -0
- data/spec/extensions/pg_row_spec.rb +28 -19
- data/spec/extensions/pg_typecast_on_load_spec.rb +6 -1
- data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +1 -1
- data/spec/extensions/rcte_tree_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/serialization_modification_detection_spec.rb +8 -0
- data/spec/extensions/serialization_spec.rb +15 -1
- data/spec/extensions/sharding_spec.rb +1 -1
- data/spec/extensions/single_table_inheritance_spec.rb +1 -1
- data/spec/extensions/static_cache_spec.rb +59 -9
- data/spec/extensions/tactical_eager_loading_spec.rb +19 -4
- data/spec/extensions/update_primary_key_spec.rb +17 -1
- data/spec/extensions/validation_class_methods_spec.rb +25 -0
- data/spec/extensions/validation_helpers_spec.rb +59 -3
- data/spec/integration/associations_test.rb +5 -5
- data/spec/integration/eager_loader_test.rb +32 -63
- data/spec/integration/model_test.rb +2 -2
- data/spec/integration/plugin_test.rb +88 -56
- data/spec/integration/prepared_statement_test.rb +1 -1
- data/spec/integration/schema_test.rb +1 -1
- data/spec/integration/timezone_test.rb +0 -1
- data/spec/integration/transaction_test.rb +0 -1
- data/spec/model/association_reflection_spec.rb +1 -1
- data/spec/model/associations_spec.rb +106 -84
- data/spec/model/base_spec.rb +4 -4
- data/spec/model/eager_loading_spec.rb +8 -8
- data/spec/model/model_spec.rb +27 -9
- data/spec/model/plugins_spec.rb +71 -0
- data/spec/model/record_spec.rb +99 -13
- metadata +12 -2
@@ -31,6 +31,6 @@ describe "LooserTypecasting Extension" do
|
|
31
31
|
|
32
32
|
specify "should not affect conversions of other types in decimal columns" do
|
33
33
|
@c.new(:d=>1).d.should == 1
|
34
|
-
@c.new(:d=>
|
34
|
+
@c.new(:d=>1).d.should be_a_kind_of(BigDecimal)
|
35
35
|
end
|
36
36
|
end
|
@@ -297,7 +297,7 @@ describe Sequel::Model, "many_through_many" do
|
|
297
297
|
MODEL_DB.sqls.should == ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234))']
|
298
298
|
end
|
299
299
|
|
300
|
-
it "should
|
300
|
+
it "should populate cache when accessed" do
|
301
301
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
302
302
|
n = @c1.load(:id => 1234)
|
303
303
|
n.associations[:tags].should == nil
|
@@ -308,7 +308,7 @@ describe Sequel::Model, "many_through_many" do
|
|
308
308
|
MODEL_DB.sqls.length.should == 0
|
309
309
|
end
|
310
310
|
|
311
|
-
it "should use
|
311
|
+
it "should use cache if available" do
|
312
312
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
313
313
|
n = @c1.load(:id => 1234)
|
314
314
|
n.associations[:tags] = []
|
@@ -316,7 +316,7 @@ describe Sequel::Model, "many_through_many" do
|
|
316
316
|
MODEL_DB.sqls.should == []
|
317
317
|
end
|
318
318
|
|
319
|
-
it "should not use
|
319
|
+
it "should not use cache if asked to reload" do
|
320
320
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
321
321
|
n = @c1.load(:id => 1234)
|
322
322
|
n.associations[:tags] = []
|
@@ -354,7 +354,6 @@ describe Sequel::Model, "many_through_many" do
|
|
354
354
|
end
|
355
355
|
|
356
356
|
it "should support a :uniq option that removes duplicates from the association" do
|
357
|
-
h = []
|
358
357
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :uniq=>true
|
359
358
|
@c2.dataset._fetch = [{:id=>20}, {:id=>30}, {:id=>20}, {:id=>30}]
|
360
359
|
@c1.load(:id=>10).tags.should == [@c2.load(:id=>20), @c2.load(:id=>30)]
|
@@ -2,7 +2,9 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
2
|
|
3
3
|
describe "Sequel::Plugins::ManyToOnePkLookup" do
|
4
4
|
before do
|
5
|
-
|
5
|
+
@db = Sequel.mock
|
6
|
+
|
7
|
+
class ::LookupModel < ::Sequel::Model(@db)
|
6
8
|
plugin :many_to_one_pk_lookup
|
7
9
|
columns :id, :caching_model_id, :caching_model_id2
|
8
10
|
many_to_one :caching_model
|
@@ -10,12 +12,10 @@ describe "Sequel::Plugins::ManyToOnePkLookup" do
|
|
10
12
|
end
|
11
13
|
@c = LookupModel
|
12
14
|
|
13
|
-
class ::CachingModel < Sequel::Model
|
15
|
+
class ::CachingModel < Sequel::Model(@db)
|
14
16
|
columns :id, :id2
|
15
17
|
end
|
16
18
|
@cc = CachingModel
|
17
|
-
|
18
|
-
@db = MODEL_DB
|
19
19
|
end
|
20
20
|
after do
|
21
21
|
Object.send(:remove_const, :CachingModel)
|
@@ -23,25 +23,25 @@ describe "Sequel::Plugins::ManyToOnePkLookup" do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
shared_examples_for "many_to_one_pk_lookup with composite keys" do
|
26
|
-
it "should use a simple primary key lookup when retrieving many_to_one associated records" do
|
26
|
+
it "should use a simple primary key lookup when retrieving many_to_one associated records with a composite key" do
|
27
27
|
@db.sqls.should == []
|
28
28
|
@c.load(:id=>3, :caching_model_id=>1, :caching_model_id2=>2).caching_model2.should equal(@cm12)
|
29
29
|
@c.load(:id=>3, :caching_model_id=>2, :caching_model_id2=>1).caching_model2.should equal(@cm21)
|
30
30
|
@db.sqls.should == []
|
31
|
-
@
|
32
|
-
@
|
31
|
+
@cc.dataset._fetch = []
|
32
|
+
@c.load(:id=>4, :caching_model_id=>2, :caching_model_id2=>2).caching_model2.should == nil
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
shared_examples_for "many_to_one_pk_lookup" do
|
37
|
-
it "should use a simple primary key lookup when retrieving many_to_one associated records
|
37
|
+
it "should use a simple primary key lookup when retrieving many_to_one associated records" do
|
38
38
|
@cc.set_primary_key([:id, :id2])
|
39
39
|
@db.sqls.should == []
|
40
40
|
@c.load(:id=>3, :caching_model_id=>1).caching_model.should equal(@cm1)
|
41
41
|
@c.load(:id=>4, :caching_model_id=>2).caching_model.should equal(@cm2)
|
42
42
|
@db.sqls.should == []
|
43
|
-
@
|
44
|
-
@
|
43
|
+
@cc.dataset._fetch = []
|
44
|
+
@c.load(:id=>4, :caching_model_id=>3).caching_model.should == nil
|
45
45
|
end
|
46
46
|
|
47
47
|
it "should not use a simple primary key lookup if the assocation has a nil :key option" do
|
@@ -62,10 +62,41 @@ describe "Sequel::Plugins::ManyToOnePkLookup" do
|
|
62
62
|
@db.sqls.should_not == []
|
63
63
|
end
|
64
64
|
|
65
|
+
it "should not use a simple primary key lookup if the assocation has :conditions" do
|
66
|
+
@c.many_to_one :caching_model, :conditions=>{:a=>1}
|
67
|
+
@c.load(:id=>3, :caching_model_id=>1).caching_model
|
68
|
+
@db.sqls.should_not == []
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should not use a simple primary key lookup if the assocation has :select" do
|
72
|
+
@c.many_to_one :caching_model, :select=>[:a, :b]
|
73
|
+
@c.load(:id=>3, :caching_model_id=>1).caching_model
|
74
|
+
@db.sqls.should_not == []
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should not use a simple primary key lookup if the assocation has a block" do
|
78
|
+
@c.many_to_one(:caching_model){|ds| ds.where{a > 1}}
|
79
|
+
@c.load(:id=>3, :caching_model_id=>1).caching_model
|
80
|
+
@db.sqls.should_not == []
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should not use a simple primary key lookup if the assocation has a non-default :dataset option" do
|
84
|
+
cc = @cc
|
85
|
+
@c.many_to_one :caching_model, :dataset=>proc{cc.where(:id=>caching_model_id)}
|
86
|
+
@c.load(:id=>3, :caching_model_id=>1).caching_model
|
87
|
+
@db.sqls.should_not == []
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should use a simple primary key lookup if explicitly set" do
|
91
|
+
@c.many_to_one :caching_model, :select=>[:a, :b], :many_to_one_pk_lookup=>true
|
92
|
+
@c.load(:id=>3, :caching_model_id=>1).caching_model
|
93
|
+
@db.sqls.should == []
|
94
|
+
end
|
95
|
+
|
65
96
|
it "should not use a simple primary key lookup if the prepared_statements_associations method is being used" do
|
66
|
-
c2 = Class.new(Sequel::Model(:not_caching_model))
|
97
|
+
c2 = Class.new(Sequel::Model(@db[:not_caching_model]))
|
67
98
|
c2.dataset._fetch = {:id=>1}
|
68
|
-
c = Class.new(Sequel::Model(:lookup_model))
|
99
|
+
c = Class.new(Sequel::Model(@db[:lookup_model]))
|
69
100
|
c.class_eval do
|
70
101
|
plugin :prepared_statements_associations
|
71
102
|
plugin :many_to_one_pk_lookup
|
@@ -106,7 +137,7 @@ describe "Sequel::Plugins::ManyToOnePkLookup" do
|
|
106
137
|
@cm12 = @cc[1, 2]
|
107
138
|
@cm21 = @cc[2, 1]
|
108
139
|
|
109
|
-
@db.
|
140
|
+
@db.sqls
|
110
141
|
end
|
111
142
|
|
112
143
|
it_should_behave_like "many_to_one_pk_lookup"
|
@@ -119,10 +150,17 @@ describe "Sequel::Plugins::ManyToOnePkLookup" do
|
|
119
150
|
@cc.plugin :static_cache
|
120
151
|
@cm1 = @cc[1]
|
121
152
|
@cm2 = @cc[2]
|
122
|
-
@db.
|
153
|
+
@db.sqls
|
123
154
|
end
|
124
155
|
|
125
156
|
it_should_behave_like "many_to_one_pk_lookup"
|
157
|
+
|
158
|
+
it "should not issue regular query if primary key lookup returns no rows" do
|
159
|
+
def @cc.primary_key_lookup(pk); end
|
160
|
+
@c.many_to_one :caching_model
|
161
|
+
@c.load(:id=>3, :caching_model_id=>1).caching_model
|
162
|
+
@db.sqls.should == []
|
163
|
+
end
|
126
164
|
end
|
127
165
|
|
128
166
|
describe "With static_cache plugin with composite key" do
|
@@ -132,7 +170,7 @@ describe "Sequel::Plugins::ManyToOnePkLookup" do
|
|
132
170
|
@cc.plugin :static_cache
|
133
171
|
@cm12 = @cc[[1, 2]]
|
134
172
|
@cm21 = @cc[[2, 1]]
|
135
|
-
@db.
|
173
|
+
@db.sqls
|
136
174
|
end
|
137
175
|
|
138
176
|
it_should_behave_like "many_to_one_pk_lookup with composite keys"
|
@@ -259,6 +259,10 @@ describe "Sequel::IntegerMigrator" do
|
|
259
259
|
specify "should raise and error if there is a missing integer migration version" do
|
260
260
|
proc{Sequel::Migrator.apply(@db, "spec/files/missing_integer_migrations")}.should raise_error(Sequel::Migrator::Error)
|
261
261
|
end
|
262
|
+
|
263
|
+
specify "should not raise and error if there is a missing integer migration version and allow_missing_migration_files is true" do
|
264
|
+
Sequel::Migrator.run(@db, "spec/files/missing_integer_migrations", :allow_missing_migration_files => true).should_not raise_error(Sequel::Migrator::Error)
|
265
|
+
end
|
262
266
|
|
263
267
|
specify "should raise and error if there is a duplicate integer migration version" do
|
264
268
|
proc{Sequel::Migrator.apply(@db, "spec/files/duplicate_integer_migrations")}.should raise_error(Sequel::Migrator::Error)
|
@@ -609,6 +613,18 @@ describe "Sequel::TimestampMigrator" do
|
|
609
613
|
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb 1273253851_create_nodes.rb 1273253853_3_create_users.rb'
|
610
614
|
end
|
611
615
|
|
616
|
+
specify "should not raise error for applied migrations not in file system if :allow_missing_migration_files is true" do
|
617
|
+
@dir = 'spec/files/timestamped_migrations'
|
618
|
+
@m.apply(@db, @dir)
|
619
|
+
[:schema_migrations, :sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_true}
|
620
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb 1273253851_create_nodes.rb 1273253853_3_create_users.rb'
|
621
|
+
|
622
|
+
@dir = 'spec/files/missing_timestamped_migrations'
|
623
|
+
proc{@m.run(@db, @dir, :allow_missing_migration_files => true)}.should_not raise_error(Sequel::Migrator::Error)
|
624
|
+
[:schema_migrations, :sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_true}
|
625
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb 1273253851_create_nodes.rb 1273253853_3_create_users.rb'
|
626
|
+
end
|
627
|
+
|
612
628
|
specify "should raise error missing column name in existing schema_migrations table" do
|
613
629
|
@dir = 'spec/files/timestamped_migrations'
|
614
630
|
@m.apply(@db, @dir)
|
@@ -14,6 +14,7 @@ describe "pg_array extension" do
|
|
14
14
|
@db.extension(:pg_array)
|
15
15
|
@m = Sequel::Postgres
|
16
16
|
@converter = @m::PG_TYPES
|
17
|
+
@db.sqls
|
17
18
|
end
|
18
19
|
|
19
20
|
it "should parse single dimensional text arrays" do
|
@@ -300,7 +301,7 @@ describe "pg_array extension" do
|
|
300
301
|
Sequel::Postgres::PG_TYPES[2].should be_a_kind_of(Sequel::Postgres::PGArray::JSONCreator)
|
301
302
|
end
|
302
303
|
|
303
|
-
it "should support registering converters with :parser=>:json option" do
|
304
|
+
it "should support registering converters with :parser=>:json option and blocks" do
|
304
305
|
Sequel::Postgres::PGArray.register('foo', :oid=>4, :parser=>:json){|s| s * 2}
|
305
306
|
Sequel::Postgres::PG_TYPES[4].call('{{1, 2}, {3, 4}}').should == [[2, 4], [6, 8]]
|
306
307
|
end
|
@@ -316,9 +317,55 @@ describe "pg_array extension" do
|
|
316
317
|
@db.schema(:items).map{|e| e[1][:type]}.should == [:float_array]
|
317
318
|
end
|
318
319
|
|
320
|
+
it "should support registering custom array types on a per-Database basis" do
|
321
|
+
@db.register_array_type('banana', :oid=>7865){|s| s}
|
322
|
+
@db.typecast_value(:banana_array, []).should be_a_kind_of(Sequel::Postgres::PGArray)
|
323
|
+
@db.fetch = [{:name=>'id', :db_type=>'banana[]'}]
|
324
|
+
@db.schema(:items).map{|e| e[1][:type]}.should == [:banana_array]
|
325
|
+
@db.conversion_procs.should have_key(7865)
|
326
|
+
@db.respond_to?(:typecast_value_banana_array, true).should be_true
|
327
|
+
|
328
|
+
db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
|
329
|
+
db.extend_datasets(Module.new{def supports_timestamp_timezones?; false; end; def supports_timestamp_usecs?; false; end})
|
330
|
+
db.extension(:pg_array)
|
331
|
+
db.fetch = [{:name=>'id', :db_type=>'banana[]'}]
|
332
|
+
db.schema(:items).map{|e| e[1][:type]}.should == [nil]
|
333
|
+
db.conversion_procs.should_not have_key(7865)
|
334
|
+
db.respond_to?(:typecast_value_banana_array, true).should be_false
|
335
|
+
end
|
336
|
+
|
337
|
+
it "should automatically look up the array and scalar oids when registering per-Database types" do
|
338
|
+
@db.fetch = [[{:oid=>21, :typarray=>7866}], [{:name=>'id', :db_type=>'banana[]'}]]
|
339
|
+
@db.register_array_type('banana', :scalar_typecast=>:integer)
|
340
|
+
@db.sqls.should == ["SELECT typarray, oid FROM pg_type WHERE (typname = 'banana') LIMIT 1"]
|
341
|
+
@db.schema(:items).map{|e| e[1][:type]}.should == [:banana_array]
|
342
|
+
@db.conversion_procs[7866].call("{1,2}").should == [1,2]
|
343
|
+
@db.typecast_value(:banana_array, %w'1 2').should == [1,2]
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should not automatically look up oids if given both scalar and array oids" do
|
347
|
+
@db.register_array_type('banana', :oid=>7866, :scalar_oid=>21, :scalar_typecast=>:integer)
|
348
|
+
@db.sqls.should == []
|
349
|
+
@db.conversion_procs[7866].call("{1,2}").should == [1,2]
|
350
|
+
@db.typecast_value(:banana_array, %w'1 2').should == [1,2]
|
351
|
+
end
|
352
|
+
|
353
|
+
it "should not automatically look up oids if given array oid and block" do
|
354
|
+
@db.register_array_type('banana', :oid=>7866, :scalar_typecast=>:integer){|s| s.to_i}
|
355
|
+
@db.sqls.should == []
|
356
|
+
@db.conversion_procs[7866].call("{1,2}").should == [1,2]
|
357
|
+
@db.typecast_value(:banana_array, %w'1 2').should == [1,2]
|
358
|
+
end
|
359
|
+
|
319
360
|
it "should set appropriate timestamp conversion procs when getting conversion procs" do
|
320
361
|
procs = @db.conversion_procs
|
321
362
|
procs[1185].call('{"2011-10-20 11:12:13"}').should == [Time.local(2011, 10, 20, 11, 12, 13)]
|
322
363
|
procs[1115].call('{"2011-10-20 11:12:13"}').should == [Time.local(2011, 10, 20, 11, 12, 13)]
|
323
364
|
end
|
365
|
+
|
366
|
+
it "should return correct results for Database#schema_type_class" do
|
367
|
+
@db.register_array_type('banana', :oid=>7866, :scalar_typecast=>:integer){|s| s.to_i}
|
368
|
+
@db.schema_type_class(:banana_array).should == Sequel::Postgres::PGArray
|
369
|
+
@db.schema_type_class(:integer).should == Integer
|
370
|
+
end
|
324
371
|
end
|
@@ -7,11 +7,19 @@ describe "Sequel::Postgres::HStoreOp" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "#- should use the - operator" do
|
10
|
-
@ds.literal(@h -
|
10
|
+
@ds.literal(@h - :a).should == "(h - a)"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "#- should cast String argument to text when using - operator" do
|
14
|
+
@ds.literal(@h - 'a').should == "(h - CAST('a' AS text))"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "#- should not cast LiteralString argument to text when using - operator" do
|
18
|
+
@ds.literal(@h - Sequel.lit('a')).should == "(h - a)"
|
11
19
|
end
|
12
20
|
|
13
21
|
it "#- should return an HStoreOp" do
|
14
|
-
@ds.literal((@h -
|
22
|
+
@ds.literal((@h - :a)['a']).should == "((h - a) -> 'a')"
|
15
23
|
end
|
16
24
|
|
17
25
|
it "#[] should use the -> operator" do
|
@@ -197,4 +197,9 @@ describe "pg_hstore extension" do
|
|
197
197
|
dump = Marshal.dump(v)
|
198
198
|
Marshal.load(dump).should == v
|
199
199
|
end
|
200
|
+
|
201
|
+
it "should return correct results for Database#schema_type_class" do
|
202
|
+
@db.schema_type_class(:hstore).should == Sequel::Postgres::HStore
|
203
|
+
@db.schema_type_class(:integer).should == Integer
|
204
|
+
end
|
200
205
|
end
|
@@ -44,4 +44,9 @@ describe "pg_inet extension" do
|
|
44
44
|
proc{@db.typecast_value(:ipaddr, '')}.should raise_error(Sequel::InvalidValue)
|
45
45
|
proc{@db.typecast_value(:ipaddr, 1)}.should raise_error(Sequel::InvalidValue)
|
46
46
|
end
|
47
|
+
|
48
|
+
it "should return correct results for Database#schema_type_class" do
|
49
|
+
@db.schema_type_class(:ipaddr).should == IPAddr
|
50
|
+
@db.schema_type_class(:integer).should == Integer
|
51
|
+
end
|
47
52
|
end
|
@@ -2,8 +2,8 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
2
|
|
3
3
|
begin
|
4
4
|
require 'active_support/duration'
|
5
|
-
rescue LoadError =>
|
6
|
-
skip_warn "pg_interval plugin: can't load active_support/duration (#{
|
5
|
+
rescue LoadError => exc
|
6
|
+
skip_warn "pg_interval plugin: can't load active_support/duration (#{exc.class}: #{exc})"
|
7
7
|
else
|
8
8
|
describe "pg_interval extension" do
|
9
9
|
before do
|
@@ -46,7 +46,6 @@ describe "pg_interval extension" do
|
|
46
46
|
end
|
47
47
|
|
48
48
|
it "should support typecasting for the interval type" do
|
49
|
-
ip = IPAddr.new('127.0.0.1')
|
50
49
|
d = ActiveSupport::Duration.new(31557600 + 2*86400*30 + 3*86400*7 + 4*86400 + 5*3600 + 6*60 + 7, [[:years, 1], [:months, 2], [:days, 25], [:seconds, 18367]])
|
51
50
|
@db.typecast_value(:interval, d).object_id.should == d.object_id
|
52
51
|
|
@@ -68,5 +67,10 @@ describe "pg_interval extension" do
|
|
68
67
|
proc{@db.typecast_value(:interval, 'foo')}.should raise_error(Sequel::InvalidValue)
|
69
68
|
proc{@db.typecast_value(:interval, Object.new)}.should raise_error(Sequel::InvalidValue)
|
70
69
|
end
|
70
|
+
|
71
|
+
it "should return correct results for Database#schema_type_class" do
|
72
|
+
@db.schema_type_class(:interval).should == ActiveSupport::Duration
|
73
|
+
@db.schema_type_class(:integer).should == Integer
|
74
|
+
end
|
71
75
|
end
|
72
76
|
end
|
@@ -55,7 +55,7 @@ describe "pg_json extension" do
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
it "should literalize
|
58
|
+
it "should literalize JSONHash and JSONArray to strings correctly" do
|
59
59
|
@db.literal(Sequel.pg_json([])).should == "'[]'::json"
|
60
60
|
@db.literal(Sequel.pg_json([1, [2], {'a'=>'b'}])).should == "'[1,[2],{\"a\":\"b\"}]'::json"
|
61
61
|
@db.literal(Sequel.pg_json({})).should == "'{}'::json"
|
@@ -110,4 +110,9 @@ describe "pg_json extension" do
|
|
110
110
|
proc{@db.typecast_value(:json, '')}.should raise_error(Sequel::InvalidValue)
|
111
111
|
proc{@db.typecast_value(:json, 1)}.should raise_error(Sequel::InvalidValue)
|
112
112
|
end
|
113
|
+
|
114
|
+
it "should return correct results for Database#schema_type_class" do
|
115
|
+
@db.schema_type_class(:json).should == [Sequel::Postgres::JSONHash, Sequel::Postgres::JSONArray]
|
116
|
+
@db.schema_type_class(:integer).should == Integer
|
117
|
+
end
|
113
118
|
end
|
@@ -33,9 +33,12 @@ describe "Sequel::Postgres::RangeOp" do
|
|
33
33
|
@ds.literal(@h.overlaps(@h)).should == "(h && h)"
|
34
34
|
@ds.literal(@h.left_of(@h)).should == "(h << h)"
|
35
35
|
@ds.literal(@h.right_of(@h)).should == "(h >> h)"
|
36
|
+
@ds.literal(@h.ends_before(@h)).should == "(h &< h)"
|
37
|
+
@ds.literal(@h.starts_after(@h)).should == "(h &> h)"
|
38
|
+
@ds.literal(@h.adjacent_to(@h)).should == "(h -|- h)"
|
39
|
+
|
36
40
|
@ds.literal(@h.starts_before(@h)).should == "(h &< h)"
|
37
41
|
@ds.literal(@h.ends_after(@h)).should == "(h &> h)"
|
38
|
-
@ds.literal(@h.adjacent_to(@h)).should == "(h -|- h)"
|
39
42
|
end
|
40
43
|
|
41
44
|
it "should define methods for all of the the PostgreSQL range functions" do
|
@@ -163,6 +163,11 @@ describe "pg_range extension" do
|
|
163
163
|
Sequel::Postgres::PG_TYPES[331].call('[1,3)').should be_a_kind_of(@R)
|
164
164
|
end
|
165
165
|
|
166
|
+
it "should return correct results for Database#schema_type_class" do
|
167
|
+
@db.schema_type_class(:int4range).should == Sequel::Postgres::PGRange
|
168
|
+
@db.schema_type_class(:integer).should == Integer
|
169
|
+
end
|
170
|
+
|
166
171
|
describe "parser" do
|
167
172
|
before do
|
168
173
|
@p = Sequel::Postgres::PG_TYPES[3904]
|
@@ -15,6 +15,14 @@ describe "Sequel::Plugins::PgRow" do
|
|
15
15
|
@c2.columns :address
|
16
16
|
@c2.db_schema[:address].merge!(:type=>:pg_row_address)
|
17
17
|
end
|
18
|
+
after do
|
19
|
+
@c.dataset.opts[:from] = [:address]
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should have schema_type_class include Sequel::Model" do
|
23
|
+
@c2.new.send(:schema_type_class, :address).should == @c
|
24
|
+
@db.conversion_procs[1098].call('(123 Foo St,Bar City)').should == @c.load(:street=>'123 Foo St', :city=>'Bar City')
|
25
|
+
end
|
18
26
|
|
19
27
|
it "should set up a parser for the type that creates a model class" do
|
20
28
|
@db.conversion_procs[1098].call('(123 Foo St,Bar City)').should == @c.load(:street=>'123 Foo St', :city=>'Bar City')
|
@@ -33,6 +41,11 @@ describe "Sequel::Plugins::PgRow" do
|
|
33
41
|
@db.literal(@c.load(:street=>'123 Foo St', :city=>'Bar City')).should == "ROW('123 Foo St', 'Bar City')::address"
|
34
42
|
end
|
35
43
|
|
44
|
+
it "should handle literalizing model instances when model table is aliased" do
|
45
|
+
@c.dataset.opts[:from] = [Sequel.as(:address, :a)]
|
46
|
+
@db.literal(@c.load(:street=>'123 Foo St', :city=>'Bar City')).should == "ROW('123 Foo St', 'Bar City')::address"
|
47
|
+
end
|
48
|
+
|
36
49
|
it "should handle model instances in bound variables" do
|
37
50
|
@db.bound_variable_arg(1, nil).should == 1
|
38
51
|
@db.bound_variable_arg(@c.load(:street=>'123 Foo St', :city=>'Bar City'), nil).should == '("123 Foo St","Bar City")'
|
@@ -137,13 +137,13 @@ describe "pg_row extension" do
|
|
137
137
|
it "should reload registered row types when reseting conversion procs" do
|
138
138
|
db = Sequel.mock(:host=>'postgres')
|
139
139
|
db.extension(:pg_row)
|
140
|
-
db.conversion_procs[4] =
|
141
|
-
db.conversion_procs[5] =
|
140
|
+
db.conversion_procs[4] = proc{|s| s.to_i}
|
141
|
+
db.conversion_procs[5] = proc{|s| s * 2}
|
142
142
|
db.sqls
|
143
143
|
db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|
144
144
|
db.register_row_type(:foo)
|
145
145
|
db.sqls.should == ["SELECT pg_type.oid, typrelid, typarray FROM pg_type WHERE ((typtype = 'c') AND (typname = 'foo')) LIMIT 1",
|
146
|
-
"SELECT attname, atttypid FROM pg_attribute WHERE ((attrelid = 2) AND (attnum > 0) AND NOT attisdropped) ORDER BY attnum"]
|
146
|
+
"SELECT attname, (CASE pg_type.typbasetype WHEN 0 THEN atttypid ELSE pg_type.typbasetype END) AS atttypid FROM pg_attribute INNER JOIN pg_type ON (pg_type.oid = pg_attribute.atttypid) WHERE ((attrelid = 2) AND (attnum > 0) AND NOT attisdropped) ORDER BY attnum"]
|
147
147
|
|
148
148
|
begin
|
149
149
|
pgnt = Sequel::Postgres::PG_NAMED_TYPES.dup
|
@@ -151,7 +151,7 @@ describe "pg_row extension" do
|
|
151
151
|
db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|
152
152
|
db.reset_conversion_procs
|
153
153
|
db.sqls.should == ["SELECT pg_type.oid, typrelid, typarray FROM pg_type WHERE ((typtype = 'c') AND (typname = 'foo')) LIMIT 1",
|
154
|
-
"SELECT attname, atttypid FROM pg_attribute WHERE ((attrelid = 2) AND (attnum > 0) AND NOT attisdropped) ORDER BY attnum"]
|
154
|
+
"SELECT attname, (CASE pg_type.typbasetype WHEN 0 THEN atttypid ELSE pg_type.typbasetype END) AS atttypid FROM pg_attribute INNER JOIN pg_type ON (pg_type.oid = pg_attribute.atttypid) WHERE ((attrelid = 2) AND (attnum > 0) AND NOT attisdropped) ORDER BY attnum"]
|
155
155
|
ensure
|
156
156
|
Sequel::Postgres::PG_NAMED_TYPES.replace pgnt
|
157
157
|
end
|
@@ -182,7 +182,7 @@ describe "pg_row extension" do
|
|
182
182
|
@db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|
183
183
|
@db.register_row_type(:foo)
|
184
184
|
@db.sqls.should == ["SELECT pg_type.oid, typrelid, typarray FROM pg_type WHERE ((typtype = 'c') AND (typname = 'foo')) LIMIT 1",
|
185
|
-
"SELECT attname, atttypid FROM pg_attribute WHERE ((attrelid = 2) AND (attnum > 0) AND NOT attisdropped) ORDER BY attnum"]
|
185
|
+
"SELECT attname, (CASE pg_type.typbasetype WHEN 0 THEN atttypid ELSE pg_type.typbasetype END) AS atttypid FROM pg_attribute INNER JOIN pg_type ON (pg_type.oid = pg_attribute.atttypid) WHERE ((attrelid = 2) AND (attnum > 0) AND NOT attisdropped) ORDER BY attnum"]
|
186
186
|
p1 = @db.conversion_procs[1]
|
187
187
|
p1.columns.should == [:bar, :baz]
|
188
188
|
p1.column_oids.should == [4, 5]
|
@@ -210,7 +210,7 @@ describe "pg_row extension" do
|
|
210
210
|
@db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|
211
211
|
@db.register_row_type(:foo__bar)
|
212
212
|
@db.sqls.should == ["SELECT pg_type.oid, typrelid, typarray FROM pg_type INNER JOIN pg_namespace ON ((pg_namespace.oid = pg_type.typnamespace) AND (pg_namespace.nspname = 'foo')) WHERE ((typtype = 'c') AND (typname = 'bar')) LIMIT 1",
|
213
|
-
"SELECT attname, atttypid FROM pg_attribute WHERE ((attrelid = 2) AND (attnum > 0) AND NOT attisdropped) ORDER BY attnum"]
|
213
|
+
"SELECT attname, (CASE pg_type.typbasetype WHEN 0 THEN atttypid ELSE pg_type.typbasetype END) AS atttypid FROM pg_attribute INNER JOIN pg_type ON (pg_type.oid = pg_attribute.atttypid) WHERE ((attrelid = 2) AND (attnum > 0) AND NOT attisdropped) ORDER BY attnum"]
|
214
214
|
p1 = @db.conversion_procs[1]
|
215
215
|
p1.columns.should == [:bar, :baz]
|
216
216
|
p1.column_oids.should == [4, 5]
|
@@ -230,8 +230,8 @@ describe "pg_row extension" do
|
|
230
230
|
end
|
231
231
|
|
232
232
|
it "should allow registering with a custom converter" do
|
233
|
-
@db.conversion_procs[4] =
|
234
|
-
@db.conversion_procs[5] =
|
233
|
+
@db.conversion_procs[4] = proc{|s| s.to_i}
|
234
|
+
@db.conversion_procs[5] = proc{|s| s * 2}
|
235
235
|
@db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|
236
236
|
c = proc{|h| [h]}
|
237
237
|
@db.register_row_type(:foo, :converter=>c)
|
@@ -241,8 +241,8 @@ describe "pg_row extension" do
|
|
241
241
|
end
|
242
242
|
|
243
243
|
it "should allow registering with a custom typecaster" do
|
244
|
-
@db.conversion_procs[4] =
|
245
|
-
@db.conversion_procs[5] =
|
244
|
+
@db.conversion_procs[4] = proc{|s| s.to_i}
|
245
|
+
@db.conversion_procs[5] = proc{|s| s * 2}
|
246
246
|
@db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|
247
247
|
@db.register_row_type(:foo, :typecaster=>proc{|h| {:bar=>(h[:bar]||0).to_i, :baz=>(h[:baz] || 'a')*2}})
|
248
248
|
@db.typecast_value(:pg_row_foo, %w'1 b').should be_a_kind_of(Hash)
|
@@ -257,16 +257,16 @@ describe "pg_row extension" do
|
|
257
257
|
end
|
258
258
|
|
259
259
|
it "should handle conversion procs that aren't added until later" do
|
260
|
-
@db.conversion_procs[5] =
|
260
|
+
@db.conversion_procs[5] = proc{|s| s * 2}
|
261
261
|
@db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|
262
262
|
c = proc{|h| [h]}
|
263
263
|
@db.register_row_type(:foo, :converter=>c)
|
264
|
-
@db.conversion_procs[4] =
|
264
|
+
@db.conversion_procs[4] = proc{|s| s.to_i}
|
265
265
|
@db.conversion_procs[1].call('(1,b)').should == [{:bar=>1, :baz=>'bb'}]
|
266
266
|
end
|
267
267
|
|
268
268
|
it "should handle nil values when converting columns" do
|
269
|
-
@db.conversion_procs[5] =
|
269
|
+
@db.conversion_procs[5] = proc{|s| s * 2}
|
270
270
|
@db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}]]
|
271
271
|
called = false
|
272
272
|
@db.conversion_procs[4] = proc{|s| called = true; s}
|
@@ -276,8 +276,8 @@ describe "pg_row extension" do
|
|
276
276
|
end
|
277
277
|
|
278
278
|
it "should registering array type for row type if type has an array oid" do
|
279
|
-
@db.conversion_procs[4] =
|
280
|
-
@db.conversion_procs[5] =
|
279
|
+
@db.conversion_procs[4] = proc{|s| s.to_i}
|
280
|
+
@db.conversion_procs[5] = proc{|s| s * 2}
|
281
281
|
@db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|
282
282
|
@db.register_row_type(:foo, :typecaster=>proc{|h| {:bar=>(h[:bar]||0).to_i, :baz=>(h[:baz] || 'a')*2}})
|
283
283
|
p3 = @db.conversion_procs[3]
|
@@ -292,8 +292,8 @@ describe "pg_row extension" do
|
|
292
292
|
end
|
293
293
|
|
294
294
|
it "should allow typecasting of registered row types via Database#row_type" do
|
295
|
-
@db.conversion_procs[4] =
|
296
|
-
@db.conversion_procs[5] =
|
295
|
+
@db.conversion_procs[4] = proc{|s| s.to_i}
|
296
|
+
@db.conversion_procs[5] = proc{|s| s * 2}
|
297
297
|
@db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|
298
298
|
@db.register_row_type(:foo, :typecaster=>proc{|h| @m::HashRow.subclass(:foo, [:bar, :baz]).new({:bar=>(h[:bar]||0).to_i, :baz=>(h[:baz] || 'a')*2})})
|
299
299
|
@db.literal(@db.row_type(:foo, ['1', 'b'])).should == "ROW(1, 'bb')::foo"
|
@@ -301,8 +301,8 @@ describe "pg_row extension" do
|
|
301
301
|
end
|
302
302
|
|
303
303
|
it "should allow parsing when typecasting registered row types via Database#row_type" do
|
304
|
-
@db.conversion_procs[4] =
|
305
|
-
@db.conversion_procs[5] =
|
304
|
+
@db.conversion_procs[4] = proc{|s| s.to_i}
|
305
|
+
@db.conversion_procs[5] = proc{|s| s * 2}
|
306
306
|
@db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|
307
307
|
@db.register_row_type(:foo, :typecaster=>proc{|h| @m::HashRow.subclass(:foo, [:bar, :baz]).new(:bar=>(h[:bar]||0).to_i, :baz=>(h[:baz] || 'a')*2)})
|
308
308
|
@db.literal(@db.row_type(:foo, ['1', 'b'])).should == "ROW(1, 'bb')::foo"
|
@@ -348,4 +348,13 @@ describe "pg_row extension" do
|
|
348
348
|
@db.fetch = []
|
349
349
|
proc{@db.register_row_type(:foo)}.should raise_error(Sequel::Error)
|
350
350
|
end
|
351
|
+
|
352
|
+
it "should return correct results for Database#schema_type_class" do
|
353
|
+
@db.conversion_procs[4] = proc{|s| s.to_i}
|
354
|
+
@db.conversion_procs[5] = proc{|s| s * 2}
|
355
|
+
@db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|
356
|
+
@db.register_row_type(:foo, :typecaster=>proc{|h| {:bar=>(h[:bar]||0).to_i, :baz=>(h[:baz] || 'a')*2}})
|
357
|
+
@db.schema_type_class(:pg_row_foo).should == [Sequel::Postgres::PGRow::HashRow, Sequel::Postgres::PGRow::ArrayRow]
|
358
|
+
@db.schema_type_class(:integer).should == Integer
|
359
|
+
end
|
351
360
|
end
|