sequel 3.21.0 → 3.31.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 (225) hide show
  1. data/CHANGELOG +485 -3
  2. data/README.rdoc +20 -6
  3. data/Rakefile +37 -19
  4. data/bin/sequel +1 -5
  5. data/doc/association_basics.rdoc +249 -43
  6. data/doc/dataset_basics.rdoc +4 -4
  7. data/doc/dataset_filtering.rdoc +8 -0
  8. data/doc/mass_assignment.rdoc +54 -0
  9. data/doc/migration.rdoc +15 -538
  10. data/doc/model_hooks.rdoc +72 -27
  11. data/doc/opening_databases.rdoc +89 -50
  12. data/doc/prepared_statements.rdoc +40 -13
  13. data/doc/reflection.rdoc +8 -2
  14. data/doc/release_notes/3.22.0.txt +39 -0
  15. data/doc/release_notes/3.23.0.txt +172 -0
  16. data/doc/release_notes/3.24.0.txt +420 -0
  17. data/doc/release_notes/3.25.0.txt +88 -0
  18. data/doc/release_notes/3.26.0.txt +88 -0
  19. data/doc/release_notes/3.27.0.txt +82 -0
  20. data/doc/release_notes/3.28.0.txt +304 -0
  21. data/doc/release_notes/3.29.0.txt +459 -0
  22. data/doc/release_notes/3.30.0.txt +135 -0
  23. data/doc/release_notes/3.31.0.txt +146 -0
  24. data/doc/schema_modification.rdoc +547 -0
  25. data/doc/sharding.rdoc +7 -1
  26. data/doc/testing.rdoc +129 -0
  27. data/doc/transactions.rdoc +137 -0
  28. data/doc/virtual_rows.rdoc +2 -2
  29. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  30. data/lib/sequel/adapters/ado.rb +40 -18
  31. data/lib/sequel/adapters/amalgalite.rb +17 -9
  32. data/lib/sequel/adapters/db2.rb +175 -86
  33. data/lib/sequel/adapters/dbi.rb +15 -15
  34. data/lib/sequel/adapters/do/mysql.rb +5 -7
  35. data/lib/sequel/adapters/do/postgres.rb +0 -5
  36. data/lib/sequel/adapters/do/sqlite.rb +0 -5
  37. data/lib/sequel/adapters/do.rb +17 -36
  38. data/lib/sequel/adapters/firebird.rb +27 -208
  39. data/lib/sequel/adapters/ibmdb.rb +448 -0
  40. data/lib/sequel/adapters/informix.rb +6 -23
  41. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  42. data/lib/sequel/adapters/jdbc/db2.rb +45 -0
  43. data/lib/sequel/adapters/jdbc/derby.rb +247 -0
  44. data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
  45. data/lib/sequel/adapters/jdbc/h2.rb +56 -29
  46. data/lib/sequel/adapters/jdbc/hsqldb.rb +170 -0
  47. data/lib/sequel/adapters/jdbc/informix.rb +26 -0
  48. data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
  49. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  50. data/lib/sequel/adapters/jdbc/mysql.rb +11 -11
  51. data/lib/sequel/adapters/jdbc/oracle.rb +81 -25
  52. data/lib/sequel/adapters/jdbc/postgresql.rb +9 -13
  53. data/lib/sequel/adapters/jdbc/sqlite.rb +2 -6
  54. data/lib/sequel/adapters/jdbc/sqlserver.rb +71 -0
  55. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  56. data/lib/sequel/adapters/jdbc.rb +231 -78
  57. data/lib/sequel/adapters/mock.rb +335 -0
  58. data/lib/sequel/adapters/mysql.rb +82 -184
  59. data/lib/sequel/adapters/mysql2.rb +26 -25
  60. data/lib/sequel/adapters/odbc/db2.rb +17 -0
  61. data/lib/sequel/adapters/odbc/mssql.rb +1 -6
  62. data/lib/sequel/adapters/odbc.rb +28 -9
  63. data/lib/sequel/adapters/openbase.rb +3 -5
  64. data/lib/sequel/adapters/oracle.rb +351 -53
  65. data/lib/sequel/adapters/postgres.rb +194 -33
  66. data/lib/sequel/adapters/shared/access.rb +32 -9
  67. data/lib/sequel/adapters/shared/db2.rb +321 -0
  68. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  69. data/lib/sequel/adapters/shared/informix.rb +53 -0
  70. data/lib/sequel/adapters/shared/mssql.rb +231 -106
  71. data/lib/sequel/adapters/shared/mysql.rb +181 -63
  72. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
  73. data/lib/sequel/adapters/shared/oracle.rb +231 -41
  74. data/lib/sequel/adapters/shared/postgres.rb +214 -82
  75. data/lib/sequel/adapters/shared/progress.rb +4 -7
  76. data/lib/sequel/adapters/shared/sqlite.rb +201 -57
  77. data/lib/sequel/adapters/sqlite.rb +29 -21
  78. data/lib/sequel/adapters/swift/mysql.rb +12 -7
  79. data/lib/sequel/adapters/swift/postgres.rb +0 -5
  80. data/lib/sequel/adapters/swift/sqlite.rb +8 -6
  81. data/lib/sequel/adapters/swift.rb +5 -5
  82. data/lib/sequel/adapters/tinytds.rb +160 -19
  83. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
  84. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  85. data/lib/sequel/ast_transformer.rb +190 -0
  86. data/lib/sequel/connection_pool/threaded.rb +3 -2
  87. data/lib/sequel/connection_pool.rb +1 -1
  88. data/lib/sequel/core.rb +46 -5
  89. data/lib/sequel/database/connecting.rb +5 -6
  90. data/lib/sequel/database/dataset.rb +4 -4
  91. data/lib/sequel/database/dataset_defaults.rb +59 -1
  92. data/lib/sequel/database/logging.rb +1 -1
  93. data/lib/sequel/database/misc.rb +104 -19
  94. data/lib/sequel/database/query.rb +153 -58
  95. data/lib/sequel/database/schema_generator.rb +17 -7
  96. data/lib/sequel/database/schema_methods.rb +59 -29
  97. data/lib/sequel/dataset/actions.rb +231 -76
  98. data/lib/sequel/dataset/features.rb +91 -8
  99. data/lib/sequel/dataset/graph.rb +38 -11
  100. data/lib/sequel/dataset/misc.rb +50 -23
  101. data/lib/sequel/dataset/mutation.rb +5 -6
  102. data/lib/sequel/dataset/prepared_statements.rb +48 -27
  103. data/lib/sequel/dataset/query.rb +236 -43
  104. data/lib/sequel/dataset/sql.rb +665 -253
  105. data/lib/sequel/dataset.rb +8 -0
  106. data/lib/sequel/exceptions.rb +4 -0
  107. data/lib/sequel/extensions/columns_introspection.rb +61 -0
  108. data/lib/sequel/extensions/migration.rb +6 -4
  109. data/lib/sequel/extensions/named_timezones.rb +5 -0
  110. data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
  111. data/lib/sequel/extensions/to_dot.rb +95 -83
  112. data/lib/sequel/model/associations.rb +1020 -337
  113. data/lib/sequel/model/base.rb +414 -132
  114. data/lib/sequel/model/errors.rb +1 -1
  115. data/lib/sequel/model/exceptions.rb +5 -1
  116. data/lib/sequel/model.rb +15 -8
  117. data/lib/sequel/plugins/association_pks.rb +22 -4
  118. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  119. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  120. data/lib/sequel/plugins/defaults_setter.rb +58 -0
  121. data/lib/sequel/plugins/force_encoding.rb +6 -6
  122. data/lib/sequel/plugins/identity_map.rb +114 -7
  123. data/lib/sequel/plugins/many_through_many.rb +65 -7
  124. data/lib/sequel/plugins/prepared_statements.rb +151 -0
  125. data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
  126. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  127. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  128. data/lib/sequel/plugins/rcte_tree.rb +29 -15
  129. data/lib/sequel/plugins/serialization.rb +88 -44
  130. data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
  131. data/lib/sequel/plugins/sharding.rb +21 -54
  132. data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
  133. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  134. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  135. data/lib/sequel/plugins/xml_serializer.rb +3 -3
  136. data/lib/sequel/sql.rb +109 -52
  137. data/lib/sequel/timezones.rb +57 -38
  138. data/lib/sequel/version.rb +1 -1
  139. data/spec/adapters/db2_spec.rb +146 -0
  140. data/spec/adapters/mssql_spec.rb +111 -29
  141. data/spec/adapters/mysql_spec.rb +135 -123
  142. data/spec/adapters/oracle_spec.rb +49 -77
  143. data/spec/adapters/postgres_spec.rb +267 -78
  144. data/spec/adapters/spec_helper.rb +6 -5
  145. data/spec/adapters/sqlite_spec.rb +35 -21
  146. data/spec/core/connection_pool_spec.rb +71 -92
  147. data/spec/core/core_sql_spec.rb +21 -30
  148. data/spec/core/database_spec.rb +788 -512
  149. data/spec/core/dataset_spec.rb +1073 -1053
  150. data/spec/core/expression_filters_spec.rb +159 -42
  151. data/spec/core/mock_adapter_spec.rb +419 -0
  152. data/spec/core/object_graph_spec.rb +86 -114
  153. data/spec/core/schema_generator_spec.rb +3 -3
  154. data/spec/core/schema_spec.rb +298 -38
  155. data/spec/core/spec_helper.rb +6 -48
  156. data/spec/extensions/association_autoreloading_spec.rb +1 -10
  157. data/spec/extensions/association_dependencies_spec.rb +2 -12
  158. data/spec/extensions/association_pks_spec.rb +66 -32
  159. data/spec/extensions/caching_spec.rb +23 -50
  160. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  161. data/spec/extensions/columns_introspection_spec.rb +91 -0
  162. data/spec/extensions/composition_spec.rb +18 -13
  163. data/spec/extensions/dataset_associations_spec.rb +199 -0
  164. data/spec/extensions/defaults_setter_spec.rb +64 -0
  165. data/spec/extensions/hook_class_methods_spec.rb +65 -91
  166. data/spec/extensions/identity_map_spec.rb +114 -22
  167. data/spec/extensions/instance_filters_spec.rb +11 -21
  168. data/spec/extensions/instance_hooks_spec.rb +53 -0
  169. data/spec/extensions/json_serializer_spec.rb +4 -5
  170. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  171. data/spec/extensions/list_spec.rb +17 -39
  172. data/spec/extensions/many_through_many_spec.rb +283 -250
  173. data/spec/extensions/migration_spec.rb +35 -32
  174. data/spec/extensions/named_timezones_spec.rb +23 -3
  175. data/spec/extensions/nested_attributes_spec.rb +97 -88
  176. data/spec/extensions/optimistic_locking_spec.rb +9 -20
  177. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  178. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  179. data/spec/extensions/prepared_statements_spec.rb +53 -0
  180. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  181. data/spec/extensions/pretty_table_spec.rb +1 -6
  182. data/spec/extensions/rcte_tree_spec.rb +41 -43
  183. data/spec/extensions/schema_dumper_spec.rb +5 -8
  184. data/spec/extensions/schema_spec.rb +13 -21
  185. data/spec/extensions/serialization_modification_detection_spec.rb +37 -0
  186. data/spec/extensions/serialization_spec.rb +72 -43
  187. data/spec/extensions/sharding_spec.rb +66 -140
  188. data/spec/extensions/single_table_inheritance_spec.rb +18 -29
  189. data/spec/extensions/spec_helper.rb +13 -61
  190. data/spec/extensions/sql_expr_spec.rb +20 -60
  191. data/spec/extensions/tactical_eager_loading_spec.rb +9 -19
  192. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  193. data/spec/extensions/timestamps_spec.rb +6 -6
  194. data/spec/extensions/to_dot_spec.rb +4 -7
  195. data/spec/extensions/touch_spec.rb +13 -14
  196. data/spec/extensions/tree_spec.rb +11 -26
  197. data/spec/extensions/typecast_on_load_spec.rb +1 -6
  198. data/spec/extensions/update_primary_key_spec.rb +30 -24
  199. data/spec/extensions/validation_class_methods_spec.rb +30 -51
  200. data/spec/extensions/validation_helpers_spec.rb +16 -35
  201. data/spec/extensions/xml_serializer_spec.rb +16 -4
  202. data/spec/integration/associations_test.rb +537 -21
  203. data/spec/integration/database_test.rb +4 -2
  204. data/spec/integration/dataset_test.rb +461 -65
  205. data/spec/integration/eager_loader_test.rb +19 -21
  206. data/spec/integration/model_test.rb +80 -1
  207. data/spec/integration/plugin_test.rb +304 -116
  208. data/spec/integration/prepared_statement_test.rb +212 -122
  209. data/spec/integration/schema_test.rb +161 -30
  210. data/spec/integration/spec_helper.rb +39 -30
  211. data/spec/integration/timezone_test.rb +38 -12
  212. data/spec/integration/transaction_test.rb +172 -5
  213. data/spec/integration/type_test.rb +17 -3
  214. data/spec/model/association_reflection_spec.rb +201 -7
  215. data/spec/model/associations_spec.rb +865 -662
  216. data/spec/model/base_spec.rb +275 -95
  217. data/spec/model/dataset_methods_spec.rb +7 -27
  218. data/spec/model/eager_loading_spec.rb +677 -676
  219. data/spec/model/hooks_spec.rb +309 -67
  220. data/spec/model/model_spec.rb +222 -168
  221. data/spec/model/plugins_spec.rb +24 -13
  222. data/spec/model/record_spec.rb +381 -218
  223. data/spec/model/spec_helper.rb +13 -71
  224. data/spec/model/validations_spec.rb +11 -0
  225. metadata +115 -73
