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