sequel_core 2.2.0 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
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