@@ -84,7 +84,9 @@ describe "A connection pool handling connections" do
84
84
  end
85
85
 
86
86
  specify "#make_new should not make more than max_size connections" do
87
- 50.times{Thread.new{@cpool.hold{sleep 0.001}}}
87
+ q = Queue.new
88
+ 50.times{Thread.new{@cpool.hold{q.pop}}}
89
+ 50.times{q.push nil}
88
90
  @cpool.created_count.should <= @max_size
89
91
  end
90
92
 
@@ -96,7 +98,8 @@ describe "A connection pool handling connections" do
96
98
 
97
99
  specify "#hold should remove the connection if a DatabaseDisconnectError is raised" do
98
100
  @cpool.created_count.should == 0
99
- @cpool.hold{Thread.new{@cpool.hold{}}; sleep 0.03}
101
+ q, q1 = Queue.new, Queue.new
102
+ @cpool.hold{Thread.new{@cpool.hold{q1.pop; q.push nil}; q1.pop; q.push nil}; q1.push nil; q.pop; q1.push nil; q.pop}
100
103
  @cpool.created_count.should == 2
101
104
  proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.should raise_error(Sequel::DatabaseDisconnectError)
102
105
  @cpool.created_count.should == 1
@@ -121,36 +124,30 @@ describe "A connection pool handling connection errors" do
121
124
  end
