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.
Files changed (91) hide show
  1. data/CHANGELOG +62 -0
  2. data/README.rdoc +3 -3
  3. data/Rakefile +7 -0
  4. data/doc/advanced_associations.rdoc +44 -0
  5. data/doc/release_notes/3.0.0.txt +221 -0
  6. data/lib/sequel/adapters/amalgalite.rb +208 -0
  7. data/lib/sequel/adapters/db2.rb +3 -0
  8. data/lib/sequel/adapters/dbi.rb +9 -0
  9. data/lib/sequel/adapters/do.rb +0 -4
  10. data/lib/sequel/adapters/firebird.rb +16 -18
  11. data/lib/sequel/adapters/informix.rb +5 -3
  12. data/lib/sequel/adapters/jdbc.rb +24 -20
  13. data/lib/sequel/adapters/jdbc/h2.rb +15 -4
  14. data/lib/sequel/adapters/mysql.rb +4 -8
  15. data/lib/sequel/adapters/odbc.rb +0 -4
  16. data/lib/sequel/adapters/oracle.rb +0 -4
  17. data/lib/sequel/adapters/shared/mssql.rb +16 -5
  18. data/lib/sequel/adapters/shared/mysql.rb +87 -86
  19. data/lib/sequel/adapters/shared/oracle.rb +92 -3
  20. data/lib/sequel/adapters/shared/postgres.rb +85 -29
  21. data/lib/sequel/adapters/shared/progress.rb +8 -3
  22. data/lib/sequel/adapters/shared/sqlite.rb +53 -23
  23. data/lib/sequel/adapters/sqlite.rb +4 -7
  24. data/lib/sequel/adapters/utils/unsupported.rb +3 -3
  25. data/lib/sequel/connection_pool.rb +18 -25
  26. data/lib/sequel/core.rb +2 -21
  27. data/lib/sequel/database.rb +60 -44
  28. data/lib/sequel/database/schema_generator.rb +26 -31
  29. data/lib/sequel/database/schema_methods.rb +8 -3
  30. data/lib/sequel/database/schema_sql.rb +114 -28
  31. data/lib/sequel/dataset.rb +14 -41
  32. data/lib/sequel/dataset/convenience.rb +31 -54
  33. data/lib/sequel/dataset/graph.rb +7 -13
  34. data/lib/sequel/dataset/sql.rb +43 -54
  35. data/lib/sequel/extensions/inflector.rb +0 -5
  36. data/lib/sequel/extensions/schema_dumper.rb +238 -0
  37. data/lib/sequel/metaprogramming.rb +0 -20
  38. data/lib/sequel/model.rb +1 -2
  39. data/lib/sequel/model/base.rb +18 -16
  40. data/lib/sequel/model/inflections.rb +6 -9
  41. data/lib/sequel/plugins/caching.rb +0 -6
  42. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  43. data/lib/sequel/sql.rb +2 -0
  44. data/lib/sequel/version.rb +2 -2
  45. data/spec/adapters/firebird_spec.rb +35 -8
  46. data/spec/adapters/mysql_spec.rb +173 -266
  47. data/spec/adapters/oracle_spec.rb +13 -0
  48. data/spec/adapters/postgres_spec.rb +127 -227
  49. data/spec/adapters/sqlite_spec.rb +13 -171
  50. data/spec/core/connection_pool_spec.rb +15 -4
  51. data/spec/core/core_sql_spec.rb +14 -170
  52. data/spec/core/database_spec.rb +50 -132
  53. data/spec/core/dataset_spec.rb +47 -930
  54. data/spec/core/expression_filters_spec.rb +12 -0
  55. data/spec/core/schema_generator_spec.rb +37 -45
  56. data/spec/core/schema_spec.rb +26 -16
  57. data/spec/core/spec_helper.rb +0 -25
  58. data/spec/extensions/inflector_spec.rb +0 -3
  59. data/spec/extensions/schema_dumper_spec.rb +292 -0
  60. data/spec/extensions/serialization_spec.rb +9 -0
  61. data/spec/extensions/single_table_inheritance_spec.rb +6 -1
  62. data/spec/extensions/spec_helper.rb +1 -3
  63. data/spec/extensions/validation_helpers_spec.rb +4 -4
  64. data/spec/integration/database_test.rb +18 -0
  65. data/spec/integration/dataset_test.rb +112 -1
  66. data/spec/integration/eager_loader_test.rb +70 -9
  67. data/spec/integration/prepared_statement_test.rb +2 -2
  68. data/spec/integration/schema_test.rb +76 -27
  69. data/spec/integration/spec_helper.rb +0 -14
  70. data/spec/integration/transaction_test.rb +27 -0
  71. data/spec/model/associations_spec.rb +0 -36
  72. data/spec/model/base_spec.rb +18 -123
  73. data/spec/model/hooks_spec.rb +2 -235
  74. data/spec/model/inflector_spec.rb +15 -115
  75. data/spec/model/model_spec.rb +0 -120
  76. data/spec/model/plugins_spec.rb +0 -70
  77. data/spec/model/record_spec.rb +35 -93
  78. data/spec/model/spec_helper.rb +0 -27
  79. data/spec/model/validations_spec.rb +0 -931
  80. metadata +9 -14
  81. data/lib/sequel/deprecated.rb +0 -593
  82. data/lib/sequel/deprecated_migration.rb +0 -91
  83. data/lib/sequel/model/deprecated.rb +0 -204
  84. data/lib/sequel/model/deprecated_hooks.rb +0 -103
  85. data/lib/sequel/model/deprecated_inflector.rb +0 -335
  86. data/lib/sequel/model/deprecated_validations.rb +0 -388
  87. data/spec/core/core_ext_spec.rb +0 -156
  88. data/spec/core/migration_spec.rb +0 -263
  89. data/spec/core/pretty_table_spec.rb +0 -58
  90. data/spec/model/caching_spec.rb +0 -217
  91. 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 fulltext indexes" do
