sequel 3.21.0 → 3.41.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 +1131 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +106 -65
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +68 -52
- data/doc/advanced_associations.rdoc +201 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/bin_sequel.rdoc +144 -0
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +10 -10
- data/doc/dataset_filtering.rdoc +54 -42
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +89 -557
- data/doc/model_hooks.rdoc +80 -29
- data/doc/object_model.rdoc +576 -0
- data/doc/opening_databases.rdoc +121 -53
- data/doc/prepared_statements.rdoc +41 -15
- data/doc/querying.rdoc +137 -56
- data/doc/reflection.rdoc +36 -10
- 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/release_notes/3.33.0.txt +157 -0
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/release_notes/3.35.0.txt +144 -0
- data/doc/release_notes/3.36.0.txt +245 -0
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/release_notes/3.39.0.txt +237 -0
- data/doc/release_notes/3.40.0.txt +73 -0
- data/doc/release_notes/3.41.0.txt +155 -0
- data/doc/schema_modification.rdoc +585 -0
- data/doc/sharding.rdoc +99 -8
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +169 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +78 -43
- data/lib/sequel/adapters/ado/access.rb +334 -0
- data/lib/sequel/adapters/ado/mssql.rb +18 -12
- data/lib/sequel/adapters/ado.rb +69 -21
- data/lib/sequel/adapters/amalgalite.rb +17 -14
- data/lib/sequel/adapters/cubrid.rb +143 -0
- data/lib/sequel/adapters/db2.rb +178 -85
- data/lib/sequel/adapters/dbi.rb +19 -21
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +2 -61
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +20 -39
- data/lib/sequel/adapters/firebird.rb +33 -210
- data/lib/sequel/adapters/ibmdb.rb +452 -0
- data/lib/sequel/adapters/informix.rb +6 -29
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/cubrid.rb +52 -0
- data/lib/sequel/adapters/jdbc/db2.rb +78 -0
- data/lib/sequel/adapters/jdbc/derby.rb +325 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +68 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +189 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +16 -28
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
- data/lib/sequel/adapters/jdbc/progress.rb +21 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
- data/lib/sequel/adapters/jdbc/sqlserver.rb +72 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +308 -114
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +130 -230
- data/lib/sequel/adapters/mysql2.rb +64 -63
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +29 -10
- data/lib/sequel/adapters/openbase.rb +7 -11
- data/lib/sequel/adapters/oracle.rb +364 -57
- data/lib/sequel/adapters/postgres.rb +379 -145
- data/lib/sequel/adapters/shared/access.rb +236 -11
- data/lib/sequel/adapters/shared/cubrid.rb +216 -0
- data/lib/sequel/adapters/shared/db2.rb +353 -0
- data/lib/sequel/adapters/shared/firebird.rb +231 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +412 -116
- data/lib/sequel/adapters/shared/mysql.rb +396 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +166 -0
- data/lib/sequel/adapters/shared/oracle.rb +262 -45
- data/lib/sequel/adapters/shared/postgres.rb +688 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +317 -96
- data/lib/sequel/adapters/sqlite.rb +109 -46
- data/lib/sequel/adapters/swift/mysql.rb +10 -12
- data/lib/sequel/adapters/swift/postgres.rb +13 -79
- data/lib/sequel/adapters/swift/sqlite.rb +9 -6
- data/lib/sequel/adapters/swift.rb +31 -27
- data/lib/sequel/adapters/tinytds.rb +177 -25
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
- data/lib/sequel/adapters/utils/pg_types.rb +81 -0
- data/lib/sequel/adapters/utils/split_alter_table.rb +36 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +23 -13
- data/lib/sequel/connection_pool/sharded_threaded.rb +64 -13
- data/lib/sequel/connection_pool/single.rb +11 -3
- data/lib/sequel/connection_pool/threaded.rb +69 -20
- data/lib/sequel/connection_pool.rb +20 -18
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +66 -29
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +63 -2
- data/lib/sequel/database/logging.rb +7 -2
- data/lib/sequel/database/misc.rb +192 -51
- data/lib/sequel/database/query.rb +299 -114
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +310 -69
- data/lib/sequel/dataset/actions.rb +344 -90
- data/lib/sequel/dataset/features.rb +101 -8
- data/lib/sequel/dataset/graph.rb +42 -15
- data/lib/sequel/dataset/misc.rb +52 -25
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +322 -68
- data/lib/sequel/dataset/sql.rb +716 -293
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +83 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +72 -0
- data/lib/sequel/extensions/connection_validator.rb +109 -0
- data/lib/sequel/extensions/constraint_validations.rb +451 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
- data/lib/sequel/extensions/eval_inspect.rb +173 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +100 -11
- data/lib/sequel/extensions/named_timezones.rb +9 -0
- data/lib/sequel/extensions/null_dataset.rb +94 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +539 -0
- data/lib/sequel/extensions/pg_array_ops.rb +263 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
- data/lib/sequel/extensions/pg_hstore.rb +334 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
- data/lib/sequel/extensions/pg_inet.rb +113 -0
- data/lib/sequel/extensions/pg_interval.rb +191 -0
- data/lib/sequel/extensions/pg_json.rb +212 -0
- data/lib/sequel/extensions/pg_range.rb +513 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +576 -0
- data/lib/sequel/extensions/pg_row_ops.rb +182 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
- data/lib/sequel/extensions/pretty_table.rb +17 -72
- data/lib/sequel/extensions/query.rb +8 -4
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +282 -76
- data/lib/sequel/extensions/select_remove.rb +39 -0
- data/lib/sequel/extensions/server_block.rb +140 -0
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +8 -110
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
- data/lib/sequel/extensions/to_dot.rb +99 -83
- data/lib/sequel/model/associations.rb +1263 -409
- data/lib/sequel/model/base.rb +624 -171
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +24 -2
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model.rb +30 -11
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +137 -16
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +44 -12
- data/lib/sequel/plugins/constraint_validations.rb +198 -0
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +72 -0
- data/lib/sequel/plugins/dirty.rb +214 -0
- data/lib/sequel/plugins/eager_each.rb +59 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +134 -15
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +77 -6
- data/lib/sequel/plugins/list.rb +13 -2
- data/lib/sequel/plugins/many_through_many.rb +103 -51
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +150 -66
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/prepared_statements.rb +168 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +87 -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 +31 -17
- data/lib/sequel/plugins/schema.rb +8 -3
- 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 +57 -12
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +29 -3
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/touch.rb +18 -6
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +57 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +721 -141
- data/lib/sequel/timezones.rb +67 -40
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +53 -39
- data/spec/adapters/mssql_spec.rb +261 -66
- data/spec/adapters/mysql_spec.rb +597 -352
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +2103 -341
- data/spec/adapters/spec_helper.rb +16 -6
- data/spec/adapters/sqlite_spec.rb +237 -76
- data/spec/core/connection_pool_spec.rb +270 -141
- data/spec/core/database_spec.rb +980 -524
- data/spec/core/dataset_spec.rb +1658 -1243
- data/spec/core/expression_filters_spec.rb +741 -334
- data/spec/core/mock_adapter_spec.rb +453 -0
- data/spec/core/object_graph_spec.rb +88 -129
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +556 -53
- data/spec/core/spec_helper.rb +7 -48
- data/spec/core_extensions_spec.rb +626 -0
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/arbitrary_servers_spec.rb +110 -0
- data/spec/extensions/association_autoreloading_spec.rb +18 -10
- data/spec/extensions/association_dependencies_spec.rb +15 -25
- data/spec/extensions/association_pks_spec.rb +227 -33
- data/spec/extensions/association_proxies_spec.rb +4 -4
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/caching_spec.rb +47 -51
- 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/connection_validator_spec.rb +118 -0
- data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
- data/spec/extensions/constraint_validations_spec.rb +316 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +88 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/eval_inspect_spec.rb +67 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +97 -128
- data/spec/extensions/identity_map_spec.rb +142 -24
- data/spec/extensions/inflector_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +72 -0
- data/spec/extensions/json_serializer_spec.rb +49 -12
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +49 -40
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +368 -254
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +140 -35
- data/spec/extensions/named_timezones_spec.rb +29 -11
- data/spec/extensions/nested_attributes_spec.rb +268 -89
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +24 -21
- data/spec/extensions/pg_array_ops_spec.rb +112 -0
- data/spec/extensions/pg_array_spec.rb +324 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
- data/spec/extensions/pg_hstore_spec.rb +200 -0
- data/spec/extensions/pg_inet_spec.rb +47 -0
- data/spec/extensions/pg_interval_spec.rb +72 -0
- data/spec/extensions/pg_json_spec.rb +99 -0
- data/spec/extensions/pg_range_ops_spec.rb +56 -0
- data/spec/extensions/pg_range_spec.rb +395 -0
- data/spec/extensions/pg_row_ops_spec.rb +58 -0
- data/spec/extensions/pg_row_plugin_spec.rb +49 -0
- data/spec/extensions/pg_row_spec.rb +340 -0
- data/spec/extensions/pg_statement_cache_spec.rb +208 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- 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 +87 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +7 -6
- data/spec/extensions/query_literals_spec.rb +167 -0
- data/spec/extensions/query_spec.rb +9 -3
- data/spec/extensions/rcte_tree_spec.rb +50 -43
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +434 -49
- data/spec/extensions/schema_spec.rb +30 -49
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +86 -48
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/sharding_spec.rb +69 -143
- data/spec/extensions/single_table_inheritance_spec.rb +65 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +34 -67
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/subclasses_spec.rb +14 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +17 -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 +8 -11
- data/spec/extensions/touch_spec.rb +53 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +9 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +77 -68
- data/spec/extensions/validation_helpers_spec.rb +48 -37
- data/spec/extensions/xml_serializer_spec.rb +29 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
- data/spec/integration/associations_test.rb +659 -21
- data/spec/integration/database_test.rb +25 -5
- data/spec/integration/dataset_test.rb +729 -141
- data/spec/integration/eager_loader_test.rb +38 -54
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +871 -160
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +377 -57
- data/spec/integration/spec_helper.rb +49 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +40 -8
- data/spec/model/association_reflection_spec.rb +207 -8
- data/spec/model/associations_spec.rb +1206 -693
- data/spec/model/base_spec.rb +334 -100
- data/spec/model/dataset_methods_spec.rb +45 -27
- data/spec/model/eager_loading_spec.rb +828 -692
- data/spec/model/hooks_spec.rb +355 -67
- data/spec/model/model_spec.rb +251 -179
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +506 -232
- data/spec/model/spec_helper.rb +16 -77
- data/spec/model/validations_spec.rb +38 -2
- data/spec/rcov.opts +2 -0
- metadata +223 -81
- data/spec/core/core_sql_spec.rb +0 -451
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
|
|
2
2
|
CONNECTION_POOL_DEFAULTS = {:pool_timeout=>5, :pool_sleep_time=>0.001, :max_connections=>4}
|
|
3
3
|
|
|
4
|
+
mock_db = lambda do |*a, &b|
|
|
5
|
+
db = Sequel.mock
|
|
6
|
+
db.meta_def(:connect){|c| b.arity == 1 ? b.call(c) : b.call} if b
|
|
7
|
+
if b2 = a.shift
|
|
8
|
+
db.meta_def(:disconnect_connection){|c| b2.arity == 1 ? b2.call(c) : b2.call}
|
|
9
|
+
end
|
|
10
|
+
db
|
|
11
|
+
end
|
|
12
|
+
|
|
4
13
|
describe "An empty ConnectionPool" do
|
|
5
14
|
before do
|
|
6
|
-
@cpool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS)
|
|
15
|
+
@cpool = Sequel::ConnectionPool.get_pool(mock_db.call, CONNECTION_POOL_DEFAULTS)
|
|
7
16
|
end
|
|
8
17
|
|
|
9
18
|
specify "should have no available connections" do
|
|
@@ -21,24 +30,25 @@ end
|
|
|
21
30
|
|
|
22
31
|
describe "ConnectionPool options" do
|
|
23
32
|
specify "should support string option values" do
|
|
24
|
-
cpool = Sequel::ConnectionPool.get_pool({:max_connections=>'5', :pool_timeout=>'3', :pool_sleep_time=>'0.01'})
|
|
33
|
+
cpool = Sequel::ConnectionPool.get_pool(mock_db.call, {:max_connections=>'5', :pool_timeout=>'3', :pool_sleep_time=>'0.01'})
|
|
25
34
|
cpool.max_size.should == 5
|
|
26
35
|
cpool.instance_variable_get(:@timeout).should == 3
|
|
27
36
|
cpool.instance_variable_get(:@sleep_time).should == 0.01
|
|
28
37
|
end
|
|
29
38
|
|
|
30
39
|
specify "should raise an error unless size is positive" do
|
|
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)
|
|
40
|
+
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>0)}.should raise_error(Sequel::Error)
|
|
41
|
+
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>-10)}.should raise_error(Sequel::Error)
|
|
42
|
+
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>'-10')}.should raise_error(Sequel::Error)
|
|
43
|
+
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>'0')}.should raise_error(Sequel::Error)
|
|
35
44
|
end
|
|
36
45
|
end
|
|
37
46
|
|
|
38
47
|
describe "A connection pool handling connections" do
|
|
39
48
|
before do
|
|
40
49
|
@max_size = 2
|
|
41
|
-
|
|
50
|
+
msp = proc{@max_size=3}
|
|
51
|
+
@cpool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| msp.call}){:got_connection}, CONNECTION_POOL_DEFAULTS.merge(:max_connections=>@max_size))
|
|
42
52
|
end
|
|
43
53
|
|
|
44
54
|
specify "#hold should increment #created_count" do
|
|
@@ -84,7 +94,9 @@ describe "A connection pool handling connections" do
|
|
|
84
94
|
end
|
|
85
95
|
|
|
86
96
|
specify "#make_new should not make more than max_size connections" do
|
|
87
|
-
|
|
97
|
+
q = Queue.new
|
|
98
|
+
50.times{Thread.new{@cpool.hold{q.pop}}}
|
|
99
|
+
50.times{q.push nil}
|
|
88
100
|
@cpool.created_count.should <= @max_size
|
|
89
101
|
end
|
|
90
102
|
|
|
@@ -96,7 +108,8 @@ describe "A connection pool handling connections" do
|
|
|
96
108
|
|
|
97
109
|
specify "#hold should remove the connection if a DatabaseDisconnectError is raised" do
|
|
98
110
|
@cpool.created_count.should == 0
|
|
99
|
-
|
|
111
|
+
q, q1 = Queue.new, Queue.new
|
|
112
|
+
@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
113
|
@cpool.created_count.should == 2
|
|
101
114
|
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.should raise_error(Sequel::DatabaseDisconnectError)
|
|
102
115
|
@cpool.created_count.should == 1
|
|
@@ -121,36 +134,30 @@ describe "A connection pool handling connection errors" do
|
|
|
121
134
|
end
|
|
122
135
|
end
|
|
123
136
|
|
|
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
137
|
describe "ConnectionPool#hold" do
|
|
136
138
|
before do
|
|
137
|
-
|
|
139
|
+
value = 0
|
|
140
|
+
c = @c = Class.new do
|
|
141
|
+
define_method(:initialize){value += 1}
|
|
142
|
+
define_method(:value){value}
|
|
143
|
+
end
|
|
144
|
+
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{c.new}, CONNECTION_POOL_DEFAULTS)
|
|
138
145
|
end
|
|
139
146
|
|
|
140
147
|
specify "should pass the result of the connection maker proc to the supplied block" do
|
|
141
148
|
res = nil
|
|
142
149
|
@pool.hold {|c| res = c}
|
|
143
|
-
res.should be_a_kind_of(
|
|
150
|
+
res.should be_a_kind_of(@c)
|
|
144
151
|
res.value.should == 1
|
|
145
152
|
@pool.hold {|c| res = c}
|
|
146
|
-
res.should be_a_kind_of(
|
|
153
|
+
res.should be_a_kind_of(@c)
|
|
147
154
|
res.value.should == 1 # the connection maker is invoked only once
|
|
148
155
|
end
|
|
149
156
|
|
|
150
157
|
specify "should be re-entrant by the same thread" do
|
|
151
158
|
cc = nil
|
|
152
159
|
@pool.hold {|c| @pool.hold {|c| @pool.hold {|c| cc = c}}}
|
|
153
|
-
cc.should be_a_kind_of(
|
|
160
|
+
cc.should be_a_kind_of(@c)
|
|
154
161
|
end
|
|
155
162
|
|
|
156
163
|
specify "should catch exceptions and reraise them" do
|
|
@@ -161,20 +168,20 @@ end
|
|
|
161
168
|
describe "A connection pool with a max size of 1" do
|
|
162
169
|
before do
|
|
163
170
|
@invoked_count = 0
|
|
164
|
-
|
|
171
|
+
icp = proc{@invoked_count += 1}
|
|
172
|
+
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{icp.call; 'herro'}, CONNECTION_POOL_DEFAULTS.merge(:max_connections=>1))
|
|
165
173
|
end
|
|
166
174
|
|
|
167
175
|
specify "should let only one thread access the connection at any time" do
|
|
168
176
|
cc,c1, c2 = nil
|
|
169
|
-
|
|
177
|
+
q, q1 = Queue.new, Queue.new
|
|
170
178
|
|
|
171
|
-
t1 = Thread.new {@pool.hold {|c| cc = c; c1 = c.dup;
|
|
172
|
-
|
|
179
|
+
t1 = Thread.new {@pool.hold {|c| cc = c; c1 = c.dup; q1.push nil; q.pop}}
|
|
180
|
+
q1.pop
|
|
173
181
|
cc.should == 'herro'
|
|
174
182
|
c1.should == 'herro'
|
|
175
183
|
|
|
176
|
-
t2 = Thread.new {@pool.hold {|c| c2 = c.dup;
|
|
177
|
-
sleep 0.02 * m
|
|
184
|
+
t2 = Thread.new {@pool.hold {|c| c2 = c.dup; q1.push nil; q.pop;}}
|
|
178
185
|
|
|
179
186
|
# connection held by t1
|
|
180
187
|
t1.should be_alive
|
|
@@ -186,26 +193,22 @@ describe "A connection pool with a max size of 1" do
|
|
|
186
193
|
|
|
187
194
|
@pool.available_connections.should be_empty
|
|
188
195
|
@pool.allocated.should == {t1=>cc}
|
|
189
|
-
|
|
196
|
+
|
|
190
197
|
cc.gsub!('rr', 'll')
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
# connection held by t2
|
|
194
|
-
t1.should_not be_alive
|
|
195
|
-
t2.should be_alive
|
|
198
|
+
q.push nil
|
|
199
|
+
q1.pop
|
|
196
200
|
|
|
201
|
+
t1.join
|
|
202
|
+
t2.should be_alive
|
|
203
|
+
|
|
197
204
|
c2.should == 'hello'
|
|
198
205
|
|
|
199
206
|
@pool.available_connections.should be_empty
|
|
200
207
|
@pool.allocated.should == {t2=>cc}
|
|
201
208
|
|
|
202
|
-
cc.gsub!('ll', 'rr')
|
|
203
|
-
sleep 0.05 * m
|
|
204
|
-
|
|
205
209
|
#connection released
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
cc.should == 'herro'
|
|
210
|
+
q.push nil
|
|
211
|
+
t2.join
|
|
209
212
|
|
|
210
213
|
@invoked_count.should == 1
|
|
211
214
|
@pool.size.should == 1
|
|
@@ -236,34 +239,81 @@ describe "A connection pool with a max size of 1" do
|
|
|
236
239
|
end
|
|
237
240
|
|
|
238
241
|
shared_examples_for "A threaded connection pool" do
|
|
242
|
+
specify "should not have all_connections yield connections allocated to other threads" do
|
|
243
|
+
pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>2, :pool_timeout=>0))
|
|
244
|
+
q, q1 = Queue.new, Queue.new
|
|
245
|
+
t = Thread.new do
|
|
246
|
+
pool.hold do |c1|
|
|
247
|
+
q1.push nil
|
|
248
|
+
q.pop
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
pool.hold do |c1|
|
|
252
|
+
q1.pop
|
|
253
|
+
pool.all_connections{|c| c.should == c1}
|
|
254
|
+
q.push nil
|
|
255
|
+
end
|
|
256
|
+
t.join
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
specify "should not have all_connections yield all available connections" do
|
|
260
|
+
pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>2, :pool_timeout=>0))
|
|
261
|
+
q, q1 = Queue.new, Queue.new
|
|
262
|
+
b = []
|
|
263
|
+
t = Thread.new do
|
|
264
|
+
pool.hold do |c1|
|
|
265
|
+
b << c1
|
|
266
|
+
q1.push nil
|
|
267
|
+
q.pop
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
pool.hold do |c1|
|
|
271
|
+
q1.pop
|
|
272
|
+
b << c1
|
|
273
|
+
q.push nil
|
|
274
|
+
end
|
|
275
|
+
t.join
|
|
276
|
+
a = []
|
|
277
|
+
pool.all_connections{|c| a << c}
|
|
278
|
+
a.sort.should == b.sort
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
specify "should raise a PoolTimeout error if a connection couldn't be acquired before timeout" do
|
|
282
|
+
x = nil
|
|
283
|
+
q, q1 = Queue.new, Queue.new
|
|
284
|
+
pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>1, :pool_timeout=>0))
|
|
285
|
+
t = Thread.new{pool.hold{|c| q1.push nil; q.pop}}
|
|
286
|
+
q1.pop
|
|
287
|
+
proc{pool.hold{|c|}}.should raise_error(Sequel::PoolTimeout)
|
|
288
|
+
q.push nil
|
|
289
|
+
t.join
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
it "should not add a disconnected connection back to the pool if the disconnection_proc raises an error" do
|
|
293
|
+
pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| raise Sequel::Error}, &@icpp), @cp_opts.merge(:max_connections=>1, :pool_timeout=>0))
|
|
294
|
+
proc{pool.hold{raise Sequel::DatabaseDisconnectError}}.should raise_error(Sequel::Error)
|
|
295
|
+
pool.available_connections.length.should == 0
|
|
296
|
+
end
|
|
297
|
+
|
|
239
298
|
specify "should let five threads simultaneously access separate connections" do
|
|
240
299
|
cc = {}
|
|
241
300
|
threads = []
|
|
242
|
-
|
|
301
|
+
q, q1, q2 = Queue.new, Queue.new, Queue.new
|
|
243
302
|
|
|
244
|
-
5.times
|
|
245
|
-
sleep 0.04
|
|
303
|
+
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
304
|
threads.each {|t| t.should be_alive}
|
|
247
305
|
cc.size.should == 5
|
|
248
306
|
@invoked_count.should == 5
|
|
249
307
|
@pool.size.should == 5
|
|
250
308
|
@pool.available_connections.should be_empty
|
|
251
|
-
|
|
309
|
+
|
|
252
310
|
h = {}
|
|
311
|
+
i = 0
|
|
253
312
|
threads.each{|t| h[t] = (i+=1)}
|
|
254
313
|
@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
|
|
314
|
+
@pool.available_connections.should == []
|
|
315
|
+
5.times{q2.push nil}
|
|
316
|
+
threads.each{|t| t.join}
|
|
267
317
|
|
|
268
318
|
@pool.available_connections.size.should == 5
|
|
269
319
|
@pool.allocated.should be_empty
|
|
@@ -272,16 +322,15 @@ shared_examples_for "A threaded connection pool" do
|
|
|
272
322
|
specify "should block threads until a connection becomes available" do
|
|
273
323
|
cc = {}
|
|
274
324
|
threads = []
|
|
275
|
-
|
|
325
|
+
q, q1 = Queue.new, Queue.new
|
|
276
326
|
|
|
277
|
-
5.times
|
|
278
|
-
|
|
327
|
+
5.times{|i| threads << Thread.new{@pool.hold{|c| cc[i] = c; q1.push nil; q.pop}}}
|
|
328
|
+
5.times{q1.pop}
|
|
279
329
|
threads.each {|t| t.should be_alive}
|
|
280
330
|
@pool.available_connections.should be_empty
|
|
281
331
|
|
|
282
|
-
3.times {|i| threads << Thread.new {@pool.hold {|c| cc[i + 5] = c}}}
|
|
332
|
+
3.times {|i| threads << Thread.new {@pool.hold {|c| cc[i + 5] = c; q1.push nil}}}
|
|
283
333
|
|
|
284
|
-
sleep 0.02
|
|
285
334
|
threads[5].should be_alive
|
|
286
335
|
threads[6].should be_alive
|
|
287
336
|
threads[7].should be_alive
|
|
@@ -290,8 +339,10 @@ shared_examples_for "A threaded connection pool" do
|
|
|
290
339
|
cc[6].should be_nil
|
|
291
340
|
cc[7].should be_nil
|
|
292
341
|
|
|
293
|
-
|
|
294
|
-
|
|
342
|
+
5.times{q.push nil}
|
|
343
|
+
5.times{|i| threads[i].join}
|
|
344
|
+
3.times{q1.pop}
|
|
345
|
+
3.times{|i| threads[i+5].join}
|
|
295
346
|
|
|
296
347
|
threads.each {|t| t.should_not be_alive}
|
|
297
348
|
|
|
@@ -300,12 +351,61 @@ shared_examples_for "A threaded connection pool" do
|
|
|
300
351
|
@pool.available_connections.size.should == 5
|
|
301
352
|
@pool.allocated.should be_empty
|
|
302
353
|
end
|
|
354
|
+
|
|
355
|
+
specify "should store connections in a stack by default" do
|
|
356
|
+
c2 = nil
|
|
357
|
+
c = @pool.hold{|cc| Thread.new{@pool.hold{|cc2| c2 = cc2}}.join; cc}
|
|
358
|
+
@pool.size.should == 2
|
|
359
|
+
@pool.hold{|cc| cc.should == c}
|
|
360
|
+
@pool.hold{|cc| cc.should == c}
|
|
361
|
+
@pool.hold do |cc|
|
|
362
|
+
cc.should == c
|
|
363
|
+
Thread.new{@pool.hold{|cc2| cc2.should == c2}}
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
specify "should store connections in a queue if :connection_handling=>:queue" do
|
|
368
|
+
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:connection_handling=>:queue))
|
|
369
|
+
c2 = nil
|
|
370
|
+
c = @pool.hold{|cc| Thread.new{@pool.hold{|cc2| c2 = cc2}}.join; cc}
|
|
371
|
+
@pool.size.should == 2
|
|
372
|
+
@pool.hold{|cc| cc.should == c2}
|
|
373
|
+
@pool.hold{|cc| cc.should == c}
|
|
374
|
+
@pool.hold do |cc|
|
|
375
|
+
cc.should == c2
|
|
376
|
+
Thread.new{@pool.hold{|cc2| cc2.should == c}}
|
|
377
|
+
end
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
specify "should not store connections if :connection_handling=>:disconnect" do
|
|
381
|
+
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:connection_handling=>:disconnect))
|
|
382
|
+
d = []
|
|
383
|
+
@pool.db.meta_def(:disconnect_connection){|c| d << c}
|
|
384
|
+
c = @pool.hold do |cc|
|
|
385
|
+
cc.should == 1
|
|
386
|
+
Thread.new{@pool.hold{|cc2| cc2.should == 2}}.join
|
|
387
|
+
d.should == [2]
|
|
388
|
+
@pool.hold{|cc3| cc3.should == 1}
|
|
389
|
+
end
|
|
390
|
+
@pool.size.should == 0
|
|
391
|
+
d.should == [2, 1]
|
|
392
|
+
|
|
393
|
+
@pool.hold{|cc| cc.should == 3}
|
|
394
|
+
@pool.size.should == 0
|
|
395
|
+
d.should == [2, 1, 3]
|
|
396
|
+
|
|
397
|
+
@pool.hold{|cc| cc.should == 4}
|
|
398
|
+
@pool.size.should == 0
|
|
399
|
+
d.should == [2, 1, 3, 4]
|
|
400
|
+
end
|
|
303
401
|
end
|
|
304
402
|
|
|
305
403
|
describe "Threaded Unsharded Connection Pool" do
|
|
306
404
|
before do
|
|
307
405
|
@invoked_count = 0
|
|
308
|
-
@
|
|
406
|
+
@icpp = proc{@invoked_count += 1}
|
|
407
|
+
@cp_opts = CONNECTION_POOL_DEFAULTS.merge(:max_connections=>5)
|
|
408
|
+
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts)
|
|
309
409
|
end
|
|
310
410
|
|
|
311
411
|
it_should_behave_like "A threaded connection pool"
|
|
@@ -314,7 +414,9 @@ end
|
|
|
314
414
|
describe "Threaded Sharded Connection Pool" do
|
|
315
415
|
before do
|
|
316
416
|
@invoked_count = 0
|
|
317
|
-
@
|
|
417
|
+
@icpp = proc{@invoked_count += 1}
|
|
418
|
+
@cp_opts = CONNECTION_POOL_DEFAULTS.merge(:max_connections=>5, :servers=>{})
|
|
419
|
+
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts)
|
|
318
420
|
end
|
|
319
421
|
|
|
320
422
|
it_should_behave_like "A threaded connection pool"
|
|
@@ -323,62 +425,40 @@ end
|
|
|
323
425
|
describe "ConnectionPool#disconnect" do
|
|
324
426
|
before do
|
|
325
427
|
@count = 0
|
|
326
|
-
|
|
428
|
+
cp = proc{@count += 1}
|
|
429
|
+
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{{:id => cp.call}}, CONNECTION_POOL_DEFAULTS.merge(:max_connections=>5, :servers=>{}))
|
|
430
|
+
threads = []
|
|
431
|
+
q, q1 = Queue.new, Queue.new
|
|
432
|
+
5.times {|i| threads << Thread.new {@pool.hold {|c| q1.push nil; q.pop}}}
|
|
433
|
+
5.times{q1.pop}
|
|
434
|
+
5.times{q.push nil}
|
|
435
|
+
threads.each {|t| t.join}
|
|
327
436
|
end
|
|
328
437
|
|
|
329
438
|
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
439
|
@pool.size.should == 5
|
|
341
440
|
@pool.available_connections.size.should == 5
|
|
342
441
|
@pool.available_connections.each {|c| c[:id].should_not be_nil}
|
|
343
442
|
conns = []
|
|
344
|
-
@pool.
|
|
443
|
+
@pool.db.meta_def(:disconnect_connection){|c| conns << c}
|
|
444
|
+
@pool.disconnect
|
|
345
445
|
conns.size.should == 5
|
|
346
446
|
end
|
|
347
447
|
|
|
348
448
|
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
449
|
@pool.size.should == 5
|
|
360
450
|
@pool.disconnect
|
|
361
451
|
@pool.size.should == 0
|
|
362
452
|
end
|
|
363
453
|
|
|
364
454
|
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
455
|
@pool.size.should == 5
|
|
376
|
-
|
|
377
456
|
@pool.hold do |conn|
|
|
378
457
|
@pool.available_connections.size.should == 4
|
|
379
458
|
@pool.available_connections.each {|c| c.should_not be(conn)}
|
|
380
459
|
conns = []
|
|
381
|
-
@pool.
|
|
460
|
+
@pool.db.meta_def(:disconnect_connection){|c| conns << c}
|
|
461
|
+
@pool.disconnect
|
|
382
462
|
conns.size.should == 4
|
|
383
463
|
@pool.size.should == 1
|
|
384
464
|
end
|
|
@@ -388,8 +468,18 @@ end
|
|
|
388
468
|
|
|
389
469
|
describe "A connection pool with multiple servers" do
|
|
390
470
|
before do
|
|
391
|
-
@invoked_counts = Hash.new(0)
|
|
392
|
-
@pool = Sequel::ConnectionPool.get_pool(
|
|
471
|
+
ic = @invoked_counts = Hash.new(0)
|
|
472
|
+
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{|server| "#{server}#{ic[server] += 1}"}, CONNECTION_POOL_DEFAULTS.merge(:servers=>{:read_only=>{}}))
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
specify "#all_connections should return connections for all servers" do
|
|
476
|
+
@pool.hold{}
|
|
477
|
+
@pool.all_connections{|c1| c1.should == "default1"}
|
|
478
|
+
a = []
|
|
479
|
+
@pool.hold(:read_only) do |c|
|
|
480
|
+
@pool.all_connections{|c1| a << c1}
|
|
481
|
+
end
|
|
482
|
+
a.sort_by{|c| c.to_s}.should == ["default1", "read_only1"]
|
|
393
483
|
end
|
|
394
484
|
|
|
395
485
|
specify "#servers should return symbols for all servers" do
|
|
@@ -420,7 +510,8 @@ describe "A connection pool with multiple servers" do
|
|
|
420
510
|
end
|
|
421
511
|
|
|
422
512
|
specify "should support a :servers_hash option used for converting the server argument" do
|
|
423
|
-
|
|
513
|
+
ic = @invoked_counts
|
|
514
|
+
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{|server| "#{server}#{ic[server] += 1}"}, CONNECTION_POOL_DEFAULTS.merge(:servers_hash=>Hash.new(:read_only), :servers=>{:read_only=>{}}))
|
|
424
515
|
@pool.hold(:blah) do |c1|
|
|
425
516
|
c1.should == "read_only1"
|
|
426
517
|
@pool.hold(:blah) do |c2|
|
|
@@ -431,7 +522,7 @@ describe "A connection pool with multiple servers" do
|
|
|
431
522
|
end
|
|
432
523
|
end
|
|
433
524
|
|
|
434
|
-
@pool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS.merge(:servers_hash=>Hash.new{|h,k| raise Sequel::Error}, :servers=>{:read_only=>{}}))
|
|
525
|
+
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{|server| "#{server}#{ic[server] += 1}"}, CONNECTION_POOL_DEFAULTS.merge(:servers_hash=>Hash.new{|h,k| raise Sequel::Error}, :servers=>{:read_only=>{}}))
|
|
435
526
|
proc{@pool.hold(:blah){|c1|}}.should raise_error(Sequel::Error)
|
|
436
527
|
end
|
|
437
528
|
|
|
@@ -468,7 +559,8 @@ describe "A connection pool with multiple servers" do
|
|
|
468
559
|
conns = []
|
|
469
560
|
@pool.size.should == 1
|
|
470
561
|
@pool.size(:read_only).should == 1
|
|
471
|
-
@pool.
|
|
562
|
+
@pool.db.meta_def(:disconnect_connection){|c| conns << c}
|
|
563
|
+
@pool.disconnect
|
|
472
564
|
conns.sort.should == %w'default1 read_only1'
|
|
473
565
|
@pool.size.should == 0
|
|
474
566
|
@pool.size(:read_only).should == 0
|
|
@@ -477,7 +569,7 @@ describe "A connection pool with multiple servers" do
|
|
|
477
569
|
end
|
|
478
570
|
|
|
479
571
|
specify "#add_servers should add new servers to the pool" do
|
|
480
|
-
pool = Sequel::ConnectionPool.get_pool(:servers=>{:server1=>{}})
|
|
572
|
+
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
|
|
481
573
|
|
|
482
574
|
pool.hold{}
|
|
483
575
|
pool.hold(:server2){}
|
|
@@ -508,7 +600,7 @@ describe "A connection pool with multiple servers" do
|
|
|
508
600
|
end
|
|
509
601
|
|
|
510
602
|
specify "#add_servers should ignore existing keys" do
|
|
511
|
-
pool = Sequel::ConnectionPool.get_pool(:servers=>{:server1=>{}})
|
|
603
|
+
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
|
|
512
604
|
|
|
513
605
|
pool.allocated.length.should == 0
|
|
514
606
|
pool.allocated(:server1).length.should == 0
|
|
@@ -554,11 +646,12 @@ describe "A connection pool with multiple servers" do
|
|
|
554
646
|
end
|
|
555
647
|
|
|
556
648
|
specify "#remove_servers should disconnect available connections immediately" do
|
|
557
|
-
pool = Sequel::ConnectionPool.get_pool(:max_connections=>5, :servers=>{:server1=>{}})
|
|
649
|
+
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :max_connections=>5, :servers=>{:server1=>{}})
|
|
558
650
|
threads = []
|
|
559
|
-
|
|
560
|
-
5.times {|i| threads << Thread.new{pool.hold(:server1){|c|
|
|
561
|
-
|
|
651
|
+
q, q1 = Queue.new, Queue.new
|
|
652
|
+
5.times {|i| threads << Thread.new {pool.hold(:server1){|c| q1.push nil; q.pop}}}
|
|
653
|
+
5.times{q1.pop}
|
|
654
|
+
5.times{q.push nil}
|
|
562
655
|
threads.each {|t| t.join}
|
|
563
656
|
|
|
564
657
|
pool.size(:server1).should == 5
|
|
@@ -568,7 +661,7 @@ describe "A connection pool with multiple servers" do
|
|
|
568
661
|
|
|
569
662
|
specify "#remove_servers should disconnect connections in use as soon as they are returned to the pool" do
|
|
570
663
|
dc = []
|
|
571
|
-
pool = Sequel::ConnectionPool.get_pool(
|
|
664
|
+
pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| dc << c}){|c| c}, :servers=>{:server1=>{}})
|
|
572
665
|
c1 = nil
|
|
573
666
|
pool.hold(:server1) do |c|
|
|
574
667
|
pool.size(:server1).should == 1
|
|
@@ -583,7 +676,7 @@ describe "A connection pool with multiple servers" do
|
|
|
583
676
|
end
|
|
584
677
|
|
|
585
678
|
specify "#remove_servers should remove server related data structures immediately" do
|
|
586
|
-
pool = Sequel::ConnectionPool.get_pool(:servers=>{:server1=>{}})
|
|
679
|
+
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
|
|
587
680
|
pool.available_connections(:server1).should == []
|
|
588
681
|
pool.allocated(:server1).should == {}
|
|
589
682
|
pool.remove_servers([:server1])
|
|
@@ -592,14 +685,14 @@ describe "A connection pool with multiple servers" do
|
|
|
592
685
|
end
|
|
593
686
|
|
|
594
687
|
specify "#remove_servers should not allow the removal of the default server" do
|
|
595
|
-
pool = Sequel::ConnectionPool.get_pool(:servers=>{:server1=>{}})
|
|
688
|
+
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
|
|
596
689
|
proc{pool.remove_servers([:server1])}.should_not raise_error
|
|
597
690
|
proc{pool.remove_servers([:default])}.should raise_error(Sequel::Error)
|
|
598
691
|
end
|
|
599
692
|
|
|
600
693
|
specify "#remove_servers should ignore servers that have already been removed" do
|
|
601
694
|
dc = []
|
|
602
|
-
pool = Sequel::ConnectionPool.get_pool(
|
|
695
|
+
pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| dc << c}){|c| c}, :servers=>{:server1=>{}})
|
|
603
696
|
c1 = nil
|
|
604
697
|
pool.hold(:server1) do |c|
|
|
605
698
|
pool.size(:server1).should == 1
|
|
@@ -619,7 +712,7 @@ ST_CONNECTION_POOL_DEFAULTS = CONNECTION_POOL_DEFAULTS.merge(:single_threaded=>t
|
|
|
619
712
|
|
|
620
713
|
describe "SingleConnectionPool" do
|
|
621
714
|
before do
|
|
622
|
-
@pool = Sequel::ConnectionPool.get_pool(
|
|
715
|
+
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{1234}, ST_CONNECTION_POOL_DEFAULTS)
|
|
623
716
|
end
|
|
624
717
|
|
|
625
718
|
specify "should provide a #hold method" do
|
|
@@ -631,7 +724,7 @@ describe "SingleConnectionPool" do
|
|
|
631
724
|
specify "should provide a #disconnect method" do
|
|
632
725
|
conn = nil
|
|
633
726
|
x = nil
|
|
634
|
-
pool = Sequel::ConnectionPool.get_pool(
|
|
727
|
+
pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| conn = c}){1234}, ST_CONNECTION_POOL_DEFAULTS)
|
|
635
728
|
pool.hold{|c| x = c}
|
|
636
729
|
x.should == 1234
|
|
637
730
|
pool.disconnect
|
|
@@ -642,7 +735,18 @@ end
|
|
|
642
735
|
describe "A single threaded pool with multiple servers" do
|
|
643
736
|
before do
|
|
644
737
|
@max_size=2
|
|
645
|
-
|
|
738
|
+
msp = proc{@max_size += 1}
|
|
739
|
+
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| msp.call}){|c| c}, ST_CONNECTION_POOL_DEFAULTS.merge(:servers=>{:read_only=>{}}))
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
specify "#all_connections should return connections for all servers" do
|
|
743
|
+
@pool.hold{}
|
|
744
|
+
@pool.all_connections{|c1| c1.should == :default}
|
|
745
|
+
a = []
|
|
746
|
+
@pool.hold(:read_only) do
|
|
747
|
+
@pool.all_connections{|c1| a << c1}
|
|
748
|
+
end
|
|
749
|
+
a.sort_by{|c| c.to_s}.should == [:default, :read_only]
|
|
646
750
|
end
|
|
647
751
|
|
|
648
752
|
specify "#servers should return symbols for all servers" do
|
|
@@ -726,11 +830,10 @@ describe "A single threaded pool with multiple servers" do
|
|
|
726
830
|
specify "#disconnect should disconnect from all servers" do
|
|
727
831
|
@pool.hold(:read_only){}
|
|
728
832
|
@pool.hold{}
|
|
729
|
-
conns = []
|
|
730
833
|
@pool.conn.should == :default
|
|
731
834
|
@pool.conn(:read_only).should == :read_only
|
|
732
|
-
@pool.disconnect
|
|
733
|
-
|
|
835
|
+
@pool.disconnect
|
|
836
|
+
@max_size.should == 4
|
|
734
837
|
@pool.conn.should == nil
|
|
735
838
|
@pool.conn(:read_only).should == nil
|
|
736
839
|
end
|
|
@@ -751,69 +854,92 @@ describe "A single threaded pool with multiple servers" do
|
|
|
751
854
|
end
|
|
752
855
|
|
|
753
856
|
shared_examples_for "All connection pools classes" do
|
|
857
|
+
specify "should have pool_type return a symbol" do
|
|
858
|
+
@class.new(mock_db.call{123}, {}).pool_type.should be_a_kind_of(Symbol)
|
|
859
|
+
end
|
|
860
|
+
|
|
861
|
+
specify "should have all_connections yield current and available connections" do
|
|
862
|
+
p = @class.new(mock_db.call{123}, {})
|
|
863
|
+
p.hold{|c| p.all_connections{|c1| c.should == c1}}
|
|
864
|
+
end
|
|
865
|
+
|
|
866
|
+
specify "should be able to modify after_connect proc after the pool is created" do
|
|
867
|
+
a = []
|
|
868
|
+
p = @class.new(mock_db.call{123}, {})
|
|
869
|
+
p.after_connect = pr = proc{|c| a << c}
|
|
870
|
+
p.after_connect.should == pr
|
|
871
|
+
a.should == []
|
|
872
|
+
p.hold{}
|
|
873
|
+
a.should == [123]
|
|
874
|
+
end
|
|
875
|
+
|
|
754
876
|
specify "should not raise an error when disconnecting twice" do
|
|
755
|
-
c = @class.new({}
|
|
877
|
+
c = @class.new(mock_db.call{123}, {})
|
|
756
878
|
proc{c.disconnect}.should_not raise_error
|
|
757
879
|
proc{c.disconnect}.should_not raise_error
|
|
758
880
|
end
|
|
759
881
|
|
|
760
882
|
specify "should yield a connection created by the initialize block to hold" do
|
|
761
883
|
x = nil
|
|
762
|
-
@class.new({}
|
|
884
|
+
@class.new(mock_db.call{123}, {}).hold{|c| x = c}
|
|
763
885
|
x.should == 123
|
|
764
886
|
end
|
|
765
887
|
|
|
766
888
|
specify "should have the initialize block accept a shard/server argument" do
|
|
767
889
|
x = nil
|
|
768
|
-
@class.new({
|
|
890
|
+
@class.new(mock_db.call{|c| [c, c]}, {}).hold{|c| x = c}
|
|
769
891
|
x.should == [:default, :default]
|
|
770
892
|
end
|
|
771
893
|
|
|
772
894
|
specify "should have respect an :after_connect proc that is called with each newly created connection" do
|
|
773
895
|
x = nil
|
|
774
|
-
@class.new(:after_connect=>proc{|c| x = [c, c]})
|
|
896
|
+
@class.new(mock_db.call{123}, :after_connect=>proc{|c| x = [c, c]}).hold{}
|
|
775
897
|
x.should == [123, 123]
|
|
776
898
|
end
|
|
777
899
|
|
|
778
900
|
specify "should raise a DatabaseConnectionError if the connection raises an exception" do
|
|
779
|
-
proc{@class.new({
|
|
901
|
+
proc{@class.new(mock_db.call{|c| raise Exception}, {}).hold{}}.should raise_error(Sequel::DatabaseConnectionError)
|
|
780
902
|
end
|
|
781
903
|
|
|
782
904
|
specify "should raise a DatabaseConnectionError if the initialize block returns nil" do
|
|
783
|
-
proc{@class.new({}
|
|
905
|
+
proc{@class.new(mock_db.call{}, {}).hold{}}.should raise_error(Sequel::DatabaseConnectionError)
|
|
784
906
|
end
|
|
785
907
|
|
|
786
908
|
specify "should call the disconnection_proc option if the hold block raises a DatabaseDisconnectError" do
|
|
787
909
|
x = nil
|
|
788
|
-
proc{@class.new(
|
|
910
|
+
proc{c = @class.new(mock_db.call(proc{|c| x = c}){123}).hold{raise Sequel::DatabaseDisconnectError}}.should raise_error(Sequel::DatabaseDisconnectError)
|
|
789
911
|
x.should == 123
|
|
790
912
|
end
|
|
791
913
|
|
|
792
|
-
specify "should have a disconnect method that
|
|
914
|
+
specify "should have a disconnect method that disconnects the connection" do
|
|
793
915
|
x = nil
|
|
794
|
-
c = @class.new(
|
|
916
|
+
c = @class.new(mock_db.call(proc{|c| x = c}){123})
|
|
795
917
|
c.hold{}
|
|
796
918
|
x.should == nil
|
|
797
919
|
c.disconnect
|
|
798
920
|
x.should == 123
|
|
799
921
|
end
|
|
800
922
|
|
|
801
|
-
specify "should have a
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
c
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
923
|
+
specify "should have a reentrent hold method" do
|
|
924
|
+
o = Object.new
|
|
925
|
+
c = @class.new(mock_db.call{o}, {})
|
|
926
|
+
c.hold do |x|
|
|
927
|
+
x.should == o
|
|
928
|
+
c.hold do |x1|
|
|
929
|
+
x1.should == o
|
|
930
|
+
c.hold do |x2|
|
|
931
|
+
x2.should == o
|
|
932
|
+
end
|
|
933
|
+
end
|
|
934
|
+
end
|
|
809
935
|
end
|
|
810
936
|
|
|
811
937
|
specify "should have a servers method that returns an array of shard/server symbols" do
|
|
812
|
-
@class.new({}
|
|
938
|
+
@class.new(mock_db.call{123}, {}).servers.should == [:default]
|
|
813
939
|
end
|
|
814
940
|
|
|
815
941
|
specify "should have a servers method that returns an array of shard/server symbols" do
|
|
816
|
-
c = @class.new({}
|
|
942
|
+
c = @class.new(mock_db.call{123}, {})
|
|
817
943
|
c.size.should == 0
|
|
818
944
|
c.hold{}
|
|
819
945
|
c.size.should == 1
|
|
@@ -823,6 +949,9 @@ end
|
|
|
823
949
|
Sequel::ConnectionPool::CONNECTION_POOL_MAP.keys.each do |k, v|
|
|
824
950
|
opts = {:single_threaded=>k, :servers=>(v ? {} : nil)}
|
|
825
951
|
describe "Connection pool with #{opts.inspect}" do
|
|
952
|
+
before(:all) do
|
|
953
|
+
Sequel::ConnectionPool.send(:get_pool, mock_db.call, opts)
|
|
954
|
+
end
|
|
826
955
|
before do
|
|
827
956
|
@class = Sequel::ConnectionPool.send(:connection_pool_class, opts)
|
|
828
957
|
end
|