122
125
  end
123
126
 
124
- class DummyConnection
125
- @@value = 0
126
- def initialize
127
- @@value += 1
128
- end
129
-
130
- def value
131
- @@value
132
- end
133
- end
134
-
135
127
  describe "ConnectionPool#hold" do
136
128
  before do
137
- @pool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS) {DummyConnection.new}
129
+ value = 0
130
+ @c = Class.new do
131
+ define_method(:initialize){value += 1}
132
+ define_method(:value){value}
133
+ end
134
+ @pool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS){@c.new}
138
135
  end
139
136
 
140
137
  specify "should pass the result of the connection maker proc to the supplied block" do
141
138
  res = nil
142
139
  @pool.hold {|c| res = c}
143
- res.should be_a_kind_of(DummyConnection)
140
+ res.should be_a_kind_of(@c)
144
141
  res.value.should == 1
145
142
  @pool.hold {|c| res = c}
146
- res.should be_a_kind_of(DummyConnection)
143
+ res.should be_a_kind_of(@c)
147
144
  res.value.should == 1 # the connection maker is invoked only once
148
145
  end
149
146
 
150
147
  specify "should be re-entrant by the same thread" do
151
148
  cc = nil
152
149
  @pool.hold {|c| @pool.hold {|c| @pool.hold {|c| cc = c}}}
