sequel 2.12.0 → 3.0.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 +3 -3
- data/Rakefile +7 -0
- data/doc/advanced_associations.rdoc +44 -0
- data/doc/release_notes/3.0.0.txt +221 -0
- data/lib/sequel/adapters/amalgalite.rb +208 -0
- data/lib/sequel/adapters/db2.rb +3 -0
- data/lib/sequel/adapters/dbi.rb +9 -0
- data/lib/sequel/adapters/do.rb +0 -4
- data/lib/sequel/adapters/firebird.rb +16 -18
- data/lib/sequel/adapters/informix.rb +5 -3
- data/lib/sequel/adapters/jdbc.rb +24 -20
- data/lib/sequel/adapters/jdbc/h2.rb +15 -4
- data/lib/sequel/adapters/mysql.rb +4 -8
- data/lib/sequel/adapters/odbc.rb +0 -4
- data/lib/sequel/adapters/oracle.rb +0 -4
- data/lib/sequel/adapters/shared/mssql.rb +16 -5
- data/lib/sequel/adapters/shared/mysql.rb +87 -86
- data/lib/sequel/adapters/shared/oracle.rb +92 -3
- data/lib/sequel/adapters/shared/postgres.rb +85 -29
- data/lib/sequel/adapters/shared/progress.rb +8 -3
- data/lib/sequel/adapters/shared/sqlite.rb +53 -23
- data/lib/sequel/adapters/sqlite.rb +4 -7
- data/lib/sequel/adapters/utils/unsupported.rb +3 -3
- data/lib/sequel/connection_pool.rb +18 -25
- data/lib/sequel/core.rb +2 -21
- data/lib/sequel/database.rb +60 -44
- data/lib/sequel/database/schema_generator.rb +26 -31
- data/lib/sequel/database/schema_methods.rb +8 -3
- data/lib/sequel/database/schema_sql.rb +114 -28
- data/lib/sequel/dataset.rb +14 -41
- data/lib/sequel/dataset/convenience.rb +31 -54
- data/lib/sequel/dataset/graph.rb +7 -13
- data/lib/sequel/dataset/sql.rb +43 -54
- data/lib/sequel/extensions/inflector.rb +0 -5
- data/lib/sequel/extensions/schema_dumper.rb +238 -0
- data/lib/sequel/metaprogramming.rb +0 -20
- data/lib/sequel/model.rb +1 -2
- data/lib/sequel/model/base.rb +18 -16
- data/lib/sequel/model/inflections.rb +6 -9
- data/lib/sequel/plugins/caching.rb +0 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/sql.rb +2 -0
- data/lib/sequel/version.rb +2 -2
- data/spec/adapters/firebird_spec.rb +35 -8
- data/spec/adapters/mysql_spec.rb +173 -266
- data/spec/adapters/oracle_spec.rb +13 -0
- data/spec/adapters/postgres_spec.rb +127 -227
- data/spec/adapters/sqlite_spec.rb +13 -171
- data/spec/core/connection_pool_spec.rb +15 -4
- data/spec/core/core_sql_spec.rb +14 -170
- data/spec/core/database_spec.rb +50 -132
- data/spec/core/dataset_spec.rb +47 -930
- data/spec/core/expression_filters_spec.rb +12 -0
- data/spec/core/schema_generator_spec.rb +37 -45
- data/spec/core/schema_spec.rb +26 -16
- data/spec/core/spec_helper.rb +0 -25
- data/spec/extensions/inflector_spec.rb +0 -3
- data/spec/extensions/schema_dumper_spec.rb +292 -0
- data/spec/extensions/serialization_spec.rb +9 -0
- data/spec/extensions/single_table_inheritance_spec.rb +6 -1
- data/spec/extensions/spec_helper.rb +1 -3
- data/spec/extensions/validation_helpers_spec.rb +4 -4
- data/spec/integration/database_test.rb +18 -0
- data/spec/integration/dataset_test.rb +112 -1
- data/spec/integration/eager_loader_test.rb +70 -9
- data/spec/integration/prepared_statement_test.rb +2 -2
- data/spec/integration/schema_test.rb +76 -27
- data/spec/integration/spec_helper.rb +0 -14
- data/spec/integration/transaction_test.rb +27 -0
- data/spec/model/associations_spec.rb +0 -36
- data/spec/model/base_spec.rb +18 -123
- data/spec/model/hooks_spec.rb +2 -235
- data/spec/model/inflector_spec.rb +15 -115
- data/spec/model/model_spec.rb +0 -120
- data/spec/model/plugins_spec.rb +0 -70
- data/spec/model/record_spec.rb +35 -93
- data/spec/model/spec_helper.rb +0 -27
- data/spec/model/validations_spec.rb +0 -931
- metadata +9 -14
- data/lib/sequel/deprecated.rb +0 -593
- data/lib/sequel/deprecated_migration.rb +0 -91
- data/lib/sequel/model/deprecated.rb +0 -204
- data/lib/sequel/model/deprecated_hooks.rb +0 -103
- data/lib/sequel/model/deprecated_inflector.rb +0 -335
- data/lib/sequel/model/deprecated_validations.rb +0 -388
- data/spec/core/core_ext_spec.rb +0 -156
- data/spec/core/migration_spec.rb +0 -263
- data/spec/core/pretty_table_spec.rb +0 -58
- data/spec/model/caching_spec.rb +0 -217
- data/spec/model/schema_spec.rb +0 -92
@@ -58,6 +58,19 @@ context "An Oracle database" do
|
|
58
58
|
expected_schema.should == schema
|
59
59
|
end
|
60
60
|
end
|
61
|
+
|
62
|
+
specify "should create a temporary table" do
|
63
|
+
ORACLE_DB.create_table :test_tmp, :temporary => true do
|
64
|
+
primary_key :id, :integer, :null => false
|
65
|
+
column :name, :text
|
66
|
+
index :name, :unique => true
|
67
|
+
end
|
68
|
+
|
69
|
+
ORACLE_DB.sqls.should == [
|
70
|
+
'CREATE GLOBAL TEMPORARY TABLE test_tmp (id integer NOT NULL PRIMARY KEY AUTOINCREMENT, name text)',
|
71
|
+
'CREATE UNIQUE INDEX test_tmp_name_index ON test_tmp (name)'
|
72
|
+
]
|
73
|
+
end
|
61
74
|
end
|
62
75
|
|
63
76
|
context "An Oracle dataset" do
|
@@ -4,6 +4,16 @@ unless defined?(POSTGRES_DB)
|
|
4
4
|
POSTGRES_URL = 'postgres://postgres:postgres@localhost:5432/reality_spec' unless defined? POSTGRES_URL
|
5
5
|
POSTGRES_DB = Sequel.connect(ENV['SEQUEL_PG_SPEC_DB']||POSTGRES_URL)
|
6
6
|
end
|
7
|
+
|
8
|
+
def POSTGRES_DB.sqls
|
9
|
+
(@sqls ||= [])
|
10
|
+
end
|
11
|
+
logger = Object.new
|
12
|
+
def logger.method_missing(m, msg)
|
13
|
+
POSTGRES_DB.sqls << msg
|
14
|
+
end
|
15
|
+
POSTGRES_DB.logger = logger
|
16
|
+
|
7
17
|
#POSTGRES_DB.instance_variable_set(:@server_version, 80100)
|
8
18
|
POSTGRES_DB.create_table! :test do
|
9
19
|
text :name
|
@@ -21,33 +31,17 @@ POSTGRES_DB.create_table! :test4 do
|
|
21
31
|
varchar :name, :size => 20
|
22
32
|
bytea :value
|
23
33
|
end
|
24
|
-
POSTGRES_DB.create_table! :test5 do
|
25
|
-
primary_key :xid
|
26
|
-
integer :value
|
27
|
-
end
|
28
34
|
|
29
35
|
context "A PostgreSQL database" do
|
30
36
|
before do
|
31
37
|
@db = POSTGRES_DB
|
32
38
|
end
|
33
39
|
|
34
|
-
specify "should provide disconnect functionality" do
|
35
|
-
@db.tables
|
36
|
-
@db.pool.size.should == 1
|
37
|
-
@db.disconnect
|
38
|
-
@db.pool.size.should == 0
|
39
|
-
end
|
40
|
-
|
41
40
|
specify "should provide the server version" do
|
42
41
|
@db.server_version.should > 70000
|
43
42
|
end
|
44
43
|
|
45
|
-
specify "should raise Sequel::Error on error" do
|
46
|
-
proc{@db << "SELECT 1 + 'a'"}.should raise_error(Sequel::Error)
|
47
|
-
end
|
48
|
-
|
49
44
|
specify "should correctly parse the schema" do
|
50
|
-
require 'logger'
|
51
45
|
@db.schema(:test3, :reload=>true).should == [
|
52
46
|
[:value, {:type=>:integer, :allow_null=>true, :default=>nil, :db_type=>"integer", :primary_key=>false}],
|
53
47
|
[:time, {:type=>:datetime, :allow_null=>true, :default=>nil, :db_type=>"timestamp without time zone", :primary_key=>false}]
|
@@ -65,54 +59,6 @@ context "A PostgreSQL dataset" do
|
|
65
59
|
@d.delete # remove all records
|
66
60
|
end
|
67
61
|
|
68
|
-
specify "should return the correct record count" do
|
69
|
-
@d.count.should == 0
|
70
|
-
@d << {:name => 'abc', :value => 123}
|
71
|
-
@d << {:name => 'abc', :value => 456}
|
72
|
-
@d << {:name => 'def', :value => 789}
|
73
|
-
@d.count.should == 3
|
74
|
-
end
|
75
|
-
|
76
|
-
specify "should return the correct records" do
|
77
|
-
@d.to_a.should == []
|
78
|
-
@d << {:name => 'abc', :value => 123}
|
79
|
-
@d << {:name => 'abc', :value => 456}
|
80
|
-
@d << {:name => 'def', :value => 789}
|
81
|
-
|
82
|
-
@d.order(:value).to_a.should == [
|
83
|
-
{:name => 'abc', :value => 123},
|
84
|
-
{:name => 'abc', :value => 456},
|
85
|
-
{:name => 'def', :value => 789}
|
86
|
-
]
|
87
|
-
end
|
88
|
-
|
89
|
-
specify "should update records correctly" do
|
90
|
-
@d << {:name => 'abc', :value => 123}
|
91
|
-
@d << {:name => 'abc', :value => 456}
|
92
|
-
@d << {:name => 'def', :value => 789}
|
93
|
-
@d.filter(:name => 'abc').update(:value => 530)
|
94
|
-
|
95
|
-
# the third record should stay the same
|
96
|
-
# floating-point precision bullshit
|
97
|
-
@d[:name => 'def'][:value].should == 789
|
98
|
-
@d.filter(:value => 530).count.should == 2
|
99
|
-
end
|
100
|
-
|
101
|
-
specify "should delete records correctly" do
|
102
|
-
@d << {:name => 'abc', :value => 123}
|
103
|
-
@d << {:name => 'abc', :value => 456}
|
104
|
-
@d << {:name => 'def', :value => 789}
|
105
|
-
@d.filter(:name => 'abc').delete
|
106
|
-
|
107
|
-
@d.count.should == 1
|
108
|
-
@d.first[:name].should == 'def'
|
109
|
-
end
|
110
|
-
|
111
|
-
specify "should be able to literalize booleans" do
|
112
|
-
proc {@d.literal(true)}.should_not raise_error
|
113
|
-
proc {@d.literal(false)}.should_not raise_error
|
114
|
-
end
|
115
|
-
|
116
62
|
specify "should quote columns and tables using double quotes if quoting identifiers" do
|
117
63
|
@d.quote_identifiers = true
|
118
64
|
@d.select(:name).sql.should == \
|
@@ -176,60 +122,6 @@ context "A PostgreSQL dataset" do
|
|
176
122
|
'SELECT * FROM "test" ORDER BY "name" ASC, "test" DESC'
|
177
123
|
end
|
178
124
|
|
179
|
-
specify "should support transactions" do
|
180
|
-
POSTGRES_DB.transaction do
|
181
|
-
@d << {:name => 'abc', :value => 1}
|
182
|
-
end
|
183
|
-
|
184
|
-
@d.count.should == 1
|
185
|
-
end
|
186
|
-
|
187
|
-
specify "should have #transaction yield the connection" do
|
188
|
-
POSTGRES_DB.transaction do |conn|
|
189
|
-
conn.should_not == nil
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
specify "should correctly rollback transactions" do
|
194
|
-
proc do
|
195
|
-
POSTGRES_DB.transaction do
|
196
|
-
@d << {:name => 'abc', :value => 1}
|
197
|
-
raise Interrupt, 'asdf'
|
198
|
-
end
|
199
|
-
end.should raise_error(Interrupt)
|
200
|
-
|
201
|
-
proc do
|
202
|
-
POSTGRES_DB.transaction do
|
203
|
-
@d << {:name => 'abc', :value => 1}
|
204
|
-
raise Sequel::Rollback
|
205
|
-
end
|
206
|
-
end.should_not raise_error
|
207
|
-
|
208
|
-
@d.count.should == 0
|
209
|
-
end
|
210
|
-
|
211
|
-
specify "should handle returning inside of the block by committing" do
|
212
|
-
def POSTGRES_DB.ret_commit
|
213
|
-
transaction do
|
214
|
-
self[:test] << {:name => 'abc'}
|
215
|
-
return
|
216
|
-
self[:test] << {:name => 'd'}
|
217
|
-
end
|
218
|
-
end
|
219
|
-
@d.count.should == 0
|
220
|
-
POSTGRES_DB.ret_commit
|
221
|
-
@d.count.should == 1
|
222
|
-
POSTGRES_DB.ret_commit
|
223
|
-
@d.count.should == 2
|
224
|
-
proc do
|
225
|
-
POSTGRES_DB.transaction do
|
226
|
-
raise Interrupt, 'asdf'
|
227
|
-
end
|
228
|
-
end.should raise_error(Interrupt)
|
229
|
-
|
230
|
-
@d.count.should == 2
|
231
|
-
end
|
232
|
-
|
233
125
|
specify "should support nested transactions through savepoints using the savepoint option" do
|
234
126
|
POSTGRES_DB.transaction do
|
235
127
|
@d << {:name => '1'}
|
@@ -260,33 +152,6 @@ context "A PostgreSQL dataset" do
|
|
260
152
|
@d.filter(:name => /bc/).count.should == 2
|
261
153
|
@d.filter(:name => /^bc/).count.should == 1
|
262
154
|
end
|
263
|
-
|
264
|
-
specify "should correctly escape strings" do
|
265
|
-
POSTGRES_DB['SELECT ? AS a', "\\dingo"].get(:a) == "\\dingo"
|
266
|
-
end
|
267
|
-
|
268
|
-
specify "should correctly escape strings with quotes" do
|
269
|
-
POSTGRES_DB['SELECT ? AS a', "\\'dingo"].get(:a) == "\\'dingo"
|
270
|
-
end
|
271
|
-
|
272
|
-
specify "should properly escape binary data" do
|
273
|
-
POSTGRES_DB['SELECT ? AS a', "\1\2\3".to_sequel_blob].get(:a) == "\1\2\3"
|
274
|
-
end
|
275
|
-
|
276
|
-
specify "should retrieve binary data as Blob object" do
|
277
|
-
d = POSTGRES_DB[:test4]
|
278
|
-
d << {:name => '123', :value => "\1\2\3".to_sequel_blob}
|
279
|
-
retrieved_binary_value = d[:name => '123'][:value]
|
280
|
-
retrieved_binary_value.should be_a_kind_of(::Sequel::SQL::Blob)
|
281
|
-
retrieved_binary_value.should == "\1\2\3"
|
282
|
-
retrieved_binary_value = d[:value => "\1\2\3".to_sequel_blob][:value]
|
283
|
-
retrieved_binary_value.should be_a_kind_of(::Sequel::SQL::Blob)
|
284
|
-
retrieved_binary_value.should == "\1\2\3"
|
285
|
-
end
|
286
|
-
|
287
|
-
specify "should properly receive binary data" do
|
288
|
-
POSTGRES_DB['SELECT ?::bytea AS a', "a"].get(:a) == "a"
|
289
|
-
end
|
290
155
|
end
|
291
156
|
|
292
157
|
context "A PostgreSQL dataset with a timestamp field" do
|
@@ -343,141 +208,161 @@ end
|
|
343
208
|
|
344
209
|
context "A PostgreSQL database" do
|
345
210
|
before do
|
211
|
+
@db = POSTGRES_DB
|
212
|
+
@db.drop_table(:posts) rescue nil
|
213
|
+
@db.sqls.clear
|
214
|
+
end
|
215
|
+
after do
|
216
|
+
@db.drop_table(:posts) rescue nil
|
346
217
|
end
|
347
218
|
|
348
|
-
specify "should support
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
]
|
219
|
+
specify "should support resetting the primary key sequence" do
|
220
|
+
@db.create_table(:posts){primary_key :a}
|
221
|
+
@db[:posts].insert(:a=>20).should == 20
|
222
|
+
@db[:posts].insert.should == 1
|
223
|
+
@db[:posts].insert.should == 2
|
224
|
+
@db[:posts].insert(:a=>10).should == 10
|
225
|
+
@db.reset_primary_key_sequence(:posts).should == 21
|
226
|
+
@db[:posts].insert.should == 21
|
227
|
+
@db[:posts].order(:a).map(:a).should == [1, 2, 10, 20, 21]
|
358
228
|
end
|
359
229
|
|
360
|
-
specify "should support fulltext indexes
|
361
|
-
|
362
|
-
|
363
|
-
text :body
|
364
|
-
full_text_index [:title, :body], :language => 'french'
|
365
|
-
end
|
366
|
-
POSTGRES_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
|
230
|
+
specify "should support fulltext indexes and searching" do
|
231
|
+
@db.create_table(:posts){text :title; text :body; full_text_index [:title, :body]; full_text_index :title, :language => 'french'}
|
232
|
+
@db.sqls.should == [
|
367
233
|
"CREATE TABLE posts (title text, body text)",
|
368
|
-
"CREATE INDEX posts_title_body_index ON posts USING gin (to_tsvector('
|
234
|
+
"CREATE INDEX posts_title_body_index ON posts USING gin (to_tsvector('simple', (COALESCE(title, '') || ' ' || COALESCE(body, ''))))",
|
235
|
+
"CREATE INDEX posts_title_index ON posts USING gin (to_tsvector('french', (COALESCE(title, ''))))"
|
369
236
|
]
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
"SELECT * FROM posts WHERE (to_tsvector('
|
237
|
+
|
238
|
+
@db[:posts].insert(:title=>'ruby rails', :body=>'yowsa')
|
239
|
+
@db[:posts].insert(:title=>'sequel', :body=>'ruby')
|
240
|
+
@db[:posts].insert(:title=>'ruby scooby', :body=>'x')
|
241
|
+
@db.sqls.clear
|
242
|
+
|
243
|
+
@db[:posts].full_text_search(:title, 'rails').all.should == [{:title=>'ruby rails', :body=>'yowsa'}]
|
244
|
+
@db[:posts].full_text_search([:title, :body], ['yowsa', 'rails']).all.should == [:title=>'ruby rails', :body=>'yowsa']
|
245
|
+
@db[:posts].full_text_search(:title, 'scooby', :language => 'french').all.should == [{:title=>'ruby scooby', :body=>'x'}]
|
246
|
+
@db.sqls.should == [
|
247
|
+
"SELECT * FROM posts WHERE (to_tsvector('simple', (COALESCE(title, ''))) @@ to_tsquery('simple', 'rails'))",
|
248
|
+
"SELECT * FROM posts WHERE (to_tsvector('simple', (COALESCE(title, '') || ' ' || COALESCE(body, ''))) @@ to_tsquery('simple', 'yowsa | rails'))",
|
249
|
+
"SELECT * FROM posts WHERE (to_tsvector('french', (COALESCE(title, ''))) @@ to_tsquery('french', 'scooby'))"]
|
381
250
|
end
|
382
251
|
|
383
252
|
specify "should support spatial indexes" do
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
end
|
388
|
-
POSTGRES_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
|
389
|
-
"CREATE TABLE posts (geom geometry)",
|
253
|
+
@db.create_table(:posts){box :geom; spatial_index [:geom]}
|
254
|
+
@db.sqls.should == [
|
255
|
+
"CREATE TABLE posts (geom box)",
|
390
256
|
"CREATE INDEX posts_geom_index ON posts USING gist (geom)"
|
391
257
|
]
|
392
258
|
end
|
393
259
|
|
394
260
|
specify "should support indexes with index type" do
|
395
|
-
|
396
|
-
|
397
|
-
index :title, :type => 'hash'
|
398
|
-
end
|
399
|
-
POSTGRES_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
|
261
|
+
@db.create_table(:posts){varchar :title, :size => 5; index :title, :type => 'hash'}
|
262
|
+
@db.sqls.should == [
|
400
263
|
"CREATE TABLE posts (title varchar(5))",
|
401
264
|
"CREATE INDEX posts_title_index ON posts USING hash (title)"
|
402
265
|
]
|
403
266
|
end
|
404
267
|
|
405
268
|
specify "should support unique indexes with index type" do
|
406
|
-
|
407
|
-
|
408
|
-
index :title, :type => 'hash', :unique => true
|
409
|
-
end
|
410
|
-
POSTGRES_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
|
269
|
+
@db.create_table(:posts){varchar :title, :size => 5; index :title, :type => 'btree', :unique => true}
|
270
|
+
@db.sqls.should == [
|
411
271
|
"CREATE TABLE posts (title varchar(5))",
|
412
|
-
"CREATE UNIQUE INDEX posts_title_index ON posts USING
|
272
|
+
"CREATE UNIQUE INDEX posts_title_index ON posts USING btree (title)"
|
413
273
|
]
|
414
274
|
end
|
415
275
|
|
416
276
|
specify "should support partial indexes" do
|
417
|
-
|
418
|
-
|
419
|
-
index :title, :where => {:something => 5}
|
420
|
-
end
|
421
|
-
POSTGRES_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
|
277
|
+
@db.create_table(:posts){varchar :title, :size => 5; index :title, :where => {:title => '5'}}
|
278
|
+
@db.sqls.should == [
|
422
279
|
"CREATE TABLE posts (title varchar(5))",
|
423
|
-
"CREATE INDEX posts_title_index ON posts (title) WHERE (
|
280
|
+
"CREATE INDEX posts_title_index ON posts (title) WHERE (title = '5')"
|
424
281
|
]
|
425
282
|
end
|
426
283
|
|
427
284
|
specify "should support identifiers for table names in indicies" do
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
POSTGRES_DB.send(:create_table_sql_list, Sequel::SQL::Identifier.new(:posts__test), *g.create_info).should == [
|
433
|
-
"CREATE TABLE posts__test (title varchar(5))",
|
434
|
-
"CREATE INDEX posts__test_title_index ON posts__test (title) WHERE (something = 5)"
|
285
|
+
@db.create_table(Sequel::SQL::Identifier.new(:posts)){varchar :title, :size => 5; index :title, :where => {:title => '5'}}
|
286
|
+
@db.sqls.should == [
|
287
|
+
"CREATE TABLE posts (title varchar(5))",
|
288
|
+
"CREATE INDEX posts_title_index ON posts (title) WHERE (title = '5')"
|
435
289
|
]
|
436
290
|
end
|
437
291
|
end
|
438
292
|
|
439
|
-
context "Postgres::Dataset#
|
293
|
+
context "Postgres::Dataset#import" do
|
440
294
|
before do
|
441
|
-
@
|
295
|
+
@db = POSTGRES_DB
|
296
|
+
@db.create_table!(:test){Integer :x; Integer :y}
|
297
|
+
@db.sqls.clear
|
298
|
+
@ds = @db[:test]
|
299
|
+
end
|
300
|
+
after do
|
301
|
+
@db.drop_table(:test) rescue nil
|
442
302
|
end
|
443
303
|
|
444
|
-
specify "should return separate insert statements if server_version < 80200" do
|
304
|
+
specify "#import should return separate insert statements if server_version < 80200" do
|
445
305
|
@ds.meta_def(:server_version){80199}
|
446
306
|
|
447
|
-
@ds.
|
307
|
+
@ds.import([:x, :y], [[1, 2], [3, 4]])
|
308
|
+
|
309
|
+
@db.sqls.should == [
|
310
|
+
'BEGIN',
|
448
311
|
'INSERT INTO test (x, y) VALUES (1, 2)',
|
449
|
-
'INSERT INTO test (x, y) VALUES (3, 4)'
|
312
|
+
'INSERT INTO test (x, y) VALUES (3, 4)',
|
313
|
+
'COMMIT'
|
450
314
|
]
|
315
|
+
@ds.all.should == [{:x=>1, :y=>2}, {:x=>3, :y=>4}]
|
451
316
|
end
|
452
317
|
|
453
|
-
specify "should a single insert statement if server_version >= 80200" do
|
318
|
+
specify "#import should a single insert statement if server_version >= 80200" do
|
454
319
|
@ds.meta_def(:server_version){80200}
|
455
|
-
|
456
|
-
@ds.multi_insert_sql([:x, :y], [[1, 2], [3, 4]]).should == [
|
457
|
-
'INSERT INTO test (x, y) VALUES (1, 2), (3, 4)'
|
458
|
-
]
|
459
|
-
|
460
|
-
@ds.meta_def(:server_version){80201}
|
461
320
|
|
462
|
-
@ds.
|
463
|
-
|
321
|
+
@ds.import([:x, :y], [[1, 2], [3, 4]])
|
322
|
+
|
323
|
+
@db.sqls.should == [
|
324
|
+
'BEGIN',
|
325
|
+
'INSERT INTO test (x, y) VALUES (1, 2), (3, 4)',
|
326
|
+
'COMMIT'
|
464
327
|
]
|
328
|
+
@ds.all.should == [{:x=>1, :y=>2}, {:x=>3, :y=>4}]
|
465
329
|
end
|
466
330
|
end
|
467
331
|
|
468
332
|
context "Postgres::Dataset#insert" do
|
469
333
|
before do
|
470
|
-
@
|
471
|
-
@
|
334
|
+
@db = POSTGRES_DB
|
335
|
+
@db.create_table!(:test5){primary_key :xid; Integer :value}
|
336
|
+
@db.sqls.clear
|
337
|
+
@ds = @db[:test5]
|
338
|
+
end
|
339
|
+
after do
|
340
|
+
@db.drop_table(:test5) rescue nil
|
341
|
+
end
|
342
|
+
|
343
|
+
specify "should work regardless of how it is used" do
|
344
|
+
@ds.insert(:value=>10).should == 1
|
345
|
+
@ds.disable_insert_returning.insert(:value=>20).should == 2
|
346
|
+
@ds.meta_def(:server_version){80100}
|
347
|
+
@ds.insert(:value=>13).should == 3
|
348
|
+
|
349
|
+
@db.sqls.reject{|x| x =~ /pg_class/}.should == [
|
350
|
+
'INSERT INTO test5 (value) VALUES (10) RETURNING xid',
|
351
|
+
'INSERT INTO test5 (value) VALUES (20)',
|
352
|
+
"SELECT currval('\"public\".test5_xid_seq')",
|
353
|
+
'INSERT INTO test5 (value) VALUES (13)',
|
354
|
+
"SELECT currval('\"public\".test5_xid_seq')"
|
355
|
+
]
|
356
|
+
@ds.all.should == [{:xid=>1, :value=>10}, {:xid=>2, :value=>20}, {:xid=>3, :value=>13}]
|
472
357
|
end
|
473
358
|
|
474
|
-
specify "should call
|
359
|
+
specify "should call execute_insert if server_version < 80200" do
|
475
360
|
@ds.meta_def(:server_version){80100}
|
476
361
|
@ds.should_receive(:execute_insert).once.with('INSERT INTO test5 (value) VALUES (10)', :table=>:test5, :values=>{:value=>10})
|
477
362
|
@ds.insert(:value=>10)
|
478
363
|
end
|
479
364
|
|
480
|
-
specify "should call
|
365
|
+
specify "should call execute_insert if disabling insert returning" do
|
481
366
|
@ds.disable_insert_returning!
|
482
367
|
@ds.should_receive(:execute_insert).once.with('INSERT INTO test5 (value) VALUES (10)', :table=>:test5, :values=>{:value=>10})
|
483
368
|
@ds.insert(:value=>10)
|
@@ -530,6 +415,7 @@ context "Postgres::Database schema qualified tables" do
|
|
530
415
|
POSTGRES_DB.instance_variable_set(:@primary_key_sequences, {})
|
531
416
|
end
|
532
417
|
after do
|
418
|
+
POSTGRES_DB.quote_identifiers = false
|
533
419
|
POSTGRES_DB << "DROP SCHEMA schema_test CASCADE"
|
534
420
|
POSTGRES_DB.default_schema = :public
|
535
421
|
end
|
@@ -574,13 +460,26 @@ context "Postgres::Database schema qualified tables" do
|
|
574
460
|
|
575
461
|
specify "should be able to get serial sequences for tables in a given schema" do
|
576
462
|
POSTGRES_DB.create_table(:schema_test__schema_test){primary_key :i}
|
577
|
-
POSTGRES_DB.primary_key_sequence(:schema_test__schema_test).should == '"schema_test".
|
463
|
+
POSTGRES_DB.primary_key_sequence(:schema_test__schema_test).should == '"schema_test".schema_test_i_seq'
|
464
|
+
end
|
465
|
+
|
466
|
+
specify "should be able to get serial sequences for tables that have spaces in the name in a given schema" do
|
467
|
+
POSTGRES_DB.quote_identifiers = true
|
468
|
+
POSTGRES_DB.create_table(:"schema_test__schema test"){primary_key :i}
|
469
|
+
POSTGRES_DB.primary_key_sequence(:"schema_test__schema test").should == '"schema_test"."schema test_i_seq"'
|
578
470
|
end
|
579
471
|
|
580
472
|
specify "should be able to get custom sequences for tables in a given schema" do
|
581
473
|
POSTGRES_DB << "CREATE SEQUENCE schema_test.kseq"
|
582
474
|
POSTGRES_DB.create_table(:schema_test__schema_test){integer :j; primary_key :k, :type=>:integer, :default=>"nextval('schema_test.kseq'::regclass)".lit}
|
583
|
-
POSTGRES_DB.primary_key_sequence(:schema_test__schema_test).should == '"schema_test".
|
475
|
+
POSTGRES_DB.primary_key_sequence(:schema_test__schema_test).should == '"schema_test".kseq'
|
476
|
+
end
|
477
|
+
|
478
|
+
specify "should be able to get custom sequences for tables that have spaces in the name in a given schema" do
|
479
|
+
POSTGRES_DB.quote_identifiers = true
|
480
|
+
POSTGRES_DB << "CREATE SEQUENCE schema_test.\"ks eq\""
|
481
|
+
POSTGRES_DB.create_table(:"schema_test__schema test"){integer :j; primary_key :k, :type=>:integer, :default=>"nextval('schema_test.\"ks eq\"'::regclass)".lit}
|
482
|
+
POSTGRES_DB.primary_key_sequence(:"schema_test__schema test").should == '"schema_test"."ks eq"'
|
584
483
|
end
|
585
484
|
|
586
485
|
specify "#default_schema= should change the default schema used from public" do
|
@@ -589,7 +488,7 @@ context "Postgres::Database schema qualified tables" do
|
|
589
488
|
POSTGRES_DB.table_exists?(:schema_test).should == true
|
590
489
|
POSTGRES_DB.tables.should == [:schema_test]
|
591
490
|
POSTGRES_DB.primary_key(:schema_test__schema_test).should == 'i'
|
592
|
-
POSTGRES_DB.primary_key_sequence(:schema_test__schema_test).should == '"schema_test".
|
491
|
+
POSTGRES_DB.primary_key_sequence(:schema_test__schema_test).should == '"schema_test".schema_test_i_seq'
|
593
492
|
end
|
594
493
|
end
|
595
494
|
|
@@ -637,9 +536,9 @@ context "Postgres::Database functions, languages, and triggers" do
|
|
637
536
|
@d.drop_function('tf', :if_exists=>true, :cascade=>true)
|
638
537
|
@d.drop_function('tf', :if_exists=>true, :cascade=>true, :args=>%w'integer integer')
|
639
538
|
@d.drop_language(:plpgsql, :if_exists=>true, :cascade=>true)
|
640
|
-
@d.
|
539
|
+
@d.drop_table(:test) rescue nil
|
641
540
|
end
|
642
|
-
|
541
|
+
|
643
542
|
specify "#create_function and #drop_function should create and drop functions" do
|
644
543
|
proc{@d['SELECT tf()'].all}.should raise_error(Sequel::DatabaseError)
|
645
544
|
args = ['tf', 'SELECT 1', {:returns=>:integer}]
|
@@ -682,6 +581,7 @@ context "Postgres::Database functions, languages, and triggers" do
|
|
682
581
|
@d.create_language(:plpgsql)
|
683
582
|
@d.create_function(:tf, 'BEGIN IF NEW.value IS NULL THEN RAISE EXCEPTION \'Blah\'; END IF; RETURN NEW; END;', :language=>:plpgsql, :returns=>:trigger)
|
684
583
|
@d.send(:create_trigger_sql, :test, :identity, :tf, :each_row=>true).should == 'CREATE TRIGGER identity BEFORE INSERT OR UPDATE OR DELETE ON public.test FOR EACH ROW EXECUTE PROCEDURE tf()'
|
584
|
+
@d.create_table(:test){String :name; Integer :value}
|
685
585
|
@d.create_trigger(:test, :identity, :tf, :each_row=>true)
|
686
586
|
@d[:test].insert(:name=>'a', :value=>1)
|
687
587
|
@d[:test].filter(:name=>'a').all.should == [{:name=>'a', :value=>1}]
|