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
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
module Plugins
|
|
5
|
+
# The insert_conflict plugin allows handling conflicts due to unique
|
|
6
|
+
# constraints when saving new model instance, using the INSERT ON CONFLICT
|
|
7
|
+
# support in PostgreSQL 9.5+ and SQLite 3.24.0+. Example:
|
|
8
|
+
#
|
|
9
|
+
# class Album < Sequel::Model
|
|
10
|
+
# plugin :insert_conflict
|
|
11
|
+
# end
|
|
12
|
+
#
|
|
13
|
+
# Album.new(name: 'Foo', copies_sold: 1000).
|
|
14
|
+
# insert_conflict(
|
|
15
|
+
# target: :name,
|
|
16
|
+
# update: {copies_sold: Sequel[:excluded][:b]}
|
|
17
|
+
# ).
|
|
18
|
+
# save
|
|
19
|
+
#
|
|
20
|
+
# This example will try to insert the album, but if there is an existing
|
|
21
|
+
# album with the name 'Foo', this will update the copies_sold attribute
|
|
22
|
+
# for that album. See the PostgreSQL and SQLite adapter documention for
|
|
23
|
+
# the options you can pass to the insert_conflict method.
|
|
24
|
+
#
|
|
25
|
+
# Usage:
|
|
26
|
+
#
|
|
27
|
+
# # Make all model subclasses support insert_conflict
|
|
28
|
+
# Sequel::Model.plugin :insert_conflict
|
|
29
|
+
#
|
|
30
|
+
# # Make the Album class support insert_conflict
|
|
31
|
+
# Album.plugin :insert_conflict
|
|
32
|
+
module InsertConflict
|
|
33
|
+
def self.configure(model)
|
|
34
|
+
model.instance_exec do
|
|
35
|
+
if @dataset && !@dataset.respond_to?(:insert_conflict)
|
|
36
|
+
raise Error, "#{self}'s dataset does not support insert_conflict"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
module InstanceMethods
|
|
42
|
+
# Set the insert_conflict options to pass to the dataset when inserting.
|
|
43
|
+
def insert_conflict(opts=OPTS)
|
|
44
|
+
raise Error, "Model#insert_conflict is only supported on new model instances" unless new?
|
|
45
|
+
@insert_conflict_opts = opts
|
|
46
|
+
self
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
# Set the dataset used for inserting to use INSERT ON CONFLICT
|
|
52
|
+
# Model#insert_conflict has been called on the instance previously.
|
|
53
|
+
def _insert_dataset
|
|
54
|
+
ds = super
|
|
55
|
+
|
|
56
|
+
if @insert_conflict_opts
|
|
57
|
+
ds = ds.insert_conflict(@insert_conflict_opts)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
ds
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Disable the use of prepared insert statements, as they are not compatible
|
|
64
|
+
# with this plugin.
|
|
65
|
+
def use_prepared_statements_for?(type)
|
|
66
|
+
return false if type == :insert || type == :insert_select
|
|
67
|
+
super if defined?(super)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
module Plugins
|
|
3
5
|
# If the model's dataset selects explicit columns and the
|
|
@@ -19,7 +21,7 @@ module Sequel
|
|
|
19
21
|
# Modify the current model's dataset selection, if the model
|
|
20
22
|
# has a dataset.
|
|
21
23
|
def self.configure(model)
|
|
22
|
-
model.
|
|
24
|
+
model.instance_exec do
|
|
23
25
|
self.dataset = dataset if @dataset && @dataset.opts[:select]
|
|
24
26
|
end
|
|
25
27
|
end
|
|
@@ -33,7 +35,7 @@ module Sequel
|
|
|
33
35
|
# When reseting the instance dataset, also reset the instance_insert_dataset.
|
|
34
36
|
def reset_instance_dataset
|
|
35
37
|
ret = super
|
|
36
|
-
ds = @instance_dataset
|
|
38
|
+
return unless ds = @instance_dataset
|
|
37
39
|
|
|
38
40
|
if columns = insert_returning_columns(ds)
|
|
39
41
|
ds = ds.returning(*columns)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
module Plugins
|
|
3
5
|
# This plugin allows you to add filters on a per object basis that
|
|
@@ -5,7 +7,9 @@ module Sequel
|
|
|
5
7
|
# where you would normally have to drop down to the dataset level
|
|
6
8
|
# to get the necessary control, because you only want to delete or
|
|
7
9
|
# update the rows in certain cases based on the current status of
|
|
8
|
-
# the row in the database.
|
|
10
|
+
# the row in the database. The main purpose of this plugin is to
|
|
11
|
+
# avoid race conditions by relying on the atomic properties of database
|
|
12
|
+
# transactions.
|
|
9
13
|
#
|
|
10
14
|
# class Item < Sequel::Model
|
|
11
15
|
# plugin :instance_filters
|
|
@@ -13,12 +17,12 @@ module Sequel
|
|
|
13
17
|
#
|
|
14
18
|
# # These are two separate objects that represent the same
|
|
15
19
|
# # database row.
|
|
16
|
-
# i1 = Item.first(:
|
|
17
|
-
# i2 = Item.first(:
|
|
20
|
+
# i1 = Item.first(id: 1, delete_allowed: false)
|
|
21
|
+
# i2 = Item.first(id: 1, delete_allowed: false)
|
|
18
22
|
#
|
|
19
23
|
# # Add an instance filter to the object. This filter is in effect
|
|
20
24
|
# # until the object is successfully updated or deleted.
|
|
21
|
-
# i1.instance_filter(:
|
|
25
|
+
# i1.instance_filter(delete_allowed: true)
|
|
22
26
|
#
|
|
23
27
|
# # Attempting to delete the object where the filter doesn't
|
|
24
28
|
# # match any rows raises an error.
|
|
@@ -26,7 +30,7 @@ module Sequel
|
|
|
26
30
|
#
|
|
27
31
|
# # The other object that represents the same row has no
|
|
28
32
|
# # instance filters, and can be updated normally.
|
|
29
|
-
# i2.update(:
|
|
33
|
+
# i2.update(delete_allowed: true)
|
|
30
34
|
#
|
|
31
35
|
# # Even though the filter is now still in effect, since the
|
|
32
36
|
# # database row has been updated to allow deleting,
|
|
@@ -98,7 +102,7 @@ module Sequel
|
|
|
98
102
|
|
|
99
103
|
# Apply the instance filters to the given dataset
|
|
100
104
|
def apply_instance_filters(ds)
|
|
101
|
-
instance_filters.inject(ds){|ds1, i| ds1.
|
|
105
|
+
instance_filters.inject(ds){|ds1, i| ds1.where(*i[0], &i[1])}
|
|
102
106
|
end
|
|
103
107
|
|
|
104
108
|
# Clear the instance filters.
|
|
@@ -119,10 +123,10 @@ module Sequel
|
|
|
119
123
|
# Only use prepared statements for update and delete queries
|
|
120
124
|
# if there are no instance filters.
|
|
121
125
|
def use_prepared_statements_for?(type)
|
|
122
|
-
if
|
|
126
|
+
if type == :update && !instance_filters.empty?
|
|
123
127
|
false
|
|
124
128
|
else
|
|
125
|
-
super
|
|
129
|
+
super if defined?(super)
|
|
126
130
|
end
|
|
127
131
|
end
|
|
128
132
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
module Plugins
|
|
3
5
|
# The instance_hooks plugin allows you to add hooks to specific instances,
|
|
@@ -7,8 +9,7 @@ module Sequel
|
|
|
7
9
|
# All of the standard hooks are supported.
|
|
8
10
|
# Instance level before hooks are executed in reverse order of addition before
|
|
9
11
|
# calling super. Instance level after hooks are executed in order of addition
|
|
10
|
-
# after calling super.
|
|
11
|
-
# false, no more instance level before hooks are called and false is returned.
|
|
12
|
+
# after calling super.
|
|
12
13
|
#
|
|
13
14
|
# Instance level hooks for before and after are cleared after all related
|
|
14
15
|
# after level instance hooks have run. This means that if you add a before_create
|
|
@@ -28,10 +29,7 @@ module Sequel
|
|
|
28
29
|
# Album.plugin :instance_hooks
|
|
29
30
|
module InstanceHooks
|
|
30
31
|
module InstanceMethods
|
|
31
|
-
|
|
32
|
-
AFTER_HOOKS = Sequel::Model::AFTER_HOOKS
|
|
33
|
-
HOOKS = BEFORE_HOOKS + AFTER_HOOKS
|
|
34
|
-
HOOKS.each{|h| class_eval(<<-END , __FILE__, __LINE__+1)}
|
|
32
|
+
Sequel::Model::HOOKS.each{|h| class_eval(<<-END , __FILE__, __LINE__+1)}
|
|
35
33
|
def #{h}_hook(&block)
|
|
36
34
|
raise Sequel::Error, "can't add hooks to frozen object" if frozen?
|
|
37
35
|
add_instance_hook(:#{h}, &block)
|
|
@@ -39,31 +37,57 @@ module Sequel
|
|
|
39
37
|
end
|
|
40
38
|
END
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
[:before_create, :before_update, :before_validation].each{|h| class_eval("def #{h}; run_before_instance_hooks(:#{h}) if @instance_hooks; super end", __FILE__, __LINE__)}
|
|
41
|
+
[:after_create, :after_update].each{|h| class_eval(<<-END, __FILE__, __LINE__ + 1)}
|
|
44
42
|
def #{h}
|
|
45
43
|
super
|
|
44
|
+
return unless @instance_hooks
|
|
46
45
|
run_after_instance_hooks(:#{h})
|
|
47
46
|
@instance_hooks.delete(:#{h})
|
|
48
47
|
@instance_hooks.delete(:#{h.to_s.sub('after', 'before')})
|
|
49
48
|
end
|
|
50
49
|
END
|
|
51
50
|
|
|
52
|
-
# Run after
|
|
51
|
+
# Run after destroy instance hooks.
|
|
52
|
+
def after_destroy
|
|
53
|
+
super
|
|
54
|
+
return unless @instance_hooks
|
|
55
|
+
run_after_instance_hooks(:after_destroy)
|
|
56
|
+
@instance_hooks.delete(:after_destroy)
|
|
57
|
+
@instance_hooks.delete(:before_destroy)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Run after validation instance hooks.
|
|
53
61
|
def after_validation
|
|
54
62
|
super
|
|
63
|
+
return unless @instance_hooks
|
|
55
64
|
run_after_instance_hooks(:after_validation)
|
|
56
65
|
end
|
|
57
66
|
|
|
58
|
-
# Run after save
|
|
67
|
+
# Run after save instance hooks.
|
|
59
68
|
def after_save
|
|
60
69
|
super
|
|
70
|
+
return unless @instance_hooks
|
|
61
71
|
run_after_instance_hooks(:after_save)
|
|
62
72
|
@instance_hooks.delete(:after_save)
|
|
63
73
|
@instance_hooks.delete(:before_save)
|
|
64
74
|
@instance_hooks.delete(:after_validation)
|
|
65
75
|
@instance_hooks.delete(:before_validation)
|
|
66
76
|
end
|
|
77
|
+
|
|
78
|
+
# Run before_destroy instance hooks.
|
|
79
|
+
def before_destroy
|
|
80
|
+
return super unless @instance_hooks
|
|
81
|
+
run_before_instance_hooks(:before_destroy)
|
|
82
|
+
super
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Run before_save instance hooks.
|
|
86
|
+
def before_save
|
|
87
|
+
return super unless @instance_hooks
|
|
88
|
+
run_before_instance_hooks(:before_save)
|
|
89
|
+
super
|
|
90
|
+
end
|
|
67
91
|
|
|
68
92
|
private
|
|
69
93
|
|
|
@@ -71,7 +95,7 @@ module Sequel
|
|
|
71
95
|
# the beginning of the instance hook's array. For after hooks, add it
|
|
72
96
|
# to the end.
|
|
73
97
|
def add_instance_hook(hook, &block)
|
|
74
|
-
instance_hooks(hook).
|
|
98
|
+
instance_hooks(hook).public_send(hook.to_s.start_with?('before') ? :unshift : :push, block)
|
|
75
99
|
end
|
|
76
100
|
|
|
77
101
|
# An array of instance level hook blocks for the given hook type.
|
|
@@ -84,12 +108,7 @@ module Sequel
|
|
|
84
108
|
def run_after_instance_hooks(hook)
|
|
85
109
|
instance_hooks(hook).each(&:call)
|
|
86
110
|
end
|
|
87
|
-
|
|
88
|
-
# Run all hook blocks of the given hook type. If a hook block returns false,
|
|
89
|
-
# immediately return false without running the remaining blocks.
|
|
90
|
-
def run_before_instance_hooks(hook)
|
|
91
|
-
instance_hooks(hook).each{|b| return false if b.call == false}
|
|
92
|
-
end
|
|
111
|
+
alias run_before_instance_hooks run_after_instance_hooks
|
|
93
112
|
end
|
|
94
113
|
end
|
|
95
114
|
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
module Plugins
|
|
5
|
+
# The instance_specific_default plugin exists to make it easier to use a
|
|
6
|
+
# global :instance_specific association option, or to warn or raise when Sequel
|
|
7
|
+
# has to guess which value to use :instance_specific option (Sequel defaults to
|
|
8
|
+
# guessing true as that is the conservative setting). It is helpful to
|
|
9
|
+
# use this plugin, particularly with the :warn or :raise settings, to determine
|
|
10
|
+
# which associations should have :instance_specific set. Setting the
|
|
11
|
+
# :instance_specific to false for associations that are not instance specific
|
|
12
|
+
# can improve performance.
|
|
13
|
+
#
|
|
14
|
+
# Associations are instance-specific if their block calls
|
|
15
|
+
# a model instance method, or where the value of the block varies
|
|
16
|
+
# based on runtime state, and the variance is outside of a delayed evaluation.
|
|
17
|
+
# For example, with the following three associations:
|
|
18
|
+
#
|
|
19
|
+
# Album.one_to_one :first_track, class: :Track do |ds|
|
|
20
|
+
# ds.where(number: 1)
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# Album.one_to_one :last_track, class: :Track do |ds|
|
|
24
|
+
# ds.where(number: num_tracks)
|
|
25
|
+
# end
|
|
26
|
+
#
|
|
27
|
+
# Album.one_to_many :recent_tracks, class: :Track do |ds|
|
|
28
|
+
# ds.where{date_updated > Date.today - 10}
|
|
29
|
+
# end
|
|
30
|
+
#
|
|
31
|
+
# +first_track+ is not instance specific, but +last_track+ and +recent_tracks+ are.
|
|
32
|
+
# +last_trac+ is because the +num_tracks+ call in the block is calling
|
|
33
|
+
# <tt>Album#num_tracks</tt>. +recent_tracks+ is because the value will change over
|
|
34
|
+
# time. This plugin allows you to find these cases, and set the :instance_specific
|
|
35
|
+
# option appropriately for them:
|
|
36
|
+
#
|
|
37
|
+
# Album.one_to_one :first_track, class: :Track, instance_specific: false do |ds|
|
|
38
|
+
# ds.where(number: 1)
|
|
39
|
+
# end
|
|
40
|
+
#
|
|
41
|
+
# Album.one_to_one :last_track, class: :Track, instance_specific: true do |ds|
|
|
42
|
+
# ds.where(number: num_tracks)
|
|
43
|
+
# end
|
|
44
|
+
#
|
|
45
|
+
# Album.one_to_many :recent_tracks, class: :Track, instance_specific: true do |ds|
|
|
46
|
+
# ds.where{date_updated > Date.today - 10}
|
|
47
|
+
# end
|
|
48
|
+
#
|
|
49
|
+
# For the +recent_tracks+ association, instead of marking it instance_specific, you
|
|
50
|
+
# could also use a delayed evaluation, since it doesn't actually contain
|
|
51
|
+
# instance-specific code:
|
|
52
|
+
#
|
|
53
|
+
# Album.one_to_many :recent_tracks, class: :Track, instance_specific: false do |ds|
|
|
54
|
+
# ds.where{date_updated > Sequel.delay{Date.today - 10}}
|
|
55
|
+
# end
|
|
56
|
+
#
|
|
57
|
+
# Possible arguments to provide when loading the plugin:
|
|
58
|
+
#
|
|
59
|
+
# true :: Set the :instance_specific option to true
|
|
60
|
+
# false :: Set the :instance_specific option to false
|
|
61
|
+
# :default :: Call super to set the :instance_specific option
|
|
62
|
+
# :warn :: Emit a warning before calling super to set the :instance_specific option
|
|
63
|
+
# :raise :: Raise a Sequel::Error if an :instance_specific option is not provided and
|
|
64
|
+
# an association could be instance-specific.
|
|
65
|
+
#
|
|
66
|
+
# Note that this plugin only affects associations which could be instance
|
|
67
|
+
# specific (those with blocks), where the :instance_specific option was not
|
|
68
|
+
# specified when the association was created.
|
|
69
|
+
#
|
|
70
|
+
# Usage:
|
|
71
|
+
#
|
|
72
|
+
# # Set how to handle associations that could be instance specific
|
|
73
|
+
# # but did not specify an :instance_specific option, for all subclasses
|
|
74
|
+
# # (set before creating subclasses).
|
|
75
|
+
# Sequel::Model.plugin :instance_specific_default, :warn
|
|
76
|
+
#
|
|
77
|
+
# # Set how to handle associations that could be instance specific
|
|
78
|
+
# # but did not specify an :instance_specific option, for the Album class
|
|
79
|
+
# Album.plugin :instance_specific_default, :warn
|
|
80
|
+
module InstanceSpecificDefault
|
|
81
|
+
# Set how to handle associations that could be instance specific but did
|
|
82
|
+
# not specify an :instance_specific value.
|
|
83
|
+
def self.configure(model, default)
|
|
84
|
+
model.instance_variable_set(:@instance_specific_default, default)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
module ClassMethods
|
|
88
|
+
Plugins.inherited_instance_variables(self, :@instance_specific_default=>nil)
|
|
89
|
+
|
|
90
|
+
private
|
|
91
|
+
|
|
92
|
+
# Return the appropriate :instance_specific value, or warn or raise if
|
|
93
|
+
# configured.
|
|
94
|
+
def _association_instance_specific_default(name)
|
|
95
|
+
case @instance_specific_default
|
|
96
|
+
when true, false
|
|
97
|
+
return @instance_specific_default
|
|
98
|
+
when :default
|
|
99
|
+
# nothing
|
|
100
|
+
when :warn
|
|
101
|
+
warn("possibly instance-specific association without :instance_specific option (class: #{self}, association: #{name})", :uplevel => 3)
|
|
102
|
+
when :raise
|
|
103
|
+
raise Sequel::Error, "possibly instance-specific association without :instance_specific option (class: #{self}, association: #{name})"
|
|
104
|
+
else
|
|
105
|
+
raise Sequel::Error, "invalid value passed to instance_specific_default plugin: #{@instance_specific_default.inspect}"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
super
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
module Plugins
|
|
3
5
|
# The inverted_subsets plugin adds another method for each defined
|
|
@@ -16,7 +18,9 @@ module Sequel
|
|
|
16
18
|
# Album.plugin :inverted_subsets
|
|
17
19
|
#
|
|
18
20
|
# # This will now create two methods, published and not_published
|
|
19
|
-
# Album.
|
|
21
|
+
# Album.dataset_module do
|
|
22
|
+
# where :published, published: true
|
|
23
|
+
# end
|
|
20
24
|
#
|
|
21
25
|
# Album.published.sql
|
|
22
26
|
# # SELECT * FROM albums WHERE (published IS TRUE)
|
|
@@ -25,22 +29,29 @@ module Sequel
|
|
|
25
29
|
# # SELECT * FROM albums WHERE (published IS NOT TRUE)
|
|
26
30
|
#
|
|
27
31
|
module InvertedSubsets
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
def self.apply(model, &block)
|
|
33
|
+
model.instance_exec do
|
|
34
|
+
@dataset_module_class = Class.new(@dataset_module_class) do
|
|
35
|
+
include DatasetModuleMethods
|
|
36
|
+
if block
|
|
37
|
+
define_method(:inverted_subset_name, &block)
|
|
38
|
+
private :inverted_subset_name
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
35
42
|
end
|
|
36
43
|
|
|
37
|
-
module
|
|
38
|
-
Plugins.inherited_instance_variables(self, :@inverted_subsets_name_block => nil)
|
|
39
|
-
|
|
44
|
+
module DatasetModuleMethods
|
|
40
45
|
# Define a not_ prefixed subset which inverts the subset condition.
|
|
41
|
-
def
|
|
46
|
+
def where(name, *args, &block)
|
|
42
47
|
super
|
|
43
|
-
|
|
48
|
+
exclude(inverted_subset_name(name), *args, &block)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def inverted_subset_name(name)
|
|
54
|
+
"not_#{name}"
|
|
44
55
|
end
|
|
45
56
|
end
|
|
46
57
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
require 'json'
|
|
2
4
|
|
|
3
5
|
module Sequel
|
|
@@ -11,41 +13,59 @@ module Sequel
|
|
|
11
13
|
#
|
|
12
14
|
# album = Album[1]
|
|
13
15
|
# album.to_json
|
|
14
|
-
# # => '{"
|
|
16
|
+
# # => '{"id"=>1,"name"=>"RF","artist_id"=>2}'
|
|
15
17
|
#
|
|
16
18
|
# In addition, you can provide options to control the JSON output:
|
|
17
19
|
#
|
|
18
|
-
# album.to_json(:
|
|
19
|
-
# album.to_json(:
|
|
20
|
+
# album.to_json(only: :name)
|
|
21
|
+
# album.to_json(except: [:id, :artist_id])
|
|
20
22
|
# # => '{"json_class"="Album","name"=>"RF"}'
|
|
21
23
|
#
|
|
22
|
-
# album.to_json(:
|
|
23
|
-
# # => '{"
|
|
24
|
-
# # "artist":{"
|
|
24
|
+
# album.to_json(include: :artist)
|
|
25
|
+
# # => '{"id":1,"name":"RF","artist_id":2,
|
|
26
|
+
# # "artist":{"id":2,"name":"YJM"}}'
|
|
25
27
|
#
|
|
26
28
|
# You can use a hash value with <tt>:include</tt> to pass options
|
|
27
29
|
# to associations:
|
|
28
30
|
#
|
|
29
|
-
# album.to_json(:
|
|
30
|
-
# # => '{"
|
|
31
|
-
# # "artist":{"
|
|
31
|
+
# album.to_json(include: {artist: {only: :name}})
|
|
32
|
+
# # => '{"id":1,"name":"RF","artist_id":2,
|
|
33
|
+
# # "artist":{"name":"YJM"}}'
|
|
34
|
+
#
|
|
35
|
+
# You can specify a name for a given association by using an aliased
|
|
36
|
+
# expression as the key in the <tt>:include</tt> hash
|
|
32
37
|
#
|
|
38
|
+
# album.to_json(include: {Sequel.as(:artist, :singer)=>{only: :name}})
|
|
39
|
+
# # => '{"id":1,"name":"RF","artist_id":2,
|
|
40
|
+
# # "singer":{"name":"YJM"}}'
|
|
41
|
+
#
|
|
33
42
|
# You can specify the <tt>:root</tt> option to nest the JSON under the
|
|
34
43
|
# name of the model:
|
|
35
44
|
#
|
|
36
|
-
# album.to_json(:
|
|
45
|
+
# album.to_json(root: true)
|
|
37
46
|
# # => '{"album":{"id":1,"name":"RF","artist_id":2}}'
|
|
38
47
|
#
|
|
48
|
+
# You can specify JSON serialization options to use later:
|
|
49
|
+
#
|
|
50
|
+
# album.json_serializer_opts(root: true)
|
|
51
|
+
# [album].to_json
|
|
52
|
+
# # => '[{"album":{"id":1,"name":"RF","artist_id":2}}]'
|
|
53
|
+
#
|
|
39
54
|
# Additionally, +to_json+ also exists as a class and dataset method, both
|
|
40
55
|
# of which return all objects in the dataset:
|
|
41
56
|
#
|
|
42
57
|
# Album.to_json
|
|
43
|
-
# Album.
|
|
58
|
+
# Album.where(artist_id: 1).to_json(include: :tags)
|
|
44
59
|
#
|
|
45
60
|
# If you have an existing array of model instances you want to convert to
|
|
46
61
|
# JSON, you can call the class to_json method with the :array option:
|
|
47
62
|
#
|
|
48
|
-
# Album.to_json(:
|
|
63
|
+
# Album.to_json(array: [Album[1], Album[2]])
|
|
64
|
+
#
|
|
65
|
+
# All to_json methods take blocks, and if a block is given, it will yield
|
|
66
|
+
# the array or hash before serialization, and will serialize the value
|
|
67
|
+
# the block returns. This allows you to customize the resulting JSON format
|
|
68
|
+
# on a per-call basis.
|
|
49
69
|
#
|
|
50
70
|
# In addition to creating JSON, this plugin also enables Sequel::Model
|
|
51
71
|
# classes to create instances directly from JSON using the from_json class
|
|
@@ -57,7 +77,7 @@ module Sequel
|
|
|
57
77
|
# The array_from_json class method exists to parse arrays of model instances
|
|
58
78
|
# from json:
|
|
59
79
|
#
|
|
60
|
-
# json = Album.
|
|
80
|
+
# json = Album.where(artist_id: 1).to_json
|
|
61
81
|
# albums = Album.array_from_json(json)
|
|
62
82
|
#
|
|
63
83
|
# These does not necessarily round trip, since doing so would let users
|
|
@@ -66,7 +86,7 @@ module Sequel
|
|
|
66
86
|
# fields, you can use the :fields option, which will call set_fields with
|
|
67
87
|
# the given fields:
|
|
68
88
|
#
|
|
69
|
-
# Album.from_json(album.to_json, :
|
|
89
|
+
# Album.from_json(album.to_json, fields: %w'id name')
|
|
70
90
|
#
|
|
71
91
|
# If you want to update an existing instance, you can use the from_json
|
|
72
92
|
# instance method:
|
|
@@ -76,27 +96,23 @@ module Sequel
|
|
|
76
96
|
# Both of these allow creation of cached associated objects, if you provide
|
|
77
97
|
# the :associations option:
|
|
78
98
|
#
|
|
79
|
-
# album.from_json(json, :
|
|
99
|
+
# album.from_json(json, associations: :artist)
|
|
80
100
|
#
|
|
81
101
|
# You can even provide options when setting up the associated objects:
|
|
82
102
|
#
|
|
83
|
-
# album.from_json(json, :
|
|
103
|
+
# album.from_json(json, associations: {artist: {fields: %w'id name', associations: :tags}})
|
|
84
104
|
#
|
|
85
105
|
# Note that active_support/json makes incompatible changes to the to_json API,
|
|
86
106
|
# and breaks some aspects of the json_serializer plugin. You can undo the damage
|
|
87
107
|
# done by active_support/json by doing:
|
|
88
108
|
#
|
|
89
|
-
#
|
|
90
|
-
# def to_json(options = {})
|
|
91
|
-
# JSON.generate(self)
|
|
92
|
-
# end
|
|
93
|
-
# end
|
|
94
|
-
#
|
|
95
|
-
# class Hash
|
|
109
|
+
# module ActiveSupportBrokenJSONFix
|
|
96
110
|
# def to_json(options = {})
|
|
97
111
|
# JSON.generate(self)
|
|
98
112
|
# end
|
|
99
113
|
# end
|
|
114
|
+
# Array.send(:prepend, ActiveSupportBrokenJSONFix)
|
|
115
|
+
# Hash.send(:prepend, ActiveSupportBrokenJSONFix)
|
|
100
116
|
#
|
|
101
117
|
# Note that this will probably cause active_support/json to no longer work
|
|
102
118
|
# correctly in some cases.
|
|
@@ -111,9 +127,9 @@ module Sequel
|
|
|
111
127
|
module JsonSerializer
|
|
112
128
|
# Set up the column readers to do deserialization and the column writers
|
|
113
129
|
# to save the value in deserialized_values.
|
|
114
|
-
def self.configure(model, opts=
|
|
115
|
-
model.
|
|
116
|
-
@json_serializer_opts = (@json_serializer_opts ||
|
|
130
|
+
def self.configure(model, opts=OPTS)
|
|
131
|
+
model.instance_exec do
|
|
132
|
+
@json_serializer_opts = (@json_serializer_opts || OPTS).merge(opts)
|
|
117
133
|
end
|
|
118
134
|
end
|
|
119
135
|
|
|
@@ -137,6 +153,15 @@ module Sequel
|
|
|
137
153
|
# The default opts to use when serializing model objects to JSON.
|
|
138
154
|
attr_reader :json_serializer_opts
|
|
139
155
|
|
|
156
|
+
# Freeze json serializier opts when freezing model class
|
|
157
|
+
def freeze
|
|
158
|
+
@json_serializer_opts.freeze.each_value do |v|
|
|
159
|
+
v.freeze if v.is_a?(Array) || v.is_a?(Hash)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
super
|
|
163
|
+
end
|
|
164
|
+
|
|
140
165
|
# Attempt to parse a single instance from the given JSON string,
|
|
141
166
|
# with options passed to InstanceMethods#from_json_node.
|
|
142
167
|
def from_json(json, opts=OPTS)
|
|
@@ -198,10 +223,10 @@ module Sequel
|
|
|
198
223
|
if assocs = opts[:associations]
|
|
199
224
|
assocs = case assocs
|
|
200
225
|
when Symbol
|
|
201
|
-
{assocs=>
|
|
226
|
+
{assocs=>OPTS}
|
|
202
227
|
when Array
|
|
203
228
|
assocs_tmp = {}
|
|
204
|
-
assocs.each{|v| assocs_tmp[v] =
|
|
229
|
+
assocs.each{|v| assocs_tmp[v] = OPTS}
|
|
205
230
|
assocs_tmp
|
|
206
231
|
when Hash
|
|
207
232
|
assocs
|
|
@@ -239,6 +264,20 @@ module Sequel
|
|
|
239
264
|
self
|
|
240
265
|
end
|
|
241
266
|
|
|
267
|
+
# Set the json serialization options that will be used by default
|
|
268
|
+
# in future calls to +to_json+. This is designed for cases where
|
|
269
|
+
# the model object will be used inside another data structure
|
|
270
|
+
# which to_json is called on, and as such will not allow passing
|
|
271
|
+
# of arguments to +to_json+.
|
|
272
|
+
#
|
|
273
|
+
# Example:
|
|
274
|
+
#
|
|
275
|
+
# obj.json_serializer_opts(only: :name)
|
|
276
|
+
# [obj].to_json # => '[{"name":"..."}]'
|
|
277
|
+
def json_serializer_opts(opts=OPTS)
|
|
278
|
+
@json_serializer_opts = (@json_serializer_opts||OPTS).merge(opts)
|
|
279
|
+
end
|
|
280
|
+
|
|
242
281
|
# Return a string in JSON format. Accepts the following
|
|
243
282
|
# options:
|
|
244
283
|
#
|
|
@@ -257,12 +296,13 @@ module Sequel
|
|
|
257
296
|
# string is given, use the string as the key, otherwise
|
|
258
297
|
# use an underscored version of the model's name.
|
|
259
298
|
def to_json(*a)
|
|
260
|
-
|
|
261
|
-
|
|
299
|
+
opts = model.json_serializer_opts
|
|
300
|
+
opts = opts.merge(@json_serializer_opts) if @json_serializer_opts
|
|
301
|
+
if (arg_opts = a.first).is_a?(Hash)
|
|
302
|
+
opts = opts.merge(arg_opts)
|
|
262
303
|
a = []
|
|
263
|
-
else
|
|
264
|
-
opts = model.json_serializer_opts
|
|
265
304
|
end
|
|
305
|
+
|
|
266
306
|
vals = values
|
|
267
307
|
cols = if only = opts[:only]
|
|
268
308
|
Array(only)
|
|
@@ -276,16 +316,39 @@ module Sequel
|
|
|
276
316
|
if inc = opts[:include]
|
|
277
317
|
if inc.is_a?(Hash)
|
|
278
318
|
inc.each do |k, v|
|
|
319
|
+
if k.is_a?(Sequel::SQL::AliasedExpression)
|
|
320
|
+
key_name = k.alias.to_s
|
|
321
|
+
k = k.expression
|
|
322
|
+
else
|
|
323
|
+
key_name = k.to_s
|
|
324
|
+
end
|
|
325
|
+
|
|
279
326
|
v = v.empty? ? [] : [v]
|
|
280
|
-
|
|
281
|
-
|
|
327
|
+
|
|
328
|
+
objs = public_send(k)
|
|
329
|
+
|
|
330
|
+
is_array = if r = model.association_reflection(k)
|
|
331
|
+
r.returns_array?
|
|
332
|
+
else
|
|
333
|
+
objs.is_a?(Array)
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
h[key_name] = if is_array
|
|
282
337
|
objs.map{|obj| Literal.new(Sequel.object_to_json(obj, *v))}
|
|
283
338
|
else
|
|
284
339
|
Literal.new(Sequel.object_to_json(objs, *v))
|
|
285
340
|
end
|
|
286
341
|
end
|
|
287
342
|
else
|
|
288
|
-
Array(inc).each
|
|
343
|
+
Array(inc).each do |c|
|
|
344
|
+
if c.is_a?(Sequel::SQL::AliasedExpression)
|
|
345
|
+
key_name = c.alias.to_s
|
|
346
|
+
c = c.expression
|
|
347
|
+
else
|
|
348
|
+
key_name = c.to_s
|
|
349
|
+
end
|
|
350
|
+
h[key_name] = public_send(c)
|
|
351
|
+
end
|
|
289
352
|
end
|
|
290
353
|
end
|
|
291
354
|
|
|
@@ -296,11 +359,19 @@ module Sequel
|
|
|
296
359
|
h = {root => h}
|
|
297
360
|
end
|
|
298
361
|
|
|
362
|
+
h = yield h if block_given?
|
|
299
363
|
Sequel.object_to_json(h, *a)
|
|
300
364
|
end
|
|
301
365
|
end
|
|
302
366
|
|
|
303
367
|
module DatasetMethods
|
|
368
|
+
# Store default options used when calling to_json on this dataset.
|
|
369
|
+
# These options take precedence over the class level options,
|
|
370
|
+
# and can be overridden by passing options directly to to_json.
|
|
371
|
+
def json_serializer_opts(opts=OPTS)
|
|
372
|
+
clone(:json_serializer_opts=>opts)
|
|
373
|
+
end
|
|
374
|
+
|
|
304
375
|
# Return a JSON string representing an array of all objects in
|
|
305
376
|
# this dataset. Takes the same options as the instance
|
|
306
377
|
# method, and passes them to every instance. Additionally,
|
|
@@ -308,6 +379,8 @@ module Sequel
|
|
|
308
379
|
#
|
|
309
380
|
# :array :: An array of instances. If this is not provided,
|
|
310
381
|
# calls #all on the receiver to get the array.
|
|
382
|
+
# :instance_block :: A block to pass to #to_json for each
|
|
383
|
+
# value in the dataset (or :array option).
|
|
311
384
|
# :root :: If set to :collection, wraps the collection
|
|
312
385
|
# in a root object using the pluralized, underscored model
|
|
313
386
|
# name as the key. If set to :instance, only wraps
|
|
@@ -316,11 +389,15 @@ module Sequel
|
|
|
316
389
|
# object. If set to a string, wraps the collection in
|
|
317
390
|
# a root object using the string as the key.
|
|
318
391
|
def to_json(*a)
|
|
319
|
-
|
|
320
|
-
|
|
392
|
+
opts = model.json_serializer_opts
|
|
393
|
+
|
|
394
|
+
if ds_opts = @opts[:json_serializer_opts]
|
|
395
|
+
opts = opts.merge(ds_opts)
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
if (arg = a.first).is_a?(Hash)
|
|
399
|
+
opts = opts.merge(arg)
|
|
321
400
|
a = []
|
|
322
|
-
else
|
|
323
|
-
opts = model.json_serializer_opts
|
|
324
401
|
end
|
|
325
402
|
|
|
326
403
|
case collection_root = opts[:root]
|
|
@@ -336,23 +413,22 @@ module Sequel
|
|
|
336
413
|
end
|
|
337
414
|
end
|
|
338
415
|
|
|
339
|
-
res = if row_proc
|
|
416
|
+
res = if row_proc || @opts[:eager_graph]
|
|
340
417
|
array = if opts[:array]
|
|
341
418
|
opts = opts.dup
|
|
342
419
|
opts.delete(:array)
|
|
343
420
|
else
|
|
344
421
|
all
|
|
345
422
|
end
|
|
346
|
-
array.map{|obj| Literal.new(Sequel.object_to_json(obj, opts))}
|
|
347
|
-
|
|
423
|
+
array.map{|obj| Literal.new(Sequel.object_to_json(obj, opts, &opts[:instance_block]))}
|
|
424
|
+
else
|
|
348
425
|
all
|
|
349
426
|
end
|
|
350
427
|
|
|
351
|
-
if collection_root
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
end
|
|
428
|
+
res = {collection_root => res} if collection_root
|
|
429
|
+
res = yield res if block_given?
|
|
430
|
+
|
|
431
|
+
Sequel.object_to_json(res, *a)
|
|
356
432
|
end
|
|
357
433
|
end
|
|
358
434
|
end
|