sequel 3.8.0 → 3.9.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 (65) hide show
  1. data/CHANGELOG +48 -0
  2. data/Rakefile +6 -28
  3. data/bin/sequel +7 -2
  4. data/doc/release_notes/3.9.0.txt +233 -0
  5. data/lib/sequel/adapters/ado.rb +4 -8
  6. data/lib/sequel/adapters/amalgalite.rb +1 -1
  7. data/lib/sequel/adapters/dbi.rb +3 -3
  8. data/lib/sequel/adapters/do.rb +7 -13
  9. data/lib/sequel/adapters/jdbc.rb +10 -16
  10. data/lib/sequel/adapters/jdbc/h2.rb +5 -0
  11. data/lib/sequel/adapters/mysql.rb +10 -23
  12. data/lib/sequel/adapters/odbc.rb +6 -10
  13. data/lib/sequel/adapters/postgres.rb +0 -5
  14. data/lib/sequel/adapters/shared/mssql.rb +17 -9
  15. data/lib/sequel/adapters/shared/mysql.rb +16 -7
  16. data/lib/sequel/adapters/shared/sqlite.rb +5 -0
  17. data/lib/sequel/adapters/sqlite.rb +2 -1
  18. data/lib/sequel/connection_pool.rb +67 -349
  19. data/lib/sequel/connection_pool/sharded_single.rb +84 -0
  20. data/lib/sequel/connection_pool/sharded_threaded.rb +211 -0
  21. data/lib/sequel/connection_pool/single.rb +29 -0
  22. data/lib/sequel/connection_pool/threaded.rb +150 -0
  23. data/lib/sequel/core.rb +46 -15
  24. data/lib/sequel/database.rb +11 -9
  25. data/lib/sequel/dataset/convenience.rb +23 -0
  26. data/lib/sequel/dataset/graph.rb +2 -2
  27. data/lib/sequel/dataset/query.rb +9 -5
  28. data/lib/sequel/dataset/sql.rb +87 -12
  29. data/lib/sequel/extensions/inflector.rb +8 -1
  30. data/lib/sequel/extensions/schema_dumper.rb +3 -4
  31. data/lib/sequel/model/associations.rb +5 -43
  32. data/lib/sequel/model/base.rb +9 -2
  33. data/lib/sequel/model/default_inflections.rb +1 -1
  34. data/lib/sequel/model/exceptions.rb +11 -1
  35. data/lib/sequel/model/inflections.rb +8 -1
  36. data/lib/sequel/model/plugins.rb +2 -12
  37. data/lib/sequel/plugins/active_model.rb +5 -0
  38. data/lib/sequel/plugins/association_dependencies.rb +1 -1
  39. data/lib/sequel/plugins/many_through_many.rb +1 -1
  40. data/lib/sequel/plugins/optimistic_locking.rb +65 -0
  41. data/lib/sequel/plugins/single_table_inheritance.rb +14 -3
  42. data/lib/sequel/plugins/validation_helpers.rb +2 -2
  43. data/lib/sequel/sql.rb +2 -2
  44. data/lib/sequel/timezones.rb +2 -2
  45. data/lib/sequel/version.rb +1 -1
  46. data/spec/adapters/mssql_spec.rb +19 -0
  47. data/spec/adapters/mysql_spec.rb +4 -0
  48. data/spec/adapters/postgres_spec.rb +180 -0
  49. data/spec/adapters/spec_helper.rb +15 -1
  50. data/spec/core/connection_pool_spec.rb +119 -78
  51. data/spec/core/database_spec.rb +41 -50
  52. data/spec/core/dataset_spec.rb +115 -4
  53. data/spec/extensions/active_model_spec.rb +40 -34
  54. data/spec/extensions/boolean_readers_spec.rb +1 -1
  55. data/spec/extensions/migration_spec.rb +43 -38
  56. data/spec/extensions/optimistic_locking_spec.rb +100 -0
  57. data/spec/extensions/schema_dumper_spec.rb +4 -4
  58. data/spec/extensions/single_table_inheritance_spec.rb +19 -11
  59. data/spec/integration/dataset_test.rb +44 -1
  60. data/spec/integration/plugin_test.rb +39 -0
  61. data/spec/integration/prepared_statement_test.rb +58 -7
  62. data/spec/integration/spec_helper.rb +4 -0
  63. data/spec/model/eager_loading_spec.rb +24 -0
  64. data/spec/model/validations_spec.rb +5 -1
  65. metadata +114 -106
@@ -1,4 +1,5 @@
1
1
  require 'rubygems'
2
+ require 'logger'
2
3
  unless Object.const_defined?('Sequel')
3
4
  $:.unshift(File.join(File.dirname(__FILE__), "../../lib/"))
