sequel 3.28.0 → 3.29.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +119 -3
- data/Rakefile +5 -3
- data/bin/sequel +1 -5
- data/doc/model_hooks.rdoc +9 -1
- data/doc/opening_databases.rdoc +49 -40
- data/doc/prepared_statements.rdoc +27 -6
- data/doc/release_notes/3.28.0.txt +2 -2
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +18 -9
- data/doc/transactions.rdoc +41 -1
- data/lib/sequel/adapters/ado.rb +28 -17
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/amalgalite.rb +11 -7
- data/lib/sequel/adapters/db2.rb +122 -70
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do.rb +5 -36
- data/lib/sequel/adapters/do/mysql.rb +0 -5
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/firebird.rb +3 -6
- data/lib/sequel/adapters/ibmdb.rb +24 -16
- data/lib/sequel/adapters/informix.rb +2 -4
- data/lib/sequel/adapters/jdbc.rb +47 -11
- data/lib/sequel/adapters/jdbc/as400.rb +5 -24
- data/lib/sequel/adapters/jdbc/db2.rb +0 -5
- data/lib/sequel/adapters/jdbc/derby.rb +217 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +0 -5
- data/lib/sequel/adapters/jdbc/h2.rb +10 -12
- data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
- data/lib/sequel/adapters/jdbc/informix.rb +0 -5
- data/lib/sequel/adapters/jdbc/jtds.rb +0 -5
- data/lib/sequel/adapters/jdbc/mysql.rb +0 -10
- data/lib/sequel/adapters/jdbc/oracle.rb +70 -3
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -11
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
- data/lib/sequel/adapters/jdbc/sqlserver.rb +0 -5
- data/lib/sequel/adapters/jdbc/transactions.rb +56 -7
- data/lib/sequel/adapters/mock.rb +315 -0
- data/lib/sequel/adapters/mysql.rb +64 -51
- data/lib/sequel/adapters/mysql2.rb +15 -9
- data/lib/sequel/adapters/odbc.rb +13 -6
- data/lib/sequel/adapters/odbc/db2.rb +0 -4
- data/lib/sequel/adapters/odbc/mssql.rb +0 -5
- data/lib/sequel/adapters/openbase.rb +2 -4
- data/lib/sequel/adapters/oracle.rb +333 -51
- data/lib/sequel/adapters/postgres.rb +80 -27
- data/lib/sequel/adapters/shared/access.rb +0 -6
- data/lib/sequel/adapters/shared/db2.rb +13 -15
- data/lib/sequel/adapters/shared/firebird.rb +6 -6
- data/lib/sequel/adapters/shared/mssql.rb +23 -18
- data/lib/sequel/adapters/shared/mysql.rb +6 -6
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +6 -0
- data/lib/sequel/adapters/shared/oracle.rb +185 -30
- data/lib/sequel/adapters/shared/postgres.rb +35 -18
- data/lib/sequel/adapters/shared/progress.rb +0 -6
- data/lib/sequel/adapters/shared/sqlite.rb +116 -37
- data/lib/sequel/adapters/sqlite.rb +16 -8
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/swift/mysql.rb +0 -5
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +6 -4
- data/lib/sequel/adapters/tinytds.rb +13 -10
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +8 -0
- data/lib/sequel/core.rb +40 -0
- data/lib/sequel/database/connecting.rb +1 -2
- data/lib/sequel/database/dataset.rb +3 -3
- data/lib/sequel/database/dataset_defaults.rb +58 -0
- data/lib/sequel/database/misc.rb +62 -2
- data/lib/sequel/database/query.rb +113 -49
- data/lib/sequel/database/schema_methods.rb +7 -2
- data/lib/sequel/dataset/actions.rb +37 -19
- data/lib/sequel/dataset/features.rb +24 -0
- data/lib/sequel/dataset/graph.rb +7 -6
- data/lib/sequel/dataset/misc.rb +11 -3
- data/lib/sequel/dataset/mutation.rb +2 -3
- data/lib/sequel/dataset/prepared_statements.rb +6 -4
- data/lib/sequel/dataset/query.rb +46 -15
- data/lib/sequel/dataset/sql.rb +28 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/model.rb +2 -1
- data/lib/sequel/model/associations.rb +115 -33
- data/lib/sequel/model/base.rb +91 -31
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +6 -10
- data/lib/sequel/plugins/prepared_statements.rb +12 -1
- data/lib/sequel/plugins/prepared_statements_associations.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +6 -1
- data/lib/sequel/plugins/sharding.rb +0 -5
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +1 -1
- data/lib/sequel/timezones.rb +42 -42
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +29 -29
- data/spec/adapters/mysql_spec.rb +86 -104
- data/spec/adapters/oracle_spec.rb +48 -76
- data/spec/adapters/postgres_spec.rb +98 -33
- data/spec/adapters/spec_helper.rb +0 -5
- data/spec/adapters/sqlite_spec.rb +24 -21
- data/spec/core/connection_pool_spec.rb +9 -15
- data/spec/core/core_sql_spec.rb +20 -31
- data/spec/core/database_spec.rb +491 -227
- data/spec/core/dataset_spec.rb +638 -1051
- data/spec/core/expression_filters_spec.rb +0 -1
- data/spec/core/mock_adapter_spec.rb +378 -0
- data/spec/core/object_graph_spec.rb +48 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +51 -114
- data/spec/core/spec_helper.rb +3 -90
- data/spec/extensions/class_table_inheritance_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/instance_hooks_spec.rb +71 -0
- data/spec/extensions/named_timezones_spec.rb +22 -2
- data/spec/extensions/nested_attributes_spec.rb +3 -0
- data/spec/extensions/schema_spec.rb +1 -1
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -0
- data/spec/extensions/serialization_spec.rb +5 -8
- data/spec/extensions/spec_helper.rb +4 -0
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/integration/associations_test.rb +123 -12
- data/spec/integration/dataset_test.rb +140 -47
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +179 -128
- data/spec/integration/prepared_statement_test.rb +92 -91
- data/spec/integration/schema_test.rb +42 -23
- data/spec/integration/spec_helper.rb +25 -31
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +161 -34
- data/spec/integration/type_test.rb +3 -3
- data/spec/model/association_reflection_spec.rb +83 -7
- data/spec/model/associations_spec.rb +393 -676
- data/spec/model/base_spec.rb +186 -116
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +343 -867
- data/spec/model/hooks_spec.rb +160 -79
- data/spec/model/model_spec.rb +118 -165
- data/spec/model/plugins_spec.rb +7 -13
- data/spec/model/record_spec.rb +138 -207
- data/spec/model/spec_helper.rb +10 -73
- metadata +14 -8
@@ -1,36 +1,26 @@
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
2
|
-
require "timeout"
|
3
2
|
|
4
3
|
unless defined?(ORACLE_DB)
|
5
4
|
ORACLE_DB = Sequel.connect('oracle://hr:hr@localhost/XE')
|
6
5
|
end
|
7
6
|
INTEGRATION_DB = ORACLE_DB unless defined?(INTEGRATION_DB)
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
varchar2 :name, :size => 50
|
14
|
-
number :value, :size => 38
|
15
|
-
date :date_created
|
8
|
+
ORACLE_DB.create_table!(:items) do
|
9
|
+
String :name, :size => 50
|
10
|
+
Integer :value
|
11
|
+
Date :date_created
|
16
12
|
index :value
|
17
13
|
end
|
18
14
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
number :id, :size => 38
|
24
|
-
varchar2 :title, :size => 50
|
25
|
-
number :category_id, :size => 38
|
15
|
+
ORACLE_DB.create_table!(:books) do
|
16
|
+
Integer :id
|
17
|
+
String :title, :size => 50
|
18
|
+
Integer :category_id
|
26
19
|
end
|
27
20
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
ORACLE_DB.create_table :categories do
|
32
|
-
number :id, :size => 38
|
33
|
-
varchar2 :cat_name, :size => 50
|
21
|
+
ORACLE_DB.create_table!(:categories) do
|
22
|
+
Integer :id
|
23
|
+
String :cat_name, :size => 50
|
34
24
|
end
|
35
25
|
|
36
26
|
describe "An Oracle database" do
|
@@ -40,38 +30,39 @@ describe "An Oracle database" do
|
|
40
30
|
ORACLE_DB.disconnect
|
41
31
|
ORACLE_DB.pool.size.should == 0
|
42
32
|
end
|
33
|
+
|
34
|
+
specify "should be able to get current sequence value with SQL" do
|
35
|
+
begin
|
36
|
+
ORACLE_DB.create_table!(:foo){primary_key :id}
|
37
|
+
ORACLE_DB.fetch('SELECT seq_foo_id.nextval FROM DUAL').single_value.should == 1
|
38
|
+
ensure
|
39
|
+
ORACLE_DB.drop_table(:foo)
|
40
|
+
end
|
41
|
+
end
|
43
42
|
|
44
43
|
specify "should provide schema information" do
|
45
|
-
books_schema = [
|
46
|
-
[:
|
47
|
-
[:
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
[:
|
52
|
-
|
53
|
-
[:name, {:char_size=>50, :type=>:varchar2, :allow_null=>true, :type_string=>"VARCHAR2(50)", :data_size=>50, :precision=>0, :char_used=>false, :scale=>0, :charset_form=>:implicit, :fsprecision=>0, :lfprecision=>0, :db_type=>"VARCHAR2(50)"}],
|
54
|
-
[:value, {:char_size=>0, :type=>:number, :allow_null=>true, :type_string=>"NUMBER(38)", :data_size=>22, :precision=>38, :char_used=>false, :scale=>0, :charset_form=>nil, :fsprecision=>38, :lfprecision=>0, :db_type=>"NUMBER(38)"}],
|
55
|
-
[:date_created, {:charset_form=>nil, :type=>:date, :type_string=>"DATE", :fsprecision=>0, :data_size=>7, :lfprecision=>0, :precision=>0, :db_type=>"DATE", :char_used=>false, :char_size=>0, :scale=>0, :allow_null=>true}]]
|
44
|
+
books_schema = [[:id, [:integer, false, true, nil]],
|
45
|
+
[:title, [:string, false, true, nil]],
|
46
|
+
[:category_id, [:integer, false, true, nil]]]
|
47
|
+
categories_schema = [[:id, [:integer, false, true, nil]],
|
48
|
+
[:cat_name, [:string, false, true, nil]]]
|
49
|
+
items_schema = [[:name, [:string, false, true, nil]],
|
50
|
+
[:value, [:integer, false, true, nil]],
|
51
|
+
[:date_created, [:datetime, false, true, nil]]]
|
56
52
|
|
57
53
|
{:books => books_schema, :categories => categories_schema, :items => items_schema}.each_pair do |table, expected_schema|
|
58
54
|
schema = ORACLE_DB.schema(table)
|
59
55
|
schema.should_not be_nil
|
60
|
-
|
56
|
+
schema.map{|c, s| [c, s.values_at(:type, :primary_key, :allow_null, :ruby_default)]}.should == expected_schema
|
61
57
|
end
|
62
58
|
end
|
63
59
|
|
64
60
|
specify "should create a temporary table" do
|
65
|
-
ORACLE_DB.create_table :test_tmp, :
|
61
|
+
ORACLE_DB.create_table! :test_tmp, :temp => true do
|
62
|
+
varchar2 :name, :size => 50
|
66
63
|
primary_key :id, :integer, :null => false
|
67
|
-
column :name, :text
|
68
64
|
index :name, :unique => true
|
69
65
|
end
|
70
|
-
|
71
|
-
ORACLE_DB.sqls.should == [
|
72
|
-
'CREATE GLOBAL TEMPORARY TABLE test_tmp (id integer NOT NULL PRIMARY KEY AUTOINCREMENT, name text)',
|
73
|
-
'CREATE UNIQUE INDEX test_tmp_name_index ON test_tmp (name)'
|
74
|
-
]
|
75
66
|
end
|
76
67
|
end
|
77
68
|
|
@@ -148,27 +139,27 @@ describe "An Oracle dataset" do
|
|
148
139
|
|
149
140
|
@d.max(:value).to_i.should == 789
|
150
141
|
|
151
|
-
@d.select(:name, :AVG.sql_function(:value)).filter(:name => 'abc').group(:name).to_a.should == [
|
152
|
-
{:name => 'abc', :
|
142
|
+
@d.select(:name, :AVG.sql_function(:value).as(:avg)).filter(:name => 'abc').group(:name).to_a.should == [
|
143
|
+
{:name => 'abc', :avg => (456+123)/2.0}
|
153
144
|
]
|
154
145
|
|
155
|
-
@d.select(:AVG.sql_function(:value)).group(:name).order(:name).limit(1).to_a.should == [
|
156
|
-
{:
|
146
|
+
@d.select(:AVG.sql_function(:value).as(:avg)).group(:name).order(:name).limit(1).to_a.should == [
|
147
|
+
{:avg => (456+123)/2.0}
|
157
148
|
]
|
158
149
|
|
159
|
-
@d.select(:name, :AVG.sql_function(:value)).group(:name).order(:name).to_a.should == [
|
160
|
-
{:name => 'abc', :
|
161
|
-
{:name => 'def', :
|
150
|
+
@d.select(:name, :AVG.sql_function(:value).as(:avg)).group(:name).order(:name).to_a.should == [
|
151
|
+
{:name => 'abc', :avg => (456+123)/2.0},
|
152
|
+
{:name => 'def', :avg => 789*1.0}
|
162
153
|
]
|
163
154
|
|
164
|
-
@d.select(:name, :AVG.sql_function(:value)).group(:name).order(:name).to_a.should == [
|
165
|
-
{:name => 'abc', :
|
166
|
-
{:name => 'def', :
|
155
|
+
@d.select(:name, :AVG.sql_function(:value).as(:avg)).group(:name).order(:name).to_a.should == [
|
156
|
+
{:name => 'abc', :avg => (456+123)/2.0},
|
157
|
+
{:name => 'def', :avg => 789*1.0}
|
167
158
|
]
|
168
159
|
|
169
|
-
@d.select(:name, :AVG.sql_function(:value)).group(:name).having(:name => ['abc', 'def']).order(:name).to_a.should == [
|
170
|
-
{:name => 'abc', :
|
171
|
-
{:name => 'def', :
|
160
|
+
@d.select(:name, :AVG.sql_function(:value).as(:avg)).group(:name).having(:name => ['abc', 'def']).order(:name).to_a.should == [
|
161
|
+
{:name => 'abc', :avg => (456+123)/2.0},
|
162
|
+
{:name => 'def', :avg => 789*1.0}
|
172
163
|
]
|
173
164
|
|
174
165
|
@d.select(:name, :value).filter(:name => 'abc').union(@d.select(:name, :value).filter(:name => 'def')).order(:value).to_a.should == [
|
@@ -194,7 +185,7 @@ describe "An Oracle dataset" do
|
|
194
185
|
specify "should translate values correctly" do
|
195
186
|
@d << {:name => 'abc', :value => 456}
|
196
187
|
@d << {:name => 'def', :value => 789}
|
197
|
-
@d.filter(
|
188
|
+
@d.filter('value > 500').update(:date_created => "to_timestamp('2009-09-09', 'YYYY-MM-DD')".lit)
|
198
189
|
|
199
190
|
@d[:name => 'def'][:date_created].should == Time.parse('2009-09-09')
|
200
191
|
end
|
@@ -289,34 +280,15 @@ end
|
|
289
280
|
describe "Row locks in Oracle" do
|
290
281
|
before do
|
291
282
|
@d1 = ORACLE_DB[:books]
|
292
|
-
@d1.delete
|
283
|
+
@d1.delete
|
293
284
|
@d1 << {:id => 1, :title => 'aaa'}
|
294
285
|
end
|
295
286
|
|
296
287
|
specify "#for_update should use FOR UPDATE" do
|
297
|
-
@d1.for_update.sql.should ==
|
288
|
+
@d1.for_update.sql.should == 'SELECT * FROM "BOOKS" FOR UPDATE'
|
298
289
|
end
|
299
290
|
|
300
291
|
specify "#lock_style should accept symbols" do
|
301
|
-
@d1.lock_style(:update).sql.should ==
|
302
|
-
end
|
303
|
-
|
304
|
-
specify "should not update during row lock" do
|
305
|
-
ORACLE_DB.transaction do
|
306
|
-
@d1.filter(:id => 1).for_update.to_a
|
307
|
-
proc do
|
308
|
-
t1 = Thread.start do
|
309
|
-
# wait for unlock
|
310
|
-
Timeout::timeout(0.02) do
|
311
|
-
ORACLE_DB[:books].filter(:id => 1).update(:title => "bbb")
|
312
|
-
end
|
313
|
-
end
|
314
|
-
t1.join
|
315
|
-
end.should raise_error
|
316
|
-
@d1.filter(:id => 1).first[:title].should == "aaa"
|
317
|
-
end
|
318
|
-
t2 = Thread.start { ORACLE_DB[:books].filter(:id => 1).update(:title => "bbb") }
|
319
|
-
t2.join
|
320
|
-
@d1.filter(:id => 1).first[:title].should == "bbb"
|
292
|
+
@d1.lock_style(:update).sql.should == 'SELECT * FROM "BOOKS" FOR UPDATE'
|
321
293
|
end
|
322
294
|
end
|
@@ -197,35 +197,39 @@ if POSTGRES_DB.pool.respond_to?(:max_size) and POSTGRES_DB.pool.max_size > 1
|
|
197
197
|
|
198
198
|
specify "should handle FOR UPDATE" do
|
199
199
|
@ds.insert(:number=>20)
|
200
|
-
c = nil
|
201
|
-
|
200
|
+
c, t = nil, nil
|
201
|
+
q = Queue.new
|
202
202
|
POSTGRES_DB.transaction do
|
203
203
|
@ds.for_update.first(:id=>1)
|
204
204
|
t = Thread.new do
|
205
205
|
POSTGRES_DB.transaction do
|
206
|
+
q.push nil
|
206
207
|
@ds.filter(:id=>1).update(:name=>'Jim')
|
207
208
|
c = @ds.first(:id=>1)
|
209
|
+
q.push nil
|
208
210
|
end
|
209
211
|
end
|
210
|
-
|
212
|
+
q.pop
|
211
213
|
@ds.filter(:id=>1).update(:number=>30)
|
212
214
|
end
|
215
|
+
q.pop
|
213
216
|
t.join
|
214
217
|
c.should == {:id=>1, :number=>30, :name=>'Jim'}
|
215
218
|
end
|
216
219
|
|
217
220
|
specify "should handle FOR SHARE" do
|
218
221
|
@ds.insert(:number=>20)
|
219
|
-
c = nil
|
220
|
-
|
222
|
+
c, t = nil
|
223
|
+
q = Queue.new
|
221
224
|
POSTGRES_DB.transaction do
|
222
225
|
@ds.for_share.first(:id=>1)
|
223
226
|
t = Thread.new do
|
224
227
|
POSTGRES_DB.transaction do
|
225
228
|
c = @ds.for_share.filter(:id=>1).first
|
229
|
+
q.push nil
|
226
230
|
end
|
227
231
|
end
|
228
|
-
|
232
|
+
q.pop
|
229
233
|
@ds.filter(:id=>1).update(:name=>'Jim')
|
230
234
|
c.should == {:id=>1, :number=>20, :name=>nil}
|
231
235
|
end
|
@@ -351,17 +355,17 @@ describe "A PostgreSQL database" do
|
|
351
355
|
specify "should support opclass specification" do
|
352
356
|
@db.create_table(:posts){text :title; text :body; integer :user_id; index(:user_id, :opclass => :int4_ops, :type => :btree)}
|
353
357
|
@db.sqls.should == [
|
354
|
-
|
355
|
-
|
358
|
+
'CREATE TABLE "posts" ("title" text, "body" text, "user_id" integer)',
|
359
|
+
'CREATE INDEX "posts_user_id_index" ON "posts" USING btree ("user_id" int4_ops)'
|
356
360
|
]
|
357
361
|
end
|
358
362
|
|
359
363
|
specify "should support fulltext indexes and searching" do
|
360
364
|
@db.create_table(:posts){text :title; text :body; full_text_index [:title, :body]; full_text_index :title, :language => 'french'}
|
361
365
|
@db.sqls.should == [
|
362
|
-
|
363
|
-
|
364
|
-
|
366
|
+
%{CREATE TABLE "posts" ("title" text, "body" text)},
|
367
|
+
%{CREATE INDEX "posts_title_body_index" ON "posts" USING gin (to_tsvector('simple', (COALESCE("title", '') || ' ' || COALESCE("body", ''))))},
|
368
|
+
%{CREATE INDEX "posts_title_index" ON "posts" USING gin (to_tsvector('french', (COALESCE("title", ''))))}
|
365
369
|
]
|
366
370
|
|
367
371
|
@db[:posts].insert(:title=>'ruby rails', :body=>'yowsa')
|
@@ -373,48 +377,48 @@ describe "A PostgreSQL database" do
|
|
373
377
|
@db[:posts].full_text_search([:title, :body], ['yowsa', 'rails']).all.should == [:title=>'ruby rails', :body=>'yowsa']
|
374
378
|
@db[:posts].full_text_search(:title, 'scooby', :language => 'french').all.should == [{:title=>'ruby scooby', :body=>'x'}]
|
375
379
|
@db.sqls.should == [
|
376
|
-
|
377
|
-
|
378
|
-
|
380
|
+
%{SELECT * FROM "posts" WHERE (to_tsvector('simple', (COALESCE("title", ''))) @@ to_tsquery('simple', 'rails'))},
|
381
|
+
%{SELECT * FROM "posts" WHERE (to_tsvector('simple', (COALESCE("title", '') || ' ' || COALESCE("body", ''))) @@ to_tsquery('simple', 'yowsa | rails'))},
|
382
|
+
%{SELECT * FROM "posts" WHERE (to_tsvector('french', (COALESCE("title", ''))) @@ to_tsquery('french', 'scooby'))}]
|
379
383
|
end
|
380
384
|
|
381
385
|
specify "should support spatial indexes" do
|
382
386
|
@db.create_table(:posts){box :geom; spatial_index [:geom]}
|
383
387
|
@db.sqls.should == [
|
384
|
-
|
385
|
-
|
388
|
+
'CREATE TABLE "posts" ("geom" box)',
|
389
|
+
'CREATE INDEX "posts_geom_index" ON "posts" USING gist ("geom")'
|
386
390
|
]
|
387
391
|
end
|
388
392
|
|
389
393
|
specify "should support indexes with index type" do
|
390
394
|
@db.create_table(:posts){varchar :title, :size => 5; index :title, :type => 'hash'}
|
391
395
|
@db.sqls.should == [
|
392
|
-
|
393
|
-
|
396
|
+
'CREATE TABLE "posts" ("title" varchar(5))',
|
397
|
+
'CREATE INDEX "posts_title_index" ON "posts" USING hash ("title")'
|
394
398
|
]
|
395
399
|
end
|
396
400
|
|
397
401
|
specify "should support unique indexes with index type" do
|
398
402
|
@db.create_table(:posts){varchar :title, :size => 5; index :title, :type => 'btree', :unique => true}
|
399
403
|
@db.sqls.should == [
|
400
|
-
|
401
|
-
|
404
|
+
'CREATE TABLE "posts" ("title" varchar(5))',
|
405
|
+
'CREATE UNIQUE INDEX "posts_title_index" ON "posts" USING btree ("title")'
|
402
406
|
]
|
403
407
|
end
|
404
408
|
|
405
409
|
specify "should support partial indexes" do
|
406
410
|
@db.create_table(:posts){varchar :title, :size => 5; index :title, :where => {:title => '5'}}
|
407
411
|
@db.sqls.should == [
|
408
|
-
|
409
|
-
|
412
|
+
'CREATE TABLE "posts" ("title" varchar(5))',
|
413
|
+
'CREATE INDEX "posts_title_index" ON "posts" ("title") WHERE ("title" = \'5\')'
|
410
414
|
]
|
411
415
|
end
|
412
416
|
|
413
417
|
specify "should support identifiers for table names in indicies" do
|
414
418
|
@db.create_table(Sequel::SQL::Identifier.new(:posts)){varchar :title, :size => 5; index :title, :where => {:title => '5'}}
|
415
419
|
@db.sqls.should == [
|
416
|
-
|
417
|
-
|
420
|
+
'CREATE TABLE "posts" ("title" varchar(5))',
|
421
|
+
'CREATE INDEX "posts_title_index" ON "posts" ("title") WHERE ("title" = \'5\')'
|
418
422
|
]
|
419
423
|
end
|
420
424
|
|
@@ -442,8 +446,8 @@ describe "Postgres::Dataset#import" do
|
|
442
446
|
|
443
447
|
@db.sqls.should == [
|
444
448
|
'BEGIN',
|
445
|
-
'INSERT INTO test (x, y) VALUES (1, 2)',
|
446
|
-
'INSERT INTO test (x, y) VALUES (3, 4)',
|
449
|
+
'INSERT INTO "test" ("x", "y") VALUES (1, 2)',
|
450
|
+
'INSERT INTO "test" ("x", "y") VALUES (3, 4)',
|
447
451
|
'COMMIT'
|
448
452
|
]
|
449
453
|
@ds.all.should == [{:x=>1, :y=>2}, {:x=>3, :y=>4}]
|
@@ -456,7 +460,7 @@ describe "Postgres::Dataset#import" do
|
|
456
460
|
|
457
461
|
@db.sqls.should == [
|
458
462
|
'BEGIN',
|
459
|
-
'INSERT INTO test (x, y) VALUES (1, 2), (3, 4)',
|
463
|
+
'INSERT INTO "test" ("x", "y") VALUES (1, 2), (3, 4)',
|
460
464
|
'COMMIT'
|
461
465
|
]
|
462
466
|
@ds.all.should == [{:x=>1, :y=>2}, {:x=>3, :y=>4}]
|
@@ -487,10 +491,10 @@ describe "Postgres::Dataset#insert" do
|
|
487
491
|
@ds.insert(:value=>13).should == 3
|
488
492
|
|
489
493
|
@db.sqls.reject{|x| x =~ /pg_class/}.should == [
|
490
|
-
'INSERT INTO test5 (value) VALUES (10) RETURNING xid',
|
491
|
-
'INSERT INTO test5 (value) VALUES (20)',
|
494
|
+
'INSERT INTO "test5" ("value") VALUES (10) RETURNING "xid"',
|
495
|
+
'INSERT INTO "test5" ("value") VALUES (20)',
|
492
496
|
"SELECT currval('\"public\".test5_xid_seq')",
|
493
|
-
'INSERT INTO test5 (value) VALUES (13)',
|
497
|
+
'INSERT INTO "test5" ("value") VALUES (13)',
|
494
498
|
"SELECT currval('\"public\".test5_xid_seq')"
|
495
499
|
]
|
496
500
|
@ds.all.should == [{:xid=>1, :value=>10}, {:xid=>2, :value=>20}, {:xid=>3, :value=>13}]
|
@@ -498,20 +502,20 @@ describe "Postgres::Dataset#insert" do
|
|
498
502
|
|
499
503
|
specify "should call execute_insert if server_version < 80200" do
|
500
504
|
@ds.meta_def(:server_version){80100}
|
501
|
-
@ds.should_receive(:execute_insert).once.with('INSERT INTO test5 (value) VALUES (10)', :table=>:test5, :values=>{:value=>10})
|
505
|
+
@ds.should_receive(:execute_insert).once.with('INSERT INTO "test5" ("value") VALUES (10)', :table=>:test5, :values=>{:value=>10})
|
502
506
|
@ds.insert(:value=>10)
|
503
507
|
end
|
504
508
|
|
505
509
|
specify "should call execute_insert if disabling insert returning" do
|
506
510
|
@ds.disable_insert_returning!
|
507
|
-
@ds.should_receive(:execute_insert).once.with('INSERT INTO test5 (value) VALUES (10)', :table=>:test5, :values=>{:value=>10})
|
511
|
+
@ds.should_receive(:execute_insert).once.with('INSERT INTO "test5" ("value") VALUES (10)', :table=>:test5, :values=>{:value=>10})
|
508
512
|
@ds.insert(:value=>10)
|
509
513
|
end
|
510
514
|
|
511
515
|
specify "should use INSERT RETURNING if server_version >= 80200" do
|
512
516
|
@ds.meta_def(:server_version){80201}
|
513
517
|
@ds.insert(:value=>10)
|
514
|
-
@db.sqls.last.should == 'INSERT INTO test5 (value) VALUES (10) RETURNING xid'
|
518
|
+
@db.sqls.last.should == 'INSERT INTO "test5" ("value") VALUES (10) RETURNING "xid"'
|
515
519
|
end
|
516
520
|
|
517
521
|
specify "should have insert_select return nil if server_version < 80200" do
|
@@ -1093,4 +1097,65 @@ if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG && POSTGRE
|
|
1093
1097
|
@db[:test_copy].select_order_map(:x).should == [1, 3]
|
1094
1098
|
end
|
1095
1099
|
end
|
1100
|
+
|
1101
|
+
describe "Postgres::Database LISTEN/NOTIFY" do
|
1102
|
+
before(:all) do
|
1103
|
+
@db = POSTGRES_DB
|
1104
|
+
end
|
1105
|
+
|
1106
|
+
specify "should support listen and notify" do
|
1107
|
+
notify_pid = @db.synchronize{|conn| conn.backend_pid}
|
1108
|
+
|
1109
|
+
called = false
|
1110
|
+
@db.listen('foo', :after_listen=>proc{@db.notify('foo')}) do |ev, pid, payload|
|
1111
|
+
ev.should == 'foo'
|
1112
|
+
pid.should == notify_pid
|
1113
|
+
['', nil].should include(payload)
|
1114
|
+
called = true
|
1115
|
+
end.should == 'foo'
|
1116
|
+
called.should be_true
|
1117
|
+
|
1118
|
+
called = false
|
1119
|
+
@db.listen('foo', :after_listen=>proc{@db.notify('foo', :payload=>'bar')}) do |ev, pid, payload|
|
1120
|
+
ev.should == 'foo'
|
1121
|
+
pid.should == notify_pid
|
1122
|
+
payload.should == 'bar'
|
1123
|
+
called = true
|
1124
|
+
end.should == 'foo'
|
1125
|
+
called.should be_true
|
1126
|
+
|
1127
|
+
@db.listen('foo', :after_listen=>proc{@db.notify('foo')}).should == 'foo'
|
1128
|
+
|
1129
|
+
called = false
|
1130
|
+
called2 = false
|
1131
|
+
i = 0
|
1132
|
+
@db.listen(['foo', 'bar'], :after_listen=>proc{@db.notify('foo', :payload=>'bar'); @db.notify('bar', :payload=>'foo')}, :loop=>proc{i+=1}) do |ev, pid, payload|
|
1133
|
+
if !called
|
1134
|
+
ev.should == 'foo'
|
1135
|
+
pid.should == notify_pid
|
1136
|
+
payload.should == 'bar'
|
1137
|
+
called = true
|
1138
|
+
else
|
1139
|
+
ev.should == 'bar'
|
1140
|
+
pid.should == notify_pid
|
1141
|
+
payload.should == 'foo'
|
1142
|
+
called2 = true
|
1143
|
+
break
|
1144
|
+
end
|
1145
|
+
end.should be_nil
|
1146
|
+
called.should be_true
|
1147
|
+
called2.should be_true
|
1148
|
+
i.should == 1
|
1149
|
+
end
|
1150
|
+
|
1151
|
+
specify "should accept a :timeout option in listen" do
|
1152
|
+
@db.listen('foo2', :timeout=>0.001).should == nil
|
1153
|
+
called = false
|
1154
|
+
@db.listen('foo2', :timeout=>0.001){|ev, pid, payload| called = true}.should == nil
|
1155
|
+
called.should be_false
|
1156
|
+
i = 0
|
1157
|
+
@db.listen('foo2', :timeout=>0.001, :loop=>proc{i+=1; throw :stop if i > 3}){|ev, pid, payload| called = true}.should == nil
|
1158
|
+
i.should == 4
|
1159
|
+
end
|
1160
|
+
end
|
1096
1161
|
end
|
@@ -3,7 +3,6 @@ require 'logger'
|
|
3
3
|
unless Object.const_defined?('Sequel')
|
4
4
|
$:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), "../../lib/"))
|
5
5
|
require 'sequel'
|
6
|
-
Sequel.quote_identifiers = false
|
7
6
|
end
|
8
7
|
begin
|
9
8
|
require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'spec_config.rb')
|
@@ -31,10 +30,6 @@ end
|
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
34
|
-
def self.log_specify(message, &block)
|
35
|
-
specify(message){log{instance_eval(&block)}}
|
36
|
-
end
|
37
|
-
|
38
33
|
def self.cspecify(message, *checked, &block)
|
39
34
|
return specify(message, &block) if ENV['SEQUEL_NO_PENDING']
|
40
35
|
pending = false
|