sequel 4.49.0 → 5.3.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 +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
|
@@ -25,27 +25,27 @@ type for the given database. So while you specified +String+, Sequel will actua
|
|
|
25
25
|
+text+ depending on the underlying database. Here's a list of all ruby classes that Sequel will
|
|
26
26
|
convert to database types:
|
|
27
27
|
|
|
28
|
-
create_table(:columns_types) do
|
|
29
|
-
Integer :a0
|
|
30
|
-
String :a1
|
|
31
|
-
String :a2, :
|
|
32
|
-
String :a3, :
|
|
33
|
-
String :a4, :
|
|
34
|
-
String :a5, :
|
|
35
|
-
File :b
|
|
36
|
-
Fixnum :c
|
|
37
|
-
Bignum :d
|
|
38
|
-
Float :e
|
|
39
|
-
BigDecimal :f
|
|
40
|
-
BigDecimal :f2, :
|
|
41
|
-
BigDecimal :f3, :
|
|
42
|
-
Date :g
|
|
43
|
-
DateTime :h
|
|
44
|
-
Time :i
|
|
45
|
-
Time :i2, :
|
|
46
|
-
Numeric :j
|
|
47
|
-
TrueClass :k
|
|
48
|
-
FalseClass :l
|
|
28
|
+
create_table(:columns_types) do # common database type used
|
|
29
|
+
Integer :a0 # integer
|
|
30
|
+
String :a1 # varchar(255)
|
|
31
|
+
String :a2, size: 50 # varchar(50)
|
|
32
|
+
String :a3, fixed: true # char(255)
|
|
33
|
+
String :a4, fixed: true, size: 50 # char(50)
|
|
34
|
+
String :a5, text: true # text
|
|
35
|
+
File :b # blob
|
|
36
|
+
Fixnum :c # integer
|
|
37
|
+
Bignum :d # bigint
|
|
38
|
+
Float :e # double precision
|
|
39
|
+
BigDecimal :f # numeric
|
|
40
|
+
BigDecimal :f2, size: 10 # numeric(10)
|
|
41
|
+
BigDecimal :f3, size: [10, 2] # numeric(10, 2)
|
|
42
|
+
Date :g # date
|
|
43
|
+
DateTime :h # timestamp
|
|
44
|
+
Time :i # timestamp
|
|
45
|
+
Time :i2, only_time: true # time
|
|
46
|
+
Numeric :j # numeric
|
|
47
|
+
TrueClass :k # boolean
|
|
48
|
+
FalseClass :l # boolean
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
Note that in addition to the ruby class name, Sequel also pays attention to the column options when
|
|
@@ -89,7 +89,7 @@ method, the fourth argument is the options hash. The following options are supp
|
|
|
89
89
|
options for the index.
|
|
90
90
|
:null :: Mark the column as allowing NULL values (if true),
|
|
91
91
|
or not allowing NULL values (if false). If unspecified, will default
|
|
92
|
-
to whatever the database default is.
|
|
92
|
+
to whatever the database default is (usually true).
|
|
93
93
|
:primary_key :: Mark this column as the primary key. This is used instead of the
|
|
94
94
|
primary key method if you want a non-autoincrementing primary key.
|
|
95
95
|
:primary_key_constraint_name :: The name to give the primary key constraint.
|
|
@@ -98,7 +98,7 @@ method, the fourth argument is the options hash. The following options are supp
|
|
|
98
98
|
as +primary_key+ or +foreign_key+.
|
|
99
99
|
:unique :: Mark the column as unique, generally has the same effect as
|
|
100
100
|
creating a unique index on the column.
|
|
101
|
-
:unique_constraint_name :: The name to give the unique
|
|
101
|
+
:unique_constraint_name :: The name to give the unique constraint.
|
|
102
102
|
|
|
103
103
|
=== Other methods
|
|
104
104
|
|
|
@@ -112,14 +112,14 @@ You've seen this one used already. It's used to create an autoincrementing inte
|
|
|
112
112
|
|
|
113
113
|
If you want an autoincrementing 64-bit integer:
|
|
114
114
|
|
|
115
|
-
create_table(:a0){primary_key :id, :
|
|
115
|
+
create_table(:a0){primary_key :id, type: :Bignum}
|
|
116
116
|
|
|
117
117
|
If you want to create a primary key column that doesn't use an autoincrementing integer, you should
|
|
118
118
|
not use this method. Instead, you should use the :primary_key option to the +column+ method or type
|
|
119
119
|
method:
|
|
120
120
|
|
|
121
|
-
create_table(:a1){Integer :id, :
|
|
122
|
-
create_table(:a2){String :name, :
|
|
121
|
+
create_table(:a1){Integer :id, primary_key: true} # Non autoincrementing integer primary key
|
|
122
|
+
create_table(:a2){String :name, primary_key: true} # varchar(255) primary key
|
|
123
123
|
|
|
124
124
|
If you want to create a composite primary key, you should call the +primary_key+ method with an
|
|
125
125
|
array of column symbols. You can provide a specific name to use for the primary key constraint
|
|
@@ -128,7 +128,7 @@ via the :name option:
|
|
|
128
128
|
create_table(:items) do
|
|
129
129
|
Integer :group_id
|
|
130
130
|
Integer :position
|
|
131
|
-
primary_key [:group_id, :position], :
|
|
131
|
+
primary_key [:group_id, :position], name: :items_pk
|
|
132
132
|
end
|
|
133
133
|
|
|
134
134
|
If provided with an array, +primary_key+ does not create a column, it just sets up the primary key constraint.
|
|
@@ -147,7 +147,7 @@ as its third argument. A simple example is:
|
|
|
147
147
|
|
|
148
148
|
+foreign_key+ accepts the same options as +column+. For example, to have a unique foreign key with varchar(16) type:
|
|
149
149
|
|
|
150
|
-
foreign_key :column_name, :table, :
|
|
150
|
+
foreign_key :column_name, :table, unique: true, type: 'varchar(16)'
|
|
151
151
|
|
|
152
152
|
+foreign_key+ also accepts some specific options:
|
|
153
153
|
|
|
@@ -186,7 +186,7 @@ When using an array of symbols, you can also provide a :name option to name the
|
|
|
186
186
|
String :artist_name
|
|
187
187
|
String :artist_location
|
|
188
188
|
String :name
|
|
189
|
-
foreign_key [:artist_name, :artist_location], :artists, :
|
|
189
|
+
foreign_key [:artist_name, :artist_location], :artists, name: 'albums_artist_name_location_fkey'
|
|
190
190
|
end
|
|
191
191
|
|
|
192
192
|
If you want to add a foreign key for a single column with a named constraint, you must use
|
|
@@ -196,7 +196,7 @@ the array form with a single symbol:
|
|
|
196
196
|
primary_key :id
|
|
197
197
|
Integer :artist_id
|
|
198
198
|
String :name
|
|
199
|
-
foreign_key [:artist_id], :artists, :
|
|
199
|
+
foreign_key [:artist_id], :artists, name: 'albums_artist_id_fkey'
|
|
200
200
|
end
|
|
201
201
|
|
|
202
202
|
==== +index+
|
|
@@ -204,18 +204,18 @@ the array form with a single symbol:
|
|
|
204
204
|
+index+ creates indexes on the table. For single columns, calling index is the same as using the
|
|
205
205
|
<tt>:index</tt> option when creating the column:
|
|
206
206
|
|
|
207
|
-
create_table(:a){Integer :id, :
|
|
207
|
+
create_table(:a){Integer :id, index: true}
|
|
208
208
|
# Same as:
|
|
209
209
|
create_table(:a) do
|
|
210
210
|
Integer :id
|
|
211
211
|
index :id
|
|
212
212
|
end
|
|
213
213
|
|
|
214
|
-
create_table(:a){Integer :id, :
|
|
214
|
+
create_table(:a){Integer :id, index: {unique: true}}
|
|
215
215
|
# Same as:
|
|
216
216
|
create_table(:a) do
|
|
217
217
|
Integer :id
|
|
218
|
-
index :id, :
|
|
218
|
+
index :id, unique: true
|
|
219
219
|
end
|
|
220
220
|
|
|
221
221
|
Similar to the +primary_key+ and +foreign_key+ methods, calling +index+ with an array of symbols
|
|
@@ -241,11 +241,11 @@ The +unique+ method creates a unique constraint on the table. A unique constrai
|
|
|
241
241
|
operates identically to a unique index, so the following three +create_table+ blocks are
|
|
242
242
|
pretty much identical:
|
|
243
243
|
|
|
244
|
-
create_table(:a){Integer :a, :
|
|
244
|
+
create_table(:a){Integer :a, unique: true}
|
|
245
245
|
|
|
246
246
|
create_table(:a) do
|
|
247
247
|
Integer :a
|
|
248
|
-
index :a, :
|
|
248
|
+
index :a, unique: true
|
|
249
249
|
end
|
|
250
250
|
|
|
251
251
|
create_table(:a) do
|
|
@@ -304,23 +304,23 @@ constraint, as that makes it easier to drop the constraint later if necessary.
|
|
|
304
304
|
|
|
305
305
|
+create_join_table+ is a shortcut that you can use to create simple many-to-many join tables:
|
|
306
306
|
|
|
307
|
-
create_join_table(:
|
|
307
|
+
create_join_table(artist_id: :artists, album_id: :albums)
|
|
308
308
|
|
|
309
309
|
which expands to:
|
|
310
310
|
|
|
311
311
|
create_table(:albums_artists) do
|
|
312
|
-
foreign_key :album_id, :albums
|
|
313
|
-
foreign_key :artist_id, :artists
|
|
312
|
+
foreign_key :album_id, :albums
|
|
313
|
+
foreign_key :artist_id, :artists
|
|
314
314
|
primary_key [:album_id, :artist_id]
|
|
315
315
|
index [:artist_id, :album_id]
|
|
316
316
|
end
|
|
317
317
|
|
|
318
|
-
== <tt>create_table :as
|
|
318
|
+
== <tt>create_table :as</tt>
|
|
319
319
|
|
|
320
320
|
To create a table from the result of a SELECT query, instead of passing a block
|
|
321
321
|
to +create_table+, provide a dataset to the :as option:
|
|
322
322
|
|
|
323
|
-
create_table(:older_items, :
|
|
323
|
+
create_table(:older_items, as: DB[:items].where{updated_at < Date.today << 6})
|
|
324
324
|
|
|
325
325
|
== +alter_table+
|
|
326
326
|
|
|
@@ -336,7 +336,7 @@ argument is the column name, the second is the type, and the third is an options
|
|
|
336
336
|
hash:
|
|
337
337
|
|
|
338
338
|
alter_table(:albums) do
|
|
339
|
-
add_column :copies_sold, Integer, :
|
|
339
|
+
add_column :copies_sold, Integer, default: 0
|
|
340
340
|
end
|
|
341
341
|
|
|
342
342
|
=== +drop_column+
|
|
@@ -374,6 +374,12 @@ Sequel will not add a column, but will add a composite primary key constraint:
|
|
|
374
374
|
add_primary_key [:album_id, :artist_id]
|
|
375
375
|
end
|
|
376
376
|
|
|
377
|
+
It is possible to specify a name for the primary key constraint: via the :name option:
|
|
378
|
+
|
|
379
|
+
alter_table(:albums_artists) do
|
|
380
|
+
add_primary_key [:album_id, :artist_id], :name=>:albums_artists_pkey
|
|
381
|
+
end
|
|
382
|
+
|
|
377
383
|
If you just want to take an existing single column and make it a primary key, call
|
|
378
384
|
+add_primary_key+ with an array with a single symbol:
|
|
379
385
|
|
|
@@ -392,18 +398,29 @@ creates a new column:
|
|
|
392
398
|
end
|
|
393
399
|
|
|
394
400
|
If you want to add a new foreign key constraint to an existing column, you provide an
|
|
395
|
-
array with a single element
|
|
396
|
-
|
|
401
|
+
array with a single element:
|
|
402
|
+
|
|
403
|
+
alter_table(:albums) do
|
|
404
|
+
add_foreign_key [:artist_id], :artists
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
It's encouraged to provide a name when adding the constraint, via the :foreign_key_constraint_name
|
|
408
|
+
option if adding the column and the constraint:
|
|
409
|
+
|
|
410
|
+
alter_table(:albums) do
|
|
411
|
+
add_foreign_key :artist_id, :artists, foreign_key_constraint_name: :albums_artist_id_fkey
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
or via the :name option if just adding the constraint:
|
|
397
415
|
|
|
398
416
|
alter_table(:albums) do
|
|
399
|
-
add_foreign_key [:artist_id], :artists, :
|
|
417
|
+
add_foreign_key [:artist_id], :artists, name: :albums_artist_id_fkey
|
|
400
418
|
end
|
|
401
419
|
|
|
402
|
-
To set up a multiple column foreign key constraint, use an array with multiple column
|
|
403
|
-
symbols:
|
|
420
|
+
To set up a multiple column foreign key constraint, use an array with multiple column symbols:
|
|
404
421
|
|
|
405
422
|
alter_table(:albums) do
|
|
406
|
-
add_foreign_key [:artist_name, :artist_location], :artists, :
|
|
423
|
+
add_foreign_key [:artist_name, :artist_location], :artists, name: :albums_artist_name_location_fkey
|
|
407
424
|
end
|
|
408
425
|
|
|
409
426
|
=== +drop_foreign_key+
|
|
@@ -420,13 +437,13 @@ an array. It's encouraged to use the :name option to provide the constraint nam
|
|
|
420
437
|
drop, though on some databases Sequel may be able to find the name through introspection:
|
|
421
438
|
|
|
422
439
|
alter_table(:albums) do
|
|
423
|
-
drop_foreign_key [:artist_id], :
|
|
440
|
+
drop_foreign_key [:artist_id], name: :albums_artist_id_fkey
|
|
424
441
|
end
|
|
425
442
|
|
|
426
443
|
An array is also used to drop a composite foreign key constraint:
|
|
427
444
|
|
|
428
445
|
alter_table(:albums) do
|
|
429
|
-
drop_foreign_key [:artist_name, :artist_location], :
|
|
446
|
+
drop_foreign_key [:artist_name, :artist_location], name: :albums_artist_name_location_fkey
|
|
430
447
|
end
|
|
431
448
|
|
|
432
449
|
If you do not provide a :name option and Sequel is not able to determine the name
|
|
@@ -445,7 +462,7 @@ It accepts the same options as +create_table+'s +index+ method, and you can set
|
|
|
445
462
|
a multiple column index using an array:
|
|
446
463
|
|
|
447
464
|
alter_table(:albums_artists) do
|
|
448
|
-
add_index [:album_id, :artist_id], :
|
|
465
|
+
add_index [:album_id, :artist_id], unique: true
|
|
449
466
|
end
|
|
450
467
|
|
|
451
468
|
=== +drop_index+
|
|
@@ -461,7 +478,7 @@ Just like +drop_column+, it is often used in the +down+ block of a migration.
|
|
|
461
478
|
To drop an index with a specific name, use the <tt>:name</tt> option:
|
|
462
479
|
|
|
463
480
|
alter_table(:albums) do
|
|
464
|
-
drop_index :artist_id, :
|
|
481
|
+
drop_index :artist_id, name: :artists_id_index
|
|
465
482
|
end
|
|
466
483
|
|
|
467
484
|
=== +add_full_text_index+, +add_spatial_index+
|
|
@@ -480,7 +497,7 @@ method:
|
|
|
480
497
|
|
|
481
498
|
There is no method to add an unnamed constraint, but you can pass +nil+ as the first
|
|
482
499
|
argument of +add_constraint+ to do so. However, it's not recommended to do that
|
|
483
|
-
as it is difficult to drop such a constraint.
|
|
500
|
+
as it is more difficult to drop such a constraint.
|
|
484
501
|
|
|
485
502
|
=== +add_unique_constraint+
|
|
486
503
|
|
|
@@ -491,6 +508,12 @@ method. This usually has the same effect as adding a unique index.
|
|
|
491
508
|
add_unique_constraint [:artist_id, :name]
|
|
492
509
|
end
|
|
493
510
|
|
|
511
|
+
You can also specify a name via the :name option when adding the constraint:
|
|
512
|
+
|
|
513
|
+
alter_table(:albums) do
|
|
514
|
+
add_unique_constraint [:artist_id, :name], name: :albums_artist_id_name_ukey
|
|
515
|
+
end
|
|
516
|
+
|
|
494
517
|
=== +drop_constraint+
|
|
495
518
|
|
|
496
519
|
This method drops an existing named constraint:
|
|
@@ -506,9 +529,9 @@ For that reason, you should not add unnamed constraints that you ever might need
|
|
|
506
529
|
On some databases, you must specify the type of constraint via a <tt>:type</tt> option:
|
|
507
530
|
|
|
508
531
|
alter_table(:albums) do
|
|
509
|
-
drop_constraint(:albums_pk, :
|
|
510
|
-
drop_constraint(:albums_fk, :
|
|
511
|
-
drop_constraint(:albums_uk, :
|
|
532
|
+
drop_constraint(:albums_pk, type: :primary_key)
|
|
533
|
+
drop_constraint(:albums_fk, type: :foreign_key)
|
|
534
|
+
drop_constraint(:albums_uk, type: :unique)
|
|
512
535
|
end
|
|
513
536
|
|
|
514
537
|
=== +set_column_default+
|
|
@@ -597,9 +620,6 @@ the table if the table already exists. On some databases, it uses
|
|
|
597
620
|
<tt>IF NOT EXISTS</tt>, on others it does a separate query to check for
|
|
598
621
|
existence.
|
|
599
622
|
|
|
600
|
-
This should not be used inside migrations, as if the table does not
|
|
601
|
-
exist, it may mess up the migration.
|
|
602
|
-
|
|
603
623
|
=== +rename_table+
|
|
604
624
|
|
|
605
625
|
You can rename an existing table using +rename_table+. Like +rename_column+,
|
|
@@ -623,9 +643,6 @@ is the same as:
|
|
|
623
643
|
primary_key :id
|
|
624
644
|
end
|
|
625
645
|
|
|
626
|
-
It should not be used inside migrations, as if the table does not exist, it may
|
|
627
|
-
mess up the migration.
|
|
628
|
-
|
|
629
646
|
=== <tt>create_table?</tt>
|
|
630
647
|
|
|
631
648
|
<tt>create_table?</tt> only creates the table if it does
|
|
@@ -643,8 +660,6 @@ is the same as:
|
|
|
643
660
|
end
|
|
644
661
|
end
|
|
645
662
|
|
|
646
|
-
Like <tt>create_table!</tt>, it should not be used inside migrations.
|
|
647
|
-
|
|
648
663
|
=== +create_view+ and +create_or_replace_view+
|
|
649
664
|
|
|
650
665
|
These can be used to create views. The difference between them is that
|
|
@@ -662,4 +677,3 @@ second argument:
|
|
|
662
677
|
arguments:
|
|
663
678
|
|
|
664
679
|
drop_view(:gold_albums, :platinum_albums)
|
|
665
|
-
|
data/doc/security.rdoc
CHANGED
|
@@ -16,14 +16,11 @@ as it never calls eval on a string that is derived from user input.
|
|
|
16
16
|
However, some Sequel methods used for creating methods via metaprogramming
|
|
17
17
|
could conceivably be abused to do so:
|
|
18
18
|
|
|
19
|
-
* Sequel::Schema::CreateTableGenerator.add_type_method
|
|
20
|
-
* Sequel::Dataset.def_mutation_method
|
|
21
19
|
* Sequel::Dataset.def_sql_method
|
|
22
|
-
* Sequel::
|
|
23
|
-
* Sequel.def_adapter_method (private)
|
|
24
|
-
* Sequel::SQL::Expression.to_s_method (private)
|
|
25
|
-
* Sequel::Plugins::HookClassMethods::ClassMethods#add_hook_type
|
|
20
|
+
* Sequel::JDBC.load_driver
|
|
26
21
|
* Sequel::Plugins.def_dataset_methods
|
|
22
|
+
* Sequel::Dataset.prepared_statements_module (private)
|
|
23
|
+
* Sequel::SQL::Expression.to_s_method (private)
|
|
27
24
|
|
|
28
25
|
As long as you don't call those with user input, you should not be
|
|
29
26
|
vulnerable to code execution.
|
|
@@ -48,6 +45,9 @@ There are basically two kinds of possible SQL injections in Sequel:
|
|
|
48
45
|
Some Sequel methods are designed to execute raw SQL strings, including:
|
|
49
46
|
|
|
50
47
|
* Sequel::Database#execute
|
|
48
|
+
* Sequel::Database#execute_ddl
|
|
49
|
+
* Sequel::Database#execute_dui
|
|
50
|
+
* Sequel::Database#execute_insert
|
|
51
51
|
* Sequel::Database#run
|
|
52
52
|
* Sequel::Database#<<
|
|
53
53
|
* Sequel::Dataset#fetch_rows
|
|
@@ -61,9 +61,12 @@ Some Sequel methods are designed to execute raw SQL strings, including:
|
|
|
61
61
|
|
|
62
62
|
Here are some examples of use:
|
|
63
63
|
|
|
64
|
+
DB.execute 'SQL'
|
|
65
|
+
DB.execute_ddl 'SQL'
|
|
66
|
+
DB.execute_dui 'SQL'
|
|
67
|
+
DB.execute_insert 'SQL'
|
|
64
68
|
DB.run 'SQL'
|
|
65
69
|
DB << 'SQL'
|
|
66
|
-
DB.execute 'SQL'
|
|
67
70
|
DB.fetch_rows('SQL'){|row| }
|
|
68
71
|
DB.dataset.with_sql_all('SQL')
|
|
69
72
|
DB.dataset.with_sql_delete('SQL')
|
|
@@ -102,19 +105,16 @@ With these methods you should use placeholders, in which case Sequel automatical
|
|
|
102
105
|
|
|
103
106
|
Sequel generally treats ruby strings as SQL strings (escaping them correctly), and
|
|
104
107
|
not as raw SQL. However, you can convert a ruby string to a literal string, and
|
|
105
|
-
Sequel will then treat it as raw SQL. This is typically done through
|
|
106
|
-
|
|
107
|
-
or Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit] if they are not in use.
|
|
108
|
+
Sequel will then treat it as raw SQL. This is typically done through
|
|
109
|
+
Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit].
|
|
108
110
|
|
|
109
|
-
'a'.lit
|
|
110
111
|
Sequel.lit('a')
|
|
111
112
|
|
|
112
|
-
Using
|
|
113
|
+
Using Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit] to turn a ruby string into a literal string results
|
|
113
114
|
in SQL injection if the string is derived from user input. With both of these
|
|
114
115
|
methods, the strings can contain placeholders, which you can use to safely include
|
|
115
116
|
user input inside a literal string:
|
|
116
117
|
|
|
117
|
-
'a = ?'.lit(params[:user_id].to_s)
|
|
118
118
|
Sequel.lit('a = ?', params[:user_id].to_s)
|
|
119
119
|
|
|
120
120
|
Even though they have similar names, note that Sequel::Database#literal operates very differently from
|
|
@@ -132,91 +132,107 @@ a ruby string as raw SQL. For example:
|
|
|
132
132
|
|
|
133
133
|
==== SQL Filter Fragments
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
Starting in Sequel 5, Sequel does not automatically convert plain strings to
|
|
136
|
+
literal strings in typical code. Instead, you can use Sequel.lit to
|
|
137
|
+
create literal strings:
|
|
136
138
|
|
|
137
|
-
|
|
139
|
+
Sequel.lit("name > 'A'")
|
|
138
140
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
+
To safely include user input as part of an SQL filter fragment, use Sequel.lit
|
|
142
|
+
with placeholders:
|
|
141
143
|
|
|
142
|
-
DB[:table].where("name >
|
|
144
|
+
DB[:table].where(Sequel.lit("name > ?", params[:id].to_s)) # Safe
|
|
143
145
|
|
|
144
|
-
|
|
146
|
+
Be careful to never call Sequel.lit where the first argument is derived from
|
|
147
|
+
user input.
|
|
145
148
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
+
There are a few uncommon cases where Sequel will still convert
|
|
150
|
+
plain strings to literal strings.
|
|
151
|
+
|
|
152
|
+
==== SQL Fragment passed to Dataset#lock_style and Model#lock!
|
|
153
|
+
|
|
154
|
+
The Sequel::Dataset#lock_style and Sequel::Model#lock! methods also treat
|
|
155
|
+
an input string as SQL code. These methods should not be called with user input.
|
|
156
|
+
|
|
157
|
+
DB[:table].lock_style(params[:id]) # SQL injection!
|
|
158
|
+
Album.first.lock!(params[:id]) # SQL injection!
|
|
159
|
+
|
|
160
|
+
==== SQL Type Names
|
|
161
|
+
|
|
162
|
+
In general, most places where Sequel needs to use an SQL type that should
|
|
163
|
+
be specified by the user, it allows you to use a ruby string, and that
|
|
164
|
+
string is used verbatim as the SQL type. You should not use user input
|
|
165
|
+
for type strings.
|
|
166
|
+
|
|
167
|
+
DB[:table].select(Sequel.cast(:a, params[:id])) # SQL injection!
|
|
168
|
+
|
|
169
|
+
==== SQL Function Names
|
|
170
|
+
|
|
171
|
+
In most cases, Sequel does not quote SQL function names. You should not use
|
|
172
|
+
user input for function names.
|
|
173
|
+
|
|
174
|
+
DB[:table].select(Sequel.function(params[:id])) # SQL injection!
|
|
175
|
+
|
|
176
|
+
==== auto_literal_strings extension
|
|
149
177
|
|
|
150
|
-
|
|
178
|
+
If the auto_literal_strings extension is used for backwards compatibility,
|
|
179
|
+
then Sequel will treat plain strings as literal strings if they are used
|
|
180
|
+
as the first argument to a filtering method. This can lead to SQL
|
|
181
|
+
injection:
|
|
151
182
|
|
|
152
|
-
|
|
153
|
-
|
|
183
|
+
DB[:table].where("name > #{params[:id].to_s}")
|
|
184
|
+
# SQL injection when using auto_literal_strings extension
|
|
154
185
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
186
|
+
If you are using the auto_literal_strings extension, you need to be very careful,
|
|
187
|
+
as the following methods will treat a plain string given as the first argument
|
|
188
|
+
as a literal string:
|
|
158
189
|
|
|
159
190
|
* Sequel::Dataset#where
|
|
160
191
|
* Sequel::Dataset#having
|
|
161
192
|
* Sequel::Dataset#filter
|
|
162
193
|
* Sequel::Dataset#exclude
|
|
163
|
-
* Sequel::Dataset#exclude_where
|
|
164
194
|
* Sequel::Dataset#exclude_having
|
|
165
|
-
* Sequel::Dataset#and
|
|
166
195
|
* Sequel::Dataset#or
|
|
167
196
|
* Sequel::Dataset#first
|
|
168
197
|
* Sequel::Dataset#last
|
|
169
198
|
* Sequel::Dataset#[]
|
|
170
199
|
|
|
171
|
-
|
|
172
|
-
class methods also call down to the filter methods.
|
|
200
|
+
Even stuff that looks like it may be safe isn't:
|
|
173
201
|
|
|
174
|
-
|
|
175
|
-
|
|
202
|
+
DB[:table].first(params[:num_rows])
|
|
203
|
+
# SQL injection when using auto_literal_strings extension
|
|
176
204
|
|
|
177
|
-
|
|
205
|
+
The Model.find[rdoc-ref:Sequel::Model::ClassMethods#find] and
|
|
206
|
+
Model.find_or_create[rdoc-ref:Sequel::Model::ClassMethods#find_or_create]
|
|
207
|
+
class methods will also treat string arguments as literal strings if the
|
|
208
|
+
auto_literal_strings extension is used:
|
|
178
209
|
|
|
179
|
-
|
|
180
|
-
|
|
210
|
+
Album.find(params[:id])
|
|
211
|
+
# SQL injection when using auto_literal_strings extension
|
|
212
|
+
|
|
213
|
+
Similar to the filter methods, the auto_literal_strings extension
|
|
214
|
+
also makes Sequel::Dataset#update treats a string argument as raw SQL:
|
|
181
215
|
|
|
182
216
|
DB[:table].update("column = 1")
|
|
183
217
|
|
|
184
218
|
So you should not do:
|
|
185
219
|
|
|
186
|
-
DB[:table].update(
|
|
220
|
+
DB[:table].update(params[:changes])
|
|
221
|
+
# SQL injection when using auto_literal_strings extension
|
|
187
222
|
|
|
188
|
-
|
|
223
|
+
or:
|
|
189
224
|
|
|
190
|
-
DB[:table].update(
|
|
225
|
+
DB[:table].update("column = #{params[:value].to_s}")
|
|
226
|
+
# SQL injection when using auto_literal_strings extension
|
|
191
227
|
|
|
192
|
-
|
|
193
|
-
for plain strings as literal strings in update methods.
|
|
194
|
-
|
|
195
|
-
==== SQL Fragment passed to Dataset#lock_style and Model#lock!
|
|
196
|
-
|
|
197
|
-
The Sequel::Dataset#lock_style and Sequel::Model#lock! methods also treat
|
|
198
|
-
an input string as SQL code. This method should not be called with user input.
|
|
199
|
-
|
|
200
|
-
==== SQL Fragment passed to Virtual Row #` method
|
|
201
|
-
|
|
202
|
-
Virtual row blocks currently support a #` method for using literal SQL:
|
|
203
|
-
|
|
204
|
-
DB[:table].where{a > `some SQL`}
|
|
205
|
-
|
|
206
|
-
This method should not be called with user input.
|
|
207
|
-
|
|
208
|
-
==== SQL Type Names
|
|
209
|
-
|
|
210
|
-
In general, most places where Sequel needs to use an SQL type that should
|
|
211
|
-
be specified by the user, it allows you to use a ruby string, and that
|
|
212
|
-
string is used verbatim as the SQL type. You should not use user input
|
|
213
|
-
for type strings.
|
|
214
|
-
|
|
215
|
-
==== SQL Function Names
|
|
228
|
+
Instead, you should do:
|
|
216
229
|
|
|
217
|
-
|
|
218
|
-
user input for function names.
|
|
230
|
+
DB[:table].update(:column => params[:value].to_s) # Safe
|
|
219
231
|
|
|
232
|
+
Because using the auto_literal_strings extension makes SQL injection
|
|
233
|
+
so much eaiser, it is recommended to not use it, and instead
|
|
234
|
+
use Sequel.lit with placeholders.
|
|
235
|
+
|
|
220
236
|
=== SQL Identifier Injections
|
|
221
237
|
|
|
222
238
|
Usually, Sequel treats ruby symbols as SQL identifiers, and ruby
|
|
@@ -236,7 +252,7 @@ the Sequel::Dataset#insert and Sequel::Dataset#update methods:
|
|
|
236
252
|
DB[:t].insert('b'=>1) # INSERT INTO "t" ("b") VALUES (1)
|
|
237
253
|
|
|
238
254
|
Note how the identifier is still quoted in these cases. Sequel quotes identifiers by default
|
|
239
|
-
on most databases. However, it does not quote identifiers by default on DB2
|
|
255
|
+
on most databases. However, it does not quote identifiers by default on DB2.
|
|
240
256
|
On those databases using an identifier derived from user input can lead to SQL injection.
|
|
241
257
|
Similarly, if you turn off identifier quoting manually on other databases, you open yourself
|
|
242
258
|
up to SQL injection if you use identifiers derived from user input.
|
|
@@ -262,6 +278,10 @@ uses symbols as identifiers. However, if you are creating symbols from user inp
|
|
|
262
278
|
you at least have a denial of service vulnerability in ruby <2.2, and possibly a
|
|
263
279
|
more serious vulnerability.
|
|
264
280
|
|
|
281
|
+
Note that many Database schema modification methods (e.g. create_table, add_column)
|
|
282
|
+
also allow for SQL identifier injections, and possibly also SQL code injections.
|
|
283
|
+
These methods should never be called with user input.
|
|
284
|
+
|
|
265
285
|
== Denial of Service
|
|
266
286
|
|
|
267
287
|
Sequel converts some strings to symbols. Because symbols in ruby <2.2 are not
|
|
@@ -293,7 +313,7 @@ if you allow the user to control the alias name:
|
|
|
293
313
|
|
|
294
314
|
DB[:table].select(:column.as(params[:alias]))
|
|
295
315
|
|
|
296
|
-
Then you have a denial of service vulnerability. In general, such a vulnerability
|
|
316
|
+
Then you can have a denial of service vulnerability. In general, such a vulnerability
|
|
297
317
|
is unlikely, because you are probably indexing into the returned hash(es) by name,
|
|
298
318
|
and if an alias was used and you didn't expect it, your application wouldn't work.
|
|
299
319
|
|
|
@@ -353,28 +373,17 @@ These two methods iterate over the second argument (+:name+ and +:copies_sold+ i
|
|
|
353
373
|
this example) instead of iterating over the entries in the first argument
|
|
354
374
|
(<tt>params[:album]</tt> in this example).
|
|
355
375
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
which are similar but iterate over the entries in the first argument, checking
|
|
360
|
-
the second argument to see if setting the entries is allowed.
|
|
361
|
-
|
|
362
|
-
album.set_only(params[:album], [:name, :copies_sold])
|
|
363
|
-
album.update_only(params[:album], [:name, :copies_sold])
|
|
364
|
-
|
|
365
|
-
If you expect all entries in the second argument to be present in the first
|
|
366
|
-
argument, use +set_fields+ or +update_fields+. If you are not sure if all
|
|
367
|
-
arguments in the second argument will be present in the first argument, but
|
|
368
|
-
do not want to allow setting any column other than the ones listed in the
|
|
369
|
-
second argument, use +set_only+ or +update_only+.
|
|
370
|
-
|
|
371
|
-
You can override the columns to allow by default during mass assignment via
|
|
372
|
-
the Model.set_allowed_columns[rdoc-ref:Sequel::Model::ClassMethods#set_allowed_columns] class method. This is a good
|
|
373
|
-
practice, though being explicit on a per-call basis is still recommended:
|
|
376
|
+
If you want to override the columns that Model#set[rdoc-ref:Sequel::Model::InstanceMethods#set]
|
|
377
|
+
allows by default during mass assignment, you can use the whitelist_security plugin, then call
|
|
378
|
+
the set_allowed_columns class method.
|
|
374
379
|
|
|
380
|
+
Album.plugin :whitelist_security
|
|
375
381
|
Album.set_allowed_columns(:name, :copies_sold)
|
|
376
382
|
Album.create(params[:album]) # Only name and copies_sold set
|
|
377
383
|
|
|
384
|
+
Being explicit on a per-call basis using the set_fields and update_fields methods is recommended
|
|
385
|
+
instead of using the whitelist_security plugin and setting a global whitelist.
|
|
386
|
+
|
|
378
387
|
For more details on the mass assignment methods, see the {Mass Assignment Guide}[rdoc-ref:doc/mass_assignment.rdoc].
|
|
379
388
|
|
|
380
389
|
== General Parameter Handling
|
|
@@ -386,7 +395,7 @@ their type. For example:
|
|
|
386
395
|
Album.where(:id=>params[:id])
|
|
387
396
|
|
|
388
397
|
is probably a bad idea. Assuming you are using a web framework, <tt>params[:id]</tt> could
|
|
389
|
-
be a string, an array, a hash, or
|
|
398
|
+
be a string, an array, a hash, nil, or potentially something else.
|
|
390
399
|
|
|
391
400
|
Assuming that +id+ is an integer field, you probably want to do:
|
|
392
401
|
|
|
@@ -400,7 +409,7 @@ a string:
|
|
|
400
409
|
If you are trying to use an IN clause with a list of id values based on input provided
|
|
401
410
|
on a web form:
|
|
402
411
|
|
|
403
|
-
Album.where(:id=>params[:ids].to_a.map
|
|
412
|
+
Album.where(:id=>params[:ids].to_a.map(&:to_i))
|
|
404
413
|
|
|
405
414
|
Basically, be as explicit as possible. While there aren't any known security issues
|
|
406
415
|
in Sequel when you do:
|