sequel 4.26.0 → 5.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG +405 -5656
- data/MIT-LICENSE +1 -1
- data/README.rdoc +232 -157
- data/bin/sequel +32 -9
- data/doc/advanced_associations.rdoc +252 -188
- data/doc/association_basics.rdoc +231 -273
- data/doc/bin_sequel.rdoc +5 -3
- data/doc/cheat_sheet.rdoc +75 -48
- data/doc/code_order.rdoc +28 -10
- data/doc/core_extensions.rdoc +104 -63
- data/doc/dataset_basics.rdoc +12 -21
- data/doc/dataset_filtering.rdoc +99 -86
- data/doc/extensions.rdoc +3 -10
- data/doc/mass_assignment.rdoc +74 -31
- data/doc/migration.rdoc +72 -46
- data/doc/model_dataset_method_design.rdoc +129 -0
- data/doc/model_hooks.rdoc +15 -25
- data/doc/model_plugins.rdoc +12 -12
- data/doc/mssql_stored_procedures.rdoc +3 -3
- data/doc/object_model.rdoc +59 -69
- data/doc/opening_databases.rdoc +84 -94
- data/doc/postgresql.rdoc +268 -38
- data/doc/prepared_statements.rdoc +29 -24
- data/doc/querying.rdoc +184 -164
- data/doc/reflection.rdoc +5 -6
- data/doc/release_notes/5.0.0.txt +159 -0
- data/doc/release_notes/5.1.0.txt +31 -0
- data/doc/release_notes/5.10.0.txt +84 -0
- data/doc/release_notes/5.11.0.txt +83 -0
- data/doc/release_notes/5.12.0.txt +141 -0
- data/doc/release_notes/5.13.0.txt +27 -0
- data/doc/release_notes/5.14.0.txt +63 -0
- data/doc/release_notes/5.15.0.txt +39 -0
- data/doc/release_notes/5.16.0.txt +110 -0
- data/doc/release_notes/5.17.0.txt +31 -0
- data/doc/release_notes/5.18.0.txt +69 -0
- data/doc/release_notes/5.19.0.txt +28 -0
- data/doc/release_notes/5.2.0.txt +33 -0
- data/doc/release_notes/5.20.0.txt +89 -0
- data/doc/release_notes/5.21.0.txt +87 -0
- data/doc/release_notes/5.22.0.txt +48 -0
- data/doc/release_notes/5.23.0.txt +56 -0
- data/doc/release_notes/5.24.0.txt +56 -0
- data/doc/release_notes/5.25.0.txt +32 -0
- data/doc/release_notes/5.26.0.txt +35 -0
- data/doc/release_notes/5.27.0.txt +21 -0
- data/doc/release_notes/5.28.0.txt +16 -0
- data/doc/release_notes/5.29.0.txt +22 -0
- data/doc/release_notes/5.3.0.txt +121 -0
- data/doc/release_notes/5.30.0.txt +20 -0
- data/doc/release_notes/5.31.0.txt +148 -0
- data/doc/release_notes/5.32.0.txt +46 -0
- data/doc/release_notes/5.33.0.txt +24 -0
- data/doc/release_notes/5.34.0.txt +40 -0
- data/doc/release_notes/5.35.0.txt +56 -0
- data/doc/release_notes/5.36.0.txt +60 -0
- data/doc/release_notes/5.37.0.txt +30 -0
- data/doc/release_notes/5.4.0.txt +80 -0
- data/doc/release_notes/5.5.0.txt +61 -0
- data/doc/release_notes/5.6.0.txt +31 -0
- data/doc/release_notes/5.7.0.txt +108 -0
- data/doc/release_notes/5.8.0.txt +170 -0
- data/doc/release_notes/5.9.0.txt +99 -0
- data/doc/schema_modification.rdoc +102 -77
- data/doc/security.rdoc +160 -87
- data/doc/sharding.rdoc +74 -47
- data/doc/sql.rdoc +135 -122
- data/doc/testing.rdoc +34 -18
- data/doc/thread_safety.rdoc +2 -4
- data/doc/transactions.rdoc +101 -19
- data/doc/validations.rdoc +64 -51
- data/doc/virtual_rows.rdoc +90 -109
- data/lib/sequel.rb +3 -1
- data/lib/sequel/adapters/ado.rb +154 -22
- data/lib/sequel/adapters/ado/access.rb +21 -21
- data/lib/sequel/adapters/ado/mssql.rb +8 -15
- data/lib/sequel/adapters/amalgalite.rb +17 -25
- data/lib/sequel/adapters/ibmdb.rb +52 -58
- data/lib/sequel/adapters/jdbc.rb +149 -127
- data/lib/sequel/adapters/jdbc/db2.rb +32 -40
- data/lib/sequel/adapters/jdbc/derby.rb +56 -58
- data/lib/sequel/adapters/jdbc/h2.rb +40 -30
- data/lib/sequel/adapters/jdbc/hsqldb.rb +22 -33
- data/lib/sequel/adapters/jdbc/jtds.rb +4 -10
- data/lib/sequel/adapters/jdbc/mssql.rb +6 -12
- data/lib/sequel/adapters/jdbc/mysql.rb +17 -18
- data/lib/sequel/adapters/jdbc/oracle.rb +25 -19
- data/lib/sequel/adapters/jdbc/postgresql.rb +90 -69
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +14 -24
- data/lib/sequel/adapters/jdbc/sqlite.rb +50 -12
- data/lib/sequel/adapters/jdbc/sqlserver.rb +36 -9
- data/lib/sequel/adapters/jdbc/transactions.rb +25 -39
- data/lib/sequel/adapters/mock.rb +104 -113
- data/lib/sequel/adapters/mysql.rb +42 -61
- data/lib/sequel/adapters/mysql2.rb +126 -35
- data/lib/sequel/adapters/odbc.rb +21 -28
- data/lib/sequel/adapters/odbc/db2.rb +3 -1
- data/lib/sequel/adapters/odbc/mssql.rb +11 -15
- data/lib/sequel/adapters/odbc/oracle.rb +11 -0
- data/lib/sequel/adapters/oracle.rb +62 -68
- data/lib/sequel/adapters/postgres.rb +257 -311
- data/lib/sequel/adapters/postgresql.rb +3 -1
- data/lib/sequel/adapters/shared/access.rb +75 -79
- data/lib/sequel/adapters/shared/db2.rb +96 -74
- data/lib/sequel/adapters/shared/mssql.rb +258 -213
- data/lib/sequel/adapters/shared/mysql.rb +284 -216
- data/lib/sequel/adapters/shared/oracle.rb +175 -60
- data/lib/sequel/adapters/shared/postgres.rb +829 -383
- data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -127
- data/lib/sequel/adapters/shared/sqlite.rb +382 -159
- data/lib/sequel/adapters/sqlanywhere.rb +53 -38
- data/lib/sequel/adapters/sqlite.rb +111 -105
- data/lib/sequel/adapters/tinytds.rb +38 -46
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +8 -9
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +7 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
- data/lib/sequel/adapters/utils/replace.rb +3 -4
- data/lib/sequel/adapters/utils/split_alter_table.rb +2 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
- data/lib/sequel/ast_transformer.rb +13 -89
- data/lib/sequel/connection_pool.rb +54 -26
- data/lib/sequel/connection_pool/sharded_single.rb +19 -12
- data/lib/sequel/connection_pool/sharded_threaded.rb +160 -111
- data/lib/sequel/connection_pool/single.rb +21 -12
- data/lib/sequel/connection_pool/threaded.rb +137 -119
- data/lib/sequel/core.rb +352 -320
- data/lib/sequel/database.rb +19 -2
- data/lib/sequel/database/connecting.rb +70 -55
- data/lib/sequel/database/dataset.rb +15 -5
- data/lib/sequel/database/dataset_defaults.rb +20 -102
- data/lib/sequel/database/features.rb +20 -4
- data/lib/sequel/database/logging.rb +25 -7
- data/lib/sequel/database/misc.rb +132 -118
- data/lib/sequel/database/query.rb +51 -28
- data/lib/sequel/database/schema_generator.rb +188 -75
- data/lib/sequel/database/schema_methods.rb +161 -92
- data/lib/sequel/database/transactions.rb +260 -58
- data/lib/sequel/dataset.rb +28 -12
- data/lib/sequel/dataset/actions.rb +354 -170
- data/lib/sequel/dataset/dataset_module.rb +46 -0
- data/lib/sequel/dataset/features.rb +81 -34
- data/lib/sequel/dataset/graph.rb +82 -58
- data/lib/sequel/dataset/misc.rb +139 -47
- data/lib/sequel/dataset/placeholder_literalizer.rb +66 -26
- data/lib/sequel/dataset/prepared_statements.rb +188 -85
- data/lib/sequel/dataset/query.rb +428 -214
- data/lib/sequel/dataset/sql.rb +446 -339
- data/lib/sequel/deprecated.rb +14 -2
- data/lib/sequel/exceptions.rb +48 -16
- data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
- data/lib/sequel/extensions/_model_pg_row.rb +43 -0
- data/lib/sequel/extensions/_pretty_table.rb +10 -9
- data/lib/sequel/extensions/any_not_empty.rb +45 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +15 -11
- data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
- data/lib/sequel/extensions/blank.rb +2 -0
- data/lib/sequel/extensions/caller_logging.rb +79 -0
- data/lib/sequel/extensions/columns_introspection.rb +9 -4
- data/lib/sequel/extensions/connection_expiration.rb +99 -0
- data/lib/sequel/extensions/connection_validator.rb +26 -13
- data/lib/sequel/extensions/constant_sql_override.rb +65 -0
- data/lib/sequel/extensions/constraint_validations.rb +93 -38
- data/lib/sequel/extensions/core_extensions.rb +45 -53
- data/lib/sequel/extensions/core_refinements.rb +44 -46
- data/lib/sequel/extensions/current_datetime_timestamp.rb +5 -4
- data/lib/sequel/extensions/dataset_source_alias.rb +4 -0
- data/lib/sequel/extensions/date_arithmetic.rb +42 -16
- data/lib/sequel/extensions/datetime_parse_to_time.rb +37 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +94 -0
- data/lib/sequel/extensions/empty_array_consider_nulls.rb +7 -3
- data/lib/sequel/extensions/error_sql.rb +7 -3
- data/lib/sequel/extensions/escaped_like.rb +100 -0
- data/lib/sequel/extensions/eval_inspect.rb +14 -15
- data/lib/sequel/extensions/exclude_or_null.rb +68 -0
- data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
- data/lib/sequel/extensions/freeze_datasets.rb +3 -0
- data/lib/sequel/extensions/from_block.rb +2 -31
- data/lib/sequel/extensions/graph_each.rb +19 -6
- data/lib/sequel/extensions/identifier_mangling.rb +180 -0
- data/lib/sequel/extensions/implicit_subquery.rb +48 -0
- data/lib/sequel/extensions/index_caching.rb +109 -0
- data/lib/sequel/extensions/inflector.rb +8 -4
- data/lib/sequel/extensions/integer64.rb +32 -0
- data/lib/sequel/extensions/looser_typecasting.rb +19 -9
- data/lib/sequel/extensions/migration.rb +132 -80
- data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +4 -0
- data/lib/sequel/extensions/named_timezones.rb +88 -23
- data/lib/sequel/extensions/no_auto_literal_strings.rb +4 -0
- data/lib/sequel/extensions/null_dataset.rb +12 -8
- data/lib/sequel/extensions/pagination.rb +35 -28
- data/lib/sequel/extensions/pg_array.rb +227 -316
- data/lib/sequel/extensions/pg_array_ops.rb +19 -7
- data/lib/sequel/extensions/pg_enum.rb +69 -24
- data/lib/sequel/extensions/pg_extended_date_support.rb +250 -0
- data/lib/sequel/extensions/pg_hstore.rb +50 -59
- data/lib/sequel/extensions/pg_hstore_ops.rb +9 -3
- data/lib/sequel/extensions/pg_inet.rb +34 -15
- data/lib/sequel/extensions/pg_inet_ops.rb +5 -1
- data/lib/sequel/extensions/pg_interval.rb +26 -26
- data/lib/sequel/extensions/pg_json.rb +422 -141
- data/lib/sequel/extensions/pg_json_ops.rb +248 -9
- data/lib/sequel/extensions/pg_loose_count.rb +5 -1
- data/lib/sequel/extensions/pg_range.rb +162 -146
- data/lib/sequel/extensions/pg_range_ops.rb +10 -5
- data/lib/sequel/extensions/pg_row.rb +53 -87
- data/lib/sequel/extensions/pg_row_ops.rb +36 -13
- data/lib/sequel/extensions/pg_static_cache_updater.rb +6 -2
- data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
- data/lib/sequel/extensions/pretty_table.rb +4 -0
- data/lib/sequel/extensions/query.rb +12 -7
- data/lib/sequel/extensions/round_timestamps.rb +6 -9
- data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
- data/lib/sequel/extensions/s.rb +59 -0
- data/lib/sequel/extensions/schema_caching.rb +14 -1
- data/lib/sequel/extensions/schema_dumper.rb +83 -55
- data/lib/sequel/extensions/select_remove.rb +8 -4
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
- data/lib/sequel/extensions/server_block.rb +50 -17
- data/lib/sequel/extensions/server_logging.rb +61 -0
- data/lib/sequel/extensions/split_array_nil.rb +8 -4
- data/lib/sequel/extensions/sql_comments.rb +96 -0
- data/lib/sequel/extensions/sql_expr.rb +4 -1
- data/lib/sequel/extensions/string_agg.rb +181 -0
- data/lib/sequel/extensions/string_date_time.rb +2 -0
- data/lib/sequel/extensions/symbol_aref.rb +53 -0
- data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
- data/lib/sequel/extensions/symbol_as.rb +23 -0
- data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
- data/lib/sequel/extensions/synchronize_sql.rb +45 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +4 -0
- data/lib/sequel/extensions/to_dot.rb +15 -5
- data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
- data/lib/sequel/model.rb +36 -126
- data/lib/sequel/model/associations.rb +850 -257
- data/lib/sequel/model/base.rb +652 -764
- data/lib/sequel/model/dataset_module.rb +13 -10
- data/lib/sequel/model/default_inflections.rb +3 -1
- data/lib/sequel/model/errors.rb +3 -3
- data/lib/sequel/model/exceptions.rb +12 -12
- data/lib/sequel/model/inflections.rb +8 -19
- data/lib/sequel/model/plugins.rb +111 -0
- data/lib/sequel/plugins/accessed_columns.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +32 -7
- data/lib/sequel/plugins/after_initialize.rb +3 -1
- data/lib/sequel/plugins/association_dependencies.rb +27 -18
- data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
- data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
- data/lib/sequel/plugins/association_pks.rb +181 -83
- data/lib/sequel/plugins/association_proxies.rb +33 -9
- data/lib/sequel/plugins/auto_validations.rb +58 -23
- data/lib/sequel/plugins/before_after_save.rb +8 -0
- data/lib/sequel/plugins/blacklist_security.rb +23 -12
- data/lib/sequel/plugins/boolean_readers.rb +9 -6
- data/lib/sequel/plugins/boolean_subsets.rb +64 -0
- data/lib/sequel/plugins/caching.rb +27 -16
- data/lib/sequel/plugins/class_table_inheritance.rb +192 -94
- data/lib/sequel/plugins/column_conflicts.rb +18 -3
- data/lib/sequel/plugins/column_select.rb +9 -5
- data/lib/sequel/plugins/columns_updated.rb +42 -0
- data/lib/sequel/plugins/composition.rb +36 -24
- data/lib/sequel/plugins/constraint_validations.rb +37 -16
- data/lib/sequel/plugins/csv_serializer.rb +58 -35
- data/lib/sequel/plugins/dataset_associations.rb +60 -18
- data/lib/sequel/plugins/def_dataset_method.rb +90 -0
- data/lib/sequel/plugins/defaults_setter.rb +74 -13
- data/lib/sequel/plugins/delay_add_association.rb +4 -1
- data/lib/sequel/plugins/dirty.rb +65 -24
- data/lib/sequel/plugins/eager_each.rb +27 -3
- data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
- data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
- data/lib/sequel/plugins/error_splitter.rb +19 -12
- data/lib/sequel/plugins/finder.rb +246 -0
- data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
- data/lib/sequel/plugins/force_encoding.rb +9 -12
- data/lib/sequel/plugins/hook_class_methods.rb +39 -54
- data/lib/sequel/plugins/input_transformer.rb +20 -10
- data/lib/sequel/plugins/insert_conflict.rb +72 -0
- data/lib/sequel/plugins/insert_returning_select.rb +4 -2
- data/lib/sequel/plugins/instance_filters.rb +12 -8
- data/lib/sequel/plugins/instance_hooks.rb +36 -17
- data/lib/sequel/plugins/instance_specific_default.rb +113 -0
- data/lib/sequel/plugins/inverted_subsets.rb +24 -13
- data/lib/sequel/plugins/json_serializer.rb +123 -47
- data/lib/sequel/plugins/lazy_attributes.rb +20 -14
- data/lib/sequel/plugins/list.rb +40 -26
- data/lib/sequel/plugins/many_through_many.rb +28 -12
- data/lib/sequel/plugins/modification_detection.rb +17 -5
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -5
- data/lib/sequel/plugins/nested_attributes.rb +55 -28
- data/lib/sequel/plugins/optimistic_locking.rb +5 -3
- data/lib/sequel/plugins/pg_array_associations.rb +52 -18
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +348 -0
- data/lib/sequel/plugins/pg_row.rb +7 -51
- data/lib/sequel/plugins/prepared_statements.rb +53 -72
- data/lib/sequel/plugins/prepared_statements_safe.rb +13 -5
- data/lib/sequel/plugins/rcte_tree.rb +43 -63
- data/lib/sequel/plugins/serialization.rb +37 -44
- data/lib/sequel/plugins/serialization_modification_detection.rb +3 -1
- data/lib/sequel/plugins/sharding.rb +17 -10
- data/lib/sequel/plugins/single_table_inheritance.rb +62 -28
- data/lib/sequel/plugins/singular_table_names.rb +2 -0
- data/lib/sequel/plugins/skip_create_refresh.rb +5 -3
- data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
- data/lib/sequel/plugins/split_values.rb +13 -6
- data/lib/sequel/plugins/static_cache.rb +79 -53
- data/lib/sequel/plugins/static_cache_cache.rb +53 -0
- data/lib/sequel/plugins/string_stripper.rb +5 -3
- data/lib/sequel/plugins/subclasses.rb +20 -2
- data/lib/sequel/plugins/subset_conditions.rb +48 -0
- data/lib/sequel/plugins/table_select.rb +4 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +120 -6
- data/lib/sequel/plugins/throw_failures.rb +110 -0
- data/lib/sequel/plugins/timestamps.rb +22 -8
- data/lib/sequel/plugins/touch.rb +21 -8
- data/lib/sequel/plugins/tree.rb +57 -30
- data/lib/sequel/plugins/typecast_on_load.rb +14 -4
- data/lib/sequel/plugins/unlimited_update.rb +3 -7
- data/lib/sequel/plugins/update_or_create.rb +6 -4
- data/lib/sequel/plugins/update_primary_key.rb +3 -1
- data/lib/sequel/plugins/update_refresh.rb +28 -15
- data/lib/sequel/plugins/uuid.rb +70 -0
- data/lib/sequel/plugins/validate_associated.rb +20 -0
- data/lib/sequel/plugins/validation_class_methods.rb +40 -19
- data/lib/sequel/plugins/validation_contexts.rb +49 -0
- data/lib/sequel/plugins/validation_helpers.rb +49 -31
- data/lib/sequel/plugins/whitelist_security.rb +122 -0
- data/lib/sequel/plugins/xml_serializer.rb +31 -30
- data/lib/sequel/sql.rb +479 -329
- data/lib/sequel/timezones.rb +62 -32
- data/lib/sequel/version.rb +10 -3
- metadata +177 -477
- data/Rakefile +0 -165
- data/doc/active_record.rdoc +0 -912
- data/doc/release_notes/1.0.txt +0 -38
- data/doc/release_notes/1.1.txt +0 -143
- data/doc/release_notes/1.3.txt +0 -101
- data/doc/release_notes/1.4.0.txt +0 -53
- data/doc/release_notes/1.5.0.txt +0 -155
- data/doc/release_notes/2.0.0.txt +0 -298
- data/doc/release_notes/2.1.0.txt +0 -271
- data/doc/release_notes/2.10.0.txt +0 -328
- data/doc/release_notes/2.11.0.txt +0 -215
- data/doc/release_notes/2.12.0.txt +0 -534
- data/doc/release_notes/2.2.0.txt +0 -253
- data/doc/release_notes/2.3.0.txt +0 -88
- data/doc/release_notes/2.4.0.txt +0 -106
- data/doc/release_notes/2.5.0.txt +0 -137
- data/doc/release_notes/2.6.0.txt +0 -157
- data/doc/release_notes/2.7.0.txt +0 -166
- data/doc/release_notes/2.8.0.txt +0 -171
- data/doc/release_notes/2.9.0.txt +0 -97
- data/doc/release_notes/3.0.0.txt +0 -221
- data/doc/release_notes/3.1.0.txt +0 -406
- data/doc/release_notes/3.10.0.txt +0 -286
- data/doc/release_notes/3.11.0.txt +0 -254
- data/doc/release_notes/3.12.0.txt +0 -304
- data/doc/release_notes/3.13.0.txt +0 -210
- data/doc/release_notes/3.14.0.txt +0 -118
- data/doc/release_notes/3.15.0.txt +0 -78
- data/doc/release_notes/3.16.0.txt +0 -45
- data/doc/release_notes/3.17.0.txt +0 -58
- data/doc/release_notes/3.18.0.txt +0 -120
- data/doc/release_notes/3.19.0.txt +0 -67
- data/doc/release_notes/3.2.0.txt +0 -268
- data/doc/release_notes/3.20.0.txt +0 -41
- data/doc/release_notes/3.21.0.txt +0 -87
- data/doc/release_notes/3.22.0.txt +0 -39
- data/doc/release_notes/3.23.0.txt +0 -172
- data/doc/release_notes/3.24.0.txt +0 -420
- data/doc/release_notes/3.25.0.txt +0 -88
- data/doc/release_notes/3.26.0.txt +0 -88
- data/doc/release_notes/3.27.0.txt +0 -82
- data/doc/release_notes/3.28.0.txt +0 -304
- data/doc/release_notes/3.29.0.txt +0 -459
- data/doc/release_notes/3.3.0.txt +0 -192
- data/doc/release_notes/3.30.0.txt +0 -135
- data/doc/release_notes/3.31.0.txt +0 -146
- data/doc/release_notes/3.32.0.txt +0 -202
- data/doc/release_notes/3.33.0.txt +0 -157
- data/doc/release_notes/3.34.0.txt +0 -671
- data/doc/release_notes/3.35.0.txt +0 -144
- data/doc/release_notes/3.36.0.txt +0 -245
- data/doc/release_notes/3.37.0.txt +0 -338
- data/doc/release_notes/3.38.0.txt +0 -234
- data/doc/release_notes/3.39.0.txt +0 -237
- data/doc/release_notes/3.4.0.txt +0 -325
- data/doc/release_notes/3.40.0.txt +0 -73
- data/doc/release_notes/3.41.0.txt +0 -155
- data/doc/release_notes/3.42.0.txt +0 -74
- data/doc/release_notes/3.43.0.txt +0 -105
- data/doc/release_notes/3.44.0.txt +0 -152
- data/doc/release_notes/3.45.0.txt +0 -179
- data/doc/release_notes/3.46.0.txt +0 -122
- data/doc/release_notes/3.47.0.txt +0 -270
- data/doc/release_notes/3.48.0.txt +0 -477
- data/doc/release_notes/3.5.0.txt +0 -510
- data/doc/release_notes/3.6.0.txt +0 -366
- data/doc/release_notes/3.7.0.txt +0 -179
- data/doc/release_notes/3.8.0.txt +0 -151
- data/doc/release_notes/3.9.0.txt +0 -233
- data/doc/release_notes/4.0.0.txt +0 -262
- data/doc/release_notes/4.1.0.txt +0 -85
- data/doc/release_notes/4.10.0.txt +0 -226
- data/doc/release_notes/4.11.0.txt +0 -147
- data/doc/release_notes/4.12.0.txt +0 -105
- data/doc/release_notes/4.13.0.txt +0 -169
- data/doc/release_notes/4.14.0.txt +0 -68
- data/doc/release_notes/4.15.0.txt +0 -56
- data/doc/release_notes/4.16.0.txt +0 -36
- data/doc/release_notes/4.17.0.txt +0 -38
- data/doc/release_notes/4.18.0.txt +0 -36
- data/doc/release_notes/4.19.0.txt +0 -45
- data/doc/release_notes/4.2.0.txt +0 -129
- data/doc/release_notes/4.20.0.txt +0 -79
- data/doc/release_notes/4.21.0.txt +0 -94
- data/doc/release_notes/4.22.0.txt +0 -72
- data/doc/release_notes/4.23.0.txt +0 -65
- data/doc/release_notes/4.24.0.txt +0 -99
- data/doc/release_notes/4.25.0.txt +0 -181
- data/doc/release_notes/4.26.0.txt +0 -44
- data/doc/release_notes/4.3.0.txt +0 -40
- data/doc/release_notes/4.4.0.txt +0 -92
- data/doc/release_notes/4.5.0.txt +0 -34
- data/doc/release_notes/4.6.0.txt +0 -30
- data/doc/release_notes/4.7.0.txt +0 -103
- data/doc/release_notes/4.8.0.txt +0 -175
- data/doc/release_notes/4.9.0.txt +0 -190
- data/lib/sequel/adapters/cubrid.rb +0 -142
- data/lib/sequel/adapters/do.rb +0 -156
- data/lib/sequel/adapters/do/mysql.rb +0 -64
- data/lib/sequel/adapters/do/postgres.rb +0 -42
- data/lib/sequel/adapters/do/sqlite3.rb +0 -40
- data/lib/sequel/adapters/jdbc/as400.rb +0 -82
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -62
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -34
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -31
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -31
- data/lib/sequel/adapters/odbc/progress.rb +0 -8
- data/lib/sequel/adapters/shared/cubrid.rb +0 -243
- data/lib/sequel/adapters/shared/firebird.rb +0 -245
- data/lib/sequel/adapters/shared/informix.rb +0 -52
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -150
- data/lib/sequel/adapters/shared/progress.rb +0 -38
- data/lib/sequel/adapters/swift.rb +0 -158
- data/lib/sequel/adapters/swift/mysql.rb +0 -47
- data/lib/sequel/adapters/swift/postgres.rb +0 -45
- data/lib/sequel/adapters/swift/sqlite.rb +0 -47
- data/lib/sequel/adapters/utils/pg_types.rb +0 -68
- data/lib/sequel/dataset/mutation.rb +0 -109
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -3
- data/lib/sequel/extensions/filter_having.rb +0 -59
- data/lib/sequel/extensions/hash_aliases.rb +0 -45
- data/lib/sequel/extensions/meta_def.rb +0 -31
- data/lib/sequel/extensions/query_literals.rb +0 -80
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -22
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -118
- data/lib/sequel/extensions/set_overrides.rb +0 -72
- data/lib/sequel/no_core_ext.rb +0 -1
- data/lib/sequel/plugins/association_autoreloading.rb +0 -7
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -7
- data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -78
- data/lib/sequel/plugins/prepared_statements_associations.rb +0 -117
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -59
- data/lib/sequel/plugins/schema.rb +0 -80
- data/lib/sequel/plugins/scissors.rb +0 -33
- data/spec/adapters/db2_spec.rb +0 -160
- data/spec/adapters/firebird_spec.rb +0 -411
- data/spec/adapters/informix_spec.rb +0 -100
- data/spec/adapters/mssql_spec.rb +0 -706
- data/spec/adapters/mysql_spec.rb +0 -1287
- data/spec/adapters/oracle_spec.rb +0 -313
- data/spec/adapters/postgres_spec.rb +0 -3725
- data/spec/adapters/spec_helper.rb +0 -43
- data/spec/adapters/sqlanywhere_spec.rb +0 -170
- data/spec/adapters/sqlite_spec.rb +0 -653
- data/spec/bin_spec.rb +0 -254
- data/spec/core/connection_pool_spec.rb +0 -1016
- data/spec/core/database_spec.rb +0 -2531
- data/spec/core/dataset_spec.rb +0 -5098
- data/spec/core/deprecated_spec.rb +0 -70
- data/spec/core/expression_filters_spec.rb +0 -1243
- data/spec/core/mock_adapter_spec.rb +0 -462
- data/spec/core/object_graph_spec.rb +0 -303
- data/spec/core/placeholder_literalizer_spec.rb +0 -163
- data/spec/core/schema_generator_spec.rb +0 -179
- data/spec/core/schema_spec.rb +0 -1659
- data/spec/core/spec_helper.rb +0 -34
- data/spec/core/version_spec.rb +0 -7
- data/spec/core_extensions_spec.rb +0 -699
- data/spec/extensions/accessed_columns_spec.rb +0 -51
- data/spec/extensions/active_model_spec.rb +0 -123
- data/spec/extensions/after_initialize_spec.rb +0 -24
- data/spec/extensions/arbitrary_servers_spec.rb +0 -109
- data/spec/extensions/association_dependencies_spec.rb +0 -117
- data/spec/extensions/association_pks_spec.rb +0 -365
- data/spec/extensions/association_proxies_spec.rb +0 -86
- data/spec/extensions/auto_validations_spec.rb +0 -192
- data/spec/extensions/blacklist_security_spec.rb +0 -88
- data/spec/extensions/blank_spec.rb +0 -69
- data/spec/extensions/boolean_readers_spec.rb +0 -93
- data/spec/extensions/caching_spec.rb +0 -270
- data/spec/extensions/class_table_inheritance_spec.rb +0 -420
- data/spec/extensions/column_conflicts_spec.rb +0 -60
- data/spec/extensions/column_select_spec.rb +0 -108
- data/spec/extensions/columns_introspection_spec.rb +0 -91
- data/spec/extensions/composition_spec.rb +0 -242
- data/spec/extensions/connection_validator_spec.rb +0 -120
- data/spec/extensions/constraint_validations_plugin_spec.rb +0 -274
- data/spec/extensions/constraint_validations_spec.rb +0 -325
- data/spec/extensions/core_refinements_spec.rb +0 -519
- data/spec/extensions/csv_serializer_spec.rb +0 -173
- data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
- data/spec/extensions/dataset_associations_spec.rb +0 -311
- data/spec/extensions/dataset_source_alias_spec.rb +0 -51
- data/spec/extensions/date_arithmetic_spec.rb +0 -150
- data/spec/extensions/defaults_setter_spec.rb +0 -101
- data/spec/extensions/delay_add_association_spec.rb +0 -52
- data/spec/extensions/dirty_spec.rb +0 -180
- data/spec/extensions/eager_each_spec.rb +0 -42
- data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
- data/spec/extensions/error_splitter_spec.rb +0 -18
- data/spec/extensions/error_sql_spec.rb +0 -20
- data/spec/extensions/eval_inspect_spec.rb +0 -73
- data/spec/extensions/filter_having_spec.rb +0 -40
- data/spec/extensions/force_encoding_spec.rb +0 -114
- data/spec/extensions/from_block_spec.rb +0 -21
- data/spec/extensions/graph_each_spec.rb +0 -109
- data/spec/extensions/hash_aliases_spec.rb +0 -24
- data/spec/extensions/hook_class_methods_spec.rb +0 -429
- data/spec/extensions/inflector_spec.rb +0 -183
- data/spec/extensions/input_transformer_spec.rb +0 -54
- data/spec/extensions/insert_returning_select_spec.rb +0 -46
- data/spec/extensions/instance_filters_spec.rb +0 -79
- data/spec/extensions/instance_hooks_spec.rb +0 -276
- data/spec/extensions/inverted_subsets_spec.rb +0 -33
- data/spec/extensions/json_serializer_spec.rb +0 -291
- data/spec/extensions/lazy_attributes_spec.rb +0 -170
- data/spec/extensions/list_spec.rb +0 -267
- data/spec/extensions/looser_typecasting_spec.rb +0 -43
- data/spec/extensions/many_through_many_spec.rb +0 -2172
- data/spec/extensions/meta_def_spec.rb +0 -21
- data/spec/extensions/migration_spec.rb +0 -712
- data/spec/extensions/modification_detection_spec.rb +0 -80
- data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
- data/spec/extensions/named_timezones_spec.rb +0 -108
- data/spec/extensions/nested_attributes_spec.rb +0 -697
- data/spec/extensions/null_dataset_spec.rb +0 -85
- data/spec/extensions/optimistic_locking_spec.rb +0 -128
- data/spec/extensions/pagination_spec.rb +0 -118
- data/spec/extensions/pg_array_associations_spec.rb +0 -736
- data/spec/extensions/pg_array_ops_spec.rb +0 -143
- data/spec/extensions/pg_array_spec.rb +0 -395
- data/spec/extensions/pg_enum_spec.rb +0 -92
- data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
- data/spec/extensions/pg_hstore_spec.rb +0 -206
- data/spec/extensions/pg_inet_ops_spec.rb +0 -101
- data/spec/extensions/pg_inet_spec.rb +0 -52
- data/spec/extensions/pg_interval_spec.rb +0 -76
- data/spec/extensions/pg_json_ops_spec.rb +0 -229
- data/spec/extensions/pg_json_spec.rb +0 -218
- data/spec/extensions/pg_loose_count_spec.rb +0 -17
- data/spec/extensions/pg_range_ops_spec.rb +0 -58
- data/spec/extensions/pg_range_spec.rb +0 -404
- data/spec/extensions/pg_row_ops_spec.rb +0 -60
- data/spec/extensions/pg_row_plugin_spec.rb +0 -62
- data/spec/extensions/pg_row_spec.rb +0 -360
- data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
- data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
- data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
- data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
- data/spec/extensions/prepared_statements_spec.rb +0 -103
- data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
- data/spec/extensions/pretty_table_spec.rb +0 -92
- data/spec/extensions/query_literals_spec.rb +0 -183
- data/spec/extensions/query_spec.rb +0 -102
- data/spec/extensions/rcte_tree_spec.rb +0 -392
- data/spec/extensions/round_timestamps_spec.rb +0 -43
- data/spec/extensions/schema_caching_spec.rb +0 -41
- data/spec/extensions/schema_dumper_spec.rb +0 -789
- data/spec/extensions/schema_spec.rb +0 -117
- data/spec/extensions/scissors_spec.rb +0 -26
- data/spec/extensions/select_remove_spec.rb +0 -38
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
- data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
- data/spec/extensions/serialization_spec.rb +0 -362
- data/spec/extensions/server_block_spec.rb +0 -90
- data/spec/extensions/set_overrides_spec.rb +0 -61
- data/spec/extensions/sharding_spec.rb +0 -198
- data/spec/extensions/shared_caching_spec.rb +0 -175
- data/spec/extensions/single_table_inheritance_spec.rb +0 -297
- data/spec/extensions/singular_table_names_spec.rb +0 -22
- data/spec/extensions/skip_create_refresh_spec.rb +0 -17
- data/spec/extensions/spec_helper.rb +0 -71
- data/spec/extensions/split_array_nil_spec.rb +0 -24
- data/spec/extensions/split_values_spec.rb +0 -22
- data/spec/extensions/sql_expr_spec.rb +0 -60
- data/spec/extensions/static_cache_spec.rb +0 -361
- data/spec/extensions/string_date_time_spec.rb +0 -95
- data/spec/extensions/string_stripper_spec.rb +0 -68
- data/spec/extensions/subclasses_spec.rb +0 -66
- data/spec/extensions/table_select_spec.rb +0 -71
- data/spec/extensions/tactical_eager_loading_spec.rb +0 -82
- data/spec/extensions/thread_local_timezones_spec.rb +0 -67
- data/spec/extensions/timestamps_spec.rb +0 -175
- data/spec/extensions/to_dot_spec.rb +0 -154
- data/spec/extensions/touch_spec.rb +0 -203
- data/spec/extensions/tree_spec.rb +0 -274
- data/spec/extensions/typecast_on_load_spec.rb +0 -80
- data/spec/extensions/unlimited_update_spec.rb +0 -20
- data/spec/extensions/update_or_create_spec.rb +0 -87
- data/spec/extensions/update_primary_key_spec.rb +0 -100
- data/spec/extensions/update_refresh_spec.rb +0 -53
- data/spec/extensions/validate_associated_spec.rb +0 -52
- data/spec/extensions/validation_class_methods_spec.rb +0 -1027
- data/spec/extensions/validation_helpers_spec.rb +0 -541
- data/spec/extensions/xml_serializer_spec.rb +0 -207
- data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
- data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
- data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
- data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
- data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
- data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
- data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
- data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
- data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
- data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
- data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
- data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
- data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
- data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/reversible_migrations/001_reversible.rb +0 -5
- data/spec/files/reversible_migrations/002_reversible.rb +0 -5
- data/spec/files/reversible_migrations/003_reversible.rb +0 -5
- data/spec/files/reversible_migrations/004_reversible.rb +0 -5
- data/spec/files/reversible_migrations/005_reversible.rb +0 -10
- data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
- data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
- data/spec/guards_helper.rb +0 -55
- data/spec/integration/associations_test.rb +0 -2454
- data/spec/integration/database_test.rb +0 -113
- data/spec/integration/dataset_test.rb +0 -1808
- data/spec/integration/eager_loader_test.rb +0 -687
- data/spec/integration/migrator_test.rb +0 -240
- data/spec/integration/model_test.rb +0 -226
- data/spec/integration/plugin_test.rb +0 -2240
- data/spec/integration/prepared_statement_test.rb +0 -467
- data/spec/integration/schema_test.rb +0 -817
- data/spec/integration/spec_helper.rb +0 -48
- data/spec/integration/timezone_test.rb +0 -86
- data/spec/integration/transaction_test.rb +0 -374
- data/spec/integration/type_test.rb +0 -133
- data/spec/model/association_reflection_spec.rb +0 -525
- data/spec/model/associations_spec.rb +0 -4426
- data/spec/model/base_spec.rb +0 -759
- data/spec/model/class_dataset_methods_spec.rb +0 -146
- data/spec/model/dataset_methods_spec.rb +0 -149
- data/spec/model/eager_loading_spec.rb +0 -2137
- data/spec/model/hooks_spec.rb +0 -604
- data/spec/model/inflector_spec.rb +0 -26
- data/spec/model/model_spec.rb +0 -982
- data/spec/model/plugins_spec.rb +0 -299
- data/spec/model/record_spec.rb +0 -2147
- data/spec/model/spec_helper.rb +0 -46
- data/spec/model/validations_spec.rb +0 -193
- data/spec/sequel_coverage.rb +0 -15
- data/spec/spec_config.rb +0 -10
data/lib/sequel/sql.rb
CHANGED
|
@@ -1,39 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
if RUBY_VERSION < '1.9.0'
|
|
3
|
-
# :nocov:
|
|
4
|
-
# If on Ruby 1.8, create a <tt>Sequel::BasicObject</tt> class that is similar to the
|
|
5
|
-
# the Ruby 1.9 +BasicObject+ class. This is used in a few places where proxy
|
|
6
|
-
# objects are needed that respond to any method call.
|
|
7
|
-
class BasicObject
|
|
8
|
-
# The instance methods to not remove from the class when removing
|
|
9
|
-
# other methods.
|
|
10
|
-
KEEP_METHODS = %w"__id__ __send__ __metaclass__ instance_eval instance_exec == equal? initialize method_missing"
|
|
11
|
-
|
|
12
|
-
# Remove all but the most basic instance methods from the class. A separate
|
|
13
|
-
# method so that it can be called again if necessary if you load libraries
|
|
14
|
-
# after Sequel that add instance methods to +Object+.
|
|
15
|
-
def self.remove_methods!
|
|
16
|
-
((private_instance_methods + instance_methods) - KEEP_METHODS).each{|m| undef_method(m)}
|
|
17
|
-
end
|
|
18
|
-
remove_methods!
|
|
19
|
-
end
|
|
20
|
-
# :nocov:
|
|
21
|
-
else
|
|
22
|
-
# If on 1.9, create a <tt>Sequel::BasicObject</tt> class that is just like the
|
|
23
|
-
# default +BasicObject+ class, except that missing constants are resolved in
|
|
24
|
-
# +Object+. This allows the virtual row support to work with classes
|
|
25
|
-
# without prefixing them with ::, such as:
|
|
26
|
-
#
|
|
27
|
-
# DB[:bonds].filter{maturity_date > Time.now}
|
|
28
|
-
class BasicObject < ::BasicObject
|
|
29
|
-
# Lookup missing constants in <tt>::Object</tt>
|
|
30
|
-
def self.const_missing(name)
|
|
31
|
-
::Object.const_get(name)
|
|
32
|
-
end
|
|
1
|
+
# frozen-string-literal: true
|
|
33
2
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
3
|
+
module Sequel
|
|
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)
|
|
37
14
|
end
|
|
38
15
|
end
|
|
39
16
|
|
|
@@ -41,12 +18,47 @@ module Sequel
|
|
|
41
18
|
end
|
|
42
19
|
|
|
43
20
|
# Time subclass that gets literalized with only the time value, so it operates
|
|
44
|
-
# 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.
|
|
45
23
|
class SQLTime < ::Time
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
24
|
+
@date = nil
|
|
25
|
+
|
|
26
|
+
class << self
|
|
27
|
+
# Set the date used for SQLTime instances.
|
|
28
|
+
attr_writer :date
|
|
29
|
+
|
|
30
|
+
# Use the date explicitly set, or the current date if there is not a
|
|
31
|
+
# date set.
|
|
32
|
+
def date
|
|
33
|
+
@date || now
|
|
34
|
+
end
|
|
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
|
+
|
|
51
|
+
# Create a new SQLTime instance given an hour, minute, second, and usec.
|
|
52
|
+
def create(hour, minute, second, usec = 0)
|
|
53
|
+
t = date
|
|
54
|
+
meth = Sequel.application_timezone == :utc ? :utc : :local
|
|
55
|
+
public_send(meth, t.year, t.month, t.day, hour, minute, second, usec)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Show that this is an SQLTime, and the time represented
|
|
60
|
+
def inspect
|
|
61
|
+
"#<#{self.class} #{to_s}>"
|
|
50
62
|
end
|
|
51
63
|
|
|
52
64
|
# Return a string in HH:MM:SS format representing the time.
|
|
@@ -62,18 +74,11 @@ module Sequel
|
|
|
62
74
|
end
|
|
63
75
|
|
|
64
76
|
# The SQL module holds classes whose instances represent SQL fragments.
|
|
65
|
-
# It also holds modules that are
|
|
66
|
-
# make Sequel a friendly DSL.
|
|
77
|
+
# It also holds modules that are used by these classes.
|
|
67
78
|
module SQL
|
|
68
|
-
|
|
69
|
-
### Parent Classes ###
|
|
70
|
-
|
|
71
|
-
# Classes/Modules aren't in alphabetical order due to the fact that
|
|
72
|
-
# some reference constants defined in others at load time.
|
|
73
|
-
|
|
74
79
|
# Base class for all SQL expression objects.
|
|
75
80
|
class Expression
|
|
76
|
-
@comparison_attrs = []
|
|
81
|
+
@comparison_attrs = [].freeze
|
|
77
82
|
|
|
78
83
|
class << self
|
|
79
84
|
# All attributes used for equality and hash methods.
|
|
@@ -95,7 +100,7 @@ module Sequel
|
|
|
95
100
|
subclass.instance_variable_set(:@comparison_attrs, comparison_attrs.dup)
|
|
96
101
|
end
|
|
97
102
|
|
|
98
|
-
|
|
103
|
+
private
|
|
99
104
|
|
|
100
105
|
# Create a to_s instance method that takes a dataset, and calls
|
|
101
106
|
# the method provided on the dataset with args as the argument (self by default).
|
|
@@ -105,9 +110,17 @@ module Sequel
|
|
|
105
110
|
# arbitrary code execution.
|
|
106
111
|
def to_s_method(meth, args=:self) # :nodoc:
|
|
107
112
|
class_eval("def to_s_append(ds, sql) ds.#{meth}_append(sql, #{args}) end", __FILE__, __LINE__)
|
|
113
|
+
@comparison_attrs.freeze
|
|
108
114
|
end
|
|
109
115
|
end
|
|
110
116
|
|
|
117
|
+
# Make clone/dup return self, since Expression objects are supposed to
|
|
118
|
+
# be frozen value objects
|
|
119
|
+
def clone
|
|
120
|
+
self
|
|
121
|
+
end
|
|
122
|
+
alias dup clone
|
|
123
|
+
|
|
111
124
|
# Alias of <tt>eql?</tt>
|
|
112
125
|
def ==(other)
|
|
113
126
|
eql?(other)
|
|
@@ -116,34 +129,21 @@ module Sequel
|
|
|
116
129
|
# Returns true if the receiver is the same expression as the
|
|
117
130
|
# the +other+ expression.
|
|
118
131
|
def eql?(other)
|
|
119
|
-
other.is_a?(self.class) && !self.class.comparison_attrs.find{|a|
|
|
132
|
+
other.is_a?(self.class) && !self.class.comparison_attrs.find{|a| public_send(a) != other.public_send(a)}
|
|
120
133
|
end
|
|
121
134
|
|
|
122
135
|
# Make sure that the hash value is the same if the attributes are the same.
|
|
123
136
|
def hash
|
|
124
|
-
([self.class] + self.class.comparison_attrs.map{|x|
|
|
137
|
+
([self.class] + self.class.comparison_attrs.map{|x| public_send(x)}).hash
|
|
125
138
|
end
|
|
126
139
|
|
|
127
|
-
# Show the class name and instance variables for the object
|
|
128
|
-
# for correct operation on ruby 1.9.2.
|
|
140
|
+
# Show the class name and instance variables for the object.
|
|
129
141
|
def inspect
|
|
130
142
|
"#<#{self.class} #{instance_variables.map{|iv| "#{iv}=>#{instance_variable_get(iv).inspect}"}.join(', ')}>"
|
|
131
143
|
end
|
|
132
|
-
|
|
133
|
-
# Returns +self+, because <tt>SQL::Expression</tt> already acts like +LiteralString+.
|
|
134
|
-
def lit
|
|
135
|
-
self
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
# Alias of +to_s+
|
|
139
|
-
def sql_literal(ds)
|
|
140
|
-
s = ''
|
|
141
|
-
to_s_append(ds, s)
|
|
142
|
-
s
|
|
143
|
-
end
|
|
144
144
|
end
|
|
145
145
|
|
|
146
|
-
# Represents a
|
|
146
|
+
# Represents a SQL expression, with a given operator and one
|
|
147
147
|
# or more attributes (which may also be ComplexExpressions, forming
|
|
148
148
|
# a tree). This class is the backbone of Sequel's ruby expression DSL.
|
|
149
149
|
#
|
|
@@ -158,46 +158,49 @@ module Sequel
|
|
|
158
158
|
:'NOT LIKE' => :LIKE, :~ => :'!~', :'!~' => :~, :IN => :'NOT IN',
|
|
159
159
|
:'NOT IN' => :IN, :IS => :'IS NOT', :'IS NOT' => :IS, :'~*' => :'!~*',
|
|
160
160
|
:'!~*' => :'~*', :NOT => :NOOP, :NOOP => :NOT, :ILIKE => :'NOT ILIKE',
|
|
161
|
-
:'NOT ILIKE'=>:ILIKE}
|
|
161
|
+
:'NOT ILIKE'=>:ILIKE}.freeze
|
|
162
162
|
|
|
163
163
|
# Standard mathematical operators used in +NumericMethods+
|
|
164
|
-
MATHEMATICAL_OPERATORS = [:+, :-, :/,
|
|
164
|
+
MATHEMATICAL_OPERATORS = [:+, :-, :/, :*, :**].freeze
|
|
165
165
|
|
|
166
|
-
# Bitwise mathematical operators used in +
|
|
167
|
-
BITWISE_OPERATORS = [:&, :|, :^, :<<, :>>, :%]
|
|
166
|
+
# Bitwise mathematical operators used in +BitwiseMethods+
|
|
167
|
+
BITWISE_OPERATORS = [:&, :|, :^, :<<, :>>, :%].freeze
|
|
168
168
|
|
|
169
169
|
# Operators that check for equality
|
|
170
|
-
EQUALITY_OPERATORS = [:'=', :'!=']
|
|
170
|
+
EQUALITY_OPERATORS = [:'=', :'!='].freeze
|
|
171
171
|
|
|
172
172
|
# Inequality operators used in +InequalityMethods+
|
|
173
|
-
INEQUALITY_OPERATORS = [:<, :>, :<=, :>=]
|
|
173
|
+
INEQUALITY_OPERATORS = [:<, :>, :<=, :>=].freeze
|
|
174
174
|
|
|
175
175
|
# Hash of ruby operator symbols to SQL operators, used in +BooleanMethods+
|
|
176
|
-
BOOLEAN_OPERATOR_METHODS = {:& => :AND, :| =>:OR}
|
|
176
|
+
BOOLEAN_OPERATOR_METHODS = {:& => :AND, :| =>:OR}.freeze
|
|
177
177
|
|
|
178
178
|
# Operators that use IN/NOT IN for inclusion/exclusion
|
|
179
|
-
IN_OPERATORS = [:IN, :'NOT IN']
|
|
179
|
+
IN_OPERATORS = [:IN, :'NOT IN'].freeze
|
|
180
180
|
|
|
181
181
|
# Operators that use IS, used for special casing to override literal true/false values
|
|
182
|
-
IS_OPERATORS = [:IS, :'IS NOT']
|
|
182
|
+
IS_OPERATORS = [:IS, :'IS NOT'].freeze
|
|
183
183
|
|
|
184
184
|
# Operators that do pattern matching via regular expressions
|
|
185
|
-
REGEXP_OPERATORS = [:~, :'!~', :'~*', :'!~*']
|
|
185
|
+
REGEXP_OPERATORS = [:~, :'!~', :'~*', :'!~*'].freeze
|
|
186
186
|
|
|
187
187
|
# Operators that do pattern matching via LIKE
|
|
188
|
-
LIKE_OPERATORS = [:LIKE, :'NOT LIKE', :ILIKE, :'NOT ILIKE']
|
|
188
|
+
LIKE_OPERATORS = [:LIKE, :'NOT LIKE', :ILIKE, :'NOT ILIKE'].freeze
|
|
189
189
|
|
|
190
190
|
# Operator symbols that take exactly two arguments
|
|
191
|
-
TWO_ARITY_OPERATORS = EQUALITY_OPERATORS + INEQUALITY_OPERATORS + IS_OPERATORS + IN_OPERATORS + REGEXP_OPERATORS + LIKE_OPERATORS
|
|
191
|
+
TWO_ARITY_OPERATORS = (EQUALITY_OPERATORS + INEQUALITY_OPERATORS + IS_OPERATORS + IN_OPERATORS + REGEXP_OPERATORS + LIKE_OPERATORS + [:**]).freeze
|
|
192
192
|
|
|
193
193
|
# Operator symbols that take one or more arguments
|
|
194
|
-
N_ARITY_OPERATORS = [:AND, :OR, :'||'] + MATHEMATICAL_OPERATORS + BITWISE_OPERATORS
|
|
194
|
+
N_ARITY_OPERATORS = ([:AND, :OR, :'||'] + MATHEMATICAL_OPERATORS + BITWISE_OPERATORS - [:**]).freeze
|
|
195
|
+
|
|
196
|
+
# Operator symbols that are associative
|
|
197
|
+
ASSOCIATIVE_OPERATORS = [:AND, :OR, :'||', :+, :*, :&, :|].freeze
|
|
195
198
|
|
|
196
199
|
# Operator symbols that take only a single argument
|
|
197
|
-
ONE_ARITY_OPERATORS = [:NOT, :NOOP, :'B~']
|
|
200
|
+
ONE_ARITY_OPERATORS = [:NOT, :NOOP, :'B~'].freeze
|
|
198
201
|
|
|
199
202
|
# Custom expressions that may have different syntax on different databases
|
|
200
|
-
CUSTOM_EXPRESSIONS = [:extract]
|
|
203
|
+
CUSTOM_EXPRESSIONS = [:extract].freeze
|
|
201
204
|
|
|
202
205
|
# The operator symbol for this object
|
|
203
206
|
attr_reader :op
|
|
@@ -216,9 +219,12 @@ module Sequel
|
|
|
216
219
|
case op
|
|
217
220
|
when *N_ARITY_OPERATORS
|
|
218
221
|
raise(Error, "The #{op} operator requires at least 1 argument") unless args.length >= 1
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
+
args.map!{|a| a.is_a?(self.class) && a.op == :NOOP ? a.args.first : a}
|
|
223
|
+
if ASSOCIATIVE_OPERATORS.include?(op)
|
|
224
|
+
old_args = args
|
|
225
|
+
args = []
|
|
226
|
+
old_args.each{|a| a.is_a?(self.class) && a.op == op ? args.concat(a.args) : args.push(a)}
|
|
227
|
+
end
|
|
222
228
|
when *TWO_ARITY_OPERATORS
|
|
223
229
|
raise(Error, "The #{op} operator requires precisely 2 arguments") unless args.length == 2
|
|
224
230
|
# With IN/NOT IN, even if the second argument is an array of two element arrays,
|
|
@@ -233,7 +239,8 @@ module Sequel
|
|
|
233
239
|
raise(Error, "Invalid operator #{op}")
|
|
234
240
|
end
|
|
235
241
|
@op = op
|
|
236
|
-
@args = args
|
|
242
|
+
@args = args.freeze
|
|
243
|
+
freeze
|
|
237
244
|
end
|
|
238
245
|
|
|
239
246
|
to_s_method :complex_expression_sql, '@op, @args'
|
|
@@ -244,8 +251,6 @@ module Sequel
|
|
|
244
251
|
class GenericExpression < Expression
|
|
245
252
|
end
|
|
246
253
|
|
|
247
|
-
### Modules ###
|
|
248
|
-
|
|
249
254
|
# Includes an +as+ method that creates an SQL alias.
|
|
250
255
|
module AliasMethods
|
|
251
256
|
# Create an SQL alias (+AliasedExpression+) of the receiving column or expression to the given alias.
|
|
@@ -261,12 +266,12 @@ module Sequel
|
|
|
261
266
|
# methods overlap with the standard +BooleanMethods methods+, and they only
|
|
262
267
|
# make sense for integers, they are only included in +NumericExpression+.
|
|
263
268
|
#
|
|
264
|
-
# :a.sql_number & :b # "a" & "b"
|
|
265
|
-
# :a.sql_number | :b # "a" | "b"
|
|
266
|
-
# :a.sql_number ^ :b # "a" ^ "b"
|
|
267
|
-
# :a.sql_number << :b # "a" << "b"
|
|
268
|
-
# :a.sql_number >> :b # "a" >> "b"
|
|
269
|
-
#
|
|
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"
|
|
270
275
|
module BitwiseMethods
|
|
271
276
|
ComplexExpression::BITWISE_OPERATORS.each do |o|
|
|
272
277
|
module_eval("def #{o}(o) NumericExpression.new(#{o.inspect}, self, o) end", __FILE__, __LINE__)
|
|
@@ -274,25 +279,24 @@ module Sequel
|
|
|
274
279
|
|
|
275
280
|
# Do the bitwise compliment of the self
|
|
276
281
|
#
|
|
277
|
-
#
|
|
282
|
+
# ~(Sequel[:a].sql_number) # ~"a"
|
|
278
283
|
def ~
|
|
279
284
|
NumericExpression.new(:'B~', self)
|
|
280
285
|
end
|
|
281
286
|
end
|
|
282
287
|
|
|
283
288
|
# This module includes the boolean/logical AND (&), OR (|) and NOT (~) operators
|
|
284
|
-
# that are defined on objects that can be used in a boolean context in SQL
|
|
285
|
-
# (+Symbol+, +LiteralString+, and <tt>SQL::GenericExpression</tt>).
|
|
289
|
+
# that are defined on objects that can be used in a boolean context in SQL.
|
|
286
290
|
#
|
|
287
|
-
# :a & :b # "a" AND "b"
|
|
288
|
-
# :a | :b # "a" OR "b"
|
|
289
|
-
#
|
|
291
|
+
# Sequel[:a] & Sequel[:b] # "a" AND "b"
|
|
292
|
+
# Sequel[:a] | Sequel[:b] # "a" OR "b"
|
|
293
|
+
# ~Sequel[:a] # NOT "a"
|
|
290
294
|
#
|
|
291
295
|
# One exception to this is when a NumericExpression or Integer is the argument
|
|
292
296
|
# to & or |, in which case a bitwise method will be used:
|
|
293
297
|
#
|
|
294
|
-
# :a & 1 # "a" & 1
|
|
295
|
-
# :a | (:b + 1) # "a" | ("b" + 1)
|
|
298
|
+
# Sequel[:a] & 1 # "a" & 1
|
|
299
|
+
# Sequel[:a] | (Sequel[:b] + 1) # "a" | ("b" + 1)
|
|
296
300
|
module BooleanMethods
|
|
297
301
|
ComplexExpression::BOOLEAN_OPERATOR_METHODS.each do |m, o|
|
|
298
302
|
module_eval(<<-END, __FILE__, __LINE__+1)
|
|
@@ -309,14 +313,14 @@ module Sequel
|
|
|
309
313
|
|
|
310
314
|
# Create a new BooleanExpression with NOT, representing the inversion of whatever self represents.
|
|
311
315
|
#
|
|
312
|
-
#
|
|
316
|
+
# ~Sequel[:a] # NOT :a
|
|
313
317
|
def ~
|
|
314
318
|
BooleanExpression.invert(self)
|
|
315
319
|
end
|
|
316
320
|
end
|
|
317
321
|
|
|
318
|
-
# These methods
|
|
319
|
-
#
|
|
322
|
+
# These methods make it easier to create Sequel expressions without
|
|
323
|
+
# using the core extensions.
|
|
320
324
|
module Builders
|
|
321
325
|
# Create an SQL::AliasedExpression for the given expression and alias.
|
|
322
326
|
#
|
|
@@ -334,7 +338,7 @@ module Sequel
|
|
|
334
338
|
# are ordered after other values).
|
|
335
339
|
#
|
|
336
340
|
# Sequel.asc(:a) # a ASC
|
|
337
|
-
# Sequel.asc(:b, :
|
|
341
|
+
# Sequel.asc(:b, nulls: :last) # b ASC NULLS LAST
|
|
338
342
|
def asc(arg, opts=OPTS)
|
|
339
343
|
SQL::OrderedExpression.new(arg, false, opts)
|
|
340
344
|
end
|
|
@@ -351,10 +355,16 @@ module Sequel
|
|
|
351
355
|
end
|
|
352
356
|
|
|
353
357
|
# Return an <tt>SQL::CaseExpression</tt> created with the given arguments.
|
|
354
|
-
#
|
|
355
|
-
#
|
|
356
|
-
#
|
|
357
|
-
|
|
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.
|
|
362
|
+
#
|
|
363
|
+
# Sequel.case({a: 1}, 0) # SQL: CASE WHEN a THEN 1 ELSE 0 END
|
|
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
|
|
367
|
+
def case(*args)
|
|
358
368
|
SQL::CaseExpression.new(*args)
|
|
359
369
|
end
|
|
360
370
|
|
|
@@ -400,10 +410,10 @@ module Sequel
|
|
|
400
410
|
# nested structures.
|
|
401
411
|
#
|
|
402
412
|
# Sequel.deep_qualify(:table, :column) # "table"."column"
|
|
403
|
-
# Sequel.deep_qualify(:table, Sequel
|
|
404
|
-
# Sequel.deep_qualify(:table, Sequel.like(
|
|
413
|
+
# Sequel.deep_qualify(:table, Sequel[:column] + 1) # "table"."column" + 1
|
|
414
|
+
# Sequel.deep_qualify(:table, Sequel[:a].like('b')) # "table"."a" LIKE 'b' ESCAPE '\'
|
|
405
415
|
def deep_qualify(qualifier, expr)
|
|
406
|
-
Sequel::Qualifier.new(
|
|
416
|
+
Sequel::Qualifier.new(qualifier).transform(expr)
|
|
407
417
|
end
|
|
408
418
|
|
|
409
419
|
# Return a delayed evaluation that uses the passed block. This is used
|
|
@@ -435,7 +445,7 @@ module Sequel
|
|
|
435
445
|
# are ordered after other values).
|
|
436
446
|
#
|
|
437
447
|
# Sequel.desc(:a) # b DESC
|
|
438
|
-
# Sequel.desc(:b, :
|
|
448
|
+
# Sequel.desc(:b, nulls: :first) # b DESC NULLS FIRST
|
|
439
449
|
def desc(arg, opts=OPTS)
|
|
440
450
|
SQL::OrderedExpression.new(arg, true, opts)
|
|
441
451
|
end
|
|
@@ -452,6 +462,10 @@ module Sequel
|
|
|
452
462
|
# to construct via other methods. For example:
|
|
453
463
|
#
|
|
454
464
|
# Sequel.expr(1) - :a # SQL: (1 - a)
|
|
465
|
+
#
|
|
466
|
+
# On the Sequel module, this is aliased as #[], for easier use:
|
|
467
|
+
#
|
|
468
|
+
# Sequel[1] - :a # SQL: (1 - a)
|
|
455
469
|
def expr(arg=(no_arg=true), &block)
|
|
456
470
|
if block_given?
|
|
457
471
|
if no_arg
|
|
@@ -520,7 +534,7 @@ module Sequel
|
|
|
520
534
|
|
|
521
535
|
# Return the argument wrapped as an <tt>SQL::Identifier</tt>.
|
|
522
536
|
#
|
|
523
|
-
# Sequel.identifier(:
|
|
537
|
+
# Sequel.identifier(:a) # "a"
|
|
524
538
|
def identifier(name)
|
|
525
539
|
SQL::Identifier.new(name)
|
|
526
540
|
end
|
|
@@ -573,17 +587,17 @@ module Sequel
|
|
|
573
587
|
# Converts a string into a <tt>Sequel::LiteralString</tt>, in order to override string
|
|
574
588
|
# literalization, e.g.:
|
|
575
589
|
#
|
|
576
|
-
# DB[:items].
|
|
590
|
+
# DB[:items].where(abc: 'def').sql #=>
|
|
577
591
|
# "SELECT * FROM items WHERE (abc = 'def')"
|
|
578
592
|
#
|
|
579
|
-
# DB[:items].
|
|
593
|
+
# DB[:items].where(abc: Sequel.lit('def')).sql #=>
|
|
580
594
|
# "SELECT * FROM items WHERE (abc = def)"
|
|
581
595
|
#
|
|
582
596
|
# You can also provide arguments, to create a <tt>Sequel::SQL::PlaceholderLiteralString</tt>:
|
|
583
597
|
#
|
|
584
598
|
# DB[:items].select{|o| o.count(Sequel.lit('DISTINCT ?', :a))}.sql #=>
|
|
585
599
|
# "SELECT count(DISTINCT a) FROM items"
|
|
586
|
-
def lit(s, *args)
|
|
600
|
+
def lit(s, *args)
|
|
587
601
|
if args.empty?
|
|
588
602
|
if s.is_a?(LiteralString)
|
|
589
603
|
s
|
|
@@ -598,7 +612,7 @@ module Sequel
|
|
|
598
612
|
# Return a <tt>Sequel::SQL::BooleanExpression</tt> created from the condition
|
|
599
613
|
# specifier, matching none of the conditions.
|
|
600
614
|
#
|
|
601
|
-
# Sequel.negate(:
|
|
615
|
+
# Sequel.negate(a: true) # SQL: a IS NOT TRUE
|
|
602
616
|
# Sequel.negate([[:a, true]]) # SQL: a IS NOT TRUE
|
|
603
617
|
# Sequel.negate([[:a, 1], [:b, 2]]) # SQL: ((a != 1) AND (b != 2))
|
|
604
618
|
def negate(arg)
|
|
@@ -612,7 +626,7 @@ module Sequel
|
|
|
612
626
|
# Return a <tt>Sequel::SQL::BooleanExpression</tt> created from the condition
|
|
613
627
|
# specifier, matching any of the conditions.
|
|
614
628
|
#
|
|
615
|
-
# Sequel.or(:
|
|
629
|
+
# Sequel.or(a: true) # SQL: a IS TRUE
|
|
616
630
|
# Sequel.or([[:a, true]]) # SQL: a IS TRUE
|
|
617
631
|
# Sequel.or([[:a, 1], [:b, 2]]) # SQL: ((a = 1) OR (b = 2))
|
|
618
632
|
def or(arg)
|
|
@@ -659,9 +673,9 @@ module Sequel
|
|
|
659
673
|
# this array as a value in a filter, but may be necessary if you are using it as a
|
|
660
674
|
# value with placeholder SQL:
|
|
661
675
|
#
|
|
662
|
-
# DB[:a].
|
|
663
|
-
# DB[:a].
|
|
664
|
-
# DB[:a].
|
|
676
|
+
# DB[:a].where([:a, :b]=>[[1, 2], [3, 4]]) # SQL: (a, b) IN ((1, 2), (3, 4))
|
|
677
|
+
# DB[:a].where('(a, b) IN ?', [[1, 2], [3, 4]]) # SQL: (a, b) IN ((1 = 2) AND (3 = 4))
|
|
678
|
+
# DB[:a].where('(a, b) IN ?', Sequel.value_list([[1, 2], [3, 4]])) # SQL: (a, b) IN ((1, 2), (3, 4))
|
|
665
679
|
def value_list(arg)
|
|
666
680
|
raise Error, 'argument to Sequel.value_list must be an array' unless arg.is_a?(Array)
|
|
667
681
|
SQL::ValueList.new(arg)
|
|
@@ -701,22 +715,11 @@ module Sequel
|
|
|
701
715
|
end
|
|
702
716
|
|
|
703
717
|
# Adds methods that allow you to treat an object as an instance of a specific
|
|
704
|
-
# +ComplexExpression+ subclass.
|
|
705
|
-
# overrides the methods defined by Sequel.
|
|
706
|
-
#
|
|
707
|
-
# For example, if <tt>Symbol#/</tt> is overridden to produce a string (for
|
|
708
|
-
# example, to make file system path creation easier), the
|
|
709
|
-
# following code will not do what you want:
|
|
710
|
-
#
|
|
711
|
-
# :price/10 > 100
|
|
712
|
-
#
|
|
713
|
-
# In that case, you need to do the following:
|
|
714
|
-
#
|
|
715
|
-
# :price.sql_number/10 > 100
|
|
718
|
+
# +ComplexExpression+ subclass.
|
|
716
719
|
module ComplexExpressionMethods
|
|
717
720
|
# Extract a datetime part (e.g. year, month) from self:
|
|
718
721
|
#
|
|
719
|
-
# :date.extract(:year) # extract(year FROM "date")
|
|
722
|
+
# Sequel[:date].extract(:year) # extract(year FROM "date")
|
|
720
723
|
#
|
|
721
724
|
# Also has the benefit of returning the result as a
|
|
722
725
|
# NumericExpression instead of a generic ComplexExpression.
|
|
@@ -731,16 +734,16 @@ module Sequel
|
|
|
731
734
|
|
|
732
735
|
# Return a NumericExpression representation of +self+.
|
|
733
736
|
#
|
|
734
|
-
#
|
|
735
|
-
#
|
|
737
|
+
# ~Sequel[:a] # NOT "a"
|
|
738
|
+
# ~(Sequel[:a].sql_number) # ~"a"
|
|
736
739
|
def sql_number
|
|
737
740
|
NumericExpression.new(:NOOP, self)
|
|
738
741
|
end
|
|
739
742
|
|
|
740
743
|
# Return a StringExpression representation of +self+.
|
|
741
744
|
#
|
|
742
|
-
# :a + :b # "a" + "b"
|
|
743
|
-
# :a.sql_string + :b # "a" || "b"
|
|
745
|
+
# Sequel[:a] + :b # "a" + "b"
|
|
746
|
+
# Sequel[:a].sql_string + :b # "a" || "b"
|
|
744
747
|
def sql_string
|
|
745
748
|
StringExpression.new(:NOOP, self)
|
|
746
749
|
end
|
|
@@ -749,10 +752,10 @@ module Sequel
|
|
|
749
752
|
# This module includes the inequality methods (>, <, >=, <=) that are defined on objects that can be
|
|
750
753
|
# used in a numeric or string context in SQL.
|
|
751
754
|
#
|
|
752
|
-
# Sequel
|
|
753
|
-
# Sequel
|
|
754
|
-
# Sequel
|
|
755
|
-
# 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"
|
|
756
759
|
module InequalityMethods
|
|
757
760
|
ComplexExpression::INEQUALITY_OPERATORS.each do |o|
|
|
758
761
|
module_eval("def #{o}(o) BooleanExpression.new(#{o.inspect}, self, o) end", __FILE__, __LINE__)
|
|
@@ -763,18 +766,33 @@ module Sequel
|
|
|
763
766
|
# that are defined on objects that can be used in a numeric context in SQL
|
|
764
767
|
# (+Symbol+, +LiteralString+, and +SQL::GenericExpression+).
|
|
765
768
|
#
|
|
766
|
-
# :a + :b # "a" + "b"
|
|
767
|
-
# :a - :b # "a" - "b"
|
|
768
|
-
# :a * :b # "a" * "b"
|
|
769
|
-
# :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"
|
|
770
773
|
#
|
|
771
774
|
# One exception to this is if + is called with a +String+ or +StringExpression+,
|
|
772
775
|
# in which case the || operator is used instead of the + operator:
|
|
773
776
|
#
|
|
774
|
-
# :a + 'b' # "a" || 'b'
|
|
777
|
+
# Sequel[:a] + 'b' # "a" || 'b'
|
|
775
778
|
module NumericMethods
|
|
776
|
-
ComplexExpression::MATHEMATICAL_OPERATORS.each do |o|
|
|
777
|
-
module_eval("def #{o}(o) NumericExpression.new(#{o.inspect}, self, o) end", __FILE__, __LINE__)
|
|
779
|
+
(ComplexExpression::MATHEMATICAL_OPERATORS - [:+]).each do |o|
|
|
780
|
+
module_eval("def #{o}(o) NumericExpression.new(#{o.inspect}, self, o) end", __FILE__, __LINE__)
|
|
781
|
+
end
|
|
782
|
+
|
|
783
|
+
# If the argument given is Numeric, treat it as a NumericExpression,
|
|
784
|
+
# allowing code such as:
|
|
785
|
+
#
|
|
786
|
+
# 1 + Sequel[:x] # SQL: (1 + x)
|
|
787
|
+
# Sequel.expr{1 - x(y)} # SQL: (1 - x(y))
|
|
788
|
+
def coerce(other)
|
|
789
|
+
if other.is_a?(Numeric)
|
|
790
|
+
[SQL::NumericExpression.new(:NOOP, other), self]
|
|
791
|
+
elsif defined?(super)
|
|
792
|
+
super
|
|
793
|
+
else
|
|
794
|
+
[self, other]
|
|
795
|
+
end
|
|
778
796
|
end
|
|
779
797
|
|
|
780
798
|
# Use || as the operator when called with StringExpression and String instances,
|
|
@@ -796,17 +814,17 @@ module Sequel
|
|
|
796
814
|
# return when using a hash with a single entry, where the receiver was the key
|
|
797
815
|
# and the argument was the value. Example:
|
|
798
816
|
#
|
|
799
|
-
# Sequel
|
|
800
|
-
# Sequel
|
|
801
|
-
# Sequel
|
|
817
|
+
# Sequel[:a] =~ 1 # (a = 1)
|
|
818
|
+
# Sequel[:a] =~ [1, 2] # (a IN [1, 2])
|
|
819
|
+
# Sequel[:a] =~ nil # (a IS NULL)
|
|
802
820
|
#
|
|
803
|
-
#
|
|
821
|
+
# This also adds the !~ method, for easily setting up not equals,
|
|
804
822
|
# exclusion, and inverse pattern matching. This is the same as as inverting the
|
|
805
823
|
# result of the =~ method
|
|
806
824
|
#
|
|
807
|
-
# Sequel
|
|
808
|
-
# Sequel
|
|
809
|
-
# Sequel
|
|
825
|
+
# Sequel[:a] !~ 1 # (a != 1)
|
|
826
|
+
# Sequel[:a] !~ [1, 2] # (a NOT IN [1, 2])
|
|
827
|
+
# Sequel[:a] !~ nil # (a IS NOT NULL)
|
|
810
828
|
module PatternMatchMethods
|
|
811
829
|
# Set up an equality, inclusion, or pattern match operation, based on the type
|
|
812
830
|
# of the argument.
|
|
@@ -814,23 +832,19 @@ module Sequel
|
|
|
814
832
|
BooleanExpression.send(:from_value_pair, self, other)
|
|
815
833
|
end
|
|
816
834
|
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
def !~(other)
|
|
820
|
-
~(self =~ other)
|
|
821
|
-
end
|
|
822
|
-
END
|
|
835
|
+
def !~(other)
|
|
836
|
+
~(self =~ other)
|
|
823
837
|
end
|
|
824
838
|
end
|
|
825
839
|
|
|
826
|
-
#
|
|
827
|
-
# methods, so that Sequel is still easy to use if the core extensions are not
|
|
828
|
-
# enabled.
|
|
840
|
+
# This adds methods to create SQL expressions using operators:
|
|
829
841
|
#
|
|
830
|
-
#
|
|
831
|
-
#
|
|
832
|
-
#
|
|
833
|
-
#
|
|
842
|
+
# Sequel.+(1, :a) # (1 + a)
|
|
843
|
+
# Sequel.-(1, :a) # (1 - a)
|
|
844
|
+
# Sequel.*(1, :a) # (1 * a)
|
|
845
|
+
# Sequel./(1, :a) # (1 / a)
|
|
846
|
+
# Sequel.&(:b, :a) # (b AND a)
|
|
847
|
+
# Sequel.|(:b, :a) # (b OR a)
|
|
834
848
|
module OperatorBuilders
|
|
835
849
|
{'::Sequel::SQL::NumericExpression'=>{'+'=>'+', '-'=>'-', '*'=>'*', '/'=>'/'},
|
|
836
850
|
'::Sequel::SQL::BooleanExpression'=>{'&'=>'AND', '|'=>'OR'}}.each do |klass, ops|
|
|
@@ -850,6 +864,13 @@ module Sequel
|
|
|
850
864
|
END
|
|
851
865
|
end
|
|
852
866
|
end
|
|
867
|
+
|
|
868
|
+
# Return NumericExpression for the exponentiation:
|
|
869
|
+
#
|
|
870
|
+
# Sequel.**(2, 3) # SQL: power(2, 3)
|
|
871
|
+
def **(a, b)
|
|
872
|
+
SQL::NumericExpression.new(:**, a, b)
|
|
873
|
+
end
|
|
853
874
|
|
|
854
875
|
# Invert the given expression. Returns a <tt>Sequel::SQL::BooleanExpression</tt>
|
|
855
876
|
# created from this argument, not matching all of the conditions.
|
|
@@ -890,13 +911,13 @@ module Sequel
|
|
|
890
911
|
end
|
|
891
912
|
end
|
|
892
913
|
|
|
893
|
-
# Includes a +qualify+
|
|
914
|
+
# Includes a +qualify+ and <tt>[]</tt> methods that create <tt>QualifiedIdentifier</tt>s, used for qualifying column
|
|
894
915
|
# names with a table or table names with a schema, and the * method for returning all columns in
|
|
895
916
|
# the identifier if no arguments are given.
|
|
896
917
|
module QualifyingMethods
|
|
897
918
|
# If no arguments are given, return an SQL::ColumnAll:
|
|
898
919
|
#
|
|
899
|
-
# Sequel
|
|
920
|
+
# Sequel[:a].* # a.*
|
|
900
921
|
def *(ce=(arg=false;nil))
|
|
901
922
|
if arg == false
|
|
902
923
|
Sequel::SQL::ColumnAll.new(self)
|
|
@@ -907,12 +928,21 @@ module Sequel
|
|
|
907
928
|
|
|
908
929
|
# Qualify the receiver with the given +qualifier+ (table for column/schema for table).
|
|
909
930
|
#
|
|
910
|
-
# Sequel
|
|
911
|
-
# Sequel
|
|
931
|
+
# Sequel[:column].qualify(:table) # "table"."column"
|
|
932
|
+
# Sequel[:table].qualify(:schema) # "schema"."table"
|
|
912
933
|
# Sequel.qualify(:table, :column).qualify(:schema) # "schema"."table"."column"
|
|
913
934
|
def qualify(qualifier)
|
|
914
935
|
QualifiedIdentifier.new(qualifier, self)
|
|
915
936
|
end
|
|
937
|
+
|
|
938
|
+
# Qualify the receiver with the given +qualifier+ (table for column/schema for table).
|
|
939
|
+
#
|
|
940
|
+
# Sequel[:table][:column] # "table"."column"
|
|
941
|
+
# Sequel[:schema][:table] # "schema"."table"
|
|
942
|
+
# Sequel[:schema][:table][:column] # "schema"."table"."column"
|
|
943
|
+
def [](identifier)
|
|
944
|
+
QualifiedIdentifier.new(self, identifier)
|
|
945
|
+
end
|
|
916
946
|
end
|
|
917
947
|
|
|
918
948
|
# This module includes the +like+ and +ilike+ methods used for pattern matching that are defined on objects that can be
|
|
@@ -921,7 +951,7 @@ module Sequel
|
|
|
921
951
|
# Create a +BooleanExpression+ case insensitive pattern match of the receiver
|
|
922
952
|
# with the given patterns. See <tt>StringExpression.like</tt>.
|
|
923
953
|
#
|
|
924
|
-
# :a.ilike('A%') # "a" ILIKE 'A%' ESCAPE '\'
|
|
954
|
+
# Sequel[:a].ilike('A%') # "a" ILIKE 'A%' ESCAPE '\'
|
|
925
955
|
def ilike(*ces)
|
|
926
956
|
StringExpression.like(self, *(ces << {:case_insensitive=>true}))
|
|
927
957
|
end
|
|
@@ -929,7 +959,7 @@ module Sequel
|
|
|
929
959
|
# Create a +BooleanExpression+ case sensitive (if the database supports it) pattern match of the receiver with
|
|
930
960
|
# the given patterns. See <tt>StringExpression.like</tt>.
|
|
931
961
|
#
|
|
932
|
-
# :a.like('A%') # "a" LIKE 'A%' ESCAPE '\'
|
|
962
|
+
# Sequel[:a].like('A%') # "a" LIKE 'A%' ESCAPE '\'
|
|
933
963
|
def like(*ces)
|
|
934
964
|
StringExpression.like(self, *ces)
|
|
935
965
|
end
|
|
@@ -941,7 +971,7 @@ module Sequel
|
|
|
941
971
|
# Return a +StringExpression+ representing the concatenation of the receiver
|
|
942
972
|
# with the given argument.
|
|
943
973
|
#
|
|
944
|
-
# :x.sql_string + :y # => "x" || "y"
|
|
974
|
+
# Sequel[:x].sql_string + :y # => "x" || "y"
|
|
945
975
|
def +(ce)
|
|
946
976
|
StringExpression.new(:'||', self, ce)
|
|
947
977
|
end
|
|
@@ -952,37 +982,34 @@ module Sequel
|
|
|
952
982
|
# Return a <tt>Subscript</tt> with the given arguments, representing an
|
|
953
983
|
# SQL array access.
|
|
954
984
|
#
|
|
955
|
-
# :array.sql_subscript(1) # array[1]
|
|
956
|
-
# :array.sql_subscript(1, 2) # array[1, 2]
|
|
957
|
-
# :array.sql_subscript([1, 2]) # array[1, 2]
|
|
958
|
-
# :array.sql_subscript(
|
|
959
|
-
# :array.sql_subscript(
|
|
985
|
+
# Sequel[:array].sql_subscript(1) # array[1]
|
|
986
|
+
# Sequel[:array].sql_subscript(1, 2) # array[1, 2]
|
|
987
|
+
# Sequel[:array].sql_subscript([1, 2]) # array[1, 2]
|
|
988
|
+
# Sequel[:array].sql_subscript(1..2) # array[1:2]
|
|
989
|
+
# Sequel[:array].sql_subscript(1...3) # array[1:2]
|
|
960
990
|
def sql_subscript(*sub)
|
|
961
991
|
Subscript.new(self, sub.flatten)
|
|
962
992
|
end
|
|
963
993
|
end
|
|
964
994
|
|
|
965
|
-
### Classes ###
|
|
966
|
-
|
|
967
995
|
# Represents an aliasing of an expression to a given alias.
|
|
968
996
|
class AliasedExpression < Expression
|
|
969
997
|
# The expression to alias
|
|
970
998
|
attr_reader :expression
|
|
971
999
|
|
|
972
|
-
# The alias to use for the expression
|
|
973
|
-
|
|
974
|
-
attr_reader :aliaz
|
|
975
|
-
alias_method :alias, :aliaz
|
|
1000
|
+
# The alias to use for the expression.
|
|
1001
|
+
attr_reader :alias
|
|
976
1002
|
|
|
977
|
-
# The columns aliases to use, for when the aliased expression is
|
|
1003
|
+
# The columns aliases (derived column list) to use, for when the aliased expression is
|
|
978
1004
|
# a record or set of records (such as a dataset).
|
|
979
1005
|
attr_reader :columns
|
|
980
1006
|
|
|
981
|
-
# Create an object with the given expression and
|
|
1007
|
+
# Create an object with the given expression, alias, and optional column aliases.
|
|
982
1008
|
def initialize(expression, aliaz, columns=nil)
|
|
983
1009
|
@expression = expression
|
|
984
|
-
@
|
|
1010
|
+
@alias = aliaz
|
|
985
1011
|
@columns = columns
|
|
1012
|
+
freeze
|
|
986
1013
|
end
|
|
987
1014
|
|
|
988
1015
|
to_s_method :aliased_expression_sql
|
|
@@ -995,11 +1022,30 @@ module Sequel
|
|
|
995
1022
|
include SQL::AliasMethods
|
|
996
1023
|
include SQL::CastMethods
|
|
997
1024
|
|
|
1025
|
+
class << self
|
|
1026
|
+
# Alias new to call for usage in conversion procs
|
|
1027
|
+
alias call new
|
|
1028
|
+
end
|
|
1029
|
+
|
|
998
1030
|
# Return a LiteralString with the same content if no args are given, otherwise
|
|
999
1031
|
# return a SQL::PlaceholderLiteralString with the current string and the given args.
|
|
1000
1032
|
def lit(*args)
|
|
1001
1033
|
args.empty? ? LiteralString.new(self) : SQL::PlaceholderLiteralString.new(self, args)
|
|
1002
1034
|
end
|
|
1035
|
+
|
|
1036
|
+
# Return a string showing that this is a blob, the size, and the some or all of the content,
|
|
1037
|
+
# depending on the size.
|
|
1038
|
+
def inspect
|
|
1039
|
+
size = length
|
|
1040
|
+
|
|
1041
|
+
content = if size > 20
|
|
1042
|
+
"start=#{self[0...10].to_s.inspect} end=#{self[-10..-1].to_s.inspect}"
|
|
1043
|
+
else
|
|
1044
|
+
"content=#{super}"
|
|
1045
|
+
end
|
|
1046
|
+
|
|
1047
|
+
"#<#{self.class}:0x#{"%x" % object_id} bytes=#{size} #{content}>"
|
|
1048
|
+
end
|
|
1003
1049
|
|
|
1004
1050
|
# Returns +self+, since it is already a blob.
|
|
1005
1051
|
def to_sequel_blob
|
|
@@ -1035,15 +1081,37 @@ module Sequel
|
|
|
1035
1081
|
def self.from_value_pairs(pairs, op=:AND, negate=false)
|
|
1036
1082
|
pairs = pairs.map{|l,r| from_value_pair(l, r)}
|
|
1037
1083
|
pairs.map!{|ce| invert(ce)} if negate
|
|
1038
|
-
pairs.length == 1 ? pairs
|
|
1084
|
+
pairs.length == 1 ? pairs[0] : new(op, *pairs)
|
|
1039
1085
|
end
|
|
1040
1086
|
|
|
1041
1087
|
# Return a BooleanExpression based on the right side of the pair.
|
|
1042
1088
|
def self.from_value_pair(l, r)
|
|
1043
1089
|
case r
|
|
1044
1090
|
when Range
|
|
1045
|
-
|
|
1046
|
-
|
|
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
|
|
1047
1115
|
new(:IN, l, r)
|
|
1048
1116
|
when NegativeBooleanConstant
|
|
1049
1117
|
new(:"IS NOT", l, r.constant)
|
|
@@ -1074,9 +1142,22 @@ module Sequel
|
|
|
1074
1142
|
when BooleanExpression
|
|
1075
1143
|
case op = ce.op
|
|
1076
1144
|
when :AND, :OR
|
|
1077
|
-
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.
|
|
1078
|
-
|
|
1145
|
+
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.map{|a| BooleanExpression.invert(a)})
|
|
1146
|
+
when :IN, :"NOT IN"
|
|
1079
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
|
|
1080
1161
|
end
|
|
1081
1162
|
when StringExpression, NumericExpression
|
|
1082
1163
|
raise(Sequel::Error, "cannot invert #{ce.inspect}")
|
|
@@ -1113,16 +1194,20 @@ module Sequel
|
|
|
1113
1194
|
# The default value if no conditions match.
|
|
1114
1195
|
attr_reader :default
|
|
1115
1196
|
|
|
1116
|
-
#
|
|
1197
|
+
# An optional expression to test the conditions against
|
|
1117
1198
|
attr_reader :expression
|
|
1118
1199
|
|
|
1119
1200
|
# Create an object with the given conditions and
|
|
1120
|
-
# default value. An expression can be provided to
|
|
1201
|
+
# default value, and optional expression. An expression can be provided to
|
|
1121
1202
|
# test each condition against, instead of having
|
|
1122
1203
|
# all conditions represent their own boolean expression.
|
|
1123
1204
|
def initialize(conditions, default, expression=(no_expression=true; nil))
|
|
1124
1205
|
raise(Sequel::Error, 'CaseExpression conditions must be a hash or array of all two pairs') unless Sequel.condition_specifier?(conditions)
|
|
1125
|
-
@conditions
|
|
1206
|
+
@conditions = conditions.to_a.dup.freeze
|
|
1207
|
+
@default = default
|
|
1208
|
+
@expression = expression
|
|
1209
|
+
@no_expression = no_expression
|
|
1210
|
+
freeze
|
|
1126
1211
|
end
|
|
1127
1212
|
|
|
1128
1213
|
# Whether to use an expression for this CASE expression.
|
|
@@ -1152,10 +1237,11 @@ module Sequel
|
|
|
1152
1237
|
# The type to which to cast the expression
|
|
1153
1238
|
attr_reader :type
|
|
1154
1239
|
|
|
1155
|
-
# Set the
|
|
1240
|
+
# Set the expression and type for the cast
|
|
1156
1241
|
def initialize(expr, type)
|
|
1157
1242
|
@expr = expr
|
|
1158
1243
|
@type = type
|
|
1244
|
+
freeze
|
|
1159
1245
|
end
|
|
1160
1246
|
|
|
1161
1247
|
to_s_method :cast_sql, '@expr, @type'
|
|
@@ -1169,6 +1255,7 @@ module Sequel
|
|
|
1169
1255
|
# Create an object with the given table
|
|
1170
1256
|
def initialize(table)
|
|
1171
1257
|
@table = table
|
|
1258
|
+
freeze
|
|
1172
1259
|
end
|
|
1173
1260
|
|
|
1174
1261
|
to_s_method :column_all_sql
|
|
@@ -1183,17 +1270,17 @@ module Sequel
|
|
|
1183
1270
|
|
|
1184
1271
|
# Return a BooleanExpression with the same op and args.
|
|
1185
1272
|
def sql_boolean
|
|
1186
|
-
BooleanExpression.new(
|
|
1273
|
+
BooleanExpression.new(op, *args)
|
|
1187
1274
|
end
|
|
1188
1275
|
|
|
1189
1276
|
# Return a NumericExpression with the same op and args.
|
|
1190
1277
|
def sql_number
|
|
1191
|
-
NumericExpression.new(
|
|
1278
|
+
NumericExpression.new(op, *args)
|
|
1192
1279
|
end
|
|
1193
1280
|
|
|
1194
1281
|
# Return a StringExpression with the same op and args.
|
|
1195
1282
|
def sql_string
|
|
1196
|
-
StringExpression.new(
|
|
1283
|
+
StringExpression.new(op, *args)
|
|
1197
1284
|
end
|
|
1198
1285
|
end
|
|
1199
1286
|
|
|
@@ -1202,15 +1289,16 @@ module Sequel
|
|
|
1202
1289
|
# The underlying constant related to this object.
|
|
1203
1290
|
attr_reader :constant
|
|
1204
1291
|
|
|
1205
|
-
# Create
|
|
1292
|
+
# Create a constant with the given value
|
|
1206
1293
|
def initialize(constant)
|
|
1207
1294
|
@constant = constant
|
|
1295
|
+
freeze
|
|
1208
1296
|
end
|
|
1209
1297
|
|
|
1210
1298
|
to_s_method :constant_sql, '@constant'
|
|
1211
1299
|
end
|
|
1212
1300
|
|
|
1213
|
-
# Represents boolean constants such as +NULL+, +
|
|
1301
|
+
# Represents boolean constants such as +NULL+, +TRUE+, and +FALSE+.
|
|
1214
1302
|
class BooleanConstant < Constant
|
|
1215
1303
|
to_s_method :boolean_constant_sql, '@constant'
|
|
1216
1304
|
end
|
|
@@ -1229,6 +1317,7 @@ module Sequel
|
|
|
1229
1317
|
CURRENT_DATE = Constant.new(:CURRENT_DATE)
|
|
1230
1318
|
CURRENT_TIME = Constant.new(:CURRENT_TIME)
|
|
1231
1319
|
CURRENT_TIMESTAMP = Constant.new(:CURRENT_TIMESTAMP)
|
|
1320
|
+
DEFAULT = Constant.new(:DEFAULT)
|
|
1232
1321
|
SQLTRUE = TRUE = BooleanConstant.new(true)
|
|
1233
1322
|
SQLFALSE = FALSE = BooleanConstant.new(false)
|
|
1234
1323
|
NULL = BooleanConstant.new(nil)
|
|
@@ -1238,7 +1327,7 @@ module Sequel
|
|
|
1238
1327
|
class ComplexExpression
|
|
1239
1328
|
# A hash of the opposite for each constant, used for inverting constants.
|
|
1240
1329
|
CONSTANT_INVERSIONS = {Constants::TRUE=>Constants::FALSE, Constants::FALSE=>Constants::TRUE,
|
|
1241
|
-
Constants::NULL=>Constants::NOTNULL, Constants::NOTNULL=>Constants::NULL}
|
|
1330
|
+
Constants::NULL=>Constants::NOTNULL, Constants::NOTNULL=>Constants::NULL}.freeze
|
|
1242
1331
|
end
|
|
1243
1332
|
|
|
1244
1333
|
# Represents a delayed evaluation, encapsulating a callable
|
|
@@ -1251,6 +1340,7 @@ module Sequel
|
|
|
1251
1340
|
# Set the callable object
|
|
1252
1341
|
def initialize(callable)
|
|
1253
1342
|
@callable = callable
|
|
1343
|
+
freeze
|
|
1254
1344
|
end
|
|
1255
1345
|
|
|
1256
1346
|
# Call the underlying callable and return the result. If the
|
|
@@ -1275,8 +1365,7 @@ module Sequel
|
|
|
1275
1365
|
|
|
1276
1366
|
# The SQL function to call
|
|
1277
1367
|
attr_reader :name
|
|
1278
|
-
|
|
1279
|
-
|
|
1368
|
+
|
|
1280
1369
|
# The array of arguments to pass to the function (may be blank)
|
|
1281
1370
|
attr_reader :args
|
|
1282
1371
|
|
|
@@ -1285,15 +1374,12 @@ module Sequel
|
|
|
1285
1374
|
|
|
1286
1375
|
# Set the name and args for the function
|
|
1287
1376
|
def initialize(name, *args)
|
|
1288
|
-
|
|
1289
|
-
@args = args
|
|
1290
|
-
@opts = OPTS
|
|
1377
|
+
_initialize(name, args, OPTS)
|
|
1291
1378
|
end
|
|
1292
1379
|
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
f
|
|
1380
|
+
# Set the name, args, and options, for internal use only.
|
|
1381
|
+
def self.new!(name, args, opts) # :nodoc:
|
|
1382
|
+
allocate.send(:_initialize, name, args, opts)
|
|
1297
1383
|
end
|
|
1298
1384
|
|
|
1299
1385
|
# If no arguments are given, return a new function with the wildcard prepended to the arguments.
|
|
@@ -1318,9 +1404,14 @@ module Sequel
|
|
|
1318
1404
|
# Return a new function with FILTER added to it, for filtered
|
|
1319
1405
|
# aggregate functions:
|
|
1320
1406
|
#
|
|
1321
|
-
# Sequel.function(:foo, :col).filter(:
|
|
1407
|
+
# Sequel.function(:foo, :col).filter(a: 1) # foo(col) FILTER (WHERE (a = 1))
|
|
1322
1408
|
def filter(*args, &block)
|
|
1323
|
-
|
|
1409
|
+
if args.length == 1
|
|
1410
|
+
args = args.first
|
|
1411
|
+
else
|
|
1412
|
+
args.freeze
|
|
1413
|
+
end
|
|
1414
|
+
|
|
1324
1415
|
with_opts(:filter=>args, :filter_block=>block)
|
|
1325
1416
|
end
|
|
1326
1417
|
|
|
@@ -1331,9 +1422,18 @@ module Sequel
|
|
|
1331
1422
|
with_opts(:lateral=>true)
|
|
1332
1423
|
end
|
|
1333
1424
|
|
|
1425
|
+
# Return a new function where the function will be ordered. Only useful for aggregate
|
|
1426
|
+
# functions that are order dependent.
|
|
1427
|
+
#
|
|
1428
|
+
# Sequel.function(:foo, :a).order(:a, Sequel.desc(:b)) # foo(a ORDER BY a, b DESC)
|
|
1429
|
+
def order(*args)
|
|
1430
|
+
with_opts(:order=>args.freeze)
|
|
1431
|
+
end
|
|
1432
|
+
|
|
1334
1433
|
# Return a new function with an OVER clause (making it a window function).
|
|
1434
|
+
# See Sequel::SQL::Window for the list of options +over+ can receive.
|
|
1335
1435
|
#
|
|
1336
|
-
# Sequel.function(:row_number).over(:
|
|
1436
|
+
# Sequel.function(:row_number).over(partition: :col) # row_number() OVER (PARTITION BY col)
|
|
1337
1437
|
def over(window=OPTS)
|
|
1338
1438
|
raise Error, "function already has a window applied to it" if opts[:over]
|
|
1339
1439
|
window = Window.new(window) unless window.is_a?(Window)
|
|
@@ -1351,7 +1451,7 @@ module Sequel
|
|
|
1351
1451
|
# Return a new function where the function name will not be quoted even
|
|
1352
1452
|
# if the database supports quoted functions:
|
|
1353
1453
|
#
|
|
1354
|
-
# Sequel
|
|
1454
|
+
# Sequel[:foo][:bar].function.unquoted # foo.bar()
|
|
1355
1455
|
def unquoted
|
|
1356
1456
|
with_opts(:quoted=>false)
|
|
1357
1457
|
end
|
|
@@ -1370,16 +1470,24 @@ module Sequel
|
|
|
1370
1470
|
# Sequel.function(:rank, :a).within_group(:b, :c)
|
|
1371
1471
|
# # rank(a) WITHIN GROUP (ORDER BY b, c)
|
|
1372
1472
|
def within_group(*expressions)
|
|
1373
|
-
with_opts(:within_group=>expressions)
|
|
1473
|
+
with_opts(:within_group=>expressions.freeze)
|
|
1374
1474
|
end
|
|
1375
1475
|
|
|
1376
1476
|
to_s_method :function_sql
|
|
1377
1477
|
|
|
1378
1478
|
private
|
|
1379
1479
|
|
|
1480
|
+
# Set name, args, and opts
|
|
1481
|
+
def _initialize(name, args, opts)
|
|
1482
|
+
@name = name
|
|
1483
|
+
@args = args.freeze
|
|
1484
|
+
@opts = opts.freeze
|
|
1485
|
+
freeze
|
|
1486
|
+
end
|
|
1487
|
+
|
|
1380
1488
|
# Return a new function call with the given opts merged into the current opts.
|
|
1381
1489
|
def with_opts(opts)
|
|
1382
|
-
self.class.new!(name, args,
|
|
1490
|
+
self.class.new!(name, args, @opts.merge(opts))
|
|
1383
1491
|
end
|
|
1384
1492
|
end
|
|
1385
1493
|
|
|
@@ -1396,18 +1504,17 @@ module Sequel
|
|
|
1396
1504
|
include SubscriptMethods
|
|
1397
1505
|
end
|
|
1398
1506
|
|
|
1399
|
-
# Represents an identifier (column
|
|
1400
|
-
# to specify a +Symbol+ with multiple underscores should not be
|
|
1401
|
-
# split, or for creating an identifier without using a symbol.
|
|
1507
|
+
# Represents an identifier (column, table, schema, etc.).
|
|
1402
1508
|
class Identifier < GenericExpression
|
|
1403
1509
|
include QualifyingMethods
|
|
1404
1510
|
|
|
1405
|
-
# The
|
|
1511
|
+
# The identifier to reference
|
|
1406
1512
|
attr_reader :value
|
|
1407
1513
|
|
|
1408
|
-
# Set the
|
|
1514
|
+
# Set the identifier to the given argument
|
|
1409
1515
|
def initialize(value)
|
|
1410
1516
|
@value = value
|
|
1517
|
+
freeze
|
|
1411
1518
|
end
|
|
1412
1519
|
|
|
1413
1520
|
# Create a Function using this identifier as the functions name, with
|
|
@@ -1432,6 +1539,7 @@ module Sequel
|
|
|
1432
1539
|
def initialize(join_type, table_expr)
|
|
1433
1540
|
@join_type = join_type
|
|
1434
1541
|
@table_expr = table_expr
|
|
1542
|
+
freeze
|
|
1435
1543
|
end
|
|
1436
1544
|
|
|
1437
1545
|
# The table/set related to the JOIN, without any alias.
|
|
@@ -1485,8 +1593,8 @@ module Sequel
|
|
|
1485
1593
|
|
|
1486
1594
|
# Create an object with the given USING conditions and call super
|
|
1487
1595
|
# with the remaining args.
|
|
1488
|
-
def initialize(
|
|
1489
|
-
@using =
|
|
1596
|
+
def initialize(cols, *args)
|
|
1597
|
+
@using = cols
|
|
1490
1598
|
super(*args)
|
|
1491
1599
|
end
|
|
1492
1600
|
|
|
@@ -1514,8 +1622,14 @@ module Sequel
|
|
|
1514
1622
|
# Create an object with the given string, placeholder arguments, and parens flag.
|
|
1515
1623
|
def initialize(str, args, parens=false)
|
|
1516
1624
|
@str = str
|
|
1517
|
-
@args = args.is_a?(Array) && args.length == 1 && (v = args
|
|
1625
|
+
@args = args.is_a?(Array) && args.length == 1 && (v = args[0]).is_a?(Hash) ? v : args
|
|
1518
1626
|
@parens = parens
|
|
1627
|
+
freeze
|
|
1628
|
+
end
|
|
1629
|
+
|
|
1630
|
+
# Return a copy of the that will be surrounded by parantheses.
|
|
1631
|
+
def with_parens
|
|
1632
|
+
@parens ? self : self.class.new(@str, @args, true)
|
|
1519
1633
|
end
|
|
1520
1634
|
|
|
1521
1635
|
to_s_method :placeholder_literal_string_sql
|
|
@@ -1557,7 +1671,10 @@ module Sequel
|
|
|
1557
1671
|
#
|
|
1558
1672
|
# :nulls :: Can be :first/:last for NULLS FIRST/LAST.
|
|
1559
1673
|
def initialize(expression, descending = true, opts=OPTS)
|
|
1560
|
-
@expression
|
|
1674
|
+
@expression = expression
|
|
1675
|
+
@descending = descending
|
|
1676
|
+
@nulls = opts[:nulls]
|
|
1677
|
+
freeze
|
|
1561
1678
|
end
|
|
1562
1679
|
|
|
1563
1680
|
# Return a copy that is ordered ASC
|
|
@@ -1590,7 +1707,9 @@ module Sequel
|
|
|
1590
1707
|
|
|
1591
1708
|
# Set the table and column to the given arguments
|
|
1592
1709
|
def initialize(table, column)
|
|
1593
|
-
@table
|
|
1710
|
+
@table = convert_identifier(table)
|
|
1711
|
+
@column = convert_identifier(column)
|
|
1712
|
+
freeze
|
|
1594
1713
|
end
|
|
1595
1714
|
|
|
1596
1715
|
# Create a Function using this identifier as the functions name, with
|
|
@@ -1600,6 +1719,18 @@ module Sequel
|
|
|
1600
1719
|
end
|
|
1601
1720
|
|
|
1602
1721
|
to_s_method :qualified_identifier_sql, "@table, @column"
|
|
1722
|
+
|
|
1723
|
+
private
|
|
1724
|
+
|
|
1725
|
+
# Automatically convert SQL::Identifiers to strings
|
|
1726
|
+
def convert_identifier(identifier)
|
|
1727
|
+
case identifier
|
|
1728
|
+
when SQL::Identifier
|
|
1729
|
+
identifier.value.to_s
|
|
1730
|
+
else
|
|
1731
|
+
identifier
|
|
1732
|
+
end
|
|
1733
|
+
end
|
|
1603
1734
|
end
|
|
1604
1735
|
|
|
1605
1736
|
# Subclass of +ComplexExpression+ where the expression results
|
|
@@ -1610,15 +1741,16 @@ module Sequel
|
|
|
1610
1741
|
include InequalityMethods
|
|
1611
1742
|
|
|
1612
1743
|
# Map of [regexp, case_insenstive] to +ComplexExpression+ operator symbol
|
|
1613
|
-
LIKE_MAP = {[true, true]=>:'~*', [true, false]=>:~, [false, true]=>:ILIKE, [false, false]=>:LIKE}
|
|
1744
|
+
LIKE_MAP = {[true, true]=>:'~*', [true, false]=>:~, [false, true]=>:ILIKE, [false, false]=>:LIKE}.freeze
|
|
1745
|
+
LIKE_MAP.each_key(&:freeze)
|
|
1614
1746
|
|
|
1615
1747
|
# Creates a SQL pattern match exprssion. left (l) is the SQL string we
|
|
1616
1748
|
# are matching against, and ces are the patterns we are matching.
|
|
1617
1749
|
# The match succeeds if any of the patterns match (SQL OR).
|
|
1618
1750
|
#
|
|
1619
1751
|
# If a regular expression is used as a pattern, an SQL regular expression will be
|
|
1620
|
-
# used, which is currently only supported on
|
|
1621
|
-
# that
|
|
1752
|
+
# used, which is currently only supported on some databases. Be aware
|
|
1753
|
+
# that SQL regular expression syntax is similar to ruby
|
|
1622
1754
|
# regular expression syntax, but it not exactly the same, especially for
|
|
1623
1755
|
# advanced regular expression features. Sequel just uses the source of the
|
|
1624
1756
|
# ruby regular expression verbatim as the SQL regular expression string.
|
|
@@ -1631,17 +1763,17 @@ module Sequel
|
|
|
1631
1763
|
# if a case insensitive regular expression is used (//i), that particular
|
|
1632
1764
|
# pattern which will always be case insensitive.
|
|
1633
1765
|
#
|
|
1634
|
-
# StringExpression.like(:a, 'a%') # "a" LIKE 'a%' ESCAPE '\'
|
|
1635
|
-
# StringExpression.like(:a, 'a%', :
|
|
1636
|
-
# StringExpression.like(:a, 'a%', /^a/i) # "a" LIKE 'a%' ESCAPE '\' OR "a" ~* '^a'
|
|
1766
|
+
# StringExpression.like(:a, 'a%') # ("a" LIKE 'a%' ESCAPE '\')
|
|
1767
|
+
# StringExpression.like(:a, 'a%', case_insensitive: true) # ("a" ILIKE 'a%' ESCAPE '\')
|
|
1768
|
+
# StringExpression.like(:a, 'a%', /^a/i) # (("a" LIKE 'a%' ESCAPE '\') OR ("a" ~* '^a'))
|
|
1637
1769
|
def self.like(l, *ces)
|
|
1638
1770
|
l, lre, lci = like_element(l)
|
|
1639
|
-
lci = (ces.last.is_a?(Hash) ? ces.pop :
|
|
1640
|
-
ces.
|
|
1771
|
+
lci = (ces.last.is_a?(Hash) ? ces.pop : OPTS)[:case_insensitive] ? true : lci
|
|
1772
|
+
ces.map! do |ce|
|
|
1641
1773
|
r, rre, rci = like_element(ce)
|
|
1642
1774
|
BooleanExpression.new(LIKE_MAP[[lre||rre, lci||rci]], l, r)
|
|
1643
1775
|
end
|
|
1644
|
-
ces.length == 1 ? ces
|
|
1776
|
+
ces.length == 1 ? ces[0] : BooleanExpression.new(:OR, *ces)
|
|
1645
1777
|
end
|
|
1646
1778
|
|
|
1647
1779
|
# Returns a three element array, made up of:
|
|
@@ -1666,30 +1798,33 @@ module Sequel
|
|
|
1666
1798
|
# Represents an SQL array access, with multiple possible arguments.
|
|
1667
1799
|
class Subscript < GenericExpression
|
|
1668
1800
|
# The SQL array column
|
|
1669
|
-
attr_reader :
|
|
1801
|
+
attr_reader :expression
|
|
1802
|
+
alias f expression
|
|
1670
1803
|
|
|
1671
1804
|
# The array of subscripts to use (should be an array of numbers)
|
|
1672
1805
|
attr_reader :sub
|
|
1673
1806
|
|
|
1674
1807
|
# Set the array column and subscripts to the given arguments
|
|
1675
|
-
def initialize(
|
|
1676
|
-
@
|
|
1808
|
+
def initialize(expression, sub)
|
|
1809
|
+
@expression = expression
|
|
1810
|
+
@sub = sub
|
|
1811
|
+
freeze
|
|
1677
1812
|
end
|
|
1678
1813
|
|
|
1679
1814
|
# Create a new +Subscript+ appending the given subscript(s)
|
|
1680
1815
|
# to the current array of subscripts.
|
|
1681
1816
|
#
|
|
1682
|
-
# :a.sql_subscript(2) # a[2]
|
|
1683
|
-
# :a.sql_subscript(2) | 1 # a[2, 1]
|
|
1817
|
+
# Sequel[:a].sql_subscript(2) # a[2]
|
|
1818
|
+
# Sequel[:a].sql_subscript(2) | 1 # a[2, 1]
|
|
1684
1819
|
def |(sub)
|
|
1685
|
-
Subscript.new(@
|
|
1820
|
+
Subscript.new(@expression, @sub + Array(sub))
|
|
1686
1821
|
end
|
|
1687
1822
|
|
|
1688
1823
|
# Create a new +Subscript+ by accessing a subarray of a multidimensional
|
|
1689
1824
|
# array.
|
|
1690
1825
|
#
|
|
1691
|
-
# :a.sql_subscript(2) # a[2]
|
|
1692
|
-
# :a.sql_subscript(2)[1] # a[2][1]
|
|
1826
|
+
# Sequel[:a].sql_subscript(2) # a[2]
|
|
1827
|
+
# Sequel[:a].sql_subscript(2)[1] # a[2][1]
|
|
1693
1828
|
def [](sub)
|
|
1694
1829
|
Subscript.new(self, Array(sub))
|
|
1695
1830
|
end
|
|
@@ -1701,64 +1836,46 @@ module Sequel
|
|
|
1701
1836
|
# ruby array of two element arrays as an SQL value list instead of an ordered
|
|
1702
1837
|
# hash-like conditions specifier.
|
|
1703
1838
|
class ValueList < ::Array
|
|
1839
|
+
# Show that this is a value list and not just an array
|
|
1840
|
+
def inspect
|
|
1841
|
+
"#<#{self.class} #{super}>"
|
|
1842
|
+
end
|
|
1704
1843
|
end
|
|
1705
1844
|
|
|
1706
|
-
# The purpose of the +VirtualRow+ class is to allow the easy creation of SQL identifiers and functions
|
|
1707
|
-
#
|
|
1708
|
-
# the methods defined by Sequel, if you are running on ruby 1.9, or if you are not using the
|
|
1709
|
-
# core extensions.
|
|
1845
|
+
# The purpose of the +VirtualRow+ class is to allow the easy creation of SQL identifiers and functions,
|
|
1846
|
+
# in a way that leads to more compact code.
|
|
1710
1847
|
#
|
|
1711
|
-
# An instance of this class is yielded to the block supplied to <tt>Dataset#
|
|
1848
|
+
# 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>
|
|
1712
1849
|
# (and the other methods that accept a block and pass it to one of those methods).
|
|
1713
1850
|
# If the block doesn't take an argument, the block is instance_execed in the context of
|
|
1714
1851
|
# an instance of this class.
|
|
1715
1852
|
#
|
|
1716
|
-
# +VirtualRow+ uses +method_missing+ to return either an +Identifier+, +
|
|
1853
|
+
# +VirtualRow+ uses +method_missing+ to return either an +Identifier+, +Function+
|
|
1717
1854
|
# depending on how it is called.
|
|
1718
1855
|
#
|
|
1719
|
-
# If a block is _not_ given, creates one of the following objects:
|
|
1720
|
-
#
|
|
1721
1856
|
# +Function+ :: Returned if any arguments are supplied, using the method name
|
|
1722
1857
|
# as the function name, and the arguments as the function arguments.
|
|
1723
|
-
# +QualifiedIdentifier+ :: Returned if the method name contains __, with the
|
|
1724
|
-
# table being the part before __, and the column being the part after.
|
|
1725
1858
|
# +Identifier+ :: Returned otherwise, using the method name.
|
|
1726
1859
|
#
|
|
1727
|
-
# If
|
|
1728
|
-
#
|
|
1729
|
-
#
|
|
1730
|
-
# no arguments given :: creates a +Function+ with no arguments.
|
|
1731
|
-
# :* :: creates a +Function+ with a literal wildcard argument (*), mostly useful for COUNT.
|
|
1732
|
-
# :distinct :: creates a +Function+ that prepends DISTINCT to the rest of the arguments, mostly
|
|
1733
|
-
# useful for aggregate functions.
|
|
1734
|
-
# :over :: creates a +Function+ with a window. If a second argument is provided, it should be a hash
|
|
1735
|
-
# of options which are used to create the +Window+ (with possible keys :window, :partition, :order, and :frame). The
|
|
1736
|
-
# arguments to the function itself should be specified as <tt>:*=>true</tt> for a wildcard, or via
|
|
1737
|
-
# the <tt>:args</tt> option.
|
|
1860
|
+
# If splitting symbols has been enabled (not the default), then method calls without
|
|
1861
|
+
# arguments will return +QualifiedIdentifier+ instances if the method call includes a
|
|
1862
|
+
# double underscore.
|
|
1738
1863
|
#
|
|
1739
1864
|
# Examples:
|
|
1740
1865
|
#
|
|
1741
1866
|
# ds = DB[:t]
|
|
1742
1867
|
#
|
|
1743
1868
|
# # Argument yielded to block
|
|
1744
|
-
# ds.
|
|
1869
|
+
# ds.where{|r| r.name < 2} # SELECT * FROM t WHERE (name < 2)
|
|
1745
1870
|
#
|
|
1746
|
-
# # Block without argument (
|
|
1747
|
-
# ds.
|
|
1748
|
-
#
|
|
1749
|
-
# # Qualified identifiers
|
|
1750
|
-
# ds.filter{table__column + 1 < 2} # SELECT * FROM t WHERE ((table.column + 1) < 2)
|
|
1871
|
+
# # Block without argument (instance_exec)
|
|
1872
|
+
# ds.where{name < 2} # SELECT * FROM t WHERE (name < 2)
|
|
1751
1873
|
#
|
|
1752
1874
|
# # Functions
|
|
1753
|
-
# ds.
|
|
1754
|
-
# ds.select{version
|
|
1755
|
-
# ds.select{count
|
|
1756
|
-
# ds.select{count(
|
|
1757
|
-
#
|
|
1758
|
-
# # Window Functions
|
|
1759
|
-
# ds.select{rank(:over){}} # SELECT rank() OVER () FROM t
|
|
1760
|
-
# ds.select{count(:over, :*=>true){}} # SELECT count(*) OVER () FROM t
|
|
1761
|
-
# ds.select{sum(:over, :args=>col1, :partition=>col2, :order=>col3){}} # SELECT sum(col1) OVER (PARTITION BY col2 ORDER BY col3) FROM t
|
|
1875
|
+
# ds.where{is_active(1, 'arg2')} # SELECT * FROM t WHERE is_active(1, 'arg2')
|
|
1876
|
+
# ds.select{version.function} # SELECT version() FROM t
|
|
1877
|
+
# ds.select{count.function.*} # SELECT count(*) FROM t
|
|
1878
|
+
# ds.select{count(col1).distinct} # SELECT count(DISTINCT col1) FROM t
|
|
1762
1879
|
#
|
|
1763
1880
|
# # Math Operators
|
|
1764
1881
|
# ds.select{|o| o.+(1, :a).as(:b)} # SELECT (1 + a) AS b FROM t
|
|
@@ -1767,25 +1884,19 @@ module Sequel
|
|
|
1767
1884
|
# ds.select{|o| o./(4, :a).as(:b)} # SELECT (4 / a) AS b FROM t
|
|
1768
1885
|
#
|
|
1769
1886
|
# # Boolean Operators
|
|
1770
|
-
# ds.
|
|
1771
|
-
# ds.
|
|
1772
|
-
# ds.
|
|
1773
|
-
# ds.
|
|
1887
|
+
# ds.where{|o| o.&({a: 1}, :b)} # SELECT * FROM t WHERE ((a = 1) AND b)
|
|
1888
|
+
# ds.where{|o| o.|({a: 1}, :b)} # SELECT * FROM t WHERE ((a = 1) OR b)
|
|
1889
|
+
# ds.where{|o| o.~(a: 1)} # SELECT * FROM t WHERE (a != 1)
|
|
1890
|
+
# ds.where{|o| o.~(a: 1, b: 2)} # SELECT * FROM t WHERE ((a != 1) OR (b != 2))
|
|
1774
1891
|
#
|
|
1775
1892
|
# # Inequality Operators
|
|
1776
|
-
# ds.
|
|
1777
|
-
# ds.
|
|
1778
|
-
# ds.
|
|
1779
|
-
# ds.
|
|
1780
|
-
#
|
|
1781
|
-
# # Literal Strings
|
|
1782
|
-
# ds.filter{{a=>`some SQL`}} # SELECT * FROM t WHERE (a = some SQL)
|
|
1893
|
+
# ds.where{|o| o.>(1, :a)} # SELECT * FROM t WHERE (1 > a)
|
|
1894
|
+
# ds.where{|o| o.<(2, :a)} # SELECT * FROM t WHERE (2 < a)
|
|
1895
|
+
# ds.where{|o| o.>=(3, :a)} # SELECT * FROM t WHERE (3 >= a)
|
|
1896
|
+
# ds.where{|o| o.<=(4, :a)} # SELECT * FROM t WHERE (4 <= a)
|
|
1783
1897
|
#
|
|
1784
1898
|
# For a more detailed explanation, see the {Virtual Rows guide}[rdoc-ref:doc/virtual_rows.rdoc].
|
|
1785
1899
|
class VirtualRow < BasicObject
|
|
1786
|
-
QUESTION_MARK = LiteralString.new('?').freeze
|
|
1787
|
-
DOUBLE_UNDERSCORE = '__'.freeze
|
|
1788
|
-
|
|
1789
1900
|
include OperatorBuilders
|
|
1790
1901
|
|
|
1791
1902
|
%w'> < >= <='.each do |op|
|
|
@@ -1796,50 +1907,82 @@ module Sequel
|
|
|
1796
1907
|
END
|
|
1797
1908
|
end
|
|
1798
1909
|
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
Sequel::LiteralString.new(s)
|
|
1910
|
+
def initialize
|
|
1911
|
+
freeze
|
|
1802
1912
|
end
|
|
1803
1913
|
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1914
|
+
m = Module.new do
|
|
1915
|
+
# Return an +Identifier+, +QualifiedIdentifier+, or +Function+, depending
|
|
1916
|
+
# on arguments and whether a block is provided. Does not currently call the block.
|
|
1917
|
+
# See the class level documentation.
|
|
1918
|
+
def method_missing(m, *args)
|
|
1809
1919
|
if args.empty?
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
when :*
|
|
1814
|
-
Function.new(m, *args).*
|
|
1815
|
-
when :distinct
|
|
1816
|
-
Function.new(m, *args).distinct
|
|
1817
|
-
when :over
|
|
1818
|
-
opts = args.shift || OPTS
|
|
1819
|
-
f = Function.new(m, *::Kernel.Array(opts[:args]))
|
|
1820
|
-
f = f.* if opts[:*]
|
|
1821
|
-
f.over(opts)
|
|
1920
|
+
if Sequel.split_symbols?
|
|
1921
|
+
table, column = m.to_s.split('__', 2)
|
|
1922
|
+
column ? QualifiedIdentifier.new(table, column) : Identifier.new(m)
|
|
1822
1923
|
else
|
|
1823
|
-
|
|
1924
|
+
Identifier.new(m)
|
|
1824
1925
|
end
|
|
1926
|
+
else
|
|
1927
|
+
Function.new(m, *args)
|
|
1825
1928
|
end
|
|
1826
|
-
elsif args.empty?
|
|
1827
|
-
table, column = m.to_s.split(DOUBLE_UNDERSCORE, 2)
|
|
1828
|
-
column ? QualifiedIdentifier.new(table, column) : Identifier.new(m)
|
|
1829
|
-
else
|
|
1830
|
-
Function.new(m, *args)
|
|
1831
1929
|
end
|
|
1832
1930
|
end
|
|
1931
|
+
include m
|
|
1833
1932
|
|
|
1834
1933
|
Sequel::VIRTUAL_ROW = new
|
|
1835
1934
|
end
|
|
1836
1935
|
|
|
1837
1936
|
# A +Window+ is part of a window function specifying the window over which a window function operates.
|
|
1937
|
+
#
|
|
1938
|
+
# Sequel::SQL::Window.new(partition: :col1)
|
|
1939
|
+
# # (PARTITION BY col1)
|
|
1940
|
+
# Sequel::SQL::Window.new(partition: [:col2, :col3])
|
|
1941
|
+
# # (PARTITION BY col2, col3)
|
|
1942
|
+
#
|
|
1943
|
+
# Sequel::SQL::Window.new(order: :col4)
|
|
1944
|
+
# # (ORDER BY col4)
|
|
1945
|
+
# Sequel::SQL::Window.new(order: [:col5, Sequel.desc(:col6)])
|
|
1946
|
+
# # (ORDER BY col5, col6 DESC)
|
|
1947
|
+
#
|
|
1948
|
+
# Sequel::SQL::Window.new(partition: :col7, frame: :all)
|
|
1949
|
+
# # (PARTITION BY col7 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
|
|
1950
|
+
# Sequel::SQL::Window.new(partition: :col7, frame: :rows)
|
|
1951
|
+
# # (PARTITION BY col7 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
|
|
1952
|
+
# Sequel::SQL::Window.new(partition: :col7, frame: {type: :range, start: current})
|
|
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)
|
|
1962
|
+
#
|
|
1963
|
+
# Sequel::SQL::Window.new(window: :named_window) # you can create a named window with Dataset#window
|
|
1964
|
+
# # (named_window)
|
|
1838
1965
|
class Window < Expression
|
|
1839
1966
|
# The options for this window. Options currently supported:
|
|
1840
|
-
# :frame :: if specified, should be :all, :rows,
|
|
1841
|
-
#
|
|
1842
|
-
#
|
|
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.
|
|
1843
1986
|
# :order :: order on the column(s) given
|
|
1844
1987
|
# :partition :: partition/group on the column(s) given
|
|
1845
1988
|
# :window :: base results on a previously specified named window
|
|
@@ -1847,7 +1990,8 @@ module Sequel
|
|
|
1847
1990
|
|
|
1848
1991
|
# Set the options to the options given
|
|
1849
1992
|
def initialize(opts=OPTS)
|
|
1850
|
-
@opts = opts
|
|
1993
|
+
@opts = opts.frozen? ? opts : Hash[opts].freeze
|
|
1994
|
+
freeze
|
|
1851
1995
|
end
|
|
1852
1996
|
|
|
1853
1997
|
to_s_method :window_sql, '@opts'
|
|
@@ -1862,6 +2006,7 @@ module Sequel
|
|
|
1862
2006
|
# Set the value wrapped by the object.
|
|
1863
2007
|
def initialize(value)
|
|
1864
2008
|
@value = value
|
|
2009
|
+
freeze
|
|
1865
2010
|
end
|
|
1866
2011
|
|
|
1867
2012
|
to_s_method :literal, '@value'
|
|
@@ -1880,6 +2025,11 @@ module Sequel
|
|
|
1880
2025
|
include SQL::InequalityMethods
|
|
1881
2026
|
include SQL::AliasMethods
|
|
1882
2027
|
include SQL::CastMethods
|
|
2028
|
+
|
|
2029
|
+
# Show that the current string is a literal string in addition to the output.
|
|
2030
|
+
def inspect
|
|
2031
|
+
"#<#{self.class} #{super}>"
|
|
2032
|
+
end
|
|
1883
2033
|
|
|
1884
2034
|
# Return self if no args are given, otherwise return a SQL::PlaceholderLiteralString
|
|
1885
2035
|
# with the current string and the given args.
|