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
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
module Plugins
|
|
5
|
+
# The throw_failures plugin throws HookFailed and ValidationFailed exceptions instead
|
|
6
|
+
# of raising them. If there is no matching catch block, the UncaughtThrowError will be rescued
|
|
7
|
+
# and the HookFailed or ValidationFailed exception will be raised normally.
|
|
8
|
+
#
|
|
9
|
+
# If you are setting up the catch blocks to handle these failures, in the failure case this
|
|
10
|
+
# plugin is about 10-15% faster on CRuby and 10x faster on JRuby. If you are not
|
|
11
|
+
# setting up the catch blocks, in the failure case this plugin is about 30% slower on CRuby
|
|
12
|
+
# and 2x slower on JRuby. So this plugin should only be used if you are setting up catch
|
|
13
|
+
# blocks manually.
|
|
14
|
+
#
|
|
15
|
+
# This plugin will setup catch blocks automatically for internally rescued HookFailed
|
|
16
|
+
# exceptions when the model is configured to not raise exceptions on failure (by default,
|
|
17
|
+
# the exceptions are internally rescued in that case.
|
|
18
|
+
#
|
|
19
|
+
# To set up the catch blocks, use the class of the exception:
|
|
20
|
+
#
|
|
21
|
+
# ret = catch(Sequel::ValidationFailed) do
|
|
22
|
+
# model_instance.save
|
|
23
|
+
# end
|
|
24
|
+
# if ret.is_a?(Sequel::ValidationFailed)
|
|
25
|
+
# # handle failure
|
|
26
|
+
# else
|
|
27
|
+
# # handle success
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
# Usage:
|
|
31
|
+
#
|
|
32
|
+
# # Make all model subclass instances throw HookFailed and ValidationFailed exceptions
|
|
33
|
+
# # (called before loading subclasses)
|
|
34
|
+
# Sequel::Model.plugin :throw_failures
|
|
35
|
+
#
|
|
36
|
+
# # Make the Album class throw HookFailed and ValidationFailed exceptions
|
|
37
|
+
# Album.plugin :throw_failures
|
|
38
|
+
module ThrowFailures
|
|
39
|
+
module InstanceMethods
|
|
40
|
+
# Catch any thrown HookFailed exceptions.
|
|
41
|
+
def valid?(opts = OPTS)
|
|
42
|
+
catch_hook_failures{super} || false
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
# Catch any HookFailed exceptions thrown inside the block, and return
|
|
48
|
+
# nil if there were any.
|
|
49
|
+
def catch_hook_failures
|
|
50
|
+
called = ret = nil
|
|
51
|
+
catch(HookFailed) do
|
|
52
|
+
ret = yield
|
|
53
|
+
called = true
|
|
54
|
+
end
|
|
55
|
+
ret if called
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Catch any thrown HookFailed exceptions if not raising on failure.
|
|
59
|
+
def checked_save_failure(opts)
|
|
60
|
+
if raise_on_failure?(opts)
|
|
61
|
+
super
|
|
62
|
+
else
|
|
63
|
+
catch_hook_failures{super}
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
if RUBY_VERSION >= '2.2' && (!defined?(JRUBY_VERSION) || JRUBY_VERSION > '9.1')
|
|
68
|
+
# Throw HookFailed with the generated error. If the throw is not
|
|
69
|
+
# caught, just return the originally generated error.
|
|
70
|
+
def hook_failed_error(msg)
|
|
71
|
+
e = super
|
|
72
|
+
throw HookFailed, e
|
|
73
|
+
rescue UncaughtThrowError
|
|
74
|
+
e
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Throw ValidationFailed with the generated error. If the throw is not
|
|
78
|
+
# caught, just return the originally generated error.
|
|
79
|
+
def validation_failed_error
|
|
80
|
+
e = super
|
|
81
|
+
throw ValidationFailed, e
|
|
82
|
+
rescue UncaughtThrowError
|
|
83
|
+
e
|
|
84
|
+
end
|
|
85
|
+
else
|
|
86
|
+
# UncaughtThrowError was added in Ruby 2.2. Older Ruby versions
|
|
87
|
+
# used ArgumentError with "uncaught throw" at the start of the message
|
|
88
|
+
|
|
89
|
+
# :nocov:
|
|
90
|
+
def hook_failed_error(msg)
|
|
91
|
+
e = super
|
|
92
|
+
throw HookFailed, e
|
|
93
|
+
rescue ArgumentError => e2
|
|
94
|
+
raise e2 unless e2.message.start_with?('uncaught throw')
|
|
95
|
+
e
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def validation_failed_error
|
|
99
|
+
e = super
|
|
100
|
+
throw ValidationFailed, e
|
|
101
|
+
rescue ArgumentError => e2
|
|
102
|
+
raise e2 unless e2.message.start_with?('uncaught throw')
|
|
103
|
+
e
|
|
104
|
+
end
|
|
105
|
+
# :nocov:
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
data/lib/sequel/plugins/tree.rb
CHANGED
|
@@ -32,25 +32,27 @@ module Sequel
|
|
|
32
32
|
def self.apply(model, opts=OPTS)
|
|
33
33
|
opts = opts.dup
|
|
34
34
|
opts[:class] = model
|
|
35
|
+
opts[:key] ||= :parent_id
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
@parent_column = (opts[:key] ||= :parent_id)
|
|
38
|
-
@tree_order = opts[:order]
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
par = opts.merge(opts.fetch(:parent, {}))
|
|
37
|
+
par = opts.merge(opts.fetch(:parent, OPTS))
|
|
42
38
|
parent = par.fetch(:name, :parent)
|
|
43
39
|
|
|
44
|
-
chi = opts.merge(opts.fetch(:children,
|
|
40
|
+
chi = opts.merge(opts.fetch(:children, OPTS))
|
|
45
41
|
children = chi.fetch(:name, :children)
|
|
46
42
|
|
|
47
43
|
par[:reciprocal] = children
|
|
48
44
|
chi[:reciprocal] = parent
|
|
49
45
|
|
|
50
|
-
model.
|
|
51
|
-
|
|
46
|
+
model.instance_exec do
|
|
47
|
+
@parent_column = opts[:key]
|
|
48
|
+
@tree_order = opts[:order]
|
|
49
|
+
@parent_association_name = parent
|
|
50
|
+
@children_association_name = children
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
many_to_one parent, par
|
|
53
|
+
one_to_many children, chi
|
|
54
|
+
plugin SingleRoot if opts[:single_root]
|
|
55
|
+
end
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
module ClassMethods
|
|
@@ -61,7 +63,14 @@ module Sequel
|
|
|
61
63
|
# parent of the leaf.
|
|
62
64
|
attr_accessor :parent_column
|
|
63
65
|
|
|
64
|
-
|
|
66
|
+
# The association name for the parent association
|
|
67
|
+
attr_reader :parent_association_name
|
|
68
|
+
|
|
69
|
+
# The association name for the children association
|
|
70
|
+
attr_reader :children_association_name
|
|
71
|
+
|
|
72
|
+
Plugins.inherited_instance_variables(self, :@parent_column=>nil, :@tree_order=>nil, :@parent_association_name=>nil, :@children_association_name=>nil)
|
|
73
|
+
Plugins.def_dataset_methods(self, [:roots, :roots_dataset])
|
|
65
74
|
|
|
66
75
|
# Should freeze tree order if it is an array when freezing the model class.
|
|
67
76
|
def freeze
|
|
@@ -69,22 +78,6 @@ module Sequel
|
|
|
69
78
|
|
|
70
79
|
super
|
|
71
80
|
end
|
|
72
|
-
|
|
73
|
-
# Returns list of all root nodes (those with no parent nodes).
|
|
74
|
-
#
|
|
75
|
-
# TreeClass.roots # => [root1, root2]
|
|
76
|
-
def roots
|
|
77
|
-
roots_dataset.all
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# Returns the dataset for retrieval of all root nodes
|
|
81
|
-
#
|
|
82
|
-
# TreeClass.roots_dataset # => Sequel::Dataset instance
|
|
83
|
-
def roots_dataset
|
|
84
|
-
ds = where(Sequel.or(Array(parent_column).zip([])))
|
|
85
|
-
ds = ds.order(*tree_order) if tree_order
|
|
86
|
-
ds
|
|
87
|
-
end
|
|
88
81
|
end
|
|
89
82
|
|
|
90
83
|
module InstanceMethods
|
|
@@ -93,7 +86,10 @@ module Sequel
|
|
|
93
86
|
# subchild1.ancestors # => [child1, root]
|
|
94
87
|
def ancestors
|
|
95
88
|
node, nodes = self, []
|
|
96
|
-
|
|
89
|
+
meth = model.parent_association_name
|
|
90
|
+
while par = node.send(meth)
|
|
91
|
+
nodes << node = par
|
|
92
|
+
end
|
|
97
93
|
nodes
|
|
98
94
|
end
|
|
99
95
|
|
|
@@ -101,8 +97,8 @@ module Sequel
|
|
|
101
97
|
#
|
|
102
98
|
# node.descendants # => [child1, child2, subchild1_1, subchild1_2, subchild2_1, subchild2_2]
|
|
103
99
|
def descendants
|
|
104
|
-
nodes =
|
|
105
|
-
|
|
100
|
+
nodes = send(model.children_association_name).dup
|
|
101
|
+
send(model.children_association_name).each{|child| nodes.concat(child.descendants)}
|
|
106
102
|
nodes
|
|
107
103
|
end
|
|
108
104
|
|
|
@@ -121,7 +117,11 @@ module Sequel
|
|
|
121
117
|
#
|
|
122
118
|
# subchild1.self_and_siblings # => [subchild1, subchild2]
|
|
123
119
|
def self_and_siblings
|
|
124
|
-
|
|
120
|
+
if parent = send(model.parent_association_name)
|
|
121
|
+
parent.send(model.children_association_name)
|
|
122
|
+
else
|
|
123
|
+
model.roots
|
|
124
|
+
end
|
|
125
125
|
end
|
|
126
126
|
|
|
127
127
|
# Returns all siblings of the current node.
|
|
@@ -139,6 +139,24 @@ module Sequel
|
|
|
139
139
|
end
|
|
140
140
|
end
|
|
141
141
|
|
|
142
|
+
module DatasetMethods
|
|
143
|
+
# Returns list of all root nodes (those with no parent nodes).
|
|
144
|
+
#
|
|
145
|
+
# TreeClass.roots # => [root1, root2]
|
|
146
|
+
def roots
|
|
147
|
+
roots_dataset.all
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Returns the dataset for retrieval of all root nodes
|
|
151
|
+
#
|
|
152
|
+
# TreeClass.roots_dataset # => Sequel::Dataset instance
|
|
153
|
+
def roots_dataset
|
|
154
|
+
ds = where(Sequel.or(Array(model.parent_column).zip([])))
|
|
155
|
+
ds = ds.order(*model.tree_order) if model.tree_order
|
|
156
|
+
ds
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
142
160
|
# Plugin included when :single_root option is passed.
|
|
143
161
|
module SingleRoot
|
|
144
162
|
module ClassMethods
|
|
@@ -41,7 +41,9 @@ module Sequel
|
|
|
41
41
|
# Typecast values using #load_typecast when the values are retrieved
|
|
42
42
|
# from the database.
|
|
43
43
|
def call(values)
|
|
44
|
-
super.load_typecast
|
|
44
|
+
o = super.load_typecast
|
|
45
|
+
o.send(:_clear_changed_columns, :initialize)
|
|
46
|
+
o
|
|
45
47
|
end
|
|
46
48
|
|
|
47
49
|
# Freeze typecast on load columns when freezing model class.
|
|
@@ -63,7 +65,6 @@ module Sequel
|
|
|
63
65
|
set_column_value("#{c}=", v)
|
|
64
66
|
end
|
|
65
67
|
end
|
|
66
|
-
_changed_columns.clear
|
|
67
68
|
self
|
|
68
69
|
end
|
|
69
70
|
|
|
@@ -188,13 +188,21 @@ module Sequel
|
|
|
188
188
|
# Sequel will attempt to insert a NULL value into the database, instead of using the
|
|
189
189
|
# database's default.
|
|
190
190
|
# :allow_nil :: Whether to skip the validation if the value is nil.
|
|
191
|
-
# :if :: A symbol (indicating an instance_method) or proc (which is
|
|
191
|
+
# :if :: A symbol (indicating an instance_method) or proc (which is used to define an instance method)
|
|
192
192
|
# skipping this validation if it returns nil or false.
|
|
193
193
|
# :tag :: The tag to use for this validation.
|
|
194
194
|
def validates_each(*atts, &block)
|
|
195
195
|
opts = extract_options!(atts)
|
|
196
196
|
blank_meth = db.method(:blank_object?).to_proc
|
|
197
|
-
|
|
197
|
+
i = opts[:if]
|
|
198
|
+
am = opts[:allow_missing]
|
|
199
|
+
an = opts[:allow_nil]
|
|
200
|
+
ab = opts[:allow_blank]
|
|
201
|
+
blk = if i || am || an || ab
|
|
202
|
+
if i.is_a?(Proc)
|
|
203
|
+
i = Plugins.def_sequel_method(self, "validation_class_methods_if", 0, &i)
|
|
204
|
+
end
|
|
205
|
+
|
|
198
206
|
proc do |o,a,v|
|
|
199
207
|
next if i && !validation_if_proc(o, i)
|
|
200
208
|
next if an && Array(v).all?(&:nil?)
|
|
@@ -419,7 +427,7 @@ module Sequel
|
|
|
419
427
|
# an empty hash is returned This method is useful when writing methods that
|
|
420
428
|
# take an options hash as the last parameter.
|
|
421
429
|
def extract_options!(array)
|
|
422
|
-
array.last.is_a?(Hash) ? array.pop :
|
|
430
|
+
array.last.is_a?(Hash) ? array.pop : OPTS
|
|
423
431
|
end
|
|
424
432
|
|
|
425
433
|
# Add the validation reflection to the class's validations.
|
|
@@ -434,8 +442,6 @@ module Sequel
|
|
|
434
442
|
case i
|
|
435
443
|
when Symbol
|
|
436
444
|
o.get_column_value(i)
|
|
437
|
-
when Proc
|
|
438
|
-
o.instance_exec(&i)
|
|
439
445
|
else
|
|
440
446
|
raise(::Sequel::Error, "invalid value for :if validation option")
|
|
441
447
|
end
|
|
@@ -244,7 +244,7 @@ module Sequel
|
|
|
244
244
|
def validates_unique(*atts)
|
|
245
245
|
opts = default_validation_helpers_options(:unique)
|
|
246
246
|
if atts.last.is_a?(Hash)
|
|
247
|
-
opts =
|
|
247
|
+
opts = opts.merge(atts.pop)
|
|
248
248
|
end
|
|
249
249
|
message = validation_error_message(opts[:message])
|
|
250
250
|
from_values = opts[:from] == :values
|
|
@@ -302,7 +302,7 @@ module Sequel
|
|
|
302
302
|
# Merge the given options with the default options for the given type
|
|
303
303
|
# and call validatable_attributes with the merged options.
|
|
304
304
|
def validatable_attributes_for_type(type, atts, opts, &block)
|
|
305
|
-
validatable_attributes(atts,
|
|
305
|
+
validatable_attributes(atts, default_validation_helpers_options(type).merge(opts), &block)
|
|
306
306
|
end
|
|
307
307
|
|
|
308
308
|
# The validation error message to use, as a string. If message
|
data/lib/sequel/sql.rb
CHANGED
|
@@ -18,7 +18,8 @@ module Sequel
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
# Time subclass that gets literalized with only the time value, so it operates
|
|
21
|
-
# like a standard SQL time type.
|
|
21
|
+
# like a standard SQL time type. This type does not support timezones, by design,
|
|
22
|
+
# so it will not work correctly with <tt>time with time zone</tt> types.
|
|
22
23
|
class SQLTime < ::Time
|
|
23
24
|
@date = nil
|
|
24
25
|
|
|
@@ -26,12 +27,27 @@ module Sequel
|
|
|
26
27
|
# Set the date used for SQLTime instances.
|
|
27
28
|
attr_writer :date
|
|
28
29
|
|
|
29
|
-
#
|
|
30
|
+
# Use the date explicitly set, or the current date if there is not a
|
|
30
31
|
# date set.
|
|
31
32
|
def date
|
|
32
33
|
@date || now
|
|
33
34
|
end
|
|
34
35
|
|
|
36
|
+
# Set the correct date and timezone when parsing times.
|
|
37
|
+
def parse(*)
|
|
38
|
+
t = super
|
|
39
|
+
|
|
40
|
+
utc = Sequel.application_timezone == :utc
|
|
41
|
+
d = @date
|
|
42
|
+
if d || utc
|
|
43
|
+
meth = utc ? :utc : :local
|
|
44
|
+
d ||= t
|
|
45
|
+
t = public_send(meth, d.year, d.month, d.day, t.hour, t.min, t.sec, t.usec)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
t
|
|
49
|
+
end
|
|
50
|
+
|
|
35
51
|
# Create a new SQLTime instance given an hour, minute, second, and usec.
|
|
36
52
|
def create(hour, minute, second, usec = 0)
|
|
37
53
|
t = date
|
|
@@ -250,12 +266,12 @@ module Sequel
|
|
|
250
266
|
# methods overlap with the standard +BooleanMethods methods+, and they only
|
|
251
267
|
# make sense for integers, they are only included in +NumericExpression+.
|
|
252
268
|
#
|
|
253
|
-
# :a.sql_number & :b # "a" & "b"
|
|
254
|
-
# :a.sql_number | :b # "a" | "b"
|
|
255
|
-
# :a.sql_number ^ :b # "a" ^ "b"
|
|
256
|
-
# :a.sql_number << :b # "a" << "b"
|
|
257
|
-
# :a.sql_number >> :b # "a" >> "b"
|
|
258
|
-
#
|
|
269
|
+
# Sequel[:a].sql_number & :b # "a" & "b"
|
|
270
|
+
# Sequel[:a].sql_number | :b # "a" | "b"
|
|
271
|
+
# Sequel[:a].sql_number ^ :b # "a" ^ "b"
|
|
272
|
+
# Sequel[:a].sql_number << :b # "a" << "b"
|
|
273
|
+
# Sequel[:a].sql_number >> :b # "a" >> "b"
|
|
274
|
+
# ~Sequel[:a].sql_number # ~"a"
|
|
259
275
|
module BitwiseMethods
|
|
260
276
|
ComplexExpression::BITWISE_OPERATORS.each do |o|
|
|
261
277
|
module_eval("def #{o}(o) NumericExpression.new(#{o.inspect}, self, o) end", __FILE__, __LINE__)
|
|
@@ -339,9 +355,15 @@ module Sequel
|
|
|
339
355
|
end
|
|
340
356
|
|
|
341
357
|
# Return an <tt>SQL::CaseExpression</tt> created with the given arguments.
|
|
358
|
+
# The first argument are the <tt>WHEN</tt>/<tt>THEN</tt> conditions,
|
|
359
|
+
# specified as an array or a hash. The second argument is the
|
|
360
|
+
# <tt>ELSE</tt> default value. The third optional argument is the
|
|
361
|
+
# <tt>CASE</tt> expression.
|
|
342
362
|
#
|
|
343
|
-
# Sequel.case(
|
|
363
|
+
# Sequel.case({a: 1}, 0) # SQL: CASE WHEN a THEN 1 ELSE 0 END
|
|
344
364
|
# Sequel.case({a: 1}, 0, :b) # SQL: CASE b WHEN a THEN 1 ELSE 0 END
|
|
365
|
+
# Sequel.case({{a: [2,3]} => 1}, 0) # SQL: CASE WHEN a IN (2, 3) THEN 1 ELSE 0 END
|
|
366
|
+
# Sequel.case([[{a: [2,3]}, 1]], 0) # SQL: CASE WHEN a IN (2, 3) THEN 1 ELSE 0 END
|
|
345
367
|
def case(*args)
|
|
346
368
|
SQL::CaseExpression.new(*args)
|
|
347
369
|
end
|
|
@@ -730,10 +752,10 @@ module Sequel
|
|
|
730
752
|
# This module includes the inequality methods (>, <, >=, <=) that are defined on objects that can be
|
|
731
753
|
# used in a numeric or string context in SQL.
|
|
732
754
|
#
|
|
733
|
-
# Sequel
|
|
734
|
-
# Sequel
|
|
735
|
-
# Sequel
|
|
736
|
-
# Sequel
|
|
755
|
+
# Sequel[:a] > :b # a > "b"
|
|
756
|
+
# Sequel[:a] < :b # a > "b"
|
|
757
|
+
# Sequel[:a] >= :b # a >= "b"
|
|
758
|
+
# Sequel[:a] <= :b # a <= "b"
|
|
737
759
|
module InequalityMethods
|
|
738
760
|
ComplexExpression::INEQUALITY_OPERATORS.each do |o|
|
|
739
761
|
module_eval("def #{o}(o) BooleanExpression.new(#{o.inspect}, self, o) end", __FILE__, __LINE__)
|
|
@@ -744,10 +766,10 @@ module Sequel
|
|
|
744
766
|
# that are defined on objects that can be used in a numeric context in SQL
|
|
745
767
|
# (+Symbol+, +LiteralString+, and +SQL::GenericExpression+).
|
|
746
768
|
#
|
|
747
|
-
# :a + :b # "a" + "b"
|
|
748
|
-
# :a - :b # "a" - "b"
|
|
749
|
-
# :a * :b # "a" * "b"
|
|
750
|
-
# :a / :b # "a" / "b"
|
|
769
|
+
# Sequel[:a] + :b # "a" + "b"
|
|
770
|
+
# Sequel[:a] - :b # "a" - "b"
|
|
771
|
+
# Sequel[:a] * :b # "a" * "b"
|
|
772
|
+
# Sequel[:a] / :b # "a" / "b"
|
|
751
773
|
#
|
|
752
774
|
# One exception to this is if + is called with a +String+ or +StringExpression+,
|
|
753
775
|
# in which case the || operator is used instead of the + operator:
|
|
@@ -766,8 +788,10 @@ module Sequel
|
|
|
766
788
|
def coerce(other)
|
|
767
789
|
if other.is_a?(Numeric)
|
|
768
790
|
[SQL::NumericExpression.new(:NOOP, other), self]
|
|
769
|
-
|
|
791
|
+
elsif defined?(super)
|
|
770
792
|
super
|
|
793
|
+
else
|
|
794
|
+
[self, other]
|
|
771
795
|
end
|
|
772
796
|
end
|
|
773
797
|
|
|
@@ -998,6 +1022,11 @@ module Sequel
|
|
|
998
1022
|
include SQL::AliasMethods
|
|
999
1023
|
include SQL::CastMethods
|
|
1000
1024
|
|
|
1025
|
+
class << self
|
|
1026
|
+
# Alias new to call for usage in conversion procs
|
|
1027
|
+
alias call new
|
|
1028
|
+
end
|
|
1029
|
+
|
|
1001
1030
|
# Return a LiteralString with the same content if no args are given, otherwise
|
|
1002
1031
|
# return a SQL::PlaceholderLiteralString with the current string and the given args.
|
|
1003
1032
|
def lit(*args)
|
|
@@ -1059,8 +1088,30 @@ module Sequel
|
|
|
1059
1088
|
def self.from_value_pair(l, r)
|
|
1060
1089
|
case r
|
|
1061
1090
|
when Range
|
|
1062
|
-
|
|
1063
|
-
|
|
1091
|
+
unless r.begin.nil?
|
|
1092
|
+
begin_expr = new(:>=, l, r.begin)
|
|
1093
|
+
end
|
|
1094
|
+
unless r.end.nil?
|
|
1095
|
+
end_expr = new(r.exclude_end? ? :< : :<=, l, r.end)
|
|
1096
|
+
end
|
|
1097
|
+
if begin_expr
|
|
1098
|
+
if end_expr
|
|
1099
|
+
new(:AND, begin_expr, end_expr)
|
|
1100
|
+
else
|
|
1101
|
+
begin_expr
|
|
1102
|
+
end
|
|
1103
|
+
elsif end_expr
|
|
1104
|
+
end_expr
|
|
1105
|
+
else
|
|
1106
|
+
new(:'=', 1, 1)
|
|
1107
|
+
end
|
|
1108
|
+
when ::Array
|
|
1109
|
+
r = r.dup.freeze unless r.frozen?
|
|
1110
|
+
new(:IN, l, r)
|
|
1111
|
+
when ::String
|
|
1112
|
+
r = r.dup.freeze unless r.frozen?
|
|
1113
|
+
new(:'=', l, r)
|
|
1114
|
+
when ::Sequel::Dataset
|
|
1064
1115
|
new(:IN, l, r)
|
|
1065
1116
|
when NegativeBooleanConstant
|
|
1066
1117
|
new(:"IS NOT", l, r.constant)
|
|
@@ -1092,8 +1143,21 @@ module Sequel
|
|
|
1092
1143
|
case op = ce.op
|
|
1093
1144
|
when :AND, :OR
|
|
1094
1145
|
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.map{|a| BooleanExpression.invert(a)})
|
|
1095
|
-
|
|
1146
|
+
when :IN, :"NOT IN"
|
|
1096
1147
|
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.dup)
|
|
1148
|
+
else
|
|
1149
|
+
if ce.args.length == 2
|
|
1150
|
+
case ce.args[1]
|
|
1151
|
+
when Function, LiteralString, PlaceholderLiteralString
|
|
1152
|
+
# Special behavior to not push down inversion in this case because doing so
|
|
1153
|
+
# can result in incorrect behavior for ANY/SOME/ALL operators.
|
|
1154
|
+
BooleanExpression.new(:NOT, ce)
|
|
1155
|
+
else
|
|
1156
|
+
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.dup)
|
|
1157
|
+
end
|
|
1158
|
+
else
|
|
1159
|
+
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.dup)
|
|
1160
|
+
end
|
|
1097
1161
|
end
|
|
1098
1162
|
when StringExpression, NumericExpression
|
|
1099
1163
|
raise(Sequel::Error, "cannot invert #{ce.inspect}")
|
|
@@ -1253,6 +1317,7 @@ module Sequel
|
|
|
1253
1317
|
CURRENT_DATE = Constant.new(:CURRENT_DATE)
|
|
1254
1318
|
CURRENT_TIME = Constant.new(:CURRENT_TIME)
|
|
1255
1319
|
CURRENT_TIMESTAMP = Constant.new(:CURRENT_TIMESTAMP)
|
|
1320
|
+
DEFAULT = Constant.new(:DEFAULT)
|
|
1256
1321
|
SQLTRUE = TRUE = BooleanConstant.new(true)
|
|
1257
1322
|
SQLFALSE = FALSE = BooleanConstant.new(false)
|
|
1258
1323
|
NULL = BooleanConstant.new(nil)
|
|
@@ -1366,7 +1431,7 @@ module Sequel
|
|
|
1366
1431
|
end
|
|
1367
1432
|
|
|
1368
1433
|
# Return a new function with an OVER clause (making it a window function).
|
|
1369
|
-
# See
|
|
1434
|
+
# See Sequel::SQL::Window for the list of options +over+ can receive.
|
|
1370
1435
|
#
|
|
1371
1436
|
# Sequel.function(:row_number).over(partition: :col) # row_number() OVER (PARTITION BY col)
|
|
1372
1437
|
def over(window=OPTS)
|
|
@@ -1422,7 +1487,7 @@ module Sequel
|
|
|
1422
1487
|
|
|
1423
1488
|
# Return a new function call with the given opts merged into the current opts.
|
|
1424
1489
|
def with_opts(opts)
|
|
1425
|
-
self.class.new!(name, args,
|
|
1490
|
+
self.class.new!(name, args, @opts.merge(opts))
|
|
1426
1491
|
end
|
|
1427
1492
|
end
|
|
1428
1493
|
|
|
@@ -1703,7 +1768,7 @@ module Sequel
|
|
|
1703
1768
|
# StringExpression.like(:a, 'a%', /^a/i) # (("a" LIKE 'a%' ESCAPE '\') OR ("a" ~* '^a'))
|
|
1704
1769
|
def self.like(l, *ces)
|
|
1705
1770
|
l, lre, lci = like_element(l)
|
|
1706
|
-
lci = (ces.last.is_a?(Hash) ? ces.pop :
|
|
1771
|
+
lci = (ces.last.is_a?(Hash) ? ces.pop : OPTS)[:case_insensitive] ? true : lci
|
|
1707
1772
|
ces.map! do |ce|
|
|
1708
1773
|
r, rre, rci = like_element(ce)
|
|
1709
1774
|
BooleanExpression.new(LIKE_MAP[[lre||rre, lci||rci]], l, r)
|
|
@@ -1846,7 +1911,7 @@ module Sequel
|
|
|
1846
1911
|
freeze
|
|
1847
1912
|
end
|
|
1848
1913
|
|
|
1849
|
-
|
|
1914
|
+
m = Module.new do
|
|
1850
1915
|
# Return an +Identifier+, +QualifiedIdentifier+, or +Function+, depending
|
|
1851
1916
|
# on arguments and whether a block is provided. Does not currently call the block.
|
|
1852
1917
|
# See the class level documentation.
|
|
@@ -1862,7 +1927,8 @@ module Sequel
|
|
|
1862
1927
|
Function.new(m, *args)
|
|
1863
1928
|
end
|
|
1864
1929
|
end
|
|
1865
|
-
end
|
|
1930
|
+
end
|
|
1931
|
+
include m
|
|
1866
1932
|
|
|
1867
1933
|
Sequel::VIRTUAL_ROW = new
|
|
1868
1934
|
end
|
|
@@ -1883,16 +1949,40 @@ module Sequel
|
|
|
1883
1949
|
# # (PARTITION BY col7 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
|
|
1884
1950
|
# Sequel::SQL::Window.new(partition: :col7, frame: :rows)
|
|
1885
1951
|
# # (PARTITION BY col7 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
|
|
1886
|
-
# Sequel::SQL::Window.new(partition: :col7, frame:
|
|
1952
|
+
# Sequel::SQL::Window.new(partition: :col7, frame: {type: :range, start: current})
|
|
1887
1953
|
# # (PARTITION BY col7 RANGE CURRENT ROW)
|
|
1954
|
+
# Sequel::SQL::Window.new(partition: :col7, frame: {type: :range, start: 1, end: 1})
|
|
1955
|
+
# # (PARTITION BY col7 RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING)
|
|
1956
|
+
# Sequel::SQL::Window.new(partition: :col7, frame: {type: :range, start: 2, end: [1, :preceding]})
|
|
1957
|
+
# # (PARTITION BY col7 RANGE BETWEEN 2 PRECEDING AND 1 PRECEDING)
|
|
1958
|
+
# Sequel::SQL::Window.new(partition: :col7, frame: {type: :range, start: 1, end: [2, :following]})
|
|
1959
|
+
# # (PARTITION BY col7 RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOWING)
|
|
1960
|
+
# Sequel::SQL::Window.new(partition: :col7, frame: {type: :range, start: :preceding, exclude: :current})
|
|
1961
|
+
# # (PARTITION BY col7 RANGE UNBOUNDED PRECEDING EXCLUDE CURRENT ROW)
|
|
1888
1962
|
#
|
|
1889
1963
|
# Sequel::SQL::Window.new(window: :named_window) # you can create a named window with Dataset#window
|
|
1890
1964
|
# # (named_window)
|
|
1891
1965
|
class Window < Expression
|
|
1892
1966
|
# The options for this window. Options currently supported:
|
|
1893
|
-
# :frame :: if specified, should be :all, :rows,
|
|
1894
|
-
#
|
|
1895
|
-
#
|
|
1967
|
+
# :frame :: if specified, should be :all, :rows, :range, :groups, a String, or a Hash.
|
|
1968
|
+
# :all :: Always operates over all rows in the partition
|
|
1969
|
+
# :rows :: Includes rows in the partition up to and including the current row
|
|
1970
|
+
# :range, :groups :: Includes rows in the partition up to and including the current group
|
|
1971
|
+
# String :: Used as literal SQL code, try to avoid
|
|
1972
|
+
# Hash :: Hash of options for the frame:
|
|
1973
|
+
# :type :: The type of frame, must be :rows, :range, or :groups (required)
|
|
1974
|
+
# :start :: The start of the frame (required). Possible values:
|
|
1975
|
+
# :preceding :: UNBOUNDED PRECEDING
|
|
1976
|
+
# :following :: UNBOUNDED FOLLOWING
|
|
1977
|
+
# :current :: CURRENT ROW
|
|
1978
|
+
# String, Numeric, or Cast :: Used as the offset of rows/values preceding
|
|
1979
|
+
# Array :: Must have two elements, with first element being String, Numeric, or
|
|
1980
|
+
# Cast and second element being :preceding or :following
|
|
1981
|
+
# :end :: The end of the frame. Can be left out. If present, takes the same values as
|
|
1982
|
+
# :start, except that when a String, Numeric, or Hash, it is used as the offset
|
|
1983
|
+
# for rows following
|
|
1984
|
+
# :exclude :: Which rows to exclude. Possible values are :current, :ties, :group
|
|
1985
|
+
# :no_others.
|
|
1896
1986
|
# :order :: order on the column(s) given
|
|
1897
1987
|
# :partition :: partition/group on the column(s) given
|
|
1898
1988
|
# :window :: base results on a previously specified named window
|