sequel 4.49.0 → 5.0.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 +70 -0
- data/README.rdoc +195 -136
- data/Rakefile +26 -42
- data/bin/sequel +3 -5
- data/doc/advanced_associations.rdoc +86 -163
- data/doc/association_basics.rdoc +197 -274
- data/doc/bin_sequel.rdoc +5 -3
- data/doc/cheat_sheet.rdoc +66 -43
- data/doc/code_order.rdoc +1 -8
- data/doc/core_extensions.rdoc +81 -56
- data/doc/dataset_basics.rdoc +8 -17
- data/doc/dataset_filtering.rdoc +81 -86
- data/doc/extensions.rdoc +3 -10
- data/doc/mass_assignment.rdoc +73 -30
- data/doc/migration.rdoc +19 -36
- data/doc/model_dataset_method_design.rdoc +14 -17
- data/doc/model_hooks.rdoc +15 -25
- data/doc/model_plugins.rdoc +10 -10
- data/doc/mssql_stored_procedures.rdoc +3 -3
- data/doc/object_model.rdoc +52 -70
- data/doc/opening_databases.rdoc +39 -32
- data/doc/postgresql.rdoc +48 -38
- data/doc/prepared_statements.rdoc +27 -22
- data/doc/querying.rdoc +173 -150
- data/doc/reflection.rdoc +5 -6
- data/doc/release_notes/5.0.0.txt +159 -0
- data/doc/schema_modification.rdoc +63 -60
- data/doc/security.rdoc +97 -88
- data/doc/sharding.rdoc +43 -30
- data/doc/sql.rdoc +53 -65
- data/doc/testing.rdoc +3 -5
- data/doc/thread_safety.rdoc +2 -4
- data/doc/transactions.rdoc +18 -17
- data/doc/validations.rdoc +48 -45
- data/doc/virtual_rows.rdoc +87 -115
- data/lib/sequel.rb +1 -1
- data/lib/sequel/adapters/ado.rb +9 -25
- data/lib/sequel/adapters/ado/access.rb +7 -13
- data/lib/sequel/adapters/ado/mssql.rb +2 -9
- data/lib/sequel/adapters/amalgalite.rb +3 -18
- data/lib/sequel/adapters/ibmdb.rb +9 -45
- data/lib/sequel/adapters/jdbc.rb +13 -73
- data/lib/sequel/adapters/jdbc/db2.rb +8 -37
- data/lib/sequel/adapters/jdbc/derby.rb +4 -50
- data/lib/sequel/adapters/jdbc/h2.rb +4 -25
- data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -26
- data/lib/sequel/adapters/jdbc/jtds.rb +2 -9
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -11
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -15
- data/lib/sequel/adapters/jdbc/oracle.rb +4 -26
- data/lib/sequel/adapters/jdbc/postgresql.rb +2 -31
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +4 -17
- data/lib/sequel/adapters/jdbc/sqlite.rb +1 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -13
- data/lib/sequel/adapters/jdbc/transactions.rb +1 -14
- data/lib/sequel/adapters/mock.rb +4 -30
- data/lib/sequel/adapters/mysql.rb +7 -44
- data/lib/sequel/adapters/mysql2.rb +5 -23
- data/lib/sequel/adapters/odbc.rb +0 -19
- data/lib/sequel/adapters/odbc/db2.rb +1 -1
- data/lib/sequel/adapters/odbc/mssql.rb +4 -12
- data/lib/sequel/adapters/odbc/oracle.rb +1 -1
- data/lib/sequel/adapters/oracle.rb +7 -13
- data/lib/sequel/adapters/postgres.rb +13 -57
- data/lib/sequel/adapters/postgresql.rb +1 -1
- data/lib/sequel/adapters/shared/access.rb +11 -51
- data/lib/sequel/adapters/shared/db2.rb +3 -61
- data/lib/sequel/adapters/shared/mssql.rb +21 -157
- data/lib/sequel/adapters/shared/mysql.rb +23 -224
- data/lib/sequel/adapters/shared/oracle.rb +13 -41
- data/lib/sequel/adapters/shared/postgres.rb +44 -259
- data/lib/sequel/adapters/shared/sqlanywhere.rb +4 -96
- data/lib/sequel/adapters/shared/sqlite.rb +12 -101
- data/lib/sequel/adapters/sqlanywhere.rb +4 -23
- data/lib/sequel/adapters/sqlite.rb +2 -19
- data/lib/sequel/adapters/tinytds.rb +5 -15
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -4
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +3 -6
- data/lib/sequel/adapters/utils/replace.rb +0 -5
- data/lib/sequel/adapters/utils/stored_procedures.rb +0 -2
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +2 -0
- data/lib/sequel/ast_transformer.rb +3 -94
- data/lib/sequel/connection_pool.rb +26 -28
- data/lib/sequel/connection_pool/sharded_single.rb +1 -4
- data/lib/sequel/connection_pool/sharded_threaded.rb +97 -95
- data/lib/sequel/connection_pool/single.rb +0 -2
- data/lib/sequel/connection_pool/threaded.rb +94 -110
- data/lib/sequel/core.rb +42 -101
- data/lib/sequel/database.rb +12 -2
- data/lib/sequel/database/connecting.rb +23 -60
- data/lib/sequel/database/dataset.rb +6 -9
- data/lib/sequel/database/dataset_defaults.rb +4 -48
- data/lib/sequel/database/features.rb +5 -4
- data/lib/sequel/database/logging.rb +2 -9
- data/lib/sequel/database/misc.rb +23 -55
- data/lib/sequel/database/query.rb +8 -13
- data/lib/sequel/database/schema_generator.rb +89 -64
- data/lib/sequel/database/schema_methods.rb +61 -79
- data/lib/sequel/database/transactions.rb +4 -24
- data/lib/sequel/dataset.rb +18 -10
- data/lib/sequel/dataset/actions.rb +53 -107
- data/lib/sequel/dataset/dataset_module.rb +3 -15
- data/lib/sequel/dataset/features.rb +30 -30
- data/lib/sequel/dataset/graph.rb +40 -49
- data/lib/sequel/dataset/misc.rb +12 -37
- data/lib/sequel/dataset/placeholder_literalizer.rb +4 -4
- data/lib/sequel/dataset/prepared_statements.rb +23 -51
- data/lib/sequel/dataset/query.rb +71 -155
- data/lib/sequel/dataset/sql.rb +30 -225
- data/lib/sequel/deprecated.rb +18 -27
- data/lib/sequel/exceptions.rb +1 -17
- data/lib/sequel/extensions/_model_pg_row.rb +0 -7
- data/lib/sequel/extensions/_pretty_table.rb +1 -3
- data/lib/sequel/extensions/arbitrary_servers.rb +10 -10
- data/lib/sequel/extensions/connection_expiration.rb +1 -1
- data/lib/sequel/extensions/connection_validator.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +11 -11
- data/lib/sequel/extensions/core_extensions.rb +39 -49
- data/lib/sequel/extensions/core_refinements.rb +39 -45
- data/lib/sequel/extensions/current_datetime_timestamp.rb +0 -4
- data/lib/sequel/extensions/date_arithmetic.rb +7 -7
- data/lib/sequel/extensions/duplicate_columns_handler.rb +12 -9
- data/lib/sequel/extensions/empty_array_consider_nulls.rb +2 -2
- data/lib/sequel/extensions/eval_inspect.rb +4 -11
- data/lib/sequel/extensions/freeze_datasets.rb +1 -69
- data/lib/sequel/extensions/from_block.rb +1 -35
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/identifier_mangling.rb +9 -19
- data/lib/sequel/extensions/implicit_subquery.rb +2 -2
- data/lib/sequel/extensions/inflector.rb +4 -4
- data/lib/sequel/extensions/migration.rb +23 -40
- data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -84
- data/lib/sequel/extensions/null_dataset.rb +2 -8
- data/lib/sequel/extensions/pagination.rb +1 -17
- data/lib/sequel/extensions/pg_array.rb +20 -189
- data/lib/sequel/extensions/pg_hstore.rb +11 -50
- data/lib/sequel/extensions/pg_hstore_ops.rb +2 -2
- data/lib/sequel/extensions/pg_inet.rb +2 -15
- data/lib/sequel/extensions/pg_interval.rb +1 -20
- data/lib/sequel/extensions/pg_json.rb +7 -27
- data/lib/sequel/extensions/pg_loose_count.rb +1 -1
- data/lib/sequel/extensions/pg_range.rb +6 -121
- data/lib/sequel/extensions/pg_range_ops.rb +1 -3
- data/lib/sequel/extensions/pg_row.rb +5 -77
- data/lib/sequel/extensions/pg_row_ops.rb +2 -13
- data/lib/sequel/extensions/query.rb +3 -4
- data/lib/sequel/extensions/round_timestamps.rb +0 -6
- data/lib/sequel/extensions/schema_dumper.rb +13 -13
- data/lib/sequel/extensions/select_remove.rb +3 -3
- data/lib/sequel/extensions/split_array_nil.rb +2 -2
- data/lib/sequel/extensions/sql_comments.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +11 -8
- data/lib/sequel/extensions/symbol_aref.rb +6 -20
- data/lib/sequel/model.rb +27 -62
- data/lib/sequel/model/associations.rb +128 -131
- data/lib/sequel/model/base.rb +171 -711
- data/lib/sequel/model/default_inflections.rb +1 -1
- data/lib/sequel/model/errors.rb +0 -3
- data/lib/sequel/model/exceptions.rb +2 -6
- data/lib/sequel/model/inflections.rb +1 -26
- data/lib/sequel/model/plugins.rb +1 -0
- data/lib/sequel/plugins/active_model.rb +2 -5
- data/lib/sequel/plugins/association_dependencies.rb +15 -15
- data/lib/sequel/plugins/association_pks.rb +14 -28
- data/lib/sequel/plugins/association_proxies.rb +6 -7
- data/lib/sequel/plugins/auto_validations.rb +4 -4
- data/lib/sequel/plugins/before_after_save.rb +0 -43
- data/lib/sequel/plugins/blacklist_security.rb +9 -8
- data/lib/sequel/plugins/boolean_readers.rb +3 -3
- data/lib/sequel/plugins/boolean_subsets.rb +2 -2
- data/lib/sequel/plugins/caching.rb +5 -5
- data/lib/sequel/plugins/class_table_inheritance.rb +71 -102
- data/lib/sequel/plugins/column_conflicts.rb +2 -2
- data/lib/sequel/plugins/column_select.rb +2 -2
- data/lib/sequel/plugins/composition.rb +15 -24
- data/lib/sequel/plugins/constraint_validations.rb +4 -3
- data/lib/sequel/plugins/csv_serializer.rb +13 -20
- data/lib/sequel/plugins/dataset_associations.rb +2 -2
- data/lib/sequel/plugins/def_dataset_method.rb +5 -5
- data/lib/sequel/plugins/defaults_setter.rb +1 -1
- data/lib/sequel/plugins/delay_add_association.rb +1 -1
- data/lib/sequel/plugins/finder.rb +16 -10
- data/lib/sequel/plugins/force_encoding.rb +1 -7
- data/lib/sequel/plugins/hook_class_methods.rb +4 -106
- data/lib/sequel/plugins/input_transformer.rb +10 -11
- data/lib/sequel/plugins/insert_returning_select.rb +1 -9
- data/lib/sequel/plugins/instance_filters.rb +5 -5
- data/lib/sequel/plugins/instance_hooks.rb +7 -52
- data/lib/sequel/plugins/inverted_subsets.rb +3 -1
- data/lib/sequel/plugins/json_serializer.rb +19 -19
- data/lib/sequel/plugins/lazy_attributes.rb +1 -10
- data/lib/sequel/plugins/list.rb +6 -6
- data/lib/sequel/plugins/many_through_many.rb +11 -8
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +3 -3
- data/lib/sequel/plugins/nested_attributes.rb +18 -31
- data/lib/sequel/plugins/optimistic_locking.rb +3 -3
- data/lib/sequel/plugins/pg_array_associations.rb +8 -2
- data/lib/sequel/plugins/pg_row.rb +2 -11
- data/lib/sequel/plugins/prepared_statements.rb +13 -66
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +7 -7
- data/lib/sequel/plugins/serialization.rb +15 -33
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +2 -8
- data/lib/sequel/plugins/single_table_inheritance.rb +10 -13
- data/lib/sequel/plugins/skip_create_refresh.rb +3 -3
- data/lib/sequel/plugins/static_cache.rb +8 -9
- data/lib/sequel/plugins/string_stripper.rb +3 -3
- data/lib/sequel/plugins/subclasses.rb +1 -1
- data/lib/sequel/plugins/subset_conditions.rb +2 -2
- data/lib/sequel/plugins/table_select.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
- data/lib/sequel/plugins/timestamps.rb +6 -7
- data/lib/sequel/plugins/touch.rb +4 -8
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +2 -2
- data/lib/sequel/plugins/unlimited_update.rb +1 -7
- data/lib/sequel/plugins/update_or_create.rb +3 -3
- data/lib/sequel/plugins/update_refresh.rb +3 -3
- data/lib/sequel/plugins/uuid.rb +7 -11
- data/lib/sequel/plugins/validation_class_methods.rb +10 -9
- data/lib/sequel/plugins/validation_contexts.rb +4 -4
- data/lib/sequel/plugins/validation_helpers.rb +26 -25
- data/lib/sequel/plugins/whitelist_security.rb +13 -9
- data/lib/sequel/plugins/xml_serializer.rb +24 -25
- data/lib/sequel/sql.rb +145 -276
- data/lib/sequel/timezones.rb +8 -22
- data/lib/sequel/version.rb +2 -2
- data/spec/adapter_spec.rb +1 -1
- data/spec/adapters/db2_spec.rb +2 -103
- data/spec/adapters/mssql_spec.rb +89 -68
- data/spec/adapters/mysql_spec.rb +101 -480
- data/spec/adapters/oracle_spec.rb +1 -9
- data/spec/adapters/postgres_spec.rb +312 -565
- data/spec/adapters/spec_helper.rb +12 -31
- data/spec/adapters/sqlanywhere_spec.rb +2 -77
- data/spec/adapters/sqlite_spec.rb +8 -146
- data/spec/bin_spec.rb +11 -16
- data/spec/core/connection_pool_spec.rb +173 -74
- data/spec/core/database_spec.rb +64 -244
- data/spec/core/dataset_spec.rb +81 -415
- data/spec/core/deprecated_spec.rb +3 -3
- data/spec/core/expression_filters_spec.rb +37 -144
- data/spec/core/mock_adapter_spec.rb +176 -4
- data/spec/core/object_graph_spec.rb +11 -60
- data/spec/core/placeholder_literalizer_spec.rb +1 -14
- data/spec/core/schema_generator_spec.rb +51 -40
- data/spec/core/schema_spec.rb +74 -77
- data/spec/core/spec_helper.rb +6 -24
- data/spec/core/version_spec.rb +1 -1
- data/spec/core_extensions_spec.rb +7 -83
- data/spec/core_model_spec.rb +2 -2
- data/spec/deprecation_helper.rb +2 -14
- data/spec/extensions/accessed_columns_spec.rb +1 -1
- data/spec/extensions/active_model_spec.rb +3 -3
- data/spec/extensions/after_initialize_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +2 -2
- data/spec/extensions/association_dependencies_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +4 -59
- data/spec/extensions/association_proxies_spec.rb +1 -1
- data/spec/extensions/auto_literal_strings_spec.rb +1 -12
- data/spec/extensions/auto_validations_spec.rb +1 -1
- data/spec/extensions/blacklist_security_spec.rb +1 -1
- data/spec/extensions/blank_spec.rb +1 -1
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/caching_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +35 -1086
- data/spec/extensions/column_conflicts_spec.rb +1 -1
- data/spec/extensions/column_select_spec.rb +4 -4
- data/spec/extensions/columns_introspection_spec.rb +1 -1
- data/spec/extensions/columns_updated_spec.rb +1 -1
- data/spec/extensions/composition_spec.rb +1 -7
- data/spec/extensions/connection_expiration_spec.rb +3 -3
- data/spec/extensions/connection_validator_spec.rb +3 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +1 -1
- data/spec/extensions/constraint_validations_spec.rb +1 -1
- data/spec/extensions/core_refinements_spec.rb +1 -3
- data/spec/extensions/csv_serializer_spec.rb +4 -9
- data/spec/extensions/current_datetime_timestamp_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +2 -1
- data/spec/extensions/dataset_source_alias_spec.rb +1 -1
- data/spec/extensions/date_arithmetic_spec.rb +3 -3
- data/spec/extensions/def_dataset_method_spec.rb +1 -1
- data/spec/extensions/defaults_setter_spec.rb +2 -2
- data/spec/extensions/delay_add_association_spec.rb +8 -9
- data/spec/extensions/dirty_spec.rb +1 -1
- data/spec/extensions/duplicate_columns_handler_spec.rb +1 -1
- data/spec/extensions/eager_each_spec.rb +2 -2
- data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
- data/spec/extensions/error_splitter_spec.rb +1 -1
- data/spec/extensions/error_sql_spec.rb +1 -1
- data/spec/extensions/eval_inspect_spec.rb +1 -1
- data/spec/extensions/finder_spec.rb +1 -1
- data/spec/extensions/force_encoding_spec.rb +2 -5
- data/spec/extensions/freeze_datasets_spec.rb +1 -1
- data/spec/extensions/graph_each_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +1 -194
- data/spec/extensions/identifier_mangling_spec.rb +17 -170
- data/spec/extensions/implicit_subquery_spec.rb +1 -5
- data/spec/extensions/inflector_spec.rb +1 -1
- data/spec/extensions/input_transformer_spec.rb +7 -2
- data/spec/extensions/insert_returning_select_spec.rb +1 -1
- data/spec/extensions/instance_filters_spec.rb +1 -1
- data/spec/extensions/instance_hooks_spec.rb +1 -95
- data/spec/extensions/inverted_subsets_spec.rb +1 -1
- data/spec/extensions/json_serializer_spec.rb +1 -1
- data/spec/extensions/lazy_attributes_spec.rb +1 -7
- data/spec/extensions/list_spec.rb +1 -1
- data/spec/extensions/looser_typecasting_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +1 -1
- data/spec/extensions/migration_spec.rb +2 -2
- data/spec/extensions/modification_detection_spec.rb +1 -1
- data/spec/extensions/mssql_optimistic_locking_spec.rb +1 -1
- data/spec/extensions/named_timezones_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +1 -29
- data/spec/extensions/null_dataset_spec.rb +1 -11
- data/spec/extensions/optimistic_locking_spec.rb +1 -1
- data/spec/extensions/pagination_spec.rb +1 -1
- data/spec/extensions/pg_array_associations_spec.rb +4 -1
- data/spec/extensions/pg_array_ops_spec.rb +1 -1
- data/spec/extensions/pg_array_spec.rb +3 -48
- data/spec/extensions/pg_enum_spec.rb +1 -1
- data/spec/extensions/pg_hstore_ops_spec.rb +1 -1
- data/spec/extensions/pg_hstore_spec.rb +23 -32
- data/spec/extensions/pg_inet_ops_spec.rb +1 -1
- data/spec/extensions/pg_inet_spec.rb +1 -14
- data/spec/extensions/pg_interval_spec.rb +3 -13
- data/spec/extensions/pg_json_ops_spec.rb +1 -1
- data/spec/extensions/pg_json_spec.rb +1 -13
- data/spec/extensions/pg_loose_count_spec.rb +1 -1
- data/spec/extensions/pg_range_ops_spec.rb +1 -1
- data/spec/extensions/pg_range_spec.rb +3 -88
- data/spec/extensions/pg_row_ops_spec.rb +1 -1
- data/spec/extensions/pg_row_plugin_spec.rb +1 -1
- data/spec/extensions/pg_row_spec.rb +1 -44
- data/spec/extensions/pg_static_cache_updater_spec.rb +1 -1
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/prepared_statements_spec.rb +13 -48
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +1 -12
- data/spec/extensions/rcte_tree_spec.rb +1 -1
- data/spec/extensions/round_timestamps_spec.rb +1 -5
- data/spec/extensions/s_spec.rb +1 -1
- data/spec/extensions/schema_caching_spec.rb +1 -1
- data/spec/extensions/schema_dumper_spec.rb +1 -1
- data/spec/extensions/select_remove_spec.rb +1 -1
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +1 -1
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
- data/spec/extensions/serialization_spec.rb +2 -14
- data/spec/extensions/server_block_spec.rb +1 -1
- data/spec/extensions/server_logging_spec.rb +2 -2
- data/spec/extensions/sharding_spec.rb +1 -1
- data/spec/extensions/shared_caching_spec.rb +1 -28
- data/spec/extensions/single_table_inheritance_spec.rb +2 -5
- data/spec/extensions/singular_table_names_spec.rb +1 -1
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +5 -27
- data/spec/extensions/split_array_nil_spec.rb +1 -1
- data/spec/extensions/split_values_spec.rb +1 -1
- data/spec/extensions/sql_comments_spec.rb +1 -1
- data/spec/extensions/sql_expr_spec.rb +1 -1
- data/spec/extensions/static_cache_spec.rb +1 -1
- data/spec/extensions/string_agg_spec.rb +2 -2
- data/spec/extensions/string_date_time_spec.rb +1 -1
- data/spec/extensions/string_stripper_spec.rb +1 -1
- data/spec/extensions/subclasses_spec.rb +1 -1
- data/spec/extensions/subset_conditions_spec.rb +1 -1
- data/spec/extensions/symbol_aref_refinement_spec.rb +1 -1
- data/spec/extensions/symbol_as_refinement_spec.rb +1 -1
- data/spec/extensions/table_select_spec.rb +4 -4
- data/spec/extensions/tactical_eager_loading_spec.rb +1 -6
- data/spec/extensions/thread_local_timezones_spec.rb +1 -1
- data/spec/extensions/timestamps_spec.rb +3 -3
- data/spec/extensions/to_dot_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +1 -1
- data/spec/extensions/tree_spec.rb +1 -1
- data/spec/extensions/typecast_on_load_spec.rb +1 -1
- data/spec/extensions/unlimited_update_spec.rb +1 -1
- data/spec/extensions/update_or_create_spec.rb +1 -1
- data/spec/extensions/update_primary_key_spec.rb +4 -3
- data/spec/extensions/update_refresh_spec.rb +1 -1
- data/spec/extensions/uuid_spec.rb +10 -12
- data/spec/extensions/validate_associated_spec.rb +1 -1
- data/spec/extensions/validation_class_methods_spec.rb +3 -3
- data/spec/extensions/validation_contexts_spec.rb +1 -1
- data/spec/extensions/validation_helpers_spec.rb +10 -44
- data/spec/extensions/whitelist_security_spec.rb +5 -5
- data/spec/extensions/xml_serializer_spec.rb +3 -3
- data/spec/guards_helper.rb +2 -1
- data/spec/integration/associations_test.rb +1 -23
- data/spec/integration/database_test.rb +7 -7
- data/spec/integration/dataset_test.rb +5 -47
- data/spec/integration/eager_loader_test.rb +1 -1
- data/spec/integration/migrator_test.rb +1 -1
- data/spec/integration/model_test.rb +4 -82
- data/spec/integration/plugin_test.rb +6 -22
- data/spec/integration/prepared_statement_test.rb +8 -88
- data/spec/integration/schema_test.rb +6 -6
- data/spec/integration/spec_helper.rb +13 -21
- data/spec/integration/timezone_test.rb +5 -5
- data/spec/integration/transaction_test.rb +3 -55
- data/spec/integration/type_test.rb +9 -9
- data/spec/model/association_reflection_spec.rb +24 -9
- data/spec/model/associations_spec.rb +124 -303
- data/spec/model/base_spec.rb +18 -137
- data/spec/model/class_dataset_methods_spec.rb +2 -20
- data/spec/model/dataset_methods_spec.rb +1 -20
- data/spec/model/eager_loading_spec.rb +17 -11
- data/spec/model/hooks_spec.rb +5 -300
- data/spec/model/inflector_spec.rb +1 -1
- data/spec/model/model_spec.rb +15 -320
- data/spec/model/plugins_spec.rb +2 -16
- data/spec/model/record_spec.rb +29 -121
- data/spec/model/spec_helper.rb +5 -15
- data/spec/model/validations_spec.rb +1 -1
- data/spec/sequel_warning.rb +1 -12
- metadata +8 -64
- data/doc/active_record.rdoc +0 -927
- data/lib/sequel/adapters/cubrid.rb +0 -160
- data/lib/sequel/adapters/do.rb +0 -166
- data/lib/sequel/adapters/do/mysql.rb +0 -69
- data/lib/sequel/adapters/do/postgres.rb +0 -46
- data/lib/sequel/adapters/do/sqlite3.rb +0 -41
- data/lib/sequel/adapters/jdbc/as400.rb +0 -92
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -65
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -37
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -34
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -34
- data/lib/sequel/adapters/odbc/progress.rb +0 -12
- data/lib/sequel/adapters/shared/cubrid.rb +0 -245
- data/lib/sequel/adapters/shared/firebird.rb +0 -261
- data/lib/sequel/adapters/shared/informix.rb +0 -63
- data/lib/sequel/adapters/shared/progress.rb +0 -40
- data/lib/sequel/adapters/swift.rb +0 -169
- data/lib/sequel/adapters/swift/mysql.rb +0 -50
- data/lib/sequel/adapters/swift/postgres.rb +0 -49
- data/lib/sequel/adapters/swift/sqlite.rb +0 -48
- data/lib/sequel/adapters/utils/pg_types.rb +0 -4
- data/lib/sequel/dataset/mutation.rb +0 -98
- data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +0 -117
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -8
- data/lib/sequel/extensions/filter_having.rb +0 -65
- data/lib/sequel/extensions/hash_aliases.rb +0 -51
- data/lib/sequel/extensions/meta_def.rb +0 -37
- data/lib/sequel/extensions/query_literals.rb +0 -86
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -26
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -133
- data/lib/sequel/extensions/set_overrides.rb +0 -82
- data/lib/sequel/no_core_ext.rb +0 -4
- data/lib/sequel/plugins/association_autoreloading.rb +0 -11
- data/lib/sequel/plugins/identifier_columns.rb +0 -49
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -11
- data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -90
- data/lib/sequel/plugins/prepared_statements_associations.rb +0 -137
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -71
- data/lib/sequel/plugins/schema.rb +0 -84
- data/lib/sequel/plugins/scissors.rb +0 -37
- data/spec/core/dataset_mutation_spec.rb +0 -253
- data/spec/extensions/_deprecated_identifier_mangling_spec.rb +0 -314
- data/spec/extensions/before_after_save_spec.rb +0 -40
- data/spec/extensions/filter_having_spec.rb +0 -42
- data/spec/extensions/from_block_spec.rb +0 -21
- data/spec/extensions/hash_aliases_spec.rb +0 -26
- data/spec/extensions/identifier_columns_spec.rb +0 -19
- data/spec/extensions/meta_def_spec.rb +0 -35
- data/spec/extensions/no_auto_literal_strings_spec.rb +0 -69
- data/spec/extensions/pg_typecast_on_load_spec.rb +0 -70
- data/spec/extensions/prepared_statements_associations_spec.rb +0 -212
- data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -40
- data/spec/extensions/query_literals_spec.rb +0 -185
- data/spec/extensions/schema_spec.rb +0 -123
- data/spec/extensions/scissors_spec.rb +0 -27
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -118
- data/spec/extensions/set_overrides_spec.rb +0 -75
@@ -23,15 +23,15 @@ module Sequel
|
|
23
23
|
#
|
24
24
|
# You can provide options to control the XML output:
|
25
25
|
#
|
26
|
-
# puts album.to_xml(:
|
27
|
-
# puts album.to_xml(:
|
26
|
+
# puts album.to_xml(only: :name)
|
27
|
+
# puts album.to_xml(except: [:id, :artist_id])
|
28
28
|
# # Output:
|
29
29
|
# # <?xml version="1.0"?>
|
30
30
|
# # <album>
|
31
31
|
# # <name>RF</name>
|
32
32
|
# # </album>
|
33
33
|
#
|
34
|
-
# album.to_xml(:
|
34
|
+
# album.to_xml(include: :artist)
|
35
35
|
# # Output:
|
36
36
|
# # <?xml version="1.0"?>
|
37
37
|
# # <album>
|
@@ -47,7 +47,7 @@ module Sequel
|
|
47
47
|
# You can use a hash value with <tt>:include</tt> to pass options
|
48
48
|
# to associations:
|
49
49
|
#
|
50
|
-
# album.to_xml(:
|
50
|
+
# album.to_xml(include: {artist: {only: :name}})
|
51
51
|
# # Output:
|
52
52
|
# # <?xml version="1.0"?>
|
53
53
|
# # <album>
|
@@ -63,12 +63,12 @@ module Sequel
|
|
63
63
|
# of which return all objects in the dataset:
|
64
64
|
#
|
65
65
|
# Album.to_xml
|
66
|
-
# Album.where(:
|
66
|
+
# Album.where(artist_id: 1).to_xml(include: :tags)
|
67
67
|
#
|
68
68
|
# If you have an existing array of model instances you want to convert to
|
69
69
|
# XML, you can call the class to_xml method with the :array option:
|
70
70
|
#
|
71
|
-
# Album.to_xml(:
|
71
|
+
# Album.to_xml(array: [Album[1], Album[2]])
|
72
72
|
#
|
73
73
|
# In addition to creating XML, this plugin also enables Sequel::Model
|
74
74
|
# classes to create instances directly from XML using the from_xml class
|
@@ -80,7 +80,7 @@ module Sequel
|
|
80
80
|
# The array_from_xml class method exists to parse arrays of model instances
|
81
81
|
# from xml:
|
82
82
|
#
|
83
|
-
# xml = Album.where(:
|
83
|
+
# xml = Album.where(artist_id: 1).to_xml
|
84
84
|
# albums = Album.array_from_xml(xml)
|
85
85
|
#
|
86
86
|
# These does not necessarily round trip, since doing so would let users
|
@@ -89,7 +89,7 @@ module Sequel
|
|
89
89
|
# fields, you can use the :fields option, which will call set_fields with
|
90
90
|
# the given fields:
|
91
91
|
#
|
92
|
-
# Album.from_xml(album.to_xml, :
|
92
|
+
# Album.from_xml(album.to_xml, fields: %w'id name')
|
93
93
|
#
|
94
94
|
# If you want to update an existing instance, you can use the from_xml
|
95
95
|
# instance method:
|
@@ -99,11 +99,11 @@ module Sequel
|
|
99
99
|
# Both of these allow creation of cached associated objects, if you provide
|
100
100
|
# the :associations option:
|
101
101
|
#
|
102
|
-
# album.from_xml(xml, :
|
102
|
+
# album.from_xml(xml, associations: :artist)
|
103
103
|
#
|
104
104
|
# You can even provide options when setting up the associated objects:
|
105
105
|
#
|
106
|
-
# album.from_xml(xml, :
|
106
|
+
# album.from_xml(xml, associations: {artist: {fields: %w'id name', associations: :tags}})
|
107
107
|
#
|
108
108
|
# Usage:
|
109
109
|
#
|
@@ -115,17 +115,17 @@ module Sequel
|
|
115
115
|
module XmlSerializer
|
116
116
|
module ClassMethods
|
117
117
|
# Proc that camelizes the input string, used for the :camelize option
|
118
|
-
CAMELIZE =
|
118
|
+
CAMELIZE = :camelize.to_proc
|
119
119
|
|
120
120
|
# Proc that dasherizes the input string, used for the :dasherize option
|
121
|
-
DASHERIZE =
|
121
|
+
DASHERIZE = :dasherize.to_proc
|
122
122
|
|
123
123
|
# Proc that returns the input string as is, used if
|
124
124
|
# no :name_proc, :dasherize, or :camelize option is used.
|
125
125
|
IDENTITY = proc{|s| s}
|
126
126
|
|
127
127
|
# Proc that underscores the input string, used for the :underscore option
|
128
|
-
UNDERSCORE =
|
128
|
+
UNDERSCORE = :underscore.to_proc
|
129
129
|
|
130
130
|
# Return an array of instances of this class based on
|
131
131
|
# the provided XML.
|
@@ -137,21 +137,20 @@ module Sequel
|
|
137
137
|
node.children.reject{|c| c.is_a?(Nokogiri::XML::Text)}.map{|c| from_xml_node(c, opts)}
|
138
138
|
end
|
139
139
|
|
140
|
-
# Return an instance of this class based on the provided
|
141
|
-
# XML.
|
140
|
+
# Return an instance of this class based on the provided XML.
|
142
141
|
def from_xml(xml, opts=OPTS)
|
143
142
|
from_xml_node(Nokogiri::XML(xml).children.first, opts)
|
144
143
|
end
|
145
144
|
|
146
145
|
# Return an instance of this class based on the given
|
147
146
|
# XML node, which should be Nokogiri::XML::Node instance.
|
148
|
-
# This should
|
147
|
+
# This should not be used directly by user code.
|
149
148
|
def from_xml_node(parent, opts=OPTS)
|
150
149
|
new.from_xml_node(parent, opts)
|
151
150
|
end
|
152
151
|
|
153
152
|
# Return an appropriate Nokogiri::XML::Builder instance
|
154
|
-
# used to create the XML. This should
|
153
|
+
# used to create the XML. This should not be used
|
155
154
|
# directly by user code.
|
156
155
|
def xml_builder(opts=OPTS)
|
157
156
|
if opts[:builder]
|
@@ -169,7 +168,7 @@ module Sequel
|
|
169
168
|
|
170
169
|
# Return a proc (or any other object that responds to []),
|
171
170
|
# used for formatting XML tag names when serializing to XML.
|
172
|
-
# This should
|
171
|
+
# This should not be used directly by user code.
|
173
172
|
def xml_deserialize_name_proc(opts=OPTS)
|
174
173
|
if opts[:name_proc]
|
175
174
|
opts[:name_proc]
|
@@ -182,7 +181,7 @@ module Sequel
|
|
182
181
|
|
183
182
|
# Return a proc (or any other object that responds to []),
|
184
183
|
# used for formatting XML tag names when serializing to XML.
|
185
|
-
# This should
|
184
|
+
# This should not be used directly by user code.
|
186
185
|
def xml_serialize_name_proc(opts=OPTS)
|
187
186
|
pr = if opts[:name_proc]
|
188
187
|
opts[:name_proc]
|
@@ -343,7 +342,7 @@ module Sequel
|
|
343
342
|
|
344
343
|
name_proc = model.xml_serialize_name_proc(opts)
|
345
344
|
x = model.xml_builder(opts)
|
346
|
-
x.
|
345
|
+
x.public_send(name_proc[opts.fetch(:root_name, model.send(:underscore, model.name).gsub('/', '__')).to_s]) do |x1|
|
347
346
|
cols.each do |c|
|
348
347
|
attrs = {}
|
349
348
|
if types
|
@@ -353,7 +352,7 @@ module Sequel
|
|
353
352
|
if v.nil?
|
354
353
|
attrs[:nil] = ''
|
355
354
|
end
|
356
|
-
x1.
|
355
|
+
x1.public_send(name_proc[c.to_s], v, attrs)
|
357
356
|
end
|
358
357
|
if inc.is_a?(Hash)
|
359
358
|
inc.each{|k, v| to_xml_include(x1, k, v)}
|
@@ -371,15 +370,15 @@ module Sequel
|
|
371
370
|
# the xml.
|
372
371
|
def to_xml_include(node, i, opts=OPTS)
|
373
372
|
name_proc = model.xml_serialize_name_proc(opts)
|
374
|
-
objs =
|
373
|
+
objs = public_send(i)
|
375
374
|
if objs.is_a?(Array) && objs.all?{|x| x.is_a?(Sequel::Model)}
|
376
|
-
node.
|
375
|
+
node.public_send(name_proc[i.to_s]) do |x2|
|
377
376
|
objs.each{|obj| obj.to_xml(opts.merge(:builder=>x2))}
|
378
377
|
end
|
379
378
|
elsif objs.is_a?(Sequel::Model)
|
380
379
|
objs.to_xml(opts.merge(:builder=>node, :root_name=>i))
|
381
380
|
else
|
382
|
-
node.
|
381
|
+
node.public_send(name_proc[i.to_s], objs)
|
383
382
|
end
|
384
383
|
end
|
385
384
|
end
|
@@ -399,7 +398,7 @@ module Sequel
|
|
399
398
|
else
|
400
399
|
all
|
401
400
|
end
|
402
|
-
x.
|
401
|
+
x.public_send(name_proc[opts.fetch(:array_root_name, model.send(:pluralize, model.send(:underscore, model.name))).to_s]) do |x1|
|
403
402
|
array.each do |obj|
|
404
403
|
obj.to_xml(opts.merge(:builder=>x1))
|
405
404
|
end
|
data/lib/sequel/sql.rb
CHANGED
@@ -1,42 +1,16 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
3
|
module Sequel
|
4
|
-
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
# Remove all but the most basic instance methods from the class. A separate
|
15
|
-
# method so that it can be called again if necessary if you load libraries
|
16
|
-
# after Sequel that add instance methods to +Object+.
|
17
|
-
def self.remove_methods!
|
18
|
-
((private_instance_methods + instance_methods) - KEEP_METHODS).each{|m| undef_method(m)}
|
19
|
-
end
|
20
|
-
remove_methods!
|
21
|
-
end
|
22
|
-
# :nocov:
|
23
|
-
else
|
24
|
-
# If on 1.9, create a <tt>Sequel::BasicObject</tt> class that is just like the
|
25
|
-
# default +BasicObject+ class, except that missing constants are resolved in
|
26
|
-
# +Object+. This allows the virtual row support to work with classes
|
27
|
-
# without prefixing them with ::, such as:
|
28
|
-
#
|
29
|
-
# DB[:bonds].where{maturity_date > Time.now}
|
30
|
-
class BasicObject < ::BasicObject
|
31
|
-
# Lookup missing constants in <tt>::Object</tt>
|
32
|
-
def self.const_missing(name)
|
33
|
-
::Object.const_get(name)
|
34
|
-
end
|
35
|
-
|
36
|
-
# No-op method on ruby 1.9, which has a real +BasicObject+ class.
|
37
|
-
def self.remove_methods!
|
38
|
-
Sequel::Deprecation.deprecate("Sequel::BasicObject#remove_methods!", "It has no effect, so stop calling it")
|
39
|
-
end
|
4
|
+
# The <tt>Sequel::BasicObject</tt> class is just like the
|
5
|
+
# default +BasicObject+ class, except that missing constants are resolved in
|
6
|
+
# +Object+. This allows the virtual row support to work with classes
|
7
|
+
# without prefixing them with ::, such as:
|
8
|
+
#
|
9
|
+
# DB[:bonds].where{maturity_date > Time.now}
|
10
|
+
class BasicObject < ::BasicObject
|
11
|
+
# Lookup missing constants in <tt>::Object</tt>
|
12
|
+
def self.const_missing(name)
|
13
|
+
::Object.const_get(name)
|
40
14
|
end
|
41
15
|
end
|
42
16
|
|
@@ -52,15 +26,17 @@ module Sequel
|
|
52
26
|
# Set the date used for SQLTime instances.
|
53
27
|
attr_writer :date
|
54
28
|
|
29
|
+
# use the date explicitly set, or the current date if there is not a
|
30
|
+
# date set.
|
55
31
|
def date
|
56
32
|
@date || now
|
57
33
|
end
|
58
34
|
|
59
|
-
# Create a new SQLTime instance given an hour, minute, and
|
35
|
+
# Create a new SQLTime instance given an hour, minute, second, and usec.
|
60
36
|
def create(hour, minute, second, usec = 0)
|
61
37
|
t = date
|
62
38
|
meth = Sequel.application_timezone == :utc ? :utc : :local
|
63
|
-
|
39
|
+
public_send(meth, t.year, t.month, t.day, hour, minute, second, usec)
|
64
40
|
end
|
65
41
|
end
|
66
42
|
|
@@ -82,18 +58,11 @@ module Sequel
|
|
82
58
|
end
|
83
59
|
|
84
60
|
# The SQL module holds classes whose instances represent SQL fragments.
|
85
|
-
# It also holds modules that are
|
86
|
-
# make Sequel a friendly DSL.
|
61
|
+
# It also holds modules that are used by these classes.
|
87
62
|
module SQL
|
88
|
-
|
89
|
-
### Parent Classes ###
|
90
|
-
|
91
|
-
# Classes/Modules aren't in alphabetical order due to the fact that
|
92
|
-
# some reference constants defined in others at load time.
|
93
|
-
|
94
63
|
# Base class for all SQL expression objects.
|
95
64
|
class Expression
|
96
|
-
@comparison_attrs = []
|
65
|
+
@comparison_attrs = [].freeze
|
97
66
|
|
98
67
|
class << self
|
99
68
|
# All attributes used for equality and hash methods.
|
@@ -115,7 +84,7 @@ module Sequel
|
|
115
84
|
subclass.instance_variable_set(:@comparison_attrs, comparison_attrs.dup)
|
116
85
|
end
|
117
86
|
|
118
|
-
|
87
|
+
private
|
119
88
|
|
120
89
|
# Create a to_s instance method that takes a dataset, and calls
|
121
90
|
# the method provided on the dataset with args as the argument (self by default).
|
@@ -125,9 +94,17 @@ module Sequel
|
|
125
94
|
# arbitrary code execution.
|
126
95
|
def to_s_method(meth, args=:self) # :nodoc:
|
127
96
|
class_eval("def to_s_append(ds, sql) ds.#{meth}_append(sql, #{args}) end", __FILE__, __LINE__)
|
97
|
+
@comparison_attrs.freeze
|
128
98
|
end
|
129
99
|
end
|
130
100
|
|
101
|
+
# Make clone/dup return self, since Expression objects are supposed to
|
102
|
+
# be frozen value objects
|
103
|
+
def clone
|
104
|
+
self
|
105
|
+
end
|
106
|
+
alias dup clone
|
107
|
+
|
131
108
|
# Alias of <tt>eql?</tt>
|
132
109
|
def ==(other)
|
133
110
|
eql?(other)
|
@@ -136,35 +113,21 @@ module Sequel
|
|
136
113
|
# Returns true if the receiver is the same expression as the
|
137
114
|
# the +other+ expression.
|
138
115
|
def eql?(other)
|
139
|
-
other.is_a?(self.class) && !self.class.comparison_attrs.find{|a|
|
116
|
+
other.is_a?(self.class) && !self.class.comparison_attrs.find{|a| public_send(a) != other.public_send(a)}
|
140
117
|
end
|
141
118
|
|
142
119
|
# Make sure that the hash value is the same if the attributes are the same.
|
143
120
|
def hash
|
144
|
-
([self.class] + self.class.comparison_attrs.map{|x|
|
121
|
+
([self.class] + self.class.comparison_attrs.map{|x| public_send(x)}).hash
|
145
122
|
end
|
146
123
|
|
147
124
|
# Show the class name and instance variables for the object.
|
148
125
|
def inspect
|
149
126
|
"#<#{self.class} #{instance_variables.map{|iv| "#{iv}=>#{instance_variable_get(iv).inspect}"}.join(', ')}>"
|
150
127
|
end
|
151
|
-
|
152
|
-
# Returns +self+, because <tt>SQL::Expression</tt> already acts like +LiteralString+.
|
153
|
-
def lit
|
154
|
-
Sequel::Deprecation.deprecate("Sequel::SQL::Expression#lit", "This method returns self, so just use the receiver")
|
155
|
-
self
|
156
|
-
end
|
157
|
-
|
158
|
-
# Alias of +to_s+
|
159
|
-
def sql_literal(ds)
|
160
|
-
Sequel::Deprecation.deprecate("Sequel::SQL::Expression#sql_literal", "Call Sequel::Dataset#literal with the expression instead")
|
161
|
-
s = String.new
|
162
|
-
to_s_append(ds, s)
|
163
|
-
s
|
164
|
-
end
|
165
128
|
end
|
166
129
|
|
167
|
-
# Represents a
|
130
|
+
# Represents a SQL expression, with a given operator and one
|
168
131
|
# or more attributes (which may also be ComplexExpressions, forming
|
169
132
|
# a tree). This class is the backbone of Sequel's ruby expression DSL.
|
170
133
|
#
|
@@ -179,49 +142,49 @@ module Sequel
|
|
179
142
|
:'NOT LIKE' => :LIKE, :~ => :'!~', :'!~' => :~, :IN => :'NOT IN',
|
180
143
|
:'NOT IN' => :IN, :IS => :'IS NOT', :'IS NOT' => :IS, :'~*' => :'!~*',
|
181
144
|
:'!~*' => :'~*', :NOT => :NOOP, :NOOP => :NOT, :ILIKE => :'NOT ILIKE',
|
182
|
-
:'NOT ILIKE'=>:ILIKE}
|
145
|
+
:'NOT ILIKE'=>:ILIKE}.freeze
|
183
146
|
|
184
147
|
# Standard mathematical operators used in +NumericMethods+
|
185
|
-
MATHEMATICAL_OPERATORS = [:+, :-, :/, :*, :**]
|
148
|
+
MATHEMATICAL_OPERATORS = [:+, :-, :/, :*, :**].freeze
|
186
149
|
|
187
150
|
# Bitwise mathematical operators used in +BitwiseMethods+
|
188
|
-
BITWISE_OPERATORS = [:&, :|, :^, :<<, :>>, :%]
|
151
|
+
BITWISE_OPERATORS = [:&, :|, :^, :<<, :>>, :%].freeze
|
189
152
|
|
190
153
|
# Operators that check for equality
|
191
|
-
EQUALITY_OPERATORS = [:'=', :'!=']
|
154
|
+
EQUALITY_OPERATORS = [:'=', :'!='].freeze
|
192
155
|
|
193
156
|
# Inequality operators used in +InequalityMethods+
|
194
|
-
INEQUALITY_OPERATORS = [:<, :>, :<=, :>=]
|
157
|
+
INEQUALITY_OPERATORS = [:<, :>, :<=, :>=].freeze
|
195
158
|
|
196
159
|
# Hash of ruby operator symbols to SQL operators, used in +BooleanMethods+
|
197
|
-
BOOLEAN_OPERATOR_METHODS = {:& => :AND, :| =>:OR}
|
160
|
+
BOOLEAN_OPERATOR_METHODS = {:& => :AND, :| =>:OR}.freeze
|
198
161
|
|
199
162
|
# Operators that use IN/NOT IN for inclusion/exclusion
|
200
|
-
IN_OPERATORS = [:IN, :'NOT IN']
|
163
|
+
IN_OPERATORS = [:IN, :'NOT IN'].freeze
|
201
164
|
|
202
165
|
# Operators that use IS, used for special casing to override literal true/false values
|
203
|
-
IS_OPERATORS = [:IS, :'IS NOT']
|
166
|
+
IS_OPERATORS = [:IS, :'IS NOT'].freeze
|
204
167
|
|
205
168
|
# Operators that do pattern matching via regular expressions
|
206
|
-
REGEXP_OPERATORS = [:~, :'!~', :'~*', :'!~*']
|
169
|
+
REGEXP_OPERATORS = [:~, :'!~', :'~*', :'!~*'].freeze
|
207
170
|
|
208
171
|
# Operators that do pattern matching via LIKE
|
209
|
-
LIKE_OPERATORS = [:LIKE, :'NOT LIKE', :ILIKE, :'NOT ILIKE']
|
172
|
+
LIKE_OPERATORS = [:LIKE, :'NOT LIKE', :ILIKE, :'NOT ILIKE'].freeze
|
210
173
|
|
211
174
|
# Operator symbols that take exactly two arguments
|
212
|
-
TWO_ARITY_OPERATORS = EQUALITY_OPERATORS + INEQUALITY_OPERATORS + IS_OPERATORS + IN_OPERATORS + REGEXP_OPERATORS + LIKE_OPERATORS + [:**]
|
175
|
+
TWO_ARITY_OPERATORS = (EQUALITY_OPERATORS + INEQUALITY_OPERATORS + IS_OPERATORS + IN_OPERATORS + REGEXP_OPERATORS + LIKE_OPERATORS + [:**]).freeze
|
213
176
|
|
214
177
|
# Operator symbols that take one or more arguments
|
215
|
-
N_ARITY_OPERATORS = [:AND, :OR, :'||'] + MATHEMATICAL_OPERATORS + BITWISE_OPERATORS - [:**]
|
178
|
+
N_ARITY_OPERATORS = ([:AND, :OR, :'||'] + MATHEMATICAL_OPERATORS + BITWISE_OPERATORS - [:**]).freeze
|
216
179
|
|
217
180
|
# Operator symbols that are associative
|
218
|
-
ASSOCIATIVE_OPERATORS = [:AND, :OR, :'||', :+, :*, :&, :|]
|
181
|
+
ASSOCIATIVE_OPERATORS = [:AND, :OR, :'||', :+, :*, :&, :|].freeze
|
219
182
|
|
220
183
|
# Operator symbols that take only a single argument
|
221
|
-
ONE_ARITY_OPERATORS = [:NOT, :NOOP, :'B~']
|
184
|
+
ONE_ARITY_OPERATORS = [:NOT, :NOOP, :'B~'].freeze
|
222
185
|
|
223
186
|
# Custom expressions that may have different syntax on different databases
|
224
|
-
CUSTOM_EXPRESSIONS = [:extract]
|
187
|
+
CUSTOM_EXPRESSIONS = [:extract].freeze
|
225
188
|
|
226
189
|
# The operator symbol for this object
|
227
190
|
attr_reader :op
|
@@ -272,8 +235,6 @@ module Sequel
|
|
272
235
|
class GenericExpression < Expression
|
273
236
|
end
|
274
237
|
|
275
|
-
### Modules ###
|
276
|
-
|
277
238
|
# Includes an +as+ method that creates an SQL alias.
|
278
239
|
module AliasMethods
|
279
240
|
# Create an SQL alias (+AliasedExpression+) of the receiving column or expression to the given alias.
|
@@ -302,25 +263,24 @@ module Sequel
|
|
302
263
|
|
303
264
|
# Do the bitwise compliment of the self
|
304
265
|
#
|
305
|
-
#
|
266
|
+
# ~(Sequel[:a].sql_number) # ~"a"
|
306
267
|
def ~
|
307
268
|
NumericExpression.new(:'B~', self)
|
308
269
|
end
|
309
270
|
end
|
310
271
|
|
311
272
|
# This module includes the boolean/logical AND (&), OR (|) and NOT (~) operators
|
312
|
-
# that are defined on objects that can be used in a boolean context in SQL
|
313
|
-
# (+Symbol+, +LiteralString+, and <tt>SQL::GenericExpression</tt>).
|
273
|
+
# that are defined on objects that can be used in a boolean context in SQL.
|
314
274
|
#
|
315
|
-
# :a & :b # "a" AND "b"
|
316
|
-
# :a | :b # "a" OR "b"
|
317
|
-
#
|
275
|
+
# Sequel[:a] & Sequel[:b] # "a" AND "b"
|
276
|
+
# Sequel[:a] | Sequel[:b] # "a" OR "b"
|
277
|
+
# ~Sequel[:a] # NOT "a"
|
318
278
|
#
|
319
279
|
# One exception to this is when a NumericExpression or Integer is the argument
|
320
280
|
# to & or |, in which case a bitwise method will be used:
|
321
281
|
#
|
322
|
-
# :a & 1 # "a" & 1
|
323
|
-
# :a | (:b + 1) # "a" | ("b" + 1)
|
282
|
+
# Sequel[:a] & 1 # "a" & 1
|
283
|
+
# Sequel[:a] | (Sequel[:b] + 1) # "a" | ("b" + 1)
|
324
284
|
module BooleanMethods
|
325
285
|
ComplexExpression::BOOLEAN_OPERATOR_METHODS.each do |m, o|
|
326
286
|
module_eval(<<-END, __FILE__, __LINE__+1)
|
@@ -337,14 +297,14 @@ module Sequel
|
|
337
297
|
|
338
298
|
# Create a new BooleanExpression with NOT, representing the inversion of whatever self represents.
|
339
299
|
#
|
340
|
-
#
|
300
|
+
# ~Sequel[:a] # NOT :a
|
341
301
|
def ~
|
342
302
|
BooleanExpression.invert(self)
|
343
303
|
end
|
344
304
|
end
|
345
305
|
|
346
|
-
# These methods
|
347
|
-
#
|
306
|
+
# These methods make it easier to create Sequel expressions without
|
307
|
+
# using the core extensions.
|
348
308
|
module Builders
|
349
309
|
# Create an SQL::AliasedExpression for the given expression and alias.
|
350
310
|
#
|
@@ -362,7 +322,7 @@ module Sequel
|
|
362
322
|
# are ordered after other values).
|
363
323
|
#
|
364
324
|
# Sequel.asc(:a) # a ASC
|
365
|
-
# Sequel.asc(:b, :
|
325
|
+
# Sequel.asc(:b, nulls: :last) # b ASC NULLS LAST
|
366
326
|
def asc(arg, opts=OPTS)
|
367
327
|
SQL::OrderedExpression.new(arg, false, opts)
|
368
328
|
end
|
@@ -380,8 +340,8 @@ module Sequel
|
|
380
340
|
|
381
341
|
# Return an <tt>SQL::CaseExpression</tt> created with the given arguments.
|
382
342
|
#
|
383
|
-
# Sequel.case([[{:
|
384
|
-
# Sequel.case({:
|
343
|
+
# Sequel.case([[{a: [2,3]}, 1]], 0) # SQL: CASE WHEN a IN (2, 3) THEN 1 ELSE 0 END
|
344
|
+
# Sequel.case({a: 1}, 0, :b) # SQL: CASE b WHEN a THEN 1 ELSE 0 END
|
385
345
|
def case(*args)
|
386
346
|
SQL::CaseExpression.new(*args)
|
387
347
|
end
|
@@ -428,8 +388,8 @@ module Sequel
|
|
428
388
|
# nested structures.
|
429
389
|
#
|
430
390
|
# Sequel.deep_qualify(:table, :column) # "table"."column"
|
431
|
-
# Sequel.deep_qualify(:table, Sequel
|
432
|
-
# Sequel.deep_qualify(:table, Sequel.like(
|
391
|
+
# Sequel.deep_qualify(:table, Sequel[:column] + 1) # "table"."column" + 1
|
392
|
+
# Sequel.deep_qualify(:table, Sequel[:a].like('b')) # "table"."a" LIKE 'b' ESCAPE '\'
|
433
393
|
def deep_qualify(qualifier, expr)
|
434
394
|
Sequel::Qualifier.new(qualifier).transform(expr)
|
435
395
|
end
|
@@ -463,7 +423,7 @@ module Sequel
|
|
463
423
|
# are ordered after other values).
|
464
424
|
#
|
465
425
|
# Sequel.desc(:a) # b DESC
|
466
|
-
# Sequel.desc(:b, :
|
426
|
+
# Sequel.desc(:b, nulls: :first) # b DESC NULLS FIRST
|
467
427
|
def desc(arg, opts=OPTS)
|
468
428
|
SQL::OrderedExpression.new(arg, true, opts)
|
469
429
|
end
|
@@ -552,7 +512,7 @@ module Sequel
|
|
552
512
|
|
553
513
|
# Return the argument wrapped as an <tt>SQL::Identifier</tt>.
|
554
514
|
#
|
555
|
-
# Sequel.identifier(:
|
515
|
+
# Sequel.identifier(:a) # "a"
|
556
516
|
def identifier(name)
|
557
517
|
SQL::Identifier.new(name)
|
558
518
|
end
|
@@ -605,10 +565,10 @@ module Sequel
|
|
605
565
|
# Converts a string into a <tt>Sequel::LiteralString</tt>, in order to override string
|
606
566
|
# literalization, e.g.:
|
607
567
|
#
|
608
|
-
# DB[:items].where(:
|
568
|
+
# DB[:items].where(abc: 'def').sql #=>
|
609
569
|
# "SELECT * FROM items WHERE (abc = 'def')"
|
610
570
|
#
|
611
|
-
# DB[:items].where(:
|
571
|
+
# DB[:items].where(abc: Sequel.lit('def')).sql #=>
|
612
572
|
# "SELECT * FROM items WHERE (abc = def)"
|
613
573
|
#
|
614
574
|
# You can also provide arguments, to create a <tt>Sequel::SQL::PlaceholderLiteralString</tt>:
|
@@ -630,7 +590,7 @@ module Sequel
|
|
630
590
|
# Return a <tt>Sequel::SQL::BooleanExpression</tt> created from the condition
|
631
591
|
# specifier, matching none of the conditions.
|
632
592
|
#
|
633
|
-
# Sequel.negate(:
|
593
|
+
# Sequel.negate(a: true) # SQL: a IS NOT TRUE
|
634
594
|
# Sequel.negate([[:a, true]]) # SQL: a IS NOT TRUE
|
635
595
|
# Sequel.negate([[:a, 1], [:b, 2]]) # SQL: ((a != 1) AND (b != 2))
|
636
596
|
def negate(arg)
|
@@ -644,7 +604,7 @@ module Sequel
|
|
644
604
|
# Return a <tt>Sequel::SQL::BooleanExpression</tt> created from the condition
|
645
605
|
# specifier, matching any of the conditions.
|
646
606
|
#
|
647
|
-
# Sequel.or(:
|
607
|
+
# Sequel.or(a: true) # SQL: a IS TRUE
|
648
608
|
# Sequel.or([[:a, true]]) # SQL: a IS TRUE
|
649
609
|
# Sequel.or([[:a, 1], [:b, 2]]) # SQL: ((a = 1) OR (b = 2))
|
650
610
|
def or(arg)
|
@@ -733,22 +693,11 @@ module Sequel
|
|
733
693
|
end
|
734
694
|
|
735
695
|
# Adds methods that allow you to treat an object as an instance of a specific
|
736
|
-
# +ComplexExpression+ subclass.
|
737
|
-
# overrides the methods defined by Sequel.
|
738
|
-
#
|
739
|
-
# For example, if <tt>Symbol#/</tt> is overridden to produce a string (for
|
740
|
-
# example, to make file system path creation easier), the
|
741
|
-
# following code will not do what you want:
|
742
|
-
#
|
743
|
-
# :price/10 > 100
|
744
|
-
#
|
745
|
-
# In that case, you need to do the following:
|
746
|
-
#
|
747
|
-
# :price.sql_number/10 > 100
|
696
|
+
# +ComplexExpression+ subclass.
|
748
697
|
module ComplexExpressionMethods
|
749
698
|
# Extract a datetime part (e.g. year, month) from self:
|
750
699
|
#
|
751
|
-
# :date.extract(:year) # extract(year FROM "date")
|
700
|
+
# Sequel[:date].extract(:year) # extract(year FROM "date")
|
752
701
|
#
|
753
702
|
# Also has the benefit of returning the result as a
|
754
703
|
# NumericExpression instead of a generic ComplexExpression.
|
@@ -763,16 +712,16 @@ module Sequel
|
|
763
712
|
|
764
713
|
# Return a NumericExpression representation of +self+.
|
765
714
|
#
|
766
|
-
#
|
767
|
-
#
|
715
|
+
# ~Sequel[:a] # NOT "a"
|
716
|
+
# ~(Sequel[:a].sql_number) # ~"a"
|
768
717
|
def sql_number
|
769
718
|
NumericExpression.new(:NOOP, self)
|
770
719
|
end
|
771
720
|
|
772
721
|
# Return a StringExpression representation of +self+.
|
773
722
|
#
|
774
|
-
# :a + :b # "a" + "b"
|
775
|
-
# :a.sql_string + :b # "a" || "b"
|
723
|
+
# Sequel[:a] + :b # "a" + "b"
|
724
|
+
# Sequel[:a].sql_string + :b # "a" || "b"
|
776
725
|
def sql_string
|
777
726
|
StringExpression.new(:NOOP, self)
|
778
727
|
end
|
@@ -803,7 +752,7 @@ module Sequel
|
|
803
752
|
# One exception to this is if + is called with a +String+ or +StringExpression+,
|
804
753
|
# in which case the || operator is used instead of the + operator:
|
805
754
|
#
|
806
|
-
# :a + 'b' # "a" || 'b'
|
755
|
+
# Sequel[:a] + 'b' # "a" || 'b'
|
807
756
|
module NumericMethods
|
808
757
|
(ComplexExpression::MATHEMATICAL_OPERATORS - [:+]).each do |o|
|
809
758
|
module_eval("def #{o}(o) NumericExpression.new(#{o.inspect}, self, o) end", __FILE__, __LINE__)
|
@@ -845,7 +794,7 @@ module Sequel
|
|
845
794
|
# Sequel[:a] =~ [1, 2] # (a IN [1, 2])
|
846
795
|
# Sequel[:a] =~ nil # (a IS NULL)
|
847
796
|
#
|
848
|
-
#
|
797
|
+
# This also adds the !~ method, for easily setting up not equals,
|
849
798
|
# exclusion, and inverse pattern matching. This is the same as as inverting the
|
850
799
|
# result of the =~ method
|
851
800
|
#
|
@@ -859,23 +808,19 @@ module Sequel
|
|
859
808
|
BooleanExpression.send(:from_value_pair, self, other)
|
860
809
|
end
|
861
810
|
|
862
|
-
|
863
|
-
|
864
|
-
def !~(other)
|
865
|
-
~(self =~ other)
|
866
|
-
end
|
867
|
-
END
|
811
|
+
def !~(other)
|
812
|
+
~(self =~ other)
|
868
813
|
end
|
869
814
|
end
|
870
815
|
|
871
|
-
#
|
872
|
-
# methods, so that Sequel is still easy to use if the core extensions are not
|
873
|
-
# enabled.
|
816
|
+
# This adds methods to create SQL expressions using operators:
|
874
817
|
#
|
875
|
-
#
|
876
|
-
#
|
877
|
-
#
|
878
|
-
#
|
818
|
+
# Sequel.+(1, :a) # (1 + a)
|
819
|
+
# Sequel.-(1, :a) # (1 - a)
|
820
|
+
# Sequel.*(1, :a) # (1 * a)
|
821
|
+
# Sequel./(1, :a) # (1 / a)
|
822
|
+
# Sequel.&(:b, :a) # (b AND a)
|
823
|
+
# Sequel.|(:b, :a) # (b OR a)
|
879
824
|
module OperatorBuilders
|
880
825
|
{'::Sequel::SQL::NumericExpression'=>{'+'=>'+', '-'=>'-', '*'=>'*', '/'=>'/'},
|
881
826
|
'::Sequel::SQL::BooleanExpression'=>{'&'=>'AND', '|'=>'OR'}}.each do |klass, ops|
|
@@ -942,13 +887,13 @@ module Sequel
|
|
942
887
|
end
|
943
888
|
end
|
944
889
|
|
945
|
-
# Includes a +qualify+
|
890
|
+
# Includes a +qualify+ and <tt>[]</tt> methods that create <tt>QualifiedIdentifier</tt>s, used for qualifying column
|
946
891
|
# names with a table or table names with a schema, and the * method for returning all columns in
|
947
892
|
# the identifier if no arguments are given.
|
948
893
|
module QualifyingMethods
|
949
894
|
# If no arguments are given, return an SQL::ColumnAll:
|
950
895
|
#
|
951
|
-
# Sequel[:
|
896
|
+
# Sequel[:a].* # a.*
|
952
897
|
def *(ce=(arg=false;nil))
|
953
898
|
if arg == false
|
954
899
|
Sequel::SQL::ColumnAll.new(self)
|
@@ -982,7 +927,7 @@ module Sequel
|
|
982
927
|
# Create a +BooleanExpression+ case insensitive pattern match of the receiver
|
983
928
|
# with the given patterns. See <tt>StringExpression.like</tt>.
|
984
929
|
#
|
985
|
-
# :a.ilike('A%') # "a" ILIKE 'A%' ESCAPE '\'
|
930
|
+
# Sequel[:a].ilike('A%') # "a" ILIKE 'A%' ESCAPE '\'
|
986
931
|
def ilike(*ces)
|
987
932
|
StringExpression.like(self, *(ces << {:case_insensitive=>true}))
|
988
933
|
end
|
@@ -990,7 +935,7 @@ module Sequel
|
|
990
935
|
# Create a +BooleanExpression+ case sensitive (if the database supports it) pattern match of the receiver with
|
991
936
|
# the given patterns. See <tt>StringExpression.like</tt>.
|
992
937
|
#
|
993
|
-
# :a.like('A%') # "a" LIKE 'A%' ESCAPE '\'
|
938
|
+
# Sequel[:a].like('A%') # "a" LIKE 'A%' ESCAPE '\'
|
994
939
|
def like(*ces)
|
995
940
|
StringExpression.like(self, *ces)
|
996
941
|
end
|
@@ -1002,7 +947,7 @@ module Sequel
|
|
1002
947
|
# Return a +StringExpression+ representing the concatenation of the receiver
|
1003
948
|
# with the given argument.
|
1004
949
|
#
|
1005
|
-
# :x.sql_string + :y # => "x" || "y"
|
950
|
+
# Sequel[:x].sql_string + :y # => "x" || "y"
|
1006
951
|
def +(ce)
|
1007
952
|
StringExpression.new(:'||', self, ce)
|
1008
953
|
end
|
@@ -1013,36 +958,29 @@ module Sequel
|
|
1013
958
|
# Return a <tt>Subscript</tt> with the given arguments, representing an
|
1014
959
|
# SQL array access.
|
1015
960
|
#
|
1016
|
-
# :array.sql_subscript(1) # array[1]
|
1017
|
-
# :array.sql_subscript(1, 2) # array[1, 2]
|
1018
|
-
# :array.sql_subscript([1, 2]) # array[1, 2]
|
1019
|
-
# :array.sql_subscript(
|
1020
|
-
# :array.sql_subscript(
|
961
|
+
# Sequel[:array].sql_subscript(1) # array[1]
|
962
|
+
# Sequel[:array].sql_subscript(1, 2) # array[1, 2]
|
963
|
+
# Sequel[:array].sql_subscript([1, 2]) # array[1, 2]
|
964
|
+
# Sequel[:array].sql_subscript(1..2) # array[1:2]
|
965
|
+
# Sequel[:array].sql_subscript(1...3) # array[1:2]
|
1021
966
|
def sql_subscript(*sub)
|
1022
967
|
Subscript.new(self, sub.flatten)
|
1023
968
|
end
|
1024
969
|
end
|
1025
970
|
|
1026
|
-
### Classes ###
|
1027
|
-
|
1028
971
|
# Represents an aliasing of an expression to a given alias.
|
1029
972
|
class AliasedExpression < Expression
|
1030
973
|
# The expression to alias
|
1031
974
|
attr_reader :expression
|
1032
975
|
|
1033
|
-
# The alias to use for the expression
|
976
|
+
# The alias to use for the expression.
|
1034
977
|
attr_reader :alias
|
1035
978
|
|
1036
|
-
|
1037
|
-
Sequel::Deprecation.deprecate("Sequel::SQL::AliasedExpression#aliaz", "Use #alias instead")
|
1038
|
-
self.alias
|
1039
|
-
end
|
1040
|
-
|
1041
|
-
# The columns aliases to use, for when the aliased expression is
|
979
|
+
# The columns aliases (derived column list) to use, for when the aliased expression is
|
1042
980
|
# a record or set of records (such as a dataset).
|
1043
981
|
attr_reader :columns
|
1044
982
|
|
1045
|
-
# Create an object with the given expression and
|
983
|
+
# Create an object with the given expression, alias, and optional column aliases.
|
1046
984
|
def initialize(expression, aliaz, columns=nil)
|
1047
985
|
@expression = expression
|
1048
986
|
@alias = aliaz
|
@@ -1192,11 +1130,11 @@ module Sequel
|
|
1192
1130
|
# The default value if no conditions match.
|
1193
1131
|
attr_reader :default
|
1194
1132
|
|
1195
|
-
#
|
1133
|
+
# An optional expression to test the conditions against
|
1196
1134
|
attr_reader :expression
|
1197
1135
|
|
1198
1136
|
# Create an object with the given conditions and
|
1199
|
-
# default value. An expression can be provided to
|
1137
|
+
# default value, and optional expression. An expression can be provided to
|
1200
1138
|
# test each condition against, instead of having
|
1201
1139
|
# all conditions represent their own boolean expression.
|
1202
1140
|
def initialize(conditions, default, expression=(no_expression=true; nil))
|
@@ -1235,7 +1173,7 @@ module Sequel
|
|
1235
1173
|
# The type to which to cast the expression
|
1236
1174
|
attr_reader :type
|
1237
1175
|
|
1238
|
-
# Set the
|
1176
|
+
# Set the expression and type for the cast
|
1239
1177
|
def initialize(expr, type)
|
1240
1178
|
@expr = expr
|
1241
1179
|
@type = type
|
@@ -1268,17 +1206,17 @@ module Sequel
|
|
1268
1206
|
|
1269
1207
|
# Return a BooleanExpression with the same op and args.
|
1270
1208
|
def sql_boolean
|
1271
|
-
BooleanExpression.new(
|
1209
|
+
BooleanExpression.new(op, *args)
|
1272
1210
|
end
|
1273
1211
|
|
1274
1212
|
# Return a NumericExpression with the same op and args.
|
1275
1213
|
def sql_number
|
1276
|
-
NumericExpression.new(
|
1214
|
+
NumericExpression.new(op, *args)
|
1277
1215
|
end
|
1278
1216
|
|
1279
1217
|
# Return a StringExpression with the same op and args.
|
1280
1218
|
def sql_string
|
1281
|
-
StringExpression.new(
|
1219
|
+
StringExpression.new(op, *args)
|
1282
1220
|
end
|
1283
1221
|
end
|
1284
1222
|
|
@@ -1287,7 +1225,7 @@ module Sequel
|
|
1287
1225
|
# The underlying constant related to this object.
|
1288
1226
|
attr_reader :constant
|
1289
1227
|
|
1290
|
-
# Create
|
1228
|
+
# Create a constant with the given value
|
1291
1229
|
def initialize(constant)
|
1292
1230
|
@constant = constant
|
1293
1231
|
freeze
|
@@ -1296,7 +1234,7 @@ module Sequel
|
|
1296
1234
|
to_s_method :constant_sql, '@constant'
|
1297
1235
|
end
|
1298
1236
|
|
1299
|
-
# Represents boolean constants such as +NULL+, +
|
1237
|
+
# Represents boolean constants such as +NULL+, +TRUE+, and +FALSE+.
|
1300
1238
|
class BooleanConstant < Constant
|
1301
1239
|
to_s_method :boolean_constant_sql, '@constant'
|
1302
1240
|
end
|
@@ -1324,7 +1262,7 @@ module Sequel
|
|
1324
1262
|
class ComplexExpression
|
1325
1263
|
# A hash of the opposite for each constant, used for inverting constants.
|
1326
1264
|
CONSTANT_INVERSIONS = {Constants::TRUE=>Constants::FALSE, Constants::FALSE=>Constants::TRUE,
|
1327
|
-
Constants::NULL=>Constants::NOTNULL, Constants::NOTNULL=>Constants::NULL}
|
1265
|
+
Constants::NULL=>Constants::NOTNULL, Constants::NOTNULL=>Constants::NULL}.freeze
|
1328
1266
|
end
|
1329
1267
|
|
1330
1268
|
# Represents a delayed evaluation, encapsulating a callable
|
@@ -1363,11 +1301,6 @@ module Sequel
|
|
1363
1301
|
# The SQL function to call
|
1364
1302
|
attr_reader :name
|
1365
1303
|
|
1366
|
-
def f
|
1367
|
-
Sequel::Deprecation.deprecate("Sequel::SQL::Function#f", "Use #name instead")
|
1368
|
-
name
|
1369
|
-
end
|
1370
|
-
|
1371
1304
|
# The array of arguments to pass to the function (may be blank)
|
1372
1305
|
attr_reader :args
|
1373
1306
|
|
@@ -1379,7 +1312,8 @@ module Sequel
|
|
1379
1312
|
_initialize(name, args, OPTS)
|
1380
1313
|
end
|
1381
1314
|
|
1382
|
-
|
1315
|
+
# Set the name, args, and options, for internal use only.
|
1316
|
+
def self.new!(name, args, opts) # :nodoc:
|
1383
1317
|
allocate.send(:_initialize, name, args, opts)
|
1384
1318
|
end
|
1385
1319
|
|
@@ -1405,7 +1339,7 @@ module Sequel
|
|
1405
1339
|
# Return a new function with FILTER added to it, for filtered
|
1406
1340
|
# aggregate functions:
|
1407
1341
|
#
|
1408
|
-
# Sequel.function(:foo, :col).filter(:
|
1342
|
+
# Sequel.function(:foo, :col).filter(a: 1) # foo(col) FILTER (WHERE (a = 1))
|
1409
1343
|
def filter(*args, &block)
|
1410
1344
|
if args.length == 1
|
1411
1345
|
args = args.first
|
@@ -1434,7 +1368,7 @@ module Sequel
|
|
1434
1368
|
# Return a new function with an OVER clause (making it a window function).
|
1435
1369
|
# See {SQL::Window} for the list of options +over+ can receive.
|
1436
1370
|
#
|
1437
|
-
# Sequel.function(:row_number).over(:
|
1371
|
+
# Sequel.function(:row_number).over(partition: :col) # row_number() OVER (PARTITION BY col)
|
1438
1372
|
def over(window=OPTS)
|
1439
1373
|
raise Error, "function already has a window applied to it" if opts[:over]
|
1440
1374
|
window = Window.new(window) unless window.is_a?(Window)
|
@@ -1452,7 +1386,7 @@ module Sequel
|
|
1452
1386
|
# Return a new function where the function name will not be quoted even
|
1453
1387
|
# if the database supports quoted functions:
|
1454
1388
|
#
|
1455
|
-
# Sequel[:foo].function.unquoted # foo()
|
1389
|
+
# Sequel[:foo][:bar].function.unquoted # foo.bar()
|
1456
1390
|
def unquoted
|
1457
1391
|
with_opts(:quoted=>false)
|
1458
1392
|
end
|
@@ -1478,7 +1412,7 @@ module Sequel
|
|
1478
1412
|
|
1479
1413
|
private
|
1480
1414
|
|
1481
|
-
# Set args and opts
|
1415
|
+
# Set name, args, and opts
|
1482
1416
|
def _initialize(name, args, opts)
|
1483
1417
|
@name = name
|
1484
1418
|
@args = args.freeze
|
@@ -1505,16 +1439,14 @@ module Sequel
|
|
1505
1439
|
include SubscriptMethods
|
1506
1440
|
end
|
1507
1441
|
|
1508
|
-
# Represents an identifier (column
|
1509
|
-
# to specify a +Symbol+ with multiple underscores should not be
|
1510
|
-
# split, or for creating an identifier without using a symbol.
|
1442
|
+
# Represents an identifier (column, table, schema, etc.).
|
1511
1443
|
class Identifier < GenericExpression
|
1512
1444
|
include QualifyingMethods
|
1513
1445
|
|
1514
|
-
# The
|
1446
|
+
# The identifier to reference
|
1515
1447
|
attr_reader :value
|
1516
1448
|
|
1517
|
-
# Set the
|
1449
|
+
# Set the identifier to the given argument
|
1518
1450
|
def initialize(value)
|
1519
1451
|
@value = value
|
1520
1452
|
freeze
|
@@ -1744,15 +1676,16 @@ module Sequel
|
|
1744
1676
|
include InequalityMethods
|
1745
1677
|
|
1746
1678
|
# Map of [regexp, case_insenstive] to +ComplexExpression+ operator symbol
|
1747
|
-
LIKE_MAP = {[true, true]=>:'~*', [true, false]=>:~, [false, true]=>:ILIKE, [false, false]=>:LIKE}
|
1679
|
+
LIKE_MAP = {[true, true]=>:'~*', [true, false]=>:~, [false, true]=>:ILIKE, [false, false]=>:LIKE}.freeze
|
1680
|
+
LIKE_MAP.each_key(&:freeze)
|
1748
1681
|
|
1749
1682
|
# Creates a SQL pattern match exprssion. left (l) is the SQL string we
|
1750
1683
|
# are matching against, and ces are the patterns we are matching.
|
1751
1684
|
# The match succeeds if any of the patterns match (SQL OR).
|
1752
1685
|
#
|
1753
1686
|
# If a regular expression is used as a pattern, an SQL regular expression will be
|
1754
|
-
# used, which is currently only supported on
|
1755
|
-
# that
|
1687
|
+
# used, which is currently only supported on some databases. Be aware
|
1688
|
+
# that SQL regular expression syntax is similar to ruby
|
1756
1689
|
# regular expression syntax, but it not exactly the same, especially for
|
1757
1690
|
# advanced regular expression features. Sequel just uses the source of the
|
1758
1691
|
# ruby regular expression verbatim as the SQL regular expression string.
|
@@ -1765,9 +1698,9 @@ module Sequel
|
|
1765
1698
|
# if a case insensitive regular expression is used (//i), that particular
|
1766
1699
|
# pattern which will always be case insensitive.
|
1767
1700
|
#
|
1768
|
-
# StringExpression.like(:a, 'a%') # "a" LIKE 'a%' ESCAPE '\'
|
1769
|
-
# StringExpression.like(:a, 'a%', :
|
1770
|
-
# StringExpression.like(:a, 'a%', /^a/i) # "a" LIKE 'a%' ESCAPE '\' OR "a" ~* '^a'
|
1701
|
+
# StringExpression.like(:a, 'a%') # ("a" LIKE 'a%' ESCAPE '\')
|
1702
|
+
# StringExpression.like(:a, 'a%', case_insensitive: true) # ("a" ILIKE 'a%' ESCAPE '\')
|
1703
|
+
# StringExpression.like(:a, 'a%', /^a/i) # (("a" LIKE 'a%' ESCAPE '\') OR ("a" ~* '^a'))
|
1771
1704
|
def self.like(l, *ces)
|
1772
1705
|
l, lre, lci = like_element(l)
|
1773
1706
|
lci = (ces.last.is_a?(Hash) ? ces.pop : {})[:case_insensitive] ? true : lci
|
@@ -1800,14 +1733,15 @@ module Sequel
|
|
1800
1733
|
# Represents an SQL array access, with multiple possible arguments.
|
1801
1734
|
class Subscript < GenericExpression
|
1802
1735
|
# The SQL array column
|
1803
|
-
attr_reader :
|
1736
|
+
attr_reader :expression
|
1737
|
+
alias f expression
|
1804
1738
|
|
1805
1739
|
# The array of subscripts to use (should be an array of numbers)
|
1806
1740
|
attr_reader :sub
|
1807
1741
|
|
1808
1742
|
# Set the array column and subscripts to the given arguments
|
1809
|
-
def initialize(
|
1810
|
-
@
|
1743
|
+
def initialize(expression, sub)
|
1744
|
+
@expression = expression
|
1811
1745
|
@sub = sub
|
1812
1746
|
freeze
|
1813
1747
|
end
|
@@ -1815,17 +1749,17 @@ module Sequel
|
|
1815
1749
|
# Create a new +Subscript+ appending the given subscript(s)
|
1816
1750
|
# to the current array of subscripts.
|
1817
1751
|
#
|
1818
|
-
# :a.sql_subscript(2) # a[2]
|
1819
|
-
# :a.sql_subscript(2) | 1 # a[2, 1]
|
1752
|
+
# Sequel[:a].sql_subscript(2) # a[2]
|
1753
|
+
# Sequel[:a].sql_subscript(2) | 1 # a[2, 1]
|
1820
1754
|
def |(sub)
|
1821
|
-
Subscript.new(@
|
1755
|
+
Subscript.new(@expression, @sub + Array(sub))
|
1822
1756
|
end
|
1823
1757
|
|
1824
1758
|
# Create a new +Subscript+ by accessing a subarray of a multidimensional
|
1825
1759
|
# array.
|
1826
1760
|
#
|
1827
|
-
# :a.sql_subscript(2) # a[2]
|
1828
|
-
# :a.sql_subscript(2)[1] # a[2][1]
|
1761
|
+
# Sequel[:a].sql_subscript(2) # a[2]
|
1762
|
+
# Sequel[:a].sql_subscript(2)[1] # a[2][1]
|
1829
1763
|
def [](sub)
|
1830
1764
|
Subscript.new(self, Array(sub))
|
1831
1765
|
end
|
@@ -1843,38 +1777,24 @@ module Sequel
|
|
1843
1777
|
end
|
1844
1778
|
end
|
1845
1779
|
|
1846
|
-
# The purpose of the +VirtualRow+ class is to allow the easy creation of SQL identifiers and functions
|
1847
|
-
#
|
1848
|
-
# the methods defined by Sequel, if you are running on ruby 1.9, or if you are not using the
|
1849
|
-
# core extensions.
|
1780
|
+
# The purpose of the +VirtualRow+ class is to allow the easy creation of SQL identifiers and functions,
|
1781
|
+
# in a way that leads to more compact code.
|
1850
1782
|
#
|
1851
1783
|
# An instance of this class is yielded to the block supplied to <tt>Dataset#where</tt>, <tt>Dataset#order</tt>, and <tt>Dataset#select</tt>
|
1852
1784
|
# (and the other methods that accept a block and pass it to one of those methods).
|
1853
1785
|
# If the block doesn't take an argument, the block is instance_execed in the context of
|
1854
1786
|
# an instance of this class.
|
1855
1787
|
#
|
1856
|
-
# +VirtualRow+ uses +method_missing+ to return either an +Identifier+, +
|
1788
|
+
# +VirtualRow+ uses +method_missing+ to return either an +Identifier+, +Function+
|
1857
1789
|
# depending on how it is called.
|
1858
1790
|
#
|
1859
|
-
# If a block is _not_ given, creates one of the following objects:
|
1860
|
-
#
|
1861
1791
|
# +Function+ :: Returned if any arguments are supplied, using the method name
|
1862
1792
|
# as the function name, and the arguments as the function arguments.
|
1863
|
-
# +QualifiedIdentifier+ :: Returned if the method name contains __, with the
|
1864
|
-
# table being the part before __, and the column being the part after.
|
1865
1793
|
# +Identifier+ :: Returned otherwise, using the method name.
|
1866
1794
|
#
|
1867
|
-
# If
|
1868
|
-
#
|
1869
|
-
#
|
1870
|
-
# no arguments given :: creates a +Function+ with no arguments.
|
1871
|
-
# :* :: creates a +Function+ with a literal wildcard argument (*), mostly useful for COUNT.
|
1872
|
-
# :distinct :: creates a +Function+ that prepends DISTINCT to the rest of the arguments, mostly
|
1873
|
-
# useful for aggregate functions.
|
1874
|
-
# :over :: creates a +Function+ with a window. If a second argument is provided, it should be a hash
|
1875
|
-
# of options which are used to create the +Window+ (with possible keys :window, :partition, :order, and :frame). The
|
1876
|
-
# arguments to the function itself should be specified as <tt>:*=>true</tt> for a wildcard, or via
|
1877
|
-
# the <tt>:args</tt> option.
|
1795
|
+
# If splitting symbols has been enabled (not the default), then method calls without
|
1796
|
+
# arguments will return +QualifiedIdentifier+ instances if the method call includes a
|
1797
|
+
# double underscore.
|
1878
1798
|
#
|
1879
1799
|
# Examples:
|
1880
1800
|
#
|
@@ -1883,22 +1803,14 @@ module Sequel
|
|
1883
1803
|
# # Argument yielded to block
|
1884
1804
|
# ds.where{|r| r.name < 2} # SELECT * FROM t WHERE (name < 2)
|
1885
1805
|
#
|
1886
|
-
# # Block without argument (
|
1806
|
+
# # Block without argument (instance_exec)
|
1887
1807
|
# ds.where{name < 2} # SELECT * FROM t WHERE (name < 2)
|
1888
1808
|
#
|
1889
|
-
# # Qualified identifiers
|
1890
|
-
# ds.where{table__column + 1 < 2} # SELECT * FROM t WHERE ((table.column + 1) < 2)
|
1891
|
-
#
|
1892
1809
|
# # Functions
|
1893
1810
|
# ds.where{is_active(1, 'arg2')} # SELECT * FROM t WHERE is_active(1, 'arg2')
|
1894
|
-
# ds.select{version
|
1895
|
-
# ds.select{count
|
1896
|
-
# ds.select{count(
|
1897
|
-
#
|
1898
|
-
# # Window Functions
|
1899
|
-
# ds.select{rank(:over){}} # SELECT rank() OVER () FROM t
|
1900
|
-
# ds.select{count(:over, :*=>true){}} # SELECT count(*) OVER () FROM t
|
1901
|
-
# ds.select{sum(:over, :args=>col1, :partition=>col2, :order=>col3){}} # SELECT sum(col1) OVER (PARTITION BY col2 ORDER BY col3) FROM t
|
1811
|
+
# ds.select{version.function} # SELECT version() FROM t
|
1812
|
+
# ds.select{count.function.*} # SELECT count(*) FROM t
|
1813
|
+
# ds.select{count(col1).distinct} # SELECT count(DISTINCT col1) FROM t
|
1902
1814
|
#
|
1903
1815
|
# # Math Operators
|
1904
1816
|
# ds.select{|o| o.+(1, :a).as(:b)} # SELECT (1 + a) AS b FROM t
|
@@ -1907,10 +1819,10 @@ module Sequel
|
|
1907
1819
|
# ds.select{|o| o./(4, :a).as(:b)} # SELECT (4 / a) AS b FROM t
|
1908
1820
|
#
|
1909
1821
|
# # Boolean Operators
|
1910
|
-
# ds.where{|o| o.&({:
|
1911
|
-
# ds.where{|o| o.|({:
|
1912
|
-
# ds.where{|o| o.~(
|
1913
|
-
# ds.where{|o| o.~(
|
1822
|
+
# ds.where{|o| o.&({a: 1}, :b)} # SELECT * FROM t WHERE ((a = 1) AND b)
|
1823
|
+
# ds.where{|o| o.|({a: 1}, :b)} # SELECT * FROM t WHERE ((a = 1) OR b)
|
1824
|
+
# ds.where{|o| o.~(a: 1)} # SELECT * FROM t WHERE (a != 1)
|
1825
|
+
# ds.where{|o| o.~(a: 1, b: 2)} # SELECT * FROM t WHERE ((a != 1) OR (b != 2))
|
1914
1826
|
#
|
1915
1827
|
# # Inequality Operators
|
1916
1828
|
# ds.where{|o| o.>(1, :a)} # SELECT * FROM t WHERE (1 > a)
|
@@ -1918,16 +1830,8 @@ module Sequel
|
|
1918
1830
|
# ds.where{|o| o.>=(3, :a)} # SELECT * FROM t WHERE (3 >= a)
|
1919
1831
|
# ds.where{|o| o.<=(4, :a)} # SELECT * FROM t WHERE (4 <= a)
|
1920
1832
|
#
|
1921
|
-
# # Literal Strings
|
1922
|
-
# ds.where{{a=>`some SQL`}} # SELECT * FROM t WHERE (a = some SQL)
|
1923
|
-
#
|
1924
1833
|
# For a more detailed explanation, see the {Virtual Rows guide}[rdoc-ref:doc/virtual_rows.rdoc].
|
1925
1834
|
class VirtualRow < BasicObject
|
1926
|
-
QUESTION_MARK = LiteralString.new('?').freeze
|
1927
|
-
Sequel::Deprecation.deprecate_constant(self, :QUESTION_MARK)
|
1928
|
-
DOUBLE_UNDERSCORE = '__'.freeze
|
1929
|
-
Sequel::Deprecation.deprecate_constant(self, :DOUBLE_UNDERSCORE)
|
1930
|
-
|
1931
1835
|
include OperatorBuilders
|
1932
1836
|
|
1933
1837
|
%w'> < >= <='.each do |op|
|
@@ -1942,49 +1846,14 @@ module Sequel
|
|
1942
1846
|
freeze
|
1943
1847
|
end
|
1944
1848
|
|
1945
|
-
# Return a literal string created with the given string.
|
1946
|
-
def `(s)
|
1947
|
-
Sequel::Deprecation.deprecate("Using Sequel#VirtualRow#` to create a literal SQL fragment", "Use Sequel.lit instead")
|
1948
|
-
Sequel::LiteralString.new(s)
|
1949
|
-
end
|
1950
|
-
|
1951
1849
|
include(Module.new do
|
1952
1850
|
# Return an +Identifier+, +QualifiedIdentifier+, or +Function+, depending
|
1953
1851
|
# on arguments and whether a block is provided. Does not currently call the block.
|
1954
1852
|
# See the class level documentation.
|
1955
|
-
def method_missing(m, *args
|
1956
|
-
if
|
1957
|
-
if
|
1958
|
-
Sequel::Deprecation.deprecate("Passing a block to a virtual row method to create a Sequel::SQL::Function", "Replace the block with a call to .function to create a function, or use the virtual_row_method_block extension")
|
1959
|
-
Function.new(m)
|
1960
|
-
else
|
1961
|
-
case args.shift
|
1962
|
-
when :*
|
1963
|
-
Sequel::Deprecation.deprecate("Passing a block to a virtual row method with a :* argument to create a Sequel::SQL::Function", "Remove the :* argument and block and a call to .function.* to create a function(*) call, or use the virtual_row_method_block extension")
|
1964
|
-
Function.new(m, *args).*
|
1965
|
-
when :distinct
|
1966
|
-
Sequel::Deprecation.deprecate("Passing a block to a virtual row method with a :distinct argument to create a Sequel::SQL::Function", "Remove the :distinct argument and block with a call to .function.distinct to create a function(DISTINCT ...) call, or use the virtual_row_method_block extension")
|
1967
|
-
Function.new(m, *args).distinct
|
1968
|
-
when :over
|
1969
|
-
opts = args.shift || OPTS
|
1970
|
-
f = Function.new(m, *::Kernel.Array(opts[:args]))
|
1971
|
-
if opts[:*]
|
1972
|
-
Sequel::Deprecation.deprecate("Passing a block to a virtual row method with a :over argument and :* option to create a Sequel::SQL::WindowFunction", "Remove the :over argument, :* option and block with a call to .function.*.over with the options to create a function(*) OVER (...) call, or use the virtual_row_method_block extension")
|
1973
|
-
f = f.*
|
1974
|
-
else
|
1975
|
-
Sequel::Deprecation.deprecate("Passing a block to a virtual row method with a :over argument to create a Sequel::SQL::WindowFunction", "Remove the :over argument and block with a call to .function.over with the options to create a function(...) OVER (...) call, or use the virtual_row_method_block extension")
|
1976
|
-
end
|
1977
|
-
f.over(opts)
|
1978
|
-
else
|
1979
|
-
Kernel.raise(Error, 'unsupported VirtualRow method argument used with block')
|
1980
|
-
end
|
1981
|
-
end
|
1982
|
-
elsif args.empty?
|
1983
|
-
if split = Sequel.split_symbols?
|
1853
|
+
def method_missing(m, *args)
|
1854
|
+
if args.empty?
|
1855
|
+
if Sequel.split_symbols?
|
1984
1856
|
table, column = m.to_s.split('__', 2)
|
1985
|
-
if column && split == :deprecated
|
1986
|
-
Sequel::Deprecation.deprecate("Splitting virtual row method names", "Either set Sequel.split_symbols = true, or change #{m.inspect} to #{table}[:#{column}]")
|
1987
|
-
end
|
1988
1857
|
column ? QualifiedIdentifier.new(table, column) : Identifier.new(m)
|
1989
1858
|
else
|
1990
1859
|
Identifier.new(m)
|