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/lib/sequel/model/base.rb
CHANGED
@@ -22,9 +22,12 @@ module Sequel
|
|
22
22
|
# truncate, unfiltered, ungraphed, ungrouped, union, unlimited, unordered, where, where_all,
|
23
23
|
# where_each, where_single_value, with, with_recursive, with_sql
|
24
24
|
module ClassMethods
|
25
|
-
#
|
26
|
-
|
27
|
-
|
25
|
+
# :nocov:
|
26
|
+
def allowed_columns
|
27
|
+
Sequel::Deprecation.deprecate("Model.allowed_columns", "It has been moved to the whitelist_security plugin")
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
# :nocov:
|
28
31
|
|
29
32
|
# Whether to cache the anonymous models created by Sequel::Model(), true by default. This is
|
30
33
|
# required for reloading them correctly (avoiding the superclass mismatch).
|
@@ -80,24 +83,10 @@ module Sequel
|
|
80
83
|
# Sequel will not check the number of rows modified (default: true).
|
81
84
|
attr_accessor :require_modification
|
82
85
|
|
83
|
-
#
|
84
|
-
# without a valid table backing it.
|
85
|
-
#
|
86
|
-
#
|
87
|
-
# set_dataset :my_foo
|
88
|
-
# end
|
89
|
-
#
|
90
|
-
# As when Sequel::Model is subclassed, before set_dataset is executed, it will try to
|
91
|
-
# get the schema for the foos table, which will raise an exception. You would need to
|
92
|
-
# switch to using:
|
93
|
-
#
|
94
|
-
# class Foo < Sequel::Model(:my_foo)
|
95
|
-
# end
|
96
|
-
#
|
97
|
-
# or:
|
98
|
-
#
|
99
|
-
# Foo = Class.new(Sequel::Model)
|
100
|
-
# Foo.set_dataset :my_foo
|
86
|
+
# If true (the default), tequires that all models have valid tables,
|
87
|
+
# raising exceptions if creating a model without a valid table backing it.
|
88
|
+
# Setting this to false will allow the creation of model classes where the
|
89
|
+
# underlying table doesn't exist.
|
101
90
|
attr_accessor :require_valid_table
|
102
91
|
|
103
92
|
# Should be the literal primary key column name if this Model's table has a simple primary key, or
|
@@ -108,7 +97,7 @@ module Sequel
|
|
108
97
|
# or nil otherwise. This and simple_pk are used for an optimization in Model.[].
|
109
98
|
attr_reader :simple_table
|
110
99
|
|
111
|
-
# Whether new
|
100
|
+
# Whether mass assigning via .create/.new/#set/#update should raise an error
|
112
101
|
# if an invalid key is used. A key is invalid if no setter method exists
|
113
102
|
# for that key or the access to the setter method is restricted (e.g. due to it
|
114
103
|
# being a primary key field). If set to false, silently skip
|
@@ -127,10 +116,16 @@ module Sequel
|
|
127
116
|
# database to typecast the value correctly.
|
128
117
|
attr_accessor :typecast_on_assignment
|
129
118
|
|
130
|
-
#
|
131
|
-
|
132
|
-
|
133
|
-
|
119
|
+
# :nocov:
|
120
|
+
def use_after_commit_rollback
|
121
|
+
Sequel::Deprecation.deprecate("Model.use_after_commit_rollback", "Model transaction hooks have been removed, switch to using database transaction hooks")
|
122
|
+
false
|
123
|
+
end
|
124
|
+
def use_after_commit_rollback=(v)
|
125
|
+
Sequel::Deprecation.deprecate("Model.use_after_commit_rollback=", "Model transaction hooks have been removed, switch to using database transaction hooks")
|
126
|
+
false
|
127
|
+
end
|
128
|
+
# :nocov:
|
134
129
|
|
135
130
|
# Whether to use a transaction by default when saving/deleting records (default: true).
|
136
131
|
# If you are sending database queries in before_* or after_* hooks, you shouldn't change
|
@@ -159,7 +154,7 @@ module Sequel
|
|
159
154
|
# end
|
160
155
|
def def_Model(mod)
|
161
156
|
model = self
|
162
|
-
|
157
|
+
mod.define_singleton_method(:Model) do |source|
|
163
158
|
model.Model(source)
|
164
159
|
end
|
165
160
|
end
|
@@ -179,11 +174,8 @@ module Sequel
|
|
179
174
|
# classes in order to create the dataset.
|
180
175
|
#
|
181
176
|
# The purpose of this method is to set the dataset/database automatically
|
182
|
-
# for a model class, if the table name doesn't match the
|
183
|
-
# name
|
184
|
-
# doesn't require a bogus query for the schema, and works when using
|
185
|
-
# +require_valid_table+, or with plugins that assume a model's dataset
|
186
|
-
# is valid.
|
177
|
+
# for a model class, if the table name doesn't match the default table
|
178
|
+
# name that Sequel would use.
|
187
179
|
#
|
188
180
|
# When creating subclasses of Sequel::Model itself, this method is usually
|
189
181
|
# called on Sequel itself, using <tt>Sequel::Model(:something)</tt>.
|
@@ -225,22 +217,6 @@ module Sequel
|
|
225
217
|
klass
|
226
218
|
end
|
227
219
|
|
228
|
-
def initialize_copy(_)
|
229
|
-
Sequel::Deprecation.deprecate("Model.clone", "Create a subclass of the model instead of cloning it")
|
230
|
-
# raise(Error, "cannot dup/clone a Sequel::Model class") # SEQUEL5
|
231
|
-
super
|
232
|
-
end
|
233
|
-
def dup
|
234
|
-
Sequel::Deprecation.deprecate("Model.dup", "Create a subclass of the model instead of duping it")
|
235
|
-
# raise(Error, "cannot dup/clone a Sequel::Model class") # SEQUEL5
|
236
|
-
super
|
237
|
-
end
|
238
|
-
|
239
|
-
def <<(arg)
|
240
|
-
Sequel::Deprecation.deprecate("Sequel::Model.<<", "Switch to using #insert")
|
241
|
-
dataset << (arg)
|
242
|
-
end
|
243
|
-
|
244
220
|
# Returns the first record from the database matching the conditions.
|
245
221
|
# If a hash is given, it is used as the conditions. If another
|
246
222
|
# object is given, it finds the first record whose primary key(s) match
|
@@ -249,7 +225,7 @@ module Sequel
|
|
249
225
|
# Artist[1] # SELECT * FROM artists WHERE id = 1
|
250
226
|
# # => #<Artist {:id=>1, ...}>
|
251
227
|
#
|
252
|
-
# Artist[:
|
228
|
+
# Artist[name: 'Bob'] # SELECT * FROM artists WHERE (name = 'Bob') LIMIT 1
|
253
229
|
# # => #<Artist {:name=>'Bob', ...}>
|
254
230
|
def [](*args)
|
255
231
|
args = args.first if args.size <= 1
|
@@ -286,7 +262,7 @@ module Sequel
|
|
286
262
|
|
287
263
|
# Creates instance using new with the given values and block, and saves it.
|
288
264
|
#
|
289
|
-
# Artist.create(:
|
265
|
+
# Artist.create(name: 'Bob')
|
290
266
|
# # INSERT INTO artists (name) VALUES ('Bob')
|
291
267
|
#
|
292
268
|
# Artist.create do |a|
|
@@ -315,7 +291,7 @@ module Sequel
|
|
315
291
|
# a plugin with the methods defined in DatasetMethods.
|
316
292
|
# This is the recommended way to add methods to model datasets.
|
317
293
|
#
|
318
|
-
# If an argument, it should be a module, and is used to extend
|
294
|
+
# If given an argument, it should be a module, and is used to extend
|
319
295
|
# the underlying dataset. Otherwise an anonymous module is created, and
|
320
296
|
# if a block is given, it is module_evaled, allowing you do define
|
321
297
|
# dataset methods directly using the standard ruby def syntax.
|
@@ -342,7 +318,7 @@ module Sequel
|
|
342
318
|
# named dataset methods:
|
343
319
|
#
|
344
320
|
# Album.dataset_module do
|
345
|
-
#
|
321
|
+
# where(:released, Sequel[:release_date] <= Sequel::CURRENT_DATE)
|
346
322
|
# order :by_release_date, :release_date
|
347
323
|
# select :for_select_options, :id, :name, :release_date
|
348
324
|
# end
|
@@ -359,6 +335,10 @@ module Sequel
|
|
359
335
|
# group_append, having, limit, offset, order, order_append, order_prepend, select, select_all,
|
360
336
|
# select_append, select_group, where, and server.
|
361
337
|
#
|
338
|
+
# The advantage of using these DatasetModule methods to define your dataset
|
339
|
+
# methods is that they can take advantage of dataset caching to improve
|
340
|
+
# performance.
|
341
|
+
#
|
362
342
|
# Any public methods in the dataset module will have class methods created that
|
363
343
|
# call the method on the dataset, assuming that the class method is not already
|
364
344
|
# defined.
|
@@ -382,7 +362,7 @@ module Sequel
|
|
382
362
|
# been created, raises an error.
|
383
363
|
#
|
384
364
|
# Artist.db.transaction do # BEGIN
|
385
|
-
# Artist.create(:
|
365
|
+
# Artist.create(name: 'Bob')
|
386
366
|
# # INSERT INTO artists (name) VALUES ('Bob')
|
387
367
|
# end # COMMIT
|
388
368
|
def db
|
@@ -392,26 +372,23 @@ module Sequel
|
|
392
372
|
@db
|
393
373
|
end
|
394
374
|
|
395
|
-
# Sets the database associated with the Model class.
|
396
|
-
#
|
397
|
-
#
|
398
|
-
#
|
399
|
-
# Sequel::Model to set the default database to be used
|
400
|
-
# by subclasses, or to override the database used for specific
|
401
|
-
# models:
|
375
|
+
# Sets the database associated with the Model class.
|
376
|
+
# Should only be used if the Model class currently does not
|
377
|
+
# have a dataset defined.
|
378
|
+
#
|
379
|
+
# This can be used directly on Sequel::Model to set the default database to be used
|
380
|
+
# by subclasses, or to override the database used for specific models:
|
402
381
|
#
|
403
382
|
# Sequel::Model.db = DB1
|
383
|
+
# Artist = Class.new(Sequel::Model)
|
404
384
|
# Artist.db = DB2
|
405
385
|
#
|
406
386
|
# Note that you should not use this to change the model's database
|
407
387
|
# at runtime. If you have that need, you should look into Sequel's
|
408
|
-
# sharding support.
|
388
|
+
# sharding support, or consider using separate model classes per Database.
|
409
389
|
def db=(db)
|
390
|
+
raise Error, "Cannot use Sequel::Model.db= on model with existing dataset. Use Sequel::Model.dataset= instead." if @dataset
|
410
391
|
@db = db
|
411
|
-
if @dataset
|
412
|
-
Sequel::Deprecation.deprecate("Sequel::Model.db= when the model has an existing dataset", "Use Sequel::Model.dataset= instead")
|
413
|
-
set_dataset(db.dataset.clone(@dataset.opts))
|
414
|
-
end
|
415
392
|
end
|
416
393
|
|
417
394
|
# Returns the cached schema information if available or gets it
|
@@ -438,44 +415,10 @@ module Sequel
|
|
438
415
|
end
|
439
416
|
end
|
440
417
|
|
441
|
-
# If a block is given, define a method on the dataset (if the model currently has an dataset) with the given argument name using
|
442
|
-
# the given block. Also define a class method on the model that calls the
|
443
|
-
# dataset method. Stores the method name and block so that it can be reapplied if the model's
|
444
|
-
# dataset changes.
|
445
|
-
#
|
446
|
-
# If a block is not given, just define a class method on the model for each argument
|
447
|
-
# that calls the dataset method of the same argument name.
|
448
|
-
#
|
449
|
-
# Using dataset_module is recommended over using this method. In addition to allowing
|
450
|
-
# more natural ruby syntax for defining methods manually, it also offers numerous
|
451
|
-
# helper methods that make defining common dataset methods more easily, as well as
|
452
|
-
# supporting dataset caching (assuming the arguments allow it).
|
453
|
-
#
|
454
|
-
# # Add new dataset method and class method that calls it
|
455
|
-
# Artist.def_dataset_method(:by_name){order(:name)}
|
456
|
-
# Artist.where(:name.like('A%')).by_name
|
457
|
-
# Artist.by_name.where(:name.like('A%'))
|
458
|
-
#
|
459
|
-
# # Just add a class method that calls an existing dataset method
|
460
|
-
# Artist.def_dataset_method(:paginate)
|
461
|
-
# Artist.paginate(2, 10)
|
462
|
-
def def_dataset_method(*args, &block)
|
463
|
-
raise(Error, "No arguments given") if args.empty?
|
464
|
-
|
465
|
-
if block
|
466
|
-
raise(Error, "Defining a dataset method using a block requires only one argument") if args.length > 1
|
467
|
-
Sequel::Deprecation.deprecate("Sequel::Model.def_dataset_method", "Define the method inside a dataset_module block, or use the def_dataset_method_plugin")
|
468
|
-
dataset_module{define_method(args.first, &block)}
|
469
|
-
else
|
470
|
-
Sequel::Deprecation.deprecate("Sequel::Model.def_dataset_method", "Define a class method that calls the dataset method, or use the def_dataset_method_plugin")
|
471
|
-
args.each{|arg| def_model_dataset_method(arg)}
|
472
|
-
end
|
473
|
-
end
|
474
|
-
|
475
418
|
# Finds a single record according to the supplied filter.
|
476
419
|
# You are encouraged to use Model.[] or Model.first instead of this method.
|
477
420
|
#
|
478
|
-
# Artist.find(:
|
421
|
+
# Artist.find(name: 'Bob')
|
479
422
|
# # SELECT * FROM artists WHERE (name = 'Bob') LIMIT 1
|
480
423
|
#
|
481
424
|
# Artist.find{name > 'M'}
|
@@ -489,171 +432,33 @@ module Sequel
|
|
489
432
|
# to +find+, but instead is passed to +create+ only if +find+ does not
|
490
433
|
# return an object.
|
491
434
|
#
|
492
|
-
# Artist.find_or_create(:
|
435
|
+
# Artist.find_or_create(name: 'Bob')
|
493
436
|
# # SELECT * FROM artists WHERE (name = 'Bob') LIMIT 1
|
494
437
|
# # INSERT INTO artists (name) VALUES ('Bob')
|
495
438
|
#
|
496
|
-
# Artist.find_or_create(:
|
439
|
+
# Artist.find_or_create(name: 'Jim'){|a| a.hometown = 'Sactown'}
|
497
440
|
# # SELECT * FROM artists WHERE (name = 'Jim') LIMIT 1
|
498
441
|
# # INSERT INTO artists (name, hometown) VALUES ('Jim', 'Sactown')
|
499
442
|
def find_or_create(cond, &block)
|
500
443
|
find(cond) || create(cond, &block)
|
501
444
|
end
|
502
445
|
|
503
|
-
FINDER_TYPES = [:first, :all, :each, :get].freeze
|
504
|
-
|
505
|
-
# Create an optimized finder method using a dataset placeholder literalizer.
|
506
|
-
# This pre-computes the SQL to use for the query, except for given arguments.
|
507
|
-
#
|
508
|
-
# There are two ways to use this. The recommended way is to pass a symbol
|
509
|
-
# that represents a model class method that returns a dataset:
|
510
|
-
#
|
511
|
-
# def Artist.by_name(name)
|
512
|
-
# where(:name=>name)
|
513
|
-
# end
|
514
|
-
#
|
515
|
-
# Artist.finder :by_name
|
516
|
-
#
|
517
|
-
# This creates an optimized first_by_name method, which you can call normally:
|
518
|
-
#
|
519
|
-
# Artist.first_by_name("Joe")
|
520
|
-
#
|
521
|
-
# The alternative way to use this to pass your own block:
|
522
|
-
#
|
523
|
-
# Artist.finder(:name=>:first_by_name){|pl, ds| ds.where(:name=>pl.arg).limit(1)}
|
524
|
-
#
|
525
|
-
# Note that if you pass your own block, you are responsible for manually setting
|
526
|
-
# limits if necessary (as shown above).
|
527
|
-
#
|
528
|
-
# Options:
|
529
|
-
# :arity :: When using a symbol method name, this specifies the arity of the method.
|
530
|
-
# This should be used if if the method accepts an arbitrary number of arguments,
|
531
|
-
# or the method has default argument values. Note that if the method is defined
|
532
|
-
# as a dataset method, the class method Sequel creates accepts an arbitrary number
|
533
|
-
# of arguments, so you should use this option in that case. If you want to handle
|
534
|
-
# multiple possible arities, you need to call the finder method multiple times with
|
535
|
-
# unique :arity and :name methods each time.
|
536
|
-
# :name :: The name of the method to create. This must be given if you pass a block.
|
537
|
-
# If you use a symbol, this defaults to the symbol prefixed by the type.
|
538
|
-
# :mod :: The module in which to create the finder method. Defaults to the singleton
|
539
|
-
# class of the model.
|
540
|
-
# :type :: The type of query to run. Can be :first, :each, :all, or :get, defaults to
|
541
|
-
# :first.
|
542
|
-
#
|
543
|
-
# Caveats:
|
544
|
-
#
|
545
|
-
# This doesn't handle all possible cases. For example, if you have a method such as:
|
546
|
-
#
|
547
|
-
# def Artist.by_name(name)
|
548
|
-
# name ? where(:name=>name) : exclude(:name=>nil)
|
549
|
-
# end
|
550
|
-
#
|
551
|
-
# Then calling a finder without an argument will not work as you expect.
|
552
|
-
#
|
553
|
-
# Artist.finder :by_name
|
554
|
-
# Artist.by_name(nil).first
|
555
|
-
# # WHERE (name IS NOT NULL)
|
556
|
-
# Artist.first_by_name(nil)
|
557
|
-
# # WHERE (name IS NULL)
|
558
|
-
#
|
559
|
-
# See Dataset::PlaceholderLiteralizer for additional caveats.
|
560
|
-
def finder(meth=OPTS, opts=OPTS, &block)
|
561
|
-
Sequel::Deprecation.deprecate("Sequel::Model.finder and Sequel::Model.prepared_finder", "They have been moved to the finder plugin")
|
562
|
-
if block
|
563
|
-
raise Error, "cannot pass both a method name argument and a block of Model.finder" unless meth.is_a?(Hash)
|
564
|
-
raise Error, "cannot pass two option hashes to Model.finder" unless opts.equal?(OPTS)
|
565
|
-
opts = meth
|
566
|
-
raise Error, "must provide method name via :name option when passing block to Model.finder" unless meth_name = opts[:name]
|
567
|
-
end
|
568
|
-
|
569
|
-
type = opts.fetch(:type, :first)
|
570
|
-
unless prepare = opts[:prepare]
|
571
|
-
raise Error, ":type option to Model.finder must be :first, :all, :each, or :get" unless FINDER_TYPES.include?(type)
|
572
|
-
end
|
573
|
-
limit1 = type == :first || type == :get
|
574
|
-
meth_name ||= opts[:name] || :"#{type}_#{meth}"
|
575
|
-
|
576
|
-
argn = lambda do |model|
|
577
|
-
if arity = opts[:arity]
|
578
|
-
arity
|
579
|
-
else
|
580
|
-
method = block || model.method(meth)
|
581
|
-
(method.arity < 0 ? method.arity.abs - 1 : method.arity)
|
582
|
-
end
|
583
|
-
end
|
584
|
-
|
585
|
-
loader_proc = if prepare
|
586
|
-
proc do |model|
|
587
|
-
args = prepare_method_args('$a', argn.call(model))
|
588
|
-
ds = if block
|
589
|
-
model.instance_exec(*args, &block)
|
590
|
-
else
|
591
|
-
model.send(meth, *args)
|
592
|
-
end
|
593
|
-
ds = ds.limit(1) if limit1
|
594
|
-
model_name = model.name
|
595
|
-
if model_name.to_s.empty?
|
596
|
-
model_name = model.object_id
|
597
|
-
else
|
598
|
-
model_name = model_name.gsub(/\W/, '_')
|
599
|
-
end
|
600
|
-
ds.prepare(type, :"#{model_name}_#{meth_name}")
|
601
|
-
end
|
602
|
-
else
|
603
|
-
proc do |model|
|
604
|
-
n = argn.call(model)
|
605
|
-
block ||= lambda do |pl, model2|
|
606
|
-
args = (0...n).map{pl.arg}
|
607
|
-
ds = model2.send(meth, *args)
|
608
|
-
ds = ds.limit(1) if limit1
|
609
|
-
ds
|
610
|
-
end
|
611
|
-
|
612
|
-
Sequel::Dataset::PlaceholderLiteralizer.loader(model, &block)
|
613
|
-
end
|
614
|
-
end
|
615
|
-
|
616
|
-
@finder_loaders[meth_name] = loader_proc
|
617
|
-
mod = opts[:mod] || (class << self; self; end)
|
618
|
-
if prepare
|
619
|
-
def_prepare_method(mod, meth_name)
|
620
|
-
else
|
621
|
-
def_finder_method(mod, meth_name, type)
|
622
|
-
end
|
623
|
-
end
|
624
|
-
|
625
|
-
def first_where(cond)
|
626
|
-
Sequel::Deprecation.deprecate("Sequel::Model.first_where", "Instead, use Sequel::Model.first")
|
627
|
-
if cond.is_a?(Integer)
|
628
|
-
dataset.where(cond).first(cond)
|
629
|
-
else
|
630
|
-
dataset.first(cond)
|
631
|
-
end
|
632
|
-
end
|
633
|
-
|
634
446
|
# Freeze a model class, disallowing any further changes to it.
|
635
447
|
def freeze
|
636
448
|
dataset_module.freeze
|
637
449
|
overridable_methods_module.freeze
|
638
450
|
|
639
|
-
@finder_loaders.freeze # SEQUEL5: Remove
|
640
|
-
|
641
451
|
if @dataset
|
642
|
-
@dataset.freeze
|
643
|
-
@instance_dataset.freeze
|
644
452
|
db_schema.freeze.each_value(&:freeze)
|
645
453
|
columns.freeze
|
646
454
|
setter_methods.freeze
|
647
|
-
@finder_loaders.each_key{|k| finder_for(k)} # SEQUEL5: Remove
|
648
455
|
else
|
649
456
|
@setter_methods = [].freeze
|
650
457
|
end
|
651
458
|
|
652
459
|
@dataset_method_modules.freeze
|
653
460
|
@default_set_fields_options.freeze
|
654
|
-
@finders.freeze # SEQUEL5: Remove
|
655
461
|
@plugins.freeze
|
656
|
-
@allowed_columns.freeze if @allowed_columns # SEQUEL5: Remove
|
657
462
|
|
658
463
|
super
|
659
464
|
end
|
@@ -676,9 +481,9 @@ module Sequel
|
|
676
481
|
# end
|
677
482
|
def inherited(subclass)
|
678
483
|
super
|
679
|
-
ivs = subclass.instance_variables
|
484
|
+
ivs = subclass.instance_variables
|
680
485
|
inherited_instance_variables.each do |iv, dup|
|
681
|
-
next if ivs.include?(iv
|
486
|
+
next if ivs.include?(iv)
|
682
487
|
if (sup_class_value = instance_variable_get(iv)) && dup
|
683
488
|
sup_class_value = case dup
|
684
489
|
when :dup
|
@@ -720,7 +525,7 @@ module Sequel
|
|
720
525
|
call(values)
|
721
526
|
end
|
722
527
|
|
723
|
-
# Clear the setter_methods cache when a setter method is added
|
528
|
+
# Clear the setter_methods cache when a setter method is added.
|
724
529
|
def method_added(meth)
|
725
530
|
clear_setter_methods_cache if meth.to_s.end_with?('=')
|
726
531
|
super
|
@@ -739,17 +544,16 @@ module Sequel
|
|
739
544
|
|
740
545
|
# Loads a plugin for use with the model class, passing optional arguments
|
741
546
|
# to the plugin. If the plugin is a module, load it directly. Otherwise,
|
742
|
-
# require the plugin from
|
743
|
-
#
|
744
|
-
# the camelized plugin name under Sequel::Plugins.
|
547
|
+
# require the plugin from sequel/plugins/#{plugin} and then attempt to load
|
548
|
+
# the module using a the camelized plugin name under Sequel::Plugins.
|
745
549
|
def plugin(plugin, *args, &block)
|
746
550
|
m = plugin.is_a?(Module) ? plugin : plugin_module(plugin)
|
747
551
|
unless @plugins.include?(m)
|
748
552
|
@plugins << m
|
749
553
|
m.apply(self, *args, &block) if m.respond_to?(:apply)
|
750
|
-
extend(m::ClassMethods) if
|
751
|
-
include(m::InstanceMethods) if
|
752
|
-
if
|
554
|
+
extend(m::ClassMethods) if m.const_defined?(:ClassMethods, false)
|
555
|
+
include(m::InstanceMethods) if m.const_defined?(:InstanceMethods, false)
|
556
|
+
if m.const_defined?(:DatasetMethods, false)
|
753
557
|
dataset_extend(m::DatasetMethods, :create_class_methods=>false)
|
754
558
|
end
|
755
559
|
end
|
@@ -797,28 +601,6 @@ module Sequel
|
|
797
601
|
end
|
798
602
|
end
|
799
603
|
|
800
|
-
# Similar to finder, but uses a prepared statement instead of a placeholder
|
801
|
-
# literalizer. This makes the SQL used static (cannot vary per call), but
|
802
|
-
# allows binding argument values instead of literalizing them into the SQL
|
803
|
-
# query string.
|
804
|
-
#
|
805
|
-
# If a block is used with this method, it is instance_execed by the model,
|
806
|
-
# and should accept the desired number of placeholder arguments.
|
807
|
-
#
|
808
|
-
# The options are the same as the options for finder, with the following
|
809
|
-
# exception:
|
810
|
-
# :type :: Specifies the type of prepared statement to create
|
811
|
-
def prepared_finder(meth=OPTS, opts=OPTS, &block)
|
812
|
-
# SEQUEL5: Remove
|
813
|
-
if block
|
814
|
-
raise Error, "cannot pass both a method name argument and a block of Model.finder" unless meth.is_a?(Hash)
|
815
|
-
meth = meth.merge(:prepare=>true)
|
816
|
-
else
|
817
|
-
opts = opts.merge(:prepare=>true)
|
818
|
-
end
|
819
|
-
finder(meth, opts, &block)
|
820
|
-
end
|
821
|
-
|
822
604
|
# Restrict the setting of the primary key(s) when using mass assignment (e.g. +set+). Because
|
823
605
|
# this is the default, this only make sense to use in a subclass where the
|
824
606
|
# parent class has used +unrestrict_primary_key+.
|
@@ -833,23 +615,6 @@ module Sequel
|
|
833
615
|
@restrict_primary_key
|
834
616
|
end
|
835
617
|
|
836
|
-
# Set the columns to allow when using mass assignment (e.g. +set+). Using this means that
|
837
|
-
# any columns not listed here will not be modified. If you have any virtual
|
838
|
-
# setter methods (methods that end in =) that you want to be used during
|
839
|
-
# mass assignment, they need to be listed here as well (without the =).
|
840
|
-
#
|
841
|
-
# It may be better to use a method such as +set_only+ or +set_fields+ that lets you specify
|
842
|
-
# the allowed fields per call.
|
843
|
-
#
|
844
|
-
# Artist.set_allowed_columns(:name, :hometown)
|
845
|
-
# Artist.set(:name=>'Bob', :hometown=>'Sactown') # No Error
|
846
|
-
# Artist.set(:name=>'Bob', :records_sold=>30000) # Error
|
847
|
-
def set_allowed_columns(*cols)
|
848
|
-
Sequel::Deprecation.deprecate("Sequel::Model.set_allowed_columns", "Load the whitelist_security plugin into the model class")
|
849
|
-
clear_setter_methods_cache
|
850
|
-
@allowed_columns = cols
|
851
|
-
end
|
852
|
-
|
853
618
|
# Sets the dataset associated with the Model class. +ds+ can be a +Symbol+,
|
854
619
|
# +LiteralString+, <tt>SQL::Identifier</tt>, <tt>SQL::QualifiedIdentifier</tt>,
|
855
620
|
# <tt>SQL::AliasedExpression</tt>
|
@@ -864,26 +629,22 @@ module Sequel
|
|
864
629
|
#
|
865
630
|
# Note that you should not use this to change the model's dataset
|
866
631
|
# at runtime. If you have that need, you should look into Sequel's
|
867
|
-
# sharding support
|
868
|
-
#
|
869
|
-
# You should avoid calling this method directly. Instead of doing:
|
870
|
-
#
|
871
|
-
# class Artist < Sequel::Model
|
872
|
-
# set_dataset :tbl_artists
|
873
|
-
# end
|
632
|
+
# sharding support, or creating a separate Model class per dataset
|
874
633
|
#
|
875
|
-
# You should
|
634
|
+
# You should avoid calling this method directly if possible. Instead you should
|
635
|
+
# set the table name or dataset when creating the model class:
|
876
636
|
#
|
637
|
+
# # table name
|
877
638
|
# class Artist < Sequel::Model(:tbl_artists)
|
878
639
|
# end
|
879
640
|
#
|
880
|
-
#
|
881
|
-
#
|
882
|
-
#
|
641
|
+
# # dataset
|
642
|
+
# class Artist < Sequel::Model(DB[:tbl_artists])
|
643
|
+
# end
|
883
644
|
def set_dataset(ds, opts=OPTS)
|
884
645
|
inherited = opts[:inherited]
|
885
646
|
@dataset = convert_input_dataset(ds)
|
886
|
-
@require_modification =
|
647
|
+
@require_modification = @dataset.provides_accurate_rows_matched? if require_modification.nil?
|
887
648
|
if inherited
|
888
649
|
self.simple_table = superclass.simple_table
|
889
650
|
@columns = superclass.instance_variable_get(:@columns)
|
@@ -899,7 +660,7 @@ module Sequel
|
|
899
660
|
|
900
661
|
# Sets the primary key for this model. You can use either a regular
|
901
662
|
# or a composite primary key. To not use a primary key, set to nil
|
902
|
-
# or use +no_primary_key+.
|
663
|
+
# or use +no_primary_key+. On most adapters, Sequel can automatically
|
903
664
|
# determine the primary key to use, so this method is not needed often.
|
904
665
|
#
|
905
666
|
# class Person < Sequel::Model
|
@@ -926,39 +687,12 @@ module Sequel
|
|
926
687
|
@primary_key = key
|
927
688
|
end
|
928
689
|
|
929
|
-
# Cache of setter methods to allow by default, in order to speed up
|
690
|
+
# Cache of setter methods to allow by default, in order to speed up mass assignment.
|
930
691
|
def setter_methods
|
931
692
|
return @setter_methods if @setter_methods
|
932
693
|
@setter_methods = get_setter_methods
|
933
694
|
end
|
934
695
|
|
935
|
-
# Sets up a dataset method that returns a filtered dataset.
|
936
|
-
# Sometimes thought of as a scope, and like most dataset methods,
|
937
|
-
# they can be chained.
|
938
|
-
# For example:
|
939
|
-
#
|
940
|
-
# Topic.subset(:joes, :username.like('%joe%'))
|
941
|
-
# Topic.subset(:popular){num_posts > 100}
|
942
|
-
# Topic.subset(:recent){created_on > Date.today - 7}
|
943
|
-
#
|
944
|
-
# Allows you to do:
|
945
|
-
#
|
946
|
-
# Topic.joes.recent.popular
|
947
|
-
#
|
948
|
-
# to get topics with a username that includes joe that
|
949
|
-
# have more than 100 posts and were created less than
|
950
|
-
# 7 days ago.
|
951
|
-
#
|
952
|
-
# Both the args given and the block are passed to <tt>Dataset#filter</tt>.
|
953
|
-
#
|
954
|
-
# This method creates dataset methods that do not accept arguments. To create
|
955
|
-
# dataset methods that accept arguments, you should use define a
|
956
|
-
# method directly inside a #dataset_module block.
|
957
|
-
def subset(*args, &block)
|
958
|
-
Sequel::Deprecation.deprecate("Sequel::Model.subset", "Use the subset method inside a dataset_module block, or use the def_dataset_method plugin")
|
959
|
-
dataset_module{where(*args, &block)}
|
960
|
-
end
|
961
|
-
|
962
696
|
# Returns name of primary table for the dataset. If the table for the dataset
|
963
697
|
# is aliased, returns the aliased name.
|
964
698
|
#
|
@@ -972,9 +706,9 @@ module Sequel
|
|
972
706
|
# Allow the setting of the primary key(s) when using the mass assignment methods.
|
973
707
|
# Using this method can open up security issues, be very careful before using it.
|
974
708
|
#
|
975
|
-
# Artist.set(:
|
709
|
+
# Artist.set(id: 1) # Error
|
976
710
|
# Artist.unrestrict_primary_key
|
977
|
-
# Artist.set(:
|
711
|
+
# Artist.set(id: 1) # No Error
|
978
712
|
def unrestrict_primary_key
|
979
713
|
clear_setter_methods_cache
|
980
714
|
@restrict_primary_key = false
|
@@ -991,26 +725,18 @@ module Sequel
|
|
991
725
|
end
|
992
726
|
|
993
727
|
# Add model methods that call dataset methods
|
994
|
-
Plugins.def_dataset_methods(self, (Dataset::ACTION_METHODS + Dataset::QUERY_METHODS + [:each_server]) - [:<<, :
|
995
|
-
# SEQUEL5: add :set_graph_aliases to remove list and remove :and
|
728
|
+
Plugins.def_dataset_methods(self, (Dataset::ACTION_METHODS + Dataset::QUERY_METHODS + [:each_server]) - [:<<, :or, :[], :columns, :columns!, :delete, :update, :set_graph_aliases, :add_graph_aliases])
|
996
729
|
|
997
730
|
private
|
998
731
|
|
999
|
-
# Yield to the passed block and swallow all errors other than DatabaseConnectionErrors.
|
732
|
+
# Yield to the passed block and if do_raise is false, swallow all errors other than DatabaseConnectionErrors.
|
1000
733
|
def check_non_connection_error(do_raise=require_valid_table)
|
1001
734
|
begin
|
1002
735
|
db.transaction(:savepoint=>:only){yield}
|
1003
736
|
rescue Sequel::DatabaseConnectionError
|
1004
737
|
raise
|
1005
738
|
rescue Sequel::Error
|
1006
|
-
|
1007
|
-
when nil
|
1008
|
-
Sequel::Deprecation.deprecate("Setting a model class dataset to an invalid dataset", "Either use a valid dataset or set require_valid_table = false for the model class")
|
1009
|
-
when false
|
1010
|
-
# nothing
|
1011
|
-
else
|
1012
|
-
raise
|
1013
|
-
end
|
739
|
+
raise if do_raise
|
1014
740
|
end
|
1015
741
|
end
|
1016
742
|
|
@@ -1022,10 +748,7 @@ module Sequel
|
|
1022
748
|
self.simple_table = db.literal(ds).freeze
|
1023
749
|
ds = db.from(ds)
|
1024
750
|
when Dataset
|
1025
|
-
if ds.joined_dataset?
|
1026
|
-
# raise Error, "Using a joined dataset as a model dataset is not support, use from_self on the dataset to wrap it in a subquery" # SEQUEL5
|
1027
|
-
Sequel::Deprecation.deprecate("Using a joined dataset as a Sequel::Model dataset", respond_to?(:cti_base_model) ? "Use the class_table_inheritance plugin :alias option in #{cti_base_model.inspect}" : "Call from_self on the dataset to wrap it in a subquery")
|
1028
|
-
end
|
751
|
+
ds = ds.from_self(:alias=>ds.first_source) if ds.joined_dataset?
|
1029
752
|
|
1030
753
|
self.simple_table = if ds.send(:simple_select_all?)
|
1031
754
|
ds.literal(ds.first_source_table).freeze
|
@@ -1064,16 +787,16 @@ module Sequel
|
|
1064
787
|
clear_setter_methods_cache
|
1065
788
|
columns, bad_columns = columns.partition{|x| /\A[A-Za-z_][A-Za-z0-9_]*\z/.match(x.to_s)}
|
1066
789
|
bad_columns.each{|x| def_bad_column_accessor(x)}
|
1067
|
-
im = instance_methods
|
790
|
+
im = instance_methods
|
1068
791
|
columns.each do |column|
|
1069
792
|
meth = "#{column}="
|
1070
|
-
overridable_methods_module.module_eval("def #{column}; self[:#{column}] end", __FILE__, __LINE__) unless im.include?(column
|
793
|
+
overridable_methods_module.module_eval("def #{column}; self[:#{column}] end", __FILE__, __LINE__) unless im.include?(column)
|
1071
794
|
overridable_methods_module.module_eval("def #{meth}(v); self[:#{column}] = v end", __FILE__, __LINE__) unless im.include?(meth)
|
1072
795
|
end
|
1073
796
|
end
|
1074
797
|
|
1075
798
|
# Define a model method that calls the dataset method with the same name,
|
1076
|
-
# only used for methods with names that can't be
|
799
|
+
# only used for methods with names that can't be represented directly in
|
1077
800
|
# ruby code.
|
1078
801
|
def def_model_dataset_method(meth)
|
1079
802
|
return if respond_to?(meth, true)
|
@@ -1081,37 +804,10 @@ module Sequel
|
|
1081
804
|
if meth.to_s =~ /\A[A-Za-z_][A-Za-z0-9_]*\z/
|
1082
805
|
instance_eval("def #{meth}(*args, &block); dataset.#{meth}(*args, &block) end", __FILE__, __LINE__)
|
1083
806
|
else
|
1084
|
-
(
|
807
|
+
define_singleton_method(meth){|*args, &block| dataset.public_send(meth, *args, &block)}
|
1085
808
|
end
|
1086
809
|
end
|
1087
810
|
|
1088
|
-
# Define a finder method in the given module with the given method name that
|
1089
|
-
# load rows using the finder with the given name.
|
1090
|
-
def def_finder_method(mod, meth, type)
|
1091
|
-
# SEQUEL5: Remove
|
1092
|
-
mod.send(:define_method, meth){|*args, &block| finder_for(meth).send(type, *args, &block)}
|
1093
|
-
end
|
1094
|
-
|
1095
|
-
# Define a prepared_finder method in the given module that will call the associated prepared
|
1096
|
-
# statement.
|
1097
|
-
def def_prepare_method(mod, meth)
|
1098
|
-
# SEQUEL5: Remove
|
1099
|
-
mod.send(:define_method, meth){|*args, &block| finder_for(meth).call(prepare_method_arg_hash(args), &block)}
|
1100
|
-
end
|
1101
|
-
|
1102
|
-
# Find the finder to use for the give method. If a finder has not been loaded
|
1103
|
-
# for the method, load the finder and set correctly in the finders hash, then
|
1104
|
-
# return the finder.
|
1105
|
-
def finder_for(meth)
|
1106
|
-
# SEQUEL5: Remove
|
1107
|
-
unless finder = (frozen? ? @finders[meth] : Sequel.synchronize{@finders[meth]})
|
1108
|
-
finder_loader = @finder_loaders.fetch(meth)
|
1109
|
-
finder = finder_loader.call(self)
|
1110
|
-
Sequel.synchronize{@finders[meth] = finder}
|
1111
|
-
end
|
1112
|
-
finder
|
1113
|
-
end
|
1114
|
-
|
1115
811
|
# Get the schema from the database, fall back on checking the columns
|
1116
812
|
# via the database if that will return inaccurate results or if
|
1117
813
|
# it raises an error.
|
@@ -1161,14 +857,9 @@ module Sequel
|
|
1161
857
|
# Uncached version of setter_methods, to be overridden by plugins
|
1162
858
|
# that want to modify the methods used.
|
1163
859
|
def get_setter_methods
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
else
|
1168
|
-
meths = instance_methods.map(&:to_s).select{|l| l.end_with?('=')} - RESTRICTED_SETTER_METHODS
|
1169
|
-
meths -= Array(primary_key).map{|x| "#{x}="} if primary_key && restrict_primary_key?
|
1170
|
-
meths
|
1171
|
-
end
|
860
|
+
meths = instance_methods.map(&:to_s).select{|l| l.end_with?('=')} - RESTRICTED_SETTER_METHODS
|
861
|
+
meths -= Array(primary_key).map{|x| "#{x}="} if primary_key && restrict_primary_key?
|
862
|
+
meths
|
1172
863
|
end
|
1173
864
|
|
1174
865
|
# A hash of instance variables to automatically set up in subclasses.
|
@@ -1179,7 +870,6 @@ module Sequel
|
|
1179
870
|
# Proc :: Call with subclass to do the assignment
|
1180
871
|
def inherited_instance_variables
|
1181
872
|
{
|
1182
|
-
:@allowed_columns=>:dup, # SEQUEL5: Remove
|
1183
873
|
:@cache_anonymous_models=>nil,
|
1184
874
|
:@dataset_method_modules=>:dup,
|
1185
875
|
:@dataset_module_class=>nil,
|
@@ -1187,8 +877,6 @@ module Sequel
|
|
1187
877
|
:@default_set_fields_options=>:dup,
|
1188
878
|
:@fast_instance_delete_sql=>nil,
|
1189
879
|
:@fast_pk_lookup_sql=>nil,
|
1190
|
-
:@finder_loaders=>:dup, # SEQUEL5: Remove
|
1191
|
-
:@finders=>:dup, # SEQUEL5: Remove
|
1192
880
|
:@plugins=>:dup,
|
1193
881
|
:@primary_key=>nil,
|
1194
882
|
:@raise_on_save_failure=>nil,
|
@@ -1202,7 +890,6 @@ module Sequel
|
|
1202
890
|
:@strict_param_setting=>nil,
|
1203
891
|
:@typecast_empty_string_to_nil=>nil,
|
1204
892
|
:@typecast_on_assignment=>nil,
|
1205
|
-
:@use_after_commit_rollback=>nil,
|
1206
893
|
:@use_transactions=>nil
|
1207
894
|
}
|
1208
895
|
end
|
@@ -1240,54 +927,19 @@ module Sequel
|
|
1240
927
|
# defined, the corresponding plugin required.
|
1241
928
|
def plugin_module(plugin)
|
1242
929
|
module_name = plugin.to_s.gsub(/(^|_)(.)/){|x| x[-1..-1].upcase}
|
1243
|
-
|
1244
|
-
|
1245
|
-
Sequel::Plugins.const_get(module_name) == Sequel.const_get(module_name))
|
1246
|
-
begin
|
1247
|
-
require "sequel/plugins/#{plugin}"
|
1248
|
-
rescue LoadError => e
|
1249
|
-
begin
|
1250
|
-
require "sequel_#{plugin}"
|
1251
|
-
Sequel::Deprecation.deprecate("requiring 'sequel_#{plugin}' to load a plugin", "Update the #{plugin} plugin to be required via 'sequel/plugins/#{plugin}'")
|
1252
|
-
rescue LoadError => e2
|
1253
|
-
e.message << "; #{e2.message}"
|
1254
|
-
raise e
|
1255
|
-
end
|
1256
|
-
end
|
930
|
+
unless Sequel::Plugins.const_defined?(module_name, false)
|
931
|
+
require "sequel/plugins/#{plugin}"
|
1257
932
|
end
|
1258
933
|
Sequel::Plugins.const_get(module_name)
|
1259
934
|
end
|
1260
935
|
|
1261
|
-
#
|
936
|
+
# :nocov:
|
1262
937
|
def plugin_module_defined?(plugin, submod)
|
1263
|
-
|
1264
|
-
|
1265
|
-
else
|
1266
|
-
# :nocov:
|
1267
|
-
plugin.const_defined?(submod)
|
1268
|
-
# :nocov:
|
1269
|
-
end
|
938
|
+
Sequel::Deprecation.deprecate("Model.plugin_module_defined? (private method)", "Use const_defined?(submod, false)")
|
939
|
+
plugin.const_defined?(submod, false)
|
1270
940
|
end
|
941
|
+
# :nocov:
|
1271
942
|
|
1272
|
-
# An hash of prepared argument values for the given arguments, with keys
|
1273
|
-
# starting at a. Used by the methods created by prepared_finder.
|
1274
|
-
def prepare_method_arg_hash(args)
|
1275
|
-
# SEQUEL5: Remove
|
1276
|
-
h = {}
|
1277
|
-
prepare_method_args('a', args.length).zip(args).each{|k, v| h[k] = v}
|
1278
|
-
h
|
1279
|
-
end
|
1280
|
-
|
1281
|
-
# An array of prepared statement argument names, of length n and starting with base.
|
1282
|
-
def prepare_method_args(base, n)
|
1283
|
-
# SEQUEL5: Remove
|
1284
|
-
(0...n).map do
|
1285
|
-
s = base.to_sym
|
1286
|
-
base = base.next
|
1287
|
-
s
|
1288
|
-
end
|
1289
|
-
end
|
1290
|
-
|
1291
943
|
# Find the row in the dataset that matches the primary key. Uses
|
1292
944
|
# a static SQL optimization if the table and primary key are simple.
|
1293
945
|
#
|
@@ -1301,9 +953,6 @@ module Sequel
|
|
1301
953
|
ds.literal_append(sql, pk)
|
1302
954
|
ds.fetch_rows(sql){|r| return ds.row_proc.call(r)}
|
1303
955
|
nil
|
1304
|
-
elsif dataset.joined_dataset?
|
1305
|
-
# SEQUEL5: Remove as joined model datasets are not allowed
|
1306
|
-
dataset.first(qualified_primary_key_hash(pk))
|
1307
956
|
else
|
1308
957
|
dataset.first(primary_key_hash(pk))
|
1309
958
|
end
|
@@ -1318,17 +967,16 @@ module Sequel
|
|
1318
967
|
# are used, or set it to nil if not used.
|
1319
968
|
def reset_fast_pk_lookup_sql
|
1320
969
|
@fast_pk_lookup_sql = if @simple_table && @simple_pk
|
1321
|
-
"SELECT * FROM
|
970
|
+
"SELECT * FROM #{@simple_table} WHERE #{@simple_pk} = ".freeze
|
1322
971
|
end
|
1323
972
|
@fast_instance_delete_sql = if @simple_table && @simple_pk
|
1324
|
-
"DELETE FROM
|
973
|
+
"DELETE FROM #{@simple_table} WHERE #{@simple_pk} = ".freeze
|
1325
974
|
end
|
1326
975
|
end
|
1327
976
|
|
1328
977
|
# Reset the instance dataset to a modified copy of the current dataset,
|
1329
978
|
# should be used whenever the model's dataset is modified.
|
1330
979
|
def reset_instance_dataset
|
1331
|
-
Sequel.synchronize{@finders.clear} if @finders && !@finders.frozen?
|
1332
980
|
@instance_dataset = @dataset.limit(1).naked.skip_limit_check if @dataset
|
1333
981
|
end
|
1334
982
|
|
@@ -1384,26 +1032,35 @@ module Sequel
|
|
1384
1032
|
# Define instance method(s) that calls class method(s) of the
|
1385
1033
|
# same name. Replaces the construct:
|
1386
1034
|
#
|
1387
|
-
# define_method(meth){self.class.
|
1035
|
+
# define_method(meth){self.class.public_send(meth)}
|
1388
1036
|
[:columns, :db, :primary_key, :db_schema].each{|meth| class_eval("def #{meth}; self.class.#{meth} end", __FILE__, __LINE__)}
|
1389
1037
|
|
1390
1038
|
# Define instance method(s) that calls class method(s) of the
|
1391
1039
|
# same name, caching the result in an instance variable. Define
|
1392
1040
|
# standard attr_writer method for modifying that instance variable.
|
1393
|
-
[:typecast_empty_string_to_nil, :typecast_on_assignment, :strict_param_setting,
|
1394
|
-
:raise_on_save_failure, :raise_on_typecast_failure, :require_modification, :use_transactions
|
1395
|
-
:use_after_commit_rollback # SEQUEL5: Remove
|
1396
|
-
].each do |meth|
|
1041
|
+
[:typecast_empty_string_to_nil, :typecast_on_assignment, :strict_param_setting,
|
1042
|
+
:raise_on_save_failure, :raise_on_typecast_failure, :require_modification, :use_transactions].each do |meth|
|
1397
1043
|
class_eval("def #{meth}; !defined?(@#{meth}) ? (frozen? ? self.class.#{meth} : (@#{meth} = self.class.#{meth})) : @#{meth} end", __FILE__, __LINE__)
|
1398
1044
|
attr_writer(meth)
|
1399
1045
|
end
|
1400
1046
|
|
1047
|
+
# :nocov:
|
1048
|
+
def use_after_commit_rollback
|
1049
|
+
Sequel::Deprecation.deprecate("Model#use_after_commit_rollback", "Model transaction hooks have been removed, switch to using database transaction hooks")
|
1050
|
+
false
|
1051
|
+
end
|
1052
|
+
def use_after_commit_rollback=(v)
|
1053
|
+
Sequel::Deprecation.deprecate("Model#use_after_commit_rollback=", "Model transaction hooks have been removed, switch to using database transaction hooks")
|
1054
|
+
false
|
1055
|
+
end
|
1056
|
+
# :nocov:
|
1057
|
+
|
1401
1058
|
# The hash of attribute values. Keys are symbols with the names of the
|
1402
1059
|
# underlying database columns. The returned hash is a reference to the
|
1403
1060
|
# receiver's values hash, and modifying it will also modify the receiver's
|
1404
1061
|
# values.
|
1405
1062
|
#
|
1406
|
-
# Artist.new(:
|
1063
|
+
# Artist.new(name: 'Bob').values # => {:name=>'Bob'}
|
1407
1064
|
# Artist[1].values # => {:id=>1, :name=>'Jim', ...}
|
1408
1065
|
attr_reader :values
|
1409
1066
|
alias to_hash values
|
@@ -1414,7 +1071,7 @@ module Sequel
|
|
1414
1071
|
# method names.
|
1415
1072
|
alias get_column_value send
|
1416
1073
|
|
1417
|
-
# Set the value of the column. Takes two
|
1074
|
+
# Set the value of the column. Takes two arguments. The first is a
|
1418
1075
|
# symbol or string argument for the column name, suffixed with =. The
|
1419
1076
|
# second is the value to set for the column. By default it calls send
|
1420
1077
|
# with the argument to set the value. This can be overridden if you have
|
@@ -1428,7 +1085,7 @@ module Sequel
|
|
1428
1085
|
# Arguments:
|
1429
1086
|
# values :: should be a hash to pass to set.
|
1430
1087
|
#
|
1431
|
-
# Artist.new(:
|
1088
|
+
# Artist.new(name: 'Bob')
|
1432
1089
|
#
|
1433
1090
|
# Artist.new do |a|
|
1434
1091
|
# a.name = 'Bob'
|
@@ -1530,11 +1187,8 @@ module Sequel
|
|
1530
1187
|
end
|
1531
1188
|
|
1532
1189
|
# Like delete but runs hooks before and after delete.
|
1533
|
-
#
|
1534
|
-
#
|
1535
|
-
# the item from the database and returns self. Uses a transaction
|
1536
|
-
# if use_transactions is true or if the :transaction option is given and
|
1537
|
-
# true.
|
1190
|
+
# Uses a transaction if use_transactions is true or if the
|
1191
|
+
# :transaction option is given and true.
|
1538
1192
|
#
|
1539
1193
|
# Artist[1].destroy # BEGIN; DELETE FROM artists WHERE (id = 1); COMMIT;
|
1540
1194
|
# # => #<Artist {:id=>1, ...}>
|
@@ -1598,7 +1252,7 @@ module Sequel
|
|
1598
1252
|
validate
|
1599
1253
|
errors.freeze
|
1600
1254
|
end
|
1601
|
-
this
|
1255
|
+
this if !new? && model.primary_key
|
1602
1256
|
super
|
1603
1257
|
end
|
1604
1258
|
|
@@ -1606,9 +1260,9 @@ module Sequel
|
|
1606
1260
|
# the same class and values (if pk is nil).
|
1607
1261
|
#
|
1608
1262
|
# Artist[1].hash == Artist[1].hash # true
|
1609
|
-
# Artist[1].set(:
|
1263
|
+
# Artist[1].set(name: 'Bob').hash == Artist[1].hash # true
|
1610
1264
|
# Artist.new.hash == Artist.new.hash # true
|
1611
|
-
# Artist.new(:
|
1265
|
+
# Artist.new(name: 'Bob').hash == Artist.new.hash # false
|
1612
1266
|
def hash
|
1613
1267
|
case primary_key
|
1614
1268
|
when Array
|
@@ -1637,7 +1291,7 @@ module Sequel
|
|
1637
1291
|
# Returns the keys in +values+. May not include all column names.
|
1638
1292
|
#
|
1639
1293
|
# Artist.new.keys # => []
|
1640
|
-
# Artist.new(:
|
1294
|
+
# Artist.new(name: 'Bob').keys # => [:name]
|
1641
1295
|
# Artist[1].keys # => [:id, :name]
|
1642
1296
|
def keys
|
1643
1297
|
@values.keys
|
@@ -1709,7 +1363,7 @@ module Sequel
|
|
1709
1363
|
#
|
1710
1364
|
# a = Artist[1]
|
1711
1365
|
# a.modified? # => false
|
1712
|
-
# a.set(:
|
1366
|
+
# a.set(name: 'Jim')
|
1713
1367
|
# a.modified? # => true
|
1714
1368
|
#
|
1715
1369
|
# If a column is given, specifically check if the given column has
|
@@ -1801,9 +1455,6 @@ module Sequel
|
|
1801
1455
|
#
|
1802
1456
|
# If it succeeds, it returns self.
|
1803
1457
|
#
|
1804
|
-
# You can provide an optional list of columns to update, in which
|
1805
|
-
# case it only updates those columns, or a options hash.
|
1806
|
-
#
|
1807
1458
|
# Takes the following options:
|
1808
1459
|
#
|
1809
1460
|
# :changed :: save all changed columns, instead of all columns or the columns given
|
@@ -1818,12 +1469,15 @@ module Sequel
|
|
1818
1469
|
def save(opts=OPTS)
|
1819
1470
|
raise Sequel::Error, "can't save frozen object" if frozen?
|
1820
1471
|
set_server(opts[:server]) if opts[:server]
|
1821
|
-
|
1822
|
-
if
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1472
|
+
# :nocov:
|
1473
|
+
if method(:_before_validation).owner != InstanceMethods
|
1474
|
+
Sequel::Deprecation.deprecate("Using Model#_before_validation", "You should switch to using Model#before_validation")
|
1475
|
+
_before_validation
|
1476
|
+
end
|
1477
|
+
# :nocov:
|
1478
|
+
unless checked_save_failure(opts){_valid?(opts)}
|
1479
|
+
raise(ValidationFailed.new(self)) if raise_on_failure?(opts)
|
1480
|
+
return
|
1827
1481
|
end
|
1828
1482
|
checked_save_failure(opts){checked_transaction(opts){_save(opts)}}
|
1829
1483
|
end
|
@@ -1846,23 +1500,12 @@ module Sequel
|
|
1846
1500
|
# a setter method (or ignoring it if <tt>strict_param_setting = false</tt>).
|
1847
1501
|
# Does not save the record.
|
1848
1502
|
#
|
1849
|
-
# artist.set(:
|
1503
|
+
# artist.set(name: 'Jim')
|
1850
1504
|
# artist.name # => 'Jim'
|
1851
1505
|
def set(hash)
|
1852
1506
|
set_restricted(hash, :default)
|
1853
1507
|
end
|
1854
1508
|
|
1855
|
-
# Set all values using the entries in the hash, ignoring any setting of
|
1856
|
-
# allowed_columns in the model.
|
1857
|
-
#
|
1858
|
-
# Artist.set_allowed_columns(:num_albums)
|
1859
|
-
# artist.set_all(:name=>'Jim')
|
1860
|
-
# artist.name # => 'Jim'
|
1861
|
-
def set_all(hash)
|
1862
|
-
Sequel::Deprecation.deprecate("Sequel::Model#set_all", "Switch to set or load the whitelist_security plugin into the model class")
|
1863
|
-
set_restricted(hash, :all)
|
1864
|
-
end
|
1865
|
-
|
1866
1509
|
# For each of the fields in the given array +fields+, call the setter
|
1867
1510
|
# method with the value of that +hash+ entry for the field. Returns self.
|
1868
1511
|
#
|
@@ -1875,19 +1518,19 @@ module Sequel
|
|
1875
1518
|
#
|
1876
1519
|
# Examples:
|
1877
1520
|
#
|
1878
|
-
# artist.set_fields({:
|
1521
|
+
# artist.set_fields({name: 'Jim'}, [:name])
|
1879
1522
|
# artist.name # => 'Jim'
|
1880
1523
|
#
|
1881
|
-
# artist.set_fields({:
|
1524
|
+
# artist.set_fields({hometown: 'LA'}, [:name])
|
1882
1525
|
# artist.name # => nil
|
1883
1526
|
# artist.hometown # => 'Sac'
|
1884
1527
|
#
|
1885
1528
|
# artist.name # => 'Jim'
|
1886
|
-
# artist.set_fields({}, [:name], :
|
1529
|
+
# artist.set_fields({}, [:name], missing: :skip)
|
1887
1530
|
# artist.name # => 'Jim'
|
1888
1531
|
#
|
1889
1532
|
# artist.name # => 'Jim'
|
1890
|
-
# artist.set_fields({}, [:name], :
|
1533
|
+
# artist.set_fields({}, [:name], missing: :raise)
|
1891
1534
|
# # Sequel::Error raised
|
1892
1535
|
def set_fields(hash, fields, opts=nil)
|
1893
1536
|
opts = if opts
|
@@ -1921,19 +1564,6 @@ module Sequel
|
|
1921
1564
|
self
|
1922
1565
|
end
|
1923
1566
|
|
1924
|
-
# Set the values using the entries in the hash, only if the key
|
1925
|
-
# is included in only. It may be a better idea to use +set_fields+
|
1926
|
-
# instead of this method.
|
1927
|
-
#
|
1928
|
-
# artist.set_only({:name=>'Jim'}, :name)
|
1929
|
-
# artist.name # => 'Jim'
|
1930
|
-
#
|
1931
|
-
# artist.set_only({:hometown=>'LA'}, :name) # Raise Error
|
1932
|
-
def set_only(hash, *only)
|
1933
|
-
Sequel::Deprecation.deprecate("Sequel::Model#set_only", "Switch to set_fields with the :missing=>:skip option or load the whitelist_security plugin into the model class")
|
1934
|
-
set_restricted(hash, only.flatten)
|
1935
|
-
end
|
1936
|
-
|
1937
1567
|
# Set the shard that this object is tied to. Returns self.
|
1938
1568
|
def set_server(s)
|
1939
1569
|
@server = s
|
@@ -1954,60 +1584,29 @@ module Sequel
|
|
1954
1584
|
def this
|
1955
1585
|
return @this if @this
|
1956
1586
|
raise Error, "No dataset for model #{model}" unless ds = model.instance_dataset
|
1957
|
-
|
1958
|
-
cond = if ds.joined_dataset?
|
1959
|
-
# SEQUEL5: Remove as joined model datasets are now allowed
|
1960
|
-
qualified_pk_hash
|
1961
|
-
else
|
1962
|
-
pk_hash
|
1963
|
-
end
|
1964
|
-
|
1965
|
-
@this = use_server(ds.where(cond))
|
1587
|
+
@this = use_server(ds.where(pk_hash))
|
1966
1588
|
end
|
1967
1589
|
|
1968
1590
|
# Runs #set with the passed hash and then runs save_changes.
|
1969
1591
|
#
|
1970
|
-
# artist.update(:
|
1592
|
+
# artist.update(name: 'Jim') # UPDATE artists SET name = 'Jim' WHERE (id = 1)
|
1971
1593
|
def update(hash)
|
1972
1594
|
update_restricted(hash, :default)
|
1973
1595
|
end
|
1974
1596
|
|
1975
|
-
# Update all values using the entries in the hash, ignoring any setting of
|
1976
|
-
# +allowed_columns+ in the model.
|
1977
|
-
#
|
1978
|
-
# Artist.set_allowed_columns(:num_albums)
|
1979
|
-
# artist.update_all(:name=>'Jim') # UPDATE artists SET name = 'Jim' WHERE (id = 1)
|
1980
|
-
def update_all(hash)
|
1981
|
-
Sequel::Deprecation.deprecate("Sequel::Model#update_all", "Switch to update or load the whitelist_security plugin into the model class")
|
1982
|
-
update_restricted(hash, :all)
|
1983
|
-
end
|
1984
|
-
|
1985
1597
|
# Update the instances values by calling +set_fields+ with the arguments, then
|
1986
1598
|
# saves any changes to the record. Returns self.
|
1987
1599
|
#
|
1988
|
-
# artist.update_fields({:
|
1600
|
+
# artist.update_fields({name: 'Jim'}, [:name])
|
1989
1601
|
# # UPDATE artists SET name = 'Jim' WHERE (id = 1)
|
1990
1602
|
#
|
1991
|
-
# artist.update_fields({:
|
1603
|
+
# artist.update_fields({hometown: 'LA'}, [:name])
|
1992
1604
|
# # UPDATE artists SET name = NULL WHERE (id = 1)
|
1993
1605
|
def update_fields(hash, fields, opts=nil)
|
1994
1606
|
set_fields(hash, fields, opts)
|
1995
1607
|
save_changes
|
1996
1608
|
end
|
1997
1609
|
|
1998
|
-
# Update the values using the entries in the hash, only if the key
|
1999
|
-
# is included in only. It may be a better idea to use +update_fields+
|
2000
|
-
# instead of this method.
|
2001
|
-
#
|
2002
|
-
# artist.update_only({:name=>'Jim'}, :name)
|
2003
|
-
# # UPDATE artists SET name = 'Jim' WHERE (id = 1)
|
2004
|
-
#
|
2005
|
-
# artist.update_only({:hometown=>'LA'}, :name) # Raise Error
|
2006
|
-
def update_only(hash, *only)
|
2007
|
-
Sequel::Deprecation.deprecate("Sequel::Model#update_only", "Switch to update_fields with the :missing=>:skip option or load the whitelist_security plugin into the model class")
|
2008
|
-
update_restricted(hash, only.flatten)
|
2009
|
-
end
|
2010
|
-
|
2011
1610
|
# Validates the object. If the object is invalid, errors should be added
|
2012
1611
|
# to the errors attribute. By default, does nothing, as all models
|
2013
1612
|
# are valid by default. See the {"Model Validations" guide}[rdoc-ref:doc/validations.rdoc].
|
@@ -2019,11 +1618,16 @@ module Sequel
|
|
2019
1618
|
|
2020
1619
|
# Validates the object and returns true if no errors are reported.
|
2021
1620
|
#
|
2022
|
-
# artist.set(:
|
2023
|
-
# artist.set(:
|
1621
|
+
# artist.set(name: 'Valid').valid? # => true
|
1622
|
+
# artist.set(name: 'Invalid').valid? # => false
|
2024
1623
|
# artist.errors.full_messages # => ['name cannot be Invalid']
|
2025
1624
|
def valid?(opts = OPTS)
|
2026
|
-
|
1625
|
+
# :nocov:
|
1626
|
+
if method(:_before_validation).owner != InstanceMethods
|
1627
|
+
Sequel::Deprecation.deprecate("Using Model#_before_validation", "You should switch to using Model#before_validation")
|
1628
|
+
_before_validation
|
1629
|
+
end
|
1630
|
+
# :nocov:
|
2027
1631
|
begin
|
2028
1632
|
_valid?(opts)
|
2029
1633
|
rescue HookFailed
|
@@ -2033,39 +1637,7 @@ module Sequel
|
|
2033
1637
|
|
2034
1638
|
private
|
2035
1639
|
|
2036
|
-
#
|
2037
|
-
# This is only a temporary API, it should not be overridden by external code.
|
2038
|
-
def _after_create(pk)
|
2039
|
-
# SEQUEL5: Remove
|
2040
|
-
@this = nil
|
2041
|
-
@new = false
|
2042
|
-
@was_new = true
|
2043
|
-
end
|
2044
|
-
|
2045
|
-
# Run code after around_save returns, before calling after_commit.
|
2046
|
-
# This is only a temporary API, it should not be overridden by external code.
|
2047
|
-
def _after_save(pk)
|
2048
|
-
# SEQUEL5: Remove
|
2049
|
-
if @was_new
|
2050
|
-
@was_new = nil
|
2051
|
-
pk ? _save_refresh : changed_columns.clear
|
2052
|
-
else
|
2053
|
-
@columns_updated = nil
|
2054
|
-
end
|
2055
|
-
@modified = false
|
2056
|
-
end
|
2057
|
-
|
2058
|
-
# Run code directly after the UPDATE query, before after_update.
|
2059
|
-
# This is only a temporary API, it should not be overridden by external code.
|
2060
|
-
def _after_update
|
2061
|
-
# SEQUEL5: Remove
|
2062
|
-
@this = nil
|
2063
|
-
end
|
2064
|
-
|
2065
|
-
# Run code before any validation is done, but also run it before saving
|
2066
|
-
# even if validation is skipped. This is a private hook. It exists so that
|
2067
|
-
# plugins can set values automatically before validation (as the values
|
2068
|
-
# need to be validated), but should be set even if validation is skipped.
|
1640
|
+
# SEQUEL51: Remove
|
2069
1641
|
def _before_validation
|
2070
1642
|
end
|
2071
1643
|
|
@@ -2077,7 +1649,7 @@ module Sequel
|
|
2077
1649
|
n
|
2078
1650
|
end
|
2079
1651
|
|
2080
|
-
# The dataset to use when deleting the object.
|
1652
|
+
# The dataset to use when deleting the object. The same as the object's
|
2081
1653
|
# dataset by default.
|
2082
1654
|
def _delete_dataset
|
2083
1655
|
this
|
@@ -2099,28 +1671,14 @@ module Sequel
|
|
2099
1671
|
# Internal destroy method, separted from destroy to
|
2100
1672
|
# allow running inside a transaction
|
2101
1673
|
def _destroy(opts)
|
2102
|
-
sh = {:server=>this_server}
|
2103
|
-
uacr = use_after_commit_rollback
|
2104
|
-
if uacr.nil? ? (method(:after_destroy_rollback).owner != InstanceMethods) : uacr
|
2105
|
-
Sequel::Deprecation.deprecate("Model#after_destroy_rollback", "Instead, call db.after_rollback in Model#before_destroy")
|
2106
|
-
db.after_rollback(sh){after_destroy_rollback}
|
2107
|
-
end
|
2108
1674
|
called = false
|
2109
1675
|
around_destroy do
|
2110
1676
|
called = true
|
2111
|
-
|
2112
|
-
Sequel::Deprecation.deprecate("Having before_destroy return false to cancel the destroy", "Instead, call cancel_action inside before_destroy")
|
2113
|
-
raise_hook_failure(:before_destroy)
|
2114
|
-
end
|
1677
|
+
before_destroy
|
2115
1678
|
_destroy_delete
|
2116
1679
|
after_destroy
|
2117
|
-
true
|
2118
1680
|
end
|
2119
1681
|
raise_hook_failure(:around_destroy) unless called
|
2120
|
-
if uacr.nil? ? (method(:after_destroy_commit).owner != InstanceMethods) : uacr
|
2121
|
-
Sequel::Deprecation.deprecate("Model#after_destroy_commit", "Instead, call db.after_commit in Model#after_destroy")
|
2122
|
-
db.after_commit(sh){after_destroy_commit}
|
2123
|
-
end
|
2124
1682
|
self
|
2125
1683
|
end
|
2126
1684
|
|
@@ -2187,7 +1745,7 @@ module Sequel
|
|
2187
1745
|
end
|
2188
1746
|
end
|
2189
1747
|
|
2190
|
-
# Set the
|
1748
|
+
# Set the values to the given hash after refreshing.
|
2191
1749
|
def _refresh_set_values(h)
|
2192
1750
|
@values = h
|
2193
1751
|
end
|
@@ -2195,36 +1753,22 @@ module Sequel
|
|
2195
1753
|
# Internal version of save, split from save to allow running inside
|
2196
1754
|
# it's own transaction.
|
2197
1755
|
def _save(opts)
|
2198
|
-
sh = {:server=>this_server}
|
2199
|
-
uacr = use_after_commit_rollback
|
2200
|
-
if uacr.nil? ? (method(:after_rollback).owner != InstanceMethods) : uacr
|
2201
|
-
Sequel::Deprecation.deprecate("Model#after_rollback", "Instead, call db.after_rollback in Model#before_save")
|
2202
|
-
db.after_rollback(sh){after_rollback}
|
2203
|
-
end
|
2204
1756
|
pk = nil
|
2205
1757
|
called_save = false
|
2206
1758
|
called_cu = false
|
2207
1759
|
around_save do
|
2208
1760
|
called_save = true
|
2209
|
-
|
2210
|
-
Sequel::Deprecation.deprecate("Having before_save return false to cancel the save", "Instead, call cancel_action inside before_save")
|
2211
|
-
raise_hook_failure(:before_save)
|
2212
|
-
end
|
1761
|
+
before_save
|
2213
1762
|
|
2214
1763
|
if new?
|
2215
1764
|
around_create do
|
2216
1765
|
called_cu = true
|
2217
|
-
|
2218
|
-
Sequel::Deprecation.deprecate("Having before_create return false to cancel the create", "Instead, call cancel_action inside before_create")
|
2219
|
-
raise_hook_failure(:before_create)
|
2220
|
-
end
|
1766
|
+
before_create
|
2221
1767
|
pk = _insert
|
2222
|
-
|
2223
|
-
|
2224
|
-
|
2225
|
-
|
2226
|
-
# @modified = false
|
2227
|
-
# pk ? _save_refresh : changed_columns.clear
|
1768
|
+
@this = nil
|
1769
|
+
@new = false
|
1770
|
+
@modified = false
|
1771
|
+
pk ? _save_refresh : changed_columns.clear
|
2228
1772
|
after_create
|
2229
1773
|
true
|
2230
1774
|
end
|
@@ -2232,13 +1776,10 @@ module Sequel
|
|
2232
1776
|
else
|
2233
1777
|
around_update do
|
2234
1778
|
called_cu = true
|
2235
|
-
|
2236
|
-
Sequel::Deprecation.deprecate("Having before_update return false to cancel the update", "Instead, call cancel_action inside before_update")
|
2237
|
-
raise_hook_failure(:before_update)
|
2238
|
-
end
|
1779
|
+
before_update
|
2239
1780
|
columns = opts[:columns]
|
2240
1781
|
if columns.nil?
|
2241
|
-
columns_updated = if opts[:changed]
|
1782
|
+
columns_updated = if opts[:changed]
|
2242
1783
|
@values.reject{|k,v| !changed_columns.include?(k)}
|
2243
1784
|
else
|
2244
1785
|
_save_update_all_columns_hash
|
@@ -2250,10 +1791,8 @@ module Sequel
|
|
2250
1791
|
changed_columns.reject!{|c| columns.include?(c)}
|
2251
1792
|
end
|
2252
1793
|
_update_columns(columns_updated)
|
2253
|
-
|
2254
|
-
|
2255
|
-
# @this = nil
|
2256
|
-
# @modified = false
|
1794
|
+
@this = nil
|
1795
|
+
@modified = false
|
2257
1796
|
after_update
|
2258
1797
|
true
|
2259
1798
|
end
|
@@ -2263,11 +1802,6 @@ module Sequel
|
|
2263
1802
|
true
|
2264
1803
|
end
|
2265
1804
|
raise_hook_failure(:around_save) unless called_save
|
2266
|
-
_after_save(pk) # SEQUEL5: Remove
|
2267
|
-
if uacr.nil? ? (method(:after_commit).owner != InstanceMethods) : uacr
|
2268
|
-
Sequel::Deprecation.deprecate("Model#after_commit", "Instead, call db.after_commit in Model#after_save")
|
2269
|
-
db.after_commit(sh){after_commit}
|
2270
|
-
end
|
2271
1805
|
self
|
2272
1806
|
end
|
2273
1807
|
|
@@ -2301,7 +1835,6 @@ module Sequel
|
|
2301
1835
|
# Plugins can override this method in order to update with
|
2302
1836
|
# additional columns, even when the column hash is initially empty.
|
2303
1837
|
def _update_columns(columns)
|
2304
|
-
@columns_updated ||= DeprecatedColumnsUpdated.new(columns) # SEQUEL5: Remove
|
2305
1838
|
_update(columns) unless columns.empty?
|
2306
1839
|
end
|
2307
1840
|
|
@@ -2334,18 +1867,16 @@ module Sequel
|
|
2334
1867
|
return errors.empty? if frozen?
|
2335
1868
|
errors.clear
|
2336
1869
|
called = false
|
2337
|
-
|
1870
|
+
skip_validate = opts[:validate] == false
|
2338
1871
|
around_validation do
|
2339
1872
|
called = true
|
2340
|
-
|
2341
|
-
|
2342
|
-
|
2343
|
-
else
|
2344
|
-
validate # unless skip_validate # SEQUEL5
|
2345
|
-
after_validation
|
2346
|
-
end
|
1873
|
+
before_validation
|
1874
|
+
validate unless skip_validate
|
1875
|
+
after_validation
|
2347
1876
|
end
|
2348
|
-
|
1877
|
+
|
1878
|
+
return true if skip_validate
|
1879
|
+
|
2349
1880
|
if called
|
2350
1881
|
errors.empty?
|
2351
1882
|
else
|
@@ -2384,24 +1915,12 @@ module Sequel
|
|
2384
1915
|
Errors
|
2385
1916
|
end
|
2386
1917
|
|
2387
|
-
if
|
2388
|
-
|
2389
|
-
|
2390
|
-
|
2391
|
-
|
2392
|
-
|
2393
|
-
self
|
2394
|
-
end
|
2395
|
-
else
|
2396
|
-
# :nocov:
|
2397
|
-
# Ruby 1.8 doesn't support initialize_clone, so override clone to dup and freeze.
|
2398
|
-
def clone
|
2399
|
-
o = dup
|
2400
|
-
o.freeze if frozen?
|
2401
|
-
o
|
2402
|
-
end
|
2403
|
-
public :clone
|
2404
|
-
# :nocov:
|
1918
|
+
# Clone constructor -- freeze internal data structures if the original's
|
1919
|
+
# are frozen.
|
1920
|
+
def initialize_clone(other)
|
1921
|
+
super
|
1922
|
+
freeze if other.frozen?
|
1923
|
+
self
|
2405
1924
|
end
|
2406
1925
|
|
2407
1926
|
# Copy constructor -- Duplicate internal data structures.
|
@@ -2410,7 +1929,6 @@ module Sequel
|
|
2410
1929
|
@values = Hash[@values]
|
2411
1930
|
@changed_columns = @changed_columns.dup if @changed_columns
|
2412
1931
|
@errors = @errors.dup if @errors
|
2413
|
-
@this = @this.dup if @this
|
2414
1932
|
self
|
2415
1933
|
end
|
2416
1934
|
|
@@ -2489,19 +2007,13 @@ module Sequel
|
|
2489
2007
|
# :all :: Allow setting all setters, except those specifically restricted (such as ==).
|
2490
2008
|
# Array :: Only allow setting of columns in the given array.
|
2491
2009
|
def setter_methods(type)
|
2492
|
-
if type == :default
|
2493
|
-
|
2494
|
-
return model.setter_methods
|
2495
|
-
end
|
2010
|
+
if type == :default && !@singleton_setter_added
|
2011
|
+
return model.setter_methods
|
2496
2012
|
end
|
2497
2013
|
|
2498
|
-
|
2499
|
-
|
2500
|
-
|
2501
|
-
meths = methods.map(&:to_s).select{|l| l.end_with?('=')} - RESTRICTED_SETTER_METHODS
|
2502
|
-
meths -= Array(primary_key).map{|x| "#{x}="} if type != :all && primary_key && model.restrict_primary_key?
|
2503
|
-
meths
|
2504
|
-
end
|
2014
|
+
meths = methods.map(&:to_s).select{|l| l.end_with?('=')} - RESTRICTED_SETTER_METHODS
|
2015
|
+
meths -= Array(primary_key).map{|x| "#{x}="} if primary_key && model.restrict_primary_key?
|
2016
|
+
meths
|
2505
2017
|
end
|
2506
2018
|
|
2507
2019
|
# The server/shard that the model object's dataset uses, or :default if the
|
@@ -2551,8 +2063,6 @@ module Sequel
|
|
2551
2063
|
|
2552
2064
|
# DatasetMethods contains methods that all model datasets have.
|
2553
2065
|
module DatasetMethods
|
2554
|
-
Dataset.def_deprecated_opts_setter(self, :model)
|
2555
|
-
|
2556
2066
|
# The model class associated with this dataset
|
2557
2067
|
#
|
2558
2068
|
# Artist.dataset.model # => Artist
|
@@ -2586,53 +2096,6 @@ module Sequel
|
|
2586
2096
|
model.use_transactions ? @db.transaction(:server=>opts[:server], &pr) : pr.call
|
2587
2097
|
end
|
2588
2098
|
|
2589
|
-
# Allow Sequel::Model classes to be used as dataset arguments when graphing:
|
2590
|
-
#
|
2591
|
-
# Artist.graph(Album, :artist_id=>id)
|
2592
|
-
# # SELECT artists.id, artists.name, albums.id AS albums_id, albums.artist_id, albums.name AS albums_name
|
2593
|
-
# # FROM artists LEFT OUTER JOIN albums ON (albums.artist_id = artists.id)
|
2594
|
-
def graph(table, *args, &block)
|
2595
|
-
if table.is_a?(Class) && table < Sequel::Model
|
2596
|
-
Sequel::Deprecation.deprecate("Passing Sequel::Model class as first argument to Sequel::Dataset#graph", "Pass the model's dataset as the first argument instead")
|
2597
|
-
super(table.dataset, *args, &block)
|
2598
|
-
else
|
2599
|
-
super
|
2600
|
-
end
|
2601
|
-
end
|
2602
|
-
|
2603
|
-
# Handle Sequel::Model instances when inserting, using the model instance's
|
2604
|
-
# values for the insert, unless the model instance can be used directly in
|
2605
|
-
# SQL.
|
2606
|
-
#
|
2607
|
-
# Album.insert(Album.load(:name=>'A'))
|
2608
|
-
# # INSERT INTO albums (name) VALUES ('A')
|
2609
|
-
def insert_sql(*values)
|
2610
|
-
if values.size == 1 && (v = values[0]).is_a?(Sequel::Model) && !v.respond_to?(:sql_literal_append)
|
2611
|
-
Sequel::Deprecation.deprecate("Passing Sequel::Model instance argument to Sequel::Dataset#insert", "Pass model_instance.values or model_instance.to_hash as the argument instead")
|
2612
|
-
super(v.to_hash)
|
2613
|
-
else
|
2614
|
-
super
|
2615
|
-
end
|
2616
|
-
end
|
2617
|
-
|
2618
|
-
# Allow Sequel::Model classes to be used as table name arguments in dataset
|
2619
|
-
# join methods:
|
2620
|
-
#
|
2621
|
-
# Artist.join(Album, :artist_id=>id)
|
2622
|
-
# # SELECT * FROM artists INNER JOIN albums ON (albums.artist_id = artists.id)
|
2623
|
-
def join_table(type, table, *args, &block)
|
2624
|
-
if table.is_a?(Class) && table < Sequel::Model
|
2625
|
-
Sequel::Deprecation.deprecate("Passing Sequel::Model class to a dataset join method", "Pass the model's table name or dataset as the first argument instead")
|
2626
|
-
if table.dataset.simple_select_all?
|
2627
|
-
super(type, table.table_name, *args, &block)
|
2628
|
-
else
|
2629
|
-
super(type, table.dataset, *args, &block)
|
2630
|
-
end
|
2631
|
-
else
|
2632
|
-
super
|
2633
|
-
end
|
2634
|
-
end
|
2635
|
-
|
2636
2099
|
# If there is no order already defined on this dataset, order it by
|
2637
2100
|
# the primary key and call last.
|
2638
2101
|
#
|
@@ -2710,14 +2173,6 @@ module Sequel
|
|
2710
2173
|
|
2711
2174
|
private
|
2712
2175
|
|
2713
|
-
# SEQUEL5: Remove
|
2714
|
-
def _model_where_loader
|
2715
|
-
# :nocov:
|
2716
|
-
Sequel::Deprecation.deprecate("Dataset#_model_where_loader", "Use _where_loader instead")
|
2717
|
-
_where_loader
|
2718
|
-
# :nocov:
|
2719
|
-
end
|
2720
|
-
|
2721
2176
|
# If the dataset is not already ordered, and the model has a primary key,
|
2722
2177
|
# return a clone ordered by the primary key.
|
2723
2178
|
def _primary_key_order
|
@@ -2750,5 +2205,10 @@ module Sequel
|
|
2750
2205
|
|
2751
2206
|
extend ClassMethods
|
2752
2207
|
plugin self
|
2208
|
+
|
2209
|
+
singleton_class.send(:undef_method, :dup, :clone, :initialize_copy)
|
2210
|
+
if RUBY_VERSION >= '1.9.3'
|
2211
|
+
singleton_class.send(:undef_method, :initialize_clone, :initialize_dup)
|
2212
|
+
end
|
2753
2213
|
end
|
2754
2214
|
end
|