sequel 3.21.0 → 3.32.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.
- data/CHANGELOG +539 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +20 -6
- data/Rakefile +37 -19
- data/bin/sequel +1 -5
- data/doc/advanced_associations.rdoc +17 -0
- data/doc/association_basics.rdoc +293 -43
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/dataset_filtering.rdoc +8 -0
- data/doc/mass_assignment.rdoc +54 -0
- data/doc/migration.rdoc +15 -538
- data/doc/model_hooks.rdoc +72 -27
- data/doc/opening_databases.rdoc +89 -50
- data/doc/prepared_statements.rdoc +40 -13
- data/doc/reflection.rdoc +8 -2
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/schema_modification.rdoc +547 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +129 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +5 -7
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/do.rb +17 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +448 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +52 -0
- data/lib/sequel/adapters/jdbc/derby.rb +260 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +66 -30
- data/lib/sequel/adapters/jdbc/hsqldb.rb +177 -0
- data/lib/sequel/adapters/jdbc/informix.rb +26 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +11 -11
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +9 -13
- data/lib/sequel/adapters/jdbc/sqlite.rb +2 -6
- data/lib/sequel/adapters/jdbc/sqlserver.rb +71 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +231 -78
- data/lib/sequel/adapters/mock.rb +339 -0
- data/lib/sequel/adapters/mysql.rb +85 -184
- data/lib/sequel/adapters/mysql2.rb +26 -25
- data/lib/sequel/adapters/odbc/db2.rb +17 -0
- data/lib/sequel/adapters/odbc/mssql.rb +1 -6
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +355 -53
- data/lib/sequel/adapters/postgres.rb +194 -33
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +328 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +278 -107
- data/lib/sequel/adapters/shared/mysql.rb +203 -65
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +237 -46
- data/lib/sequel/adapters/shared/postgres.rb +214 -82
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +200 -50
- data/lib/sequel/adapters/sqlite.rb +29 -21
- data/lib/sequel/adapters/swift/mysql.rb +12 -7
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +8 -6
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/tinytds.rb +160 -19
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +190 -0
- data/lib/sequel/connection_pool/threaded.rb +3 -2
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +68 -5
- data/lib/sequel/database/connecting.rb +5 -6
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +59 -1
- data/lib/sequel/database/logging.rb +1 -1
- data/lib/sequel/database/misc.rb +104 -19
- data/lib/sequel/database/query.rb +163 -59
- data/lib/sequel/database/schema_generator.rb +17 -7
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +240 -76
- data/lib/sequel/dataset/features.rb +91 -8
- data/lib/sequel/dataset/graph.rb +38 -11
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +59 -27
- data/lib/sequel/dataset/query.rb +236 -43
- data/lib/sequel/dataset/sql.rb +676 -267
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/extensions/migration.rb +6 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/query.rb +1 -1
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +1081 -344
- data/lib/sequel/model/base.rb +420 -133
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +20 -10
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +43 -10
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +114 -7
- data/lib/sequel/plugins/many_through_many.rb +68 -7
- data/lib/sequel/plugins/nested_attributes.rb +65 -10
- data/lib/sequel/plugins/prepared_statements.rb +151 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +109 -52
- data/lib/sequel/timezones.rb +57 -38
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/mssql_spec.rb +135 -30
- data/spec/adapters/mysql_spec.rb +244 -212
- data/spec/adapters/oracle_spec.rb +67 -77
- data/spec/adapters/postgres_spec.rb +267 -78
- data/spec/adapters/spec_helper.rb +6 -5
- data/spec/adapters/sqlite_spec.rb +35 -21
- data/spec/core/connection_pool_spec.rb +71 -92
- data/spec/core/core_sql_spec.rb +21 -30
- data/spec/core/database_spec.rb +789 -512
- data/spec/core/dataset_spec.rb +1176 -1061
- data/spec/core/expression_filters_spec.rb +159 -42
- data/spec/core/mock_adapter_spec.rb +419 -0
- data/spec/core/object_graph_spec.rb +86 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +298 -38
- data/spec/core/spec_helper.rb +6 -48
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/association_autoreloading_spec.rb +1 -10
- data/spec/extensions/association_dependencies_spec.rb +2 -12
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/caching_spec.rb +23 -50
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/hook_class_methods_spec.rb +65 -91
- data/spec/extensions/identity_map_spec.rb +114 -22
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +53 -0
- data/spec/extensions/json_serializer_spec.rb +4 -5
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +17 -39
- data/spec/extensions/many_through_many_spec.rb +283 -250
- data/spec/extensions/migration_spec.rb +35 -32
- data/spec/extensions/named_timezones_spec.rb +23 -3
- data/spec/extensions/nested_attributes_spec.rb +97 -88
- data/spec/extensions/optimistic_locking_spec.rb +9 -20
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +53 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +1 -6
- data/spec/extensions/query_spec.rb +6 -0
- data/spec/extensions/rcte_tree_spec.rb +41 -43
- data/spec/extensions/schema_dumper_spec.rb +5 -8
- data/spec/extensions/schema_spec.rb +13 -21
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +81 -43
- data/spec/extensions/sharding_spec.rb +66 -140
- data/spec/extensions/single_table_inheritance_spec.rb +18 -29
- data/spec/extensions/spec_helper.rb +13 -61
- data/spec/extensions/sql_expr_spec.rb +20 -60
- data/spec/extensions/tactical_eager_loading_spec.rb +9 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +4 -7
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +30 -51
- data/spec/extensions/validation_helpers_spec.rb +16 -35
- data/spec/extensions/xml_serializer_spec.rb +16 -4
- data/spec/integration/associations_test.rb +661 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +500 -67
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +367 -119
- data/spec/integration/prepared_statement_test.rb +222 -125
- data/spec/integration/schema_test.rb +217 -39
- data/spec/integration/spec_helper.rb +39 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +182 -5
- data/spec/integration/type_test.rb +17 -3
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +955 -662
- data/spec/model/base_spec.rb +275 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +677 -676
- data/spec/model/hooks_spec.rb +349 -67
- data/spec/model/model_spec.rb +222 -168
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +381 -218
- data/spec/model/spec_helper.rb +13 -71
- data/spec/model/validations_spec.rb +11 -0
- metadata +117 -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
166
|
+
q, q1 = Queue.new, Queue.new
|
|
170
167
|
|
|
171
|
-
t1 = Thread.new {@pool.hold {|c| cc = c; c1 = c.dup;
|
|
172
|
-
|
|
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;
|
|
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
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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
|
-
|
|
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
|
-
|
|
251
|
+
q, q1, q2 = Queue.new, Queue.new, Queue.new
|
|
243
252
|
|
|
244
|
-
5.times
|
|
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
|
-
|
|
259
|
+
|
|
252
260
|
h = {}
|
|
261
|
+
i = 0
|
|
253
262
|
threads.each{|t| h[t] = (i+=1)}
|
|
254
263
|
@pool.allocated.should == h
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
-
|
|
275
|
+
q, q1 = Queue.new, Queue.new
|
|
276
276
|
|
|
277
|
-
5.times
|
|
278
|
-
|
|
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
|
-
|
|
294
|
-
|
|
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
|
-
@
|
|
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
|
-
@
|
|
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
|
-
|
|
560
|
-
5.times {|i| threads << Thread.new{pool.hold(:server1){|c|
|
|
561
|
-
|
|
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
|
data/spec/core/core_sql_spec.rb
CHANGED
|
@@ -75,16 +75,16 @@ end
|
|
|
75
75
|
|
|
76
76
|
describe "String#lit" do
|
|
77
77
|
before do
|
|
78
|
-
@ds = ds =
|
|
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
|
-
|
|
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
|
-
@
|
|
180
|
-
|
|
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 =
|
|
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::
|
|
328
|
+
@ds = Sequel::Database.new.dataset
|
|
329
329
|
end
|
|
330
330
|
|
|
331
|
-
specify "should support
|
|
331
|
+
specify "should support sql_function method" do
|
|
332
332
|
:COUNT.sql_function('1').to_s(@ds).should == "COUNT('1')"
|
|
333
|
-
|
|
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
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
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
|
-
@
|
|
379
|
-
:abc.cast(String).to_s(@ds).should == "CAST(abc AS
|
|
380
|
-
:abc.
|
|
381
|
-
:abc.
|
|
382
|
-
:abc.
|
|
383
|
-
:abc.
|
|
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
|