sequel 4.49.0 → 5.0.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 +70 -0
- data/README.rdoc +195 -136
- data/Rakefile +26 -42
- data/bin/sequel +3 -5
- data/doc/advanced_associations.rdoc +86 -163
- data/doc/association_basics.rdoc +197 -274
- data/doc/bin_sequel.rdoc +5 -3
- data/doc/cheat_sheet.rdoc +66 -43
- data/doc/code_order.rdoc +1 -8
- data/doc/core_extensions.rdoc +81 -56
- data/doc/dataset_basics.rdoc +8 -17
- data/doc/dataset_filtering.rdoc +81 -86
- data/doc/extensions.rdoc +3 -10
- data/doc/mass_assignment.rdoc +73 -30
- data/doc/migration.rdoc +19 -36
- data/doc/model_dataset_method_design.rdoc +14 -17
- data/doc/model_hooks.rdoc +15 -25
- data/doc/model_plugins.rdoc +10 -10
- data/doc/mssql_stored_procedures.rdoc +3 -3
- data/doc/object_model.rdoc +52 -70
- data/doc/opening_databases.rdoc +39 -32
- data/doc/postgresql.rdoc +48 -38
- data/doc/prepared_statements.rdoc +27 -22
- data/doc/querying.rdoc +173 -150
- data/doc/reflection.rdoc +5 -6
- data/doc/release_notes/5.0.0.txt +159 -0
- data/doc/schema_modification.rdoc +63 -60
- data/doc/security.rdoc +97 -88
- data/doc/sharding.rdoc +43 -30
- data/doc/sql.rdoc +53 -65
- data/doc/testing.rdoc +3 -5
- data/doc/thread_safety.rdoc +2 -4
- data/doc/transactions.rdoc +18 -17
- data/doc/validations.rdoc +48 -45
- data/doc/virtual_rows.rdoc +87 -115
- data/lib/sequel.rb +1 -1
- data/lib/sequel/adapters/ado.rb +9 -25
- data/lib/sequel/adapters/ado/access.rb +7 -13
- data/lib/sequel/adapters/ado/mssql.rb +2 -9
- data/lib/sequel/adapters/amalgalite.rb +3 -18
- data/lib/sequel/adapters/ibmdb.rb +9 -45
- data/lib/sequel/adapters/jdbc.rb +13 -73
- data/lib/sequel/adapters/jdbc/db2.rb +8 -37
- data/lib/sequel/adapters/jdbc/derby.rb +4 -50
- data/lib/sequel/adapters/jdbc/h2.rb +4 -25
- data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -26
- data/lib/sequel/adapters/jdbc/jtds.rb +2 -9
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -11
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -15
- data/lib/sequel/adapters/jdbc/oracle.rb +4 -26
- data/lib/sequel/adapters/jdbc/postgresql.rb +2 -31
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +4 -17
- data/lib/sequel/adapters/jdbc/sqlite.rb +1 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -13
- data/lib/sequel/adapters/jdbc/transactions.rb +1 -14
- data/lib/sequel/adapters/mock.rb +4 -30
- data/lib/sequel/adapters/mysql.rb +7 -44
- data/lib/sequel/adapters/mysql2.rb +5 -23
- data/lib/sequel/adapters/odbc.rb +0 -19
- data/lib/sequel/adapters/odbc/db2.rb +1 -1
- data/lib/sequel/adapters/odbc/mssql.rb +4 -12
- data/lib/sequel/adapters/odbc/oracle.rb +1 -1
- data/lib/sequel/adapters/oracle.rb +7 -13
- data/lib/sequel/adapters/postgres.rb +13 -57
- data/lib/sequel/adapters/postgresql.rb +1 -1
- data/lib/sequel/adapters/shared/access.rb +11 -51
- data/lib/sequel/adapters/shared/db2.rb +3 -61
- data/lib/sequel/adapters/shared/mssql.rb +21 -157
- data/lib/sequel/adapters/shared/mysql.rb +23 -224
- data/lib/sequel/adapters/shared/oracle.rb +13 -41
- data/lib/sequel/adapters/shared/postgres.rb +44 -259
- data/lib/sequel/adapters/shared/sqlanywhere.rb +4 -96
- data/lib/sequel/adapters/shared/sqlite.rb +12 -101
- data/lib/sequel/adapters/sqlanywhere.rb +4 -23
- data/lib/sequel/adapters/sqlite.rb +2 -19
- data/lib/sequel/adapters/tinytds.rb +5 -15
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -4
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +3 -6
- data/lib/sequel/adapters/utils/replace.rb +0 -5
- data/lib/sequel/adapters/utils/stored_procedures.rb +0 -2
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +2 -0
- data/lib/sequel/ast_transformer.rb +3 -94
- data/lib/sequel/connection_pool.rb +26 -28
- data/lib/sequel/connection_pool/sharded_single.rb +1 -4
- data/lib/sequel/connection_pool/sharded_threaded.rb +97 -95
- data/lib/sequel/connection_pool/single.rb +0 -2
- data/lib/sequel/connection_pool/threaded.rb +94 -110
- data/lib/sequel/core.rb +42 -101
- data/lib/sequel/database.rb +12 -2
- data/lib/sequel/database/connecting.rb +23 -60
- data/lib/sequel/database/dataset.rb +6 -9
- data/lib/sequel/database/dataset_defaults.rb +4 -48
- data/lib/sequel/database/features.rb +5 -4
- data/lib/sequel/database/logging.rb +2 -9
- data/lib/sequel/database/misc.rb +23 -55
- data/lib/sequel/database/query.rb +8 -13
- data/lib/sequel/database/schema_generator.rb +89 -64
- data/lib/sequel/database/schema_methods.rb +61 -79
- data/lib/sequel/database/transactions.rb +4 -24
- data/lib/sequel/dataset.rb +18 -10
- data/lib/sequel/dataset/actions.rb +53 -107
- data/lib/sequel/dataset/dataset_module.rb +3 -15
- data/lib/sequel/dataset/features.rb +30 -30
- data/lib/sequel/dataset/graph.rb +40 -49
- data/lib/sequel/dataset/misc.rb +12 -37
- data/lib/sequel/dataset/placeholder_literalizer.rb +4 -4
- data/lib/sequel/dataset/prepared_statements.rb +23 -51
- data/lib/sequel/dataset/query.rb +71 -155
- data/lib/sequel/dataset/sql.rb +30 -225
- data/lib/sequel/deprecated.rb +18 -27
- data/lib/sequel/exceptions.rb +1 -17
- data/lib/sequel/extensions/_model_pg_row.rb +0 -7
- data/lib/sequel/extensions/_pretty_table.rb +1 -3
- data/lib/sequel/extensions/arbitrary_servers.rb +10 -10
- data/lib/sequel/extensions/connection_expiration.rb +1 -1
- data/lib/sequel/extensions/connection_validator.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +11 -11
- data/lib/sequel/extensions/core_extensions.rb +39 -49
- data/lib/sequel/extensions/core_refinements.rb +39 -45
- data/lib/sequel/extensions/current_datetime_timestamp.rb +0 -4
- data/lib/sequel/extensions/date_arithmetic.rb +7 -7
- data/lib/sequel/extensions/duplicate_columns_handler.rb +12 -9
- data/lib/sequel/extensions/empty_array_consider_nulls.rb +2 -2
- data/lib/sequel/extensions/eval_inspect.rb +4 -11
- data/lib/sequel/extensions/freeze_datasets.rb +1 -69
- data/lib/sequel/extensions/from_block.rb +1 -35
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/identifier_mangling.rb +9 -19
- data/lib/sequel/extensions/implicit_subquery.rb +2 -2
- data/lib/sequel/extensions/inflector.rb +4 -4
- data/lib/sequel/extensions/migration.rb +23 -40
- data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -84
- data/lib/sequel/extensions/null_dataset.rb +2 -8
- data/lib/sequel/extensions/pagination.rb +1 -17
- data/lib/sequel/extensions/pg_array.rb +20 -189
- data/lib/sequel/extensions/pg_hstore.rb +11 -50
- data/lib/sequel/extensions/pg_hstore_ops.rb +2 -2
- data/lib/sequel/extensions/pg_inet.rb +2 -15
- data/lib/sequel/extensions/pg_interval.rb +1 -20
- data/lib/sequel/extensions/pg_json.rb +7 -27
- data/lib/sequel/extensions/pg_loose_count.rb +1 -1
- data/lib/sequel/extensions/pg_range.rb +6 -121
- data/lib/sequel/extensions/pg_range_ops.rb +1 -3
- data/lib/sequel/extensions/pg_row.rb +5 -77
- data/lib/sequel/extensions/pg_row_ops.rb +2 -13
- data/lib/sequel/extensions/query.rb +3 -4
- data/lib/sequel/extensions/round_timestamps.rb +0 -6
- data/lib/sequel/extensions/schema_dumper.rb +13 -13
- data/lib/sequel/extensions/select_remove.rb +3 -3
- data/lib/sequel/extensions/split_array_nil.rb +2 -2
- data/lib/sequel/extensions/sql_comments.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +11 -8
- data/lib/sequel/extensions/symbol_aref.rb +6 -20
- data/lib/sequel/model.rb +27 -62
- data/lib/sequel/model/associations.rb +128 -131
- data/lib/sequel/model/base.rb +171 -711
- data/lib/sequel/model/default_inflections.rb +1 -1
- data/lib/sequel/model/errors.rb +0 -3
- data/lib/sequel/model/exceptions.rb +2 -6
- data/lib/sequel/model/inflections.rb +1 -26
- data/lib/sequel/model/plugins.rb +1 -0
- data/lib/sequel/plugins/active_model.rb +2 -5
- data/lib/sequel/plugins/association_dependencies.rb +15 -15
- data/lib/sequel/plugins/association_pks.rb +14 -28
- data/lib/sequel/plugins/association_proxies.rb +6 -7
- data/lib/sequel/plugins/auto_validations.rb +4 -4
- data/lib/sequel/plugins/before_after_save.rb +0 -43
- data/lib/sequel/plugins/blacklist_security.rb +9 -8
- data/lib/sequel/plugins/boolean_readers.rb +3 -3
- data/lib/sequel/plugins/boolean_subsets.rb +2 -2
- data/lib/sequel/plugins/caching.rb +5 -5
- data/lib/sequel/plugins/class_table_inheritance.rb +71 -102
- data/lib/sequel/plugins/column_conflicts.rb +2 -2
- data/lib/sequel/plugins/column_select.rb +2 -2
- data/lib/sequel/plugins/composition.rb +15 -24
- data/lib/sequel/plugins/constraint_validations.rb +4 -3
- data/lib/sequel/plugins/csv_serializer.rb +13 -20
- data/lib/sequel/plugins/dataset_associations.rb +2 -2
- data/lib/sequel/plugins/def_dataset_method.rb +5 -5
- data/lib/sequel/plugins/defaults_setter.rb +1 -1
- data/lib/sequel/plugins/delay_add_association.rb +1 -1
- data/lib/sequel/plugins/finder.rb +16 -10
- data/lib/sequel/plugins/force_encoding.rb +1 -7
- data/lib/sequel/plugins/hook_class_methods.rb +4 -106
- data/lib/sequel/plugins/input_transformer.rb +10 -11
- data/lib/sequel/plugins/insert_returning_select.rb +1 -9
- data/lib/sequel/plugins/instance_filters.rb +5 -5
- data/lib/sequel/plugins/instance_hooks.rb +7 -52
- data/lib/sequel/plugins/inverted_subsets.rb +3 -1
- data/lib/sequel/plugins/json_serializer.rb +19 -19
- data/lib/sequel/plugins/lazy_attributes.rb +1 -10
- data/lib/sequel/plugins/list.rb +6 -6
- data/lib/sequel/plugins/many_through_many.rb +11 -8
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +3 -3
- data/lib/sequel/plugins/nested_attributes.rb +18 -31
- data/lib/sequel/plugins/optimistic_locking.rb +3 -3
- data/lib/sequel/plugins/pg_array_associations.rb +8 -2
- data/lib/sequel/plugins/pg_row.rb +2 -11
- data/lib/sequel/plugins/prepared_statements.rb +13 -66
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +7 -7
- data/lib/sequel/plugins/serialization.rb +15 -33
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +2 -8
- data/lib/sequel/plugins/single_table_inheritance.rb +10 -13
- data/lib/sequel/plugins/skip_create_refresh.rb +3 -3
- data/lib/sequel/plugins/static_cache.rb +8 -9
- data/lib/sequel/plugins/string_stripper.rb +3 -3
- data/lib/sequel/plugins/subclasses.rb +1 -1
- data/lib/sequel/plugins/subset_conditions.rb +2 -2
- data/lib/sequel/plugins/table_select.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
- data/lib/sequel/plugins/timestamps.rb +6 -7
- data/lib/sequel/plugins/touch.rb +4 -8
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +2 -2
- data/lib/sequel/plugins/unlimited_update.rb +1 -7
- data/lib/sequel/plugins/update_or_create.rb +3 -3
- data/lib/sequel/plugins/update_refresh.rb +3 -3
- data/lib/sequel/plugins/uuid.rb +7 -11
- data/lib/sequel/plugins/validation_class_methods.rb +10 -9
- data/lib/sequel/plugins/validation_contexts.rb +4 -4
- data/lib/sequel/plugins/validation_helpers.rb +26 -25
- data/lib/sequel/plugins/whitelist_security.rb +13 -9
- data/lib/sequel/plugins/xml_serializer.rb +24 -25
- data/lib/sequel/sql.rb +145 -276
- data/lib/sequel/timezones.rb +8 -22
- data/lib/sequel/version.rb +2 -2
- data/spec/adapter_spec.rb +1 -1
- data/spec/adapters/db2_spec.rb +2 -103
- data/spec/adapters/mssql_spec.rb +89 -68
- data/spec/adapters/mysql_spec.rb +101 -480
- data/spec/adapters/oracle_spec.rb +1 -9
- data/spec/adapters/postgres_spec.rb +312 -565
- data/spec/adapters/spec_helper.rb +12 -31
- data/spec/adapters/sqlanywhere_spec.rb +2 -77
- data/spec/adapters/sqlite_spec.rb +8 -146
- data/spec/bin_spec.rb +11 -16
- data/spec/core/connection_pool_spec.rb +173 -74
- data/spec/core/database_spec.rb +64 -244
- data/spec/core/dataset_spec.rb +81 -415
- data/spec/core/deprecated_spec.rb +3 -3
- data/spec/core/expression_filters_spec.rb +37 -144
- data/spec/core/mock_adapter_spec.rb +176 -4
- data/spec/core/object_graph_spec.rb +11 -60
- data/spec/core/placeholder_literalizer_spec.rb +1 -14
- data/spec/core/schema_generator_spec.rb +51 -40
- data/spec/core/schema_spec.rb +74 -77
- data/spec/core/spec_helper.rb +6 -24
- data/spec/core/version_spec.rb +1 -1
- data/spec/core_extensions_spec.rb +7 -83
- data/spec/core_model_spec.rb +2 -2
- data/spec/deprecation_helper.rb +2 -14
- data/spec/extensions/accessed_columns_spec.rb +1 -1
- data/spec/extensions/active_model_spec.rb +3 -3
- data/spec/extensions/after_initialize_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +2 -2
- data/spec/extensions/association_dependencies_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +4 -59
- data/spec/extensions/association_proxies_spec.rb +1 -1
- data/spec/extensions/auto_literal_strings_spec.rb +1 -12
- data/spec/extensions/auto_validations_spec.rb +1 -1
- data/spec/extensions/blacklist_security_spec.rb +1 -1
- data/spec/extensions/blank_spec.rb +1 -1
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/caching_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +35 -1086
- data/spec/extensions/column_conflicts_spec.rb +1 -1
- data/spec/extensions/column_select_spec.rb +4 -4
- data/spec/extensions/columns_introspection_spec.rb +1 -1
- data/spec/extensions/columns_updated_spec.rb +1 -1
- data/spec/extensions/composition_spec.rb +1 -7
- data/spec/extensions/connection_expiration_spec.rb +3 -3
- data/spec/extensions/connection_validator_spec.rb +3 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +1 -1
- data/spec/extensions/constraint_validations_spec.rb +1 -1
- data/spec/extensions/core_refinements_spec.rb +1 -3
- data/spec/extensions/csv_serializer_spec.rb +4 -9
- data/spec/extensions/current_datetime_timestamp_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +2 -1
- data/spec/extensions/dataset_source_alias_spec.rb +1 -1
- data/spec/extensions/date_arithmetic_spec.rb +3 -3
- data/spec/extensions/def_dataset_method_spec.rb +1 -1
- data/spec/extensions/defaults_setter_spec.rb +2 -2
- data/spec/extensions/delay_add_association_spec.rb +8 -9
- data/spec/extensions/dirty_spec.rb +1 -1
- data/spec/extensions/duplicate_columns_handler_spec.rb +1 -1
- data/spec/extensions/eager_each_spec.rb +2 -2
- data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
- data/spec/extensions/error_splitter_spec.rb +1 -1
- data/spec/extensions/error_sql_spec.rb +1 -1
- data/spec/extensions/eval_inspect_spec.rb +1 -1
- data/spec/extensions/finder_spec.rb +1 -1
- data/spec/extensions/force_encoding_spec.rb +2 -5
- data/spec/extensions/freeze_datasets_spec.rb +1 -1
- data/spec/extensions/graph_each_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +1 -194
- data/spec/extensions/identifier_mangling_spec.rb +17 -170
- data/spec/extensions/implicit_subquery_spec.rb +1 -5
- data/spec/extensions/inflector_spec.rb +1 -1
- data/spec/extensions/input_transformer_spec.rb +7 -2
- data/spec/extensions/insert_returning_select_spec.rb +1 -1
- data/spec/extensions/instance_filters_spec.rb +1 -1
- data/spec/extensions/instance_hooks_spec.rb +1 -95
- data/spec/extensions/inverted_subsets_spec.rb +1 -1
- data/spec/extensions/json_serializer_spec.rb +1 -1
- data/spec/extensions/lazy_attributes_spec.rb +1 -7
- data/spec/extensions/list_spec.rb +1 -1
- data/spec/extensions/looser_typecasting_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +1 -1
- data/spec/extensions/migration_spec.rb +2 -2
- data/spec/extensions/modification_detection_spec.rb +1 -1
- data/spec/extensions/mssql_optimistic_locking_spec.rb +1 -1
- data/spec/extensions/named_timezones_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +1 -29
- data/spec/extensions/null_dataset_spec.rb +1 -11
- data/spec/extensions/optimistic_locking_spec.rb +1 -1
- data/spec/extensions/pagination_spec.rb +1 -1
- data/spec/extensions/pg_array_associations_spec.rb +4 -1
- data/spec/extensions/pg_array_ops_spec.rb +1 -1
- data/spec/extensions/pg_array_spec.rb +3 -48
- data/spec/extensions/pg_enum_spec.rb +1 -1
- data/spec/extensions/pg_hstore_ops_spec.rb +1 -1
- data/spec/extensions/pg_hstore_spec.rb +23 -32
- data/spec/extensions/pg_inet_ops_spec.rb +1 -1
- data/spec/extensions/pg_inet_spec.rb +1 -14
- data/spec/extensions/pg_interval_spec.rb +3 -13
- data/spec/extensions/pg_json_ops_spec.rb +1 -1
- data/spec/extensions/pg_json_spec.rb +1 -13
- data/spec/extensions/pg_loose_count_spec.rb +1 -1
- data/spec/extensions/pg_range_ops_spec.rb +1 -1
- data/spec/extensions/pg_range_spec.rb +3 -88
- data/spec/extensions/pg_row_ops_spec.rb +1 -1
- data/spec/extensions/pg_row_plugin_spec.rb +1 -1
- data/spec/extensions/pg_row_spec.rb +1 -44
- data/spec/extensions/pg_static_cache_updater_spec.rb +1 -1
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/prepared_statements_spec.rb +13 -48
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +1 -12
- data/spec/extensions/rcte_tree_spec.rb +1 -1
- data/spec/extensions/round_timestamps_spec.rb +1 -5
- data/spec/extensions/s_spec.rb +1 -1
- data/spec/extensions/schema_caching_spec.rb +1 -1
- data/spec/extensions/schema_dumper_spec.rb +1 -1
- data/spec/extensions/select_remove_spec.rb +1 -1
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +1 -1
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
- data/spec/extensions/serialization_spec.rb +2 -14
- data/spec/extensions/server_block_spec.rb +1 -1
- data/spec/extensions/server_logging_spec.rb +2 -2
- data/spec/extensions/sharding_spec.rb +1 -1
- data/spec/extensions/shared_caching_spec.rb +1 -28
- data/spec/extensions/single_table_inheritance_spec.rb +2 -5
- data/spec/extensions/singular_table_names_spec.rb +1 -1
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +5 -27
- data/spec/extensions/split_array_nil_spec.rb +1 -1
- data/spec/extensions/split_values_spec.rb +1 -1
- data/spec/extensions/sql_comments_spec.rb +1 -1
- data/spec/extensions/sql_expr_spec.rb +1 -1
- data/spec/extensions/static_cache_spec.rb +1 -1
- data/spec/extensions/string_agg_spec.rb +2 -2
- data/spec/extensions/string_date_time_spec.rb +1 -1
- data/spec/extensions/string_stripper_spec.rb +1 -1
- data/spec/extensions/subclasses_spec.rb +1 -1
- data/spec/extensions/subset_conditions_spec.rb +1 -1
- data/spec/extensions/symbol_aref_refinement_spec.rb +1 -1
- data/spec/extensions/symbol_as_refinement_spec.rb +1 -1
- data/spec/extensions/table_select_spec.rb +4 -4
- data/spec/extensions/tactical_eager_loading_spec.rb +1 -6
- data/spec/extensions/thread_local_timezones_spec.rb +1 -1
- data/spec/extensions/timestamps_spec.rb +3 -3
- data/spec/extensions/to_dot_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +1 -1
- data/spec/extensions/tree_spec.rb +1 -1
- data/spec/extensions/typecast_on_load_spec.rb +1 -1
- data/spec/extensions/unlimited_update_spec.rb +1 -1
- data/spec/extensions/update_or_create_spec.rb +1 -1
- data/spec/extensions/update_primary_key_spec.rb +4 -3
- data/spec/extensions/update_refresh_spec.rb +1 -1
- data/spec/extensions/uuid_spec.rb +10 -12
- data/spec/extensions/validate_associated_spec.rb +1 -1
- data/spec/extensions/validation_class_methods_spec.rb +3 -3
- data/spec/extensions/validation_contexts_spec.rb +1 -1
- data/spec/extensions/validation_helpers_spec.rb +10 -44
- data/spec/extensions/whitelist_security_spec.rb +5 -5
- data/spec/extensions/xml_serializer_spec.rb +3 -3
- data/spec/guards_helper.rb +2 -1
- data/spec/integration/associations_test.rb +1 -23
- data/spec/integration/database_test.rb +7 -7
- data/spec/integration/dataset_test.rb +5 -47
- data/spec/integration/eager_loader_test.rb +1 -1
- data/spec/integration/migrator_test.rb +1 -1
- data/spec/integration/model_test.rb +4 -82
- data/spec/integration/plugin_test.rb +6 -22
- data/spec/integration/prepared_statement_test.rb +8 -88
- data/spec/integration/schema_test.rb +6 -6
- data/spec/integration/spec_helper.rb +13 -21
- data/spec/integration/timezone_test.rb +5 -5
- data/spec/integration/transaction_test.rb +3 -55
- data/spec/integration/type_test.rb +9 -9
- data/spec/model/association_reflection_spec.rb +24 -9
- data/spec/model/associations_spec.rb +124 -303
- data/spec/model/base_spec.rb +18 -137
- data/spec/model/class_dataset_methods_spec.rb +2 -20
- data/spec/model/dataset_methods_spec.rb +1 -20
- data/spec/model/eager_loading_spec.rb +17 -11
- data/spec/model/hooks_spec.rb +5 -300
- data/spec/model/inflector_spec.rb +1 -1
- data/spec/model/model_spec.rb +15 -320
- data/spec/model/plugins_spec.rb +2 -16
- data/spec/model/record_spec.rb +29 -121
- data/spec/model/spec_helper.rb +5 -15
- data/spec/model/validations_spec.rb +1 -1
- data/spec/sequel_warning.rb +1 -12
- metadata +8 -64
- data/doc/active_record.rdoc +0 -927
- data/lib/sequel/adapters/cubrid.rb +0 -160
- data/lib/sequel/adapters/do.rb +0 -166
- data/lib/sequel/adapters/do/mysql.rb +0 -69
- data/lib/sequel/adapters/do/postgres.rb +0 -46
- data/lib/sequel/adapters/do/sqlite3.rb +0 -41
- data/lib/sequel/adapters/jdbc/as400.rb +0 -92
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -65
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -37
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -34
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -34
- data/lib/sequel/adapters/odbc/progress.rb +0 -12
- data/lib/sequel/adapters/shared/cubrid.rb +0 -245
- data/lib/sequel/adapters/shared/firebird.rb +0 -261
- data/lib/sequel/adapters/shared/informix.rb +0 -63
- data/lib/sequel/adapters/shared/progress.rb +0 -40
- data/lib/sequel/adapters/swift.rb +0 -169
- data/lib/sequel/adapters/swift/mysql.rb +0 -50
- data/lib/sequel/adapters/swift/postgres.rb +0 -49
- data/lib/sequel/adapters/swift/sqlite.rb +0 -48
- data/lib/sequel/adapters/utils/pg_types.rb +0 -4
- data/lib/sequel/dataset/mutation.rb +0 -98
- data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +0 -117
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -8
- data/lib/sequel/extensions/filter_having.rb +0 -65
- data/lib/sequel/extensions/hash_aliases.rb +0 -51
- data/lib/sequel/extensions/meta_def.rb +0 -37
- data/lib/sequel/extensions/query_literals.rb +0 -86
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -26
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -133
- data/lib/sequel/extensions/set_overrides.rb +0 -82
- data/lib/sequel/no_core_ext.rb +0 -4
- data/lib/sequel/plugins/association_autoreloading.rb +0 -11
- data/lib/sequel/plugins/identifier_columns.rb +0 -49
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -11
- data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -90
- data/lib/sequel/plugins/prepared_statements_associations.rb +0 -137
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -71
- data/lib/sequel/plugins/schema.rb +0 -84
- data/lib/sequel/plugins/scissors.rb +0 -37
- data/spec/core/dataset_mutation_spec.rb +0 -253
- data/spec/extensions/_deprecated_identifier_mangling_spec.rb +0 -314
- data/spec/extensions/before_after_save_spec.rb +0 -40
- data/spec/extensions/filter_having_spec.rb +0 -42
- data/spec/extensions/from_block_spec.rb +0 -21
- data/spec/extensions/hash_aliases_spec.rb +0 -26
- data/spec/extensions/identifier_columns_spec.rb +0 -19
- data/spec/extensions/meta_def_spec.rb +0 -35
- data/spec/extensions/no_auto_literal_strings_spec.rb +0 -69
- data/spec/extensions/pg_typecast_on_load_spec.rb +0 -70
- data/spec/extensions/prepared_statements_associations_spec.rb +0 -212
- data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -40
- data/spec/extensions/query_literals_spec.rb +0 -185
- data/spec/extensions/schema_spec.rb +0 -123
- data/spec/extensions/scissors_spec.rb +0 -27
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -118
- data/spec/extensions/set_overrides_spec.rb +0 -75
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
3
|
require 'tiny_tds'
|
4
|
-
|
4
|
+
require_relative 'shared/mssql'
|
5
5
|
|
6
6
|
module Sequel
|
7
7
|
module TinyTDS
|
@@ -59,7 +59,7 @@ module Sequel
|
|
59
59
|
else
|
60
60
|
log_connection_yield(sql, c) do
|
61
61
|
r = c.execute(sql)
|
62
|
-
return r.
|
62
|
+
return r.public_send(m) if m
|
63
63
|
end
|
64
64
|
end
|
65
65
|
yield(r) if block_given?
|
@@ -71,22 +71,18 @@ module Sequel
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
# Return the number of rows modified by the given +sql+.
|
75
74
|
def execute_dui(sql, opts=OPTS)
|
76
75
|
opts = Hash[opts]
|
77
76
|
opts[:return] = :do
|
78
77
|
execute(sql, opts)
|
79
78
|
end
|
80
79
|
|
81
|
-
# Return the value of the autogenerated primary key (if any)
|
82
|
-
# for the row inserted by the given +sql+.
|
83
80
|
def execute_insert(sql, opts=OPTS)
|
84
81
|
opts = Hash[opts]
|
85
82
|
opts[:return] = :insert
|
86
83
|
execute(sql, opts)
|
87
84
|
end
|
88
85
|
|
89
|
-
# Execute the DDL +sql+ on the database and return nil.
|
90
86
|
def execute_ddl(sql, opts=OPTS)
|
91
87
|
opts = Hash[opts]
|
92
88
|
opts[:return] = :each
|
@@ -135,9 +131,6 @@ module Sequel
|
|
135
131
|
Dataset
|
136
132
|
end
|
137
133
|
|
138
|
-
TINYTDS_DISCONNECT_ERRORS = /\A(Attempt to initiate a new Adaptive Server operation with results pending|The request failed to run because the batch is aborted, this can be caused by abort signal sent from client|Adaptive Server connection timed out)/
|
139
|
-
Sequel::Deprecation.deprecate_constant(self, :TINYTDS_DISCONNECT_ERRORS)
|
140
|
-
|
141
134
|
# Return true if the :conn argument is present and not active.
|
142
135
|
def disconnect_error?(e, opts)
|
143
136
|
super || (opts[:conn] && !opts[:conn].active?) || ((e.is_a?(::TinyTds::Error) && /\A(Attempt to initiate a new Adaptive Server operation with results pending|The request failed to run because the batch is aborted, this can be caused by abort signal sent from client|Adaptive Server connection timed out)/.match(e.message)))
|
@@ -185,9 +178,6 @@ module Sequel
|
|
185
178
|
class Dataset < Sequel::Dataset
|
186
179
|
include Sequel::MSSQL::DatasetMethods
|
187
180
|
|
188
|
-
Database::DatasetClass = self
|
189
|
-
Sequel::Deprecation.deprecate_constant(Database, :DatasetClass)
|
190
|
-
|
191
181
|
module ArgumentMapper
|
192
182
|
include Sequel::Dataset::ArgumentMapper
|
193
183
|
|
@@ -213,10 +203,10 @@ module Sequel
|
|
213
203
|
|
214
204
|
PreparedStatementMethods = prepared_statements_module("sql = prepared_sql; opts = Hash[opts]; opts[:arguments] = bind_arguments", ArgumentMapper)
|
215
205
|
|
216
|
-
# Yield hashes with symbol keys, attempting to optimize for
|
217
|
-
# various cases.
|
218
206
|
def fetch_rows(sql)
|
219
207
|
execute(sql) do |result|
|
208
|
+
# Mutating an array in the result is questionable, but supported
|
209
|
+
# by tiny_tds developers (tiny_tds issue #57)
|
220
210
|
columns = result.fields.map!{|c| output_identifier(c)}
|
221
211
|
if columns.empty?
|
222
212
|
args = []
|
@@ -247,7 +237,7 @@ module Sequel
|
|
247
237
|
|
248
238
|
private
|
249
239
|
|
250
|
-
# Properly escape the given string
|
240
|
+
# Properly escape the given string
|
251
241
|
def literal_string_append(sql, v)
|
252
242
|
sql << (mssql_unicode_strings ? "N'" : "'")
|
253
243
|
sql << db.synchronize(@opts[:server]){|c| c.escape(v)}.gsub(/\\((?:\r\n)|\n)/, '\\\\\\\\\\1\\1') << "'"
|
@@ -7,7 +7,7 @@ module Sequel
|
|
7
7
|
# when ordering.
|
8
8
|
def empty?
|
9
9
|
return super unless emulate_offset_with_row_number?
|
10
|
-
|
10
|
+
select(Dataset::EMPTY_SELECT).limit(1).single_value!.nil?
|
11
11
|
end
|
12
12
|
|
13
13
|
# Emulate OFFSET support with the ROW_NUMBER window function
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative '../shared/mysql'
|
4
|
+
require_relative 'stored_procedures'
|
4
5
|
|
5
6
|
module Sequel
|
6
7
|
module MySQL
|
@@ -47,9 +48,6 @@ module Sequel
|
|
47
48
|
conn.prepared_statements = {}
|
48
49
|
end
|
49
50
|
|
50
|
-
# Stupid MySQL doesn't use SQLState error codes correctly, mapping
|
51
|
-
# all constraint violations to 23000 even though it recognizes
|
52
|
-
# different types.
|
53
51
|
def database_specific_error_class(exception, opts)
|
54
52
|
case exception.errno
|
55
53
|
when 1048
|
@@ -8,10 +8,9 @@ module Sequel
|
|
8
8
|
|
9
9
|
# Executes a prepared statement on an available connection. If the
|
10
10
|
# prepared statement already exists for the connection and has the same
|
11
|
-
# SQL, reuse it, otherwise, prepare the new statement.
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# arguments.
|
11
|
+
# SQL, reuse it, otherwise, prepare the new statement. Issue a SET
|
12
|
+
# query with literalized values for each argument, then an EXECUTE to
|
13
|
+
# execute the query with the arguments.
|
15
14
|
def execute_prepared_statement(ps_name, opts, &block)
|
16
15
|
args = opts[:arguments]
|
17
16
|
ps = prepared_statement(ps_name)
|
@@ -30,8 +29,6 @@ module Sequel
|
|
30
29
|
end
|
31
30
|
|
32
31
|
module DatasetMethods
|
33
|
-
# Methods to add to MySQL prepared statement calls without using a
|
34
|
-
# real database prepared statement and bound variables.
|
35
32
|
module CallableStatementMethods
|
36
33
|
# Extend given dataset with this module so subselects inside subselects in
|
37
34
|
# prepared statements work.
|
@@ -3,11 +3,6 @@
|
|
3
3
|
module Sequel
|
4
4
|
class Dataset
|
5
5
|
module Replace
|
6
|
-
INSERT = 'INSERT'.freeze
|
7
|
-
Sequel::Deprecation.deprecate_constant(self, :INSERT)
|
8
|
-
REPLACE = 'REPLACE'.freeze
|
9
|
-
Sequel::Deprecation.deprecate_constant(self, :REPLACE)
|
10
|
-
|
11
6
|
# Execute a REPLACE statement on the database (deletes any duplicate
|
12
7
|
# rows before inserting).
|
13
8
|
def replace(*values)
|
@@ -55,7 +55,7 @@ module Sequel
|
|
55
55
|
end
|
56
56
|
SQL::Function.new!(o.name, v(o.args), h)
|
57
57
|
when SQL::Subscript
|
58
|
-
SQL::Subscript.new(v(o.
|
58
|
+
SQL::Subscript.new(v(o.expression), v(o.sub))
|
59
59
|
when SQL::Window
|
60
60
|
opts = o.opts.dup
|
61
61
|
opts[:partition] = v(opts[:partition]) if opts[:partition]
|
@@ -90,15 +90,8 @@ module Sequel
|
|
90
90
|
# in the dataset are qualified with a given table name.
|
91
91
|
class Qualifier < ASTTransformer
|
92
92
|
# Set the table used to qualify unqualified columns
|
93
|
-
def initialize(table
|
94
|
-
|
95
|
-
# :nocov:
|
96
|
-
Sequel::Deprecation.deprecate("Passing two arguments to Sequel::Qualifier.new", 'Pass only the second argument specifying the table used for qualification')
|
97
|
-
@table = unused
|
98
|
-
# :nocov:
|
99
|
-
else
|
100
|
-
@table = table
|
101
|
-
end
|
93
|
+
def initialize(table)
|
94
|
+
@table = table
|
102
95
|
end
|
103
96
|
|
104
97
|
private
|
@@ -128,88 +121,4 @@ module Sequel
|
|
128
121
|
end
|
129
122
|
end
|
130
123
|
end
|
131
|
-
|
132
|
-
# +Unbinder+ is used to take a dataset filter and return a modified version
|
133
|
-
# that unbinds already bound values and returns a dataset with bound value
|
134
|
-
# placeholders and a hash of bind values. You can then prepare the dataset
|
135
|
-
# and use the bound variables to execute it with the same values.
|
136
|
-
#
|
137
|
-
# This class only does a limited form of unbinding where the variable names
|
138
|
-
# and values can be associated unambiguously. The only cases it handles
|
139
|
-
# are <tt>SQL::ComplexExpression<tt> with an operator in +UNBIND_OPS+, a
|
140
|
-
# first argument that's an instance of a member of +UNBIND_KEY_CLASSES+, and
|
141
|
-
# a second argument that's an instance of a member of +UNBIND_VALUE_CLASSES+.
|
142
|
-
#
|
143
|
-
# So it can handle cases like:
|
144
|
-
#
|
145
|
-
# DB.where(:a=>1).exclude(:b=>2).where{c > 3}
|
146
|
-
#
|
147
|
-
# But it cannot handle cases like:
|
148
|
-
#
|
149
|
-
# DB.where(:a + 1 < 0)
|
150
|
-
class Unbinder < ASTTransformer
|
151
|
-
# The <tt>SQL::ComplexExpression<tt> operates that will be considered
|
152
|
-
# for transformation.
|
153
|
-
UNBIND_OPS = [:'=', :'!=', :<, :>, :<=, :>=]
|
154
|
-
|
155
|
-
# The key classes (first argument of the ComplexExpression) that will
|
156
|
-
# considered for transformation.
|
157
|
-
UNBIND_KEY_CLASSES = [Symbol, SQL::Identifier, SQL::QualifiedIdentifier]
|
158
|
-
|
159
|
-
# The value classes (second argument of the ComplexExpression) that
|
160
|
-
# will be considered for transformation.
|
161
|
-
UNBIND_VALUE_CLASSES = [Numeric, String, Date, Time]
|
162
|
-
|
163
|
-
# The hash of bind variables that were extracted from the dataset filter.
|
164
|
-
attr_reader :binds
|
165
|
-
|
166
|
-
# Intialize an empty +binds+ hash.
|
167
|
-
def initialize
|
168
|
-
Sequel::Deprecation.deprecate("Sequel::Unbinder", 'There is no replacement')
|
169
|
-
@binds = {}
|
170
|
-
end
|
171
|
-
|
172
|
-
private
|
173
|
-
|
174
|
-
# Create a suitable bound variable key for the object, which should be
|
175
|
-
# an instance of one of the +UNBIND_KEY_CLASSES+.
|
176
|
-
def bind_key(obj)
|
177
|
-
case obj
|
178
|
-
when Symbol
|
179
|
-
obj
|
180
|
-
when String
|
181
|
-
obj.to_sym
|
182
|
-
when SQL::Identifier
|
183
|
-
bind_key(obj.value)
|
184
|
-
when SQL::QualifiedIdentifier
|
185
|
-
:"#{bind_key(obj.table)}.#{bind_key(obj.column)}"
|
186
|
-
else
|
187
|
-
raise Error, "unhandled object in Sequel::Unbinder#bind_key: #{obj}"
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
# Handle <tt>SQL::ComplexExpression</tt> instances with suitable ops
|
192
|
-
# and arguments, substituting the value with a bound variable placeholder
|
193
|
-
# and assigning it an entry in the +binds+ hash with a matching key.
|
194
|
-
def v(o)
|
195
|
-
if o.is_a?(SQL::ComplexExpression) && UNBIND_OPS.include?(o.op)
|
196
|
-
l, r = o.args
|
197
|
-
l = l.value if l.is_a?(Sequel::SQL::Wrapper)
|
198
|
-
r = r.value if r.is_a?(Sequel::SQL::Wrapper)
|
199
|
-
if UNBIND_KEY_CLASSES.any?{|c| l.is_a?(c)} && UNBIND_VALUE_CLASSES.any?{|c| r.is_a?(c)} && !r.is_a?(LiteralString)
|
200
|
-
key = bind_key(l)
|
201
|
-
if (old = binds[key]) && old != r
|
202
|
-
raise UnbindDuplicate, "two different values for #{key.inspect}: #{[r, old].inspect}"
|
203
|
-
end
|
204
|
-
binds[key] = r
|
205
|
-
SQL::ComplexExpression.new(o.op, l, :"$#{key}")
|
206
|
-
else
|
207
|
-
super
|
208
|
-
end
|
209
|
-
else
|
210
|
-
super
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
Sequel::Deprecation.deprecate_constant(self, :Unbinder)
|
215
124
|
end
|
@@ -26,19 +26,13 @@
|
|
26
26
|
# specified by the array of symbols.
|
27
27
|
class Sequel::ConnectionPool
|
28
28
|
OPTS = Sequel::OPTS
|
29
|
+
POOL_CLASS_MAP = {
|
30
|
+
:threaded => :ThreadedConnectionPool,
|
31
|
+
:single => :SingleConnectionPool,
|
32
|
+
:sharded_threaded => :ShardedThreadedConnectionPool,
|
33
|
+
:sharded_single => :ShardedSingleConnectionPool
|
34
|
+
}.freeze
|
29
35
|
|
30
|
-
# The default server to use
|
31
|
-
DEFAULT_SERVER = :default
|
32
|
-
Sequel::Deprecation.deprecate_constant(self, :DEFAULT_SERVER)
|
33
|
-
|
34
|
-
# A map of [single threaded, sharded] values to symbols or ConnectionPool subclasses.
|
35
|
-
CONNECTION_POOL_MAP = {[true, false] => :single,
|
36
|
-
[true, true] => :sharded_single,
|
37
|
-
[false, false] => :threaded,
|
38
|
-
[false, true] => :sharded_threaded}
|
39
|
-
CONNECTION_POOL__MAP = CONNECTION_POOL_MAP
|
40
|
-
Sequel::Deprecation.deprecate_constant(self, :CONNECTION_POOL_MAP)
|
41
|
-
|
42
36
|
# Class methods used to return an appropriate pool subclass, separated
|
43
37
|
# into a module for easier overridding by extensions.
|
44
38
|
module ClassMethods
|
@@ -47,23 +41,33 @@ class Sequel::ConnectionPool
|
|
47
41
|
# use a new instance of an appropriate pool subclass based on the
|
48
42
|
# <tt>:single_threaded</tt> and <tt>:servers</tt> options.
|
49
43
|
def get_pool(db, opts = OPTS)
|
50
|
-
|
51
|
-
when Class
|
52
|
-
v.new(db, opts)
|
53
|
-
when Symbol
|
54
|
-
require("sequel/connection_pool/#{v}")
|
55
|
-
connection_pool_class(opts).new(db, opts) || raise(Sequel::Error, "No connection pool class found")
|
56
|
-
end
|
44
|
+
connection_pool_class(opts).new(db, opts)
|
57
45
|
end
|
58
46
|
|
59
47
|
private
|
60
48
|
|
61
49
|
# Return a connection pool class based on the given options.
|
62
50
|
def connection_pool_class(opts)
|
63
|
-
if
|
64
|
-
|
51
|
+
if pc = opts[:pool_class]
|
52
|
+
unless pc.is_a?(Class)
|
53
|
+
unless name = POOL_CLASS_MAP[pc]
|
54
|
+
raise Sequel::Error, "unsupported connection pool type, please pass appropriate class as the :pool_class option"
|
55
|
+
end
|
56
|
+
|
57
|
+
require_relative "connection_pool/#{pc}"
|
58
|
+
pc = Sequel.const_get(name)
|
59
|
+
end
|
60
|
+
|
61
|
+
pc
|
62
|
+
else
|
63
|
+
pc = if opts[:single_threaded]
|
64
|
+
opts[:servers] ? :sharded_single : :single
|
65
|
+
else
|
66
|
+
opts[:servers] ? :sharded_threaded : :threaded
|
67
|
+
end
|
68
|
+
|
69
|
+
connection_pool_class(:pool_class=>pc)
|
65
70
|
end
|
66
|
-
CONNECTION_POOL__MAP[opts[:pool_class]] || opts[:pool_class] || CONNECTION_POOL__MAP[[!!opts[:single_threaded], !!opts[:servers]]]
|
67
71
|
end
|
68
72
|
end
|
69
73
|
extend ClassMethods
|
@@ -93,12 +97,6 @@ class Sequel::ConnectionPool
|
|
93
97
|
@error_classes = db.send(:database_error_classes).dup.freeze
|
94
98
|
end
|
95
99
|
|
96
|
-
# Alias for +size+, not aliased directly for ease of subclass implementation
|
97
|
-
def created_count(*args)
|
98
|
-
Sequel::Deprecation.deprecate("Sequel::ConnectionPool#created_count", "Use #size instead")
|
99
|
-
size(*args)
|
100
|
-
end
|
101
|
-
|
102
100
|
# An array of symbols for all shards/servers, which is a single <tt>:default</tt> by default.
|
103
101
|
def servers
|
104
102
|
[:default]
|
@@ -66,8 +66,7 @@ class Sequel::ShardedSingleConnectionPool < Sequel::ConnectionPool
|
|
66
66
|
1
|
67
67
|
end
|
68
68
|
|
69
|
-
# Remove servers from the connection pool.
|
70
|
-
# or shard configurations. Similar to disconnecting from all given servers,
|
69
|
+
# Remove servers from the connection pool. Similar to disconnecting from all given servers,
|
71
70
|
# except that after it is used, future requests for the server will use the
|
72
71
|
# :default server instead.
|
73
72
|
def remove_servers(servers)
|
@@ -110,6 +109,4 @@ class Sequel::ShardedSingleConnectionPool < Sequel::ConnectionPool
|
|
110
109
|
def preconnect(concurrent = nil)
|
111
110
|
servers.each{|s| hold(s){}}
|
112
111
|
end
|
113
|
-
|
114
|
-
CONNECTION_POOL__MAP[[true, true]] = self
|
115
112
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'threaded'
|
4
4
|
|
5
5
|
# The slowest and most advanced connection, dealing with both multi-threaded
|
6
6
|
# access and configurations with multiple shards/servers.
|
@@ -20,18 +20,14 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
20
20
|
@available_connections = {}
|
21
21
|
@connections_to_remove = []
|
22
22
|
@servers = opts.fetch(:servers_hash, Hash.new(:default))
|
23
|
-
|
24
|
-
|
25
|
-
@waiter = nil
|
26
|
-
@waiters = {}
|
27
|
-
end
|
23
|
+
remove_instance_variable(:@waiter)
|
24
|
+
@waiters = {}
|
28
25
|
|
29
26
|
add_servers([:default])
|
30
27
|
add_servers(opts[:servers].keys) if opts[:servers]
|
31
28
|
end
|
32
29
|
|
33
|
-
# Adds new servers to the connection pool.
|
34
|
-
# or shard configurations. Allows for dynamic expansion of the potential slaves/shards
|
30
|
+
# Adds new servers to the connection pool. Allows for dynamic expansion of the potential slaves/shards
|
35
31
|
# at runtime. servers argument should be an array of symbols.
|
36
32
|
def add_servers(servers)
|
37
33
|
sync do
|
@@ -40,7 +36,7 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
40
36
|
@servers[server] = server
|
41
37
|
@available_connections[server] = []
|
42
38
|
@allocated[server] = {}
|
43
|
-
@waiters[server] = ConditionVariable.new
|
39
|
+
@waiters[server] = ConditionVariable.new
|
44
40
|
end
|
45
41
|
end
|
46
42
|
end
|
@@ -77,12 +73,11 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
77
73
|
@available_connections[server]
|
78
74
|
end
|
79
75
|
|
80
|
-
# The total number of connections opened for the given server
|
81
|
-
#
|
82
|
-
#
|
76
|
+
# The total number of connections opened for the given server.
|
77
|
+
# Nonexistent servers will return the created count of the default server.
|
78
|
+
# The calling code should not have the mutex before calling this.
|
83
79
|
def size(server=:default)
|
84
|
-
|
85
|
-
@allocated[server].length + @available_connections[server].length
|
80
|
+
@mutex.synchronize{_size(server)}
|
86
81
|
end
|
87
82
|
|
88
83
|
# Removes all connections currently available on all servers, optionally
|
@@ -120,8 +115,7 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
120
115
|
# If no connection is immediately available and the pool is already using the maximum
|
121
116
|
# number of connections, Pool#hold will block until a connection
|
122
117
|
# is available or the timeout expires. If the timeout expires before a
|
123
|
-
# connection can be acquired, a Sequel::PoolTimeout is
|
124
|
-
# raised.
|
118
|
+
# connection can be acquired, a Sequel::PoolTimeout is raised.
|
125
119
|
def hold(server=:default)
|
126
120
|
server = pick_server(server)
|
127
121
|
t = Thread.current
|
@@ -139,8 +133,7 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
139
133
|
end
|
140
134
|
end
|
141
135
|
|
142
|
-
# Remove servers from the connection pool.
|
143
|
-
# or shard configurations. Similar to disconnecting from all given servers,
|
136
|
+
# Remove servers from the connection pool. Similar to disconnecting from all given servers,
|
144
137
|
# except that after it is used, future requests for the server will use the
|
145
138
|
# :default server instead.
|
146
139
|
def remove_servers(servers)
|
@@ -150,7 +143,7 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
150
143
|
servers.each do |server|
|
151
144
|
if @servers.include?(server)
|
152
145
|
conns = disconnect_server_connections(server)
|
153
|
-
@waiters.delete(server)
|
146
|
+
@waiters.delete(server)
|
154
147
|
@available_connections.delete(server)
|
155
148
|
@allocated.delete(server)
|
156
149
|
@servers.delete(server)
|
@@ -174,71 +167,89 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
174
167
|
|
175
168
|
private
|
176
169
|
|
177
|
-
#
|
178
|
-
#
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
allocated(server)[thread] = conn
|
183
|
-
end
|
170
|
+
# The total number of connections opened for the given server.
|
171
|
+
# The calling code should already have the mutex before calling this.
|
172
|
+
def _size(server)
|
173
|
+
server = @servers[server]
|
174
|
+
@allocated[server].length + @available_connections[server].length
|
184
175
|
end
|
185
176
|
|
186
|
-
if
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
177
|
+
# Assigns a connection to the supplied thread, if one
|
178
|
+
# is available. The calling code should NOT already have the mutex when
|
179
|
+
# calling this.
|
180
|
+
#
|
181
|
+
# This should return a connection is one is available within the timeout,
|
182
|
+
# or nil if a connection could not be acquired within the timeout.
|
183
|
+
def acquire(thread, server)
|
184
|
+
if conn = assign_connection(thread, server)
|
185
|
+
return conn
|
186
|
+
end
|
187
|
+
|
188
|
+
time = Time.now
|
189
|
+
|
190
|
+
sync do
|
191
|
+
@waiters[server].wait(@mutex, @timeout)
|
192
|
+
if conn = next_available(server)
|
193
|
+
return(allocated(server)[thread] = conn)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
until conn = assign_connection(thread, server)
|
198
|
+
deadline ||= time + @timeout
|
199
|
+
current_time = Time.now
|
200
|
+
raise_pool_timeout(current_time - time, server) if current_time > deadline
|
201
|
+
# :nocov:
|
202
|
+
# It's difficult to get to this point, it can only happen if there is a race condition
|
203
|
+
# where a connection cannot be acquired even after the thread is signalled by the condition
|
194
204
|
sync do
|
195
|
-
|
196
|
-
|
205
|
+
@waiters[server].wait(@mutex, deadline - current_time)
|
206
|
+
if conn = next_available(server)
|
207
|
+
return(allocated(server)[thread] = conn)
|
197
208
|
end
|
209
|
+
end
|
210
|
+
# :nocov:
|
211
|
+
end
|
212
|
+
|
213
|
+
conn
|
214
|
+
end
|
198
215
|
|
199
|
-
|
200
|
-
|
201
|
-
|
216
|
+
# Assign a connection to the thread, or return nil if one cannot be assigned.
|
217
|
+
# The caller should NOT have the mutex before calling this.
|
218
|
+
def assign_connection(thread, server)
|
219
|
+
alloc = allocated(server)
|
202
220
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
end
|
221
|
+
do_make_new = false
|
222
|
+
sync do
|
223
|
+
if conn = next_available(server)
|
224
|
+
alloc[thread] = conn
|
225
|
+
return conn
|
226
|
+
end
|
227
|
+
|
228
|
+
if (n = _size(server)) >= (max = @max_size)
|
229
|
+
alloc.to_a.each{|t,c| release(t, c, server) unless t.alive?}
|
230
|
+
n = nil
|
231
|
+
end
|
215
232
|
|
216
|
-
|
233
|
+
if (n || _size(server)) < max
|
234
|
+
do_make_new = alloc[thread] = true
|
217
235
|
end
|
218
236
|
end
|
219
|
-
|
220
|
-
#
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
237
|
+
|
238
|
+
# Connect to the database outside of the connection pool mutex,
|
239
|
+
# as that can take a long time and the connection pool mutex
|
240
|
+
# shouldn't be locked while the connection takes place.
|
241
|
+
if do_make_new
|
242
|
+
begin
|
243
|
+
conn = make_new(server)
|
244
|
+
sync{alloc[thread] = conn}
|
245
|
+
ensure
|
246
|
+
unless conn
|
247
|
+
sync{alloc.delete(thread)}
|
230
248
|
end
|
231
249
|
end
|
232
|
-
conn
|
233
250
|
end
|
234
|
-
# :nocov:
|
235
|
-
end
|
236
251
|
|
237
|
-
|
238
|
-
# available, tries to create a new connection. The calling code should already
|
239
|
-
# have the mutex before calling this.
|
240
|
-
def available(server)
|
241
|
-
next_available(server) || make_new(server)
|
252
|
+
conn
|
242
253
|
end
|
243
254
|
|
244
255
|
# Return a connection to the pool of available connections for the server,
|
@@ -246,10 +257,7 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
246
257
|
# before calling this.
|
247
258
|
def checkin_connection(server, conn)
|
248
259
|
available_connections(server) << conn
|
249
|
-
|
250
|
-
@waiters[server].signal
|
251
|
-
Thread.pass
|
252
|
-
end
|
260
|
+
@waiters[server].signal
|
253
261
|
conn
|
254
262
|
end
|
255
263
|
|
@@ -263,29 +271,18 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
263
271
|
if dis_conns = available_connections(server)
|
264
272
|
conns = dis_conns.dup
|
265
273
|
dis_conns.clear
|
274
|
+
@waiters[server].signal
|
266
275
|
end
|
267
276
|
conns
|
268
277
|
end
|
269
278
|
|
270
|
-
# Disconnect all
|
271
|
-
# immediately, and schedules currently allocated connections for disconnection
|
279
|
+
# Disconnect all available connections immediately, and schedule currently allocated connections for disconnection
|
272
280
|
# as soon as they are returned to the pool. The calling code should not
|
273
281
|
# have the mutex before calling this.
|
274
282
|
def disconnect_connections(conns)
|
275
283
|
conns.each{|conn| disconnect_connection(conn)}
|
276
284
|
end
|
277
285
|
|
278
|
-
# Creates a new connection to the given server if the size of the pool for
|
279
|
-
# the server is less than the maximum size of the pool. The calling code
|
280
|
-
# should already have the mutex before calling this.
|
281
|
-
def make_new(server)
|
282
|
-
if (n = size(server)) >= @max_size
|
283
|
-
allocated(server).to_a.each{|t, c| release(t, c, server) unless t.alive?}
|
284
|
-
n = nil
|
285
|
-
end
|
286
|
-
default_make_new(server) if (n || size(server)) < @max_size
|
287
|
-
end
|
288
|
-
|
289
286
|
# Return the next available connection in the pool for the given server, or nil
|
290
287
|
# if there is not currently an available connection for the server.
|
291
288
|
# The calling code should already have the mutex before calling this.
|
@@ -309,17 +306,20 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
309
306
|
sync{@servers[server]}
|
310
307
|
end
|
311
308
|
|
312
|
-
# Create the maximum number of connections
|
309
|
+
# Create the maximum number of connections immediately. The calling code should
|
310
|
+
# NOT have the mutex before calling this.
|
313
311
|
def preconnect(concurrent = false)
|
314
|
-
conn_servers = @servers.keys.map{|s| Array.new(max_size -
|
312
|
+
conn_servers = @servers.keys.map!{|s| Array.new(max_size - _size(s), s)}.flatten!
|
315
313
|
|
316
314
|
if concurrent
|
317
|
-
conn_servers.map{|s| Thread.new{[s, make_new(s)]}}.map(&:
|
315
|
+
conn_servers.map!{|s| Thread.new{[s, make_new(s)]}}.map!(&:value)
|
318
316
|
else
|
319
|
-
conn_servers.
|
317
|
+
conn_servers.map!{|s| [s, make_new(s)]}
|
320
318
|
end
|
319
|
+
|
320
|
+
sync{conn_servers.each{|s, conn| checkin_connection(s, conn)}}
|
321
321
|
end
|
322
|
-
|
322
|
+
|
323
323
|
# Raise a PoolTimeout error showing the current timeout, the elapsed time, the server
|
324
324
|
# the connection attempt was made to, and the database's name (if any).
|
325
325
|
def raise_pool_timeout(elapsed, server)
|
@@ -343,6 +343,10 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
343
343
|
checkin_connection(server, conn)
|
344
344
|
end
|
345
345
|
end
|
346
|
+
|
347
|
+
if waiter = @waiters[server]
|
348
|
+
waiter.signal
|
349
|
+
end
|
346
350
|
end
|
347
351
|
|
348
352
|
# Removes the currently allocated connection from the connection pool. The
|
@@ -352,6 +356,4 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
352
356
|
allocated(server).delete(thread) if @servers.include?(server)
|
353
357
|
disconnect_connection(conn)
|
354
358
|
end
|
355
|
-
|
356
|
-
CONNECTION_POOL__MAP[[false, true]] = self
|
357
359
|
end
|