sequel 5.8.0 → 5.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +409 -1795
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -4
- data/bin/sequel +4 -0
- data/doc/advanced_associations.rdoc +136 -18
- data/doc/association_basics.rdoc +10 -5
- data/doc/cheat_sheet.rdoc +1 -0
- data/doc/code_order.rdoc +12 -2
- data/doc/dataset_filtering.rdoc +17 -2
- data/doc/mass_assignment.rdoc +3 -3
- data/doc/model_dataset_method_design.rdoc +1 -1
- data/doc/model_plugins.rdoc +1 -1
- data/doc/opening_databases.rdoc +30 -8
- data/doc/postgresql.rdoc +107 -2
- 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.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.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.38.0.txt +28 -0
- data/doc/release_notes/5.9.0.txt +99 -0
- data/doc/security.rdoc +10 -0
- data/doc/sharding.rdoc +42 -28
- data/doc/sql.rdoc +12 -0
- data/doc/testing.rdoc +24 -17
- data/doc/transactions.rdoc +78 -0
- data/doc/validations.rdoc +2 -2
- data/lib/sequel/adapters/ado.rb +26 -18
- data/lib/sequel/adapters/ado/access.rb +2 -2
- data/lib/sequel/adapters/ado/mssql.rb +5 -8
- data/lib/sequel/adapters/amalgalite.rb +1 -1
- data/lib/sequel/adapters/jdbc.rb +71 -27
- data/lib/sequel/adapters/jdbc/mysql.rb +6 -6
- data/lib/sequel/adapters/jdbc/oracle.rb +7 -6
- data/lib/sequel/adapters/jdbc/postgresql.rb +17 -28
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +5 -6
- data/lib/sequel/adapters/jdbc/sqlite.rb +33 -2
- data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -3
- data/lib/sequel/adapters/jdbc/transactions.rb +14 -28
- data/lib/sequel/adapters/mysql.rb +14 -15
- data/lib/sequel/adapters/mysql2.rb +5 -3
- data/lib/sequel/adapters/odbc.rb +4 -6
- data/lib/sequel/adapters/oracle.rb +7 -7
- data/lib/sequel/adapters/postgres.rb +52 -16
- data/lib/sequel/adapters/shared/access.rb +16 -12
- data/lib/sequel/adapters/shared/db2.rb +5 -0
- data/lib/sequel/adapters/shared/mssql.rb +41 -18
- data/lib/sequel/adapters/shared/mysql.rb +66 -19
- data/lib/sequel/adapters/shared/oracle.rb +29 -23
- data/lib/sequel/adapters/shared/postgres.rb +341 -95
- data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
- data/lib/sequel/adapters/shared/sqlite.rb +174 -21
- data/lib/sequel/adapters/sqlanywhere.rb +33 -17
- data/lib/sequel/adapters/sqlite.rb +78 -68
- data/lib/sequel/adapters/tinytds.rb +14 -6
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +2 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +5 -1
- data/lib/sequel/connection_pool.rb +2 -6
- data/lib/sequel/connection_pool/sharded_single.rb +7 -4
- data/lib/sequel/connection_pool/sharded_threaded.rb +32 -21
- data/lib/sequel/connection_pool/single.rb +1 -1
- data/lib/sequel/connection_pool/threaded.rb +26 -11
- data/lib/sequel/core.rb +327 -319
- data/lib/sequel/database/connecting.rb +7 -8
- data/lib/sequel/database/logging.rb +7 -1
- data/lib/sequel/database/misc.rb +68 -34
- data/lib/sequel/database/query.rb +6 -4
- data/lib/sequel/database/schema_generator.rb +31 -11
- data/lib/sequel/database/schema_methods.rb +32 -22
- data/lib/sequel/database/transactions.rb +129 -25
- data/lib/sequel/dataset.rb +4 -2
- data/lib/sequel/dataset/actions.rb +34 -23
- data/lib/sequel/dataset/features.rb +34 -0
- data/lib/sequel/dataset/graph.rb +27 -11
- data/lib/sequel/dataset/misc.rb +17 -3
- data/lib/sequel/dataset/placeholder_literalizer.rb +50 -21
- data/lib/sequel/dataset/prepared_statements.rb +96 -26
- data/lib/sequel/dataset/query.rb +43 -8
- data/lib/sequel/dataset/sql.rb +189 -41
- data/lib/sequel/deprecated.rb +3 -1
- data/lib/sequel/exceptions.rb +2 -0
- data/lib/sequel/extensions/_pretty_table.rb +1 -2
- data/lib/sequel/extensions/any_not_empty.rb +45 -0
- data/lib/sequel/extensions/caller_logging.rb +79 -0
- data/lib/sequel/extensions/columns_introspection.rb +1 -2
- data/lib/sequel/extensions/connection_expiration.rb +6 -6
- data/lib/sequel/extensions/connection_validator.rb +7 -6
- data/lib/sequel/extensions/constant_sql_override.rb +65 -0
- data/lib/sequel/extensions/constraint_validations.rb +53 -28
- data/lib/sequel/extensions/core_refinements.rb +2 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +2 -0
- data/lib/sequel/extensions/escaped_like.rb +100 -0
- data/lib/sequel/extensions/eval_inspect.rb +3 -1
- data/lib/sequel/extensions/exclude_or_null.rb +68 -0
- data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
- data/lib/sequel/extensions/index_caching.rb +9 -7
- data/lib/sequel/extensions/integer64.rb +3 -1
- data/lib/sequel/extensions/looser_typecasting.rb +3 -3
- data/lib/sequel/extensions/migration.rb +13 -6
- data/lib/sequel/extensions/named_timezones.rb +84 -23
- data/lib/sequel/extensions/pg_array.rb +87 -79
- data/lib/sequel/extensions/pg_array_ops.rb +14 -6
- data/lib/sequel/extensions/pg_enum.rb +34 -18
- data/lib/sequel/extensions/pg_extended_date_support.rb +34 -14
- data/lib/sequel/extensions/pg_hstore.rb +6 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +2 -0
- data/lib/sequel/extensions/pg_inet.rb +15 -5
- data/lib/sequel/extensions/pg_interval.rb +2 -0
- data/lib/sequel/extensions/pg_json.rb +387 -123
- data/lib/sequel/extensions/pg_json_ops.rb +168 -0
- data/lib/sequel/extensions/pg_range.rb +20 -10
- data/lib/sequel/extensions/pg_range_ops.rb +2 -0
- data/lib/sequel/extensions/pg_row.rb +3 -2
- data/lib/sequel/extensions/pg_row_ops.rb +24 -0
- data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
- data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
- data/lib/sequel/extensions/query.rb +1 -0
- data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
- data/lib/sequel/extensions/s.rb +2 -0
- data/lib/sequel/extensions/schema_dumper.rb +13 -7
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +4 -2
- data/lib/sequel/extensions/server_block.rb +18 -7
- data/lib/sequel/extensions/sql_comments.rb +2 -2
- data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
- data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
- data/lib/sequel/extensions/to_dot.rb +9 -3
- data/lib/sequel/model.rb +3 -1
- data/lib/sequel/model/associations.rb +403 -69
- data/lib/sequel/model/base.rb +170 -90
- data/lib/sequel/model/plugins.rb +105 -0
- data/lib/sequel/plugins/after_initialize.rb +1 -1
- data/lib/sequel/plugins/association_dependencies.rb +3 -3
- 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 +74 -22
- data/lib/sequel/plugins/association_proxies.rb +6 -2
- data/lib/sequel/plugins/auto_validations.rb +36 -17
- data/lib/sequel/plugins/blacklist_security.rb +1 -2
- data/lib/sequel/plugins/boolean_subsets.rb +4 -1
- data/lib/sequel/plugins/caching.rb +3 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +62 -34
- data/lib/sequel/plugins/composition.rb +13 -9
- data/lib/sequel/plugins/csv_serializer.rb +28 -9
- data/lib/sequel/plugins/defaults_setter.rb +2 -2
- data/lib/sequel/plugins/dirty.rb +60 -22
- data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
- data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
- data/lib/sequel/plugins/finder.rb +2 -2
- data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
- data/lib/sequel/plugins/hook_class_methods.rb +17 -5
- data/lib/sequel/plugins/insert_conflict.rb +72 -0
- data/lib/sequel/plugins/instance_specific_default.rb +113 -0
- data/lib/sequel/plugins/inverted_subsets.rb +2 -2
- data/lib/sequel/plugins/json_serializer.rb +21 -14
- data/lib/sequel/plugins/lazy_attributes.rb +1 -1
- data/lib/sequel/plugins/list.rb +22 -10
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +27 -5
- data/lib/sequel/plugins/pg_array_associations.rb +12 -9
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +149 -61
- data/lib/sequel/plugins/prepared_statements.rb +6 -12
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
- data/lib/sequel/plugins/rcte_tree.rb +20 -22
- data/lib/sequel/plugins/sharding.rb +13 -7
- data/lib/sequel/plugins/single_table_inheritance.rb +20 -15
- data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
- data/lib/sequel/plugins/static_cache.rb +36 -17
- data/lib/sequel/plugins/static_cache_cache.rb +53 -0
- data/lib/sequel/plugins/string_stripper.rb +1 -1
- data/lib/sequel/plugins/subclasses.rb +2 -0
- data/lib/sequel/plugins/subset_conditions.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +73 -2
- data/lib/sequel/plugins/throw_failures.rb +110 -0
- data/lib/sequel/plugins/tree.rb +49 -31
- data/lib/sequel/plugins/typecast_on_load.rb +3 -2
- data/lib/sequel/plugins/validation_class_methods.rb +11 -5
- data/lib/sequel/plugins/validation_helpers.rb +2 -2
- data/lib/sequel/sql.rb +120 -30
- data/lib/sequel/timezones.rb +55 -14
- data/lib/sequel/version.rb +6 -1
- metadata +101 -361
- data/Rakefile +0 -151
- 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.27.0.txt +0 -78
- data/doc/release_notes/4.28.0.txt +0 -57
- data/doc/release_notes/4.29.0.txt +0 -41
- data/doc/release_notes/4.3.0.txt +0 -40
- data/doc/release_notes/4.30.0.txt +0 -37
- data/doc/release_notes/4.31.0.txt +0 -57
- data/doc/release_notes/4.32.0.txt +0 -132
- data/doc/release_notes/4.33.0.txt +0 -88
- data/doc/release_notes/4.34.0.txt +0 -86
- data/doc/release_notes/4.35.0.txt +0 -130
- data/doc/release_notes/4.36.0.txt +0 -116
- data/doc/release_notes/4.37.0.txt +0 -50
- data/doc/release_notes/4.38.0.txt +0 -67
- data/doc/release_notes/4.39.0.txt +0 -127
- data/doc/release_notes/4.4.0.txt +0 -92
- data/doc/release_notes/4.40.0.txt +0 -179
- data/doc/release_notes/4.41.0.txt +0 -77
- data/doc/release_notes/4.42.0.txt +0 -221
- data/doc/release_notes/4.43.0.txt +0 -87
- data/doc/release_notes/4.44.0.txt +0 -125
- data/doc/release_notes/4.45.0.txt +0 -370
- data/doc/release_notes/4.46.0.txt +0 -404
- data/doc/release_notes/4.47.0.txt +0 -56
- data/doc/release_notes/4.48.0.txt +0 -293
- data/doc/release_notes/4.49.0.txt +0 -222
- 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/spec/adapter_spec.rb +0 -4
- data/spec/adapters/db2_spec.rb +0 -170
- data/spec/adapters/mssql_spec.rb +0 -804
- data/spec/adapters/mysql_spec.rb +0 -1041
- data/spec/adapters/oracle_spec.rb +0 -327
- data/spec/adapters/postgres_spec.rb +0 -4000
- data/spec/adapters/spec_helper.rb +0 -43
- data/spec/adapters/sqlanywhere_spec.rb +0 -97
- data/spec/adapters/sqlite_spec.rb +0 -600
- data/spec/bin_spec.rb +0 -269
- data/spec/core/connection_pool_spec.rb +0 -1228
- data/spec/core/database_spec.rb +0 -2673
- data/spec/core/dataset_spec.rb +0 -5419
- data/spec/core/deprecated_spec.rb +0 -70
- data/spec/core/expression_filters_spec.rb +0 -1344
- data/spec/core/mock_adapter_spec.rb +0 -722
- data/spec/core/object_graph_spec.rb +0 -306
- data/spec/core/placeholder_literalizer_spec.rb +0 -166
- data/spec/core/schema_generator_spec.rb +0 -214
- data/spec/core/schema_spec.rb +0 -1820
- data/spec/core/spec_helper.rb +0 -23
- data/spec/core/version_spec.rb +0 -7
- data/spec/core_extensions_spec.rb +0 -762
- data/spec/core_model_spec.rb +0 -2
- data/spec/core_spec.rb +0 -1
- data/spec/deprecation_helper.rb +0 -30
- data/spec/extensions/accessed_columns_spec.rb +0 -51
- data/spec/extensions/active_model_spec.rb +0 -99
- 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 -125
- data/spec/extensions/association_pks_spec.rb +0 -423
- data/spec/extensions/association_proxies_spec.rb +0 -100
- data/spec/extensions/auto_literal_strings_spec.rb +0 -205
- data/spec/extensions/auto_validations_spec.rb +0 -202
- data/spec/extensions/blacklist_security_spec.rb +0 -95
- data/spec/extensions/blank_spec.rb +0 -69
- data/spec/extensions/boolean_readers_spec.rb +0 -93
- data/spec/extensions/boolean_subsets_spec.rb +0 -47
- data/spec/extensions/caching_spec.rb +0 -273
- data/spec/extensions/class_table_inheritance_spec.rb +0 -568
- data/spec/extensions/column_conflicts_spec.rb +0 -75
- data/spec/extensions/column_select_spec.rb +0 -129
- data/spec/extensions/columns_introspection_spec.rb +0 -90
- data/spec/extensions/columns_updated_spec.rb +0 -35
- data/spec/extensions/composition_spec.rb +0 -248
- data/spec/extensions/connection_expiration_spec.rb +0 -133
- data/spec/extensions/connection_validator_spec.rb +0 -127
- data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
- data/spec/extensions/constraint_validations_spec.rb +0 -395
- data/spec/extensions/core_refinements_spec.rb +0 -528
- data/spec/extensions/csv_serializer_spec.rb +0 -183
- data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
- data/spec/extensions/dataset_associations_spec.rb +0 -365
- data/spec/extensions/dataset_source_alias_spec.rb +0 -51
- data/spec/extensions/date_arithmetic_spec.rb +0 -181
- data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
- data/spec/extensions/def_dataset_method_spec.rb +0 -100
- data/spec/extensions/defaults_setter_spec.rb +0 -141
- data/spec/extensions/delay_add_association_spec.rb +0 -73
- data/spec/extensions/dirty_spec.rb +0 -189
- data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
- data/spec/extensions/eager_each_spec.rb +0 -62
- 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 -74
- data/spec/extensions/finder_spec.rb +0 -260
- data/spec/extensions/force_encoding_spec.rb +0 -126
- data/spec/extensions/freeze_datasets_spec.rb +0 -31
- data/spec/extensions/graph_each_spec.rb +0 -113
- data/spec/extensions/hook_class_methods_spec.rb +0 -380
- data/spec/extensions/identifier_mangling_spec.rb +0 -201
- data/spec/extensions/implicit_subquery_spec.rb +0 -58
- data/spec/extensions/index_caching_spec.rb +0 -66
- data/spec/extensions/inflector_spec.rb +0 -183
- data/spec/extensions/input_transformer_spec.rb +0 -69
- data/spec/extensions/insert_returning_select_spec.rb +0 -72
- data/spec/extensions/instance_filters_spec.rb +0 -79
- data/spec/extensions/instance_hooks_spec.rb +0 -246
- data/spec/extensions/integer64_spec.rb +0 -22
- data/spec/extensions/inverted_subsets_spec.rb +0 -33
- data/spec/extensions/json_serializer_spec.rb +0 -336
- data/spec/extensions/lazy_attributes_spec.rb +0 -183
- data/spec/extensions/list_spec.rb +0 -275
- data/spec/extensions/looser_typecasting_spec.rb +0 -43
- data/spec/extensions/many_through_many_spec.rb +0 -2177
- data/spec/extensions/migration_spec.rb +0 -840
- data/spec/extensions/modification_detection_spec.rb +0 -93
- data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
- data/spec/extensions/named_timezones_spec.rb +0 -109
- data/spec/extensions/nested_attributes_spec.rb +0 -703
- data/spec/extensions/null_dataset_spec.rb +0 -85
- data/spec/extensions/optimistic_locking_spec.rb +0 -127
- data/spec/extensions/pagination_spec.rb +0 -116
- data/spec/extensions/pg_array_associations_spec.rb +0 -802
- data/spec/extensions/pg_array_ops_spec.rb +0 -144
- data/spec/extensions/pg_array_spec.rb +0 -398
- data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -165
- data/spec/extensions/pg_enum_spec.rb +0 -113
- data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
- data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
- data/spec/extensions/pg_hstore_spec.rb +0 -219
- data/spec/extensions/pg_inet_ops_spec.rb +0 -102
- data/spec/extensions/pg_inet_spec.rb +0 -72
- data/spec/extensions/pg_interval_spec.rb +0 -103
- data/spec/extensions/pg_json_ops_spec.rb +0 -289
- data/spec/extensions/pg_json_spec.rb +0 -262
- data/spec/extensions/pg_loose_count_spec.rb +0 -23
- data/spec/extensions/pg_range_ops_spec.rb +0 -60
- data/spec/extensions/pg_range_spec.rb +0 -487
- data/spec/extensions/pg_row_ops_spec.rb +0 -61
- data/spec/extensions/pg_row_plugin_spec.rb +0 -60
- data/spec/extensions/pg_row_spec.rb +0 -363
- data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
- data/spec/extensions/pg_timestamptz_spec.rb +0 -17
- data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
- data/spec/extensions/prepared_statements_spec.rb +0 -182
- data/spec/extensions/pretty_table_spec.rb +0 -123
- data/spec/extensions/query_spec.rb +0 -94
- data/spec/extensions/rcte_tree_spec.rb +0 -381
- data/spec/extensions/round_timestamps_spec.rb +0 -39
- data/spec/extensions/s_spec.rb +0 -60
- data/spec/extensions/schema_caching_spec.rb +0 -64
- data/spec/extensions/schema_dumper_spec.rb +0 -868
- data/spec/extensions/select_remove_spec.rb +0 -38
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
- data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
- data/spec/extensions/serialization_spec.rb +0 -365
- data/spec/extensions/server_block_spec.rb +0 -97
- data/spec/extensions/server_logging_spec.rb +0 -45
- data/spec/extensions/sharding_spec.rb +0 -189
- data/spec/extensions/shared_caching_spec.rb +0 -151
- data/spec/extensions/single_table_inheritance_spec.rb +0 -347
- data/spec/extensions/singular_table_names_spec.rb +0 -22
- data/spec/extensions/skip_create_refresh_spec.rb +0 -18
- data/spec/extensions/spec_helper.rb +0 -61
- data/spec/extensions/split_array_nil_spec.rb +0 -24
- data/spec/extensions/split_values_spec.rb +0 -57
- data/spec/extensions/sql_comments_spec.rb +0 -33
- data/spec/extensions/sql_expr_spec.rb +0 -59
- data/spec/extensions/static_cache_spec.rb +0 -410
- data/spec/extensions/string_agg_spec.rb +0 -90
- 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 -79
- data/spec/extensions/subset_conditions_spec.rb +0 -38
- data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
- data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
- data/spec/extensions/synchronize_sql_spec.rb +0 -124
- data/spec/extensions/table_select_spec.rb +0 -83
- data/spec/extensions/tactical_eager_loading_spec.rb +0 -141
- data/spec/extensions/thread_local_timezones_spec.rb +0 -67
- data/spec/extensions/timestamps_spec.rb +0 -209
- data/spec/extensions/to_dot_spec.rb +0 -153
- data/spec/extensions/touch_spec.rb +0 -226
- data/spec/extensions/tree_spec.rb +0 -284
- data/spec/extensions/typecast_on_load_spec.rb +0 -86
- data/spec/extensions/unlimited_update_spec.rb +0 -21
- data/spec/extensions/update_or_create_spec.rb +0 -83
- data/spec/extensions/update_primary_key_spec.rb +0 -105
- data/spec/extensions/update_refresh_spec.rb +0 -59
- data/spec/extensions/uuid_spec.rb +0 -101
- data/spec/extensions/validate_associated_spec.rb +0 -52
- data/spec/extensions/validation_class_methods_spec.rb +0 -1040
- data/spec/extensions/validation_contexts_spec.rb +0 -31
- data/spec/extensions/validation_helpers_spec.rb +0 -525
- data/spec/extensions/whitelist_security_spec.rb +0 -157
- data/spec/extensions/xml_serializer_spec.rb +0 -213
- 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/double_migration/001_create_sessions.rb +0 -9
- data/spec/files/double_migration/002_create_nodes.rb +0 -19
- data/spec/files/double_migration/003_3_create_users.rb +0 -4
- 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/empty_migration/001_create_sessions.rb +0 -9
- data/spec/files/empty_migration/002_create_nodes.rb +0 -0
- data/spec/files/empty_migration/003_3_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/reversible_migrations/006_reversible.rb +0 -10
- data/spec/files/reversible_migrations/007_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 -58
- data/spec/integration/associations_test.rb +0 -2513
- data/spec/integration/database_test.rb +0 -113
- data/spec/integration/dataset_test.rb +0 -1880
- data/spec/integration/eager_loader_test.rb +0 -687
- data/spec/integration/migrator_test.rb +0 -262
- data/spec/integration/model_test.rb +0 -203
- data/spec/integration/plugin_test.rb +0 -2302
- data/spec/integration/prepared_statement_test.rb +0 -398
- data/spec/integration/schema_test.rb +0 -869
- data/spec/integration/spec_helper.rb +0 -64
- data/spec/integration/timezone_test.rb +0 -86
- data/spec/integration/transaction_test.rb +0 -354
- data/spec/integration/type_test.rb +0 -127
- data/spec/model/association_reflection_spec.rb +0 -803
- data/spec/model/associations_spec.rb +0 -4538
- data/spec/model/base_spec.rb +0 -817
- data/spec/model/class_dataset_methods_spec.rb +0 -146
- data/spec/model/dataset_methods_spec.rb +0 -198
- data/spec/model/eager_loading_spec.rb +0 -2262
- data/spec/model/hooks_spec.rb +0 -370
- data/spec/model/inflector_spec.rb +0 -26
- data/spec/model/model_spec.rb +0 -953
- data/spec/model/plugins_spec.rb +0 -318
- data/spec/model/record_spec.rb +0 -2107
- data/spec/model/spec_helper.rb +0 -45
- data/spec/model/validations_spec.rb +0 -193
- data/spec/model_no_assoc_spec.rb +0 -1
- data/spec/model_spec.rb +0 -1
- data/spec/plugin_spec.rb +0 -1
- data/spec/sequel_coverage.rb +0 -15
- data/spec/sequel_warning.rb +0 -4
- data/spec/spec_config.rb +0 -12
|
@@ -95,7 +95,7 @@ module Sequel
|
|
|
95
95
|
end
|
|
96
96
|
end
|
|
97
97
|
end
|
|
98
|
-
@default_values = h.merge!(@default_values ||
|
|
98
|
+
@default_values = h.merge!(@default_values || OPTS)
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
# Handle the CURRENT_DATE and CURRENT_TIMESTAMP values specially by returning an appropriate Date or
|
|
@@ -116,7 +116,7 @@ module Sequel
|
|
|
116
116
|
# Use default value for a new record if values doesn't already contain an entry for it.
|
|
117
117
|
def [](k)
|
|
118
118
|
if new? && !values.has_key?(k)
|
|
119
|
-
v = model.default_values
|
|
119
|
+
v = model.default_values.fetch(k){return}
|
|
120
120
|
v = v.call if v.respond_to?(:call)
|
|
121
121
|
values[k] = v if model.cache_default_values?
|
|
122
122
|
v
|
data/lib/sequel/plugins/dirty.rb
CHANGED
|
@@ -41,6 +41,15 @@ module Sequel
|
|
|
41
41
|
# artist.column_changes # => {}
|
|
42
42
|
# artist.previous_changes # => {:name=>['Foo', 'Bar']}
|
|
43
43
|
#
|
|
44
|
+
# artist.column_previously_was(:name)
|
|
45
|
+
# # => 'Foo'
|
|
46
|
+
# artist.column_previously_changed?(:name)
|
|
47
|
+
# # => true
|
|
48
|
+
# artist.column_previously_changed?(:name, from: 'Foo', to: 'Bar')
|
|
49
|
+
# # => true
|
|
50
|
+
# artist.column_previously_changed?(:name, from: 'Foo', to: 'Baz')
|
|
51
|
+
# # => false
|
|
52
|
+
#
|
|
44
53
|
# There is one caveat; when used with a column that also uses the
|
|
45
54
|
# serialization plugin, setting the column back to its original value
|
|
46
55
|
# after changing it is not correctly detected and will leave an entry
|
|
@@ -61,6 +70,19 @@ module Sequel
|
|
|
61
70
|
# that were used in the update statement.
|
|
62
71
|
attr_reader :previous_changes
|
|
63
72
|
|
|
73
|
+
# Reset the initial values after saving.
|
|
74
|
+
def after_save
|
|
75
|
+
super
|
|
76
|
+
reset_initial_values
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Save the current changes so they are available after updating. This happens
|
|
80
|
+
# before after_save resets them.
|
|
81
|
+
def after_update
|
|
82
|
+
super
|
|
83
|
+
@previous_changes = column_changes
|
|
84
|
+
end
|
|
85
|
+
|
|
64
86
|
# An array with the initial value and the current value
|
|
65
87
|
# of the column, if the column has been changed. If the
|
|
66
88
|
# column has not been changed, returns nil.
|
|
@@ -92,6 +114,41 @@ module Sequel
|
|
|
92
114
|
initial_values.has_key?(column)
|
|
93
115
|
end
|
|
94
116
|
|
|
117
|
+
# Whether the column was previously changed.
|
|
118
|
+
# Options:
|
|
119
|
+
# :from :: If given, the previous initial value of the column must match this
|
|
120
|
+
# :to :: If given, the previous changed value of the column must match this
|
|
121
|
+
#
|
|
122
|
+
# update(name: 'Current')
|
|
123
|
+
# previous_changes # => {:name=>['Initial', 'Current']}
|
|
124
|
+
# column_previously_changed?(:name) # => true
|
|
125
|
+
# column_previously_changed?(:id) # => false
|
|
126
|
+
# column_previously_changed?(:name, from: 'Initial', to: 'Current') # => true
|
|
127
|
+
# column_previously_changed?(:name, from: 'Foo', to: 'Current') # => false
|
|
128
|
+
def column_previously_changed?(column, opts=OPTS)
|
|
129
|
+
return false unless (pc = @previous_changes) && (val = pc[column])
|
|
130
|
+
|
|
131
|
+
if opts.has_key?(:from)
|
|
132
|
+
return false unless val[0] == opts[:from]
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
if opts.has_key?(:to)
|
|
136
|
+
return false unless val[1] == opts[:to]
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
true
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# The previous value of the column, which is the initial value of
|
|
143
|
+
# the column before the object was previously saved.
|
|
144
|
+
#
|
|
145
|
+
# initial_value(:name) # => 'Initial'
|
|
146
|
+
# update(name: 'Current')
|
|
147
|
+
# column_previously_was(:name) # => 'Initial'
|
|
148
|
+
def column_previously_was(column)
|
|
149
|
+
(pc = @previous_changes) && (val = pc[column]) && val[0]
|
|
150
|
+
end
|
|
151
|
+
|
|
95
152
|
# Freeze internal data structures
|
|
96
153
|
def freeze
|
|
97
154
|
initial_values.freeze
|
|
@@ -159,23 +216,10 @@ module Sequel
|
|
|
159
216
|
|
|
160
217
|
private
|
|
161
218
|
|
|
162
|
-
# Reset
|
|
163
|
-
def
|
|
164
|
-
reset_initial_values
|
|
165
|
-
super
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
# Reset the initial values after saving.
|
|
169
|
-
def after_save
|
|
170
|
-
super
|
|
171
|
-
reset_initial_values
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
# Save the current changes so they are available after updating. This happens
|
|
175
|
-
# before after_save resets them.
|
|
176
|
-
def after_update
|
|
219
|
+
# Reset initial values when clearing changed columns
|
|
220
|
+
def _clear_changed_columns(reason)
|
|
221
|
+
reset_initial_values if reason == :initialize || reason == :refresh
|
|
177
222
|
super
|
|
178
|
-
@previous_changes = column_changes
|
|
179
223
|
end
|
|
180
224
|
|
|
181
225
|
# When changing the column value, save the initial column value. If the column
|
|
@@ -214,12 +258,6 @@ module Sequel
|
|
|
214
258
|
self
|
|
215
259
|
end
|
|
216
260
|
|
|
217
|
-
# Reset the initial values when initializing.
|
|
218
|
-
def initialize_set(h)
|
|
219
|
-
super
|
|
220
|
-
reset_initial_values
|
|
221
|
-
end
|
|
222
|
-
|
|
223
261
|
# Array holding column symbols that were not present initially. This is necessary
|
|
224
262
|
# to differentiate between values that were not present and values that were
|
|
225
263
|
# present but equal to nil.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
module Plugins
|
|
5
|
+
# The eager_graph_eager plugin allows for chaining eager loads after eager_graph
|
|
6
|
+
# loads. Given the following model associations:
|
|
7
|
+
#
|
|
8
|
+
# Band.one_to_many :albums
|
|
9
|
+
# Album.one_to_many :tracks
|
|
10
|
+
#
|
|
11
|
+
# Let's say you wanted to return bands ordered by album name, and eagerly load
|
|
12
|
+
# those albums, you can do that using:
|
|
13
|
+
#
|
|
14
|
+
# Band.eager_graph(:albums).order{albums[:name]}
|
|
15
|
+
#
|
|
16
|
+
# Let's say you also wanted to eagerly load the tracks for each album. You could
|
|
17
|
+
# just add them to the eager_graph call:
|
|
18
|
+
#
|
|
19
|
+
# Band.eager_graph(albums: :tracks).order{albums[:name]}
|
|
20
|
+
#
|
|
21
|
+
# However, the bloats the result set, and you aren't ordering by the track
|
|
22
|
+
# information, so a join is not required. The eager_graph_eager plugin allows
|
|
23
|
+
# you to specify that the tracks be eagerly loaded in a separate query after
|
|
24
|
+
# the eager_graph load of albums:
|
|
25
|
+
#
|
|
26
|
+
# Band.eager_graph(:albums).eager_graph_eager([:albums], :tracks).order{albums[:name]}
|
|
27
|
+
#
|
|
28
|
+
# <tt>Dataset#eager_graph_eager</tt>'s first argument is a dependency chain, specified
|
|
29
|
+
# as an array of symbols. This specifies the point at which to perform the eager load.
|
|
30
|
+
# The remaining arguments are arguments that could be passed to Dataset#eager to specify
|
|
31
|
+
# what dependent associations should be loaded at that point.
|
|
32
|
+
#
|
|
33
|
+
# If you also have the following model association:
|
|
34
|
+
#
|
|
35
|
+
# Track.one_to_many :lyrics
|
|
36
|
+
#
|
|
37
|
+
# Here's some different ways of performing eager loading:
|
|
38
|
+
#
|
|
39
|
+
# # 4 Queries: bands, albums, tracks, lyrics
|
|
40
|
+
# Band.eager(albums: {tracks: :lyrics})
|
|
41
|
+
#
|
|
42
|
+
# # 1 Query: bands+albums+tracks+lyrics
|
|
43
|
+
# Band.eager_graph(albums: {tracks: :lyrics})
|
|
44
|
+
#
|
|
45
|
+
# # 3 Queries: bands+albums, tracks, lyrics
|
|
46
|
+
# Band.eager_graph(:albums).eager_graph_eager([:albums], tracks: :lyrics)
|
|
47
|
+
#
|
|
48
|
+
# # 2 Queries: bands+albums+tracks, lyrics
|
|
49
|
+
# Band.eager_graph(albums: :tracks).eager_graph_eager([:albums, :tracks], :lyrics)
|
|
50
|
+
#
|
|
51
|
+
# # 2 Queries: bands+albums, tracks+lyrics
|
|
52
|
+
# Band.eager_graph(:albums).eager_graph_eager([:albums], tracks: proc{|ds| ds.eager_graph(:lyrics)})
|
|
53
|
+
#
|
|
54
|
+
# Usage:
|
|
55
|
+
#
|
|
56
|
+
# # Support eager_graph_eager in all subclass datasets (called before loading subclasses)
|
|
57
|
+
# Sequel::Model.plugin :eager_graph_eager
|
|
58
|
+
#
|
|
59
|
+
# # Support eager_graph_eager in Album class datasets
|
|
60
|
+
# Album.plugin :eager_graph_eager
|
|
61
|
+
module EagerGraphEager
|
|
62
|
+
module DatasetMethods
|
|
63
|
+
# Specify for the given dependency chain, after loading objects for the
|
|
64
|
+
# current dataset via eager_graph, eagerly load the given associations at that point in the
|
|
65
|
+
# dependency chain.
|
|
66
|
+
#
|
|
67
|
+
# dependency_chain :: Array of association symbols, with the first association symbol
|
|
68
|
+
# specifying an association in the dataset's model, the next
|
|
69
|
+
# association specifying an association in the previous association's
|
|
70
|
+
# associated model, and so on.
|
|
71
|
+
# assocs :: Symbols or hashes specifying associations to eagerly load at the point
|
|
72
|
+
# specified by the dependency chain.
|
|
73
|
+
def eager_graph_eager(dependency_chain, *assocs)
|
|
74
|
+
unless dependency_chain.is_a?(Array) && dependency_chain.all?{|s| s.is_a?(Symbol)} && !dependency_chain.empty?
|
|
75
|
+
raise Error, "eager_graph_eager first argument must be array of symbols"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
current = model
|
|
79
|
+
deps = dependency_chain.map do |dep|
|
|
80
|
+
unless ref = current.association_reflection(dep)
|
|
81
|
+
raise Error, "invalid association #{dep.inspect} for #{current.inspect}"
|
|
82
|
+
end
|
|
83
|
+
current = ref.associated_class
|
|
84
|
+
[dep, ref.returns_array?]
|
|
85
|
+
end
|
|
86
|
+
assocs = current.dataset.send(:eager_options_for_associations, assocs)
|
|
87
|
+
|
|
88
|
+
deps.each(&:freeze)
|
|
89
|
+
deps.unshift(current)
|
|
90
|
+
deps.freeze
|
|
91
|
+
|
|
92
|
+
assocs.freeze
|
|
93
|
+
|
|
94
|
+
if h = @opts[:eager_graph_eager]
|
|
95
|
+
h = Hash[h]
|
|
96
|
+
h[deps] = assocs
|
|
97
|
+
else
|
|
98
|
+
h = {deps => assocs}
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
clone(:eager_graph_eager=>h.freeze)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
protected
|
|
105
|
+
|
|
106
|
+
# After building objects from the rows, if eager_graph_eager has been
|
|
107
|
+
# called on the datasets, for each dependency chain specified, eagerly
|
|
108
|
+
# load the appropriate associations.
|
|
109
|
+
def eager_graph_build_associations(rows)
|
|
110
|
+
objects = super
|
|
111
|
+
|
|
112
|
+
if eager_data = @opts[:eager_graph_eager]
|
|
113
|
+
eager_data.each do |deps, assocs|
|
|
114
|
+
current = objects
|
|
115
|
+
|
|
116
|
+
last_class, *deps = deps
|
|
117
|
+
deps.each do |dep, is_multiple|
|
|
118
|
+
current_assocs = current.map(&:associations)
|
|
119
|
+
|
|
120
|
+
if is_multiple
|
|
121
|
+
current = current_assocs.flat_map{|a| a[dep]}
|
|
122
|
+
else
|
|
123
|
+
current = current_assocs.map{|a| a[dep]}
|
|
124
|
+
current.compact!
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
current.uniq!(&:object_id)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
last_class.dataset.send(:eager_load, current, assocs)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
objects
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
module Plugins
|
|
5
|
+
# The empty_failure_backtraces plugin uses empty backtraces when raising HookFailed and ValidationFailed
|
|
6
|
+
# exceptions. This can be significantly faster, and if you are using these exceptions for
|
|
7
|
+
# flow control, you do not need the backtraces. This plugin is about 10% faster on CRuby
|
|
8
|
+
# and 10-15x faster on JRuby 9.2.7.0+. This does not have an effect on JRuby <9.2.7.0.
|
|
9
|
+
#
|
|
10
|
+
# Usage:
|
|
11
|
+
#
|
|
12
|
+
# # Make all model subclass instances use empty backtraces for HookFailed
|
|
13
|
+
# # and ValidationFailed exceptions (called before loading subclasses)
|
|
14
|
+
# Sequel::Model.plugin :empty_failure_backtraces
|
|
15
|
+
#
|
|
16
|
+
# # Make the Album class use empty backtraces for HookFailed and ValidationFailed exceptions
|
|
17
|
+
# Album.plugin :empty_failure_backtraces
|
|
18
|
+
module EmptyFailureBacktraces
|
|
19
|
+
module InstanceMethods
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
# Use empty backtrace for HookFailed exceptions.
|
|
23
|
+
def hook_failed_error(msg)
|
|
24
|
+
e = super
|
|
25
|
+
e.set_backtrace([])
|
|
26
|
+
e
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Use empty backtrace for ValidationFailed exceptions.
|
|
30
|
+
def validation_failed_error
|
|
31
|
+
e = super
|
|
32
|
+
e.set_backtrace([])
|
|
33
|
+
e
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
module Plugins
|
|
5
|
+
# The forbid_lazy_load plugin forbids lazy loading of associations
|
|
6
|
+
# for objects in cases where the object wasn't loaded with a
|
|
7
|
+
# method that only returns a single object.
|
|
8
|
+
#
|
|
9
|
+
# The main reason for doing this is it makes it easier to detect
|
|
10
|
+
# N+1 query issues. Note that Sequel also offers a
|
|
11
|
+
# tactical_eager_loading plugin which will automatically eagerly
|
|
12
|
+
# load associations for all objects retrived in the same query
|
|
13
|
+
# if any object would attempt to lazily load an association. That
|
|
14
|
+
# approach may be simpler if you are trying to prevent N+1 issues,
|
|
15
|
+
# though it does retain more objects in memory.
|
|
16
|
+
#
|
|
17
|
+
# This plugin offers multiple different ways to forbid lazy
|
|
18
|
+
# loading. You can forbid lazy loading associations for individual
|
|
19
|
+
# model instances:
|
|
20
|
+
#
|
|
21
|
+
# obj = Album[1]
|
|
22
|
+
# obj.forbid_lazy_load
|
|
23
|
+
# obj.artist # raises Sequel::Plugins::ForbidLazyLoad::Error
|
|
24
|
+
#
|
|
25
|
+
# +forbid_lazy_load+ is automatically called on instances if the
|
|
26
|
+
# instances are loaded via a method such as Dataset#all,
|
|
27
|
+
# Dataset#each, and other methods that load multiple instances
|
|
28
|
+
# at once. These are the cases where lazily loading associations
|
|
29
|
+
# for such instances can cause N+1 issues.
|
|
30
|
+
#
|
|
31
|
+
# Album.all.first.artist
|
|
32
|
+
# objs.first.artist # raises Sequel::Plugins::ForbidLazyLoad::Error
|
|
33
|
+
#
|
|
34
|
+
# Album.each do |obj|
|
|
35
|
+
# obj.artist # raises Sequel::Plugins::ForbidLazyLoad::Error
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# Album[1].artist # no error
|
|
39
|
+
#
|
|
40
|
+
# Album.first.artist # no error
|
|
41
|
+
#
|
|
42
|
+
# You can allow lazy loading associations for an instance that it
|
|
43
|
+
# was previously forbidden for:
|
|
44
|
+
#
|
|
45
|
+
# obj = Album.all.first
|
|
46
|
+
# obj.allow_lazy_load
|
|
47
|
+
# obj.artist # no error
|
|
48
|
+
#
|
|
49
|
+
# You can forbid lazy loading associations on a per-call basis,
|
|
50
|
+
# even if lazy loading of associations is allowed for the instance:
|
|
51
|
+
#
|
|
52
|
+
# obj = Album[1]
|
|
53
|
+
# obj.artist(forbid_lazy_load: true)
|
|
54
|
+
# # raises Sequel::Plugins::ForbidLazyLoad::Error
|
|
55
|
+
#
|
|
56
|
+
# This also works for allowing lazy loading associations for a
|
|
57
|
+
# specific association load even if it is forbidden for the instance:
|
|
58
|
+
#
|
|
59
|
+
# obj = Album.all.first
|
|
60
|
+
# obj.artist(forbid_lazy_load: false)
|
|
61
|
+
# # nothing raised
|
|
62
|
+
#
|
|
63
|
+
# You can also forbid lazy loading on a per-association basis using the
|
|
64
|
+
# +:forbid_lazy_load+ association option with a +true+ value:
|
|
65
|
+
#
|
|
66
|
+
# Album.many_to_one :artist, forbid_lazy_load: true
|
|
67
|
+
# Album[1].artist # raises Sequel::Plugins::ForbidLazyLoad::Error
|
|
68
|
+
#
|
|
69
|
+
# However, you probably don't want to do this as it will forbid any
|
|
70
|
+
# lazy loading of the association, even if the loading could not
|
|
71
|
+
# result in an N+1 issue.
|
|
72
|
+
#
|
|
73
|
+
# On the flip side, you can allow lazy loading using the
|
|
74
|
+
# +:forbid_lazy_load+ association option with a +false+ value:
|
|
75
|
+
#
|
|
76
|
+
# Album.many_to_one :artist, forbid_lazy_load: false
|
|
77
|
+
# Album.all.first.artist # no error
|
|
78
|
+
#
|
|
79
|
+
# One reason to do this is when using a plugin like static_cache
|
|
80
|
+
# on the associated model, where a query is not actually issued
|
|
81
|
+
# when doing a lazy association load. To make that particular
|
|
82
|
+
# case easier, this plugin makes Model.finalize_associations
|
|
83
|
+
# automatically set the association option if the associated
|
|
84
|
+
# class uses the static_cache plugin.
|
|
85
|
+
#
|
|
86
|
+
# Note that even with this plugin, there can still be N+1 issues,
|
|
87
|
+
# such as:
|
|
88
|
+
#
|
|
89
|
+
# Album.each do |obj| # 1 query for all albums
|
|
90
|
+
# Artist[obj.artist_id] # 1 query per album for each artist
|
|
91
|
+
# end
|
|
92
|
+
#
|
|
93
|
+
# Usage:
|
|
94
|
+
#
|
|
95
|
+
# # Make all model subclasses support forbidding lazy load
|
|
96
|
+
# # (called before loading subclasses)
|
|
97
|
+
# Sequel::Model.plugin :forbid_lazy_load
|
|
98
|
+
#
|
|
99
|
+
# # Make the Album class support forbidding lazy load
|
|
100
|
+
# Album.plugin :forbid_lazy_load
|
|
101
|
+
module ForbidLazyLoad
|
|
102
|
+
# Error raised when attempting to lazy load an association when
|
|
103
|
+
# lazy loading has been forbidden.
|
|
104
|
+
class Error < StandardError
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
module ClassMethods
|
|
108
|
+
Plugins.def_dataset_methods(self, :forbid_lazy_load)
|
|
109
|
+
|
|
110
|
+
# If the static_cache plugin is used by the associated class for
|
|
111
|
+
# an association, allow lazy loading that association, since the
|
|
112
|
+
# lazy association load will use a hash table lookup and not a query.
|
|
113
|
+
def allow_lazy_load_for_static_cache_associations
|
|
114
|
+
# :nocov:
|
|
115
|
+
if defined?(::Sequel::Plugins::StaticCache::ClassMethods)
|
|
116
|
+
# :nocov:
|
|
117
|
+
@association_reflections.each_value do |ref|
|
|
118
|
+
if ref.associated_class.is_a?(::Sequel::Plugins::StaticCache::ClassMethods)
|
|
119
|
+
ref[:forbid_lazy_load] = false
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Allow lazy loading for static cache associations before finalizing.
|
|
126
|
+
def finalize_associations
|
|
127
|
+
allow_lazy_load_for_static_cache_associations
|
|
128
|
+
super
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
module InstanceMethods
|
|
133
|
+
# Set this model instance to allow lazy loading of associations.
|
|
134
|
+
def allow_lazy_load
|
|
135
|
+
@forbid_lazy_load = false
|
|
136
|
+
self
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Set this model instance to not allow lazy loading of associations.
|
|
140
|
+
def forbid_lazy_load
|
|
141
|
+
@forbid_lazy_load = true
|
|
142
|
+
self
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
private
|
|
146
|
+
|
|
147
|
+
# Allow lazy loading for objects returned by singular associations.
|
|
148
|
+
def _load_associated_object(opts, dynamic_opts)
|
|
149
|
+
# The implementation that loads these associations does
|
|
150
|
+
# .all.first, which would result in the object returned being
|
|
151
|
+
# marked as forbidding lazy load.
|
|
152
|
+
obj = super
|
|
153
|
+
obj.allow_lazy_load if obj.is_a?(InstanceMethods)
|
|
154
|
+
obj
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Raise an Error if lazy loading has been forbidden for
|
|
158
|
+
# the instance, association, or call.
|
|
159
|
+
def _load_associated_objects(opts, dynamic_opts=OPTS)
|
|
160
|
+
case dynamic_opts[:forbid_lazy_load]
|
|
161
|
+
when false
|
|
162
|
+
# nothing
|
|
163
|
+
when nil
|
|
164
|
+
unless dynamic_opts[:reload]
|
|
165
|
+
case opts[:forbid_lazy_load]
|
|
166
|
+
when nil
|
|
167
|
+
raise Error, "lazy loading forbidden for this object (association: #{opts.inspect}, object: #{inspect})" if @forbid_lazy_load
|
|
168
|
+
when false
|
|
169
|
+
# nothing
|
|
170
|
+
else
|
|
171
|
+
raise Error, "lazy loading forbidden for this association (#{opts.inspect})"
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
else
|
|
175
|
+
raise Error, "lazy loading forbidden for this association method call (association: #{opts.inspect})"
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
super
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
module DatasetMethods
|
|
183
|
+
# Mark model instances retrieved in this call as forbidding lazy loading.
|
|
184
|
+
def each
|
|
185
|
+
if row_proc
|
|
186
|
+
super do |obj|
|
|
187
|
+
obj.forbid_lazy_load if obj.is_a?(InstanceMethods)
|
|
188
|
+
yield obj
|
|
189
|
+
end
|
|
190
|
+
else
|
|
191
|
+
super
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Mark model instances retrieved in this call as forbidding lazy loading.
|
|
196
|
+
def with_sql_each(sql)
|
|
197
|
+
if row_proc
|
|
198
|
+
super(sql) do |obj|
|
|
199
|
+
obj.forbid_lazy_load if obj.is_a?(InstanceMethods)
|
|
200
|
+
yield obj
|
|
201
|
+
end
|
|
202
|
+
else
|
|
203
|
+
super
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Mark model instances retrieved in this call as allowing lazy loading.
|
|
208
|
+
def with_sql_first(sql)
|
|
209
|
+
obj = super
|
|
210
|
+
obj.allow_lazy_load if obj.is_a?(InstanceMethods)
|
|
211
|
+
obj
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|