153
- cc.should be_a_kind_of(DummyConnection)
150
+ cc.should be_a_kind_of(@c)
154
151
  end
155
152
 
156
153
  specify "should catch exceptions and reraise them" do
@@ -166,15 +163,14 @@ describe "A connection pool with a max size of 1" do
166
163
 
167
164
  specify "should let only one thread access the connection at any time" do
168
165
  cc,c1, c2 = nil
169
- m = (defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx') ? 30 : 1
166
+ q, q1 = Queue.new, Queue.new
170
167
 
171
- t1 = Thread.new {@pool.hold {|c| cc = c; c1 = c.dup; while c == 'herro';sleep 0.01;end}}
172
- sleep 0.02 * m
168
+ t1 = Thread.new {@pool.hold {|c| cc = c; c1 = c.dup; q1.push nil; q.pop}}
169
+ q1.pop
173
170
  cc.should == 'herro'
174
171
  c1.should == 'herro'
175
172
 
176
- t2 = Thread.new {@pool.hold {|c| c2 = c.dup; while c == 'hello';sleep 0.01;end}}
177
- sleep 0.02 * m
173
+ t2 = Thread.new {@pool.hold {|c| c2 = c.dup; q1.push nil; q.pop;}}
178
174
 
179
175
  # connection held by t1
180
176
  t1.should be_alive
@@ -186,26 +182,22 @@ describe "A connection pool with a max size of 1" do
186
182
 
187
183
  @pool.available_connections.should be_empty
188
184
  @pool.allocated.should == {t1=>cc}
189
-
185
+
190
186
  cc.gsub!('rr', 'll')
191
- sleep 0.05 * m
192
-
193
- # connection held by t2
187
+ q.push nil
188
+ q1.pop
189
+
194
190
  t1.should_not be_alive
195
191
  t2.should be_alive
196
-
192
+
197
193
  c2.should == 'hello'
198
194
 
199
195
  @pool.available_connections.should be_empty
200
196
  @pool.allocated.should == {t2=>cc}
201
197
 
202
- cc.gsub!('ll', 'rr')
203
- sleep 0.05 * m
204
-
205
198
  #connection released
206
- t2.should_not be_alive
207
-
208
- cc.should == 'herro'
199
+ q.push nil
200
+ t2.join
209
201
 
210
202
  @invoked_count.should == 1
211
203
  @pool.size.should == 1
@@ -236,34 +228,42 @@ describe "A connection pool with a max size of 1" do
236
228
  end
237
229
 
238
230
  shared_examples_for "A threaded connection pool" do
231
+ specify "should raise a PoolTimeout error if a connection couldn't be acquired before timeout" do
232
+ x = nil
233
+ q, q1 = Queue.new, Queue.new
234
+ pool = Sequel::ConnectionPool.get_pool(@cp_opts.merge(:max_connections=>1, :pool_timeout=>0)) {@invoked_count += 1}
235
+ t = Thread.new{pool.hold{|c| q1.push nil; q.pop}}
236
+ q1.pop
237
+ proc{pool.hold{|c|}}.should raise_error(Sequel::PoolTimeout)
238
+ q.push nil
239
+ t.join
240
+ end
241
+
242
+ it "should not add a disconnected connection back to the pool if the disconnection_proc raises an error" do
243
+ pool = Sequel::ConnectionPool.get_pool(@cp_opts.merge(:max_connections=>1, :pool_timeout=>0, :disconnection_proc=>proc{|c| raise Sequel::Error})) {@invoked_count += 1}
244
+ proc{pool.hold{raise Sequel::DatabaseDisconnectError}}.should raise_error(Sequel::Error)
245
+ pool.available_connections.length.should == 0
246
+ end
247
+
239
248
  specify "should let five threads simultaneously access separate connections" do
240
249
  cc = {}
241
250
  threads = []
242
- stop = nil
251
+ q, q1, q2 = Queue.new, Queue.new, Queue.new
243
252
 
244
- 5.times {|i| threads << Thread.new {@pool.hold {|c| cc[i] = c; while !stop;sleep 0.02;end}}; sleep 0.02}
245
- sleep 0.04
253
+ 5.times{|i| threads << Thread.new{@pool.hold{|c| q.pop; cc[i] = c; q1.push nil; q2.pop}}; q.push nil; q1.pop}
246
254
  threads.each {|t| t.should be_alive}
247
255
  cc.size.should == 5
248
256
  @invoked_count.should == 5
249
257
  @pool.size.should == 5
250
258
  @pool.available_connections.should be_empty
251
- i = 0
259
+
252
260
  h = {}
261
+ i = 0
253
262
  threads.each{|t| h[t] = (i+=1)}
254
263
  @pool.allocated.should == h
255
-
256
- threads[0].raise "your'e dead"
257
- sleep 0.02
258
- threads[3].raise "your'e dead too"
259
-
260
- sleep 0.02
261
-
262
- @pool.available_connections.should == [1, 4]
263
- @pool.allocated.should == {threads[1]=>2, threads[2]=>3, threads[4]=>5}
264
-
265
- stop = true
266
- sleep 0.04
264
+ @pool.available_connections.should == []
265
+ 5.times{q2.push nil}
266
+ threads.each{|t| t.join}
267
267
 
268
268
  @pool.available_connections.size.should == 5
269
269
  @pool.allocated.should be_empty
@@ -272,16 +272,15 @@ shared_examples_for "A threaded connection pool" do
272
272
  specify "should block threads until a connection becomes available" do
273
273
  cc = {}
274
274
  threads = []
275
- stop = nil
275
+ q, q1 = Queue.new, Queue.new
276
276
 
277
- 5.times {|i| threads << Thread.new {@pool.hold {|c| cc[i] = c; while !stop;sleep 0.01;end}}; sleep 0.01}
278
- sleep 0.02
277
+ 5.times{|i| threads << Thread.new{@pool.hold{|c| cc[i] = c; q1.push nil; q.pop}}}
278
+ 5.times{q1.pop}
279
279
  threads.each {|t| t.should be_alive}
280
280
  @pool.available_connections.should be_empty
281
281
 
282
- 3.times {|i| threads << Thread.new {@pool.hold {|c| cc[i + 5] = c}}}
282
+ 3.times {|i| threads << Thread.new {@pool.hold {|c| cc[i + 5] = c; q1.push nil}}}
283
283
 
284
- sleep 0.02
285
284
  threads[5].should be_alive
286
285
  threads[6].should be_alive
287
286
  threads[7].should be_alive
@@ -290,8 +289,10 @@ shared_examples_for "A threaded connection pool" do
290
289
  cc[6].should be_nil
291
290
  cc[7].should be_nil
292
291
 
293
- stop = true
294
- sleep 0.1
292
+ 5.times{q.push nil}
293
+ 5.times{|i| threads[i].join}
294
+ 3.times{q1.pop}
295
+ 3.times{|i| threads[i+5].join}
295
296
 
296
297
  threads.each {|t| t.should_not be_alive}
297
298
 
@@ -305,7 +306,8 @@ end
305
306
  describe "Threaded Unsharded Connection Pool" do
306
307
  before do
307
308
  @invoked_count = 0
308
- @pool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS.merge(:max_connections=>5)) {@invoked_count += 1}
309
+ @cp_opts = CONNECTION_POOL_DEFAULTS.merge(:max_connections=>5)
310
+ @pool = Sequel::ConnectionPool.get_pool(@cp_opts) {@invoked_count += 1}
309
311
  end
