sequel 3.8.0 → 3.9.0

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