sequel 2.12.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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}]
|