310
312
 
311
313
  it_should_behave_like "A threaded connection pool"
@@ -314,7 +316,8 @@ end
314
316
  describe "Threaded Sharded Connection Pool" do
315
317
  before do
316
318
  @invoked_count = 0
317
- @pool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS.merge(:max_connections=>5, :servers=>{})) {@invoked_count += 1}
319
+ @cp_opts = CONNECTION_POOL_DEFAULTS.merge(:max_connections=>5, :servers=>{})
320
+ @pool = Sequel::ConnectionPool.get_pool(@cp_opts) {@invoked_count += 1}
318
321
  end
319
322
 
320
323
  it_should_behave_like "A threaded connection pool"
@@ -324,19 +327,15 @@ describe "ConnectionPool#disconnect" do
324
327
  before do
325
328
  @count = 0
326
329
  @pool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS.merge(:max_connections=>5, :servers=>{})) {{:id => @count += 1}}
330
+ threads = []
331
+ q, q1 = Queue.new, Queue.new
332
+ 5.times {|i| threads << Thread.new {@pool.hold {|c| q1.push nil; q.pop}}}
333
+ 5.times{q1.pop}
334
+ 5.times{q.push nil}
335
+ threads.each {|t| t.join}
327
336
  end
328
337
 
329
338
  specify "should invoke the given block for each available connection" do