4
5
  require 'sequel'
@@ -10,6 +11,19 @@ rescue LoadError
10
11
  end
11
12
 
12
13
  class Spec::Example::ExampleGroup
14
+ def log
15
+ begin
16
+ INTEGRATION_DB.loggers << Logger.new(STDOUT)
17
+ yield
18
+ ensure
19
+ INTEGRATION_DB.loggers.pop
20
+ end
21
+ end
22
+
23
+ def self.log_specify(message, &block)
24
+ specify(message){log{instance_eval(&block)}}
25
+ end
26
+
13
27
  def self.cspecify(message, *checked, &block)
14
28
  pending = false
15
29
  checked.each do |c|
@@ -28,4 +42,4 @@ class Spec::Example::ExampleGroup
28
42
  specify(message, &block)
29
43
  end
30
44
  end
31
- end
45
+ end
@@ -1,10 +1,9 @@
1
1
  require File.join(File.dirname(__FILE__), 'spec_helper')
2
- CONNECTION_POOL_DEFAULTS = {:pool_timeout=>5, :pool_sleep_time=>0.001,
3
- :pool_reuse_connections=>:allow, :pool_convert_exceptions=>true, :max_connections=>4}
2
+ CONNECTION_POOL_DEFAULTS = {:pool_timeout=>5, :pool_sleep_time=>0.001, :max_connections=>4}
4
3
 
5
4
  context "An empty ConnectionPool" do
6
5
  before do
7
- @cpool = Sequel::ConnectionPool.new(CONNECTION_POOL_DEFAULTS)
6
+ @cpool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS){}
8
7
  end
9
8
 
10
9
  specify "should have no available connections" do
@@ -22,24 +21,24 @@ end
22
21
 
23
22
  context "ConnectionPool options" do
24
23
  specify "should support string option values" do
25
- cpool = Sequel::ConnectionPool.new({:max_connections=>'5', :pool_timeout=>'3', :pool_sleep_time=>'0.01'})
24
+ cpool = Sequel::ConnectionPool.get_pool({:max_connections=>'5', :pool_timeout=>'3', :pool_sleep_time=>'0.01'}){}
26
25
  cpool.max_size.should == 5
27
26
  cpool.instance_variable_get(:@timeout).should == 3
28
27
  cpool.instance_variable_get(:@sleep_time).should == 0.01
29
28
  end
30
29
 
31
30
  specify "should raise an error unless size is positive" do
32
- lambda{Sequel::ConnectionPool.new(:max_connections=>0)}.should raise_error(Sequel::Error)
33
- lambda{Sequel::ConnectionPool.new(:max_connections=>-10)}.should raise_error(Sequel::Error)
34
- lambda{Sequel::ConnectionPool.new(:max_connections=>'-10')}.should raise_error(Sequel::Error)
35
- lambda{Sequel::ConnectionPool.new(:max_connections=>'0')}.should raise_error(Sequel::Error)
31
+ lambda{Sequel::ConnectionPool.get_pool(:max_connections=>0)}.should raise_error(Sequel::Error)
32
+ lambda{Sequel::ConnectionPool.get_pool(:max_connections=>-10)}.should raise_error(Sequel::Error)
33
+ lambda{Sequel::ConnectionPool.get_pool(:max_connections=>'-10')}.should raise_error(Sequel::Error)
34
+ lambda{Sequel::ConnectionPool.get_pool(:max_connections=>'0')}.should raise_error(Sequel::Error)
36
35
  end
37
36
  end
38
37
 
39
38
  context "A connection pool handling connections" do
40
39
  before do
41
40
  @max_size = 2
42
- @cpool = Sequel::ConnectionPool.new(CONNECTION_POOL_DEFAULTS.merge(:disconnection_proc=>proc{|c| @max_size=3}, :max_connections=>@max_size)) {:got_connection}
41
+ @cpool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS.merge(:disconnection_proc=>proc{|c| @max_size=3}, :max_connections=>@max_size)) {:got_connection}
43
42
  end
44
43
 
45
44
  specify "#hold should increment #created_count" do
@@ -95,13 +94,6 @@ context "A connection pool handling connections" do
95
94
  @max_size.should == 3
96
95
  end
97
96
 
98
- specify "#disconnection_proc= should set the disconnection proc to use" do
99
- a = 1
100
- @cpool.disconnection_proc = proc{|c| a += 1}
101
- proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.should raise_error(Sequel::DatabaseDisconnectError)
102
- a.should == 2
103
- end
104
-
105
97
  specify "#hold should remove the connection if a DatabaseDisconnectError is raised" do
106
98
  @cpool.created_count.should == 0
