sequel 4.26.0 → 5.37.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 +5 -5
- data/CHANGELOG +405 -5656
- data/MIT-LICENSE +1 -1
- data/README.rdoc +232 -157
- data/bin/sequel +32 -9
- data/doc/advanced_associations.rdoc +252 -188
- data/doc/association_basics.rdoc +231 -273
- data/doc/bin_sequel.rdoc +5 -3
- data/doc/cheat_sheet.rdoc +75 -48
- data/doc/code_order.rdoc +28 -10
- data/doc/core_extensions.rdoc +104 -63
- data/doc/dataset_basics.rdoc +12 -21
- data/doc/dataset_filtering.rdoc +99 -86
- data/doc/extensions.rdoc +3 -10
- data/doc/mass_assignment.rdoc +74 -31
- data/doc/migration.rdoc +72 -46
- data/doc/model_dataset_method_design.rdoc +129 -0
- data/doc/model_hooks.rdoc +15 -25
- data/doc/model_plugins.rdoc +12 -12
- data/doc/mssql_stored_procedures.rdoc +3 -3
- data/doc/object_model.rdoc +59 -69
- data/doc/opening_databases.rdoc +84 -94
- data/doc/postgresql.rdoc +268 -38
- data/doc/prepared_statements.rdoc +29 -24
- data/doc/querying.rdoc +184 -164
- data/doc/reflection.rdoc +5 -6
- data/doc/release_notes/5.0.0.txt +159 -0
- data/doc/release_notes/5.1.0.txt +31 -0
- data/doc/release_notes/5.10.0.txt +84 -0
- data/doc/release_notes/5.11.0.txt +83 -0
- data/doc/release_notes/5.12.0.txt +141 -0
- data/doc/release_notes/5.13.0.txt +27 -0
- data/doc/release_notes/5.14.0.txt +63 -0
- data/doc/release_notes/5.15.0.txt +39 -0
- data/doc/release_notes/5.16.0.txt +110 -0
- data/doc/release_notes/5.17.0.txt +31 -0
- data/doc/release_notes/5.18.0.txt +69 -0
- data/doc/release_notes/5.19.0.txt +28 -0
- data/doc/release_notes/5.2.0.txt +33 -0
- data/doc/release_notes/5.20.0.txt +89 -0
- data/doc/release_notes/5.21.0.txt +87 -0
- data/doc/release_notes/5.22.0.txt +48 -0
- data/doc/release_notes/5.23.0.txt +56 -0
- data/doc/release_notes/5.24.0.txt +56 -0
- data/doc/release_notes/5.25.0.txt +32 -0
- data/doc/release_notes/5.26.0.txt +35 -0
- data/doc/release_notes/5.27.0.txt +21 -0
- data/doc/release_notes/5.28.0.txt +16 -0
- data/doc/release_notes/5.29.0.txt +22 -0
- data/doc/release_notes/5.3.0.txt +121 -0
- data/doc/release_notes/5.30.0.txt +20 -0
- data/doc/release_notes/5.31.0.txt +148 -0
- data/doc/release_notes/5.32.0.txt +46 -0
- data/doc/release_notes/5.33.0.txt +24 -0
- data/doc/release_notes/5.34.0.txt +40 -0
- data/doc/release_notes/5.35.0.txt +56 -0
- data/doc/release_notes/5.36.0.txt +60 -0
- data/doc/release_notes/5.37.0.txt +30 -0
- data/doc/release_notes/5.4.0.txt +80 -0
- data/doc/release_notes/5.5.0.txt +61 -0
- data/doc/release_notes/5.6.0.txt +31 -0
- data/doc/release_notes/5.7.0.txt +108 -0
- data/doc/release_notes/5.8.0.txt +170 -0
- data/doc/release_notes/5.9.0.txt +99 -0
- data/doc/schema_modification.rdoc +102 -77
- data/doc/security.rdoc +160 -87
- data/doc/sharding.rdoc +74 -47
- data/doc/sql.rdoc +135 -122
- data/doc/testing.rdoc +34 -18
- data/doc/thread_safety.rdoc +2 -4
- data/doc/transactions.rdoc +101 -19
- data/doc/validations.rdoc +64 -51
- data/doc/virtual_rows.rdoc +90 -109
- data/lib/sequel.rb +3 -1
- data/lib/sequel/adapters/ado.rb +154 -22
- data/lib/sequel/adapters/ado/access.rb +21 -21
- data/lib/sequel/adapters/ado/mssql.rb +8 -15
- data/lib/sequel/adapters/amalgalite.rb +17 -25
- data/lib/sequel/adapters/ibmdb.rb +52 -58
- data/lib/sequel/adapters/jdbc.rb +149 -127
- data/lib/sequel/adapters/jdbc/db2.rb +32 -40
- data/lib/sequel/adapters/jdbc/derby.rb +56 -58
- data/lib/sequel/adapters/jdbc/h2.rb +40 -30
- data/lib/sequel/adapters/jdbc/hsqldb.rb +22 -33
- data/lib/sequel/adapters/jdbc/jtds.rb +4 -10
- data/lib/sequel/adapters/jdbc/mssql.rb +6 -12
- data/lib/sequel/adapters/jdbc/mysql.rb +17 -18
- data/lib/sequel/adapters/jdbc/oracle.rb +25 -19
- data/lib/sequel/adapters/jdbc/postgresql.rb +90 -69
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +14 -24
- data/lib/sequel/adapters/jdbc/sqlite.rb +50 -12
- data/lib/sequel/adapters/jdbc/sqlserver.rb +36 -9
- data/lib/sequel/adapters/jdbc/transactions.rb +25 -39
- data/lib/sequel/adapters/mock.rb +104 -113
- data/lib/sequel/adapters/mysql.rb +42 -61
- data/lib/sequel/adapters/mysql2.rb +126 -35
- data/lib/sequel/adapters/odbc.rb +21 -28
- data/lib/sequel/adapters/odbc/db2.rb +3 -1
- data/lib/sequel/adapters/odbc/mssql.rb +11 -15
- data/lib/sequel/adapters/odbc/oracle.rb +11 -0
- data/lib/sequel/adapters/oracle.rb +62 -68
- data/lib/sequel/adapters/postgres.rb +257 -311
- data/lib/sequel/adapters/postgresql.rb +3 -1
- data/lib/sequel/adapters/shared/access.rb +75 -79
- data/lib/sequel/adapters/shared/db2.rb +96 -74
- data/lib/sequel/adapters/shared/mssql.rb +258 -213
- data/lib/sequel/adapters/shared/mysql.rb +284 -216
- data/lib/sequel/adapters/shared/oracle.rb +175 -60
- data/lib/sequel/adapters/shared/postgres.rb +829 -383
- data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -127
- data/lib/sequel/adapters/shared/sqlite.rb +382 -159
- data/lib/sequel/adapters/sqlanywhere.rb +53 -38
- data/lib/sequel/adapters/sqlite.rb +111 -105
- data/lib/sequel/adapters/tinytds.rb +38 -46
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +8 -9
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +7 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
- data/lib/sequel/adapters/utils/replace.rb +3 -4
- data/lib/sequel/adapters/utils/split_alter_table.rb +2 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
- data/lib/sequel/ast_transformer.rb +13 -89
- data/lib/sequel/connection_pool.rb +54 -26
- data/lib/sequel/connection_pool/sharded_single.rb +19 -12
- data/lib/sequel/connection_pool/sharded_threaded.rb +160 -111
- data/lib/sequel/connection_pool/single.rb +21 -12
- data/lib/sequel/connection_pool/threaded.rb +137 -119
- data/lib/sequel/core.rb +352 -320
- data/lib/sequel/database.rb +19 -2
- data/lib/sequel/database/connecting.rb +70 -55
- data/lib/sequel/database/dataset.rb +15 -5
- data/lib/sequel/database/dataset_defaults.rb +20 -102
- data/lib/sequel/database/features.rb +20 -4
- data/lib/sequel/database/logging.rb +25 -7
- data/lib/sequel/database/misc.rb +132 -118
- data/lib/sequel/database/query.rb +51 -28
- data/lib/sequel/database/schema_generator.rb +188 -75
- data/lib/sequel/database/schema_methods.rb +161 -92
- data/lib/sequel/database/transactions.rb +260 -58
- data/lib/sequel/dataset.rb +28 -12
- data/lib/sequel/dataset/actions.rb +354 -170
- data/lib/sequel/dataset/dataset_module.rb +46 -0
- data/lib/sequel/dataset/features.rb +81 -34
- data/lib/sequel/dataset/graph.rb +82 -58
- data/lib/sequel/dataset/misc.rb +139 -47
- data/lib/sequel/dataset/placeholder_literalizer.rb +66 -26
- data/lib/sequel/dataset/prepared_statements.rb +188 -85
- data/lib/sequel/dataset/query.rb +428 -214
- data/lib/sequel/dataset/sql.rb +446 -339
- data/lib/sequel/deprecated.rb +14 -2
- data/lib/sequel/exceptions.rb +48 -16
- data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
- data/lib/sequel/extensions/_model_pg_row.rb +43 -0
- data/lib/sequel/extensions/_pretty_table.rb +10 -9
- data/lib/sequel/extensions/any_not_empty.rb +45 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +15 -11
- data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
- data/lib/sequel/extensions/blank.rb +2 -0
- data/lib/sequel/extensions/caller_logging.rb +79 -0
- data/lib/sequel/extensions/columns_introspection.rb +9 -4
- data/lib/sequel/extensions/connection_expiration.rb +99 -0
- data/lib/sequel/extensions/connection_validator.rb +26 -13
- data/lib/sequel/extensions/constant_sql_override.rb +65 -0
- data/lib/sequel/extensions/constraint_validations.rb +93 -38
- data/lib/sequel/extensions/core_extensions.rb +45 -53
- data/lib/sequel/extensions/core_refinements.rb +44 -46
- data/lib/sequel/extensions/current_datetime_timestamp.rb +5 -4
- data/lib/sequel/extensions/dataset_source_alias.rb +4 -0
- data/lib/sequel/extensions/date_arithmetic.rb +42 -16
- data/lib/sequel/extensions/datetime_parse_to_time.rb +37 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +94 -0
- data/lib/sequel/extensions/empty_array_consider_nulls.rb +7 -3
- data/lib/sequel/extensions/error_sql.rb +7 -3
- data/lib/sequel/extensions/escaped_like.rb +100 -0
- data/lib/sequel/extensions/eval_inspect.rb +14 -15
- data/lib/sequel/extensions/exclude_or_null.rb +68 -0
- data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
- data/lib/sequel/extensions/freeze_datasets.rb +3 -0
- data/lib/sequel/extensions/from_block.rb +2 -31
- data/lib/sequel/extensions/graph_each.rb +19 -6
- data/lib/sequel/extensions/identifier_mangling.rb +180 -0
- data/lib/sequel/extensions/implicit_subquery.rb +48 -0
- data/lib/sequel/extensions/index_caching.rb +109 -0
- data/lib/sequel/extensions/inflector.rb +8 -4
- data/lib/sequel/extensions/integer64.rb +32 -0
- data/lib/sequel/extensions/looser_typecasting.rb +19 -9
- data/lib/sequel/extensions/migration.rb +132 -80
- data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +4 -0
- data/lib/sequel/extensions/named_timezones.rb +88 -23
- data/lib/sequel/extensions/no_auto_literal_strings.rb +4 -0
- data/lib/sequel/extensions/null_dataset.rb +12 -8
- data/lib/sequel/extensions/pagination.rb +35 -28
- data/lib/sequel/extensions/pg_array.rb +227 -316
- data/lib/sequel/extensions/pg_array_ops.rb +19 -7
- data/lib/sequel/extensions/pg_enum.rb +69 -24
- data/lib/sequel/extensions/pg_extended_date_support.rb +250 -0
- data/lib/sequel/extensions/pg_hstore.rb +50 -59
- data/lib/sequel/extensions/pg_hstore_ops.rb +9 -3
- data/lib/sequel/extensions/pg_inet.rb +34 -15
- data/lib/sequel/extensions/pg_inet_ops.rb +5 -1
- data/lib/sequel/extensions/pg_interval.rb +26 -26
- data/lib/sequel/extensions/pg_json.rb +422 -141
- data/lib/sequel/extensions/pg_json_ops.rb +248 -9
- data/lib/sequel/extensions/pg_loose_count.rb +5 -1
- data/lib/sequel/extensions/pg_range.rb +162 -146
- data/lib/sequel/extensions/pg_range_ops.rb +10 -5
- data/lib/sequel/extensions/pg_row.rb +53 -87
- data/lib/sequel/extensions/pg_row_ops.rb +36 -13
- data/lib/sequel/extensions/pg_static_cache_updater.rb +6 -2
- data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
- data/lib/sequel/extensions/pretty_table.rb +4 -0
- data/lib/sequel/extensions/query.rb +12 -7
- data/lib/sequel/extensions/round_timestamps.rb +6 -9
- data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
- data/lib/sequel/extensions/s.rb +59 -0
- data/lib/sequel/extensions/schema_caching.rb +14 -1
- data/lib/sequel/extensions/schema_dumper.rb +83 -55
- data/lib/sequel/extensions/select_remove.rb +8 -4
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
- data/lib/sequel/extensions/server_block.rb +50 -17
- data/lib/sequel/extensions/server_logging.rb +61 -0
- data/lib/sequel/extensions/split_array_nil.rb +8 -4
- data/lib/sequel/extensions/sql_comments.rb +96 -0
- data/lib/sequel/extensions/sql_expr.rb +4 -1
- data/lib/sequel/extensions/string_agg.rb +181 -0
- data/lib/sequel/extensions/string_date_time.rb +2 -0
- data/lib/sequel/extensions/symbol_aref.rb +53 -0
- data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
- data/lib/sequel/extensions/symbol_as.rb +23 -0
- data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
- data/lib/sequel/extensions/synchronize_sql.rb +45 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +4 -0
- data/lib/sequel/extensions/to_dot.rb +15 -5
- data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
- data/lib/sequel/model.rb +36 -126
- data/lib/sequel/model/associations.rb +850 -257
- data/lib/sequel/model/base.rb +652 -764
- data/lib/sequel/model/dataset_module.rb +13 -10
- data/lib/sequel/model/default_inflections.rb +3 -1
- data/lib/sequel/model/errors.rb +3 -3
- data/lib/sequel/model/exceptions.rb +12 -12
- data/lib/sequel/model/inflections.rb +8 -19
- data/lib/sequel/model/plugins.rb +111 -0
- data/lib/sequel/plugins/accessed_columns.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +32 -7
- data/lib/sequel/plugins/after_initialize.rb +3 -1
- data/lib/sequel/plugins/association_dependencies.rb +27 -18
- data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
- data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
- data/lib/sequel/plugins/association_pks.rb +181 -83
- data/lib/sequel/plugins/association_proxies.rb +33 -9
- data/lib/sequel/plugins/auto_validations.rb +58 -23
- data/lib/sequel/plugins/before_after_save.rb +8 -0
- data/lib/sequel/plugins/blacklist_security.rb +23 -12
- data/lib/sequel/plugins/boolean_readers.rb +9 -6
- data/lib/sequel/plugins/boolean_subsets.rb +64 -0
- data/lib/sequel/plugins/caching.rb +27 -16
- data/lib/sequel/plugins/class_table_inheritance.rb +192 -94
- data/lib/sequel/plugins/column_conflicts.rb +18 -3
- data/lib/sequel/plugins/column_select.rb +9 -5
- data/lib/sequel/plugins/columns_updated.rb +42 -0
- data/lib/sequel/plugins/composition.rb +36 -24
- data/lib/sequel/plugins/constraint_validations.rb +37 -16
- data/lib/sequel/plugins/csv_serializer.rb +58 -35
- data/lib/sequel/plugins/dataset_associations.rb +60 -18
- data/lib/sequel/plugins/def_dataset_method.rb +90 -0
- data/lib/sequel/plugins/defaults_setter.rb +74 -13
- data/lib/sequel/plugins/delay_add_association.rb +4 -1
- data/lib/sequel/plugins/dirty.rb +65 -24
- data/lib/sequel/plugins/eager_each.rb +27 -3
- data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
- data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
- data/lib/sequel/plugins/error_splitter.rb +19 -12
- data/lib/sequel/plugins/finder.rb +246 -0
- data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
- data/lib/sequel/plugins/force_encoding.rb +9 -12
- data/lib/sequel/plugins/hook_class_methods.rb +39 -54
- data/lib/sequel/plugins/input_transformer.rb +20 -10
- data/lib/sequel/plugins/insert_conflict.rb +72 -0
- data/lib/sequel/plugins/insert_returning_select.rb +4 -2
- data/lib/sequel/plugins/instance_filters.rb +12 -8
- data/lib/sequel/plugins/instance_hooks.rb +36 -17
- data/lib/sequel/plugins/instance_specific_default.rb +113 -0
- data/lib/sequel/plugins/inverted_subsets.rb +24 -13
- data/lib/sequel/plugins/json_serializer.rb +123 -47
- data/lib/sequel/plugins/lazy_attributes.rb +20 -14
- data/lib/sequel/plugins/list.rb +40 -26
- data/lib/sequel/plugins/many_through_many.rb +28 -12
- data/lib/sequel/plugins/modification_detection.rb +17 -5
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -5
- data/lib/sequel/plugins/nested_attributes.rb +55 -28
- data/lib/sequel/plugins/optimistic_locking.rb +5 -3
- data/lib/sequel/plugins/pg_array_associations.rb +52 -18
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +348 -0
- data/lib/sequel/plugins/pg_row.rb +7 -51
- data/lib/sequel/plugins/prepared_statements.rb +53 -72
- data/lib/sequel/plugins/prepared_statements_safe.rb +13 -5
- data/lib/sequel/plugins/rcte_tree.rb +43 -63
- data/lib/sequel/plugins/serialization.rb +37 -44
- data/lib/sequel/plugins/serialization_modification_detection.rb +3 -1
- data/lib/sequel/plugins/sharding.rb +17 -10
- data/lib/sequel/plugins/single_table_inheritance.rb +62 -28
- data/lib/sequel/plugins/singular_table_names.rb +2 -0
- data/lib/sequel/plugins/skip_create_refresh.rb +5 -3
- data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
- data/lib/sequel/plugins/split_values.rb +13 -6
- data/lib/sequel/plugins/static_cache.rb +79 -53
- data/lib/sequel/plugins/static_cache_cache.rb +53 -0
- data/lib/sequel/plugins/string_stripper.rb +5 -3
- data/lib/sequel/plugins/subclasses.rb +20 -2
- data/lib/sequel/plugins/subset_conditions.rb +48 -0
- data/lib/sequel/plugins/table_select.rb +4 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +120 -6
- data/lib/sequel/plugins/throw_failures.rb +110 -0
- data/lib/sequel/plugins/timestamps.rb +22 -8
- data/lib/sequel/plugins/touch.rb +21 -8
- data/lib/sequel/plugins/tree.rb +57 -30
- data/lib/sequel/plugins/typecast_on_load.rb +14 -4
- data/lib/sequel/plugins/unlimited_update.rb +3 -7
- data/lib/sequel/plugins/update_or_create.rb +6 -4
- data/lib/sequel/plugins/update_primary_key.rb +3 -1
- data/lib/sequel/plugins/update_refresh.rb +28 -15
- data/lib/sequel/plugins/uuid.rb +70 -0
- data/lib/sequel/plugins/validate_associated.rb +20 -0
- data/lib/sequel/plugins/validation_class_methods.rb +40 -19
- data/lib/sequel/plugins/validation_contexts.rb +49 -0
- data/lib/sequel/plugins/validation_helpers.rb +49 -31
- data/lib/sequel/plugins/whitelist_security.rb +122 -0
- data/lib/sequel/plugins/xml_serializer.rb +31 -30
- data/lib/sequel/sql.rb +479 -329
- data/lib/sequel/timezones.rb +62 -32
- data/lib/sequel/version.rb +10 -3
- metadata +177 -477
- data/Rakefile +0 -165
- data/doc/active_record.rdoc +0 -912
- data/doc/release_notes/1.0.txt +0 -38
- data/doc/release_notes/1.1.txt +0 -143
- data/doc/release_notes/1.3.txt +0 -101
- data/doc/release_notes/1.4.0.txt +0 -53
- data/doc/release_notes/1.5.0.txt +0 -155
- data/doc/release_notes/2.0.0.txt +0 -298
- data/doc/release_notes/2.1.0.txt +0 -271
- data/doc/release_notes/2.10.0.txt +0 -328
- data/doc/release_notes/2.11.0.txt +0 -215
- data/doc/release_notes/2.12.0.txt +0 -534
- data/doc/release_notes/2.2.0.txt +0 -253
- data/doc/release_notes/2.3.0.txt +0 -88
- data/doc/release_notes/2.4.0.txt +0 -106
- data/doc/release_notes/2.5.0.txt +0 -137
- data/doc/release_notes/2.6.0.txt +0 -157
- data/doc/release_notes/2.7.0.txt +0 -166
- data/doc/release_notes/2.8.0.txt +0 -171
- data/doc/release_notes/2.9.0.txt +0 -97
- data/doc/release_notes/3.0.0.txt +0 -221
- data/doc/release_notes/3.1.0.txt +0 -406
- data/doc/release_notes/3.10.0.txt +0 -286
- data/doc/release_notes/3.11.0.txt +0 -254
- data/doc/release_notes/3.12.0.txt +0 -304
- data/doc/release_notes/3.13.0.txt +0 -210
- data/doc/release_notes/3.14.0.txt +0 -118
- data/doc/release_notes/3.15.0.txt +0 -78
- data/doc/release_notes/3.16.0.txt +0 -45
- data/doc/release_notes/3.17.0.txt +0 -58
- data/doc/release_notes/3.18.0.txt +0 -120
- data/doc/release_notes/3.19.0.txt +0 -67
- data/doc/release_notes/3.2.0.txt +0 -268
- data/doc/release_notes/3.20.0.txt +0 -41
- data/doc/release_notes/3.21.0.txt +0 -87
- data/doc/release_notes/3.22.0.txt +0 -39
- data/doc/release_notes/3.23.0.txt +0 -172
- data/doc/release_notes/3.24.0.txt +0 -420
- data/doc/release_notes/3.25.0.txt +0 -88
- data/doc/release_notes/3.26.0.txt +0 -88
- data/doc/release_notes/3.27.0.txt +0 -82
- data/doc/release_notes/3.28.0.txt +0 -304
- data/doc/release_notes/3.29.0.txt +0 -459
- data/doc/release_notes/3.3.0.txt +0 -192
- data/doc/release_notes/3.30.0.txt +0 -135
- data/doc/release_notes/3.31.0.txt +0 -146
- data/doc/release_notes/3.32.0.txt +0 -202
- data/doc/release_notes/3.33.0.txt +0 -157
- data/doc/release_notes/3.34.0.txt +0 -671
- data/doc/release_notes/3.35.0.txt +0 -144
- data/doc/release_notes/3.36.0.txt +0 -245
- data/doc/release_notes/3.37.0.txt +0 -338
- data/doc/release_notes/3.38.0.txt +0 -234
- data/doc/release_notes/3.39.0.txt +0 -237
- data/doc/release_notes/3.4.0.txt +0 -325
- data/doc/release_notes/3.40.0.txt +0 -73
- data/doc/release_notes/3.41.0.txt +0 -155
- data/doc/release_notes/3.42.0.txt +0 -74
- data/doc/release_notes/3.43.0.txt +0 -105
- data/doc/release_notes/3.44.0.txt +0 -152
- data/doc/release_notes/3.45.0.txt +0 -179
- data/doc/release_notes/3.46.0.txt +0 -122
- data/doc/release_notes/3.47.0.txt +0 -270
- data/doc/release_notes/3.48.0.txt +0 -477
- data/doc/release_notes/3.5.0.txt +0 -510
- data/doc/release_notes/3.6.0.txt +0 -366
- data/doc/release_notes/3.7.0.txt +0 -179
- data/doc/release_notes/3.8.0.txt +0 -151
- data/doc/release_notes/3.9.0.txt +0 -233
- data/doc/release_notes/4.0.0.txt +0 -262
- data/doc/release_notes/4.1.0.txt +0 -85
- data/doc/release_notes/4.10.0.txt +0 -226
- data/doc/release_notes/4.11.0.txt +0 -147
- data/doc/release_notes/4.12.0.txt +0 -105
- data/doc/release_notes/4.13.0.txt +0 -169
- data/doc/release_notes/4.14.0.txt +0 -68
- data/doc/release_notes/4.15.0.txt +0 -56
- data/doc/release_notes/4.16.0.txt +0 -36
- data/doc/release_notes/4.17.0.txt +0 -38
- data/doc/release_notes/4.18.0.txt +0 -36
- data/doc/release_notes/4.19.0.txt +0 -45
- data/doc/release_notes/4.2.0.txt +0 -129
- data/doc/release_notes/4.20.0.txt +0 -79
- data/doc/release_notes/4.21.0.txt +0 -94
- data/doc/release_notes/4.22.0.txt +0 -72
- data/doc/release_notes/4.23.0.txt +0 -65
- data/doc/release_notes/4.24.0.txt +0 -99
- data/doc/release_notes/4.25.0.txt +0 -181
- data/doc/release_notes/4.26.0.txt +0 -44
- data/doc/release_notes/4.3.0.txt +0 -40
- data/doc/release_notes/4.4.0.txt +0 -92
- data/doc/release_notes/4.5.0.txt +0 -34
- data/doc/release_notes/4.6.0.txt +0 -30
- data/doc/release_notes/4.7.0.txt +0 -103
- data/doc/release_notes/4.8.0.txt +0 -175
- data/doc/release_notes/4.9.0.txt +0 -190
- data/lib/sequel/adapters/cubrid.rb +0 -142
- data/lib/sequel/adapters/do.rb +0 -156
- data/lib/sequel/adapters/do/mysql.rb +0 -64
- data/lib/sequel/adapters/do/postgres.rb +0 -42
- data/lib/sequel/adapters/do/sqlite3.rb +0 -40
- data/lib/sequel/adapters/jdbc/as400.rb +0 -82
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -62
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -34
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -31
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -31
- data/lib/sequel/adapters/odbc/progress.rb +0 -8
- data/lib/sequel/adapters/shared/cubrid.rb +0 -243
- data/lib/sequel/adapters/shared/firebird.rb +0 -245
- data/lib/sequel/adapters/shared/informix.rb +0 -52
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -150
- data/lib/sequel/adapters/shared/progress.rb +0 -38
- data/lib/sequel/adapters/swift.rb +0 -158
- data/lib/sequel/adapters/swift/mysql.rb +0 -47
- data/lib/sequel/adapters/swift/postgres.rb +0 -45
- data/lib/sequel/adapters/swift/sqlite.rb +0 -47
- data/lib/sequel/adapters/utils/pg_types.rb +0 -68
- data/lib/sequel/dataset/mutation.rb +0 -109
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -3
- data/lib/sequel/extensions/filter_having.rb +0 -59
- data/lib/sequel/extensions/hash_aliases.rb +0 -45
- data/lib/sequel/extensions/meta_def.rb +0 -31
- data/lib/sequel/extensions/query_literals.rb +0 -80
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -22
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -118
- data/lib/sequel/extensions/set_overrides.rb +0 -72
- data/lib/sequel/no_core_ext.rb +0 -1
- data/lib/sequel/plugins/association_autoreloading.rb +0 -7
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -7
- data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -78
- data/lib/sequel/plugins/prepared_statements_associations.rb +0 -117
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -59
- data/lib/sequel/plugins/schema.rb +0 -80
- data/lib/sequel/plugins/scissors.rb +0 -33
- data/spec/adapters/db2_spec.rb +0 -160
- data/spec/adapters/firebird_spec.rb +0 -411
- data/spec/adapters/informix_spec.rb +0 -100
- data/spec/adapters/mssql_spec.rb +0 -706
- data/spec/adapters/mysql_spec.rb +0 -1287
- data/spec/adapters/oracle_spec.rb +0 -313
- data/spec/adapters/postgres_spec.rb +0 -3725
- data/spec/adapters/spec_helper.rb +0 -43
- data/spec/adapters/sqlanywhere_spec.rb +0 -170
- data/spec/adapters/sqlite_spec.rb +0 -653
- data/spec/bin_spec.rb +0 -254
- data/spec/core/connection_pool_spec.rb +0 -1016
- data/spec/core/database_spec.rb +0 -2531
- data/spec/core/dataset_spec.rb +0 -5098
- data/spec/core/deprecated_spec.rb +0 -70
- data/spec/core/expression_filters_spec.rb +0 -1243
- data/spec/core/mock_adapter_spec.rb +0 -462
- data/spec/core/object_graph_spec.rb +0 -303
- data/spec/core/placeholder_literalizer_spec.rb +0 -163
- data/spec/core/schema_generator_spec.rb +0 -179
- data/spec/core/schema_spec.rb +0 -1659
- data/spec/core/spec_helper.rb +0 -34
- data/spec/core/version_spec.rb +0 -7
- data/spec/core_extensions_spec.rb +0 -699
- data/spec/extensions/accessed_columns_spec.rb +0 -51
- data/spec/extensions/active_model_spec.rb +0 -123
- data/spec/extensions/after_initialize_spec.rb +0 -24
- data/spec/extensions/arbitrary_servers_spec.rb +0 -109
- data/spec/extensions/association_dependencies_spec.rb +0 -117
- data/spec/extensions/association_pks_spec.rb +0 -365
- data/spec/extensions/association_proxies_spec.rb +0 -86
- data/spec/extensions/auto_validations_spec.rb +0 -192
- data/spec/extensions/blacklist_security_spec.rb +0 -88
- data/spec/extensions/blank_spec.rb +0 -69
- data/spec/extensions/boolean_readers_spec.rb +0 -93
- data/spec/extensions/caching_spec.rb +0 -270
- data/spec/extensions/class_table_inheritance_spec.rb +0 -420
- data/spec/extensions/column_conflicts_spec.rb +0 -60
- data/spec/extensions/column_select_spec.rb +0 -108
- data/spec/extensions/columns_introspection_spec.rb +0 -91
- data/spec/extensions/composition_spec.rb +0 -242
- data/spec/extensions/connection_validator_spec.rb +0 -120
- data/spec/extensions/constraint_validations_plugin_spec.rb +0 -274
- data/spec/extensions/constraint_validations_spec.rb +0 -325
- data/spec/extensions/core_refinements_spec.rb +0 -519
- data/spec/extensions/csv_serializer_spec.rb +0 -173
- data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
- data/spec/extensions/dataset_associations_spec.rb +0 -311
- data/spec/extensions/dataset_source_alias_spec.rb +0 -51
- data/spec/extensions/date_arithmetic_spec.rb +0 -150
- data/spec/extensions/defaults_setter_spec.rb +0 -101
- data/spec/extensions/delay_add_association_spec.rb +0 -52
- data/spec/extensions/dirty_spec.rb +0 -180
- data/spec/extensions/eager_each_spec.rb +0 -42
- data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
- data/spec/extensions/error_splitter_spec.rb +0 -18
- data/spec/extensions/error_sql_spec.rb +0 -20
- data/spec/extensions/eval_inspect_spec.rb +0 -73
- data/spec/extensions/filter_having_spec.rb +0 -40
- data/spec/extensions/force_encoding_spec.rb +0 -114
- data/spec/extensions/from_block_spec.rb +0 -21
- data/spec/extensions/graph_each_spec.rb +0 -109
- data/spec/extensions/hash_aliases_spec.rb +0 -24
- data/spec/extensions/hook_class_methods_spec.rb +0 -429
- data/spec/extensions/inflector_spec.rb +0 -183
- data/spec/extensions/input_transformer_spec.rb +0 -54
- data/spec/extensions/insert_returning_select_spec.rb +0 -46
- data/spec/extensions/instance_filters_spec.rb +0 -79
- data/spec/extensions/instance_hooks_spec.rb +0 -276
- data/spec/extensions/inverted_subsets_spec.rb +0 -33
- data/spec/extensions/json_serializer_spec.rb +0 -291
- data/spec/extensions/lazy_attributes_spec.rb +0 -170
- data/spec/extensions/list_spec.rb +0 -267
- data/spec/extensions/looser_typecasting_spec.rb +0 -43
- data/spec/extensions/many_through_many_spec.rb +0 -2172
- data/spec/extensions/meta_def_spec.rb +0 -21
- data/spec/extensions/migration_spec.rb +0 -712
- data/spec/extensions/modification_detection_spec.rb +0 -80
- data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
- data/spec/extensions/named_timezones_spec.rb +0 -108
- data/spec/extensions/nested_attributes_spec.rb +0 -697
- data/spec/extensions/null_dataset_spec.rb +0 -85
- data/spec/extensions/optimistic_locking_spec.rb +0 -128
- data/spec/extensions/pagination_spec.rb +0 -118
- data/spec/extensions/pg_array_associations_spec.rb +0 -736
- data/spec/extensions/pg_array_ops_spec.rb +0 -143
- data/spec/extensions/pg_array_spec.rb +0 -395
- data/spec/extensions/pg_enum_spec.rb +0 -92
- data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
- data/spec/extensions/pg_hstore_spec.rb +0 -206
- data/spec/extensions/pg_inet_ops_spec.rb +0 -101
- data/spec/extensions/pg_inet_spec.rb +0 -52
- data/spec/extensions/pg_interval_spec.rb +0 -76
- data/spec/extensions/pg_json_ops_spec.rb +0 -229
- data/spec/extensions/pg_json_spec.rb +0 -218
- data/spec/extensions/pg_loose_count_spec.rb +0 -17
- data/spec/extensions/pg_range_ops_spec.rb +0 -58
- data/spec/extensions/pg_range_spec.rb +0 -404
- data/spec/extensions/pg_row_ops_spec.rb +0 -60
- data/spec/extensions/pg_row_plugin_spec.rb +0 -62
- data/spec/extensions/pg_row_spec.rb +0 -360
- data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
- data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
- data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
- data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
- data/spec/extensions/prepared_statements_spec.rb +0 -103
- data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
- data/spec/extensions/pretty_table_spec.rb +0 -92
- data/spec/extensions/query_literals_spec.rb +0 -183
- data/spec/extensions/query_spec.rb +0 -102
- data/spec/extensions/rcte_tree_spec.rb +0 -392
- data/spec/extensions/round_timestamps_spec.rb +0 -43
- data/spec/extensions/schema_caching_spec.rb +0 -41
- data/spec/extensions/schema_dumper_spec.rb +0 -789
- data/spec/extensions/schema_spec.rb +0 -117
- data/spec/extensions/scissors_spec.rb +0 -26
- data/spec/extensions/select_remove_spec.rb +0 -38
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
- data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
- data/spec/extensions/serialization_spec.rb +0 -362
- data/spec/extensions/server_block_spec.rb +0 -90
- data/spec/extensions/set_overrides_spec.rb +0 -61
- data/spec/extensions/sharding_spec.rb +0 -198
- data/spec/extensions/shared_caching_spec.rb +0 -175
- data/spec/extensions/single_table_inheritance_spec.rb +0 -297
- data/spec/extensions/singular_table_names_spec.rb +0 -22
- data/spec/extensions/skip_create_refresh_spec.rb +0 -17
- data/spec/extensions/spec_helper.rb +0 -71
- data/spec/extensions/split_array_nil_spec.rb +0 -24
- data/spec/extensions/split_values_spec.rb +0 -22
- data/spec/extensions/sql_expr_spec.rb +0 -60
- data/spec/extensions/static_cache_spec.rb +0 -361
- data/spec/extensions/string_date_time_spec.rb +0 -95
- data/spec/extensions/string_stripper_spec.rb +0 -68
- data/spec/extensions/subclasses_spec.rb +0 -66
- data/spec/extensions/table_select_spec.rb +0 -71
- data/spec/extensions/tactical_eager_loading_spec.rb +0 -82
- data/spec/extensions/thread_local_timezones_spec.rb +0 -67
- data/spec/extensions/timestamps_spec.rb +0 -175
- data/spec/extensions/to_dot_spec.rb +0 -154
- data/spec/extensions/touch_spec.rb +0 -203
- data/spec/extensions/tree_spec.rb +0 -274
- data/spec/extensions/typecast_on_load_spec.rb +0 -80
- data/spec/extensions/unlimited_update_spec.rb +0 -20
- data/spec/extensions/update_or_create_spec.rb +0 -87
- data/spec/extensions/update_primary_key_spec.rb +0 -100
- data/spec/extensions/update_refresh_spec.rb +0 -53
- data/spec/extensions/validate_associated_spec.rb +0 -52
- data/spec/extensions/validation_class_methods_spec.rb +0 -1027
- data/spec/extensions/validation_helpers_spec.rb +0 -541
- data/spec/extensions/xml_serializer_spec.rb +0 -207
- data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
- data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
- data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
- data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
- data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
- data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
- data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
- data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
- data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
- data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
- data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
- data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
- data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
- data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/reversible_migrations/001_reversible.rb +0 -5
- data/spec/files/reversible_migrations/002_reversible.rb +0 -5
- data/spec/files/reversible_migrations/003_reversible.rb +0 -5
- data/spec/files/reversible_migrations/004_reversible.rb +0 -5
- data/spec/files/reversible_migrations/005_reversible.rb +0 -10
- data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
- data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
- data/spec/guards_helper.rb +0 -55
- data/spec/integration/associations_test.rb +0 -2454
- data/spec/integration/database_test.rb +0 -113
- data/spec/integration/dataset_test.rb +0 -1808
- data/spec/integration/eager_loader_test.rb +0 -687
- data/spec/integration/migrator_test.rb +0 -240
- data/spec/integration/model_test.rb +0 -226
- data/spec/integration/plugin_test.rb +0 -2240
- data/spec/integration/prepared_statement_test.rb +0 -467
- data/spec/integration/schema_test.rb +0 -817
- data/spec/integration/spec_helper.rb +0 -48
- data/spec/integration/timezone_test.rb +0 -86
- data/spec/integration/transaction_test.rb +0 -374
- data/spec/integration/type_test.rb +0 -133
- data/spec/model/association_reflection_spec.rb +0 -525
- data/spec/model/associations_spec.rb +0 -4426
- data/spec/model/base_spec.rb +0 -759
- data/spec/model/class_dataset_methods_spec.rb +0 -146
- data/spec/model/dataset_methods_spec.rb +0 -149
- data/spec/model/eager_loading_spec.rb +0 -2137
- data/spec/model/hooks_spec.rb +0 -604
- data/spec/model/inflector_spec.rb +0 -26
- data/spec/model/model_spec.rb +0 -982
- data/spec/model/plugins_spec.rb +0 -299
- data/spec/model/record_spec.rb +0 -2147
- data/spec/model/spec_helper.rb +0 -46
- data/spec/model/validations_spec.rb +0 -193
- data/spec/sequel_coverage.rb +0 -15
- data/spec/spec_config.rb +0 -10
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
module Plugins
|
|
3
5
|
# The lazy_attributes plugin allows users to easily set that some attributes
|
|
@@ -11,7 +13,7 @@ module Sequel
|
|
|
11
13
|
# get the reviews for all of those albums:
|
|
12
14
|
#
|
|
13
15
|
# Album.plugin :lazy_attributes, :review
|
|
14
|
-
# Album.
|
|
16
|
+
# Album.where{id < 100}.all do |a|
|
|
15
17
|
# a.review
|
|
16
18
|
# end
|
|
17
19
|
#
|
|
@@ -36,9 +38,12 @@ module Sequel
|
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
module ClassMethods
|
|
39
|
-
#
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
# Freeze lazy attributes module when freezing model class.
|
|
42
|
+
def freeze
|
|
43
|
+
@lazy_attributes_module.freeze if @lazy_attributes_module
|
|
44
|
+
|
|
45
|
+
super
|
|
46
|
+
end
|
|
42
47
|
|
|
43
48
|
# Remove the given attributes from the list of columns selected by default.
|
|
44
49
|
# For each attribute given, create an accessor method that allows a lazy
|
|
@@ -57,8 +62,8 @@ module Sequel
|
|
|
57
62
|
# :dataset :: The base dataset to use for the lazy attribute lookup
|
|
58
63
|
# :table :: The table name to use to qualify the attribute and primary key columns.
|
|
59
64
|
def define_lazy_attribute_getter(a, opts=OPTS)
|
|
60
|
-
include(
|
|
61
|
-
lazy_attributes_module.class_eval do
|
|
65
|
+
include(@lazy_attributes_module ||= Module.new) unless @lazy_attributes_module
|
|
66
|
+
@lazy_attributes_module.class_eval do
|
|
62
67
|
define_method(a) do
|
|
63
68
|
if !values.has_key?(a) && !new?
|
|
64
69
|
lazy_attribute_lookup(a, opts)
|
|
@@ -78,9 +83,8 @@ module Sequel
|
|
|
78
83
|
# the attribute for just the current object. Return the value of
|
|
79
84
|
# the attribute for the current object.
|
|
80
85
|
def lazy_attribute_lookup(a, opts=OPTS)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
end
|
|
86
|
+
table = opts[:table] || model.table_name
|
|
87
|
+
selection = Sequel.qualify(table, a)
|
|
84
88
|
|
|
85
89
|
if base_ds = opts[:dataset]
|
|
86
90
|
ds = base_ds.where(qualified_pk_hash(table))
|
|
@@ -89,19 +93,21 @@ module Sequel
|
|
|
89
93
|
ds = this
|
|
90
94
|
end
|
|
91
95
|
|
|
92
|
-
selection = Sequel.qualify(table, a)
|
|
93
|
-
|
|
94
96
|
if frozen?
|
|
95
|
-
return ds.
|
|
97
|
+
return ds.get(selection)
|
|
96
98
|
end
|
|
97
99
|
|
|
98
100
|
if retrieved_with
|
|
99
|
-
|
|
101
|
+
primary_key = model.primary_key
|
|
100
102
|
composite_pk = true if primary_key.is_a?(Array)
|
|
101
103
|
id_map = {}
|
|
102
104
|
retrieved_with.each{|o| id_map[o.pk] = o unless o.values.has_key?(a) || o.frozen?}
|
|
103
105
|
predicate_key = composite_pk ? primary_key.map{|k| Sequel.qualify(table, k)} : Sequel.qualify(table, primary_key)
|
|
104
|
-
base_ds.
|
|
106
|
+
base_ds.
|
|
107
|
+
select(*(Array(primary_key).map{|k| Sequel.qualify(table, k)} + [selection])).
|
|
108
|
+
where(predicate_key=>id_map.keys).
|
|
109
|
+
naked.
|
|
110
|
+
each do |row|
|
|
105
111
|
obj = id_map[composite_pk ? row.values_at(*primary_key) : row[primary_key]]
|
|
106
112
|
if obj && !obj.values.has_key?(a)
|
|
107
113
|
obj.values[a] = row[a]
|
data/lib/sequel/plugins/list.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
module Plugins
|
|
3
5
|
# The list plugin allows for model instances to be part of an ordered list,
|
|
@@ -9,7 +11,7 @@ module Sequel
|
|
|
9
11
|
#
|
|
10
12
|
# class Item < Sequel::Model(:items)
|
|
11
13
|
# plugin :list # will use :position field for position
|
|
12
|
-
# plugin :list, :
|
|
14
|
+
# plugin :list, field: :pos # will use :pos field for position
|
|
13
15
|
# end
|
|
14
16
|
#
|
|
15
17
|
# item = Item[1]
|
|
@@ -36,34 +38,41 @@ module Sequel
|
|
|
36
38
|
# For example, if each item has a +user_id+ field, and you want every user
|
|
37
39
|
# to have their own list:
|
|
38
40
|
#
|
|
39
|
-
# Item.plugin :list, :
|
|
41
|
+
# Item.plugin :list, scope: :user_id
|
|
40
42
|
#
|
|
41
43
|
# Note that using this plugin modifies the order of the model's dataset to
|
|
42
44
|
# sort by the position and scope fields. Also note that this plugin is subject to
|
|
43
45
|
# race conditions, and is not safe when concurrent modifications are made
|
|
44
46
|
# to the same list.
|
|
45
47
|
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
+
# Note that by default, unlike ruby arrays, the list plugin assumes the first
|
|
49
|
+
# entry in the list has position 1, not position 0.
|
|
50
|
+
#
|
|
51
|
+
# You can change this by providing an integer <tt>:top</tt> option:
|
|
52
|
+
#
|
|
53
|
+
# Item.plugin :list, top: 0
|
|
48
54
|
#
|
|
49
55
|
# Copyright (c) 2007-2010 Sharon Rosner, Wayne E. Seguin, Aman Gupta, Adrian Madrid, Jeremy Evans
|
|
50
56
|
module List
|
|
51
|
-
# Set the +position_field+ and +
|
|
52
|
-
# using the <tt>:field</tt
|
|
57
|
+
# Set the +position_field+, +scope_proc+ and +top_of_list+ attributes for the model,
|
|
58
|
+
# using the <tt>:field</tt>, <tt>:scope</tt>, and <tt>:top</tt> options, respectively.
|
|
53
59
|
# The <tt>:scope</tt> option can be a symbol, array of symbols, or a proc that
|
|
54
60
|
# accepts a model instance and returns a dataset representing the list.
|
|
55
61
|
# Also, modify the model dataset's order to order by the position and scope fields.
|
|
56
62
|
def self.configure(model, opts = OPTS)
|
|
57
63
|
model.position_field = opts[:field] || :position
|
|
58
64
|
model.dataset = model.dataset.order_prepend(model.position_field)
|
|
65
|
+
model.instance_exec do
|
|
66
|
+
@top_of_list = opts[:top] || 1
|
|
67
|
+
end
|
|
59
68
|
|
|
60
69
|
model.scope_proc = case scope = opts[:scope]
|
|
61
70
|
when Symbol
|
|
62
71
|
model.dataset = model.dataset.order_prepend(scope)
|
|
63
|
-
proc{|obj| obj.model.
|
|
72
|
+
proc{|obj| obj.model.where(scope=>obj.public_send(scope))}
|
|
64
73
|
when Array
|
|
65
74
|
model.dataset = model.dataset.order_prepend(*scope)
|
|
66
|
-
proc{|obj| obj.model.
|
|
75
|
+
proc{|obj| obj.model.where(scope.map{|s| [s, obj.get_column_value(s)]})}
|
|
67
76
|
else
|
|
68
77
|
scope
|
|
69
78
|
end
|
|
@@ -78,7 +87,10 @@ module Sequel
|
|
|
78
87
|
# proc should accept an instance and return a dataset representing the list.
|
|
79
88
|
attr_accessor :scope_proc
|
|
80
89
|
|
|
81
|
-
|
|
90
|
+
# An Integer to use as the position of the top of the list. Defaults to 1.
|
|
91
|
+
attr_reader :top_of_list
|
|
92
|
+
|
|
93
|
+
Plugins.inherited_instance_variables(self, :@position_field=>nil, :@scope_proc=>nil, :@top_of_list=>nil)
|
|
82
94
|
end
|
|
83
95
|
|
|
84
96
|
module InstanceMethods
|
|
@@ -87,21 +99,12 @@ module Sequel
|
|
|
87
99
|
list_dataset.first(position_field => p)
|
|
88
100
|
end
|
|
89
101
|
|
|
90
|
-
# Set the value of the position_field to the maximum value plus 1 unless the
|
|
91
|
-
# position field already has a value.
|
|
92
|
-
def before_create
|
|
93
|
-
unless get_column_value(position_field)
|
|
94
|
-
set_column_value("#{position_field}=", list_dataset.max(position_field).to_i+1)
|
|
95
|
-
end
|
|
96
|
-
super
|
|
97
|
-
end
|
|
98
|
-
|
|
99
102
|
# When destroying an instance, move all entries after the instance down
|
|
100
103
|
# one position, so that there aren't any gaps
|
|
101
104
|
def after_destroy
|
|
102
105
|
super
|
|
103
106
|
|
|
104
|
-
f = Sequel
|
|
107
|
+
f = Sequel[position_field]
|
|
105
108
|
list_dataset.where(f > position_value).update(f => f - 1)
|
|
106
109
|
end
|
|
107
110
|
|
|
@@ -121,20 +124,22 @@ module Sequel
|
|
|
121
124
|
move_to(position_value + n)
|
|
122
125
|
end
|
|
123
126
|
|
|
124
|
-
# Move this instance to the given place in the list.
|
|
125
|
-
#
|
|
127
|
+
# Move this instance to the given place in the list. If lp is not
|
|
128
|
+
# given or greater than the last list position, uses the last list
|
|
129
|
+
# position. If lp is less than the top list position, uses the
|
|
130
|
+
# top list position.
|
|
126
131
|
def move_to(target, lp = nil)
|
|
127
132
|
current = position_value
|
|
128
133
|
if target != current
|
|
129
134
|
checked_transaction do
|
|
130
135
|
ds = list_dataset
|
|
131
136
|
op, ds = if target < current
|
|
132
|
-
target =
|
|
133
|
-
[:+, ds.
|
|
137
|
+
target = model.top_of_list if target < model.top_of_list
|
|
138
|
+
[:+, ds.where(position_field=>target...current)]
|
|
134
139
|
else
|
|
135
140
|
lp ||= last_position
|
|
136
141
|
target = lp if target > lp
|
|
137
|
-
[:-, ds.
|
|
142
|
+
[:-, ds.where(position_field=>(current + 1)..target)]
|
|
138
143
|
end
|
|
139
144
|
ds.update(position_field => Sequel::SQL::NumericExpression.new(op, position_field, 1))
|
|
140
145
|
update(position_field => target)
|
|
@@ -149,9 +154,9 @@ module Sequel
|
|
|
149
154
|
move_to(lp, lp)
|
|
150
155
|
end
|
|
151
156
|
|
|
152
|
-
# Move this instance to the top (first position, position 1) of the list.
|
|
157
|
+
# Move this instance to the top (first position, usually position 1) of the list.
|
|
153
158
|
def move_to_top
|
|
154
|
-
move_to(
|
|
159
|
+
move_to(model.top_of_list)
|
|
155
160
|
end
|
|
156
161
|
|
|
157
162
|
# Move this instance the given number of places up in the list, or 1 place
|
|
@@ -177,6 +182,15 @@ module Sequel
|
|
|
177
182
|
self.next(n * -1)
|
|
178
183
|
end
|
|
179
184
|
|
|
185
|
+
# Set the value of the position_field to the maximum value plus 1 unless the
|
|
186
|
+
# position field already has a value.
|
|
187
|
+
def before_validation
|
|
188
|
+
unless get_column_value(position_field)
|
|
189
|
+
set_column_value("#{position_field}=", list_dataset.max(position_field).to_i+1)
|
|
190
|
+
end
|
|
191
|
+
super
|
|
192
|
+
end
|
|
193
|
+
|
|
180
194
|
private
|
|
181
195
|
|
|
182
196
|
# The model's position field, an instance method for ease of use.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
module Plugins
|
|
3
5
|
# The many_through_many plugin allow you to create an association using multiple join tables.
|
|
@@ -44,18 +46,18 @@ module Sequel
|
|
|
44
46
|
# Artist.many_through_many :artists, [[:albums_artists, :artist_id, :album_id], [:albums_artists, :album_id, :artist_id]]
|
|
45
47
|
#
|
|
46
48
|
# # All albums by artists that are associated to any album that this artist is associated to
|
|
47
|
-
# Artist.many_through_many :artist_albums, [[:albums_artists, :artist_id, :album_id],
|
|
48
|
-
# [:albums_artists, :album_id, :artist_id], [:albums_artists, :artist_id, :album_id]],
|
|
49
|
-
# :
|
|
49
|
+
# Artist.many_through_many :artist_albums, [[:albums_artists, :artist_id, :album_id],
|
|
50
|
+
# [:albums_artists, :album_id, :artist_id], [:albums_artists, :artist_id, :album_id]],
|
|
51
|
+
# class: :Album
|
|
50
52
|
#
|
|
51
53
|
# # All tracks on albums by this artist (also could be a many_to_many)
|
|
52
|
-
# Artist.many_through_many :tracks, [[:albums_artists, :artist_id, :album_id]],
|
|
53
|
-
# :
|
|
54
|
+
# Artist.many_through_many :tracks, [[:albums_artists, :artist_id, :album_id]],
|
|
55
|
+
# right_primary_key: :album_id
|
|
54
56
|
#
|
|
55
57
|
# Often you don't want the current object to appear in the array of associated objects. This is easiest to handle via an :after_load hook:
|
|
56
58
|
#
|
|
57
59
|
# Artist.many_through_many :artists, [[:albums_artists, :artist_id, :album_id], [:albums_artists, :album_id, :artist_id]],
|
|
58
|
-
# :
|
|
60
|
+
# after_load: lambda{|artist, associated_artists| associated_artists.delete(artist)}
|
|
59
61
|
#
|
|
60
62
|
# You can also handle it by adding a dataset block that excludes the current record (so it won't be retrieved at all), but
|
|
61
63
|
# that won't work when eagerly loading, which is why the :after_load proc is recommended instead.
|
|
@@ -63,7 +65,7 @@ module Sequel
|
|
|
63
65
|
# It's also common to not want duplicate records, in which case the :distinct option can be used:
|
|
64
66
|
#
|
|
65
67
|
# Artist.many_through_many :artists, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_artists, :album_id, :artist_id]],
|
|
66
|
-
# :
|
|
68
|
+
# distinct: true
|
|
67
69
|
#
|
|
68
70
|
# In addition to many_through_many, this plugin also adds one_through_many, for an association to a single object through multiple join tables.
|
|
69
71
|
# This is useful if there are unique constraints on the foreign keys in the join tables that reference back to the current table, or if you want
|
|
@@ -79,7 +81,7 @@ module Sequel
|
|
|
79
81
|
module ManyThroughMany
|
|
80
82
|
# The AssociationReflection subclass for many_through_many associations.
|
|
81
83
|
class ManyThroughManyAssociationReflection < Sequel::Model::Associations::ManyToManyAssociationReflection
|
|
82
|
-
Sequel::Model::Associations::ASSOCIATION_TYPES[:many_through_many] = self
|
|
84
|
+
Sequel.synchronize{Sequel::Model::Associations::ASSOCIATION_TYPES[:many_through_many] = self}
|
|
83
85
|
|
|
84
86
|
# many_through_many and one_through_many associations can be clones
|
|
85
87
|
def cloneable?(ref)
|
|
@@ -100,6 +102,17 @@ module Sequel
|
|
|
100
102
|
END
|
|
101
103
|
end
|
|
102
104
|
|
|
105
|
+
FINALIZE_SETTINGS = superclass::FINALIZE_SETTINGS.merge(
|
|
106
|
+
:associated_key_table=>:associated_key_table,
|
|
107
|
+
:edges=>:edges,
|
|
108
|
+
:final_edge=>:final_edge,
|
|
109
|
+
:final_reverse_edge=>:final_reverse_edge,
|
|
110
|
+
:reverse_edges=>:reverse_edges
|
|
111
|
+
).freeze
|
|
112
|
+
def finalize_settings
|
|
113
|
+
FINALIZE_SETTINGS
|
|
114
|
+
end
|
|
115
|
+
|
|
103
116
|
# The alias for the first join table.
|
|
104
117
|
def join_table_alias
|
|
105
118
|
final_reverse_edge[:alias]
|
|
@@ -131,7 +144,7 @@ module Sequel
|
|
|
131
144
|
table_alias = e[:table]
|
|
132
145
|
if aliases.include?(table_alias)
|
|
133
146
|
i = 0
|
|
134
|
-
table_alias =
|
|
147
|
+
table_alias = while true
|
|
135
148
|
ta = :"#{table_alias}_#{i}"
|
|
136
149
|
break ta unless aliases.include?(ta)
|
|
137
150
|
i += 1
|
|
@@ -179,7 +192,7 @@ module Sequel
|
|
|
179
192
|
end
|
|
180
193
|
|
|
181
194
|
class OneThroughManyAssociationReflection < ManyThroughManyAssociationReflection
|
|
182
|
-
Sequel::Model::Associations::ASSOCIATION_TYPES[:one_through_many] = self
|
|
195
|
+
Sequel.synchronize{Sequel::Model::Associations::ASSOCIATION_TYPES[:one_through_many] = self}
|
|
183
196
|
include Sequel::Model::Associations::SingularAssociationReflection
|
|
184
197
|
end
|
|
185
198
|
|
|
@@ -215,7 +228,10 @@ module Sequel
|
|
|
215
228
|
def def_many_through_many(opts)
|
|
216
229
|
one_through_many = opts[:type] == :one_through_many
|
|
217
230
|
opts[:read_only] = true
|
|
218
|
-
|
|
231
|
+
if opts[:uniq]
|
|
232
|
+
opts[:after_load] ||= []
|
|
233
|
+
opts[:after_load].unshift(:array_uniq!)
|
|
234
|
+
end
|
|
219
235
|
opts[:cartesian_product_number] ||= one_through_many ? 0 : 2
|
|
220
236
|
opts[:through] = opts[:through].map do |e|
|
|
221
237
|
case e
|
|
@@ -270,7 +286,7 @@ module Sequel
|
|
|
270
286
|
iq = nil
|
|
271
287
|
end
|
|
272
288
|
fe = opts.final_edge
|
|
273
|
-
ds.graph(opts.associated_class, use_only_conditions ? only_conditions : (Array(opts.right_primary_key).zip(Array(fe[:left])) + conditions), :select=>select, :table_alias=>eo[:table_alias], :qualify=>:deep, :join_type=>eo[:join_type]||join_type, :join_only=>eo[:join_only], &graph_block)
|
|
289
|
+
ds.graph(opts.associated_class.dataset, use_only_conditions ? only_conditions : (Array(opts.right_primary_key).zip(Array(fe[:left])) + conditions), :select=>select, :table_alias=>eo[:table_alias], :qualify=>:deep, :join_type=>eo[:join_type]||join_type, :join_only=>eo[:join_only], &graph_block)
|
|
274
290
|
end
|
|
275
291
|
end
|
|
276
292
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
module Plugins
|
|
3
5
|
# This plugin automatically detects in-place modifications to
|
|
@@ -15,6 +17,9 @@ module Sequel
|
|
|
15
17
|
# Note that for this plugin to work correctly, the column values must
|
|
16
18
|
# correctly implement the #hash method, returning the same value if
|
|
17
19
|
# the object is equal, and a different value if the object is not equal.
|
|
20
|
+
# As this solely uses hash values to check for modification, there may
|
|
21
|
+
# be cases where a modification is made and the hash value is the same,
|
|
22
|
+
# resulting in a false negative.
|
|
18
23
|
#
|
|
19
24
|
# Note that this plugin causes a performance hit for all retrieved
|
|
20
25
|
# objects, so it shouldn't be used in cases where performance is a
|
|
@@ -53,13 +58,20 @@ module Sequel
|
|
|
53
58
|
# Detect which columns have been modified by comparing the cached hash
|
|
54
59
|
# value to the hash of the current value.
|
|
55
60
|
def changed_columns
|
|
56
|
-
|
|
57
|
-
changed = []
|
|
58
|
-
v = @values
|
|
61
|
+
changed = super
|
|
59
62
|
if vh = @values_hashes
|
|
60
|
-
|
|
63
|
+
values = @values
|
|
64
|
+
changed = changed.dup if frozen?
|
|
65
|
+
vh.each do |c, v|
|
|
66
|
+
match = values.has_key?(c) && v == values[c].hash
|
|
67
|
+
if changed.include?(c)
|
|
68
|
+
changed.delete(c) if match
|
|
69
|
+
else
|
|
70
|
+
changed << c unless match
|
|
71
|
+
end
|
|
72
|
+
end
|
|
61
73
|
end
|
|
62
|
-
|
|
74
|
+
changed
|
|
63
75
|
end
|
|
64
76
|
|
|
65
77
|
private
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
module Plugins
|
|
3
5
|
# This plugin implements optimistic locking mechanism on Microsoft SQL Server
|
|
@@ -10,15 +12,15 @@ module Sequel
|
|
|
10
12
|
# end
|
|
11
13
|
# p1 = Person[1]
|
|
12
14
|
# p2 = Person[1]
|
|
13
|
-
# p1.update(:
|
|
14
|
-
# p2.update(:
|
|
15
|
+
# p1.update(name: 'Jim') # works
|
|
16
|
+
# p2.update(name: 'Bob') # raises Sequel::NoExistingObject
|
|
15
17
|
#
|
|
16
18
|
# In order for this plugin to work, you need to make sure that the database
|
|
17
19
|
# table has a column of timestamp or rowversion. The plugin uses a default
|
|
18
20
|
# name of timestamp for this columns, but you can override that using the
|
|
19
21
|
# :lock_column option:
|
|
20
22
|
#
|
|
21
|
-
# plugin :mssql_optimistic_locking, :
|
|
23
|
+
# plugin :mssql_optimistic_locking, lock_column: :column_name
|
|
22
24
|
#
|
|
23
25
|
# This plugin relies on the instance_filters plugin.
|
|
24
26
|
module MssqlOptimisticLocking
|
|
@@ -73,7 +75,8 @@ module Sequel
|
|
|
73
75
|
# it to be assigned.
|
|
74
76
|
def _save_update_all_columns_hash
|
|
75
77
|
v = @values.dup
|
|
76
|
-
|
|
78
|
+
cc = changed_columns
|
|
79
|
+
Array(primary_key).each{|x| v.delete(x) unless cc.include?(x)}
|
|
77
80
|
v.delete(model.lock_column)
|
|
78
81
|
v
|
|
79
82
|
end
|
|
@@ -82,7 +85,7 @@ module Sequel
|
|
|
82
85
|
def _update_without_checking(columns)
|
|
83
86
|
ds = _update_dataset
|
|
84
87
|
lc = model.lock_column
|
|
85
|
-
rows = ds.clone(ds.send(:default_server_opts, :sql=>ds.output(nil, [Sequel
|
|
88
|
+
rows = ds.clone(ds.send(:default_server_opts, :sql=>ds.output(nil, [Sequel[:inserted][lc]]).update_sql(columns))).all
|
|
86
89
|
values[lc] = rows.first[lc] unless rows.empty?
|
|
87
90
|
rows.length
|
|
88
91
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
module Plugins
|
|
3
5
|
# The nested_attributes plugin allows you to create, update, and delete
|
|
@@ -11,11 +13,11 @@ module Sequel
|
|
|
11
13
|
# The nested_attributes call defines a single method, <tt><i>association</i>_attributes=</tt>,
|
|
12
14
|
# (e.g. <tt>albums_attributes=</tt>). So if you have an Artist instance:
|
|
13
15
|
#
|
|
14
|
-
# a = Artist.new(:
|
|
16
|
+
# a = Artist.new(name: 'YJM')
|
|
15
17
|
#
|
|
16
18
|
# You can create new album instances related to this artist:
|
|
17
19
|
#
|
|
18
|
-
# a.albums_attributes = [{:
|
|
20
|
+
# a.albums_attributes = [{name: 'RF'}, {name: 'MO'}]
|
|
19
21
|
#
|
|
20
22
|
# Note that this doesn't send any queries to the database yet. That doesn't happen till
|
|
21
23
|
# you save the object:
|
|
@@ -31,7 +33,7 @@ module Sequel
|
|
|
31
33
|
# objects. You just need to make sure that the primary key field is filled in for the
|
|
32
34
|
# associated object:
|
|
33
35
|
#
|
|
34
|
-
# a.update(:albums_attributes => [{:
|
|
36
|
+
# a.update(:albums_attributes => [{id: 1, name: 'T'}])
|
|
35
37
|
#
|
|
36
38
|
# Since the primary key field is filled in, the plugin will update the album with id 1 instead
|
|
37
39
|
# of creating a new album.
|
|
@@ -39,15 +41,15 @@ module Sequel
|
|
|
39
41
|
# If you would like to delete the associated object instead of updating it, you add a _delete
|
|
40
42
|
# entry to the hash, and also pass the :destroy option when calling +nested_attributes+:
|
|
41
43
|
#
|
|
42
|
-
# Artist.nested_attributes :albums, :
|
|
43
|
-
# a.update(:albums_attributes => [{:
|
|
44
|
+
# Artist.nested_attributes :albums, destroy: true
|
|
45
|
+
# a.update(:albums_attributes => [{id: 1, _delete: true}])
|
|
44
46
|
#
|
|
45
47
|
# This will delete the related associated object from the database. If you want to leave the
|
|
46
48
|
# associated object in the database, but just remove it from the association, add a _remove
|
|
47
49
|
# entry in the hash, and also pass the :remove option when calling +nested_attributes+:
|
|
48
50
|
#
|
|
49
|
-
# Artist.nested_attributes :albums, :
|
|
50
|
-
# a.update(:albums_attributes => [{:
|
|
51
|
+
# Artist.nested_attributes :albums, remove: true
|
|
52
|
+
# a.update(:albums_attributes => [{id: 1, _remove: true}])
|
|
51
53
|
#
|
|
52
54
|
# The above example was for a one_to_many association, but the plugin also works similarly
|
|
53
55
|
# for other association types. For one_to_one and many_to_one associations, you need to
|
|
@@ -64,14 +66,25 @@ module Sequel
|
|
|
64
66
|
#
|
|
65
67
|
# Your web stack will probably parse that into a nested hash similar to:
|
|
66
68
|
#
|
|
67
|
-
# {
|
|
69
|
+
# {'artist'=>{'name'=>'Y', 'albums_attributes'=>{'0'=>{'name'=>'X'}, '1'=>{'id'=>'2', 'name'=>'Z'}}}}
|
|
68
70
|
#
|
|
69
71
|
# Then you can do:
|
|
70
72
|
#
|
|
71
|
-
# artist.
|
|
73
|
+
# artist.update_fields(params['artist'], %w'name albums_attributes')
|
|
74
|
+
#
|
|
75
|
+
# Note that Rails 5+ does not use a Hash for submitted parameters, and therefore
|
|
76
|
+
# the above will not work. With Rails 5+, you have to use:
|
|
77
|
+
#
|
|
78
|
+
# artist.update_fields(params.to_unsafe_h['artist'], %w'name albums_attributes')
|
|
72
79
|
#
|
|
73
80
|
# To save changes to the artist, create the first album and associate it to the artist,
|
|
74
81
|
# and update the other existing associated album.
|
|
82
|
+
#
|
|
83
|
+
# You can pass options for individual nested attributes, which will override the default
|
|
84
|
+
# nested attributes options for that association. This is useful for per-call filtering
|
|
85
|
+
# of the allowed fields:
|
|
86
|
+
#
|
|
87
|
+
# a.set_nested_attributes(:albums, params['artist'], :fields=>%w'name')
|
|
75
88
|
module NestedAttributes
|
|
76
89
|
# Depend on the validate_associated plugin.
|
|
77
90
|
def self.apply(model)
|
|
@@ -79,10 +92,13 @@ module Sequel
|
|
|
79
92
|
end
|
|
80
93
|
|
|
81
94
|
module ClassMethods
|
|
82
|
-
#
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
95
|
+
# Freeze nested_attributes_module when freezing model class.
|
|
96
|
+
def freeze
|
|
97
|
+
@nested_attributes_module.freeze if @nested_attributes_module
|
|
98
|
+
|
|
99
|
+
super
|
|
100
|
+
end
|
|
101
|
+
|
|
86
102
|
# Allow nested attributes to be set for the given associations. Options:
|
|
87
103
|
# :destroy :: Allow destruction of nested records.
|
|
88
104
|
# :fields :: If provided, should be an Array or proc. If it is an array,
|
|
@@ -97,6 +113,10 @@ module Sequel
|
|
|
97
113
|
# value, the attribute hash is ignored.
|
|
98
114
|
# :remove :: Allow disassociation of nested records (can remove the associated
|
|
99
115
|
# object from the parent object, but not destroy the associated object).
|
|
116
|
+
# :require_modification :: Whether to require modification of nested objects when
|
|
117
|
+
# updating or deleting them (checking that a single row was
|
|
118
|
+
# updated). By default, uses the default require_modification
|
|
119
|
+
# setting for the nested object.
|
|
100
120
|
# :transform :: A proc to transform attribute hashes before they are
|
|
101
121
|
# passed to associated object. Takes two arguments, the parent object and
|
|
102
122
|
# the attribute hash. Uses the return value as the new attribute hash.
|
|
@@ -108,12 +128,12 @@ module Sequel
|
|
|
108
128
|
#
|
|
109
129
|
# If a block is provided, it is used to set the :reject_if option.
|
|
110
130
|
def nested_attributes(*associations, &block)
|
|
111
|
-
include(
|
|
112
|
-
opts = associations.last.is_a?(Hash) ? associations.pop :
|
|
131
|
+
include(@nested_attributes_module ||= Module.new) unless @nested_attributes_module
|
|
132
|
+
opts = associations.last.is_a?(Hash) ? associations.pop : OPTS
|
|
113
133
|
reflections = associations.map{|a| association_reflection(a) || raise(Error, "no association named #{a} for #{self}")}
|
|
114
134
|
reflections.each do |r|
|
|
115
|
-
r[:nested_attributes] = opts
|
|
116
|
-
r[:nested_attributes][:unmatched_pk] ||=
|
|
135
|
+
r[:nested_attributes] = opts.dup
|
|
136
|
+
r[:nested_attributes][:unmatched_pk] ||= :raise
|
|
117
137
|
r[:nested_attributes][:reject_if] ||= block
|
|
118
138
|
def_nested_attribute_method(r)
|
|
119
139
|
end
|
|
@@ -124,7 +144,7 @@ module Sequel
|
|
|
124
144
|
# Add a nested attribute setter method to a module included in the
|
|
125
145
|
# class.
|
|
126
146
|
def def_nested_attribute_method(reflection)
|
|
127
|
-
nested_attributes_module.class_eval do
|
|
147
|
+
@nested_attributes_module.class_eval do
|
|
128
148
|
define_method("#{reflection[:name]}_attributes=") do |v|
|
|
129
149
|
set_nested_attributes(reflection[:name], v)
|
|
130
150
|
end
|
|
@@ -139,7 +159,7 @@ module Sequel
|
|
|
139
159
|
def set_nested_attributes(assoc, obj, opts=OPTS)
|
|
140
160
|
raise(Error, "no association named #{assoc} for #{model.inspect}") unless ref = model.association_reflection(assoc)
|
|
141
161
|
raise(Error, "nested attributes are not enabled for association #{assoc} for #{model.inspect}") unless meta = ref[:nested_attributes]
|
|
142
|
-
meta =
|
|
162
|
+
meta = meta.merge(opts)
|
|
143
163
|
meta[:reflection] = ref
|
|
144
164
|
if ref.returns_array?
|
|
145
165
|
nested_attributes_list_setter(meta, obj)
|
|
@@ -170,8 +190,9 @@ module Sequel
|
|
|
170
190
|
nested_attributes_set_attributes(meta, obj, attributes)
|
|
171
191
|
delay_validate_associated_object(reflection, obj)
|
|
172
192
|
if reflection.returns_array?
|
|
173
|
-
|
|
174
|
-
|
|
193
|
+
public_send(reflection[:name]) << obj
|
|
194
|
+
obj.skip_validation_on_next_save!
|
|
195
|
+
after_save_hook{public_send(reflection[:add_method], obj)}
|
|
175
196
|
else
|
|
176
197
|
associations[reflection[:name]] = obj
|
|
177
198
|
|
|
@@ -183,9 +204,12 @@ module Sequel
|
|
|
183
204
|
# Don't need to validate the object twice if :validate association option is not false
|
|
184
205
|
# and don't want to validate it at all if it is false.
|
|
185
206
|
if reflection[:type] == :many_to_one
|
|
186
|
-
before_save_hook{
|
|
207
|
+
before_save_hook{public_send(reflection[:setter_method], obj.save(:validate=>false))}
|
|
187
208
|
else
|
|
188
|
-
after_save_hook
|
|
209
|
+
after_save_hook do
|
|
210
|
+
obj.skip_validation_on_next_save!
|
|
211
|
+
public_send(reflection[:setter_method], obj)
|
|
212
|
+
end
|
|
189
213
|
end
|
|
190
214
|
end
|
|
191
215
|
add_reciprocal_object(reflection, obj)
|
|
@@ -197,7 +221,7 @@ module Sequel
|
|
|
197
221
|
# If there is a limit on the nested attributes for this association,
|
|
198
222
|
# make sure the length of the attributes_list is not greater than the limit.
|
|
199
223
|
def nested_attributes_list_setter(meta, attributes_list)
|
|
200
|
-
attributes_list = attributes_list.
|
|
224
|
+
attributes_list = attributes_list.sort.map{|k,v| v} if attributes_list.is_a?(Hash)
|
|
201
225
|
if (limit = meta[:limit]) && attributes_list.length > limit
|
|
202
226
|
raise(Error, "number of nested attributes (#{attributes_list.length}) exceeds the limit (#{limit})")
|
|
203
227
|
end
|
|
@@ -213,9 +237,9 @@ module Sequel
|
|
|
213
237
|
if !opts[:destroy] || reflection.remove_before_destroy?
|
|
214
238
|
before_save_hook do
|
|
215
239
|
if reflection.returns_array?
|
|
216
|
-
|
|
240
|
+
public_send(reflection[:remove_method], obj)
|
|
217
241
|
else
|
|
218
|
-
|
|
242
|
+
public_send(reflection[:setter_method], nil)
|
|
219
243
|
end
|
|
220
244
|
end
|
|
221
245
|
end
|
|
@@ -231,7 +255,7 @@ module Sequel
|
|
|
231
255
|
def nested_attributes_set_attributes(meta, obj, attributes)
|
|
232
256
|
if fields = meta[:fields]
|
|
233
257
|
fields = fields.call(obj) if fields.respond_to?(:call)
|
|
234
|
-
obj.
|
|
258
|
+
obj.set_fields(attributes, fields, :missing=>:skip)
|
|
235
259
|
else
|
|
236
260
|
obj.set(attributes)
|
|
237
261
|
end
|
|
@@ -259,9 +283,12 @@ module Sequel
|
|
|
259
283
|
str_keys = sym_keys.map(&:to_s)
|
|
260
284
|
if (pk = attributes.values_at(*sym_keys)).all? || (pk = attributes.values_at(*str_keys)).all?
|
|
261
285
|
pk = pk.map(&:to_s)
|
|
262
|
-
obj = Array(
|
|
286
|
+
obj = Array(public_send(reflection[:name])).find{|x| Array(x.pk).map(&:to_s) == pk}
|
|
263
287
|
end
|
|
264
288
|
if obj
|
|
289
|
+
unless (require_modification = meta[:require_modification]).nil?
|
|
290
|
+
obj.require_modification = require_modification
|
|
291
|
+
end
|
|
265
292
|
attributes = attributes.dup.delete_if{|k,v| str_keys.include? k.to_s}
|
|
266
293
|
if meta[:destroy] && klass.db.send(:typecast_value_boolean, attributes.delete(:_delete) || attributes.delete('_delete'))
|
|
267
294
|
nested_attributes_remove(meta, obj, :destroy=>true)
|