sequel 4.49.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|