107
99
  @cpool.hold{Thread.new{@cpool.hold{}}; sleep 0.01}
@@ -117,13 +109,13 @@ end
117
109
 
118
110
  context "A connection pool handling connection errors" do
119
111
  specify "#hold should raise a Sequel::DatabaseConnectionError if an exception is raised by the connection_proc" do
120
- cpool = Sequel::ConnectionPool.new(CONNECTION_POOL_DEFAULTS){raise Interrupt}
112
+ cpool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS){raise Interrupt}
121
113
  proc{cpool.hold{:block_return}}.should raise_error(Sequel::DatabaseConnectionError)
122
114
  cpool.created_count.should == 0
123
115
  end
124
116
 
125
117
  specify "#hold should raise a Sequel::DatabaseConnectionError if nil is returned by the connection_proc" do
126
- cpool = Sequel::ConnectionPool.new(CONNECTION_POOL_DEFAULTS){nil}
118
+ cpool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS){nil}
127
119
  proc{cpool.hold{:block_return}}.should raise_error(Sequel::DatabaseConnectionError)
128
120
  cpool.created_count.should == 0
129
121
  end
@@ -142,7 +134,7 @@ end
142
134
 
143
135
  context "ConnectionPool#hold" do
144
136
  before do
145
- @pool = Sequel::ConnectionPool.new(CONNECTION_POOL_DEFAULTS) {DummyConnection.new}
137
+ @pool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS) {DummyConnection.new}
146
138
  end
147
139
 
148
140
  specify "should pass the result of the connection maker proc to the supplied block" do
@@ -164,40 +156,12 @@ context "ConnectionPool#hold" do
164
156
  specify "should catch exceptions and reraise them" do
165
157
  proc {@pool.hold {|c| c.foobar}}.should raise_error(NoMethodError)
166
158
  end
167
-
168
- specify "should handle Exception errors (normally not caught by rescue)" do
169
- err = nil
170
- begin
171
- @pool.hold {raise Exception}
172
- rescue => e
173
- err = e
174
- end
175
- err.should be_a_kind_of(RuntimeError)
176
- end
177
- end
178
-
179
- context "ConnectionPool#connection_proc" do
180
- before do
181
- @pool = Sequel::ConnectionPool.new(CONNECTION_POOL_DEFAULTS)
182
- end
183
-
184
- specify "should be nil if no block is supplied to the pool" do
185
- @pool.connection_proc.should be_nil
186
- proc {@pool.hold {}}.should raise_error
187
- end
188
-
189
- specify "should be mutable" do
190
- @pool.connection_proc = proc {'herro'}
191
- res = nil
192
- proc {@pool.hold {|c| res = c}}.should_not raise_error
193
- res.should == 'herro'
194
- end
195
159
  end
196
160
 
197
161
  context "A connection pool with a max size of 1" do
198
162
  before do
199
163
  @invoked_count = 0
200
- @pool = Sequel::ConnectionPool.new(CONNECTION_POOL_DEFAULTS.merge(:max_connections=>1)) {@invoked_count += 1; 'herro'}
164
+ @pool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS.merge(:max_connections=>1)) {@invoked_count += 1; 'herro'}
201
165
  end
202
166
 
203
167
  specify "should let only one thread access the connection at any time" do
@@ -270,12 +234,7 @@ context "A connection pool with a max size of 1" do
270
234
  end
271
235
  end
272
236
 
273
- context "A connection pool with a max size of 5" do
274
- before do
275
- @invoked_count = 0
276
- @pool = Sequel::ConnectionPool.new(CONNECTION_POOL_DEFAULTS.merge(:max_connections=>5)) {@invoked_count += 1}
277
- end
278
-
237
+ shared_examples_for "A threaded connection pool" do
279
238
  specify "should let five threads simultaneously access separate connections" do
280
239
  cc = {}
281
240
  threads = []
@@ -342,10 +301,28 @@ context "A connection pool with a max size of 5" do
342
301
  end
343
302
  end
344
303
 
304
+ context "Threaded Unsharded Connection Pool" do
305
+ before do
306
+ @invoked_count = 0
307
+ @pool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS.merge(:max_connections=>5)) {@invoked_count += 1}
308
+ end
309
+
310
+ it_should_behave_like "A threaded connection pool"
311
+ end
312
+
313
+ context "Threaded Sharded Connection Pool" do
314
+ before do
315
+ @invoked_count = 0
316
+ @pool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS.merge(:max_connections=>5, :servers=>{})) {@invoked_count += 1}
317
+ end
318
+
319
+ it_should_behave_like "A threaded connection pool"
320
+ end
321
+
345
322
  context "ConnectionPool#disconnect" do
346
323
  before do
