sequel 5.20.0 → 5.49.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.
- checksums.yaml +4 -4
- data/CHANGELOG +398 -1922
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -7
- data/doc/advanced_associations.rdoc +4 -4
- data/doc/association_basics.rdoc +80 -16
- data/doc/cheat_sheet.rdoc +6 -5
- data/doc/code_order.rdoc +10 -12
- data/doc/dataset_filtering.rdoc +17 -2
- data/doc/fork_safety.rdoc +84 -0
- data/doc/migration.rdoc +11 -5
- data/doc/model_dataset_method_design.rdoc +1 -1
- data/doc/model_plugins.rdoc +1 -1
- data/doc/opening_databases.rdoc +10 -2
- data/doc/postgresql.rdoc +82 -3
- data/doc/querying.rdoc +4 -4
- data/doc/release_notes/5.21.0.txt +87 -0
- data/doc/release_notes/5.22.0.txt +48 -0
- data/doc/release_notes/5.23.0.txt +56 -0
- data/doc/release_notes/5.24.0.txt +56 -0
- data/doc/release_notes/5.25.0.txt +32 -0
- data/doc/release_notes/5.26.0.txt +35 -0
- data/doc/release_notes/5.27.0.txt +21 -0
- data/doc/release_notes/5.28.0.txt +16 -0
- data/doc/release_notes/5.29.0.txt +22 -0
- data/doc/release_notes/5.30.0.txt +20 -0
- data/doc/release_notes/5.31.0.txt +148 -0
- data/doc/release_notes/5.32.0.txt +46 -0
- data/doc/release_notes/5.33.0.txt +24 -0
- data/doc/release_notes/5.34.0.txt +40 -0
- data/doc/release_notes/5.35.0.txt +56 -0
- data/doc/release_notes/5.36.0.txt +60 -0
- data/doc/release_notes/5.37.0.txt +30 -0
- data/doc/release_notes/5.38.0.txt +28 -0
- data/doc/release_notes/5.39.0.txt +19 -0
- data/doc/release_notes/5.40.0.txt +40 -0
- data/doc/release_notes/5.41.0.txt +25 -0
- data/doc/release_notes/5.42.0.txt +136 -0
- data/doc/release_notes/5.43.0.txt +98 -0
- data/doc/release_notes/5.44.0.txt +32 -0
- data/doc/release_notes/5.45.0.txt +34 -0
- data/doc/release_notes/5.46.0.txt +87 -0
- data/doc/release_notes/5.47.0.txt +59 -0
- data/doc/release_notes/5.48.0.txt +14 -0
- data/doc/release_notes/5.49.0.txt +59 -0
- data/doc/sharding.rdoc +2 -0
- data/doc/sql.rdoc +13 -1
- data/doc/testing.rdoc +20 -7
- data/doc/transactions.rdoc +0 -8
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +1 -1
- data/lib/sequel/adapters/ado/access.rb +1 -1
- data/lib/sequel/adapters/ado.rb +43 -35
- data/lib/sequel/adapters/ibmdb.rb +2 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +6 -6
- data/lib/sequel/adapters/jdbc/postgresql.rb +11 -17
- data/lib/sequel/adapters/jdbc/sqlite.rb +29 -0
- data/lib/sequel/adapters/jdbc.rb +24 -6
- data/lib/sequel/adapters/mysql.rb +1 -1
- data/lib/sequel/adapters/mysql2.rb +2 -3
- data/lib/sequel/adapters/odbc.rb +8 -6
- data/lib/sequel/adapters/oracle.rb +5 -4
- data/lib/sequel/adapters/postgres.rb +15 -9
- data/lib/sequel/adapters/shared/access.rb +6 -6
- data/lib/sequel/adapters/shared/mssql.rb +66 -21
- data/lib/sequel/adapters/shared/mysql.rb +27 -10
- data/lib/sequel/adapters/shared/oracle.rb +29 -23
- data/lib/sequel/adapters/shared/postgres.rb +271 -32
- data/lib/sequel/adapters/shared/sqlanywhere.rb +9 -9
- data/lib/sequel/adapters/shared/sqlite.rb +161 -19
- data/lib/sequel/adapters/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +1 -1
- data/lib/sequel/adapters/tinytds.rb +15 -2
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +4 -1
- data/lib/sequel/ast_transformer.rb +6 -0
- data/lib/sequel/connection_pool/sharded_single.rb +4 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +12 -12
- data/lib/sequel/connection_pool/single.rb +1 -1
- data/lib/sequel/connection_pool/threaded.rb +2 -2
- data/lib/sequel/core.rb +333 -319
- data/lib/sequel/database/connecting.rb +3 -4
- data/lib/sequel/database/logging.rb +7 -1
- data/lib/sequel/database/misc.rb +31 -12
- data/lib/sequel/database/query.rb +3 -1
- data/lib/sequel/database/schema_generator.rb +53 -51
- data/lib/sequel/database/schema_methods.rb +38 -23
- data/lib/sequel/database/transactions.rb +17 -18
- data/lib/sequel/dataset/actions.rb +14 -9
- data/lib/sequel/dataset/features.rb +16 -0
- data/lib/sequel/dataset/misc.rb +2 -2
- data/lib/sequel/dataset/placeholder_literalizer.rb +3 -7
- data/lib/sequel/dataset/prepared_statements.rb +2 -0
- data/lib/sequel/dataset/query.rb +26 -9
- data/lib/sequel/dataset/sql.rb +76 -25
- data/lib/sequel/dataset.rb +4 -2
- data/lib/sequel/deprecated.rb +3 -1
- data/lib/sequel/exceptions.rb +2 -0
- data/lib/sequel/extensions/_pretty_table.rb +1 -2
- data/lib/sequel/extensions/any_not_empty.rb +45 -0
- data/lib/sequel/extensions/async_thread_pool.rb +438 -0
- data/lib/sequel/extensions/blank.rb +8 -0
- data/lib/sequel/extensions/columns_introspection.rb +1 -2
- data/lib/sequel/extensions/connection_expiration.rb +2 -2
- data/lib/sequel/extensions/connection_validator.rb +2 -2
- data/lib/sequel/extensions/core_refinements.rb +2 -0
- data/lib/sequel/extensions/date_arithmetic.rb +36 -24
- data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -1
- data/lib/sequel/extensions/eval_inspect.rb +2 -0
- data/lib/sequel/extensions/exclude_or_null.rb +68 -0
- data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
- data/lib/sequel/extensions/index_caching.rb +9 -7
- data/lib/sequel/extensions/inflector.rb +9 -1
- data/lib/sequel/extensions/integer64.rb +2 -0
- data/lib/sequel/extensions/migration.rb +11 -3
- data/lib/sequel/extensions/named_timezones.rb +56 -8
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +5 -0
- data/lib/sequel/extensions/pg_array_ops.rb +14 -6
- data/lib/sequel/extensions/pg_enum.rb +11 -3
- data/lib/sequel/extensions/pg_extended_date_support.rb +2 -2
- data/lib/sequel/extensions/pg_hstore.rb +6 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +54 -2
- data/lib/sequel/extensions/pg_inet.rb +15 -5
- data/lib/sequel/extensions/pg_interval.rb +36 -8
- data/lib/sequel/extensions/pg_json.rb +387 -123
- data/lib/sequel/extensions/pg_json_ops.rb +238 -0
- data/lib/sequel/extensions/pg_loose_count.rb +3 -1
- data/lib/sequel/extensions/pg_range.rb +17 -9
- data/lib/sequel/extensions/pg_range_ops.rb +2 -0
- data/lib/sequel/extensions/pg_row.rb +4 -2
- data/lib/sequel/extensions/pg_row_ops.rb +24 -0
- data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
- data/lib/sequel/extensions/query.rb +3 -0
- data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
- data/lib/sequel/extensions/s.rb +2 -0
- data/lib/sequel/extensions/schema_dumper.rb +24 -7
- data/lib/sequel/extensions/server_block.rb +18 -7
- data/lib/sequel/extensions/sql_comments.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +1 -1
- data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
- data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
- data/lib/sequel/extensions/to_dot.rb +9 -3
- data/lib/sequel/model/associations.rb +356 -117
- data/lib/sequel/model/base.rb +107 -68
- data/lib/sequel/model/errors.rb +10 -1
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model/plugins.rb +9 -3
- data/lib/sequel/model.rb +3 -1
- data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
- data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
- data/lib/sequel/plugins/association_pks.rb +60 -18
- data/lib/sequel/plugins/association_proxies.rb +8 -2
- data/lib/sequel/plugins/async_thread_pool.rb +39 -0
- data/lib/sequel/plugins/auto_validations.rb +39 -5
- data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
- data/lib/sequel/plugins/blacklist_security.rb +1 -2
- data/lib/sequel/plugins/boolean_subsets.rb +4 -1
- data/lib/sequel/plugins/caching.rb +3 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +33 -28
- data/lib/sequel/plugins/column_encryption.rb +728 -0
- data/lib/sequel/plugins/composition.rb +7 -2
- data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
- data/lib/sequel/plugins/constraint_validations.rb +2 -1
- data/lib/sequel/plugins/csv_serializer.rb +28 -9
- data/lib/sequel/plugins/dataset_associations.rb +4 -1
- data/lib/sequel/plugins/dirty.rb +60 -22
- data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
- data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
- data/lib/sequel/plugins/insert_conflict.rb +72 -0
- data/lib/sequel/plugins/instance_specific_default.rb +113 -0
- data/lib/sequel/plugins/json_serializer.rb +57 -35
- data/lib/sequel/plugins/lazy_attributes.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +108 -9
- data/lib/sequel/plugins/nested_attributes.rb +15 -3
- data/lib/sequel/plugins/pg_array_associations.rb +58 -41
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +91 -30
- data/lib/sequel/plugins/prepared_statements.rb +15 -12
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
- data/lib/sequel/plugins/rcte_tree.rb +43 -35
- data/lib/sequel/plugins/serialization.rb +8 -3
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +11 -5
- data/lib/sequel/plugins/single_table_inheritance.rb +22 -15
- data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
- data/lib/sequel/plugins/static_cache.rb +9 -4
- data/lib/sequel/plugins/static_cache_cache.rb +53 -0
- data/lib/sequel/plugins/string_stripper.rb +1 -1
- data/lib/sequel/plugins/subclasses.rb +2 -0
- data/lib/sequel/plugins/throw_failures.rb +1 -1
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/tree.rb +9 -4
- data/lib/sequel/plugins/typecast_on_load.rb +3 -2
- data/lib/sequel/plugins/unused_associations.rb +521 -0
- data/lib/sequel/plugins/update_or_create.rb +1 -1
- data/lib/sequel/plugins/validation_class_methods.rb +5 -1
- data/lib/sequel/plugins/validation_helpers.rb +18 -11
- data/lib/sequel/plugins/xml_serializer.rb +1 -1
- data/lib/sequel/sql.rb +20 -5
- data/lib/sequel/timezones.rb +63 -17
- data/lib/sequel/version.rb +1 -1
- metadata +113 -381
- data/Rakefile +0 -151
- data/doc/release_notes/4.0.0.txt +0 -262
- data/doc/release_notes/4.1.0.txt +0 -85
- data/doc/release_notes/4.10.0.txt +0 -226
- data/doc/release_notes/4.11.0.txt +0 -147
- data/doc/release_notes/4.12.0.txt +0 -105
- data/doc/release_notes/4.13.0.txt +0 -169
- data/doc/release_notes/4.14.0.txt +0 -68
- data/doc/release_notes/4.15.0.txt +0 -56
- data/doc/release_notes/4.16.0.txt +0 -36
- data/doc/release_notes/4.17.0.txt +0 -38
- data/doc/release_notes/4.18.0.txt +0 -36
- data/doc/release_notes/4.19.0.txt +0 -45
- data/doc/release_notes/4.2.0.txt +0 -129
- data/doc/release_notes/4.20.0.txt +0 -79
- data/doc/release_notes/4.21.0.txt +0 -94
- data/doc/release_notes/4.22.0.txt +0 -72
- data/doc/release_notes/4.23.0.txt +0 -65
- data/doc/release_notes/4.24.0.txt +0 -99
- data/doc/release_notes/4.25.0.txt +0 -181
- data/doc/release_notes/4.26.0.txt +0 -44
- data/doc/release_notes/4.27.0.txt +0 -78
- data/doc/release_notes/4.28.0.txt +0 -57
- data/doc/release_notes/4.29.0.txt +0 -41
- data/doc/release_notes/4.3.0.txt +0 -40
- data/doc/release_notes/4.30.0.txt +0 -37
- data/doc/release_notes/4.31.0.txt +0 -57
- data/doc/release_notes/4.32.0.txt +0 -132
- data/doc/release_notes/4.33.0.txt +0 -88
- data/doc/release_notes/4.34.0.txt +0 -86
- data/doc/release_notes/4.35.0.txt +0 -130
- data/doc/release_notes/4.36.0.txt +0 -116
- data/doc/release_notes/4.37.0.txt +0 -50
- data/doc/release_notes/4.38.0.txt +0 -67
- data/doc/release_notes/4.39.0.txt +0 -127
- data/doc/release_notes/4.4.0.txt +0 -92
- data/doc/release_notes/4.40.0.txt +0 -179
- data/doc/release_notes/4.41.0.txt +0 -77
- data/doc/release_notes/4.42.0.txt +0 -221
- data/doc/release_notes/4.43.0.txt +0 -87
- data/doc/release_notes/4.44.0.txt +0 -125
- data/doc/release_notes/4.45.0.txt +0 -370
- data/doc/release_notes/4.46.0.txt +0 -404
- data/doc/release_notes/4.47.0.txt +0 -56
- data/doc/release_notes/4.48.0.txt +0 -293
- data/doc/release_notes/4.49.0.txt +0 -222
- data/doc/release_notes/4.5.0.txt +0 -34
- data/doc/release_notes/4.6.0.txt +0 -30
- data/doc/release_notes/4.7.0.txt +0 -103
- data/doc/release_notes/4.8.0.txt +0 -175
- data/doc/release_notes/4.9.0.txt +0 -190
- data/spec/adapter_spec.rb +0 -4
- data/spec/adapters/db2_spec.rb +0 -170
- data/spec/adapters/mssql_spec.rb +0 -804
- data/spec/adapters/mysql_spec.rb +0 -1065
- data/spec/adapters/oracle_spec.rb +0 -371
- data/spec/adapters/postgres_spec.rb +0 -4125
- data/spec/adapters/spec_helper.rb +0 -44
- data/spec/adapters/sqlanywhere_spec.rb +0 -97
- data/spec/adapters/sqlite_spec.rb +0 -652
- data/spec/bin_spec.rb +0 -278
- data/spec/core/connection_pool_spec.rb +0 -1250
- data/spec/core/database_spec.rb +0 -2865
- data/spec/core/dataset_spec.rb +0 -5515
- data/spec/core/deprecated_spec.rb +0 -70
- data/spec/core/expression_filters_spec.rb +0 -1455
- data/spec/core/mock_adapter_spec.rb +0 -722
- data/spec/core/object_graph_spec.rb +0 -336
- data/spec/core/placeholder_literalizer_spec.rb +0 -166
- data/spec/core/schema_generator_spec.rb +0 -214
- data/spec/core/schema_spec.rb +0 -1826
- data/spec/core/spec_helper.rb +0 -24
- data/spec/core/version_spec.rb +0 -14
- data/spec/core_extensions_spec.rb +0 -763
- data/spec/core_model_spec.rb +0 -2
- data/spec/core_spec.rb +0 -1
- data/spec/deprecation_helper.rb +0 -30
- data/spec/extensions/accessed_columns_spec.rb +0 -51
- data/spec/extensions/active_model_spec.rb +0 -99
- data/spec/extensions/after_initialize_spec.rb +0 -28
- data/spec/extensions/arbitrary_servers_spec.rb +0 -109
- data/spec/extensions/association_dependencies_spec.rb +0 -125
- data/spec/extensions/association_pks_spec.rb +0 -423
- data/spec/extensions/association_proxies_spec.rb +0 -100
- data/spec/extensions/auto_literal_strings_spec.rb +0 -205
- data/spec/extensions/auto_validations_spec.rb +0 -229
- data/spec/extensions/blacklist_security_spec.rb +0 -95
- data/spec/extensions/blank_spec.rb +0 -69
- data/spec/extensions/boolean_readers_spec.rb +0 -93
- data/spec/extensions/boolean_subsets_spec.rb +0 -47
- data/spec/extensions/caching_spec.rb +0 -273
- data/spec/extensions/caller_logging_spec.rb +0 -52
- data/spec/extensions/class_table_inheritance_spec.rb +0 -750
- data/spec/extensions/column_conflicts_spec.rb +0 -75
- data/spec/extensions/column_select_spec.rb +0 -129
- data/spec/extensions/columns_introspection_spec.rb +0 -90
- data/spec/extensions/columns_updated_spec.rb +0 -35
- data/spec/extensions/composition_spec.rb +0 -248
- data/spec/extensions/connection_expiration_spec.rb +0 -151
- data/spec/extensions/connection_validator_spec.rb +0 -144
- data/spec/extensions/constant_sql_override_spec.rb +0 -24
- data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
- data/spec/extensions/constraint_validations_spec.rb +0 -439
- data/spec/extensions/core_refinements_spec.rb +0 -528
- data/spec/extensions/csv_serializer_spec.rb +0 -183
- data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
- data/spec/extensions/dataset_associations_spec.rb +0 -365
- data/spec/extensions/dataset_source_alias_spec.rb +0 -51
- data/spec/extensions/date_arithmetic_spec.rb +0 -181
- data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
- data/spec/extensions/def_dataset_method_spec.rb +0 -100
- data/spec/extensions/defaults_setter_spec.rb +0 -150
- data/spec/extensions/delay_add_association_spec.rb +0 -73
- data/spec/extensions/dirty_spec.rb +0 -189
- data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
- data/spec/extensions/eager_each_spec.rb +0 -62
- data/spec/extensions/eager_graph_eager_spec.rb +0 -100
- data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
- data/spec/extensions/error_splitter_spec.rb +0 -18
- data/spec/extensions/error_sql_spec.rb +0 -20
- data/spec/extensions/escaped_like_spec.rb +0 -40
- data/spec/extensions/eval_inspect_spec.rb +0 -81
- data/spec/extensions/finder_spec.rb +0 -260
- data/spec/extensions/force_encoding_spec.rb +0 -126
- data/spec/extensions/freeze_datasets_spec.rb +0 -31
- data/spec/extensions/graph_each_spec.rb +0 -113
- data/spec/extensions/hook_class_methods_spec.rb +0 -402
- data/spec/extensions/identifier_mangling_spec.rb +0 -201
- data/spec/extensions/implicit_subquery_spec.rb +0 -58
- data/spec/extensions/index_caching_spec.rb +0 -66
- data/spec/extensions/inflector_spec.rb +0 -183
- data/spec/extensions/input_transformer_spec.rb +0 -69
- data/spec/extensions/insert_returning_select_spec.rb +0 -72
- data/spec/extensions/instance_filters_spec.rb +0 -79
- data/spec/extensions/instance_hooks_spec.rb +0 -246
- data/spec/extensions/integer64_spec.rb +0 -22
- data/spec/extensions/inverted_subsets_spec.rb +0 -33
- data/spec/extensions/json_serializer_spec.rb +0 -336
- data/spec/extensions/lazy_attributes_spec.rb +0 -183
- data/spec/extensions/list_spec.rb +0 -291
- data/spec/extensions/looser_typecasting_spec.rb +0 -43
- data/spec/extensions/many_through_many_spec.rb +0 -2177
- data/spec/extensions/migration_spec.rb +0 -864
- data/spec/extensions/modification_detection_spec.rb +0 -93
- data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
- data/spec/extensions/named_timezones_spec.rb +0 -111
- data/spec/extensions/nested_attributes_spec.rb +0 -767
- data/spec/extensions/null_dataset_spec.rb +0 -85
- data/spec/extensions/optimistic_locking_spec.rb +0 -127
- data/spec/extensions/pagination_spec.rb +0 -116
- data/spec/extensions/pg_array_associations_spec.rb +0 -802
- data/spec/extensions/pg_array_ops_spec.rb +0 -144
- data/spec/extensions/pg_array_spec.rb +0 -398
- data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -172
- data/spec/extensions/pg_enum_spec.rb +0 -118
- data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
- data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
- data/spec/extensions/pg_hstore_spec.rb +0 -219
- data/spec/extensions/pg_inet_ops_spec.rb +0 -102
- data/spec/extensions/pg_inet_spec.rb +0 -72
- data/spec/extensions/pg_interval_spec.rb +0 -103
- data/spec/extensions/pg_json_ops_spec.rb +0 -289
- data/spec/extensions/pg_json_spec.rb +0 -262
- data/spec/extensions/pg_loose_count_spec.rb +0 -23
- data/spec/extensions/pg_range_ops_spec.rb +0 -60
- data/spec/extensions/pg_range_spec.rb +0 -519
- data/spec/extensions/pg_row_ops_spec.rb +0 -61
- data/spec/extensions/pg_row_plugin_spec.rb +0 -60
- data/spec/extensions/pg_row_spec.rb +0 -363
- data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
- data/spec/extensions/pg_timestamptz_spec.rb +0 -17
- data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
- data/spec/extensions/prepared_statements_spec.rb +0 -177
- data/spec/extensions/pretty_table_spec.rb +0 -123
- data/spec/extensions/query_spec.rb +0 -94
- data/spec/extensions/rcte_tree_spec.rb +0 -381
- data/spec/extensions/round_timestamps_spec.rb +0 -39
- data/spec/extensions/s_spec.rb +0 -60
- data/spec/extensions/schema_caching_spec.rb +0 -64
- data/spec/extensions/schema_dumper_spec.rb +0 -870
- data/spec/extensions/select_remove_spec.rb +0 -38
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
- data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
- data/spec/extensions/serialization_spec.rb +0 -365
- data/spec/extensions/server_block_spec.rb +0 -97
- data/spec/extensions/server_logging_spec.rb +0 -45
- data/spec/extensions/sharding_spec.rb +0 -189
- data/spec/extensions/shared_caching_spec.rb +0 -151
- data/spec/extensions/single_table_inheritance_spec.rb +0 -347
- data/spec/extensions/singular_table_names_spec.rb +0 -22
- data/spec/extensions/skip_create_refresh_spec.rb +0 -18
- data/spec/extensions/spec_helper.rb +0 -63
- data/spec/extensions/split_array_nil_spec.rb +0 -24
- data/spec/extensions/split_values_spec.rb +0 -57
- data/spec/extensions/sql_comments_spec.rb +0 -33
- data/spec/extensions/sql_expr_spec.rb +0 -59
- data/spec/extensions/static_cache_spec.rb +0 -471
- data/spec/extensions/string_agg_spec.rb +0 -90
- data/spec/extensions/string_date_time_spec.rb +0 -95
- data/spec/extensions/string_stripper_spec.rb +0 -68
- data/spec/extensions/subclasses_spec.rb +0 -79
- data/spec/extensions/subset_conditions_spec.rb +0 -38
- data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
- data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
- data/spec/extensions/synchronize_sql_spec.rb +0 -124
- data/spec/extensions/table_select_spec.rb +0 -83
- data/spec/extensions/tactical_eager_loading_spec.rb +0 -402
- data/spec/extensions/thread_local_timezones_spec.rb +0 -67
- data/spec/extensions/throw_failures_spec.rb +0 -74
- data/spec/extensions/timestamps_spec.rb +0 -209
- data/spec/extensions/to_dot_spec.rb +0 -153
- data/spec/extensions/touch_spec.rb +0 -226
- data/spec/extensions/tree_spec.rb +0 -334
- data/spec/extensions/typecast_on_load_spec.rb +0 -86
- data/spec/extensions/unlimited_update_spec.rb +0 -21
- data/spec/extensions/update_or_create_spec.rb +0 -83
- data/spec/extensions/update_primary_key_spec.rb +0 -105
- data/spec/extensions/update_refresh_spec.rb +0 -59
- data/spec/extensions/uuid_spec.rb +0 -101
- data/spec/extensions/validate_associated_spec.rb +0 -52
- data/spec/extensions/validation_class_methods_spec.rb +0 -1040
- data/spec/extensions/validation_contexts_spec.rb +0 -31
- data/spec/extensions/validation_helpers_spec.rb +0 -525
- data/spec/extensions/whitelist_security_spec.rb +0 -157
- data/spec/extensions/xml_serializer_spec.rb +0 -213
- data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
- data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
- data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
- data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
- data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
- data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
- data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
- data/spec/files/double_migration/001_create_sessions.rb +0 -9
- data/spec/files/double_migration/002_create_nodes.rb +0 -19
- data/spec/files/double_migration/003_3_create_users.rb +0 -4
- data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
- data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
- data/spec/files/empty_migration/001_create_sessions.rb +0 -9
- data/spec/files/empty_migration/002_create_nodes.rb +0 -0
- data/spec/files/empty_migration/003_3_create_users.rb +0 -4
- data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
- data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
- data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
- data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
- data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/reversible_migrations/001_reversible.rb +0 -5
- data/spec/files/reversible_migrations/002_reversible.rb +0 -5
- data/spec/files/reversible_migrations/003_reversible.rb +0 -5
- data/spec/files/reversible_migrations/004_reversible.rb +0 -5
- data/spec/files/reversible_migrations/005_reversible.rb +0 -10
- data/spec/files/reversible_migrations/006_reversible.rb +0 -10
- data/spec/files/reversible_migrations/007_reversible.rb +0 -10
- data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
- data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
- data/spec/guards_helper.rb +0 -59
- data/spec/integration/associations_test.rb +0 -2597
- data/spec/integration/database_test.rb +0 -113
- data/spec/integration/dataset_test.rb +0 -1981
- data/spec/integration/eager_loader_test.rb +0 -687
- data/spec/integration/migrator_test.rb +0 -262
- data/spec/integration/model_test.rb +0 -203
- data/spec/integration/plugin_test.rb +0 -2396
- data/spec/integration/prepared_statement_test.rb +0 -405
- data/spec/integration/schema_test.rb +0 -889
- data/spec/integration/spec_helper.rb +0 -65
- data/spec/integration/timezone_test.rb +0 -86
- data/spec/integration/transaction_test.rb +0 -603
- data/spec/integration/type_test.rb +0 -127
- data/spec/model/association_reflection_spec.rb +0 -803
- data/spec/model/associations_spec.rb +0 -4738
- data/spec/model/base_spec.rb +0 -875
- data/spec/model/class_dataset_methods_spec.rb +0 -146
- data/spec/model/dataset_methods_spec.rb +0 -198
- data/spec/model/eager_loading_spec.rb +0 -2377
- data/spec/model/hooks_spec.rb +0 -370
- data/spec/model/inflector_spec.rb +0 -26
- data/spec/model/model_spec.rb +0 -956
- data/spec/model/plugins_spec.rb +0 -429
- data/spec/model/record_spec.rb +0 -2118
- data/spec/model/spec_helper.rb +0 -46
- data/spec/model/validations_spec.rb +0 -220
- data/spec/model_no_assoc_spec.rb +0 -1
- data/spec/model_spec.rb +0 -1
- data/spec/plugin_spec.rb +0 -1
- data/spec/sequel_coverage.rb +0 -15
- data/spec/sequel_warning.rb +0 -4
- data/spec/spec_config.rb +0 -12
|
@@ -1,1250 +0,0 @@
|
|
|
1
|
-
require_relative "spec_helper"
|
|
2
|
-
require_relative '../../lib/sequel/connection_pool/sharded_threaded'
|
|
3
|
-
|
|
4
|
-
connection_pool_defaults = {:pool_timeout=>5, :max_connections=>4}
|
|
5
|
-
st_connection_pool_defaults = connection_pool_defaults.merge(:single_threaded=>true)
|
|
6
|
-
|
|
7
|
-
mock_db = lambda do |*a, &b|
|
|
8
|
-
db = Sequel.mock
|
|
9
|
-
db.define_singleton_method(:connect){|c| b.arity == 1 ? b.call(c) : b.call} if b
|
|
10
|
-
if b2 = a.shift
|
|
11
|
-
db.define_singleton_method(:disconnect_connection){|c| b2.arity == 1 ? b2.call(c) : b2.call}
|
|
12
|
-
end
|
|
13
|
-
# Work around JRuby Issue #3854
|
|
14
|
-
db.singleton_class.send(:public, :connect, :disconnect_connection)
|
|
15
|
-
db
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
describe "An empty ConnectionPool" do
|
|
19
|
-
before do
|
|
20
|
-
@cpool = Sequel::ConnectionPool.get_pool(mock_db.call, connection_pool_defaults)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "should have no available connections" do
|
|
24
|
-
@cpool.available_connections.must_equal []
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "should have no allocated connections" do
|
|
28
|
-
@cpool.allocated.must_equal({})
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it "should have a size of zero" do
|
|
32
|
-
@cpool.size.must_equal 0
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it "should raise Error for bad pool class" do
|
|
36
|
-
proc{Sequel::ConnectionPool.get_pool(mock_db.call, :pool_class=>:foo)}.must_raise Sequel::Error
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
describe "ConnectionPool options" do
|
|
41
|
-
it "should support string option values" do
|
|
42
|
-
cpool = Sequel::ConnectionPool.get_pool(mock_db.call, {:max_connections=>'5', :pool_timeout=>'3'})
|
|
43
|
-
cpool.max_size.must_equal 5
|
|
44
|
-
cpool.instance_variable_get(:@timeout).must_equal 3
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
it "should raise an error unless size is positive" do
|
|
48
|
-
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>0)}.must_raise(Sequel::Error)
|
|
49
|
-
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>-10)}.must_raise(Sequel::Error)
|
|
50
|
-
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>'-10')}.must_raise(Sequel::Error)
|
|
51
|
-
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>'0')}.must_raise(Sequel::Error)
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
describe "A connection pool handling connections" do
|
|
56
|
-
before do
|
|
57
|
-
@max_size = 2
|
|
58
|
-
msp = proc{@max_size=3}
|
|
59
|
-
@cpool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| msp.call}){:got_connection}, connection_pool_defaults.merge(:max_connections=>@max_size))
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it "#hold should increment #size" do
|
|
63
|
-
@cpool.hold do
|
|
64
|
-
@cpool.size.must_equal 1
|
|
65
|
-
@cpool.hold {@cpool.hold {@cpool.size.must_equal 1}}
|
|
66
|
-
Thread.new{@cpool.hold {_(@cpool.size).must_equal 2}}.join
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
it "#hold should add the connection to the #allocated array" do
|
|
71
|
-
@cpool.hold do
|
|
72
|
-
@cpool.allocated.size.must_equal 1
|
|
73
|
-
|
|
74
|
-
@cpool.allocated.must_equal(Thread.current=>:got_connection)
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
it "#hold should yield a new connection" do
|
|
79
|
-
@cpool.hold {|conn| conn.must_equal :got_connection}
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
it "a connection should be de-allocated after it has been used in #hold" do
|
|
83
|
-
@cpool.hold {}
|
|
84
|
-
@cpool.allocated.size.must_equal 0
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
it "#hold should return the value of its block" do
|
|
88
|
-
@cpool.hold {:block_return}.must_equal :block_return
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
it "#make_new should not make more than max_size connections" do
|
|
92
|
-
q = Queue.new
|
|
93
|
-
50.times{Thread.new{@cpool.hold{q.pop}}}
|
|
94
|
-
50.times{q.push nil}
|
|
95
|
-
@cpool.size.must_be :<=, @max_size
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
it "database's disconnect connection method should be called when a disconnect is detected" do
|
|
99
|
-
@max_size.must_equal 2
|
|
100
|
-
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
|
101
|
-
@max_size.must_equal 3
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
it "#hold should remove the connection if a DatabaseDisconnectError is raised" do
|
|
105
|
-
@cpool.size.must_equal 0
|
|
106
|
-
q, q1 = Queue.new, Queue.new
|
|
107
|
-
@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}
|
|
108
|
-
@cpool.size.must_equal 2
|
|
109
|
-
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
|
110
|
-
@cpool.size.must_equal 1
|
|
111
|
-
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
|
112
|
-
@cpool.size.must_equal 0
|
|
113
|
-
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
|
114
|
-
@cpool.size.must_equal 0
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
describe "A connection pool handling connection errors" do
|
|
119
|
-
it "#hold should raise a Sequel::DatabaseConnectionError if an exception is raised by the connection_proc" do
|
|
120
|
-
cpool = Sequel::ConnectionPool.get_pool(mock_db.call{raise Interrupt}, connection_pool_defaults)
|
|
121
|
-
proc{cpool.hold{:block_return}}.must_raise(Sequel::DatabaseConnectionError)
|
|
122
|
-
cpool.size.must_equal 0
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
it "#hold should raise a Sequel::DatabaseConnectionError if nil is returned by the connection_proc" do
|
|
126
|
-
cpool = Sequel::ConnectionPool.get_pool(mock_db.call{nil}, connection_pool_defaults)
|
|
127
|
-
proc{cpool.hold{:block_return}}.must_raise(Sequel::DatabaseConnectionError)
|
|
128
|
-
cpool.size.must_equal 0
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
describe "ConnectionPool#hold" do
|
|
133
|
-
before do
|
|
134
|
-
value = 0
|
|
135
|
-
c = @c = Class.new do
|
|
136
|
-
define_method(:initialize){value += 1}
|
|
137
|
-
define_method(:value){value}
|
|
138
|
-
end
|
|
139
|
-
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{c.new}, connection_pool_defaults)
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
it "shoulda use the database's connect method to get new connections" do
|
|
143
|
-
res = nil
|
|
144
|
-
@pool.hold {|c| res = c}
|
|
145
|
-
res.must_be_kind_of(@c)
|
|
146
|
-
res.value.must_equal 1
|
|
147
|
-
@pool.hold {|c| res = c}
|
|
148
|
-
res.must_be_kind_of(@c)
|
|
149
|
-
res.value.must_equal 1 # the connection maker is invoked only once
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
it "should be re-entrant by the same thread" do
|
|
153
|
-
cc = nil
|
|
154
|
-
@pool.hold {|c| @pool.hold {|c1| @pool.hold {|c2| cc = c2}}}
|
|
155
|
-
cc.must_be_kind_of(@c)
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
it "should catch exceptions and reraise them" do
|
|
159
|
-
proc {@pool.hold {|c| c.foobar}}.must_raise(NoMethodError)
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
describe "A connection pool with a max size of 1" do
|
|
164
|
-
before do
|
|
165
|
-
@invoked_count = 0
|
|
166
|
-
icp = proc{@invoked_count += 1}
|
|
167
|
-
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{icp.call; 'herro'.dup}, connection_pool_defaults.merge(:max_connections=>1))
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
it "should let only one thread access the connection at any time" do
|
|
171
|
-
cc,c1, c2 = nil
|
|
172
|
-
q, q1 = Queue.new, Queue.new
|
|
173
|
-
|
|
174
|
-
t1 = Thread.new {@pool.hold {|c| cc = c; c1 = c.dup; q1.push nil; q.pop}}
|
|
175
|
-
q1.pop
|
|
176
|
-
cc.must_equal 'herro'
|
|
177
|
-
c1.must_equal 'herro'
|
|
178
|
-
|
|
179
|
-
t2 = Thread.new {@pool.hold {|c| c2 = c.dup; q1.push nil; q.pop;}}
|
|
180
|
-
|
|
181
|
-
# connection held by t1
|
|
182
|
-
t1.must_be :alive?
|
|
183
|
-
t2.must_be :alive?
|
|
184
|
-
|
|
185
|
-
cc.must_equal 'herro'
|
|
186
|
-
c1.must_equal 'herro'
|
|
187
|
-
c2.must_be_nil
|
|
188
|
-
|
|
189
|
-
@pool.available_connections.must_be :empty?
|
|
190
|
-
@pool.allocated.must_equal(t1=>cc)
|
|
191
|
-
|
|
192
|
-
cc.gsub!('rr', 'll')
|
|
193
|
-
q.push nil
|
|
194
|
-
q1.pop
|
|
195
|
-
|
|
196
|
-
t1.join
|
|
197
|
-
t2.must_be :alive?
|
|
198
|
-
|
|
199
|
-
c2.must_equal 'hello'
|
|
200
|
-
|
|
201
|
-
@pool.available_connections.must_be :empty?
|
|
202
|
-
@pool.allocated.must_equal(t2=>cc)
|
|
203
|
-
|
|
204
|
-
#connection released
|
|
205
|
-
q.push nil
|
|
206
|
-
t2.join
|
|
207
|
-
|
|
208
|
-
@invoked_count.must_equal 1
|
|
209
|
-
@pool.size.must_equal 1
|
|
210
|
-
@pool.available_connections.must_equal [cc]
|
|
211
|
-
@pool.allocated.must_be :empty?
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
it "should let the same thread reenter #hold" do
|
|
215
|
-
c1, c2, c3 = nil
|
|
216
|
-
@pool.hold do |c|
|
|
217
|
-
c1 = c
|
|
218
|
-
@pool.hold do |cc2|
|
|
219
|
-
c2 = cc2
|
|
220
|
-
@pool.hold do |cc3|
|
|
221
|
-
c3 = cc3
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
c1.must_equal 'herro'
|
|
226
|
-
c2.must_equal 'herro'
|
|
227
|
-
c3.must_equal 'herro'
|
|
228
|
-
|
|
229
|
-
@invoked_count.must_equal 1
|
|
230
|
-
@pool.size.must_equal 1
|
|
231
|
-
@pool.available_connections.size.must_equal 1
|
|
232
|
-
@pool.allocated.must_be :empty?
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
ThreadedConnectionPoolSpecs = shared_description do
|
|
237
|
-
it "should not have all_connections yield connections allocated to other threads" do
|
|
238
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>2, :pool_timeout=>0))
|
|
239
|
-
q, q1 = Queue.new, Queue.new
|
|
240
|
-
t = Thread.new do
|
|
241
|
-
pool.hold do |c1|
|
|
242
|
-
q1.push nil
|
|
243
|
-
q.pop
|
|
244
|
-
end
|
|
245
|
-
end
|
|
246
|
-
pool.hold do |c1|
|
|
247
|
-
q1.pop
|
|
248
|
-
pool.all_connections{|c| c.must_equal c1}
|
|
249
|
-
q.push nil
|
|
250
|
-
end
|
|
251
|
-
t.join
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
it "should work when acquire fails and then succeeds" do
|
|
255
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>2, :pool_timeout=>0))
|
|
256
|
-
def pool._acquire(*)
|
|
257
|
-
if @called
|
|
258
|
-
super
|
|
259
|
-
else
|
|
260
|
-
@called = true
|
|
261
|
-
nil
|
|
262
|
-
end
|
|
263
|
-
end
|
|
264
|
-
c = nil
|
|
265
|
-
pool.hold do |c1|
|
|
266
|
-
c = c1
|
|
267
|
-
end
|
|
268
|
-
c.wont_be_nil
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
it "should wait until a connection is available if all are checked out" do
|
|
272
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>1, :pool_timeout=>0.1))
|
|
273
|
-
q, q1 = Queue.new, Queue.new
|
|
274
|
-
t = Thread.new do
|
|
275
|
-
pool.hold do |c|
|
|
276
|
-
q1.push nil
|
|
277
|
-
3.times{Thread.pass}
|
|
278
|
-
q.pop
|
|
279
|
-
end
|
|
280
|
-
end
|
|
281
|
-
q1.pop
|
|
282
|
-
proc{pool.hold{}}.must_raise(Sequel::PoolTimeout)
|
|
283
|
-
q.push nil
|
|
284
|
-
t.join
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
it "should not have all_connections yield all available connections" do
|
|
288
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>2, :pool_timeout=>0))
|
|
289
|
-
q, q1 = Queue.new, Queue.new
|
|
290
|
-
b = []
|
|
291
|
-
t = Thread.new do
|
|
292
|
-
pool.hold do |c1|
|
|
293
|
-
@m.synchronize{b << c1}
|
|
294
|
-
q1.push nil
|
|
295
|
-
q.pop
|
|
296
|
-
end
|
|
297
|
-
end
|
|
298
|
-
pool.hold do |c1|
|
|
299
|
-
q1.pop
|
|
300
|
-
@m.synchronize{b << c1}
|
|
301
|
-
q.push nil
|
|
302
|
-
end
|
|
303
|
-
t.join
|
|
304
|
-
a = []
|
|
305
|
-
pool.all_connections{|c| a << c}
|
|
306
|
-
a.sort.must_equal b.sort
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
it "should raise a PoolTimeout error if a connection couldn't be acquired before timeout" do
|
|
310
|
-
q, q1 = Queue.new, Queue.new
|
|
311
|
-
db = mock_db.call(&@icpp)
|
|
312
|
-
db.opts[:name] = 'testing'
|
|
313
|
-
pool = Sequel::ConnectionPool.get_pool(db, @cp_opts.merge(:max_connections=>1, :pool_timeout=>0))
|
|
314
|
-
t = Thread.new{pool.hold{|c| q1.push nil; q.pop}}
|
|
315
|
-
q1.pop
|
|
316
|
-
e = proc{pool.hold{|c|}}.must_raise(Sequel::PoolTimeout)
|
|
317
|
-
e.message.must_include "name: testing"
|
|
318
|
-
e.message.must_include "server: default" if pool.is_a?(Sequel::ShardedThreadedConnectionPool)
|
|
319
|
-
q.push nil
|
|
320
|
-
t.join
|
|
321
|
-
end
|
|
322
|
-
|
|
323
|
-
it "should not add a disconnected connection back to the pool if the disconnection_proc raises an error" do
|
|
324
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| raise Sequel::Error}, &@icpp), @cp_opts.merge(:max_connections=>1, :pool_timeout=>0))
|
|
325
|
-
proc{pool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::Error)
|
|
326
|
-
pool.available_connections.length.must_equal 0
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
it "should let five threads simultaneously access separate connections" do
|
|
330
|
-
cc = {}
|
|
331
|
-
threads = []
|
|
332
|
-
q, q1, q2 = Queue.new, Queue.new, Queue.new
|
|
333
|
-
|
|
334
|
-
5.times{|i| threads << Thread.new{@pool.hold{|c| q.pop; @m.synchronize{cc[i] = c}; q1.push nil; q2.pop}}; q.push nil; q1.pop}
|
|
335
|
-
threads.each {|t| t.must_be :alive?}
|
|
336
|
-
cc.size.must_equal 5
|
|
337
|
-
@invoked_count.must_equal 5
|
|
338
|
-
@pool.size.must_equal 5
|
|
339
|
-
@pool.available_connections.must_be :empty?
|
|
340
|
-
|
|
341
|
-
h = {}
|
|
342
|
-
i = 0
|
|
343
|
-
threads.each{|t| h[t] = (i+=1)}
|
|
344
|
-
@pool.allocated.must_equal h
|
|
345
|
-
@pool.available_connections.must_equal []
|
|
346
|
-
5.times{q2.push nil}
|
|
347
|
-
threads.each{|t| t.join}
|
|
348
|
-
|
|
349
|
-
@pool.available_connections.size.must_equal 5
|
|
350
|
-
@pool.allocated.must_be :empty?
|
|
351
|
-
end
|
|
352
|
-
|
|
353
|
-
it "should allow simultaneous connections without preconnecting" do
|
|
354
|
-
@pool.disconnect
|
|
355
|
-
b = @icpp
|
|
356
|
-
|
|
357
|
-
time = Time.now
|
|
358
|
-
cc = {}
|
|
359
|
-
threads = []
|
|
360
|
-
results = []
|
|
361
|
-
j = 0
|
|
362
|
-
q, q1, q2, q3, q4 = Queue.new, Queue.new, Queue.new, Queue.new, Queue.new
|
|
363
|
-
m = @m
|
|
364
|
-
@pool.db.define_singleton_method(:connect) do |server|
|
|
365
|
-
q1.pop
|
|
366
|
-
m.synchronize{q3.push(j += 1)}
|
|
367
|
-
q4.pop
|
|
368
|
-
b.call
|
|
369
|
-
end
|
|
370
|
-
5.times{|i| threads << Thread.new{@pool.hold{|c| m.synchronize{i -= 1; cc[i] = c}; q2.pop; q.push nil}}}
|
|
371
|
-
5.times{|i| q1.push nil}
|
|
372
|
-
5.times{|i| results << q3.pop}
|
|
373
|
-
5.times{|i| q4.push nil}
|
|
374
|
-
5.times{|i| q2.push nil}
|
|
375
|
-
5.times{|i| q.pop}
|
|
376
|
-
results.sort.must_equal (1..5).to_a
|
|
377
|
-
threads.each(&:join)
|
|
378
|
-
(Time.now - time).must_be :<, 0.75
|
|
379
|
-
|
|
380
|
-
threads.each{|t| t.wont_be :alive?}
|
|
381
|
-
cc.size.must_equal 5
|
|
382
|
-
@invoked_count.must_equal 5
|
|
383
|
-
@pool.size.must_equal 5
|
|
384
|
-
@pool.available_connections.sort.must_equal (1..5).to_a
|
|
385
|
-
end
|
|
386
|
-
|
|
387
|
-
it "should block threads until a connection becomes available" do
|
|
388
|
-
cc = {}
|
|
389
|
-
threads = []
|
|
390
|
-
q, q1 = Queue.new, Queue.new
|
|
391
|
-
|
|
392
|
-
5.times{|i| threads << Thread.new{@pool.hold{|c| @m.synchronize{cc[i] = c}; q1.push nil; q.pop}}}
|
|
393
|
-
5.times{q1.pop}
|
|
394
|
-
threads.each {|t| t.must_be :alive?}
|
|
395
|
-
@pool.available_connections.must_be :empty?
|
|
396
|
-
|
|
397
|
-
3.times {|i| threads << Thread.new {@pool.hold {|c| @m.synchronize{cc[i + 5] = c}; q1.push nil}}}
|
|
398
|
-
|
|
399
|
-
threads[5].must_be :alive?
|
|
400
|
-
threads[6].must_be :alive?
|
|
401
|
-
threads[7].must_be :alive?
|
|
402
|
-
cc.size.must_equal 5
|
|
403
|
-
cc[5].must_be_nil
|
|
404
|
-
cc[6].must_be_nil
|
|
405
|
-
cc[7].must_be_nil
|
|
406
|
-
|
|
407
|
-
5.times{q.push nil}
|
|
408
|
-
5.times{|i| threads[i].join}
|
|
409
|
-
3.times{q1.pop}
|
|
410
|
-
3.times{|i| threads[i+5].join}
|
|
411
|
-
|
|
412
|
-
threads.each {|t| t.wont_be :alive?}
|
|
413
|
-
cc.values.uniq.length.must_equal 5
|
|
414
|
-
|
|
415
|
-
@pool.size.must_equal 5
|
|
416
|
-
@invoked_count.must_equal 5
|
|
417
|
-
@pool.available_connections.size.must_equal 5
|
|
418
|
-
@pool.allocated.must_be :empty?
|
|
419
|
-
end
|
|
420
|
-
|
|
421
|
-
it "should block threads until a connection becomes available, when assign connection returns nil" do
|
|
422
|
-
# Shorten pool timeout, as making assign_connection return nil when there are
|
|
423
|
-
# connections in the pool can make the pool later block until the timeout expires,
|
|
424
|
-
# since then the pool will not be signalled correctly.
|
|
425
|
-
# This spec is only added for coverage purposes, to ensure that fallback code is tested.
|
|
426
|
-
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:pool_timeout=>0.25))
|
|
427
|
-
|
|
428
|
-
cc = {}
|
|
429
|
-
threads = []
|
|
430
|
-
q, q1 = Queue.new, Queue.new
|
|
431
|
-
|
|
432
|
-
5.times{|i| threads << Thread.new{@pool.hold{|c| @m.synchronize{cc[i] = c}; q1.push nil; q.pop}}}
|
|
433
|
-
5.times{q1.pop}
|
|
434
|
-
threads.each {|t| t.must_be :alive?}
|
|
435
|
-
@pool.available_connections.must_be :empty?
|
|
436
|
-
|
|
437
|
-
def @pool.assign_connection(*) nil end
|
|
438
|
-
3.times {|i| threads << Thread.new {@pool.hold {|c| @m.synchronize{cc[i + 5] = c}; q1.push nil}}}
|
|
439
|
-
|
|
440
|
-
threads[5].must_be :alive?
|
|
441
|
-
threads[6].must_be :alive?
|
|
442
|
-
threads[7].must_be :alive?
|
|
443
|
-
cc.size.must_equal 5
|
|
444
|
-
cc[5].must_be_nil
|
|
445
|
-
cc[6].must_be_nil
|
|
446
|
-
cc[7].must_be_nil
|
|
447
|
-
|
|
448
|
-
5.times{q.push nil}
|
|
449
|
-
5.times{|i| threads[i].join}
|
|
450
|
-
3.times{q1.pop}
|
|
451
|
-
3.times{|i| threads[i+5].join}
|
|
452
|
-
|
|
453
|
-
threads.each {|t| t.wont_be :alive?}
|
|
454
|
-
cc.values.uniq.length.must_equal 5
|
|
455
|
-
|
|
456
|
-
@pool.size.must_equal 5
|
|
457
|
-
@invoked_count.must_equal 5
|
|
458
|
-
@pool.available_connections.size.must_equal 5
|
|
459
|
-
@pool.allocated.must_be :empty?
|
|
460
|
-
end
|
|
461
|
-
|
|
462
|
-
it "should block threads until a connection becomes available, and reconnect on disconnection" do
|
|
463
|
-
cc = {}
|
|
464
|
-
threads = []
|
|
465
|
-
exceptions = []
|
|
466
|
-
q, q1, q2, q3 = Queue.new, Queue.new, Queue.new, Queue.new
|
|
467
|
-
b = @icpp
|
|
468
|
-
@pool.db.define_singleton_method(:connect) do |server|
|
|
469
|
-
b.call
|
|
470
|
-
Object.new
|
|
471
|
-
end
|
|
472
|
-
5.times{|i| threads << Thread.new{@pool.hold{|c| @m.synchronize{cc[i] = c}; q1.push nil; q.pop; raise Sequel::DatabaseDisconnectError} rescue q2.push($!)}}
|
|
473
|
-
5.times{q1.pop}
|
|
474
|
-
threads.each {|t| t.must_be :alive?}
|
|
475
|
-
@pool.available_connections.must_be :empty?
|
|
476
|
-
|
|
477
|
-
3.times {|i| threads << Thread.new {@pool.hold {|c| @m.synchronize{cc[i + 5] = c}; q1.push nil; q3.pop}}}
|
|
478
|
-
|
|
479
|
-
threads[5].must_be :alive?
|
|
480
|
-
threads[6].must_be :alive?
|
|
481
|
-
threads[7].must_be :alive?
|
|
482
|
-
cc.size.must_equal 5
|
|
483
|
-
cc[5].must_be_nil
|
|
484
|
-
cc[6].must_be_nil
|
|
485
|
-
cc[7].must_be_nil
|
|
486
|
-
|
|
487
|
-
5.times{q.push nil}
|
|
488
|
-
5.times{|i| threads[i].join}
|
|
489
|
-
5.times{exceptions << q2.pop}
|
|
490
|
-
3.times{q1.pop}
|
|
491
|
-
3.times{q3.push nil}
|
|
492
|
-
3.times{|i| threads[i+5].join}
|
|
493
|
-
|
|
494
|
-
threads.each {|t| t.wont_be :alive?}
|
|
495
|
-
exceptions.length.must_equal 5
|
|
496
|
-
cc.values.uniq.length.must_equal 8
|
|
497
|
-
|
|
498
|
-
@pool.size.must_equal 3
|
|
499
|
-
@invoked_count.must_equal 8
|
|
500
|
-
@pool.available_connections.size.must_equal 3
|
|
501
|
-
@pool.allocated.must_be :empty?
|
|
502
|
-
end
|
|
503
|
-
|
|
504
|
-
it "should store connections in a stack if :connection_handling=>:stack" do
|
|
505
|
-
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:connection_handling=>:stack))
|
|
506
|
-
c2 = nil
|
|
507
|
-
c = @pool.hold{|cc| Thread.new{@pool.hold{|cc2| c2 = cc2}}.join; cc}
|
|
508
|
-
@pool.size.must_equal 2
|
|
509
|
-
@pool.hold{|cc| cc.must_equal c}
|
|
510
|
-
@pool.hold{|cc| cc.must_equal c}
|
|
511
|
-
@pool.hold do |cc|
|
|
512
|
-
cc.must_equal c
|
|
513
|
-
Thread.new{@pool.hold{|cc2| _(cc2).must_equal c2}}.join
|
|
514
|
-
end
|
|
515
|
-
end
|
|
516
|
-
|
|
517
|
-
it "should store connections in a queue if :connection_handling=>:queue" do
|
|
518
|
-
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:connection_handling=>:queue))
|
|
519
|
-
c2 = nil
|
|
520
|
-
c = @pool.hold{|cc| Thread.new{@pool.hold{|cc2| c2 = cc2}}.join; cc}
|
|
521
|
-
@pool.size.must_equal 2
|
|
522
|
-
@pool.hold{|cc| cc.must_equal c2}
|
|
523
|
-
@pool.hold{|cc| cc.must_equal c}
|
|
524
|
-
@pool.hold do |cc|
|
|
525
|
-
cc.must_equal c2
|
|
526
|
-
Thread.new{@pool.hold{|cc2| _(cc2).must_equal c}}.join
|
|
527
|
-
end
|
|
528
|
-
end
|
|
529
|
-
|
|
530
|
-
it "should not store connections if :connection_handling=>:disconnect" do
|
|
531
|
-
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:connection_handling=>:disconnect))
|
|
532
|
-
d = []
|
|
533
|
-
m = @m
|
|
534
|
-
@pool.db.define_singleton_method(:disconnect_connection){|c| m.synchronize{d << c}}
|
|
535
|
-
@pool.hold do |cc|
|
|
536
|
-
cc.must_equal 1
|
|
537
|
-
Thread.new{@pool.hold{|cc2| _(cc2).must_equal 2}}.join
|
|
538
|
-
d.must_equal [2]
|
|
539
|
-
@pool.hold{|cc3| cc3.must_equal 1}
|
|
540
|
-
end
|
|
541
|
-
@pool.size.must_equal 0
|
|
542
|
-
d.must_equal [2, 1]
|
|
543
|
-
|
|
544
|
-
@pool.hold{|cc| cc.must_equal 3}
|
|
545
|
-
@pool.size.must_equal 0
|
|
546
|
-
d.must_equal [2, 1, 3]
|
|
547
|
-
|
|
548
|
-
@pool.hold{|cc| cc.must_equal 4}
|
|
549
|
-
@pool.size.must_equal 0
|
|
550
|
-
d.must_equal [2, 1, 3, 4]
|
|
551
|
-
end
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
it "should handle dead threads with checked out connections" do
|
|
555
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>1))
|
|
556
|
-
|
|
557
|
-
skip = true
|
|
558
|
-
# Leave allocated connection to emulate dead thread with checked out connection
|
|
559
|
-
pool.define_singleton_method(:release){|*a| return if skip; super(*a)}
|
|
560
|
-
Thread.new{pool.hold{Thread.current.kill}}.join
|
|
561
|
-
skip = false
|
|
562
|
-
|
|
563
|
-
pool.allocated.wont_be :empty?
|
|
564
|
-
pool.available_connections.must_be :empty?
|
|
565
|
-
|
|
566
|
-
pool.hold{|c1| c1}
|
|
567
|
-
pool.allocated.must_be :empty?
|
|
568
|
-
pool.available_connections.wont_be :empty?
|
|
569
|
-
|
|
570
|
-
pool.disconnect
|
|
571
|
-
pool.allocated.must_be :empty?
|
|
572
|
-
pool.available_connections.must_be :empty?
|
|
573
|
-
end
|
|
574
|
-
end
|
|
575
|
-
|
|
576
|
-
describe "Threaded Unsharded Connection Pool" do
|
|
577
|
-
before do
|
|
578
|
-
@m = Mutex.new
|
|
579
|
-
@invoked_count = 0
|
|
580
|
-
@icpp = proc{@m.synchronize{@invoked_count += 1}}
|
|
581
|
-
@cp_opts = connection_pool_defaults.merge(:max_connections=>5)
|
|
582
|
-
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts)
|
|
583
|
-
end
|
|
584
|
-
|
|
585
|
-
include ThreadedConnectionPoolSpecs
|
|
586
|
-
end
|
|
587
|
-
|
|
588
|
-
describe "Threaded Sharded Connection Pool" do
|
|
589
|
-
before do
|
|
590
|
-
@m = Mutex.new
|
|
591
|
-
@invoked_count = 0
|
|
592
|
-
@icpp = proc{@m.synchronize{@invoked_count += 1}}
|
|
593
|
-
@cp_opts = connection_pool_defaults.merge(:max_connections=>5, :servers=>{})
|
|
594
|
-
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts)
|
|
595
|
-
end
|
|
596
|
-
|
|
597
|
-
include ThreadedConnectionPoolSpecs
|
|
598
|
-
end
|
|
599
|
-
|
|
600
|
-
describe "ConnectionPool#disconnect" do
|
|
601
|
-
before do
|
|
602
|
-
@count = 0
|
|
603
|
-
cp = proc{@count += 1}
|
|
604
|
-
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{{:id => cp.call}}, connection_pool_defaults.merge(:max_connections=>5, :servers=>{}))
|
|
605
|
-
threads = []
|
|
606
|
-
q, q1 = Queue.new, Queue.new
|
|
607
|
-
5.times {|i| threads << Thread.new {@pool.hold {|c| q1.push nil; q.pop}}}
|
|
608
|
-
5.times{q1.pop}
|
|
609
|
-
5.times{q.push nil}
|
|
610
|
-
threads.each {|t| t.join}
|
|
611
|
-
end
|
|
612
|
-
|
|
613
|
-
it "should invoke the given block for each available connection" do
|
|
614
|
-
@pool.size.must_equal 5
|
|
615
|
-
@pool.available_connections.size.must_equal 5
|
|
616
|
-
@pool.available_connections.each {|c| c[:id].wont_equal nil}
|
|
617
|
-
conns = []
|
|
618
|
-
@pool.db.define_singleton_method(:disconnect_connection){|c| conns << c}
|
|
619
|
-
@pool.disconnect
|
|
620
|
-
conns.size.must_equal 5
|
|
621
|
-
end
|
|
622
|
-
|
|
623
|
-
it "should remove all available connections" do
|
|
624
|
-
@pool.size.must_equal 5
|
|
625
|
-
@pool.disconnect
|
|
626
|
-
@pool.size.must_equal 0
|
|
627
|
-
end
|
|
628
|
-
|
|
629
|
-
it "should disconnect connections in use as soon as they are no longer in use" do
|
|
630
|
-
@pool.size.must_equal 5
|
|
631
|
-
@pool.hold do |conn|
|
|
632
|
-
@pool.available_connections.size.must_equal 4
|
|
633
|
-
@pool.available_connections.each {|c| c.wont_be_same_as(conn)}
|
|
634
|
-
conns = []
|
|
635
|
-
@pool.db.define_singleton_method(:disconnect_connection){|c| conns << c}
|
|
636
|
-
@pool.disconnect
|
|
637
|
-
conns.size.must_equal 4
|
|
638
|
-
@pool.size.must_equal 1
|
|
639
|
-
end
|
|
640
|
-
@pool.size.must_equal 0
|
|
641
|
-
end
|
|
642
|
-
end
|
|
643
|
-
|
|
644
|
-
describe "A connection pool with multiple servers" do
|
|
645
|
-
before do
|
|
646
|
-
ic = @invoked_counts = Hash.new(0)
|
|
647
|
-
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{|server| "#{server}#{ic[server] += 1}"}, connection_pool_defaults.merge(:servers=>{:read_only=>{}}))
|
|
648
|
-
end
|
|
649
|
-
|
|
650
|
-
it "should support preconnect method that immediately creates the maximum number of connections" do
|
|
651
|
-
@pool.send(:preconnect)
|
|
652
|
-
i = 0
|
|
653
|
-
@pool.all_connections{|c1| i+=1}
|
|
654
|
-
i.must_equal(@pool.max_size * 2)
|
|
655
|
-
end
|
|
656
|
-
|
|
657
|
-
it "should support preconnect method that immediately creates the maximum number of connections concurrently" do
|
|
658
|
-
@pool.send(:preconnect, true)
|
|
659
|
-
i = 0
|
|
660
|
-
@pool.all_connections{|c1| i+=1}
|
|
661
|
-
i.must_equal(@pool.max_size * 2)
|
|
662
|
-
end
|
|
663
|
-
|
|
664
|
-
it "#all_connections should return connections for all servers" do
|
|
665
|
-
@pool.hold{}
|
|
666
|
-
@pool.all_connections{|c1| c1.must_equal "default1"}
|
|
667
|
-
a = []
|
|
668
|
-
@pool.hold(:read_only) do |c|
|
|
669
|
-
@pool.all_connections{|c1| a << c1}
|
|
670
|
-
end
|
|
671
|
-
a.sort_by{|c| c.to_s}.must_equal ["default1", "read_only1"]
|
|
672
|
-
end
|
|
673
|
-
|
|
674
|
-
it "#servers should return symbols for all servers" do
|
|
675
|
-
@pool.servers.sort_by{|s| s.to_s}.must_equal [:default, :read_only]
|
|
676
|
-
end
|
|
677
|
-
|
|
678
|
-
it "should use the :default server by default" do
|
|
679
|
-
@pool.size.must_equal 0
|
|
680
|
-
@pool.hold do |c|
|
|
681
|
-
c.must_equal "default1"
|
|
682
|
-
@pool.allocated.must_equal(Thread.current=>"default1")
|
|
683
|
-
end
|
|
684
|
-
@pool.available_connections.must_equal ["default1"]
|
|
685
|
-
@pool.size.must_equal 1
|
|
686
|
-
@invoked_counts.must_equal(:default=>1)
|
|
687
|
-
end
|
|
688
|
-
|
|
689
|
-
it "should use the :default server an invalid server is used" do
|
|
690
|
-
@pool.hold do |c1|
|
|
691
|
-
c1.must_equal "default1"
|
|
692
|
-
@pool.hold(:blah) do |c2|
|
|
693
|
-
c2.must_equal c1
|
|
694
|
-
@pool.hold(:blah2) do |c3|
|
|
695
|
-
c2.must_equal c3
|
|
696
|
-
end
|
|
697
|
-
end
|
|
698
|
-
end
|
|
699
|
-
end
|
|
700
|
-
|
|
701
|
-
it "should support a :servers_hash option used for converting the server argument" do
|
|
702
|
-
ic = @invoked_counts
|
|
703
|
-
@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=>{}}))
|
|
704
|
-
@pool.hold(:blah) do |c1|
|
|
705
|
-
c1.must_equal "read_only1"
|
|
706
|
-
@pool.hold(:blah) do |c2|
|
|
707
|
-
c2.must_equal c1
|
|
708
|
-
@pool.hold(:blah2) do |c3|
|
|
709
|
-
c2.must_equal c3
|
|
710
|
-
end
|
|
711
|
-
end
|
|
712
|
-
end
|
|
713
|
-
|
|
714
|
-
@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=>{}}))
|
|
715
|
-
proc{@pool.hold(:blah){|c1|}}.must_raise(Sequel::Error)
|
|
716
|
-
end
|
|
717
|
-
|
|
718
|
-
it "should use the requested server if server is given" do
|
|
719
|
-
@pool.size(:read_only).must_equal 0
|
|
720
|
-
@pool.hold(:read_only) do |c|
|
|
721
|
-
c.must_equal "read_only1"
|
|
722
|
-
@pool.allocated(:read_only).must_equal(Thread.current=>"read_only1")
|
|
723
|
-
end
|
|
724
|
-
@pool.available_connections(:read_only).must_equal ["read_only1"]
|
|
725
|
-
@pool.size(:read_only).must_equal 1
|
|
726
|
-
@invoked_counts.must_equal(:read_only=>1)
|
|
727
|
-
end
|
|
728
|
-
|
|
729
|
-
it "#hold should only yield connections for the server requested" do
|
|
730
|
-
@pool.hold(:read_only) do |c|
|
|
731
|
-
c.must_equal "read_only1"
|
|
732
|
-
@pool.allocated(:read_only).must_equal(Thread.current=>"read_only1")
|
|
733
|
-
@pool.hold do |d|
|
|
734
|
-
d.must_equal "default1"
|
|
735
|
-
@pool.hold do |e|
|
|
736
|
-
e.must_equal d
|
|
737
|
-
@pool.hold(:read_only){|b| b.must_equal c}
|
|
738
|
-
end
|
|
739
|
-
@pool.allocated.must_equal(Thread.current=>"default1")
|
|
740
|
-
end
|
|
741
|
-
end
|
|
742
|
-
@invoked_counts.must_equal(:read_only=>1, :default=>1)
|
|
743
|
-
end
|
|
744
|
-
|
|
745
|
-
it "#disconnect should disconnect from all servers" do
|
|
746
|
-
@pool.hold(:read_only){}
|
|
747
|
-
@pool.hold{}
|
|
748
|
-
conns = []
|
|
749
|
-
@pool.size.must_equal 1
|
|
750
|
-
@pool.size(:read_only).must_equal 1
|
|
751
|
-
@pool.db.define_singleton_method(:disconnect_connection){|c| conns << c}
|
|
752
|
-
@pool.disconnect
|
|
753
|
-
conns.sort.must_equal %w'default1 read_only1'
|
|
754
|
-
@pool.size.must_equal 0
|
|
755
|
-
@pool.size(:read_only).must_equal 0
|
|
756
|
-
@pool.hold(:read_only){|c| c.must_equal 'read_only2'}
|
|
757
|
-
@pool.hold{|c| c.must_equal 'default2'}
|
|
758
|
-
end
|
|
759
|
-
|
|
760
|
-
it "#add_servers should add new servers to the pool" do
|
|
761
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
|
|
762
|
-
|
|
763
|
-
pool.hold{}
|
|
764
|
-
pool.hold(:server2){}
|
|
765
|
-
pool.hold(:server3){}
|
|
766
|
-
pool.hold(:server1) do
|
|
767
|
-
pool.allocated.length.must_equal 0
|
|
768
|
-
pool.allocated(:server1).length.must_equal 1
|
|
769
|
-
pool.allocated(:server2).must_be_nil
|
|
770
|
-
pool.allocated(:server3).must_be_nil
|
|
771
|
-
pool.available_connections.length.must_equal 1
|
|
772
|
-
pool.available_connections(:server1).length.must_equal 0
|
|
773
|
-
pool.available_connections(:server2).must_be_nil
|
|
774
|
-
pool.available_connections(:server3).must_be_nil
|
|
775
|
-
|
|
776
|
-
pool.add_servers([:server2, :server3])
|
|
777
|
-
pool.hold(:server2){}
|
|
778
|
-
pool.hold(:server3) do
|
|
779
|
-
pool.allocated.length.must_equal 0
|
|
780
|
-
pool.allocated(:server1).length.must_equal 1
|
|
781
|
-
pool.allocated(:server2).length.must_equal 0
|
|
782
|
-
pool.allocated(:server3).length.must_equal 1
|
|
783
|
-
pool.available_connections.length.must_equal 1
|
|
784
|
-
pool.available_connections(:server1).length.must_equal 0
|
|
785
|
-
pool.available_connections(:server2).length.must_equal 1
|
|
786
|
-
pool.available_connections(:server3).length.must_equal 0
|
|
787
|
-
end
|
|
788
|
-
end
|
|
789
|
-
end
|
|
790
|
-
|
|
791
|
-
it "#add_servers should ignore existing keys" do
|
|
792
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
|
|
793
|
-
|
|
794
|
-
pool.allocated.length.must_equal 0
|
|
795
|
-
pool.allocated(:server1).length.must_equal 0
|
|
796
|
-
pool.available_connections.length.must_equal 0
|
|
797
|
-
pool.available_connections(:server1).length.must_equal 0
|
|
798
|
-
pool.hold do |c1|
|
|
799
|
-
c1.must_equal :default
|
|
800
|
-
pool.allocated.length.must_equal 1
|
|
801
|
-
pool.allocated(:server1).length.must_equal 0
|
|
802
|
-
pool.available_connections.length.must_equal 0
|
|
803
|
-
pool.available_connections(:server1).length.must_equal 0
|
|
804
|
-
pool.hold(:server1) do |c2|
|
|
805
|
-
c2.must_equal :server1
|
|
806
|
-
pool.allocated.length.must_equal 1
|
|
807
|
-
pool.allocated(:server1).length.must_equal 1
|
|
808
|
-
pool.available_connections.length.must_equal 0
|
|
809
|
-
pool.available_connections(:server1).length.must_equal 0
|
|
810
|
-
pool.add_servers([:default, :server1])
|
|
811
|
-
pool.allocated.length.must_equal 1
|
|
812
|
-
pool.allocated(:server1).length.must_equal 1
|
|
813
|
-
pool.available_connections.length.must_equal 0
|
|
814
|
-
pool.available_connections(:server1).length.must_equal 0
|
|
815
|
-
end
|
|
816
|
-
pool.allocated.length.must_equal 1
|
|
817
|
-
pool.allocated(:server1).length.must_equal 0
|
|
818
|
-
pool.available_connections.length.must_equal 0
|
|
819
|
-
pool.available_connections(:server1).length.must_equal 1
|
|
820
|
-
pool.add_servers([:default, :server1])
|
|
821
|
-
pool.allocated.length.must_equal 1
|
|
822
|
-
pool.allocated(:server1).length.must_equal 0
|
|
823
|
-
pool.available_connections.length.must_equal 0
|
|
824
|
-
pool.available_connections(:server1).length.must_equal 1
|
|
825
|
-
end
|
|
826
|
-
pool.allocated.length.must_equal 0
|
|
827
|
-
pool.allocated(:server1).length.must_equal 0
|
|
828
|
-
pool.available_connections.length.must_equal 1
|
|
829
|
-
pool.available_connections(:server1).length.must_equal 1
|
|
830
|
-
pool.add_servers([:default, :server1])
|
|
831
|
-
pool.allocated.length.must_equal 0
|
|
832
|
-
pool.allocated(:server1).length.must_equal 0
|
|
833
|
-
pool.available_connections.length.must_equal 1
|
|
834
|
-
pool.available_connections(:server1).length.must_equal 1
|
|
835
|
-
end
|
|
836
|
-
|
|
837
|
-
it "#remove_servers should disconnect available connections immediately" do
|
|
838
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :max_connections=>5, :servers=>{:server1=>{}})
|
|
839
|
-
threads = []
|
|
840
|
-
q, q1 = Queue.new, Queue.new
|
|
841
|
-
5.times {|i| threads << Thread.new {pool.hold(:server1){|c| q1.push nil; q.pop}}}
|
|
842
|
-
5.times{q1.pop}
|
|
843
|
-
5.times{q.push nil}
|
|
844
|
-
threads.each {|t| t.join}
|
|
845
|
-
|
|
846
|
-
pool.size(:server1).must_equal 5
|
|
847
|
-
pool.remove_servers([:server1])
|
|
848
|
-
pool.size(:server1).must_equal 0
|
|
849
|
-
end
|
|
850
|
-
|
|
851
|
-
it "#remove_servers should disconnect connections in use as soon as they are returned to the pool" do
|
|
852
|
-
dc = []
|
|
853
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| dc << c}){|c| c}, :servers=>{:server1=>{}})
|
|
854
|
-
c1 = nil
|
|
855
|
-
pool.hold(:server1) do |c|
|
|
856
|
-
pool.size(:server1).must_equal 1
|
|
857
|
-
dc.must_equal []
|
|
858
|
-
pool.remove_servers([:server1])
|
|
859
|
-
pool.size(:server1).must_equal 0
|
|
860
|
-
dc.must_equal []
|
|
861
|
-
c1 = c
|
|
862
|
-
end
|
|
863
|
-
pool.size(:server1).must_equal 0
|
|
864
|
-
dc.must_equal [c1]
|
|
865
|
-
end
|
|
866
|
-
|
|
867
|
-
it "#remove_servers should remove server related data structures immediately" do
|
|
868
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
|
|
869
|
-
pool.available_connections(:server1).must_equal []
|
|
870
|
-
pool.allocated(:server1).must_equal({})
|
|
871
|
-
pool.remove_servers([:server1])
|
|
872
|
-
pool.available_connections(:server1).must_be_nil
|
|
873
|
-
pool.allocated(:server1).must_be_nil
|
|
874
|
-
end
|
|
875
|
-
|
|
876
|
-
it "#remove_servers should not allow the removal of the default server" do
|
|
877
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
|
|
878
|
-
pool.remove_servers([:server1])
|
|
879
|
-
proc{pool.remove_servers([:default])}.must_raise(Sequel::Error)
|
|
880
|
-
end
|
|
881
|
-
|
|
882
|
-
it "#remove_servers should ignore servers that have already been removed" do
|
|
883
|
-
dc = []
|
|
884
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| dc << c}){|c| c}, :servers=>{:server1=>{}})
|
|
885
|
-
c1 = nil
|
|
886
|
-
pool.hold(:server1) do |c|
|
|
887
|
-
pool.size(:server1).must_equal 1
|
|
888
|
-
dc.must_equal []
|
|
889
|
-
pool.remove_servers([:server1])
|
|
890
|
-
pool.remove_servers([:server1])
|
|
891
|
-
pool.size(:server1).must_equal 0
|
|
892
|
-
dc.must_equal []
|
|
893
|
-
c1 = c
|
|
894
|
-
end
|
|
895
|
-
pool.size(:server1).must_equal 0
|
|
896
|
-
dc.must_equal [c1]
|
|
897
|
-
end
|
|
898
|
-
end
|
|
899
|
-
|
|
900
|
-
describe "SingleConnectionPool" do
|
|
901
|
-
before do
|
|
902
|
-
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{1234}, st_connection_pool_defaults)
|
|
903
|
-
end
|
|
904
|
-
|
|
905
|
-
it "should provide a #hold method" do
|
|
906
|
-
conn = nil
|
|
907
|
-
@pool.hold{|c| conn = c}
|
|
908
|
-
conn.must_equal 1234
|
|
909
|
-
end
|
|
910
|
-
|
|
911
|
-
it "should provide a #disconnect method" do
|
|
912
|
-
conn = nil
|
|
913
|
-
x = nil
|
|
914
|
-
pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| conn = c; c.must_be_kind_of(Integer)}){1234}, st_connection_pool_defaults)
|
|
915
|
-
pool.hold{|c| x = c}
|
|
916
|
-
x.must_equal 1234
|
|
917
|
-
pool.disconnect
|
|
918
|
-
conn.must_equal 1234
|
|
919
|
-
pool.disconnect
|
|
920
|
-
end
|
|
921
|
-
end
|
|
922
|
-
|
|
923
|
-
describe "A single threaded pool with multiple servers" do
|
|
924
|
-
before do
|
|
925
|
-
@max_size=2
|
|
926
|
-
msp = proc{@max_size += 1}
|
|
927
|
-
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| msp.call}){|c| c}, st_connection_pool_defaults.merge(:servers=>{:read_only=>{}}))
|
|
928
|
-
end
|
|
929
|
-
|
|
930
|
-
it "should support preconnect method that immediately creates the maximum number of connections" do
|
|
931
|
-
@pool.send(:preconnect)
|
|
932
|
-
i = 0
|
|
933
|
-
@pool.all_connections{|c1| i+=1}
|
|
934
|
-
i.must_equal 2
|
|
935
|
-
end
|
|
936
|
-
|
|
937
|
-
it "should support preconnect method that immediately creates the maximum number of connections, ignoring concurrent param" do
|
|
938
|
-
@pool.send(:preconnect, true)
|
|
939
|
-
i = 0
|
|
940
|
-
@pool.all_connections{|c1| i+=1}
|
|
941
|
-
i.must_equal 2
|
|
942
|
-
end
|
|
943
|
-
|
|
944
|
-
it "#all_connections should return connections for all servers" do
|
|
945
|
-
@pool.hold{}
|
|
946
|
-
@pool.all_connections{|c1| c1.must_equal :default}
|
|
947
|
-
a = []
|
|
948
|
-
@pool.hold(:read_only) do
|
|
949
|
-
@pool.all_connections{|c1| a << c1}
|
|
950
|
-
end
|
|
951
|
-
a.sort_by{|c| c.to_s}.must_equal [:default, :read_only]
|
|
952
|
-
end
|
|
953
|
-
|
|
954
|
-
it "#servers should return symbols for all servers" do
|
|
955
|
-
@pool.servers.sort_by{|s| s.to_s}.must_equal [:default, :read_only]
|
|
956
|
-
end
|
|
957
|
-
|
|
958
|
-
it "#add_servers should add new servers to the pool" do
|
|
959
|
-
@pool.hold(:blah){|c| c.must_equal :default}
|
|
960
|
-
@pool.add_servers([:blah])
|
|
961
|
-
@pool.hold(:blah){|c| c.must_equal :blah}
|
|
962
|
-
end
|
|
963
|
-
|
|
964
|
-
it "#add_servers should ignore keys already existing" do
|
|
965
|
-
@pool.hold{|c| c.must_equal :default}
|
|
966
|
-
@pool.hold(:read_only){|c| c.must_equal :read_only}
|
|
967
|
-
@pool.add_servers([:default, :read_only])
|
|
968
|
-
@pool.conn.must_equal :default
|
|
969
|
-
@pool.conn(:read_only).must_equal :read_only
|
|
970
|
-
end
|
|
971
|
-
|
|
972
|
-
it "#remove_servers should remove servers from the pool" do
|
|
973
|
-
@pool.hold(:read_only){|c| c.must_equal :read_only}
|
|
974
|
-
@pool.remove_servers([:read_only])
|
|
975
|
-
@pool.hold(:read_only){|c| c.must_equal :default}
|
|
976
|
-
end
|
|
977
|
-
|
|
978
|
-
it "#remove_servers should not allow the removal of the default server" do
|
|
979
|
-
proc{@pool.remove_servers([:default])}.must_raise(Sequel::Error)
|
|
980
|
-
end
|
|
981
|
-
|
|
982
|
-
it "#remove_servers should disconnect connection immediately" do
|
|
983
|
-
@pool.hold(:read_only){|c| c.must_equal :read_only}
|
|
984
|
-
@pool.conn(:read_only).must_equal :read_only
|
|
985
|
-
@pool.remove_servers([:read_only])
|
|
986
|
-
@pool.conn(:read_only).must_be_nil
|
|
987
|
-
@pool.hold{}
|
|
988
|
-
@pool.conn(:read_only).must_equal :default
|
|
989
|
-
end
|
|
990
|
-
|
|
991
|
-
it "#remove_servers should ignore keys that do not exist" do
|
|
992
|
-
@pool.remove_servers([:blah])
|
|
993
|
-
end
|
|
994
|
-
|
|
995
|
-
it "should use the :default server by default" do
|
|
996
|
-
@pool.hold{|c| c.must_equal :default}
|
|
997
|
-
@pool.conn.must_equal :default
|
|
998
|
-
end
|
|
999
|
-
|
|
1000
|
-
it "should use the :default server an invalid server is used" do
|
|
1001
|
-
@pool.hold do |c1|
|
|
1002
|
-
c1.must_equal :default
|
|
1003
|
-
@pool.hold(:blah) do |c2|
|
|
1004
|
-
c2.must_equal c1
|
|
1005
|
-
@pool.hold(:blah2) do |c3|
|
|
1006
|
-
c2.must_equal c3
|
|
1007
|
-
end
|
|
1008
|
-
end
|
|
1009
|
-
end
|
|
1010
|
-
end
|
|
1011
|
-
|
|
1012
|
-
it "should use the requested server if server is given" do
|
|
1013
|
-
@pool.hold(:read_only){|c| c.must_equal :read_only}
|
|
1014
|
-
@pool.conn(:read_only).must_equal :read_only
|
|
1015
|
-
end
|
|
1016
|
-
|
|
1017
|
-
it "#hold should only yield connections for the server requested" do
|
|
1018
|
-
@pool.hold(:read_only) do |c|
|
|
1019
|
-
c.must_equal :read_only
|
|
1020
|
-
@pool.hold do |d|
|
|
1021
|
-
d.must_equal :default
|
|
1022
|
-
@pool.hold do |e|
|
|
1023
|
-
e.must_equal d
|
|
1024
|
-
@pool.hold(:read_only){|b| b.must_equal c}
|
|
1025
|
-
end
|
|
1026
|
-
end
|
|
1027
|
-
end
|
|
1028
|
-
@pool.conn.must_equal :default
|
|
1029
|
-
@pool.conn(:read_only).must_equal :read_only
|
|
1030
|
-
end
|
|
1031
|
-
|
|
1032
|
-
it "#disconnect should disconnect from all servers" do
|
|
1033
|
-
@pool.hold(:read_only){}
|
|
1034
|
-
@pool.hold{}
|
|
1035
|
-
@pool.conn.must_equal :default
|
|
1036
|
-
@pool.conn(:read_only).must_equal :read_only
|
|
1037
|
-
@pool.disconnect
|
|
1038
|
-
@max_size.must_equal 4
|
|
1039
|
-
@pool.conn.must_be_nil
|
|
1040
|
-
@pool.conn(:read_only).must_be_nil
|
|
1041
|
-
end
|
|
1042
|
-
|
|
1043
|
-
it ":disconnection_proc option should set the disconnection proc to use" do
|
|
1044
|
-
@max_size.must_equal 2
|
|
1045
|
-
proc{@pool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
|
1046
|
-
@max_size.must_equal 3
|
|
1047
|
-
end
|
|
1048
|
-
|
|
1049
|
-
it "#hold should remove the connection if a DatabaseDisconnectError is raised" do
|
|
1050
|
-
@pool.instance_variable_get(:@conns).length.must_equal 0
|
|
1051
|
-
@pool.hold{}
|
|
1052
|
-
@pool.instance_variable_get(:@conns).length.must_equal 1
|
|
1053
|
-
proc{@pool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
|
1054
|
-
@pool.instance_variable_get(:@conns).length.must_equal 0
|
|
1055
|
-
end
|
|
1056
|
-
end
|
|
1057
|
-
|
|
1058
|
-
AllConnectionPoolClassesSpecs = shared_description do
|
|
1059
|
-
it "should work correctly after being frozen" do
|
|
1060
|
-
o = Object.new
|
|
1061
|
-
db = mock_db.call{o}
|
|
1062
|
-
cp = @class.new(db, {})
|
|
1063
|
-
db.instance_variable_set(:@pool, cp)
|
|
1064
|
-
db.freeze
|
|
1065
|
-
cp.frozen?.must_equal true
|
|
1066
|
-
db.synchronize{|c| c.must_be_same_as o}
|
|
1067
|
-
end
|
|
1068
|
-
|
|
1069
|
-
it "should have pool correctly handle disconnect errors not raised as DatabaseDisconnectError" do
|
|
1070
|
-
db = mock_db.call{Object.new}
|
|
1071
|
-
def db.dec; @dec ||= Class.new(StandardError) end
|
|
1072
|
-
def db.database_error_classes; super + [dec] end
|
|
1073
|
-
def db.disconnect_error?(e, opts); e.message =~ /foo/ end
|
|
1074
|
-
cp = @class.new(db, {})
|
|
1075
|
-
|
|
1076
|
-
conn = nil
|
|
1077
|
-
cp.hold do |c|
|
|
1078
|
-
conn = c
|
|
1079
|
-
end
|
|
1080
|
-
|
|
1081
|
-
proc do
|
|
1082
|
-
cp.hold do |c|
|
|
1083
|
-
c.must_equal conn
|
|
1084
|
-
raise db.dec, "bar"
|
|
1085
|
-
end
|
|
1086
|
-
end.must_raise db.dec
|
|
1087
|
-
|
|
1088
|
-
proc do
|
|
1089
|
-
cp.hold do |c|
|
|
1090
|
-
c.must_equal conn
|
|
1091
|
-
raise StandardError
|
|
1092
|
-
end
|
|
1093
|
-
end.must_raise StandardError
|
|
1094
|
-
|
|
1095
|
-
cp.hold do |c|
|
|
1096
|
-
c.must_equal conn
|
|
1097
|
-
end
|
|
1098
|
-
|
|
1099
|
-
proc do
|
|
1100
|
-
cp.hold do |c|
|
|
1101
|
-
c.must_equal conn
|
|
1102
|
-
raise db.dec, "foo"
|
|
1103
|
-
end
|
|
1104
|
-
end.must_raise db.dec
|
|
1105
|
-
|
|
1106
|
-
cp.hold do |c|
|
|
1107
|
-
c.wont_equal conn
|
|
1108
|
-
end
|
|
1109
|
-
end
|
|
1110
|
-
|
|
1111
|
-
it "should have pool_type return a symbol" do
|
|
1112
|
-
@class.new(mock_db.call{123}, {}).pool_type.must_be_kind_of(Symbol)
|
|
1113
|
-
end
|
|
1114
|
-
|
|
1115
|
-
it "should have all_connections yield current and available connections" do
|
|
1116
|
-
p = @class.new(mock_db.call{123}, {})
|
|
1117
|
-
p.hold{|c| p.all_connections{|c1| c.must_equal c1}}
|
|
1118
|
-
end
|
|
1119
|
-
|
|
1120
|
-
it "should have a size method that gives the current size of the pool" do
|
|
1121
|
-
p = @class.new(mock_db.call{123}, {})
|
|
1122
|
-
p.size.must_equal 0
|
|
1123
|
-
p.hold{}
|
|
1124
|
-
p.size.must_equal 1
|
|
1125
|
-
end
|
|
1126
|
-
|
|
1127
|
-
it "should have a max_size method that gives the maximum size of the pool" do
|
|
1128
|
-
@class.new(mock_db.call{123}, {}).max_size.must_be :>=, 1
|
|
1129
|
-
end
|
|
1130
|
-
|
|
1131
|
-
it "should support preconnect method that immediately creates the maximum number of connections" do
|
|
1132
|
-
p = @class.new(mock_db.call{123}, {})
|
|
1133
|
-
p.send(:preconnect)
|
|
1134
|
-
i = 0
|
|
1135
|
-
p.all_connections{|c1| i+=1}
|
|
1136
|
-
i.must_equal p.max_size
|
|
1137
|
-
end
|
|
1138
|
-
|
|
1139
|
-
it "should support preconnect method that immediately creates the maximum number of connections concurrently" do
|
|
1140
|
-
p = @class.new(mock_db.call{123}, {})
|
|
1141
|
-
p.send(:preconnect, true)
|
|
1142
|
-
i = 0
|
|
1143
|
-
p.all_connections{|c1| i+=1}
|
|
1144
|
-
i.must_equal p.max_size
|
|
1145
|
-
end
|
|
1146
|
-
|
|
1147
|
-
it "should be able to modify after_connect proc after the pool is created" do
|
|
1148
|
-
a = []
|
|
1149
|
-
p = @class.new(mock_db.call{123}, {})
|
|
1150
|
-
p.after_connect = pr = proc{|c| a << c}
|
|
1151
|
-
p.after_connect.must_equal pr
|
|
1152
|
-
a.must_equal []
|
|
1153
|
-
p.hold{}
|
|
1154
|
-
a.must_equal [123]
|
|
1155
|
-
end
|
|
1156
|
-
|
|
1157
|
-
it "should not raise an error when disconnecting twice" do
|
|
1158
|
-
c = @class.new(mock_db.call{123}, {})
|
|
1159
|
-
c.disconnect
|
|
1160
|
-
c.disconnect
|
|
1161
|
-
end
|
|
1162
|
-
|
|
1163
|
-
it "should yield a connection created by the initialize block to hold" do
|
|
1164
|
-
x = nil
|
|
1165
|
-
@class.new(mock_db.call{123}, {}).hold{|c| x = c}
|
|
1166
|
-
x.must_equal 123
|
|
1167
|
-
end
|
|
1168
|
-
|
|
1169
|
-
it "should have the initialize block accept a shard/server argument" do
|
|
1170
|
-
x = nil
|
|
1171
|
-
@class.new(mock_db.call{|c| [c, c]}, {}).hold{|c| x = c}
|
|
1172
|
-
x.must_equal [:default, :default]
|
|
1173
|
-
end
|
|
1174
|
-
|
|
1175
|
-
it "should have respect an :after_connect proc that is called with each newly created connection" do
|
|
1176
|
-
x = nil
|
|
1177
|
-
@class.new(mock_db.call{123}, :after_connect=>proc{|c| x = [c, c]}).hold{}
|
|
1178
|
-
x.must_equal [123, 123]
|
|
1179
|
-
@class.new(mock_db.call{123}, :after_connect=>lambda{|c| x = [c, c]}).hold{}
|
|
1180
|
-
x.must_equal [123, 123]
|
|
1181
|
-
@class.new(mock_db.call{123}, :after_connect=>proc{|c, s| x = [c, s]}).hold{}
|
|
1182
|
-
x.must_equal [123, :default]
|
|
1183
|
-
@class.new(mock_db.call{123}, :after_connect=>lambda{|c, s| x = [c, s]}).hold{}
|
|
1184
|
-
x.must_equal [123, :default]
|
|
1185
|
-
end
|
|
1186
|
-
|
|
1187
|
-
it "should raise a DatabaseConnectionError if the connection raises an exception" do
|
|
1188
|
-
proc{@class.new(mock_db.call{|c| raise Exception}, {}).hold{}}.must_raise(Sequel::DatabaseConnectionError)
|
|
1189
|
-
end
|
|
1190
|
-
|
|
1191
|
-
it "should raise a DatabaseConnectionError if the initialize block returns nil" do
|
|
1192
|
-
proc{@class.new(mock_db.call{}, {}).hold{}}.must_raise(Sequel::DatabaseConnectionError)
|
|
1193
|
-
end
|
|
1194
|
-
|
|
1195
|
-
it "should call the disconnection_proc option if the hold block raises a DatabaseDisconnectError" do
|
|
1196
|
-
x = nil
|
|
1197
|
-
proc{@class.new(mock_db.call(proc{|c| x = c}){123}).hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
|
1198
|
-
x.must_equal 123
|
|
1199
|
-
end
|
|
1200
|
-
|
|
1201
|
-
it "should have a disconnect method that disconnects the connection" do
|
|
1202
|
-
x = nil
|
|
1203
|
-
c = @class.new(mock_db.call(proc{|c1| x = c1}){123})
|
|
1204
|
-
c.hold{}
|
|
1205
|
-
x.must_be_nil
|
|
1206
|
-
c.disconnect
|
|
1207
|
-
x.must_equal 123
|
|
1208
|
-
end
|
|
1209
|
-
|
|
1210
|
-
it "should have a reentrent hold method" do
|
|
1211
|
-
o = Object.new
|
|
1212
|
-
c = @class.new(mock_db.call{o}, {})
|
|
1213
|
-
c.hold do |x|
|
|
1214
|
-
x.must_equal o
|
|
1215
|
-
c.hold do |x1|
|
|
1216
|
-
x1.must_equal o
|
|
1217
|
-
c.hold do |x2|
|
|
1218
|
-
x2.must_equal o
|
|
1219
|
-
end
|
|
1220
|
-
end
|
|
1221
|
-
end
|
|
1222
|
-
end
|
|
1223
|
-
|
|
1224
|
-
it "should have a servers method that returns an array of shard/server symbols" do
|
|
1225
|
-
@class.new(mock_db.call{123}, {}).servers.must_equal [:default]
|
|
1226
|
-
end
|
|
1227
|
-
|
|
1228
|
-
it "should have a servers method that returns an array of shard/server symbols" do
|
|
1229
|
-
c = @class.new(mock_db.call{123}, {})
|
|
1230
|
-
c.size.must_equal 0
|
|
1231
|
-
c.hold{}
|
|
1232
|
-
c.size.must_equal 1
|
|
1233
|
-
end
|
|
1234
|
-
end
|
|
1235
|
-
|
|
1236
|
-
[true, false].each do |k|
|
|
1237
|
-
[true, false].each do |v|
|
|
1238
|
-
opts = {:single_threaded=>k, :servers=>(v ? {} : nil)}
|
|
1239
|
-
describe "Connection pool with #{opts.inspect}" do
|
|
1240
|
-
before(:all) do
|
|
1241
|
-
Sequel::ConnectionPool.send(:get_pool, mock_db.call, opts)
|
|
1242
|
-
end
|
|
1243
|
-
before do
|
|
1244
|
-
@class = Sequel::ConnectionPool.send(:connection_pool_class, opts)
|
|
1245
|
-
end
|
|
1246
|
-
|
|
1247
|
-
include AllConnectionPoolClassesSpecs
|
|
1248
|
-
end
|
|
1249
|
-
end
|
|
1250
|
-
end
|