sequel 0.5.0.2 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/COPYING +18 -18
  2. data/Rakefile +17 -98
  3. data/lib/sequel.rb +2 -71
  4. metadata +10 -108
  5. data/CHANGELOG +0 -989
  6. data/bin/sequel +0 -41
  7. data/lib/sequel/adapters/adapter_skeleton.rb +0 -68
  8. data/lib/sequel/adapters/ado.rb +0 -100
  9. data/lib/sequel/adapters/db2.rb +0 -158
  10. data/lib/sequel/adapters/dbi.rb +0 -126
  11. data/lib/sequel/adapters/informix.rb +0 -87
  12. data/lib/sequel/adapters/jdbc.rb +0 -108
  13. data/lib/sequel/adapters/mysql.rb +0 -269
  14. data/lib/sequel/adapters/odbc.rb +0 -145
  15. data/lib/sequel/adapters/odbc_mssql.rb +0 -93
  16. data/lib/sequel/adapters/openbase.rb +0 -90
  17. data/lib/sequel/adapters/oracle.rb +0 -99
  18. data/lib/sequel/adapters/postgres.rb +0 -519
  19. data/lib/sequel/adapters/sqlite.rb +0 -192
  20. data/lib/sequel/ado.rb +0 -6
  21. data/lib/sequel/array_keys.rb +0 -296
  22. data/lib/sequel/connection_pool.rb +0 -152
  23. data/lib/sequel/core_ext.rb +0 -59
  24. data/lib/sequel/core_sql.rb +0 -191
  25. data/lib/sequel/database.rb +0 -433
  26. data/lib/sequel/dataset.rb +0 -409
  27. data/lib/sequel/dataset/convenience.rb +0 -321
  28. data/lib/sequel/dataset/sequelizer.rb +0 -354
  29. data/lib/sequel/dataset/sql.rb +0 -586
  30. data/lib/sequel/db2.rb +0 -6
  31. data/lib/sequel/dbi.rb +0 -6
  32. data/lib/sequel/exceptions.rb +0 -45
  33. data/lib/sequel/informix.rb +0 -6
  34. data/lib/sequel/migration.rb +0 -191
  35. data/lib/sequel/model.rb +0 -8
  36. data/lib/sequel/mysql.rb +0 -6
  37. data/lib/sequel/odbc.rb +0 -6
  38. data/lib/sequel/oracle.rb +0 -6
  39. data/lib/sequel/postgres.rb +0 -6
  40. data/lib/sequel/pretty_table.rb +0 -73
  41. data/lib/sequel/schema.rb +0 -8
  42. data/lib/sequel/schema/schema_generator.rb +0 -131
  43. data/lib/sequel/schema/schema_sql.rb +0 -131
  44. data/lib/sequel/sqlite.rb +0 -6
  45. data/lib/sequel/worker.rb +0 -58
  46. data/spec/adapters/informix_spec.rb +0 -139
  47. data/spec/adapters/mysql_spec.rb +0 -330
  48. data/spec/adapters/oracle_spec.rb +0 -130
  49. data/spec/adapters/postgres_spec.rb +0 -189
  50. data/spec/adapters/sqlite_spec.rb +0 -345
  51. data/spec/array_keys_spec.rb +0 -679
  52. data/spec/connection_pool_spec.rb +0 -356
  53. data/spec/core_ext_spec.rb +0 -67
  54. data/spec/core_sql_spec.rb +0 -301
  55. data/spec/database_spec.rb +0 -811
  56. data/spec/dataset_spec.rb +0 -2381
  57. data/spec/migration_spec.rb +0 -261
  58. data/spec/pretty_table_spec.rb +0 -66
  59. data/spec/rcov.opts +0 -4
  60. data/spec/schema_generator_spec.rb +0 -86
  61. data/spec/schema_spec.rb +0 -230
  62. data/spec/sequel_spec.rb +0 -10
  63. data/spec/sequelizer_spec.rb +0 -389
  64. data/spec/spec.opts +0 -5
  65. data/spec/spec_helper.rb +0 -44
  66. data/spec/worker_spec.rb +0 -96