347
324
  @count = 0
348
- @pool = Sequel::ConnectionPool.new(CONNECTION_POOL_DEFAULTS.merge(:max_connections=>5)) {{:id => @count += 1}}
325
+ @pool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS.merge(:max_connections=>5, :servers=>{})) {{:id => @count += 1}}
349
326
  end
350
327
 
351
328
  specify "should invoke the given block for each available connection" do
@@ -411,7 +388,7 @@ end
411
388
  context "A connection pool with multiple servers" do
412
389
  before do
413
390
  @invoked_counts = Hash.new(0)
414
- @pool = Sequel::ConnectionPool.new(CONNECTION_POOL_DEFAULTS.merge(:servers=>{:read_only=>{}})){|server| "#{server}#{@invoked_counts[server] += 1}"}
391
+ @pool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS.merge(:servers=>{:read_only=>{}})){|server| "#{server}#{@invoked_counts[server] += 1}"}
415
392
  end
416
393
 
417
394
  specify "#servers should return symbols for all servers" do
@@ -483,7 +460,7 @@ context "A connection pool with multiple servers" do
483
460
  end
484
461
 
485
462
  specify "#add_servers should add new servers to the pool" do
486
- pool = Sequel::ConnectionPool.new(:servers=>{:server1=>{}}){|s| s}
463
+ pool = Sequel::ConnectionPool.get_pool(:servers=>{:server1=>{}}){|s| s}
487
464
 
488
465
  pool.hold{}
489
466
  pool.hold(:server2){}
@@ -514,7 +491,7 @@ context "A connection pool with multiple servers" do
514
491
  end
515
492
 
516
493
  specify "#add_servers should ignore existing keys" do
517
- pool = Sequel::ConnectionPool.new(:servers=>{:server1=>{}}){|s| s}
494
+ pool = Sequel::ConnectionPool.get_pool(:servers=>{:server1=>{}}){|s| s}
518
495
 
519
496
  pool.allocated.length.should == 0
520
497
  pool.allocated(:server1).length.should == 0
@@ -560,7 +537,7 @@ context "A connection pool with multiple servers" do
560
537
  end
561
538
 
562
539
  specify "#remove_servers should disconnect available connections immediately" do
563
- pool = Sequel::ConnectionPool.new(:max_connections=>5, :servers=>{:server1=>{}}){|s| s}
540
+ pool = Sequel::ConnectionPool.get_pool(:max_connections=>5, :servers=>{:server1=>{}}){|s| s}
564
541
  threads = []
565
542
  stop = nil
566
543
  5.times {|i| threads << Thread.new{pool.hold(:server1){|c| sleep 0.05}}}
@@ -574,7 +551,7 @@ context "A connection pool with multiple servers" do
574
551
 
575
552
  specify "#remove_servers should disconnect connections in use as soon as they are returned to the pool" do
576
553
  dc = []
577
- pool = Sequel::ConnectionPool.new(:servers=>{:server1=>{}}, :disconnection_proc=>proc{|c| dc << c}){|s| s}
554
+ pool = Sequel::ConnectionPool.get_pool(:servers=>{:server1=>{}}, :disconnection_proc=>proc{|c| dc << c}){|s| s}
578
555
  c1 = nil
579
556
  pool.hold(:server1) do |c|
580
557
  pool.size(:server1).should == 1
@@ -589,7 +566,7 @@ context "A connection pool with multiple servers" do
589
566
  end
590
567
 
591
568
  specify "#remove_servers should remove server related data structures immediately" do
592
- pool = Sequel::ConnectionPool.new(:servers=>{:server1=>{}}){|s| s}
569
+ pool = Sequel::ConnectionPool.get_pool(:servers=>{:server1=>{}}){|s| s}
593
570
  pool.available_connections(:server1).should == []
594
571
  pool.allocated(:server1).should == {}
595
572
  pool.remove_servers([:server1])
@@ -598,14 +575,14 @@ context "A connection pool with multiple servers" do
598
575
  end
599
576
 
600
577
  specify "#remove_servers should not allow the removal of the default server" do
601
- pool = Sequel::ConnectionPool.new(:servers=>{:server1=>{}}){|s| s}
578
+ pool = Sequel::ConnectionPool.get_pool(:servers=>{:server1=>{}}){|s| s}
602
579
  proc{pool.remove_servers([:server1])}.should_not raise_error
603
580
  proc{pool.remove_servers([:default])}.should raise_error(Sequel::Error)
604
581
  end
605
582
 
606
583
  specify "#remove_servers should ignore servers that have already been removed" do
607
584
  dc = []
