sequel 4.49.0 → 5.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +130 -0
- data/README.rdoc +195 -136
- data/Rakefile +26 -42
- data/bin/sequel +6 -9
- data/doc/advanced_associations.rdoc +91 -168
- 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/release_notes/5.1.0.txt +31 -0
- data/doc/release_notes/5.2.0.txt +33 -0
- data/doc/release_notes/5.3.0.txt +121 -0
- data/doc/schema_modification.rdoc +78 -64
- data/doc/security.rdoc +97 -88
- data/doc/sharding.rdoc +43 -30
- data/doc/sql.rdoc +53 -65
- data/doc/testing.rdoc +4 -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/adapters/ado/access.rb +7 -13
- data/lib/sequel/adapters/ado/mssql.rb +2 -9
- data/lib/sequel/adapters/ado.rb +9 -25
- data/lib/sequel/adapters/amalgalite.rb +3 -18
- data/lib/sequel/adapters/ibmdb.rb +9 -45
- 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 +6 -26
- data/lib/sequel/adapters/jdbc/hsqldb.rb +2 -27
- 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 +11 -15
- data/lib/sequel/adapters/jdbc/oracle.rb +4 -26
- data/lib/sequel/adapters/jdbc/postgresql.rb +23 -33
- 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/jdbc.rb +18 -74
- 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/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/odbc.rb +0 -19
- data/lib/sequel/adapters/oracle.rb +8 -13
- data/lib/sequel/adapters/postgres.rb +28 -150
- 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 +61 -227
- data/lib/sequel/adapters/shared/oracle.rb +13 -41
- data/lib/sequel/adapters/shared/postgres.rb +58 -264
- data/lib/sequel/adapters/shared/sqlanywhere.rb +4 -96
- data/lib/sequel/adapters/shared/sqlite.rb +22 -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 +4 -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/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/connection_pool.rb +38 -28
- data/lib/sequel/core.rb +42 -101
- 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 +36 -55
- data/lib/sequel/database/query.rb +8 -13
- data/lib/sequel/database/schema_generator.rb +93 -64
- data/lib/sequel/database/schema_methods.rb +61 -79
- data/lib/sequel/database/transactions.rb +4 -24
- data/lib/sequel/database.rb +12 -2
- data/lib/sequel/dataset/actions.rb +57 -107
- data/lib/sequel/dataset/dataset_module.rb +4 -16
- data/lib/sequel/dataset/features.rb +35 -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 +91 -161
- data/lib/sequel/dataset/sql.rb +33 -225
- data/lib/sequel/dataset.rb +18 -10
- 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 +27 -43
- 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_extended_date_support.rb +230 -0
- 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 +3 -16
- 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/extensions/synchronize_sql.rb +45 -0
- data/lib/sequel/model/associations.rb +129 -131
- data/lib/sequel/model/base.rb +133 -731
- 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/model.rb +27 -62
- 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 -23
- data/lib/sequel/version.rb +2 -2
- data/lib/sequel.rb +1 -1
- 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 +111 -478
- data/spec/adapters/oracle_spec.rb +1 -9
- data/spec/adapters/postgres_spec.rb +459 -664
- 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 +96 -244
- data/spec/core/dataset_spec.rb +99 -414
- data/spec/core/deprecated_spec.rb +3 -3
- data/spec/core/expression_filters_spec.rb +37 -144
- data/spec/core/mock_adapter_spec.rb +241 -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 +88 -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 +30 -92
- 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 +53 -1118
- 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 +8 -30
- 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 +5 -6
- data/spec/extensions/looser_typecasting_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +25 -33
- data/spec/extensions/migration_spec.rb +12 -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 +2 -2
- data/spec/extensions/pagination_spec.rb +1 -1
- data/spec/extensions/pg_array_associations_spec.rb +22 -26
- 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_extended_date_support_spec.rb +122 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +1 -1
- data/spec/extensions/pg_hstore_spec.rb +22 -31
- 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 +7 -7
- data/spec/extensions/prepared_statements_spec.rb +13 -48
- data/spec/extensions/pretty_table_spec.rb +40 -9
- data/spec/extensions/query_spec.rb +1 -12
- data/spec/extensions/rcte_tree_spec.rb +23 -34
- 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 +43 -32
- 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 +5 -17
- 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/synchronize_sql_spec.rb +124 -0
- 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 +5 -7
- 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 +12 -16
- 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 -13
- 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 +8 -13
- 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 +12 -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 +7 -23
- data/spec/integration/prepared_statement_test.rb +8 -88
- data/spec/integration/schema_test.rb +10 -10
- data/spec/integration/spec_helper.rb +17 -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 +43 -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 +48 -17
- data/spec/model/hooks_spec.rb +5 -300
- data/spec/model/inflector_spec.rb +1 -1
- data/spec/model/model_spec.rb +29 -339
- data/spec/model/plugins_spec.rb +2 -16
- data/spec/model/record_spec.rb +33 -129
- data/spec/model/spec_helper.rb +5 -15
- data/spec/model/validations_spec.rb +1 -1
- data/spec/sequel_warning.rb +1 -12
- metadata +19 -65
- data/doc/active_record.rdoc +0 -927
- data/lib/sequel/adapters/cubrid.rb +0 -160
- 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/do.rb +0 -166
- 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/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/swift.rb +0 -169
- 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
data/doc/sharding.rdoc
CHANGED
@@ -13,7 +13,7 @@ option. Using the :servers database option makes Sequel use a connection pool
|
|
13
13
|
class that supports sharding, and the minimum required to enable sharding
|
14
14
|
support is to use the empty hash:
|
15
15
|
|
16
|
-
DB=Sequel.connect('postgres://master_server/database', :
|
16
|
+
DB=Sequel.connect('postgres://master_server/database', servers: {})
|
17
17
|
|
18
18
|
In most cases, you are probably not going to want to use an empty hash. Keys in the server hash are
|
19
19
|
not restricted to type, but the general recommendation is to use a symbol
|
@@ -35,8 +35,8 @@ tables you are accessing, unless you really know what you are doing.
|
|
35
35
|
To use a single, read-only slave that handles SELECT queries, the following
|
36
36
|
is the simplest configuration:
|
37
37
|
|
38
|
-
DB=Sequel.connect('postgres://master_server/database',
|
39
|
-
:
|
38
|
+
DB=Sequel.connect('postgres://master_server/database',
|
39
|
+
servers: {read_only: {host: 'slave_server'}})
|
40
40
|
|
41
41
|
This will use the slave_server for SELECT queries and master_server for
|
42
42
|
other queries.
|
@@ -48,8 +48,8 @@ the symbol name defined in the connect options. For example:
|
|
48
48
|
# Force the SELECT to run on the master
|
49
49
|
DB[:users].server(:default).all
|
50
50
|
|
51
|
-
# Force the
|
52
|
-
DB[:users].server(:read_only).
|
51
|
+
# Force the DELETE to run on the read-only slave
|
52
|
+
DB[:users].server(:read_only).delete
|
53
53
|
|
54
54
|
=== Multiple Read-Only Slaves, Single Master
|
55
55
|
|
@@ -59,13 +59,13 @@ slave_server1, slave_server2, and slave_server3.
|
|
59
59
|
num_read_only = 4
|
60
60
|
read_only_host = rand(num_read_only)
|
61
61
|
read_only_proc = proc do |db|
|
62
|
-
{:
|
62
|
+
{host: "slave_server#{(read_only_host+=1) % num_read_only}"}
|
63
63
|
end
|
64
|
-
DB=Sequel.connect('postgres://master_server/database',
|
65
|
-
:
|
64
|
+
DB=Sequel.connect('postgres://master_server/database',
|
65
|
+
servers: {read_only: read_only_proc})
|
66
66
|
|
67
67
|
This will use one of the slave servers for SELECT queries and use the
|
68
|
-
|
68
|
+
master server for other queries. It's also possible to pick a random host
|
69
69
|
instead of using the round robin approach presented above, but that can result
|
70
70
|
in less optimal resource usage.
|
71
71
|
|
@@ -78,15 +78,15 @@ it shows that the master database is named :default. So for 4 masters and
|
|
78
78
|
num_read_only = 4
|
79
79
|
read_only_host = rand(num_read_only)
|
80
80
|
read_only_proc = proc do |db|
|
81
|
-
{:
|
81
|
+
{host: "slave_server#{(read_only_host+=1) % num_read_only}"}
|
82
82
|
end
|
83
83
|
num_default = 4
|
84
84
|
default_host = rand(num_default)
|
85
85
|
default_proc = proc do |db|
|
86
|
-
{:
|
86
|
+
{host: "master_server#{(default_host+=1) % num_default}"}
|
87
87
|
end
|
88
|
-
DB=Sequel.connect('postgres://master_server/database',
|
89
|
-
:
|
88
|
+
DB=Sequel.connect('postgres://master_server/database',
|
89
|
+
servers: {default: default_proc, read_only: read_only_proc})
|
90
90
|
|
91
91
|
== Sharding
|
92
92
|
|
@@ -100,16 +100,16 @@ of 16 shards). First, you need to configure the database:
|
|
100
100
|
|
101
101
|
servers = {}
|
102
102
|
(('0'..'9').to_a + ('a'..'f').to_a).each do |hex|
|
103
|
-
servers[hex.to_sym] = {:
|
103
|
+
servers[hex.to_sym] = {host: "hash_host_#{hex}"}
|
104
104
|
end
|
105
|
-
DB=Sequel.connect('postgres://hash_host/hashes', :servers
|
105
|
+
DB=Sequel.connect('postgres://hash_host/hashes', servers: servers)
|
106
106
|
|
107
107
|
This configures 17 servers, the 16 shard servers (/hash_host_[0-9a-f]/), and 1
|
108
108
|
default server which will be used if no shard is specified ("hash_host"). If
|
109
109
|
you want the default server to be one of the shard servers (e.g. hash_host_a),
|
110
110
|
it's easiest to do:
|
111
111
|
|
112
|
-
DB=Sequel.connect('postgres://hash_host_a/hashes', :servers
|
112
|
+
DB=Sequel.connect('postgres://hash_host_a/hashes', servers: servers)
|
113
113
|
|
114
114
|
That will still set up a second pool of connections for the default server,
|
115
115
|
since it considers the default server and shard servers independent. Note that
|
@@ -120,7 +120,7 @@ schemas, so you should always have a default server that works.
|
|
120
120
|
|
121
121
|
To set the shard for a given query, you use the Dataset#server method:
|
122
122
|
|
123
|
-
DB[:hashes].server(:a).where(:
|
123
|
+
DB[:hashes].server(:a).where(hash: /31337/)
|
124
124
|
|
125
125
|
That will return all matching rows on the hash_host_a shard that have a hash
|
126
126
|
column that contains 31337.
|
@@ -133,7 +133,7 @@ the shard to use. This is fairly easy using a Sequel::Model:
|
|
133
133
|
dataset_module do
|
134
134
|
def plaintext_for_hash(hash)
|
135
135
|
raise(ArgumentError, 'Invalid SHA-1 Hash') unless /\A[0-9a-f]{40}\z/.match(hash)
|
136
|
-
server(hash[0...1].to_sym).where(:hash
|
136
|
+
server(hash[0...1].to_sym).where(hash: hash).get(:plaintext)
|
137
137
|
end
|
138
138
|
end
|
139
139
|
end
|
@@ -146,24 +146,24 @@ to assume the :default shard. However, you can specify a
|
|
146
146
|
different shard using the :servers_hash option when connecting
|
147
147
|
to the database:
|
148
148
|
|
149
|
-
DB = Sequel.connect('postgres://...', :
|
149
|
+
DB = Sequel.connect('postgres://...', servers_hash: Hash.new(:some_shard))
|
150
150
|
|
151
151
|
You can also use this feature to raise an exception if an
|
152
152
|
unconfigured shard is used:
|
153
153
|
|
154
|
-
DB = Sequel.connect('postgres://...', :
|
154
|
+
DB = Sequel.connect('postgres://...', servers_hash: Hash.new{raise 'foo'})
|
155
155
|
|
156
156
|
If you specify a :servers_hash option to raise an exception for non configured
|
157
157
|
shards you should also explicitly specify a :read_only entry in your :servers option
|
158
158
|
for the case where a shard is not specified. In most cases it is sufficient
|
159
159
|
to make the :read_only entry the same as the :default shard:
|
160
160
|
|
161
|
-
servers = {:
|
161
|
+
servers = {read_only: {}}
|
162
162
|
(('0'..'9').to_a + ('a'..'f').to_a).each do |hex|
|
163
|
-
servers[hex.to_sym] = {:
|
163
|
+
servers[hex.to_sym] = {host: "hash_host_#{hex}"}
|
164
164
|
end
|
165
|
-
DB=Sequel.connect('postgres://hash_host/hashes', :servers
|
166
|
-
:
|
165
|
+
DB=Sequel.connect('postgres://hash_host/hashes', servers: servers,
|
166
|
+
servers_hash: Hash.new{raise "Invalid Server"})
|
167
167
|
|
168
168
|
=== Sharding Plugin
|
169
169
|
|
@@ -176,7 +176,7 @@ work well with shards. You just need to remember to set to model to use the plu
|
|
176
176
|
plugin :sharding
|
177
177
|
end
|
178
178
|
|
179
|
-
Rainbow.server(:a).first(:
|
179
|
+
Rainbow.server(:a).first(id: 1).update(plaintext: 'VGM')
|
180
180
|
|
181
181
|
If all of your models are sharded, you can set all models to use the plugin via:
|
182
182
|
|
@@ -186,7 +186,7 @@ If all of your models are sharded, you can set all models to use the plugin via:
|
|
186
186
|
|
187
187
|
By default, you must specify the server/shard you want to use for every dataset/action,
|
188
188
|
or Sequel will use the default shard. If you have a group of queries that should use the
|
189
|
-
same shard, it can get a bit
|
189
|
+
same shard, it can get a bit redundant to specify the same shard for all of them.
|
190
190
|
|
191
191
|
The server_block extension adds a Database#with_server method that scopes all database
|
192
192
|
access inside the block to the given shard by default:
|
@@ -194,7 +194,7 @@ access inside the block to the given shard by default:
|
|
194
194
|
DB.extension :server_block
|
195
195
|
DB.with_server(:a) do
|
196
196
|
# this SELECT query uses the "a" shard
|
197
|
-
if r = Rainbow.first(:
|
197
|
+
if r = Rainbow.first(hash: /31337/)
|
198
198
|
r.count += 1
|
199
199
|
# this UPDATE query also uses the "a" shard
|
200
200
|
r.save
|
@@ -209,6 +209,19 @@ you retrieve the models inside the block and save them outside of the block. If
|
|
209
209
|
need to do that, call the server method explicitly on the dataset used to retrieve the
|
210
210
|
model objects.
|
211
211
|
|
212
|
+
The with_server method also supports a second argument for the default read_only server
|
213
|
+
to use, which can be useful if you are mixing sharding and master/slave servers:
|
214
|
+
|
215
|
+
DB.extension :server_block
|
216
|
+
DB.with_server(:a, :a_read_only) do
|
217
|
+
# this SELECT query uses the "a_read_only" shard
|
218
|
+
if r = Rainbow.first(hash: /31337/)
|
219
|
+
r.count += 1
|
220
|
+
# this UPDATE query also uses the "a" shard
|
221
|
+
r.save
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
212
225
|
=== arbitrary_servers Extension
|
213
226
|
|
214
227
|
By default, Sequel's sharding support is designed to work with predefined shards. It ships
|
@@ -220,13 +233,13 @@ The arbitrary_servers extension allows you to pass a server/shard options hash a
|
|
220
233
|
server to use, and those options will be merged directly into the database's default options:
|
221
234
|
|
222
235
|
DB.extension :arbitrary_servers
|
223
|
-
DB[:rainbows].server(:
|
236
|
+
DB[:rainbows].server(host: 'hash_host_a').all
|
224
237
|
# or
|
225
|
-
DB[:rainbows].server(:
|
238
|
+
DB[:rainbows].server(host: 'hash_host_b', database: 'backup').all
|
226
239
|
|
227
240
|
arbitrary_servers is designed to work well in conjunction with the server_block extension:
|
228
241
|
|
229
|
-
DB.with_server(:
|
242
|
+
DB.with_server(host: 'hash_host_b', database: 'backup') do
|
230
243
|
DB.synchronize do
|
231
244
|
# All queries here default to the backup database on hash_host_b
|
232
245
|
end
|
data/doc/sql.rdoc
CHANGED
@@ -22,7 +22,7 @@ For SELECT queries, you should probably use <tt>Database#fetch</tt> with a strin
|
|
22
22
|
|
23
23
|
You can also use named placeholders by starting the placeholder with a colon, and using a hash for the argument:
|
24
24
|
|
25
|
-
DB.fetch("SELECT * FROM albums WHERE name LIKE :pattern", :
|
25
|
+
DB.fetch("SELECT * FROM albums WHERE name LIKE :pattern", pattern: 'A%') do |row|
|
26
26
|
puts row[:name]
|
27
27
|
end
|
28
28
|
|
@@ -121,21 +121,15 @@ As you can see, Sequel quotes identifiers by default. Depending on your databas
|
|
121
121
|
|
122
122
|
:column # "COLUMN" on some databases
|
123
123
|
|
124
|
-
A plain symbol is usually treated as an unqualified identifier. However, if you are using multiple tables in a query, and you want to reference a column in one of the tables that has the same name as a column in another one of the tables, you need to qualify that reference.
|
125
|
-
|
126
|
-
:table__column # "table"."column"
|
127
|
-
|
128
|
-
This works by default, but it is possible to turn off by setting <tt>Sequel.split_symbols = false</tt>.
|
129
|
-
|
130
|
-
Note that you can't use a period to separate them:
|
124
|
+
A plain symbol is usually treated as an unqualified identifier. However, if you are using multiple tables in a query, and you want to reference a column in one of the tables that has the same name as a column in another one of the tables, you need to qualify that reference. Note that you can't use a period to separate them:
|
131
125
|
|
132
126
|
:table.column # calls the column method on the symbol
|
133
127
|
|
134
128
|
Also note that specifying the period inside the symbol doesn't work if you are quoting identifiers:
|
135
129
|
|
136
|
-
:"table.column" # "table.column"
|
130
|
+
:"table.column" # "table.column" instead of "table"."column"
|
137
131
|
|
138
|
-
The
|
132
|
+
There are a few different Sequel methods for creating qualified identifier objects. The recommended way is to explicitly create a qualified identifier by using <tt>Sequel.[]</tt> to create an identifier and call <tt>[]</tt> or +qualify+ on that, or by using the <tt>Sequel.qualify</tt> method with the table and column symbols:
|
139
133
|
|
140
134
|
Sequel[:table][:column] # "table"."column"
|
141
135
|
Sequel[:column].qualify(:table) # "table"."column"
|
@@ -148,6 +142,7 @@ Another way to generate identifiers is to use Sequel's {virtual row support}[rdo
|
|
148
142
|
|
149
143
|
You can also use the symbol_aref extension for creating qualified identifiers:
|
150
144
|
|
145
|
+
Sequel.extension :symbol_aref
|
151
146
|
:table[:column] # "table"."column"
|
152
147
|
|
153
148
|
=== Numbers
|
@@ -173,24 +168,16 @@ In general, Ruby strings map directly to SQL strings:
|
|
173
168
|
|
174
169
|
=== Aliasing
|
175
170
|
|
176
|
-
|
177
|
-
|
178
|
-
:column___alias # "column" AS "alias"
|
179
|
-
|
180
|
-
You can combine this with implicit qualification:
|
181
|
-
|
182
|
-
:table__column___alias # "table"."column" AS "alias"
|
183
|
-
|
184
|
-
As with creating qualified identifiers via a double underscore, this works by default, but it is possible to turn off by setting <tt>Sequel.split_symbols = false</tt>.
|
185
|
-
|
186
|
-
You can also use the <tt>Sequel.as</tt> method to create an alias, and the +as+ method on most Sequel-specific expression objects:
|
171
|
+
You can use the <tt>Sequel.as</tt> method to create an alias, and the +as+ method on most Sequel-specific expression objects:
|
187
172
|
|
188
173
|
Sequel.as(:column, :alias) # "column" AS "alias"
|
189
174
|
Sequel[:column].as(:alias) # "column" AS "alias"
|
190
175
|
Sequel[:table][:column].as(:alias) # "table"."column" AS "alias"
|
176
|
+
(Sequel[:column] + 1).as(:alias) # ("column" + 1) AS "alias"
|
191
177
|
|
192
178
|
You can also use the symbol_as extension for creating aliased identifiers:
|
193
179
|
|
180
|
+
Sequel.extension :symbol_as
|
194
181
|
:column.as(:alias) # "column" AS "alias"
|
195
182
|
|
196
183
|
If you want to use a derived column list, you can provide an array of column aliases:
|
@@ -215,11 +202,11 @@ Aggregate functions work the same way as normal functions, since they share the
|
|
215
202
|
|
216
203
|
Sequel.function(:sum, :column) # sum(column)
|
217
204
|
|
218
|
-
To use the DISTINCT modifier to an aggregate function, call the +distinct+ method on the function:
|
205
|
+
To use the DISTINCT modifier to an aggregate function, call the +distinct+ method on the function expression, which returns a new function expression:
|
219
206
|
|
220
207
|
DB[:albums].select{sum(:column).distinct} # SELECT sum(DISTINCT column) FROM albums
|
221
208
|
|
222
|
-
If you want to use the wildcard as the sole argument of the aggregate function, use the * method on the
|
209
|
+
If you want to use the wildcard as the sole argument of the aggregate function, use the * method on the function expression:
|
223
210
|
|
224
211
|
Sequel.function(:count).* # count(*)
|
225
212
|
DB[:albums].select{count.function.*} # SELECT count(*) FROM albums
|
@@ -228,10 +215,10 @@ Note that Sequel provides helper methods for aggregate functions such as +count+
|
|
228
215
|
|
229
216
|
=== Window Functions
|
230
217
|
|
231
|
-
If the database supports window functions, Sequel can handle them by calling the +over+ method on a
|
218
|
+
If the database supports window functions, Sequel can handle them by calling the +over+ method on a function expression:
|
232
219
|
|
233
|
-
DB[:albums].select{
|
234
|
-
# SELECT
|
220
|
+
DB[:albums].select{row_number.function.over}
|
221
|
+
# SELECT row_number() OVER () FROM albums
|
235
222
|
|
236
223
|
DB[:albums].select{count.function.*.over}
|
237
224
|
# SELECT count(*) OVER () FROM albums
|
@@ -244,12 +231,12 @@ If the database supports window functions, Sequel can handle them by calling the
|
|
244
231
|
|
245
232
|
=== Schema Qualified Functions
|
246
233
|
|
247
|
-
If the database supports schema qualified functions, Sequel can handle them by calling the +function+ method on a
|
234
|
+
If the database supports schema qualified functions, Sequel can handle them by calling the +function+ method on a qualified identifier:
|
248
235
|
|
249
236
|
DB[:albums].select{schema[:function].function}
|
250
237
|
# SELECT schema.function() FROM albums
|
251
238
|
|
252
|
-
DB[:albums].select{schema[:function].function(col, 2, "a")}
|
239
|
+
DB[:albums].select{schema[:function].function(:col, 2, "a")}
|
253
240
|
# SELECT schema.function(col, 2, 'a') FROM albums
|
254
241
|
|
255
242
|
=== Portable/Emulated Functions
|
@@ -265,7 +252,7 @@ Some examples are:
|
|
265
252
|
|
266
253
|
Sequel uses hashes to specify equality:
|
267
254
|
|
268
|
-
{:
|
255
|
+
{column: 1} # ("column" = 1)
|
269
256
|
|
270
257
|
You can also specify this as an array of two element arrays:
|
271
258
|
|
@@ -279,27 +266,27 @@ For expression objects, you can also use the =~ method:
|
|
279
266
|
|
280
267
|
You can specify a not equals condition by inverting the hash or array of two element arrays using <tt>Sequel.negate</tt> or <tt>Sequel.~</tt>:
|
281
268
|
|
282
|
-
Sequel.negate(:
|
269
|
+
Sequel.negate(column: 1) # ("column" != 1)
|
283
270
|
Sequel.negate([[:column, 1]]) # ("column" != 1)
|
284
|
-
Sequel.~(:
|
271
|
+
Sequel.~(column: 1) # ("column" != 1)
|
285
272
|
Sequel.~([[:column, 1]]) # ("column" != 1)
|
286
273
|
|
287
274
|
The difference between the two is that +negate+ only works on hashes and arrays of element arrays, and it negates all entries in the hash or array, while ~ does a general inversion. This is best shown by an example with multiple entries:
|
288
275
|
|
289
|
-
Sequel.negate(:
|
290
|
-
Sequel.~(:
|
276
|
+
Sequel.negate(column: 1, foo: 2) # (("column" != 1) AND (foo != 2))
|
277
|
+
Sequel.~(column: 1, foo: 2) # (("column" != 1) OR (foo != 2))
|
291
278
|
|
292
279
|
You can also use the ~ method on an equality expression:
|
293
280
|
|
294
281
|
where{~(column =~ 1)} # ("column" != 1)
|
295
282
|
|
296
|
-
|
283
|
+
Or you can use the !~ method:
|
297
284
|
|
298
285
|
where{column !~ 1} # ("column" != 1)
|
299
286
|
|
300
287
|
The most common need for not equals is in filters, in which case you can use the +exclude+ method:
|
301
288
|
|
302
|
-
DB[:albums].exclude(:
|
289
|
+
DB[:albums].exclude(column: 1) # SELECT * FROM "albums" WHERE ("column" != 1)
|
303
290
|
|
304
291
|
Note that +exclude+ does a generalized inversion, similar to <tt>Sequel.~</tt>.
|
305
292
|
|
@@ -307,19 +294,19 @@ Note that +exclude+ does a generalized inversion, similar to <tt>Sequel.~</tt>.
|
|
307
294
|
|
308
295
|
Sequel also uses hashes to specify inclusion, and inversions of those hashes to specify exclusion:
|
309
296
|
|
310
|
-
{:
|
311
|
-
Sequel.~(:
|
297
|
+
{column: [1, 2, 3]} # ("column" IN (1, 2, 3))
|
298
|
+
Sequel.~(column: [1, 2, 3]) # ("column" NOT IN (1, 2, 3))
|
312
299
|
|
313
300
|
As you may have guessed, Sequel switches from an = to an IN when the hash value is an array. It also does this for datasets, which easily allows you to test for inclusion and exclusion in a subselect:
|
314
301
|
|
315
|
-
{:
|
316
|
-
Sequel.~(:
|
302
|
+
{column: DB[:albums].select(:id)} # ("column" IN (SELECT "id" FROM "albums"))
|
303
|
+
Sequel.~(column: DB[:albums].select(:id)) # ("column" NOT IN (SELECT "id" FROM "albums"))
|
317
304
|
|
318
305
|
Similar to =, you can also use =~ with expressions for inclusion:
|
319
306
|
|
320
307
|
where{column =~ [1, 2, 3]} # ("column" IN (1, 2, 3))
|
321
308
|
|
322
|
-
and
|
309
|
+
and !~ for exclusion:
|
323
310
|
|
324
311
|
where{column !~ [1, 2, 3]} # ("column" NOT IN (1, 2, 3))
|
325
312
|
|
@@ -331,17 +318,17 @@ Sequel also supports the SQL EXISTS operator using <tt>Dataset#exists</tt>:
|
|
331
318
|
|
332
319
|
Hashes in Sequel use IS if the value is +true+, +false+, or +nil+:
|
333
320
|
|
334
|
-
{:
|
335
|
-
{:
|
336
|
-
{:
|
321
|
+
{column: nil} # ("column" IS NULL)
|
322
|
+
{column: true} # ("column" IS TRUE)
|
323
|
+
{column: false} # ("column" IS FALSE)
|
337
324
|
|
338
325
|
Negation works the same way as it does for equality and inclusion:
|
339
326
|
|
340
|
-
Sequel.~(:
|
341
|
-
Sequel.~(:
|
342
|
-
Sequel.~(:
|
327
|
+
Sequel.~(column: nil) # ("column" IS NOT NULL)
|
328
|
+
Sequel.~(column: true) # ("column" IS NOT TRUE)
|
329
|
+
Sequel.~(column: false) # ("column" IS NOT FALSE)
|
343
330
|
|
344
|
-
Likewise, =~ works for identity
|
331
|
+
Likewise, =~ works for identity and !~ for negative identity on expressions:
|
345
332
|
|
346
333
|
where{column =~ nil} # ("column" IS NULL)
|
347
334
|
where{column !~ nil} # ("column" IS NOT NULL)
|
@@ -354,7 +341,7 @@ Sequel's general inversion operator is ~, which works on symbols and most Sequel
|
|
354
341
|
|
355
342
|
Note that ~ will actually apply the inversion operation to the underlying object, which is why
|
356
343
|
|
357
|
-
Sequel.~(:
|
344
|
+
Sequel.~(column: 1)
|
358
345
|
|
359
346
|
produces <tt>(column != 1)</tt> instead of <tt>NOT (column = 1)</tt>.
|
360
347
|
|
@@ -367,7 +354,7 @@ Sequel defines the inequality operators directly on most Sequel-specific express
|
|
367
354
|
Sequel.function(:func) >= 1 # (func() >= 1)
|
368
355
|
Sequel.function(:func, :column) <= 1 # (func("column") <= 1)
|
369
356
|
|
370
|
-
If you want to use them on a symbol, you should call <tt>Sequel.[]</tt> with the symbol:
|
357
|
+
If you want to use them on a symbol, you should call <tt>Sequel.[]</tt> with the symbol to get an expression object:
|
371
358
|
|
372
359
|
Sequel[:column] > 1 # ("column" > 1)
|
373
360
|
|
@@ -403,7 +390,7 @@ Note that since Sequel implements support for Ruby's coercion protocol, the foll
|
|
403
390
|
Sequel defines the & and | methods on most Sequel-specific expression objects to handle AND and OR:
|
404
391
|
|
405
392
|
Sequel[:column1] & :column2 # ("column1" AND "column2")
|
406
|
-
Sequel[:
|
393
|
+
Sequel[{column1: 1}] | {column2: 2} # (("column1" = 1) OR ("column2" = 2))
|
407
394
|
(Sequel.function(:func) > 1) & :column3 # ((func() > 1) AND "column3")
|
408
395
|
|
409
396
|
Note the use of parentheses in the last statement. If you omit them, you won't get what you expect.
|
@@ -418,28 +405,28 @@ is parsed as:
|
|
418
405
|
You can also use the <tt>Sequel.&</tt> and <tt>Sequel.|</tt> methods:
|
419
406
|
|
420
407
|
Sequel.&(:column1, :column2) # ("column1" AND "column2")
|
421
|
-
Sequel.|({:
|
408
|
+
Sequel.|({column1: 1}, {column2: 2}) # (("column1" = 1) OR ("column2" = 2))
|
422
409
|
|
423
410
|
You can use hashes and arrays of two element arrays to specify AND and OR with equality conditions:
|
424
411
|
|
425
|
-
{:
|
412
|
+
{column1: 1, column2: 2} # (("column1" = 1) AND ("column2" = 2))
|
426
413
|
[[:column1, 1], [:column2, 2]] # (("column1" = 1) AND ("column2" = 2))
|
427
414
|
|
428
415
|
As you can see, these literalize with ANDs by default. You can use the <tt>Sequel.or</tt> method to use OR instead:
|
429
416
|
|
430
|
-
Sequel.or(:
|
417
|
+
Sequel.or(column1: 1, column2: 2) # (("column1" = 1) OR ("column2" = 2))
|
431
418
|
|
432
419
|
You've already seen the <tt>Sequel.negate</tt> method, which will use ANDs if multiple entries are used:
|
433
420
|
|
434
|
-
Sequel.negate(:
|
421
|
+
Sequel.negate(column1: 1, column2: 2) # (("column1" != 1) AND ("column2" != 2))
|
435
422
|
|
436
423
|
To negate while using ORs, the <tt>Sequel.~</tt> operator can be used:
|
437
424
|
|
438
|
-
Sequel.~(:
|
425
|
+
Sequel.~(column1: 1, column2: 2) # (("column1" != 1) OR ("column2" != 2))
|
439
426
|
|
440
427
|
Note again that <tt>Dataset#exclude</tt> uses ~, not +negate+:
|
441
428
|
|
442
|
-
DB[:albums].exclude(:
|
429
|
+
DB[:albums].exclude(column1: 1, column2: 2) # SELECT * FROM "albums" WHERE (("column" != 1) OR ("column2" != 2))
|
443
430
|
|
444
431
|
=== Casts
|
445
432
|
|
@@ -521,8 +508,8 @@ Sequel also supports SQL regular expressions on MySQL and PostgreSQL. You can u
|
|
521
508
|
|
522
509
|
Sequel.like(:name, /^A/) # ("name" ~ '^A')
|
523
510
|
~Sequel.ilike(:name, /^A/) # ("name" !~* '^A')
|
524
|
-
{:
|
525
|
-
Sequel.~(:
|
511
|
+
{name: /^A/i} # ("name" ~* '^A')
|
512
|
+
Sequel.~(name: /^A/) # ("name" !~ '^A')
|
526
513
|
|
527
514
|
Note that using +ilike+ with a regular expression will always make the regexp case insensitive. If you use +like+ or the hash with regexp value, it will only be case insensitive if the Regexp itself is case insensitive.
|
528
515
|
|
@@ -545,21 +532,22 @@ On some databases, you can specify null ordering:
|
|
545
532
|
|
546
533
|
=== All Columns (.*)
|
547
534
|
|
548
|
-
To select all columns in a table, Sequel supports the * method on identifiers without an argument:
|
535
|
+
To select all columns in a table, Sequel supports the * method on identifiers and qualified without an argument:
|
549
536
|
|
550
|
-
Sequel[:table].*
|
537
|
+
Sequel[:table].* # "table".*
|
538
|
+
Sequel[:schema][:table].* # "schema"."table".*
|
551
539
|
|
552
540
|
=== CASE statements
|
553
541
|
|
554
|
-
Sequel
|
542
|
+
Sequel supports SQL CASE statements using the <tt>Sequel.case</tt> method. The first argument is a hash or array of two element arrays representing the conditions, the second argument is the default value (ELSE). The keys of the hash (or first element in each array) is the WHEN condition, and the values of the hash (or second element in each array) is the THEN result. Here are some examples:
|
555
543
|
|
556
|
-
Sequel.case({:
|
557
|
-
Sequel.case([[column, 1]], 0) # (CASE WHEN "column" THEN 1 ELSE 0 END)
|
558
|
-
Sequel.case({{:
|
544
|
+
Sequel.case({column: 1}, 0) # (CASE WHEN "column" THEN 1 ELSE 0 END)
|
545
|
+
Sequel.case([[:column, 1]], 0) # (CASE WHEN "column" THEN 1 ELSE 0 END)
|
546
|
+
Sequel.case({{column: nil}=>1}, 0) # (CASE WHEN (column IS NULL) THEN 1 ELSE 0 END)
|
559
547
|
|
560
548
|
If the hash or array has multiple arguments, multiple WHEN clauses are used:
|
561
549
|
|
562
|
-
Sequel.case({:
|
550
|
+
Sequel.case({c: 1, d: 2}, 0) # (CASE WHEN "c" THEN 1 WHEN "d" THEN 2 ELSE 0 END)
|
563
551
|
Sequel.case([[:c, 1], [:d, 2]], 0) # (CASE WHEN "c" THEN 1 WHEN "d" THEN 2 ELSE 0 END)
|
564
552
|
|
565
553
|
If you provide a 3rd argument to <tt>Sequel.case</tt>, it goes between CASE and WHEN:
|
data/doc/testing.rdoc
CHANGED
@@ -156,13 +156,12 @@ SEQUEL_COLUMNS_INTROSPECTION :: Use the columns_introspection extension when run
|
|
156
156
|
SEQUEL_CONNECTION_VALIDATOR :: Use the connection validator extension when running the specs
|
157
157
|
SEQUEL_DUPLICATE_COLUMNS_HANDLER :: Use the duplicate columns handler extension with value given when running the specs
|
158
158
|
SEQUEL_ERROR_SQL :: Use the error_sql extension when running the specs
|
159
|
-
SEQUEL_FREEZE_DATASETS :: Use the freeze_datasets extension when running the specs
|
160
159
|
SEQUEL_FREEZE_DATABASE :: Freeze the database before running the integration specs
|
161
160
|
SEQUEL_IDENTIFIER_MANGLING :: Use the identifier_mangling extension when running the specs
|
162
|
-
SEQUEL_MODEL_PREPARED_STATEMENTS :: Use the prepared_statements
|
163
|
-
SEQUEL_NO_AUTO_LITERAL_STRINGS :: Use the no_auto_string_literals extension when running the specs
|
161
|
+
SEQUEL_MODEL_PREPARED_STATEMENTS :: Use the prepared_statements plugin when running the specs
|
164
162
|
SEQUEL_NO_CACHE_ASSOCIATIONS :: Don't cache association metadata when running the specs
|
165
163
|
SEQUEL_NO_CHECK_SQLS :: Don't check for specific SQL syntax when running the specs
|
164
|
+
SEQUEL_CHECK_PENDING :: Try running all specs (note, can cause lockups for some adapters), and raise errors for skipped specs that don't fail
|
166
165
|
SEQUEL_NO_PENDING :: Don't skip any specs, try running all specs (note, can cause lockups for some adapters)
|
167
|
-
|
168
|
-
|
166
|
+
SEQUEL_SPLIT_SYMBOLS :: Turn on symbol splitting when running the adapter and integration specs
|
167
|
+
SEQUEL_SYNCHRONIZE_SQL :: Use the synchronize_sql extension when running the specs
|
data/doc/thread_safety.rdoc
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
= Thread Safety
|
2
2
|
|
3
|
-
Most Sequel usage (and all common Sequel usage) is thread safe by default. Specifically, multiple threads can operate on Database instances, Dataset instances, and Model classes concurrently without problems. In general, Database instance and Model classes are not modified after application startup, and
|
3
|
+
Most Sequel usage (and all common Sequel usage) is thread safe by default. Specifically, multiple threads can operate on Database instances, Dataset instances, and Model classes concurrently without problems. In general, Database instance and Model classes are not modified after application startup, and Dataset instances are always frozen.
|
4
4
|
|
5
5
|
== Connection Pool
|
6
6
|
|
7
|
-
In order to allow multiple threads to operate on the same database at the same time, Sequel uses a connection pool. The connection pool is designed so that a thread uses a connection for the minimum amount of time, returning the connection to the pool as soon as it is done using the connection. If a thread requests a connection and the pool does not have an available connection, a new connection will be created. If the maximum number of connections in the pool has already been reached, the thread will block until a connection is available or the connection pool timeout has elapsed (in which case a PoolTimeout error will be raised).
|
7
|
+
In order to allow multiple threads to operate on the same database at the same time, Sequel uses a connection pool. The connection pool is designed so that a thread uses a connection for the minimum amount of time, returning the connection to the pool as soon as it is done using the connection. If a thread requests a connection and the pool does not have an available connection, a new connection will be created. If the maximum number of connections in the pool has already been reached, the thread will block until a connection is available or the connection pool timeout has elapsed (in which case a Sequel::PoolTimeout error will be raised).
|
8
8
|
|
9
9
|
== Exceptions
|
10
10
|
|
@@ -13,5 +13,3 @@ This is a small list of things that are specifically non thread-safe. This is n
|
|
13
13
|
1) Model instances: Model instances are not thread-safe unless they are frozen first. Multiple threads should not operate on an unfrozen model instance concurrently.
|
14
14
|
|
15
15
|
2) Model class modifications: Model class modifications, such as adding associations and loading plugins, are not designed to be thread safe. You should not modify a class in one thread if any other thread can concurrently access it. Model subclassing is designed to be thread-safe, so you create a model subclass in a thread and modify it safely.
|
16
|
-
|
17
|
-
3) Dataset mutation methods: Dataset mutation methods are not thread safe, you should not call them on datasets that could be accessed by other threads. It is safe to clone the dataset first inside a thread and call mutation methods on the cloned dataset.
|