@@ -1,811 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper')
2
-
3
- context "A new Database" do
4
- setup do
5
- @db = Sequel::Database.new(1 => 2, :logger => 3)
6
- end
7
-
8
- specify "should receive options" do
9
- @db.opts.should == {1 => 2, :logger => 3}
10
- end
11
-
12
- specify "should set the logger from opts[:logger]" do
13
- @db.logger.should == 3
14
- end
15
-
16
- specify "should create a connection pool" do
17
- @db.pool.should be_a_kind_of(Sequel::ConnectionPool)
18
- @db.pool.max_size.should == 4
19
-
20
- Sequel::Database.new(:max_connections => 10).pool.max_size.should == 10
21
- end
22
-
23
- specify "should pass the supplied block to the connection pool" do
24
- cc = nil
25
- d = Sequel::Database.new {1234}
26
- d.synchronize {|c| cc = c}
27
- cc.should == 1234
28
- end
29
- end
30
-
31
- context "Database#connect" do
32
- specify "should raise Sequel::Error::NotImplemented" do
33
- proc {Sequel::Database.new.connect}.should raise_error(NotImplementedError)
34
- end
35
- end
36
-
37
- context "Database#disconnect" do
38
- specify "should raise Sequel::Error::NotImplemented" do
39
- proc {Sequel::Database.new.disconnect}.should raise_error(NotImplementedError)
40
- end
41
- end
42
-
43
- context "Database#uri" do
44
- setup do
45
- @c = Class.new(Sequel::Database) do
46
- set_adapter_scheme :mau
47
- end
48
-
49
- @db = Sequel('mau://user:pass@localhost:9876/maumau')
50
- end
51
-
52
- specify "should return the connection URI for the database" do
53
- @db.uri.should == 'mau://user:pass@localhost:9876/maumau'
54
- end
55
- end
56
-
57
- context "Database.adapter_scheme" do
58
- specify "should return the database schema" do
59
- Sequel::Database.adapter_scheme.should be_nil
60
-
61
- @c = Class.new(Sequel::Database) do
62
- set_adapter_scheme :mau
63
- end
64
-
65
- @c.adapter_scheme.should == :mau
66
- end
67
- end
68
-
69
- context "Database#dataset" do
70
- setup do
71
- @db = Sequel::Database.new
72
- @ds = @db.dataset
73
- end
74
-
75
- specify "should provide a blank dataset through #dataset" do
76
- @ds.should be_a_kind_of(Sequel::Dataset)
77
- @ds.opts.should == {}
78
- @ds.db.should be(@db)
79
- end
80
-
81
- specify "should provide a #from dataset" do
82
- d = @db.from(:mau)
83
- d.should be_a_kind_of(Sequel::Dataset)
84
- d.sql.should == 'SELECT * FROM mau'
85
-
86
- e = @db[:miu]
87
- e.should be_a_kind_of(Sequel::Dataset)
88
- e.sql.should == 'SELECT * FROM miu'
89
- end
90
-
91
- specify "should provide a filtered #from dataset if a block is given" do
92
- d = @db.from(:mau) {:x > 100}
93
- d.should be_a_kind_of(Sequel::Dataset)
94
- d.sql.should == 'SELECT * FROM mau WHERE (x > 100)'
95
- end
96
-
97
- specify "should provide a #select dataset" do
98
- d = @db.select(:a, :b, :c).from(:mau)
99
- d.should be_a_kind_of(Sequel::Dataset)
100
- d.sql.should == 'SELECT a, b, c FROM mau'
101
- end
102
- end
103
-
104
- context "Database#execute" do
105
- specify "should raise Sequel::Error::NotImplemented" do
106
- proc {Sequel::Database.new.execute('blah blah')}.should raise_error(NotImplementedError)
107
- proc {Sequel::Database.new << 'blah blah'}.should raise_error(NotImplementedError)
108
- end
109
- end
110
-
111
- context "Database#<<" do
112
- setup do
113
- @c = Class.new(Sequel::Database) do
114
- define_method(:execute) {|sql| sql}
115
- end
116
- @db = @c.new({})
117
- end
118
-
119
- specify "should pass the supplied sql to #execute" do
120
- (@db << "DELETE FROM items").should == "DELETE FROM items"
121
- end
122
-
123
- specify "should accept an array and convert it to SQL" do
124
- a = %[
125
- --
126
- CREATE TABLE items (a integer, /*b integer*/
127
- b text, c integer);
128
- DROP TABLE old_items;
129
- ].split($/)
130
- (@db << a).should ==
131
- "CREATE TABLE items (a integer, b text, c integer); DROP TABLE old_items;"
132
- end
133
-
134
- specify "should remove comments and whitespace from arrays" do
135
- s = %[
136
- --
137
- CREATE TABLE items (a integer, /*b integer*/
138
- b text, c integer); \r\n
139
- DROP TABLE old_items;
140
- ].split($/)
141
- (@db << s).should ==
142
- "CREATE TABLE items (a integer, b text, c integer); DROP TABLE old_items;"
143
- end
144
-
145
- specify "should not remove comments and whitespace from strings" do
146
- s = "INSERT INTO items VALUES ('---abc')"
147
- (@db << s).should == s
148
- end
149
- end
150
-
151
- context "Database#synchronize" do
152
- setup do
153
- @db = Sequel::Database.new(:max_connections => 1)
154
- @db.pool.connection_proc = proc {12345}
155
- end
156
-
157
- specify "should wrap the supplied block in pool.hold" do
158
- stop = false
159
- c1, c2 = nil
160
- t1 = Thread.new {@db.synchronize {|c| c1 = c; while !stop;sleep 0.1;end}}
161
- while !c1;end
162
- c1.should == 12345
163
- t2 = Thread.new {@db.synchronize {|c| c2 = c}}
164
- sleep 0.2
165
- @db.pool.available_connections.should be_empty
166
- c2.should be_nil
167
- stop = true
168
- t1.join
169
- sleep 0.1
170
- c2.should == 12345
171
- t2.join
172
- end
173
- end
174
-
175
- context "Database#test_connection" do
176
- setup do
177
- @db = Sequel::Database.new
178
- @test = nil
179
- @db.pool.connection_proc = proc {@test = rand(100)}
180
- end
181
-
182
- specify "should call pool#hold" do
183
- @db.test_connection
184
- @test.should_not be_nil
185
- end
186
-
187
- specify "should return true if successful" do
188
- @db.test_connection.should be_true
189
- end
190
- end
191
-
192
- class DummyDataset < Sequel::Dataset
193
- def first
194
- raise if @opts[:from] == [:a]
195
- true
196
- end
197
- end
198
-
199
- class DummyDatabase < Sequel::Database
200
- attr_reader :sqls
201
-
202
- def execute(sql)
203
- @sqls ||= []
204
- @sqls << sql
205
- end
206
-
207
- def transaction; yield; end
208
-
209
- def dataset
210
- DummyDataset.new(self)
211
- end
212
- end
213
-
214
- context "Database#create_table" do
215
- setup do
216
- @db = DummyDatabase.new
217
- end
218
-
219
- specify "should construct proper SQL" do
220
- @db.create_table :test do
221
- primary_key :id, :integer, :null => false
222
- column :name, :text
223
- index :name, :unique => true
224
- end
225
- @db.sqls.should == [
226
- 'CREATE TABLE test (id integer NOT NULL PRIMARY KEY AUTOINCREMENT, name text)',
227
- 'CREATE UNIQUE INDEX test_name_index ON test (name)'
228
- ]
229
- end
230
- end
231
-
232
- context "Database#alter_table" do
233
- setup do
234
- @db = DummyDatabase.new
235
- end
236
-
237
- specify "should construct proper SQL" do
238
- @db.alter_table :xyz do
239
- add_column :aaa, :text, :null => false, :unique => true
240
- drop_column :bbb
241
- rename_column :ccc, :ddd
242
- set_column_type :eee, :integer
243
- set_column_default :hhh, 'abcd'
244
-
245
- add_index :fff, :unique => true
246
- drop_index :ggg
247
- end
248
-
249
- @db.sqls.should == [
250
- 'ALTER TABLE xyz ADD COLUMN aaa text UNIQUE NOT NULL',
251
- 'ALTER TABLE xyz DROP COLUMN bbb',
252
- 'ALTER TABLE xyz RENAME COLUMN ccc TO ddd',
253
- 'ALTER TABLE xyz ALTER COLUMN eee TYPE integer',
254
- "ALTER TABLE xyz ALTER COLUMN hhh SET DEFAULT 'abcd'",
255
-
256
- 'CREATE UNIQUE INDEX xyz_fff_index ON xyz (fff)',
257
- 'DROP INDEX xyz_ggg_index'
258
- ]
259
- end
260
- end
261
-
262
- context "Database#add_column" do
263
- setup do
264
- @db = DummyDatabase.new
265
- end
266
-
267
- specify "should construct proper SQL" do
268
- @db.add_column :test, :name, :text, :unique => true
269
- @db.sqls.should == [
270
- 'ALTER TABLE test ADD COLUMN name text UNIQUE'
271
- ]
272
- end
273
- end
274
-
275
- context "Database#drop_column" do
276
- setup do
277
- @db = DummyDatabase.new
278
- end
279
-
280
- specify "should construct proper SQL" do
281
- @db.drop_column :test, :name
282
- @db.sqls.should == [
283
- 'ALTER TABLE test DROP COLUMN name'
284
- ]
285
- end
286
- end
287
-
288
- context "Database#rename_column" do
289
- setup do
290
- @db = DummyDatabase.new
291
- end
292
-
293
- specify "should construct proper SQL" do
294
- @db.rename_column :test, :abc, :def
295
- @db.sqls.should == [
296
- 'ALTER TABLE test RENAME COLUMN abc TO def'
297
- ]
298
- end
299
- end
300
-
301
- context "Database#set_column_type" do
302
- setup do
303
- @db = DummyDatabase.new
304
- end
305
-
306
- specify "should construct proper SQL" do
307
- @db.set_column_type :test, :name, :integer
308
- @db.sqls.should == [
309
- 'ALTER TABLE test ALTER COLUMN name TYPE integer'
310
- ]
311
- end
312
- end
313
-
314
- context "Database#set_column_default" do
315
- setup do
316
- @db = DummyDatabase.new
317
- end
318
-
319
- specify "should construct proper SQL" do
320
- @db.set_column_default :test, :name, 'zyx'
321
- @db.sqls.should == [
322
- "ALTER TABLE test ALTER COLUMN name SET DEFAULT 'zyx'"
323
- ]
324
- end
325
- end
326
-
327
- context "Database#add_index" do
328
- setup do
329
- @db = DummyDatabase.new
330
- end
331
-
332
- specify "should construct proper SQL" do
333
- @db.add_index :test, :name, :unique => true
334
- @db.sqls.should == [
335
- 'CREATE UNIQUE INDEX test_name_index ON test (name)'
336
- ]
337
- end
338
-
339
- specify "should accept multiple columns" do
340
- @db.add_index :test, [:one, :two]
341
- @db.sqls.should == [
342
- 'CREATE INDEX test_one_two_index ON test (one, two)'
343
- ]
344
- end
345
- end
346
-
347
- context "Database#drop_index" do
348
- setup do
349
- @db = DummyDatabase.new
350
- end
351
-
352
- specify "should construct proper SQL" do
353
- @db.drop_index :test, :name
354
- @db.sqls.should == [
355
- 'DROP INDEX test_name_index'
356
- ]
357
- end
358
-
359
- end
360
-
361
- class Dummy2Database < Sequel::Database
362
- attr_reader :sql
363
- def execute(sql); @sql = sql; end
364
- def transaction; yield; end
365
- end
366
-
367
- context "Database#drop_table" do
368
- setup do
369
- @db = DummyDatabase.new
370
- end
371
-
372
- specify "should construct proper SQL" do
373
- @db.drop_table :test
374
- @db.sqls.should == ['DROP TABLE test']
375
- end
376
-
377
- specify "should accept multiple table names" do
378
- @db.drop_table :a, :bb, :ccc
379
- @db.sqls.should == [
380
- 'DROP TABLE a',
381
- 'DROP TABLE bb',
382
- 'DROP TABLE ccc'
383
- ]
384
- end
385
- end
386
-
387
- context "Database#rename_table" do
388
- setup do
389
- @db = DummyDatabase.new
390
- end
391
-
392
- specify "should construct proper SQL" do
393
- @db.rename_table :abc, :xyz
394
- @db.sqls.should == ['ALTER TABLE abc RENAME TO xyz']
395
- end
396
- end
397
-
398
- context "Database#table_exists?" do
399
- setup do
400
- @db = DummyDatabase.new
401
- @db.stub!(:tables).and_return([:a, :b])
402
- @db2 = DummyDatabase.new
403
- Sequel::Dataset.stub!(:first).and_return(nil)
404
- end
405
-
406
- specify "should use Database#tables if available" do
407
- @db.table_exists?(:a).should be_true
408
- @db.table_exists?(:b).should be_true
409
- @db.table_exists?(:c).should be_false
410
- end
411
-
412
- specify "should otherwise try to select the first record from the table's dataset" do
413
- @db2.table_exists?(:a).should be_false
414
- @db2.table_exists?(:b).should be_true
415
- end
416
- end
417
-
418
-
419
- class Dummy3Database < Sequel::Database
420
- attr_reader :sql, :transactions
421
- def execute(sql); @sql ||= []; @sql << sql; end
422
-
423
- class DummyConnection
424
- def initialize(db); @db = db; end
425
- def execute(sql); @db.execute(sql); end
426
- end
427
- end
428
-
429
- context "Database#transaction" do
430
- setup do
431
- @db = Dummy3Database.new
432
- @db.pool.connection_proc = proc {Dummy3Database::DummyConnection.new(@db)}
433
- end
434
-
435
- specify "should wrap the supplied block with BEGIN + COMMIT statements" do
436
- @db.transaction {@db.execute 'DROP TABLE test;'}
437
- @db.sql.should == ['BEGIN', 'DROP TABLE test;', 'COMMIT']
438
- end
439
-
440
- specify "should issue ROLLBACK if an exception is raised, and re-raise" do
441
- @db.transaction {@db.execute 'DROP TABLE test'; raise RuntimeError} rescue nil
442
- @db.sql.should == ['BEGIN', 'DROP TABLE test', 'ROLLBACK']
443
-
444
- proc {@db.transaction {raise RuntimeError}}.should raise_error(RuntimeError)
445
- end
446
-
447
- specify "should issue ROLLBACK if rollback! is called in the transaction" do
448
- @db.transaction do
449
- @db.drop_table(:a)
450
- rollback!
451
- @db.drop_table(:b)
452
- end
453
-
454
- @db.sql.should == ['BEGIN', 'DROP TABLE a', 'ROLLBACK']
455
- end
456
-
457
- specify "should be re-entrant" do
458
- stop = false
459
- cc = nil
460
- t = Thread.new do
461
- @db.transaction {@db.transaction {@db.transaction {|c|
462
- cc = c
463
- while !stop; sleep 0.1; end
464
- }}}
465
- end
466
- while cc.nil?; sleep 0.1; end
467
- cc.should be_a_kind_of(Dummy3Database::DummyConnection)
468
- @db.transactions.should == [t]
469
- stop = true
470
- t.join
471
- @db.transactions.should be_empty
472
- end
473
- end
474
-
475
- class Sequel::Database
476
- def self.get_adapters; @@adapters; end
477
- end
478
-
479
- context "A Database adapter with a scheme" do
480
- setup do
481
- class CCC < Sequel::Database
482
- set_adapter_scheme :ccc
483
- end
484
- end
485
-
486
- specify "should be registered in adapters" do
487
- Sequel::Database.get_adapters[:ccc].should == CCC
488
- end
489
-
490
- specify "should be instantiated when its scheme is specified" do
491
- c = Sequel::Database.connect('ccc://localhost/db')
492
- c.should be_a_kind_of(CCC)
493
- c.opts[:host].should == 'localhost'
494
- c.opts[:database].should == 'db'
495
- end
496
-
497
- specify "should be accessible through Sequel.connect" do
498
- c = Sequel.connect 'ccc://localhost/db'
499
- c.should be_a_kind_of(CCC)
500
- c.opts[:host].should == 'localhost'
501
- c.opts[:database].should == 'db'
502
- end
503
-
504
- specify "should be accessible through Sequel.open" do
505
- c = Sequel.open 'ccc://localhost/db'
506
- c.should be_a_kind_of(CCC)
507
- c.opts[:host].should == 'localhost'
508
- c.opts[:database].should == 'db'
509
- end
510
-
511
- specify "should be accessible through Sequel()" do
512
- c = Sequel('ccc://localhost/db')
513
- c.should be_a_kind_of(CCC)
514
- c.opts[:host].should == 'localhost'
515
- c.opts[:database].should == 'db'
516
- end
517
-
518
- specify "should be accessible through Sequel.<adapter>" do
519
- # invalid parameters
520
- proc {Sequel.ccc('abc', 'def')}.should raise_error(Sequel::Error)
521
-
522
- c = Sequel.ccc('mydb')
523
- c.should be_a_kind_of(CCC)
524
- c.opts.should == {:database => 'mydb'}
525
-
526
- c = Sequel.ccc('mydb', :host => 'localhost')
527
- c.should be_a_kind_of(CCC)
528
- c.opts.should == {:database => 'mydb', :host => 'localhost'}
529
-
530
- c = Sequel.ccc
531
- c.should be_a_kind_of(CCC)
532
- c.opts.should == {}
533
-
534
- c = Sequel.ccc(:database => 'mydb', :host => 'localhost')
535
- c.should be_a_kind_of(CCC)
536
- c.opts.should == {:database => 'mydb', :host => 'localhost'}
537
- end
538
-
539
- specify "should be accessible through Sequel.connect with options" do
540
- c = Sequel.connect(:adapter => :ccc, :database => 'mydb')
541
- c.should be_a_kind_of(CCC)
542
- c.opts.should == {:adapter => :ccc, :database => 'mydb'}
543
- end
544
- end
545
-
546
- context "An unknown database scheme" do
547
- specify "should raise an error in Sequel::Database.connect" do
548
- proc {Sequel::Database.connect('ddd://localhost/db')}.should raise_error(Sequel::Error::AdapterNotFound)
549
- end
550
-
551
- specify "should raise an error in Sequel.connect" do
552
- proc {Sequel.connect('ddd://localhost/db')}.should raise_error(Sequel::Error::AdapterNotFound)
553
- end
554
-
555
- specify "should raise an error in Sequel.open" do
556
- proc {Sequel.open('ddd://localhost/db')}.should raise_error(Sequel::Error::AdapterNotFound)
557
- end
558
- end
559
-
560
- context "A broken adapter (lib is there but the class is not)" do
561
- setup do
562
- FileUtils.touch('lib/sequel/adapters/blah.rb')
563
- end
564
-
565
- teardown do
566
- FileUtils.rm('lib/sequel/adapters/blah.rb')
567
- end
568
-
569
- specify "should raise an error" do
570
- proc {Sequel.connect('blah://blow')}.should raise_error(Sequel::Error::AdapterNotFound)
571
- end
572
- end
573
-
574
- context "Database#uri_to_options" do
575
- specify "should convert a URI to an options hash" do
576
- h = Sequel::Database.uri_to_options(URI.parse('ttt://uuu:ppp@192.168.60.1:1234/blah'))
577
- h[:user].should == 'uuu'
578
- h[:password].should == 'ppp'
579
- h[:host].should == '192.168.60.1'
580
- h[:port].should == 1234
581
- h[:database].should == 'blah'
582
- end
583
- end
584
-
585
- context "A single threaded database" do
586
- teardown do
587
- Sequel::Database.single_threaded = false
588
- end
589
-
590
- specify "should use a SingleThreadedPool instead of a ConnectionPool" do
591
- db = Sequel::Database.new(:single_threaded => true)
592
- db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
593
- end
594
-
595
- specify "should be constructable using :single_threaded => true option" do
596
- db = Sequel::Database.new(:single_threaded => true)
597
- db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
598
- end
599
-
600
- specify "should be constructable using Database.single_threaded = true" do
601
- Sequel::Database.single_threaded = true
602
- db = Sequel::Database.new
603
- db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
604
- end
605
-
606
- specify "should be constructable using Sequel.single_threaded = true" do
607
- Sequel.single_threaded = true
608
- db = Sequel::Database.new
609
- db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
610
- end
611
- end
612
-
613
- context "A single threaded database" do
614
- setup do
615
- conn = 1234567
616
- @db = Sequel::Database.new(:single_threaded => true) do
617
- conn += 1
618
- end
619
- end
620
-
621
- specify "should invoke connection_proc only once" do
622
- @db.pool.hold {|c| c.should == 1234568}
623
- @db.pool.hold {|c| c.should == 1234568}
624
- end
625
-
626
- specify "should convert an Exception into a RuntimeError" do
627
- db = Sequel::Database.new(:single_threaded => true) do
628
- raise Exception
629
- end
630
-
631
- proc {db.pool.hold {|c|}}.should raise_error(RuntimeError)
632
- end
633
- end
634
-
635
- context "A database" do
636
- setup do
637
- Sequel::Database.single_threaded = false
638
- end
639
-
640
- teardown do
641
- Sequel::Database.single_threaded = false
642
- end
643
-
644
- specify "should be either single_threaded? or multi_threaded?" do
645
- db = Sequel::Database.new(:single_threaded => true)
646
- db.should be_single_threaded
647
- db.should_not be_multi_threaded
648
-
649
- db = Sequel::Database.new(:max_options => 1)
650
- db.should_not be_single_threaded
651
- db.should be_multi_threaded
652
-
653
- db = Sequel::Database.new
654
- db.should_not be_single_threaded
655
- db.should be_multi_threaded
656
-
657
- Sequel::Database.single_threaded = true
658
-
659
- db = Sequel::Database.new
660
- db.should be_single_threaded
661
- db.should_not be_multi_threaded
662
-
663
- db = Sequel::Database.new(:max_options => 4)
664
- db.should be_single_threaded
665
- db.should_not be_multi_threaded
666
- end
667
-
668
- specify "should accept a logger object" do
669
- db = Sequel::Database.new
670
- s = "I'm a logger"
671
- db.logger = s
672
- db.logger.should be(s)
673
- db.logger = nil
674
- db.logger.should be_nil
675
- end
676
- end
677
-
678
- context "Database#dataset" do
679
- setup do
680
- @db = Sequel::Database.new
681
- end
682
-
683
- specify "should delegate to Dataset#query if block is provided" do
684
- @d = @db.query {select :x; from :y}
685
- @d.should be_a_kind_of(Sequel::Dataset)
686
- @d.sql.should == "SELECT x FROM y"
687
- end
688
- end
689
-
690
- context "Database#fetch" do
691
- setup do
692
- @db = Sequel::Database.new
693
- c = Class.new(Sequel::Dataset) do
694
- def fetch_rows(sql); yield({:sql => sql}); end
695
- end
696
- @db.meta_def(:dataset) {c.new(self)}
697
- end
698
-
699
- specify "should create a dataset and invoke its fetch_rows method with the given sql" do
700
- sql = nil
701
- @db.fetch('select * from xyz') {|r| sql = r[:sql]}
702
- sql.should == 'select * from xyz'
703
- end
704
-
705
- specify "should format the given sql with any additional arguments" do
706
- sql = nil
707
- @db.fetch('select * from xyz where x = ? and y = ?', 15, 'abc') {|r| sql = r[:sql]}
708
- sql.should == "select * from xyz where x = 15 and y = 'abc'"
709
-
710
- # and Aman Gupta's example
711
- @db.fetch('select name from table where name = ? or id in (?)',
712
- 'aman', [3,4,7]) {|r| sql = r[:sql]}
713
- sql.should == "select name from table where name = 'aman' or id in (3, 4, 7)"
714
- end
715
-
716
- specify "should return the dataset if no block is given" do
717
- @db.fetch('select * from xyz').should be_a_kind_of(Sequel::Dataset)
718
-
719
- @db.fetch('select a from b').map {|r| r[:sql]}.should == ['select a from b']
720
-
721
- @db.fetch('select c from d').inject([]) {|m, r| m << r; m}.should == \
722
- [{:sql => 'select c from d'}]
723
- end
724
-
725
- specify "should return a dataset that always uses the given sql for SELECTs" do
726
- ds = @db.fetch('select * from xyz')
727
- ds.select_sql.should == 'select * from xyz'
728
- ds.sql.should == 'select * from xyz'
729
-
730
- ds.filter! {:price < 100}
731
- ds.select_sql.should == 'select * from xyz'
732
- ds.sql.should == 'select * from xyz'
733
- end
734
- end
735
-
736
- context "Database#[]" do
737
- setup do
738
- @db = Sequel::Database.new
739
- end
740
-
741
- specify "should return a dataset when symbols are given" do
742
- ds = @db[:items]
743
- ds.class.should == Sequel::Dataset
744
- ds.opts[:from].should == [:items]
745
- end
746
-
747
- specify "should return an enumerator when a string is given" do
748
- c = Class.new(Sequel::Dataset) do
749
- def fetch_rows(sql); yield({:sql => sql}); end
750
- end
751
- @db.meta_def(:dataset) {c.new(self)}
752
-
753
- sql = nil
754
- @db['select * from xyz where x = ? and y = ?', 15, 'abc'].each {|r| sql = r[:sql]}
755
- sql.should == "select * from xyz where x = 15 and y = 'abc'"
756
- end
757
- end
758
-
759
- context "Database#create_view" do
760
- setup do
761
- @db = DummyDatabase.new
762
- end
763
-
764
- specify "should construct proper SQL with raw SQL" do
765
- @db.create_view :test, "SELECT * FROM xyz"
766
- @db.sqls.should == ['CREATE VIEW test AS SELECT * FROM xyz']
767
- end
768
-
769
- specify "should construct proper SQL with dataset" do
770
- @db.create_view :test, @db[:items].select(:a, :b).order(:c)
771
- @db.sqls.should == ['CREATE VIEW test AS SELECT a, b FROM items ORDER BY c']
772
- end
773
- end
774
-
775
- context "Database#create_or_replace_view" do
776
- setup do
777
- @db = DummyDatabase.new
778
- end
779
-
780
- specify "should construct proper SQL with raw SQL" do
781
- @db.create_or_replace_view :test, "SELECT * FROM xyz"
782
- @db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT * FROM xyz']
783
- end
784
-
785
- specify "should construct proper SQL with dataset" do
786
- @db.create_or_replace_view :test, @db[:items].select(:a, :b).order(:c)
787
- @db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT a, b FROM items ORDER BY c']
788
- end
789
- end
790
-
791
- context "Database#drop_view" do
792
- setup do
793
- @db = DummyDatabase.new
794
- end
795
-
796
- specify "should construct proper SQL" do
797
- @db.drop_view :test
798
- @db.sqls.should == ['DROP VIEW test']
799
- end
800
- end
801
-
802
- # TODO: beaf this up with specs for all supported ops
803
- context "Database#alter_table_sql" do
804
- setup do
805
- @db = DummyDatabase.new
806
- end
807
-
808
- specify "should raise error for an invalid op" do
809
- proc {@db.alter_table_sql(:mau, :op => :blah)}.should raise_error(Sequel::Error)
810
- end
811
- end