330
- threads = []
331
- stop = nil
332
- 5.times {|i| threads << Thread.new {@pool.hold {|c| while !stop;sleep 0.01;end}}; sleep 0.01}
333
- while @pool.size < 5
334
- sleep 0.02
335
- end
336
- stop = true
337
- sleep 0.1
338
- threads.each {|t| t.join}
339
-
340
339
  @pool.size.should == 5
341
340
  @pool.available_connections.size.should == 5
342
341
  @pool.available_connections.each {|c| c[:id].should_not be_nil}
@@ -346,34 +345,13 @@ describe "ConnectionPool#disconnect" do
346
345
  end
347
346
 
348
347
  specify "should remove all available connections" do
349
- threads = []
350
- stop = nil
351
- 5.times {|i| threads << Thread.new {@pool.hold {|c| while !stop;sleep 0.01;end}}; sleep 0.01}
352
- while @pool.size < 5
353
- sleep 0.02
354
- end
355
- stop = true
356
- sleep 0.1
357
- threads.each {|t| t.join}
358
-
359
348
  @pool.size.should == 5
360
349
  @pool.disconnect
361
350
  @pool.size.should == 0
362
351
  end
363
352
 
364
353
  specify "should disconnect connections in use as soon as they are no longer in use" do
365
- threads = []
366
- stop = nil
367
- 5.times {|i| threads << Thread.new {@pool.hold {|c| while !stop;sleep 0.01;end}}; sleep 0.01}
368
- while @pool.size < 5
369
- sleep 0.02
370
- end
371
- stop = true
372
- sleep 0.1
373
- threads.each {|t| t.join}
374
-
375
354
  @pool.size.should == 5
