sequel 3.38.0 → 3.39.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +62 -0
- data/README.rdoc +2 -2
- data/bin/sequel +12 -2
- data/doc/advanced_associations.rdoc +1 -1
- data/doc/association_basics.rdoc +13 -0
- data/doc/release_notes/3.39.0.txt +237 -0
- data/doc/schema_modification.rdoc +4 -4
- data/lib/sequel/adapters/jdbc/derby.rb +1 -0
- data/lib/sequel/adapters/mock.rb +5 -0
- data/lib/sequel/adapters/mysql.rb +8 -1
- data/lib/sequel/adapters/mysql2.rb +10 -3
- data/lib/sequel/adapters/postgres.rb +72 -8
- data/lib/sequel/adapters/shared/db2.rb +1 -0
- data/lib/sequel/adapters/shared/mssql.rb +57 -0
- data/lib/sequel/adapters/shared/mysql.rb +95 -19
- data/lib/sequel/adapters/shared/oracle.rb +14 -0
- data/lib/sequel/adapters/shared/postgres.rb +63 -24
- data/lib/sequel/adapters/shared/sqlite.rb +6 -9
- data/lib/sequel/connection_pool/sharded_threaded.rb +8 -3
- data/lib/sequel/connection_pool/threaded.rb +9 -4
- data/lib/sequel/database/query.rb +60 -48
- data/lib/sequel/database/schema_generator.rb +13 -6
- data/lib/sequel/database/schema_methods.rb +65 -12
- data/lib/sequel/dataset/actions.rb +22 -4
- data/lib/sequel/dataset/features.rb +5 -0
- data/lib/sequel/dataset/graph.rb +2 -3
- data/lib/sequel/dataset/misc.rb +2 -2
- data/lib/sequel/dataset/query.rb +0 -2
- data/lib/sequel/dataset/sql.rb +33 -12
- data/lib/sequel/extensions/constraint_validations.rb +451 -0
- data/lib/sequel/extensions/eval_inspect.rb +17 -2
- data/lib/sequel/extensions/pg_array_ops.rb +15 -5
- data/lib/sequel/extensions/pg_interval.rb +2 -2
- data/lib/sequel/extensions/pg_row_ops.rb +18 -0
- data/lib/sequel/extensions/schema_dumper.rb +3 -11
- data/lib/sequel/model/associations.rb +3 -2
- data/lib/sequel/model/base.rb +57 -13
- data/lib/sequel/model/exceptions.rb +20 -2
- data/lib/sequel/plugins/constraint_validations.rb +198 -0
- data/lib/sequel/plugins/defaults_setter.rb +15 -1
- data/lib/sequel/plugins/dirty.rb +2 -2
- data/lib/sequel/plugins/identity_map.rb +12 -8
- data/lib/sequel/plugins/subclasses.rb +19 -1
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/validation_helpers.rb +24 -4
- data/lib/sequel/sql.rb +64 -24
- data/lib/sequel/timezones.rb +10 -2
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +26 -25
- data/spec/adapters/mysql_spec.rb +57 -23
- data/spec/adapters/oracle_spec.rb +34 -49
- data/spec/adapters/postgres_spec.rb +226 -128
- data/spec/adapters/sqlite_spec.rb +50 -49
- data/spec/core/connection_pool_spec.rb +22 -0
- data/spec/core/database_spec.rb +53 -47
- data/spec/core/dataset_spec.rb +36 -32
- data/spec/core/expression_filters_spec.rb +14 -2
- data/spec/core/mock_adapter_spec.rb +4 -0
- data/spec/core/object_graph_spec.rb +0 -13
- data/spec/core/schema_spec.rb +64 -5
- data/spec/core_extensions_spec.rb +1 -0
- data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
- data/spec/extensions/constraint_validations_spec.rb +316 -0
- data/spec/extensions/defaults_setter_spec.rb +24 -0
- data/spec/extensions/eval_inspect_spec.rb +9 -0
- data/spec/extensions/identity_map_spec.rb +11 -2
- data/spec/extensions/pg_array_ops_spec.rb +9 -0
- data/spec/extensions/pg_row_ops_spec.rb +11 -1
- data/spec/extensions/pg_row_plugin_spec.rb +4 -0
- data/spec/extensions/schema_dumper_spec.rb +8 -5
- data/spec/extensions/subclasses_spec.rb +14 -0
- data/spec/extensions/validation_helpers_spec.rb +15 -2
- data/spec/integration/dataset_test.rb +75 -1
- data/spec/integration/plugin_test.rb +146 -0
- data/spec/integration/schema_test.rb +34 -0
- data/spec/model/dataset_methods_spec.rb +38 -0
- data/spec/model/hooks_spec.rb +6 -0
- data/spec/model/validations_spec.rb +27 -2
- metadata +8 -2
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -14,10 +14,6 @@ INTEGRATION_DB = MYSQL_DB unless defined?(INTEGRATION_DB)
|
|
14
14
|
|
15
15
|
MYSQL_URI = URI.parse(MYSQL_DB.uri)
|
16
16
|
|
17
|
-
MYSQL_DB.create_table! :test2 do
|
18
|
-
text :name
|
19
|
-
integer :value
|
20
|
-
end
|
21
17
|
def MYSQL_DB.sqls
|
22
18
|
(@sqls ||= [])
|
23
19
|
end
|
@@ -86,24 +82,17 @@ describe "MySQL", '#create_table' do
|
|
86
82
|
@db[:dolls].insert
|
87
83
|
@db[:dolls].select_map(:name).should == ["foo"]
|
88
84
|
end
|
89
|
-
end
|
90
|
-
|
91
|
-
describe "A MySQL database" do
|
92
|
-
specify "should provide the server version" do
|
93
|
-
MYSQL_DB.server_version.should >= 40000
|
94
|
-
end
|
95
85
|
|
96
|
-
specify "should
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
MYSQL_DB.transaction{MYSQL_DB[:test2].for_share.all.should == []}
|
86
|
+
specify "should be able to parse the default value for set and enum types" do
|
87
|
+
@db.create_table!(:dolls){column :t, "set('a', 'b', 'c', 'd')", :default=>'a,b'}
|
88
|
+
@db.schema(:dolls).first.last[:ruby_default].should == 'a,b'
|
89
|
+
@db.create_table!(:dolls){column :t, "enum('a', 'b', 'c', 'd')", :default=>'b'}
|
90
|
+
@db.schema(:dolls).first.last[:ruby_default].should == 'b'
|
102
91
|
end
|
103
92
|
end
|
104
93
|
|
105
|
-
if MYSQL_DB.adapter_scheme
|
106
|
-
describe "Sequel::MySQL
|
94
|
+
if [:mysql, :mysql2].include?(MYSQL_DB.adapter_scheme)
|
95
|
+
describe "Sequel::MySQL::Database#convert_tinyint_to_bool" do
|
107
96
|
before do
|
108
97
|
@db = MYSQL_DB
|
109
98
|
@db.create_table(:booltest){column :b, 'tinyint(1)'; column :i, 'tinyint(4)'}
|
@@ -149,6 +138,17 @@ if MYSQL_DB.adapter_scheme == :mysql
|
|
149
138
|
@ds << {:b=>0, :i=>0}
|
150
139
|
@ds.all.should == [{:b=>0, :i=>0}]
|
151
140
|
end
|
141
|
+
|
142
|
+
specify "should allow disabling the conversion on a per-dataset basis" do
|
143
|
+
@db.convert_tinyint_to_bool = true
|
144
|
+
ds = @ds.clone
|
145
|
+
ds.meta_def(:cast_tinyint_integer?){|f| true} # mysql
|
146
|
+
ds.meta_def(:convert_tinyint_to_bool?){false} # mysql2
|
147
|
+
ds.delete
|
148
|
+
ds << {:b=>true, :i=>10}
|
149
|
+
ds.all.should == [{:b=>1, :i=>10}]
|
150
|
+
@ds.all.should == [{:b=>true, :i=>10}]
|
151
|
+
end
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
@@ -269,7 +269,6 @@ end
|
|
269
269
|
describe "MySQL join expressions" do
|
270
270
|
before do
|
271
271
|
@ds = MYSQL_DB[:nodes]
|
272
|
-
@ds.db.meta_def(:server_version) {50014}
|
273
272
|
end
|
274
273
|
|
275
274
|
specify "should raise error for :full_outer join requests." do
|
@@ -342,8 +341,41 @@ describe "Joined MySQL dataset" do
|
|
342
341
|
end
|
343
342
|
|
344
343
|
describe "A MySQL database" do
|
345
|
-
|
344
|
+
after do
|
345
|
+
MYSQL_DB.drop_table?(:test_innodb)
|
346
|
+
end
|
347
|
+
|
348
|
+
specify "should handle the creation and dropping of an InnoDB table with foreign keys" do
|
349
|
+
proc{MYSQL_DB.create_table!(:test_innodb, :engine=>:InnoDB){primary_key :id; foreign_key :fk, :test_innodb, :key=>:id}}.should_not raise_error
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
describe "A MySQL database" do
|
354
|
+
before(:all) do
|
346
355
|
@db = MYSQL_DB
|
356
|
+
@db.create_table! :test2 do
|
357
|
+
text :name
|
358
|
+
integer :value
|
359
|
+
end
|
360
|
+
end
|
361
|
+
after(:all) do
|
362
|
+
@db.drop_table?(:test2)
|
363
|
+
end
|
364
|
+
|
365
|
+
specify "should provide the server version" do
|
366
|
+
@db.server_version.should >= 40000
|
367
|
+
end
|
368
|
+
|
369
|
+
specify "should cache the server version" do
|
370
|
+
# warm cache:
|
371
|
+
@db.server_version
|
372
|
+
@db.sqls.clear
|
373
|
+
3.times{@db.server_version}
|
374
|
+
@db.sqls.should be_empty
|
375
|
+
end
|
376
|
+
|
377
|
+
specify "should support for_share" do
|
378
|
+
@db.transaction{@db[:test2].for_share.all.should == []}
|
347
379
|
end
|
348
380
|
|
349
381
|
specify "should support add_column operations" do
|
@@ -472,8 +504,7 @@ describe "A MySQL database" do
|
|
472
504
|
@db.alter_table(:items){add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade}
|
473
505
|
@db.sqls.should == ["CREATE TABLE `items` (`id` integer)",
|
474
506
|
"CREATE TABLE `users` (`id` integer PRIMARY KEY AUTO_INCREMENT)",
|
475
|
-
"ALTER TABLE `items` ADD COLUMN `p_id` integer NOT NULL"
|
476
|
-
"ALTER TABLE `items` ADD FOREIGN KEY (`p_id`) REFERENCES `users`(`id`) ON DELETE CASCADE"]
|
507
|
+
"ALTER TABLE `items` ADD COLUMN `p_id` integer NOT NULL, ADD FOREIGN KEY (`p_id`) REFERENCES `users`(`id`) ON DELETE CASCADE"]
|
477
508
|
end
|
478
509
|
|
479
510
|
specify "should have rename_column support keep existing options" do
|
@@ -500,7 +531,7 @@ describe "A MySQL database" do
|
|
500
531
|
specify "should have set_column_type pass through options" do
|
501
532
|
@db.create_table(:items){integer :id; enum :list, :elements=>%w[one]}
|
502
533
|
@db.alter_table(:items){set_column_type :id, :int, :unsigned=>true, :size=>8; set_column_type :list, :enum, :elements=>%w[two]}
|
503
|
-
@db.sqls.should == ["CREATE TABLE `items` (`id` integer, `list` enum('one'))", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(8) UNSIGNED NULL
|
534
|
+
@db.sqls.should == ["CREATE TABLE `items` (`id` integer, `list` enum('one'))", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(8) UNSIGNED NULL, CHANGE COLUMN `list` `list` enum('two') NULL"]
|
504
535
|
end
|
505
536
|
|
506
537
|
specify "should have set_column_default support keep existing options" do
|
@@ -625,6 +656,9 @@ describe "A grouped MySQL dataset" do
|
|
625
656
|
MYSQL_DB[:test2] << {:name => '12', :value => 20}
|
626
657
|
MYSQL_DB[:test2] << {:name => '13', :value => 10}
|
627
658
|
end
|
659
|
+
after do
|
660
|
+
MYSQL_DB.drop_table?(:test2)
|
661
|
+
end
|
628
662
|
|
629
663
|
specify "should return the correct count for raw sql query" do
|
630
664
|
ds = MYSQL_DB["select name FROM test2 WHERE name = '11' GROUP BY name"]
|
@@ -5,25 +5,34 @@ unless defined?(ORACLE_DB)
|
|
5
5
|
end
|
6
6
|
INTEGRATION_DB = ORACLE_DB unless defined?(INTEGRATION_DB)
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
describe "An Oracle database" do
|
9
|
+
before(:all) do
|
10
|
+
ORACLE_DB.create_table!(:items) do
|
11
|
+
String :name, :size => 50
|
12
|
+
Integer :value
|
13
|
+
Date :date_created
|
14
|
+
index :value
|
15
|
+
end
|
14
16
|
|
15
|
-
ORACLE_DB.create_table!(:books) do
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
17
|
+
ORACLE_DB.create_table!(:books) do
|
18
|
+
Integer :id
|
19
|
+
String :title, :size => 50
|
20
|
+
Integer :category_id
|
21
|
+
end
|
20
22
|
|
21
|
-
ORACLE_DB.create_table!(:categories) do
|
22
|
-
|
23
|
-
|
24
|
-
end
|
23
|
+
ORACLE_DB.create_table!(:categories) do
|
24
|
+
Integer :id
|
25
|
+
String :cat_name, :size => 50
|
26
|
+
end
|
27
|
+
@d = ORACLE_DB[:items]
|
28
|
+
end
|
29
|
+
after do
|
30
|
+
@d.delete
|
31
|
+
end
|
32
|
+
after(:all) do
|
33
|
+
ORACLE_DB.drop_table?(:items, :books, :categories)
|
34
|
+
end
|
25
35
|
|
26
|
-
describe "An Oracle database" do
|
27
36
|
specify "should provide disconnect functionality" do
|
28
37
|
ORACLE_DB.execute("select user from dual")
|
29
38
|
ORACLE_DB.pool.size.should == 1
|
@@ -81,15 +90,9 @@ describe "An Oracle database" do
|
|
81
90
|
primary_key :id, :integer, :null => false
|
82
91
|
index :name, :unique => true
|
83
92
|
end
|
93
|
+
ORACLE_DB.drop_table?(:test_tmp)
|
84
94
|
end
|
85
|
-
end
|
86
95
|
|
87
|
-
describe "An Oracle dataset" do
|
88
|
-
before do
|
89
|
-
@d = ORACLE_DB[:items]
|
90
|
-
@d.delete # remove all records
|
91
|
-
end
|
92
|
-
|
93
96
|
specify "should return the correct record count" do
|
94
97
|
@d.count.should == 0
|
95
98
|
@d << {:name => 'abc', :value => 123}
|
@@ -194,8 +197,6 @@ describe "An Oracle dataset" do
|
|
194
197
|
@d << {:name => 'def', :value => 789}
|
195
198
|
@d.filter(:name => 'abc').update(:value => 530)
|
196
199
|
|
197
|
-
# the third record should stay the same
|
198
|
-
# floating-point precision bullshit
|
199
200
|
@d[:name => 'def'][:value].should == 789
|
200
201
|
@d.filter(:value => 530).count.should == 2
|
201
202
|
end
|
@@ -230,24 +231,20 @@ describe "An Oracle dataset" do
|
|
230
231
|
|
231
232
|
@d.count.should == 1
|
232
233
|
end
|
233
|
-
end
|
234
234
|
|
235
|
-
|
236
|
-
before do
|
235
|
+
specify "should return correct result" do
|
237
236
|
@d1 = ORACLE_DB[:books]
|
238
|
-
@d1.delete
|
237
|
+
@d1.delete
|
239
238
|
@d1 << {:id => 1, :title => 'aaa', :category_id => 100}
|
240
239
|
@d1 << {:id => 2, :title => 'bbb', :category_id => 100}
|
241
240
|
@d1 << {:id => 3, :title => 'ccc', :category_id => 101}
|
242
241
|
@d1 << {:id => 4, :title => 'ddd', :category_id => 102}
|
243
242
|
|
244
243
|
@d2 = ORACLE_DB[:categories]
|
245
|
-
@d2.delete
|
244
|
+
@d2.delete
|
246
245
|
@d2 << {:id => 100, :cat_name => 'ruby'}
|
247
246
|
@d2 << {:id => 101, :cat_name => 'rails'}
|
248
|
-
end
|
249
247
|
|
250
|
-
specify "should return correct result" do
|
251
248
|
@d1.join(:categories, :id => :category_id).select(:books__id, :title, :cat_name).order(:books__id).to_a.should == [
|
252
249
|
{:id => 1, :title => 'aaa', :cat_name => 'ruby'},
|
253
250
|
{:id => 2, :title => 'bbb', :cat_name => 'ruby'},
|
@@ -271,18 +268,14 @@ describe "Joined Oracle dataset" do
|
|
271
268
|
{:id => 3, :title => 'ccc', :cat_name => 'rails'}
|
272
269
|
]
|
273
270
|
end
|
274
|
-
end
|
275
271
|
|
276
|
-
|
277
|
-
before do
|
272
|
+
specify "should allow columns to be renamed" do
|
278
273
|
@d1 = ORACLE_DB[:books]
|
279
|
-
@d1.delete
|
274
|
+
@d1.delete
|
280
275
|
@d1 << {:id => 1, :title => 'aaa', :category_id => 100}
|
281
276
|
@d1 << {:id => 2, :title => 'bbb', :category_id => 100}
|
282
277
|
@d1 << {:id => 3, :title => 'bbb', :category_id => 100}
|
283
|
-
end
|
284
278
|
|
285
|
-
specify "should allow columns to be renamed" do
|
286
279
|
@d1.select(Sequel.as(:title, :name)).order_by(:id).to_a.should == [
|
287
280
|
{ :name => 'aaa' },
|
288
281
|
{ :name => 'bbb' },
|
@@ -291,22 +284,14 @@ describe "Oracle aliasing" do
|
|
291
284
|
end
|
292
285
|
|
293
286
|
specify "nested queries should work" do
|
294
|
-
|
295
|
-
end
|
296
|
-
end
|
297
|
-
|
298
|
-
describe "Row locks in Oracle" do
|
299
|
-
before do
|
300
|
-
@d1 = ORACLE_DB[:books]
|
301
|
-
@d1.delete
|
302
|
-
@d1 << {:id => 1, :title => 'aaa'}
|
287
|
+
ORACLE_DB[:books].select(:title).group_by(:title).count.should == 2
|
303
288
|
end
|
304
289
|
|
305
290
|
specify "#for_update should use FOR UPDATE" do
|
306
|
-
|
291
|
+
ORACLE_DB[:books].for_update.sql.should == 'SELECT * FROM "BOOKS" FOR UPDATE'
|
307
292
|
end
|
308
293
|
|
309
294
|
specify "#lock_style should accept symbols" do
|
310
|
-
|
295
|
+
ORACLE_DB[:books].lock_style(:update).sql.should == 'SELECT * FROM "BOOKS" FOR UPDATE'
|
311
296
|
end
|
312
297
|
end
|
@@ -24,26 +24,14 @@ end
|
|
24
24
|
POSTGRES_DB.loggers << logger
|
25
25
|
|
26
26
|
#POSTGRES_DB.instance_variable_set(:@server_version, 80200)
|
27
|
-
POSTGRES_DB.create_table! :test do
|
28
|
-
text :name
|
29
|
-
integer :value, :index => true
|
30
|
-
end
|
31
|
-
POSTGRES_DB.create_table! :test2 do
|
32
|
-
text :name
|
33
|
-
integer :value
|
34
|
-
end
|
35
|
-
POSTGRES_DB.create_table! :test3 do
|
36
|
-
integer :value
|
37
|
-
timestamp :time
|
38
|
-
end
|
39
|
-
POSTGRES_DB.create_table! :test4 do
|
40
|
-
varchar :name, :size => 20
|
41
|
-
bytea :value
|
42
|
-
end
|
43
27
|
|
44
28
|
describe "A PostgreSQL database" do
|
45
|
-
before do
|
29
|
+
before(:all) do
|
46
30
|
@db = POSTGRES_DB
|
31
|
+
@db.create_table!(:public__testfk){primary_key :id; foreign_key :i, :public__testfk}
|
32
|
+
end
|
33
|
+
after(:all) do
|
34
|
+
@db.drop_table?(:public__testfk)
|
47
35
|
end
|
48
36
|
|
49
37
|
specify "should provide the server version" do
|
@@ -51,23 +39,13 @@ describe "A PostgreSQL database" do
|
|
51
39
|
end
|
52
40
|
|
53
41
|
specify "should correctly parse the schema" do
|
54
|
-
@db.schema(:
|
55
|
-
[:
|
56
|
-
[:
|
57
|
-
]
|
58
|
-
@db.schema(:test4, :reload=>true).should == [
|
59
|
-
[:name, {:oid=>1043, :type=>:string, :allow_null=>true, :default=>nil, :ruby_default=>nil, :db_type=>"character varying(20)", :primary_key=>false}],
|
60
|
-
[:value, {:oid=>17, :type=>:blob, :allow_null=>true, :default=>nil, :ruby_default=>nil, :db_type=>"bytea", :primary_key=>false}]
|
61
|
-
]
|
42
|
+
@db.schema(:public__testfk, :reload=>true).should == [
|
43
|
+
[:id, {:type=>:integer, :ruby_default=>nil, :db_type=>"integer", :default=>"nextval('testfk_id_seq'::regclass)", :oid=>23, :primary_key=>true, :allow_null=>false}],
|
44
|
+
[:i, {:type=>:integer, :ruby_default=>nil, :db_type=>"integer", :default=>nil, :oid=>23, :primary_key=>false, :allow_null=>true}]]
|
62
45
|
end
|
63
46
|
|
64
47
|
specify "should parse foreign keys for tables in a schema" do
|
65
|
-
|
66
|
-
@db.create_table!(:public__testfk){primary_key :id; foreign_key :i, :public__testfk}
|
67
|
-
@db.foreign_key_list(:public__testfk).should == [{:on_delete=>:no_action, :on_update=>:no_action, :columns=>[:i], :key=>[:id], :deferrable=>false, :table=>Sequel.qualify(:public, :testfk), :name=>:testfk_i_fkey}]
|
68
|
-
ensure
|
69
|
-
@db.drop_table(:public__testfk)
|
70
|
-
end
|
48
|
+
@db.foreign_key_list(:public__testfk).should == [{:on_delete=>:no_action, :on_update=>:no_action, :columns=>[:i], :key=>[:id], :deferrable=>false, :table=>Sequel.qualify(:public, :testfk), :name=>:testfk_i_fkey}]
|
71
49
|
end
|
72
50
|
|
73
51
|
specify "should return uuid fields as strings" do
|
@@ -76,10 +54,23 @@ describe "A PostgreSQL database" do
|
|
76
54
|
end
|
77
55
|
|
78
56
|
describe "A PostgreSQL dataset" do
|
57
|
+
before(:all) do
|
58
|
+
@db = POSTGRES_DB
|
59
|
+
@d = @db[:test]
|
60
|
+
@db.create_table! :test do
|
61
|
+
text :name
|
62
|
+
integer :value, :index => true
|
63
|
+
end
|
64
|
+
end
|
79
65
|
before do
|
80
|
-
@d = POSTGRES_DB[:test]
|
81
66
|
@d.delete
|
82
|
-
|
67
|
+
@db.sqls.clear
|
68
|
+
end
|
69
|
+
after do
|
70
|
+
@db.drop_table?(:atest)
|
71
|
+
end
|
72
|
+
after(:all) do
|
73
|
+
@db.drop_table?(:test)
|
83
74
|
end
|
84
75
|
|
85
76
|
specify "should quote columns and tables using double quotes if quoting identifiers" do
|
@@ -130,68 +121,52 @@ describe "A PostgreSQL dataset" do
|
|
130
121
|
end
|
131
122
|
|
132
123
|
specify "should support exclusion constraints when creating or altering tables" do
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
proc{@db[:atest].insert(2)}.should raise_error(Sequel::DatabaseError)
|
145
|
-
@db.alter_table(:atest){drop_constraint 'atest_ex'}
|
146
|
-
ensure
|
147
|
-
@db.drop_table?(:atest)
|
148
|
-
end
|
124
|
+
@db.create_table!(:atest){Integer :t; exclude [[Sequel.desc(:t, :nulls=>:last), '=']], :using=>:btree, :where=>proc{t > 0}}
|
125
|
+
@db[:atest].insert(1)
|
126
|
+
@db[:atest].insert(2)
|
127
|
+
proc{@db[:atest].insert(2)}.should raise_error(Sequel::DatabaseError)
|
128
|
+
|
129
|
+
@db.create_table!(:atest){Integer :t}
|
130
|
+
@db.alter_table(:atest){add_exclusion_constraint [[:t, '=']], :using=>:btree, :name=>'atest_ex'}
|
131
|
+
@db[:atest].insert(1)
|
132
|
+
@db[:atest].insert(2)
|
133
|
+
proc{@db[:atest].insert(2)}.should raise_error(Sequel::DatabaseError)
|
134
|
+
@db.alter_table(:atest){drop_constraint 'atest_ex'}
|
149
135
|
end if POSTGRES_DB.server_version >= 90000
|
150
136
|
|
151
137
|
specify "should support adding foreign key constarints that are not yet valid, and validating them later" do
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
@db.alter_table(:atest){validate_constraint :atest_fk}
|
163
|
-
proc{@db.alter_table(:atest){validate_constraint :atest_fk}}.should_not raise_error
|
164
|
-
ensure
|
165
|
-
@db.drop_table?(:atest)
|
166
|
-
end
|
138
|
+
@db.create_table!(:atest){primary_key :id; Integer :fk}
|
139
|
+
@db[:atest].insert(1, 5)
|
140
|
+
@db.alter_table(:atest){add_foreign_key [:fk], :atest, :not_valid=>true, :name=>:atest_fk}
|
141
|
+
@db[:atest].insert(2, 1)
|
142
|
+
proc{@db[:atest].insert(3, 4)}.should raise_error(Sequel::DatabaseError)
|
143
|
+
|
144
|
+
proc{@db.alter_table(:atest){validate_constraint :atest_fk}}.should raise_error(Sequel::DatabaseError)
|
145
|
+
@db[:atest].where(:id=>1).update(:fk=>2)
|
146
|
+
@db.alter_table(:atest){validate_constraint :atest_fk}
|
147
|
+
proc{@db.alter_table(:atest){validate_constraint :atest_fk}}.should_not raise_error
|
167
148
|
end if POSTGRES_DB.server_version >= 90200
|
168
149
|
|
169
150
|
specify "should support :using when altering a column's type" do
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
@db.alter_table(:atest){set_column_type :t, Time, :using=>Sequel.cast('epoch', Time) + Sequel.cast('1 second', :interval) * :t}
|
175
|
-
@db[:atest].get(Sequel.extract(:year, :t)).should == 2010
|
176
|
-
ensure
|
177
|
-
@db.drop_table?(:atest)
|
178
|
-
end
|
151
|
+
@db.create_table!(:atest){Integer :t}
|
152
|
+
@db[:atest].insert(1262304000)
|
153
|
+
@db.alter_table(:atest){set_column_type :t, Time, :using=>Sequel.cast('epoch', Time) + Sequel.cast('1 second', :interval) * :t}
|
154
|
+
@db[:atest].get(Sequel.extract(:year, :t)).should == 2010
|
179
155
|
end
|
180
156
|
|
181
157
|
specify "should support :using with a string when altering a column's type" do
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
158
|
+
@db.create_table!(:atest){Integer :t}
|
159
|
+
@db[:atest].insert(1262304000)
|
160
|
+
@db.alter_table(:atest){set_column_type :t, Time, :using=>"'epoch'::timestamp + '1 second'::interval * t"}
|
161
|
+
@db[:atest].get(Sequel.extract(:year, :t)).should == 2010
|
162
|
+
end
|
163
|
+
|
164
|
+
specify "should be able to parse the default value for an interval type" do
|
165
|
+
@db.create_table!(:atest){interval :t, :default=>'1 week'}
|
166
|
+
@db.schema(:atest).first.last[:ruby_default].should == '7 days'
|
191
167
|
end
|
192
168
|
|
193
169
|
specify "should have #transaction support various types of synchronous options" do
|
194
|
-
@db = POSTGRES_DB
|
195
170
|
@db.transaction(:synchronous=>:on){}
|
196
171
|
@db.transaction(:synchronous=>true){}
|
197
172
|
@db.transaction(:synchronous=>:off){}
|
@@ -216,7 +191,6 @@ describe "A PostgreSQL dataset" do
|
|
216
191
|
end
|
217
192
|
|
218
193
|
specify "should have #transaction support read only transactions" do
|
219
|
-
@db = POSTGRES_DB
|
220
194
|
@db.transaction(:read_only=>true){}
|
221
195
|
@db.transaction(:read_only=>false){}
|
222
196
|
@db.transaction(:isolation=>:serializable, :read_only=>true){}
|
@@ -225,7 +199,6 @@ describe "A PostgreSQL dataset" do
|
|
225
199
|
end
|
226
200
|
|
227
201
|
specify "should have #transaction support deferrable transactions" do
|
228
|
-
@db = POSTGRES_DB
|
229
202
|
@db.transaction(:deferrable=>true){}
|
230
203
|
@db.transaction(:deferrable=>false){}
|
231
204
|
@db.transaction(:deferrable=>true, :read_only=>true){}
|
@@ -236,43 +209,42 @@ describe "A PostgreSQL dataset" do
|
|
236
209
|
end if POSTGRES_DB.server_version >= 90100
|
237
210
|
|
238
211
|
specify "should support creating indexes concurrently" do
|
239
|
-
|
240
|
-
|
241
|
-
POSTGRES_DB.sqls.should == ['CREATE INDEX CONCURRENTLY "test_name_value_index" ON "test" ("name", "value")'] if check_sqls
|
212
|
+
@db.add_index :test, [:name, :value], :concurrently=>true
|
213
|
+
@db.sqls.should == ['CREATE INDEX CONCURRENTLY "test_name_value_index" ON "test" ("name", "value")'] if check_sqls
|
242
214
|
end
|
243
215
|
|
244
216
|
specify "should support dropping indexes only if they already exist" do
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
217
|
+
@db.add_index :test, [:name, :value], :name=>'tnv1'
|
218
|
+
@db.sqls.clear
|
219
|
+
@db.drop_index :test, [:name, :value], :if_exists=>true, :name=>'tnv1'
|
220
|
+
@db.sqls.should == ['DROP INDEX IF EXISTS "tnv1"']
|
249
221
|
end
|
250
222
|
|
251
223
|
specify "should support CASCADE when dropping indexes" do
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
224
|
+
@db.add_index :test, [:name, :value], :name=>'tnv2'
|
225
|
+
@db.sqls.clear
|
226
|
+
@db.drop_index :test, [:name, :value], :cascade=>true, :name=>'tnv2'
|
227
|
+
@db.sqls.should == ['DROP INDEX "tnv2" CASCADE']
|
256
228
|
end
|
257
229
|
|
258
230
|
specify "should support dropping indexes concurrently" do
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
231
|
+
@db.add_index :test, [:name, :value], :name=>'tnv2'
|
232
|
+
@db.sqls.clear
|
233
|
+
@db.drop_index :test, [:name, :value], :concurrently=>true, :name=>'tnv2'
|
234
|
+
@db.sqls.should == ['DROP INDEX CONCURRENTLY "tnv2"']
|
263
235
|
end if POSTGRES_DB.server_version >= 90200
|
264
236
|
|
265
237
|
specify "#lock should lock table if inside a transaction" do
|
266
|
-
|
238
|
+
@db.transaction{@d.lock('EXCLUSIVE'); @d.insert(:name=>'a')}
|
267
239
|
end
|
268
240
|
|
269
241
|
specify "#lock should return nil" do
|
270
242
|
@d.lock('EXCLUSIVE'){@d.insert(:name=>'a')}.should == nil
|
271
|
-
|
243
|
+
@db.transaction{@d.lock('EXCLUSIVE').should == nil; @d.insert(:name=>'a')}
|
272
244
|
end
|
273
245
|
|
274
246
|
specify "should raise an error if attempting to update a joined dataset with a single FROM table" do
|
275
|
-
proc{
|
247
|
+
proc{@db[:test].join(:test, [:name]).update(:name=>'a')}.should raise_error(Sequel::Error, 'Need multiple FROM tables if updating/deleting a dataset with JOINs')
|
276
248
|
end
|
277
249
|
|
278
250
|
specify "should truncate with options" do
|
@@ -288,9 +260,9 @@ describe "A PostgreSQL dataset" do
|
|
288
260
|
end
|
289
261
|
|
290
262
|
specify "should truncate multiple tables at once" do
|
291
|
-
tables = [:test, :
|
263
|
+
tables = [:test, :test]
|
292
264
|
tables.each{|t| @d.from(t).insert}
|
293
|
-
@d.from(:test, :
|
265
|
+
@d.from(:test, :test).truncate
|
294
266
|
tables.each{|t| @d.from(t).count.should == 0}
|
295
267
|
end
|
296
268
|
end
|
@@ -377,14 +349,23 @@ if POSTGRES_DB.pool.respond_to?(:max_size) and POSTGRES_DB.pool.max_size > 1
|
|
377
349
|
end
|
378
350
|
|
379
351
|
describe "A PostgreSQL dataset with a timestamp field" do
|
380
|
-
before do
|
352
|
+
before(:all) do
|
381
353
|
@db = POSTGRES_DB
|
354
|
+
@db.create_table! :test3 do
|
355
|
+
integer :value
|
356
|
+
timestamp :time
|
357
|
+
end
|
382
358
|
@d = @db[:test3]
|
359
|
+
end
|
360
|
+
before do
|
383
361
|
@d.delete
|
384
362
|
end
|
385
363
|
after do
|
386
364
|
@db.convert_infinite_timestamps = false if @db.adapter_scheme == :postgres
|
387
365
|
end
|
366
|
+
after(:all) do
|
367
|
+
@db.drop_table?(:test3)
|
368
|
+
end
|
388
369
|
|
389
370
|
cspecify "should store milliseconds in time fields for Time objects", :do, :swift do
|
390
371
|
t = Time.now
|
@@ -432,19 +413,29 @@ describe "A PostgreSQL dataset with a timestamp field" do
|
|
432
413
|
c.new(:time=>-1.0/0.0).time.should == -1.0/0.0
|
433
414
|
end
|
434
415
|
end
|
435
|
-
end
|
436
416
|
|
437
|
-
|
438
|
-
specify "should not raise errors" do
|
417
|
+
specify "explain and analyze should not raise errors" do
|
439
418
|
@d = POSTGRES_DB[:test3]
|
440
419
|
proc{@d.explain}.should_not raise_error
|
441
420
|
proc{@d.analyze}.should_not raise_error
|
442
421
|
end
|
422
|
+
|
423
|
+
specify "#locks should be a dataset returning database locks " do
|
424
|
+
@db.locks.should be_a_kind_of(Sequel::Dataset)
|
425
|
+
@db.locks.all.should be_a_kind_of(Array)
|
426
|
+
end
|
443
427
|
end
|
444
428
|
|
445
429
|
describe "A PostgreSQL database" do
|
446
430
|
before do
|
447
431
|
@db = POSTGRES_DB
|
432
|
+
@db.create_table! :test2 do
|
433
|
+
text :name
|
434
|
+
integer :value
|
435
|
+
end
|
436
|
+
end
|
437
|
+
after do
|
438
|
+
@db.drop_table?(:test2)
|
448
439
|
end
|
449
440
|
|
450
441
|
specify "should support column operations" do
|
@@ -478,11 +469,6 @@ describe "A PostgreSQL database" do
|
|
478
469
|
|
479
470
|
@db[:test2].first[:xyz].should == 57
|
480
471
|
end
|
481
|
-
|
482
|
-
specify "#locks should be a dataset returning database locks " do
|
483
|
-
@db.locks.should be_a_kind_of(Sequel::Dataset)
|
484
|
-
@db.locks.all.should be_a_kind_of(Array)
|
485
|
-
end
|
486
472
|
end
|
487
473
|
|
488
474
|
describe "A PostgreSQL database" do
|
@@ -679,9 +665,9 @@ describe "Postgres::Dataset#insert" do
|
|
679
665
|
end
|
680
666
|
|
681
667
|
specify "should return nil if the table has no primary key" do
|
682
|
-
|
683
|
-
ds.delete
|
684
|
-
ds.insert(:name=>'a').should == nil
|
668
|
+
@db.create_table!(:test5){String :name; Integer :value}
|
669
|
+
@ds.delete
|
670
|
+
@ds.insert(:name=>'a').should == nil
|
685
671
|
end
|
686
672
|
end
|
687
673
|
|
@@ -763,7 +749,7 @@ describe "Postgres::Database schema qualified tables" do
|
|
763
749
|
|
764
750
|
specify "should be able to get serial sequences for tables in a given schema" do
|
765
751
|
POSTGRES_DB.create_table(:schema_test__schema_test){primary_key :i}
|
766
|
-
POSTGRES_DB.primary_key_sequence(:schema_test__schema_test).should == '"schema_test".schema_test_i_seq'
|
752
|
+
POSTGRES_DB.primary_key_sequence(:schema_test__schema_test).should == '"schema_test"."schema_test_i_seq"'
|
767
753
|
end
|
768
754
|
|
769
755
|
specify "should be able to get serial sequences for tables that have spaces in the name in a given schema" do
|
@@ -789,7 +775,7 @@ describe "Postgres::Database schema qualified tables" do
|
|
789
775
|
POSTGRES_DB.table_exists?(:schema_test).should == true
|
790
776
|
POSTGRES_DB.tables.should == [:schema_test]
|
791
777
|
POSTGRES_DB.primary_key(:schema_test__schema_test).should == 'i'
|
792
|
-
POSTGRES_DB.primary_key_sequence(:schema_test__schema_test).should == '"schema_test".schema_test_i_seq'
|
778
|
+
POSTGRES_DB.primary_key_sequence(:schema_test__schema_test).should == '"schema_test"."schema_test_i_seq"'
|
793
779
|
end
|
794
780
|
end
|
795
781
|
|
@@ -972,20 +958,21 @@ describe "Postgres::Database schema qualified tables and eager graphing" do
|
|
972
958
|
end
|
973
959
|
|
974
960
|
if POSTGRES_DB.server_version >= 80300
|
975
|
-
|
976
|
-
POSTGRES_DB.create_table! :test6 do
|
977
|
-
text :title
|
978
|
-
text :body
|
979
|
-
full_text_index [:title, :body]
|
980
|
-
end
|
981
|
-
|
982
961
|
describe "PostgreSQL tsearch2" do
|
983
|
-
before do
|
962
|
+
before(:all) do
|
963
|
+
POSTGRES_DB.create_table! :test6 do
|
964
|
+
text :title
|
965
|
+
text :body
|
966
|
+
full_text_index [:title, :body]
|
967
|
+
end
|
984
968
|
@ds = POSTGRES_DB[:test6]
|
985
969
|
end
|
986
970
|
after do
|
987
971
|
POSTGRES_DB[:test6].delete
|
988
972
|
end
|
973
|
+
after(:all) do
|
974
|
+
POSTGRES_DB.drop_table?(:test6)
|
975
|
+
end
|
989
976
|
|
990
977
|
specify "should search by indexed column" do
|
991
978
|
record = {:title => "oopsla conference", :body => "test"}
|
@@ -1244,6 +1231,78 @@ if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG && POSTGRE
|
|
1244
1231
|
end
|
1245
1232
|
end
|
1246
1233
|
|
1234
|
+
describe "Postgres::Database#copy_table_from" do
|
1235
|
+
before(:all) do
|
1236
|
+
@db = POSTGRES_DB
|
1237
|
+
@db.create_table!(:test_copy){Integer :x; Integer :y}
|
1238
|
+
@ds = @db[:test_copy].order(:x, :y)
|
1239
|
+
end
|
1240
|
+
before do
|
1241
|
+
@db[:test_copy].delete
|
1242
|
+
end
|
1243
|
+
after(:all) do
|
1244
|
+
@db.drop_table?(:test_copy)
|
1245
|
+
end
|
1246
|
+
|
1247
|
+
specify "should work with a :data option containing data in PostgreSQL text format" do
|
1248
|
+
@db.copy_into(:test_copy, :data=>"1\t2\n3\t4\n")
|
1249
|
+
@ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
|
1250
|
+
end
|
1251
|
+
|
1252
|
+
specify "should work with :format=>:csv option and :data option containing data in CSV format" do
|
1253
|
+
@db.copy_into(:test_copy, :format=>:csv, :data=>"1,2\n3,4\n")
|
1254
|
+
@ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
|
1255
|
+
end
|
1256
|
+
|
1257
|
+
specify "should respect given :options" do
|
1258
|
+
@db.copy_into(:test_copy, :options=>"FORMAT csv, HEADER TRUE", :data=>"x,y\n1,2\n3,4\n")
|
1259
|
+
@ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
|
1260
|
+
end
|
1261
|
+
|
1262
|
+
specify "should respect given :options options when :format is used" do
|
1263
|
+
@db.copy_into(:test_copy, :options=>"QUOTE '''', DELIMITER '|'", :format=>:csv, :data=>"'1'|'2'\n'3'|'4'\n")
|
1264
|
+
@ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
|
1265
|
+
end
|
1266
|
+
|
1267
|
+
specify "should accept :columns option to online copy the given columns" do
|
1268
|
+
@db.copy_into(:test_copy, :data=>"1\t2\n3\t4\n", :columns=>[:y, :x])
|
1269
|
+
@ds.select_map([:x, :y]).should == [[2, 1], [4, 3]]
|
1270
|
+
end
|
1271
|
+
|
1272
|
+
specify "should accept a block and use returned values for the copy in data stream" do
|
1273
|
+
buf = ["1\t2\n", "3\t4\n"]
|
1274
|
+
@db.copy_into(:test_copy){buf.shift}
|
1275
|
+
@ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
|
1276
|
+
end
|
1277
|
+
|
1278
|
+
specify "should work correctly with a block and :format=>:csv" do
|
1279
|
+
buf = ["1,2\n", "3,4\n"]
|
1280
|
+
@db.copy_into(:test_copy, :format=>:csv){buf.shift}
|
1281
|
+
@ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
|
1282
|
+
end
|
1283
|
+
|
1284
|
+
specify "should accept an enumerable as the :data option" do
|
1285
|
+
@db.copy_into(:test_copy, :data=>["1\t2\n", "3\t4\n"])
|
1286
|
+
@ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
|
1287
|
+
end
|
1288
|
+
|
1289
|
+
specify "should have an exception should cause a rollback of copied data and still have a usable connection" do
|
1290
|
+
2.times do
|
1291
|
+
sent = false
|
1292
|
+
proc{@db.copy_into(:test_copy){raise ArgumentError if sent; sent = true; "1\t2\n"}}.should raise_error(ArgumentError)
|
1293
|
+
@ds.select_map([:x, :y]).should == []
|
1294
|
+
end
|
1295
|
+
end
|
1296
|
+
|
1297
|
+
specify "should raise an Error if both :data and a block are provided" do
|
1298
|
+
proc{@db.copy_into(:test_copy, :data=>["1\t2\n", "3\t4\n"]){}}.should raise_error(Sequel::Error)
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
specify "should raise an Error if neither :data or a block are provided" do
|
1302
|
+
proc{@db.copy_into(:test_copy)}.should raise_error(Sequel::Error)
|
1303
|
+
end
|
1304
|
+
end
|
1305
|
+
|
1247
1306
|
describe "Postgres::Database LISTEN/NOTIFY" do
|
1248
1307
|
before(:all) do
|
1249
1308
|
@db = POSTGRES_DB
|
@@ -2363,6 +2422,7 @@ end if ((require 'active_support/duration'; require 'active_support/inflector';
|
|
2363
2422
|
describe 'PostgreSQL row-valued/composite types' do
|
2364
2423
|
before(:all) do
|
2365
2424
|
@db = POSTGRES_DB
|
2425
|
+
Sequel.extension :pg_array_ops, :pg_row_ops
|
2366
2426
|
@db.extension :pg_array, :pg_row
|
2367
2427
|
@ds = @db[:person]
|
2368
2428
|
|
@@ -2450,7 +2510,6 @@ describe 'PostgreSQL row-valued/composite types' do
|
|
2450
2510
|
end if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
|
2451
2511
|
|
2452
2512
|
specify 'operations/functions with pg_row_ops' do
|
2453
|
-
Sequel.extension :pg_row_ops, :pg_array_ops
|
2454
2513
|
@ds.insert(:id=>1, :address=>Sequel.pg_row(['123 Sesame St', 'Somewhere', '12345']))
|
2455
2514
|
@ds.get(Sequel.pg_row(:address)[:street]).should == '123 Sesame St'
|
2456
2515
|
@ds.get(Sequel.pg_row(:address)[:city]).should == 'Somewhere'
|
@@ -2470,6 +2529,45 @@ describe 'PostgreSQL row-valued/composite types' do
|
|
2470
2529
|
@ds.get(Sequel.pg_row(:company)[:employees][1][:address][:zip]).should == '12345'
|
2471
2530
|
end
|
2472
2531
|
|
2532
|
+
context "#splat and #*" do
|
2533
|
+
before(:all) do
|
2534
|
+
@db.create_table!(:a){Integer :a}
|
2535
|
+
@db.create_table!(:b){a :b; Integer :a}
|
2536
|
+
@db.register_row_type(:a)
|
2537
|
+
@db.register_row_type(:b)
|
2538
|
+
@db[:b].insert(:a=>1, :b=>@db.row_type(:a, [2]))
|
2539
|
+
end
|
2540
|
+
after(:all) do
|
2541
|
+
@db.drop_table?(:b, :a)
|
2542
|
+
end
|
2543
|
+
|
2544
|
+
specify "splat should reference the table type" do
|
2545
|
+
@db[:b].select(:a).first.should == {:a=>1}
|
2546
|
+
@db[:b].select(:b__a).first.should == {:a=>1}
|
2547
|
+
@db[:b].select(Sequel.pg_row(:b)[:a]).first.should == {:a=>2}
|
2548
|
+
@db[:b].select(Sequel.pg_row(:b).splat[:a]).first.should == {:a=>1}
|
2549
|
+
|
2550
|
+
if @native
|
2551
|
+
@db[:b].select(:b).first.should == {:b=>{:a=>2}}
|
2552
|
+
@db[:b].select(Sequel.pg_row(:b).splat).first.should == {:a=>1, :b=>{:a=>2}}
|
2553
|
+
@db[:b].select(Sequel.pg_row(:b).splat(:b)).first.should == {:b=>{:a=>1, :b=>{:a=>2}}}
|
2554
|
+
end
|
2555
|
+
end
|
2556
|
+
|
2557
|
+
specify "* should expand the table type into separate columns" do
|
2558
|
+
ds = @db[:b].select(Sequel.pg_row(:b).splat(:b)).from_self(:alias=>:t)
|
2559
|
+
if @native
|
2560
|
+
ds.first.should == {:b=>{:a=>1, :b=>{:a=>2}}}
|
2561
|
+
ds.select(Sequel.pg_row(:b).*).first.should == {:a=>1, :b=>{:a=>2}}
|
2562
|
+
ds.select(Sequel.pg_row(:b)[:b]).first.should == {:b=>{:a=>2}}
|
2563
|
+
ds.select(Sequel.pg_row(:t__b).*).first.should == {:a=>1, :b=>{:a=>2}}
|
2564
|
+
ds.select(Sequel.pg_row(:t__b)[:b]).first.should == {:b=>{:a=>2}}
|
2565
|
+
end
|
2566
|
+
ds.select(Sequel.pg_row(:b)[:a]).first.should == {:a=>1}
|
2567
|
+
ds.select(Sequel.pg_row(:t__b)[:a]).first.should == {:a=>1}
|
2568
|
+
end
|
2569
|
+
end
|
2570
|
+
|
2473
2571
|
context "with models" do
|
2474
2572
|
before(:all) do
|
2475
2573
|
class Address < Sequel::Model(:address)
|