608
- pool = Sequel::ConnectionPool.new(:servers=>{:server1=>{}}, :disconnection_proc=>proc{|c| dc << c}){|s| s}
585
+ pool = Sequel::ConnectionPool.get_pool(:servers=>{:server1=>{}}, :disconnection_proc=>proc{|c| dc << c}){|s| s}
609
586
  c1 = nil
610
587
  pool.hold(:server1) do |c|
611
588
  pool.size(:server1).should == 1
@@ -621,31 +598,34 @@ context "A connection pool with multiple servers" do
621
598
  end
622
599
  end
623
600
 
624
- context "SingleThreadedPool" do
601
+ ST_CONNECTION_POOL_DEFAULTS = CONNECTION_POOL_DEFAULTS.merge(:single_threaded=>true)
602
+
603
+ context "SingleConnectionPool" do
625
604
  before do
626
- @pool = Sequel::SingleThreadedPool.new(CONNECTION_POOL_DEFAULTS){1234}
605
+ @pool = Sequel::ConnectionPool.get_pool(ST_CONNECTION_POOL_DEFAULTS){1234}
627
606
  end
628
607
 
629
608
  specify "should provide a #hold method" do
630
609
  conn = nil
631
- @pool.hold {|c| conn = c}
610
+ @pool.hold{|c| conn = c}
632
611
  conn.should == 1234
633
612
  end
634
613
 
635
614
  specify "should provide a #disconnect method" do
636
- @pool.hold {|c|}
637
- @pool.conn.should == 1234
638
615
  conn = nil
639
- @pool.disconnect {|c| conn = c}
616
+ x = nil
617
+ pool = Sequel::ConnectionPool.get_pool(ST_CONNECTION_POOL_DEFAULTS.merge(:disconnection_proc=>proc{|c| conn = c})){1234}
618
+ pool.hold{|c| x = c}
619
+ x.should == 1234
620
+ pool.disconnect
640
621
  conn.should == 1234
641
- @pool.conn.should be_nil
642
622
  end
643
623
  end
644
624
 
645
625
  context "A single threaded pool with multiple servers" do
646
626
  before do
647
627
  @max_size=2
648
- @pool = Sequel::SingleThreadedPool.new(CONNECTION_POOL_DEFAULTS.merge(:disconnection_proc=>proc{|c| @max_size=3}, :servers=>{:read_only=>{}})){|server| server}
628
+ @pool = Sequel::ConnectionPool.get_pool(ST_CONNECTION_POOL_DEFAULTS.merge(:disconnection_proc=>proc{|c| @max_size=3}, :servers=>{:read_only=>{}})){|server| server}
649
629
  end
650
630
 
651
631
  specify "#servers should return symbols for all servers" do
@@ -744,13 +724,6 @@ context "A single threaded pool with multiple servers" do
744
724
  @max_size.should == 3
745
725
  end
746
726
 
747
- specify "#disconnection_proc= should set the disconnection proc to use" do
748
- a = 1
749
- @pool.disconnection_proc = proc{|c| a += 1}
750
- proc{@pool.hold{raise Sequel::DatabaseDisconnectError}}.should raise_error(Sequel::DatabaseDisconnectError)
751
- a.should == 2
752
- end
753
-
754
727
  specify "#hold should remove the connection if a DatabaseDisconnectError is raised" do
755
728
  @pool.instance_variable_get(:@conns).length.should == 0
756
729
  @pool.hold{}
@@ -759,3 +732,71 @@ context "A single threaded pool with multiple servers" do
759
732
  @pool.instance_variable_get(:@conns).length.should == 0
760
733
  end
761
734
  end