376
-
377
355
  @pool.hold do |conn|
378
356
  @pool.available_connections.size.should == 4
379
357
  @pool.available_connections.each {|c| c.should_not be(conn)}
@@ -556,9 +534,10 @@ describe "A connection pool with multiple servers" do
556
534
  specify "#remove_servers should disconnect available connections immediately" do
557
535
  pool = Sequel::ConnectionPool.get_pool(:max_connections=>5, :servers=>{:server1=>{}}){|s| s}
558
536
  threads = []
559
- stop = nil
560
- 5.times {|i| threads << Thread.new{pool.hold(:server1){|c| sleep 0.05}}}
561
- sleep 0.1
537
+ q, q1 = Queue.new, Queue.new
538
+ 5.times {|i| threads << Thread.new {pool.hold(:server1){|c| q1.push nil; q.pop}}}
539
+ 5.times{q1.pop}
540
+ 5.times{q.push nil}
562
541
  threads.each {|t| t.join}
563
542
 
564
543
  pool.size(:server1).should == 5
@@ -75,16 +75,16 @@ end
75
75
 
76
76
  describe "String#lit" do
77
77
  before do
78
- @ds = ds = MockDatabase.new.dataset
78
+ @ds = ds = Sequel::Database.new[:t]
79
79
  end
80
+
80
81
  specify "should return an LiteralString object" do
81
82
  'xyz'.lit.should be_a_kind_of(Sequel::LiteralString)
82
83
  'xyz'.lit.to_s.should == 'xyz'
83
84
  end
84
85
 
85
86
  specify "should inhibit string literalization" do
