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
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,11 @@ 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
|
-
SKIPPED_TEST_WARN :: Warn when skipping any tests because libraries aren't available
|
166
|
+
SEQUEL_SPLIT_SYMBOLS :: Turn on symbol splitting when running the adapter and integration 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.
|
data/doc/transactions.rdoc
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
Sequel uses autocommit mode by default for all of its database adapters, so in general in Sequel if you want to use database transactions, you need to be explicit about it. There are a few cases where transactions are used implicitly by default:
|
4
4
|
|
5
5
|
* Dataset#import to insert many records at once
|
6
|
+
* Dataset#paged_each to iterate over large datasets in batches
|
6
7
|
* Model#save
|
7
8
|
* Model#destroy
|
8
9
|
* Migrations if the database supports transactional schema
|
@@ -35,16 +36,16 @@ If any other exception is raised, the transaction is rolled back, and the except
|
|
35
36
|
end # ROLLBACK
|
36
37
|
# ArgumentError raised
|
37
38
|
|
38
|
-
If you want Sequel::Rollback exceptions to be reraised, use the <tt
|
39
|
+
If you want Sequel::Rollback exceptions to be reraised, use the <tt>rollback: :reraise</tt> option:
|
39
40
|
|
40
|
-
DB.transaction(:
|
41
|
+
DB.transaction(rollback: :reraise) do # BEGIN
|
41
42
|
raise Sequel::Rollback
|
42
43
|
end # ROLLBACK
|
43
44
|
# Sequel::Rollback raised
|
44
45
|
|
45
|
-
If you always want to rollback (useful for testing), use the <tt
|
46
|
+
If you always want to rollback (useful for testing), use the <tt>rollback: :always</tt> option:
|
46
47
|
|
47
|
-
DB.transaction(:
|
48
|
+
DB.transaction(rollback: :always) do # BEGIN
|
48
49
|
DB[:foo].insert(1) # INSERT
|
49
50
|
end # ROLLBACK
|
50
51
|
# no exception raised
|
@@ -86,17 +87,17 @@ You can nest calls to transaction, which by default just reuses the existing tra
|
|
86
87
|
end
|
87
88
|
end # COMMIT
|
88
89
|
|
89
|
-
You can use the <tt
|
90
|
+
You can use the <tt>savepoint: true</tt> option in the inner transaction to explicitly use a savepoint (if the database supports it):
|
90
91
|
|
91
92
|
DB.transaction do # BEGIN
|
92
|
-
DB.transaction(:
|
93
|
+
DB.transaction(savepoint: true) do # SAVEPOINT
|
93
94
|
DB[:foo].insert(1) # INSERT
|
94
95
|
end # RELEASE SAVEPOINT
|
95
96
|
end # COMMIT
|
96
97
|
|
97
|
-
You can use the <tt
|
98
|
+
You can use the <tt>auto_savepoint: true</tt> option in the outer transaction to explicitly use a savepoint in the inner transaction (if the database supports it):
|
98
99
|
|
99
|
-
DB.transaction(:
|
100
|
+
DB.transaction(auto_savepoint: true) do # BEGIN
|
100
101
|
DB.transaction do # SAVEPOINT
|
101
102
|
DB[:foo].insert(1) # INSERT
|
102
103
|
end # RELEASE SAVEPOINT
|
@@ -105,7 +106,7 @@ You can use the <tt>:auto_savepoint => true</tt> option in the outer transaction
|
|
105
106
|
If a Sequel::Rollback exception is raised inside the savepoint block, it will only rollback to the savepoint:
|
106
107
|
|
107
108
|
DB.transaction do # BEGIN
|
108
|
-
DB.transaction(:
|
109
|
+
DB.transaction(savepoint: true) do # SAVEPOINT
|
109
110
|
raise Sequel::Rollback
|
110
111
|
end # ROLLBACK TO SAVEPOINT
|
111
112
|
# no exception raised
|
@@ -114,7 +115,7 @@ If a Sequel::Rollback exception is raised inside the savepoint block, it will on
|
|
114
115
|
Other exceptions, unless rescued inside the outer transaction block, will rollback the savepoint and the outer transactions, since they are reraised by the transaction code:
|
115
116
|
|
116
117
|
DB.transaction do # BEGIN
|
117
|
-
DB.transaction(:
|
118
|
+
DB.transaction(savepoint: true) do # SAVEPOINT
|
118
119
|
raise ArgumentError
|
119
120
|
end # ROLLBACK TO SAVEPOINT
|
120
121
|
end # ROLLBACK
|
@@ -126,7 +127,7 @@ Sequel supports database prepared transactions on PostgreSQL, MySQL, and H2. Wi
|
|
126
127
|
|
127
128
|
To use prepared transactions in Sequel, you provide a string as the value of the :prepare option:
|
128
129
|
|
129
|
-
DB.transaction(:
|
130
|
+
DB.transaction(prepare: 'foo') do # BEGIN
|
130
131
|
DB[:foo].insert(1) # INSERT
|
131
132
|
end # PREPARE TRANSACTION 'foo'
|
132
133
|
|
@@ -140,9 +141,9 @@ or roll the prepared transaction back:
|
|
140
141
|
|
141
142
|
== Transaction Isolation Levels
|
142
143
|
|
143
|
-
The SQL standard supports 4 isolation levels: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, and SERIALIZABLE. Not all databases implement the levels as specified in the standard (or implement the levels at all), but on most databases, you can specify which transaction isolation level you want to use via the :isolation option to <tt>Database#transaction</tt>. The isolation level is specified as one of the following symbols: :uncommitted, :committed, :repeatable, and :serializable. Using this option
|
144
|
+
The SQL standard supports 4 isolation levels: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, and SERIALIZABLE. Not all databases implement the levels as specified in the standard (or implement the levels at all), but on most databases, you can specify which transaction isolation level you want to use via the :isolation option to <tt>Database#transaction</tt>. The isolation level is specified as one of the following symbols: :uncommitted, :committed, :repeatable, and :serializable. Using this option makes Sequel use the correct transaction isolation syntax for your database:
|
144
145
|
|
145
|
-
DB.transaction(:
|
146
|
+
DB.transaction(isolation: :serializable) do # BEGIN
|
146
147
|
# SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
|
147
148
|
DB[:foo].insert(1) # INSERT
|
148
149
|
end # COMMIT
|
@@ -151,8 +152,8 @@ The SQL standard supports 4 isolation levels: READ UNCOMMITTED, READ COMMITTED,
|
|
151
152
|
|
152
153
|
Sequel offers the ability to automatically restart transactions if specific types of errors are detected. For example, if you want to automatically restart a transaction if a serialization failure is detected:
|
153
154
|
|
154
|
-
DB.transaction(:
|
155
|
-
ModelClass.find_or_create(:
|
155
|
+
DB.transaction(isolation: :serializable, retry_on: [Sequel::SerializationFailure]) do
|
156
|
+
ModelClass.find_or_create(name: 'Foo')
|
156
157
|
end
|
157
158
|
|
158
159
|
At the serializable transaction isolation level, find_or_create may raises a Sequel::SerializationFailure exception if multiple threads simultaneously run that code. With the :retry_on option set, the transaction will be automatically retried until it succeeds.
|
@@ -161,9 +162,9 @@ Note that automatic retrying should not be used unless the entire transaction
|
|
161
162
|
block is idempotent, as otherwise it can cause non-idempotent
|
162
163
|
behavior to execute multiple times. For example, with the following code:
|
163
164
|
|
164
|
-
DB.transaction(:
|
165
|
+
DB.transaction(isolation: :serializable, retry_on: [Sequel::SerializationFailure]) do
|
165
166
|
logger.info 'Ensuring existence of ModelClass with name Foo'
|
166
|
-
ModelClass.find_or_create(:
|
167
|
+
ModelClass.find_or_create(name: 'Foo')
|
167
168
|
end
|
168
169
|
|
169
170
|
The logger.info method will be called multiple times if there is a serialization failure.
|
data/doc/validations.rdoc
CHANGED
@@ -13,7 +13,7 @@ types of validations to your models.
|
|
13
13
|
|
14
14
|
Validations are primarily useful for associating error messages to display to the user
|
15
15
|
with specific attributes on the model. It is also possible to use them to enforce
|
16
|
-
data integrity for model instances, but that's not
|
16
|
+
data integrity for model instances, but that's not recommended unless
|
17
17
|
the only way to modify the database is through model instances, or you have
|
18
18
|
complex data integrity requirements that aren't possible to specify via
|
19
19
|
database-level constraints.
|
@@ -30,19 +30,17 @@ be setting the size of the varchar column to 255, and using a CHECK constraint
|
|
30
30
|
to ensure that all values have at least two characters.
|
31
31
|
|
32
32
|
Unfortunately, sometimes there are situations where that is not possible. For
|
33
|
-
example, if you
|
34
|
-
|
35
|
-
varchar(255) field, then MySQL may just silently truncate it for you, instead of
|
36
|
-
raising an error. In that case, it may be necessary to use a model validation
|
33
|
+
example, if you don't have control over the schema and cannot add constraints,
|
34
|
+
or you are using MySQL (which doesn't support CHECK constraints), it may be necessary to use a model validation
|
37
35
|
to enforce the database integrity.
|
38
36
|
|
39
|
-
|
37
|
+
In some cases you may have data integrity requirements that are difficult to
|
40
38
|
enforce via database constraints, especially if you are targetting multiple
|
41
39
|
database types.
|
42
40
|
|
43
|
-
|
41
|
+
Validations are generally easier to write than database constraints,
|
44
42
|
so if data integrity isn't of great importance, using validations to provide minimal
|
45
|
-
data integrity
|
43
|
+
data integrity may be acceptable.
|
46
44
|
|
47
45
|
== Usage
|
48
46
|
|
@@ -71,11 +69,12 @@ saving of model objects passes through the +save+ method. This means that all
|
|
71
69
|
saving of model objects goes through the validation process.
|
72
70
|
|
73
71
|
The only way to skip validations when saving a model object is to pass the
|
74
|
-
<tt
|
72
|
+
<tt>validate: false</tt> option to +save+. If you use that option, +save+ will
|
75
73
|
not attempt to validate the object before saving it.
|
76
74
|
|
77
75
|
Note that it's always possible to update the instance's database row without using
|
78
|
-
+save+, by using a dataset to update it
|
76
|
+
+save+, by using a Sequel dataset to update it, or updating it via another program.
|
77
|
+
Validations will only be run if you call
|
79
78
|
+save+ on the model object, or another model method that calls +save+. For example,
|
80
79
|
the +create+ class method instantiates a new instance of the model, and then calls
|
81
80
|
+save+, so it validates the object. However, the +insert+ class method is a dataset
|
@@ -96,8 +95,8 @@ model instance is valid. This method should not be overridden. Instead, the
|
|
96
95
|
end
|
97
96
|
|
98
97
|
Album.new.valid? # false
|
99
|
-
Album.new(:
|
100
|
-
Album.new(:
|
98
|
+
Album.new(name: '').valid? # false
|
99
|
+
Album.new(name: 'RF').valid? # true
|
101
100
|
|
102
101
|
If the <tt>valid?</tt> method returns false, you can call the +errors+ method to
|
103
102
|
get an instance of <tt>Sequel::Model::Errors</tt> describing the errors on the model:
|
@@ -135,7 +134,7 @@ specifying validations like this:
|
|
135
134
|
def validate
|
136
135
|
super
|
137
136
|
errors.add(:name, 'cannot be empty') if !name || name.empty?
|
138
|
-
errors.add(:name, 'is already taken') if name && new? && Album[:name
|
137
|
+
errors.add(:name, 'is already taken') if name && new? && Album[{name: name}]
|
139
138
|
errors.add(:website, 'cannot be empty') if !website || website.empty?
|
140
139
|
errors.add(:website, 'is not a valid URL') unless website =~ /\Ahttps?:\/\//
|
141
140
|
end
|
@@ -149,7 +148,7 @@ You can call simple methods such as:
|
|
149
148
|
super
|
150
149
|
validates_presence [:name, :website]
|
151
150
|
validates_unique :name
|
152
|
-
validates_format /\Ahttps?:\/\//, :website, :
|
151
|
+
validates_format /\Ahttps?:\/\//, :website, message: 'is not a valid URL'
|
153
152
|
end
|
154
153
|
end
|
155
154
|
|
@@ -168,7 +167,7 @@ The following methods are provided by +validation_helpers+:
|
|
168
167
|
|
169
168
|
=== +validates_presence+
|
170
169
|
|
171
|
-
This
|
170
|
+
This method checks that the specified attributes are not blank. In general, if an object responds to <tt>blank?</tt>, it calls the method to determine if the object is blank. Otherwise, nil is considered blank, empty strings or strings that just contain whitespace are blank, and objects that respond to <tt>empty?</tt> and return true are considered blank. All other objects are considered non-blank for the purposes of +validates_presence+. This means that +validates_presence+ is safe to use on boolean columns where you want to ensure that either true or false is used, but not NULL.
|
172
171
|
|
173
172
|
class Album < Sequel::Model
|
174
173
|
def validate
|
@@ -195,7 +194,7 @@ This is similar to +validates_presence+, but only checks for NULL/nil values, al
|
|
195
194
|
|
196
195
|
=== +validates_exact_length+, +validates_min_length+, +validates_max_length+, +validates_length_range+
|
197
196
|
|
198
|
-
These methods all deal with ensuring that the length of the specified attribute matches the criteria specified by the first argument to the method. +validates_exact_length+ is for checking that the length of the attribute is equal to that value, +validates_min_length+ is for checking that the length of the attribute is greater than or equal to that value, +validates_max_length+ is for checking that the length of the attribute is less than or equal to that value, and +validates_length_range+ is for checking that the length of the attribute falls in the value, which should be a range or
|
197
|
+
These methods all deal with ensuring that the length of the specified attribute matches the criteria specified by the first argument to the method. +validates_exact_length+ is for checking that the length of the attribute is equal to that value, +validates_min_length+ is for checking that the length of the attribute is greater than or equal to that value, +validates_max_length+ is for checking that the length of the attribute is less than or equal to that value, and +validates_length_range+ is for checking that the length of the attribute falls in the value, which should be a range or an object that responds to <tt>include?</tt>.
|
199
198
|
|
200
199
|
|
201
200
|
class Album < Sequel::Model
|
@@ -257,17 +256,17 @@ These methods check that the specified attributes can be valid integers or valid
|
|
257
256
|
|
258
257
|
=== +validates_schema_types+
|
259
258
|
|
260
|
-
+validates_schema_types+ uses the database metadata for the model's table to determine which ruby type(s) should be used for the given database type, and calls +validates_type+ with that ruby type. It's designed to be used with the <tt>raise_on_typecast_failure = false</tt> setting
|
259
|
+
+validates_schema_types+ uses the database metadata for the model's table to determine which ruby type(s) should be used for the given database type, and calls +validates_type+ with that ruby type. It's designed to be used with the default <tt>raise_on_typecast_failure = false</tt> setting, where Sequel will attempt to typecast values, but silently ignore any errors raised:
|
261
260
|
|
262
|
-
Album.raise_on_typecast_failure = false
|
263
261
|
album = Album.new
|
262
|
+
album.copies_sold = '1'
|
263
|
+
album.copies_sold # => 1
|
264
264
|
album.copies_sold = 'banana'
|
265
265
|
album.copies_sold # => 'banana'
|
266
266
|
|
267
|
-
|
267
|
+
In general, you can call +validates_schema_types+ with all columns. If any of those columns has a value that doesn't match the type that Sequel expects, it's probably because the column was set and Sequel was not able to typecast it correctly, which means it probably isn't valid. For example, let's say that you want to check that a couple of columns contain valid dates:
|
268
268
|
|
269
269
|
class Album < Sequel::Model
|
270
|
-
self.raise_on_typecast_failure = false
|
271
270
|
def validate
|
272
271
|
super
|
273
272
|
validates_schema_types [:release_date, :record_date]
|
@@ -282,7 +281,7 @@ When <tt>raise_on_typecast_failure = false</tt>, you can call +validates_schema_
|
|
282
281
|
album.valid? # => false
|
283
282
|
album.errors # => {:release_date=>["is not a valid date"]}
|
284
283
|
|
285
|
-
For web applications, you usually want the
|
284
|
+
For web applications, you usually want the default setting, so that you can accept all of the input without raising an error, and then present the user with all error messages. If <tt>raise_on_typecast_failure = true</tt> is set and the user submits any invalid data, Sequel will immediately raise an error. +validates_schema_types+ is helpful because it allows you to check for typecasting errors on columns, and provides a good default error message stating that the attribute is not of the expected type.
|
286
285
|
|
287
286
|
=== +validates_unique+
|
288
287
|
|
@@ -310,7 +309,7 @@ You can also include an options hash as the last argument. Unlike the other val
|
|
310
309
|
|
311
310
|
:dataset :: The base dataset to use for the unique query, defaults to the model's dataset
|
312
311
|
:message :: The message to use
|
313
|
-
:only_if_modified :: Only check the uniqueness if the object is new or one of the columns has been modified.
|
312
|
+
:only_if_modified :: Only check the uniqueness if the object is new or one of the columns has been modified (true by default).
|
314
313
|
:where :: A callable object where call takes three arguments, a dataset,
|
315
314
|
the current object, and an array of columns, and should return
|
316
315
|
a modified dataset that is filtered to include only rows with
|
@@ -323,17 +322,17 @@ You can also include an options hash as the last argument. Unlike the other val
|
|
323
322
|
|
324
323
|
== +validation_helpers+ Options
|
325
324
|
|
326
|
-
All +validation_helpers+ methods
|
325
|
+
All other +validation_helpers+ methods accept the following options:
|
327
326
|
|
328
327
|
=== <tt>:message</tt>
|
329
328
|
|
330
|
-
The
|
329
|
+
The <tt>:message</tt> option overrides the default validation error message. Can be either a string or a proc. If a string, it is used directly. If a proc, the proc is called and should return a string. If the validation method takes an argument before the array of attributes, that argument is passed as an argument to the proc.
|
331
330
|
|
332
331
|
class Album < Sequel::Model
|
333
332
|
def validate
|
334
333
|
super
|
335
|
-
validates_presence :copies_sold, :
|
336
|
-
validates_min_length 3, :name, :
|
334
|
+
validates_presence :copies_sold, message: 'was not given'
|
335
|
+
validates_min_length 3, :name, message: lambda{|s| "should be more than #{s} characters"}
|
337
336
|
end
|
338
337
|
end
|
339
338
|
|
@@ -345,7 +344,7 @@ The <tt>:allow_nil</tt> option skips the validation if the attribute value is ni
|
|
345
344
|
def validate
|
346
345
|
super
|
347
346
|
validates_presence :copies_sold
|
348
|
-
validates_integer :copies_sold, :
|
347
|
+
validates_integer :copies_sold, allow_nil: true
|
349
348
|
end
|
350
349
|
end
|
351
350
|
|
@@ -358,17 +357,13 @@ The <tt>:allow_blank</tt> is similar to the <tt>:allow_nil</tt> option, but inst
|
|
358
357
|
class Album < Sequel::Model
|
359
358
|
def validate
|
360
359
|
super
|
361
|
-
validates_format /\Ahttps?:\/\//, :website, :
|
360
|
+
validates_format /\Ahttps?:\/\//, :website, allow_blank: true
|
362
361
|
end
|
363
362
|
end
|
364
363
|
a = Album.new
|
365
364
|
a.website = ''
|
366
365
|
a.valid? # true
|
367
366
|
|
368
|
-
If you are going to use <tt>:allow_blank</tt> you should make sure that all objects respond to the blank? method. Sequel ships with an extension that will do this for you:
|
369
|
-
|
370
|
-
Sequel.extension :blank
|
371
|
-
|
372
367
|
=== <tt>:allow_missing</tt>
|
373
368
|
|
374
369
|
The <tt>:allow_missing</tt> option is different from the <tt>:allow_nil</tt> option, in that instead of checking if the attribute value is nil, it checks if the attribute is present in the model instance's values hash. <tt>:allow_nil</tt> will skip the validation when the attribute is in the values hash and has a nil value and when the attribute is not in the values hash. <tt>:allow_missing</tt> will only skip the validation when the attribute is not in the values hash. If the attribute is in the values hash but has a nil value, <tt>:allow_missing</tt> will not skip it.
|
@@ -428,17 +423,26 @@ These are the default error messages for all of the helper methods in +validatio
|
|
428
423
|
|
429
424
|
== Modifying the Default Options
|
430
425
|
|
431
|
-
|
432
|
-
|
433
|
-
Sequel::Plugins::ValidationHelpers::DEFAULT_OPTIONS.merge!(
|
434
|
-
:presence=>{:message=>'cannot be empty'},
|
435
|
-
:includes=>{:message=>'invalid option', :allow_nil=>true},
|
436
|
-
:max_length=>{:message=>lambda{|i| "cannot be more than #{i} characters"}, :allow_nil=>true},
|
437
|
-
:format=>{:message=>'contains invalid characters', :allow_nil=>true})
|
438
|
-
|
439
|
-
This updates the default messages that will be used for the presence, includes, max_length, and format validations, and sets the default value of the <tt>:allow_nil</tt> option to true for the includes, max_length, and format validations.
|
426
|
+
You can override <tt>Sequel::Model#default_validation_helpers_options</tt> private method to override the default settings on a per validation type basis:
|
440
427
|
|
441
|
-
|
428
|
+
class Sequel::Model
|
429
|
+
private
|
430
|
+
|
431
|
+
def default_validation_helpers_options(type)
|
432
|
+
case type
|
433
|
+
when :presence
|
434
|
+
{message: 'cannot be empty'}
|
435
|
+
when :includes
|
436
|
+
{message: 'invalid option', allow_nil: true}
|
437
|
+
when :max_length
|
438
|
+
{message: lambda{|i| "cannot be more than #{i} characters"}, allow_nil: true}
|
439
|
+
when :format
|
440
|
+
{message: 'contains invalid characters', allow_nil: true}
|
441
|
+
else
|
442
|
+
super
|
443
|
+
end
|
444
|
+
end
|
445
|
+
end
|
442
446
|
|
443
447
|
== Custom Validations
|
444
448
|
|
@@ -480,7 +484,7 @@ Let's say you want to add some default validations that apply to all of your mod
|
|
480
484
|
super
|
481
485
|
validates_format(/\A[^\x00-\x08\x0e-\x1f\x7f\x81\x8d\x8f\x90\x9d]*\z/n,
|
482
486
|
model.string_columns,
|
483
|
-
:
|
487
|
+
message: "contains invalid characters")
|
484
488
|
end
|
485
489
|
end
|
486
490
|
|
@@ -547,9 +551,8 @@ Sequel ships with a +constraint_validations+ plugin and extension, that allows y
|
|
547
551
|
|
548
552
|
=== +auto_validations+
|
549
553
|
|
550
|
-
|
554
|
+
auto_validations uses the not null and type information obtained from parsing the database schema, and the unique index information from parsing the database's index information, and automatically setting up not_null, string length, schema type, and unique validations. If you don't require customizing validation messages on a per-column basis, it can DRY up a lot of validation code.
|
551
555
|
|
552
556
|
=== +validation_class_methods+
|
553
557
|
|
554
558
|
Sequel ships with the +validation_class_methods+ plugin, which uses class methods instead of instance methods to define validations. It exists mostly for legacy compatibility, but it is still supported.
|
555
|
-
|