735
+
736
+ shared_examples_for "All connection pools classes" do
737
+ specify "should yield a connection created by the initialize block to hold" do
738
+ x = nil
739
+ @class.new({}){123}.hold{|c| x = c}
740
+ x.should == 123
741
+ end
742
+
743
+ specify "should have the initialize block accept a shard/server argument" do
744
+ x = nil
745
+ @class.new({}){|c| [c, c]}.hold{|c| x = c}
746
+ x.should == [:default, :default]
747
+ end
748
+
749
+ specify "should raise a DatabaseConnectionError if the connection raises an exception" do
750
+ proc{@class.new({}){|c| raise Exception}.hold{}}.should raise_error(Sequel::DatabaseConnectionError)
751
+ end
752
+
753
+ specify "should raise a DatabaseConnectionError if the initialize block returns nil" do
754
+ proc{@class.new({}){}.hold{}}.should raise_error(Sequel::DatabaseConnectionError)
755
+ end
756
+
757
+ specify "should call the disconnection_proc option if the hold block raises a DatabaseDisconnectError" do
758
+ x = nil
759
+ proc{@class.new(:disconnection_proc=>proc{|c| x = c}){123}.hold{raise Sequel::DatabaseDisconnectError}}.should raise_error(Sequel::DatabaseDisconnectError)
760
+ x.should == 123
761
+ end
762
+
763
+ specify "should have a disconnect method that calls the :disconnection_proc option with the connection" do
764
+ x = nil
765
+ c = @class.new(:disconnection_proc=>proc{|c| x = c}){123}
766
+ c.hold{}
767
+ x.should == nil
768
+ c.disconnect
769
+ x.should == 123
770
+ end
771
+
772
+ specify "should have a disconnect method that calls the given block with the connection" do
773
+ x = nil
774
+ y = nil
775
+ c = @class.new(:disconnection_proc=>proc{|c| x = c}){123}
776
+ c.hold{}
777
+ c.disconnect{|c| y = c}
778
+ x.should == nil
779
+ y.should == 123
780
+ end
781
+
782
+ specify "should have a servers method that returns an array of shard/server symbols" do
783
+ @class.new({}){123}.servers.should == [:default]
784
+ end
785
+
786
+ specify "should have a servers method that returns an array of shard/server symbols" do
787
+ c = @class.new({}){123}
788
+ c.size.should == 0
789
+ c.hold{}
790
+ c.size.should == 1
791
+ end
792
+ end
793
+
794
+ Sequel::ConnectionPool::CONNECTION_POOL_MAP.keys.each do |k, v|
795
+ opts = {:single_threaded=>k, :servers=>(v ? {} : nil)}
796
+ describe "Connection pool with #{opts.inspect}" do
797
+ before do
798
+ @class = Sequel::ConnectionPool.send(:connection_pool_class, opts)
799
+ end
800
+ it_should_behave_like "All connection pools classes"
801
+ end
802
+ end
@@ -11,7 +11,8 @@ context "A new Database" do
11
11
  end
12
12
 
13
13
  specify "should receive options" do
14
- @db.opts.should == {1 => 2, :logger => 3}
14
+ @db.opts[1].should == 2
15
+ @db.opts[:logger].should == 3
15
16
  end
16
17
 
17
18
  specify "should set the logger from opts[:logger] and opts[:loggers]" do
@@ -37,17 +38,17 @@ context "A new Database" do
37
38
  end
38
39
 
39
40
  specify "should respect the :single_threaded option" do
40
- db = Sequel::Database.new(:single_threaded=>true)
41
- db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
42
- db = Sequel::Database.new(:single_threaded=>'t')
43
- db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
44
- db = Sequel::Database.new(:single_threaded=>'1')
45
- db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
46
- db = Sequel::Database.new(:single_threaded=>false)
41
+ db = Sequel::Database.new(:single_threaded=>true){123}
42
+ db.pool.should be_a_kind_of(Sequel::SingleConnectionPool)
43
+ db = Sequel::Database.new(:single_threaded=>'t'){123}
44
+ db.pool.should be_a_kind_of(Sequel::SingleConnectionPool)
45
+ db = Sequel::Database.new(:single_threaded=>'1'){123}
46
+ db.pool.should be_a_kind_of(Sequel::SingleConnectionPool)
47
+ db = Sequel::Database.new(:single_threaded=>false){123}
47
48
  db.pool.should be_a_kind_of(Sequel::ConnectionPool)
48
- db = Sequel::Database.new(:single_threaded=>'f')
49
+ db = Sequel::Database.new(:single_threaded=>'f'){123}
49
50
  db.pool.should be_a_kind_of(Sequel::ConnectionPool)
50
- db = Sequel::Database.new(:single_threaded=>'0')
51
+ db = Sequel::Database.new(:single_threaded=>'0'){123}
51
52
  db.pool.should be_a_kind_of(Sequel::ConnectionPool)
52
53
  end
53
54
 
@@ -204,7 +205,7 @@ end
204
205
 
205
206
  context "Database#connect" do
206
207
  specify "should raise NotImplementedError" do
207
- proc {Sequel::Database.new.connect}.should raise_error(NotImplementedError)
208
+ proc {Sequel::Database.new.connect(:default)}.should raise_error(NotImplementedError)
208
209
  end
209
210
  end
210
211
 
@@ -315,8 +316,7 @@ end
315
316
 
316
317
  context "Database#synchronize" do
317
318
  before do
318
- @db = Sequel::Database.new(:max_connections => 1)
319
- @db.pool.connection_proc = proc {12345}
319
+ @db = Sequel::Database.new(:max_connections => 1){12345}
320
320
  end
321
321
 
322
322
  specify "should wrap the supplied block in pool.hold" do
@@ -339,9 +339,7 @@ end
339
339
 
340
340
  context "Database#test_connection" do