86
- Sequel::Database.new[:t].update_sql(:stamp => "NOW()".lit).should == \
87
- "UPDATE t SET stamp = NOW()"
87
+ @ds.update_sql(:stamp => "NOW()".lit).should == "UPDATE t SET stamp = NOW()"
88
88
  end
89
89
 
90
90
  specify "should return a PlaceholderLiteralString object if args are given" do
@@ -176,10 +176,10 @@ end
176
176
 
177
177
  describe "Column references" do
178
178
  before do
179
- @c = Class.new(Sequel::Dataset) do
180
- def quoted_identifier(c); "`#{c}`"; end
179
+ @ds = Sequel::Database.new.dataset
180
+ def @ds.quoted_identifier_append(sql, c)
181
+ sql << "`#{c}`"
181
182
  end
182
- @ds = @c.new(MockDatabase.new)
183
183
  @ds.quote_identifiers = true
184
184
  end
185
185
 
@@ -289,7 +289,7 @@ end
289
289
 
290
290
  describe "Dataset#literal" do
291
291
  before do
292
- @ds = MockDataset.new(nil)
292
+ @ds = Sequel::Database.new.dataset
293
293
  end
294
294
 
295
295
  specify "should convert qualified symbol notation into dot notation" do
@@ -325,17 +325,12 @@ end
325
325
 
326
326
  describe "Symbol" do
327
327
  before do
328
- @ds = Sequel::Dataset.new(MockDatabase.new)
328
+ @ds = Sequel::Database.new.dataset
329
329
  end
330
330
 
331
- specify "should support upper case outer functions" do
331
+ specify "should support sql_function method" do
332
332
  :COUNT.sql_function('1').to_s(@ds).should == "COUNT('1')"
333
- end
334
-
335
- specify "should inhibit string literalization" do
336
- db = Sequel::Database.new
337
- ds = db[:t]
338
- ds.select(:COUNT.sql_function('1')).sql.should == "SELECT COUNT('1') FROM t"
333
+ @ds.select(:COUNT.sql_function('1')).sql.should == "SELECT COUNT('1')"
339
334
  end
340
335
 
341
336
  specify "should support cast method" do
@@ -367,22 +362,18 @@ describe "Symbol" do
367
362
  end
368
363
 
369
364
  specify "should allow database independent types when casting" do
370
- m = MockDatabase.new
371
- m.instance_eval do
372
- def cast_type_literal(type)
373
- return :foo if type == Integer
374
- return :bar if type == String
375
- type
376
- end
365
+ db = @ds.db
366
+ def db.cast_type_literal(type)
367
+ return :foo if type == Integer
368
+ return :bar if type == String
369
+ type
377
370
  end
378
- @ds2 = Sequel::Dataset.new(m)
379
- :abc.cast(String).to_s(@ds).should == "CAST(abc AS varchar(255))"
380
- :abc.cast(String).to_s(@ds2).should == "CAST(abc AS bar)"
381
- :abc.cast(String).to_s(@ds2).should == "CAST(abc AS bar)"
382
- :abc.cast_string.to_s(@ds2).should == "CAST(abc AS bar)"
383
- :abc.cast_string(Integer).to_s(@ds2).should == "CAST(abc AS foo)"
384
- :abc.cast_numeric.to_s(@ds2).should == "CAST(abc AS foo)"
385
- :abc.cast_numeric(String).to_s(@ds2).should == "CAST(abc AS bar)"
371
+ :abc.cast(String).to_s(@ds).should == "CAST(abc AS bar)"
372
+ :abc.cast(String).to_s(@ds).should == "CAST(abc AS bar)"
373
+ :abc.cast_string.to_s(@ds).should == "CAST(abc AS bar)"
374
+ :abc.cast_string(Integer).to_s(@ds).should == "CAST(abc AS foo)"
375
+ :abc.cast_numeric.to_s(@ds).should == "CAST(abc AS foo)"
376
+ :abc.cast_numeric(String).to_s(@ds).should == "CAST(abc AS bar)"
386
377
  end
387
378
 
388
379
  specify "should support SQL EXTRACT function via #extract " do