349
- g = Sequel::Schema::Generator.new(POSTGRES_DB) do
350
- text :title
351
- text :body
352
- full_text_index [:title, :body]
353
- end
354
- POSTGRES_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
355
- "CREATE TABLE posts (title text, body text)",
356
- "CREATE INDEX posts_title_body_index ON posts USING gin (to_tsvector('simple', (COALESCE(title, '') || ' ' || COALESCE(body, ''))))"
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 with a specific language" do
361
- g = Sequel::Schema::Generator.new(POSTGRES_DB) do
362
- text :title
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('french', (COALESCE(title, '') || ' ' || COALESCE(body, ''))))"
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
- end
371
-
372
- specify "should support full_text_search" do
373
- POSTGRES_DB[:posts].full_text_search(:title, 'ruby').sql.should ==
374
- "SELECT * FROM posts WHERE (to_tsvector('simple', (COALESCE(title, ''))) @@ to_tsquery('simple', 'ruby'))"
375
-
376
- POSTGRES_DB[:posts].full_text_search([:title, :body], ['ruby', 'sequel']).sql.should ==
377
- "SELECT * FROM posts WHERE (to_tsvector('simple', (COALESCE(title, '') || ' ' || COALESCE(body, ''))) @@ to_tsquery('simple', 'ruby | sequel'))"
378
-
379
- POSTGRES_DB[:posts].full_text_search(:title, 'ruby', :language => 'french').sql.should ==
380
- "SELECT * FROM posts WHERE (to_tsvector('french', (COALESCE(title, ''))) @@ to_tsquery('french', 'ruby'))"
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
- g = Sequel::Schema::Generator.new(POSTGRES_DB) do
385
- geometry :geom
386
- spatial_index [:geom]
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
- g = Sequel::Schema::Generator.new(POSTGRES_DB) do
396
- varchar :title, :size => 5
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
- g = Sequel::Schema::Generator.new(POSTGRES_DB) do
407
- varchar :title, :size => 5
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 hash (title)"
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
- g = Sequel::Schema::Generator.new(POSTGRES_DB) do
418
- varchar :title, :size => 5
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 (something = 5)"
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
- g = Sequel::Schema::Generator.new(POSTGRES_DB) do
429
- varchar :title, :size => 5
430
- index :title, :where => {:something => 5}
431
- end
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#multi_insert_sql" do
293
+ context "Postgres::Dataset#import" do
440
294
  before do
441
- @ds = POSTGRES_DB[:test]
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.multi_insert_sql([:x, :y], [[1, 2], [3, 4]]).should == [
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.multi_insert_sql([:x, :y], [[1, 2], [3, 4]]).should == [
463
- 'INSERT INTO test (x, y) VALUES (1, 2), (3, 4)'
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
- @ds = POSTGRES_DB[:test5]
471
- @ds.delete
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 insert_sql if server_version < 80200" do
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 insert_sql if disabling insert returning" do
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"."schema_test_i_seq"'
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"."kseq"'
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"."schema_test_i_seq"'
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.drop_trigger(:test5, :identity, :if_exists=>true, :cascade=>true)
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}]