341
341
  before do
342
- @db = Sequel::Database.new
343
- @test = nil
344
- @db.pool.connection_proc = proc {@test = rand(100)}
342
+ @db = Sequel::Database.new{@test = rand(100)}
345
343
  end
346
344
 
347
345
  specify "should call pool#hold" do
@@ -593,8 +591,7 @@ end
593
591
 
594
592
  context "Database#transaction" do
595
593
  before do
596
- @db = Dummy3Database.new
597
- @db.pool.connection_proc = proc {Dummy3Database::DummyConnection.new(@db)}
594
+ @db = Dummy3Database.new{Dummy3Database::DummyConnection.new(@db)}
598
595
  end
599
596
 
600
597
  specify "should wrap the supplied block with BEGIN + COMMIT statements" do
@@ -659,9 +656,8 @@ end
659
656
 
660
657
  context "Database#transaction with savepoints" do
661
658
  before do
662
- @db = Dummy3Database.new
659
+ @db = Dummy3Database.new{Dummy3Database::DummyConnection.new(@db)}
663
660
  @db.meta_def(:supports_savepoints?){true}
664
- @db.pool.connection_proc = proc {Dummy3Database::DummyConnection.new(@db)}
665
661
  end
666
662
 
667
663
  specify "should wrap the supplied block with BEGIN + COMMIT statements" do
@@ -825,26 +821,27 @@ context "A Database adapter with a scheme" do
825
821
  proc {Sequel.ccc('abc', 'def')}.should raise_error(Sequel::Error)
826
822
 
827
823
  c = Sequel.ccc('mydb')
824
+ p = proc{c.opts.delete_if{|k,v| k == :disconnection_proc || k == :single_threaded}}
828
825
  c.should be_a_kind_of(CCC)
829
- c.opts.should == {:adapter=>:ccc, :database => 'mydb'}
826
+ p.call.should == {:adapter=>:ccc, :database => 'mydb'}
830
827
 
831
828
  c = Sequel.ccc('mydb', :host => 'localhost')
832
829
  c.should be_a_kind_of(CCC)
833
- c.opts.should == {:adapter=>:ccc, :database => 'mydb', :host => 'localhost'}
830
+ p.call.should == {:adapter=>:ccc, :database => 'mydb', :host => 'localhost'}
834
831
 
835
832
  c = Sequel.ccc
836
833
  c.should be_a_kind_of(CCC)
837
- c.opts.should == {:adapter=>:ccc}
834
+ p.call.should == {:adapter=>:ccc}
838
835
 
839
836
  c = Sequel.ccc(:database => 'mydb', :host => 'localhost')
840
837
  c.should be_a_kind_of(CCC)
841
- c.opts.should == {:adapter=>:ccc, :database => 'mydb', :host => 'localhost'}
838
+ p.call.should == {:adapter=>:ccc, :database => 'mydb', :host => 'localhost'}
842
839
  end
843
840
 
844
841
  specify "should be accessible through Sequel.connect with options" do
845
842
  c = Sequel.connect(:adapter => :ccc, :database => 'mydb')
846
843
  c.should be_a_kind_of(CCC)
847
- c.opts.should == {:adapter => :ccc, :database => 'mydb'}
844
+ c.opts[:adapter].should == :ccc
848
845
  end
849
846
 
850
847
  specify "should be accessible through Sequel.connect with URL parameters" do
@@ -915,26 +912,26 @@ context "A single threaded database" do
915
912
  Sequel::Database.single_threaded = false
916
913
  end
917
914
 
918
- specify "should use a SingleThreadedPool instead of a ConnectionPool" do
919
- db = Sequel::Database.new(:single_threaded => true)
920
- db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
915
+ specify "should use a SingleConnectionPool instead of a ConnectionPool" do
916
+ db = Sequel::Database.new(:single_threaded => true){123}
917
+ db.pool.should be_a_kind_of(Sequel::SingleConnectionPool)
921
918
  end
922
919
 
923
920
  specify "should be constructable using :single_threaded => true option" do
924
- db = Sequel::Database.new(:single_threaded => true)
925
- db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
921
+ db = Sequel::Database.new(:single_threaded => true){123}
922
+ db.pool.should be_a_kind_of(Sequel::SingleConnectionPool)
926
923
  end
927
924
 
928
925
  specify "should be constructable using Database.single_threaded = true" do
929
926
  Sequel::Database.single_threaded = true
930
- db = Sequel::Database.new
931
- db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
927
+ db = Sequel::Database.new{123}
928
+ db.pool.should be_a_kind_of(Sequel::SingleConnectionPool)
932
929
  end
933
930
 
934
931
  specify "should be constructable using Sequel.single_threaded = true" do
935
932
  Sequel.single_threaded = true
936
- db = Sequel::Database.new
937
- db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
933
+ db = Sequel::Database.new{123}
934
+ db.pool.should be_a_kind_of(Sequel::SingleConnectionPool)
938
935
  end
939
936
  end
940
937
 
@@ -956,26 +953,20 @@ context "A single threaded database" do
956
953
  def @db.dc; @dc end
957
954
  x = nil
958
955
  @db.pool.hold{|c| x = c}
959
- @db.pool.conn.should == x
956
+ @db.pool.hold{|c| c.should == x}
960
957
  proc{@db.disconnect}.should_not raise_error
961
- @db.pool.conn.should == nil
962
958
  @db.dc.should == x
963
959
  end
964
960
 
965
961
  specify "should convert an Exception on connection into a DatabaseConnectionError" do
966
- db = Sequel::Database.new(:single_threaded => true){raise Exception}
962
+ db = Sequel::Database.new(:single_threaded => true, :servers=>{}){raise Exception}
967
963
  proc {db.pool.hold {|c|}}.should raise_error(Sequel::DatabaseConnectionError)
968
964
  end
969
965
 
970
966
  specify "should raise a DatabaseConnectionError if the connection proc returns nil" do
971
- db = Sequel::Database.new(:single_threaded => true){nil}
967
+ db = Sequel::Database.new(:single_threaded => true, :servers=>{}){nil}
972
968
  proc {db.pool.hold {|c|}}.should raise_error(Sequel::DatabaseConnectionError)
973
969
  end
974
-
975
- specify "should convert an Exceptions during use into RuntimeErrors" do
976
- db = Sequel::Database.new(:single_threaded => true){Object.new}
977
- proc {db.synchronize{raise Exception}}.should raise_error(RuntimeError)
978
- end
979
970
  end
980
971
 
981
972
  context "A database" do
@@ -988,7 +979,7 @@ context "A database" do
988
979
  end
989
980
 
990
981
  specify "should have single_threaded? respond to true if in single threaded mode" do
991
- db = Sequel::Database.new(:single_threaded => true)
982
+ db = Sequel::Database.new(:single_threaded => true){1234}
992
983
  db.should be_single_threaded
993
984
 
994
985
  db = Sequel::Database.new(:max_options => 1)
@@ -999,10 +990,10 @@ context "A database" do
999
990
 
1000
991
  Sequel::Database.single_threaded = true
1001
992
 
1002
- db = Sequel::Database.new
993
+ db = Sequel::Database.new{123}
1003
994
  db.should be_single_threaded
1004
995
 
1005
- db = Sequel::Database.new(:max_options => 4)
996
+ db = Sequel::Database.new(:max_options => 4){123}
1006
997
  db.should be_single_threaded
1007
998
  end
1008
999
 
@@ -1226,22 +1217,22 @@ end
1226
1217
  context "Database#server_opts" do
1227
1218
  specify "should return the general opts if no :servers option is used" do
1228
1219
  opts = {:host=>1, :database=>2}
1229
- MockDatabase.new(opts).send(:server_opts, :server1).should == {:host=>1, :database=>2}
1220
+ MockDatabase.new(opts).send(:server_opts, :server1)[:host].should == 1
1230
1221
  end
1231
1222
 
1232
1223
  specify "should return the general opts if entry for the server is present in the :servers option" do
1233
1224
  opts = {:host=>1, :database=>2, :servers=>{}}
1234
- MockDatabase.new(opts).send(:server_opts, :server1).should == {:host=>1, :database=>2}
1225
+ MockDatabase.new(opts).send(:server_opts, :server1)[:host].should == 1
1235
1226
  end
1236
1227
 
1237
1228
  specify "should return the general opts merged with the specific opts if given as a hash" do
1238
1229
  opts = {:host=>1, :database=>2, :servers=>{:server1=>{:host=>3}}}
1239
- MockDatabase.new(opts).send(:server_opts, :server1).should == {:host=>3, :database=>2}
1230
+ MockDatabase.new(opts).send(:server_opts, :server1)[:host].should == 3
1240
1231
  end
1241
1232
 
1242
1233
  specify "should return the sgeneral opts merged with the specific opts if given as a proc" do
1243
1234
  opts = {:host=>1, :database=>2, :servers=>{:server1=>proc{|db| {:host=>4}}}}
1244
- MockDatabase.new(opts).send(:server_opts, :server1).should == {:host=>4, :database=>2}
1235
+ MockDatabase.new(opts).send(:server_opts, :server1)[:host].should == 4
1245
1236
  end
1246
1237
 
1247
1238
  specify "should raise an error if the specific opts is not a proc or hash" do