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/dataset/misc.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
class Dataset
|
|
3
5
|
# ---------------------
|
|
@@ -5,11 +7,6 @@ module Sequel
|
|
|
5
7
|
# These methods don't fit cleanly into another section.
|
|
6
8
|
# ---------------------
|
|
7
9
|
|
|
8
|
-
NOTIMPL_MSG = "This method must be overridden in Sequel adapters".freeze
|
|
9
|
-
ARRAY_ACCESS_ERROR_MSG = 'You cannot call Dataset#[] with an integer or with no arguments.'.freeze
|
|
10
|
-
ARG_BLOCK_ERROR_MSG = 'Must use either an argument or a block, not both'.freeze
|
|
11
|
-
IMPORT_ERROR_MSG = 'Using Sequel::Dataset#import an empty column array is not allowed'.freeze
|
|
12
|
-
|
|
13
10
|
# The database related to this dataset. This is the Database instance that
|
|
14
11
|
# will execute all of this dataset's queries.
|
|
15
12
|
attr_reader :db
|
|
@@ -28,12 +25,14 @@ module Sequel
|
|
|
28
25
|
def initialize(db)
|
|
29
26
|
@db = db
|
|
30
27
|
@opts = OPTS
|
|
28
|
+
@cache = {}
|
|
29
|
+
freeze
|
|
31
30
|
end
|
|
32
31
|
|
|
33
|
-
# Define a hash value such that datasets with the same
|
|
32
|
+
# Define a hash value such that datasets with the same class, DB, and opts
|
|
34
33
|
# will be considered equal.
|
|
35
34
|
def ==(o)
|
|
36
|
-
o.is_a?(self.class) && db == o.db && opts == o.opts
|
|
35
|
+
o.is_a?(self.class) && db == o.db && opts == o.opts
|
|
37
36
|
end
|
|
38
37
|
|
|
39
38
|
# An object representing the current date or time, should be an instance
|
|
@@ -47,18 +46,16 @@ module Sequel
|
|
|
47
46
|
self == o
|
|
48
47
|
end
|
|
49
48
|
|
|
50
|
-
#
|
|
49
|
+
# Return self, as datasets are always frozen.
|
|
51
50
|
def dup
|
|
52
|
-
|
|
53
|
-
o.instance_variable_set(:@frozen, false) if frozen?
|
|
54
|
-
o
|
|
51
|
+
self
|
|
55
52
|
end
|
|
56
53
|
|
|
57
54
|
# Yield a dataset for each server in the connection pool that is tied to that server.
|
|
58
55
|
# Intended for use in sharded environments where all servers need to be modified
|
|
59
56
|
# with the same data:
|
|
60
57
|
#
|
|
61
|
-
# DB[:configs].where(:
|
|
58
|
+
# DB[:configs].where(key: 'setting').each_server{|ds| ds.update(value: 'new_value')}
|
|
62
59
|
def each_server
|
|
63
60
|
db.servers.each{|s| yield server(s)}
|
|
64
61
|
end
|
|
@@ -72,15 +69,22 @@ module Sequel
|
|
|
72
69
|
string.gsub(/[\\%_]/){|m| "\\#{m}"}
|
|
73
70
|
end
|
|
74
71
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
if TRUE_FREEZE
|
|
73
|
+
# Freeze the opts when freezing the dataset.
|
|
74
|
+
def freeze
|
|
75
|
+
@opts.freeze
|
|
76
|
+
super
|
|
77
|
+
end
|
|
78
|
+
else
|
|
79
|
+
# :nocov:
|
|
80
|
+
def freeze # :nodoc:
|
|
81
|
+
self
|
|
82
|
+
end
|
|
80
83
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
def frozen? # :nodoc:
|
|
85
|
+
true
|
|
86
|
+
end
|
|
87
|
+
# :nocov:
|
|
84
88
|
end
|
|
85
89
|
|
|
86
90
|
# Alias of +first_source_alias+
|
|
@@ -94,7 +98,7 @@ module Sequel
|
|
|
94
98
|
# DB[:table].first_source_alias
|
|
95
99
|
# # => :table
|
|
96
100
|
#
|
|
97
|
-
# DB[:
|
|
101
|
+
# DB[Sequel[:table].as(:t)].first_source_alias
|
|
98
102
|
# # => :t
|
|
99
103
|
def first_source_alias
|
|
100
104
|
source = @opts[:from]
|
|
@@ -119,7 +123,7 @@ module Sequel
|
|
|
119
123
|
# DB[:table].first_source_table
|
|
120
124
|
# # => :table
|
|
121
125
|
#
|
|
122
|
-
# DB[:
|
|
126
|
+
# DB[Sequel[:table].as(:t)].first_source_table
|
|
123
127
|
# # => :table
|
|
124
128
|
def first_source_table
|
|
125
129
|
source = @opts[:from]
|
|
@@ -137,30 +141,10 @@ module Sequel
|
|
|
137
141
|
end
|
|
138
142
|
end
|
|
139
143
|
|
|
140
|
-
# Define a hash value such that datasets with the same
|
|
141
|
-
# will have the same hash value
|
|
144
|
+
# Define a hash value such that datasets with the same class, DB, and opts,
|
|
145
|
+
# will have the same hash value.
|
|
142
146
|
def hash
|
|
143
|
-
[db, opts
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
# The String instance method to call on identifiers before sending them to
|
|
147
|
-
# the database.
|
|
148
|
-
def identifier_input_method
|
|
149
|
-
if defined?(@identifier_input_method)
|
|
150
|
-
@identifier_input_method
|
|
151
|
-
else
|
|
152
|
-
@identifier_input_method = db.identifier_input_method
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
# The String instance method to call on identifiers before sending them to
|
|
157
|
-
# the database.
|
|
158
|
-
def identifier_output_method
|
|
159
|
-
if defined?(@identifier_output_method)
|
|
160
|
-
@identifier_output_method
|
|
161
|
-
else
|
|
162
|
-
@identifier_output_method = db.identifier_output_method
|
|
163
|
-
end
|
|
147
|
+
[self.class, db, opts].hash
|
|
164
148
|
end
|
|
165
149
|
|
|
166
150
|
# Returns a string representation of the dataset including the class name
|
|
@@ -180,6 +164,12 @@ module Sequel
|
|
|
180
164
|
:x_sequel_row_number_x
|
|
181
165
|
end
|
|
182
166
|
|
|
167
|
+
# The row_proc for this database, should be any object that responds to +call+ with
|
|
168
|
+
# a single hash argument and returns the object you want #each to return.
|
|
169
|
+
def row_proc
|
|
170
|
+
@opts[:row_proc]
|
|
171
|
+
end
|
|
172
|
+
|
|
183
173
|
# Splits a possible implicit alias in +c+, handling both SQL::AliasedExpressions
|
|
184
174
|
# and Symbols. Returns an array of two elements, with the first being the
|
|
185
175
|
# main expression, and the second being the alias.
|
|
@@ -201,7 +191,7 @@ module Sequel
|
|
|
201
191
|
# SQL identifier that represents the unqualified column for the given value.
|
|
202
192
|
# The given value should be a Symbol, SQL::Identifier, SQL::QualifiedIdentifier,
|
|
203
193
|
# or SQL::AliasedExpression containing one of those. In other cases, this
|
|
204
|
-
# returns nil
|
|
194
|
+
# returns nil.
|
|
205
195
|
def unqualified_column_for(v)
|
|
206
196
|
unless v.is_a?(String)
|
|
207
197
|
_unqualified_column_for(v)
|
|
@@ -236,7 +226,7 @@ module Sequel
|
|
|
236
226
|
used_aliases += opts[:join].map{|j| j.table_alias ? alias_alias_symbol(j.table_alias) : alias_symbol(j.table)} if opts[:join]
|
|
237
227
|
if used_aliases.include?(table_alias)
|
|
238
228
|
i = 0
|
|
239
|
-
|
|
229
|
+
while true
|
|
240
230
|
ta = :"#{table_alias}_#{i}"
|
|
241
231
|
return ta unless used_aliases.include?(ta)
|
|
242
232
|
i += 1
|
|
@@ -246,8 +236,110 @@ module Sequel
|
|
|
246
236
|
end
|
|
247
237
|
end
|
|
248
238
|
|
|
239
|
+
# Return a modified dataset with quote_identifiers set.
|
|
240
|
+
def with_quote_identifiers(v)
|
|
241
|
+
clone(:quote_identifiers=>v, :skip_symbol_cache=>true)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
protected
|
|
245
|
+
|
|
246
|
+
# Access the cache for the current dataset. Should be used with caution,
|
|
247
|
+
# as access to the cache is not thread safe without a mutex if other
|
|
248
|
+
# threads can reference the dataset. Symbol keys prefixed with an
|
|
249
|
+
# underscore are reserved for internal use.
|
|
250
|
+
attr_reader :cache
|
|
251
|
+
|
|
252
|
+
# Retreive a value from the dataset's cache in a thread safe manner.
|
|
253
|
+
def cache_get(k)
|
|
254
|
+
Sequel.synchronize{@cache[k]}
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Set a value in the dataset's cache in a thread safe manner.
|
|
258
|
+
def cache_set(k, v)
|
|
259
|
+
Sequel.synchronize{@cache[k] = v}
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# Clear the columns hash for the current dataset. This is not a
|
|
263
|
+
# thread safe operation, so it should only be used if the dataset
|
|
264
|
+
# could not be used by another thread (such as one that was just
|
|
265
|
+
# created via clone).
|
|
266
|
+
def clear_columns_cache
|
|
267
|
+
@cache.delete(:_columns)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# The cached columns for the current dataset.
|
|
271
|
+
def _columns
|
|
272
|
+
cache_get(:_columns)
|
|
273
|
+
end
|
|
274
|
+
|
|
249
275
|
private
|
|
250
276
|
|
|
277
|
+
# Check the cache for the given key, returning the value.
|
|
278
|
+
# Otherwise, yield to get the dataset and cache the dataset under the given key.
|
|
279
|
+
def cached_dataset(key)
|
|
280
|
+
unless ds = cache_get(key)
|
|
281
|
+
ds = yield
|
|
282
|
+
cache_set(key, ds)
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
ds
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Return a cached placeholder literalizer for the given key if there
|
|
289
|
+
# is one for this dataset. If there isn't one, increment the counter
|
|
290
|
+
# for the number of calls for the key, and if the counter is at least
|
|
291
|
+
# three, then create a placeholder literalizer by yielding to the block,
|
|
292
|
+
# and cache it.
|
|
293
|
+
def cached_placeholder_literalizer(key)
|
|
294
|
+
if loader = cache_get(key)
|
|
295
|
+
return loader unless loader.is_a?(Integer)
|
|
296
|
+
loader += 1
|
|
297
|
+
|
|
298
|
+
if loader >= 3
|
|
299
|
+
loader = Sequel::Dataset::PlaceholderLiteralizer.loader(self){|pl, _| yield pl}
|
|
300
|
+
cache_set(key, loader)
|
|
301
|
+
else
|
|
302
|
+
cache_set(key, loader + 1)
|
|
303
|
+
loader = nil
|
|
304
|
+
end
|
|
305
|
+
elsif cache_sql?
|
|
306
|
+
cache_set(key, 1)
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
loader
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# Return a cached placeholder literalizer for the key, unless where_block is
|
|
313
|
+
# nil and where_args is an empty array or hash. This is designed to guard
|
|
314
|
+
# against placeholder literalizer use when passing arguments to where
|
|
315
|
+
# in the uncached case and filter_expr if a cached placeholder literalizer
|
|
316
|
+
# is used.
|
|
317
|
+
def cached_where_placeholder_literalizer(where_args, where_block, key, &block)
|
|
318
|
+
where_args = where_args[0] if where_args.length == 1
|
|
319
|
+
unless where_block
|
|
320
|
+
return if where_args == OPTS || where_args == EMPTY_ARRAY
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
cached_placeholder_literalizer(key, &block)
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
# Set the columns for the current dataset.
|
|
327
|
+
def columns=(v)
|
|
328
|
+
cache_set(:_columns, v)
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
# Set the db, opts, and cache for the copy of the dataset.
|
|
332
|
+
def initialize_clone(c, _=nil)
|
|
333
|
+
@db = c.db
|
|
334
|
+
@opts = Hash[c.opts]
|
|
335
|
+
if cols = c.cache_get(:_columns)
|
|
336
|
+
@cache = {:_columns=>cols}
|
|
337
|
+
else
|
|
338
|
+
@cache = {}
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
alias initialize_copy initialize_clone
|
|
342
|
+
|
|
251
343
|
# Internal recursive version of unqualified_column_for, handling Strings inside
|
|
252
344
|
# of other objects.
|
|
253
345
|
def _unqualified_column_for(v)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
class Dataset
|
|
3
5
|
# PlaceholderLiteralizer allows you to record the application of arbitrary changes
|
|
@@ -13,7 +15,7 @@ module Sequel
|
|
|
13
15
|
# Example:
|
|
14
16
|
#
|
|
15
17
|
# loader = Sequel::Dataset::PlaceholderLiteralizer.loader(DB[:items]) do |pl, ds|
|
|
16
|
-
# ds.where(:
|
|
18
|
+
# ds.where(id: pl.arg).exclude(name: pl.arg).limit(1)
|
|
17
19
|
# end
|
|
18
20
|
# loader.first(1, "foo")
|
|
19
21
|
# # SELECT * FROM items WHERE ((id = 1) AND (name != 'foo')) LIMIT 1
|
|
@@ -25,7 +27,7 @@ module Sequel
|
|
|
25
27
|
# Note that this method does not handle all possible cases. For example:
|
|
26
28
|
#
|
|
27
29
|
# loader = Sequel::Dataset::PlaceholderLiteralizer.loader(DB[:items]) do |pl, ds|
|
|
28
|
-
# ds.join(pl.arg, :
|
|
30
|
+
# ds.join(pl.arg, item_id: :id)
|
|
29
31
|
# end
|
|
30
32
|
# loader.all(:cart_items)
|
|
31
33
|
#
|
|
@@ -33,7 +35,7 @@ module Sequel
|
|
|
33
35
|
# best to add a table alias when joining:
|
|
34
36
|
#
|
|
35
37
|
# loader = Sequel::Dataset::PlaceholderLiteralizer.loader(DB[:items]) do |pl, ds|
|
|
36
|
-
# ds.join(Sequel.as(pl.arg, :t), :
|
|
38
|
+
# ds.join(Sequel.as(pl.arg, :t), item_id: :id)
|
|
37
39
|
# end
|
|
38
40
|
# loader.all(:cart_items)
|
|
39
41
|
#
|
|
@@ -49,6 +51,7 @@ module Sequel
|
|
|
49
51
|
@recorder = recorder
|
|
50
52
|
@pos = pos
|
|
51
53
|
@transformer = transformer
|
|
54
|
+
freeze
|
|
52
55
|
end
|
|
53
56
|
|
|
54
57
|
# Record the SQL query offset, argument position, and transforming block where the
|
|
@@ -74,23 +77,8 @@ module Sequel
|
|
|
74
77
|
# Yields the receiver and the dataset to the block, which should
|
|
75
78
|
# call #arg on the receiver for each placeholder argument, and
|
|
76
79
|
# return the dataset that you want to load.
|
|
77
|
-
def loader(dataset)
|
|
78
|
-
|
|
79
|
-
@args = []
|
|
80
|
-
ds = yield self, dataset
|
|
81
|
-
sql = ds.clone(:placeholder_literalizer=>self).sql
|
|
82
|
-
|
|
83
|
-
last_offset = 0
|
|
84
|
-
fragments = @args.map do |used_sql, offset, arg, t|
|
|
85
|
-
raise Error, "placeholder literalizer argument literalized into different string than dataset returned" unless used_sql.equal?(sql)
|
|
86
|
-
a = [sql[last_offset...offset], arg, t]
|
|
87
|
-
last_offset = offset
|
|
88
|
-
a
|
|
89
|
-
end
|
|
90
|
-
final_sql = sql[last_offset..-1]
|
|
91
|
-
|
|
92
|
-
arity = @argn+1
|
|
93
|
-
PlaceholderLiteralizer.new(ds.clone, fragments, final_sql, arity)
|
|
80
|
+
def loader(dataset, &block)
|
|
81
|
+
PlaceholderLiteralizer.new(*process(dataset, &block))
|
|
94
82
|
end
|
|
95
83
|
|
|
96
84
|
# Return an Argument with the specified position, or the next position. In
|
|
@@ -104,10 +92,53 @@ module Sequel
|
|
|
104
92
|
end
|
|
105
93
|
|
|
106
94
|
# Record the offset at which the argument is used in the SQL query, and any
|
|
107
|
-
# transforming
|
|
95
|
+
# transforming block.
|
|
108
96
|
def use(sql, arg, transformer)
|
|
109
97
|
@args << [sql, sql.length, arg, transformer]
|
|
110
98
|
end
|
|
99
|
+
|
|
100
|
+
private
|
|
101
|
+
|
|
102
|
+
# Return an array with two elements, the first being an
|
|
103
|
+
# SQL string with interpolated prepared argument placeholders
|
|
104
|
+
# (suitable for inspect), the the second being an array of
|
|
105
|
+
# SQL fragments suitable for using for creating a
|
|
106
|
+
# Sequel::SQL::PlaceholderLiteralString. Designed for use with
|
|
107
|
+
# emulated prepared statements.
|
|
108
|
+
def prepared_sql_and_frags(dataset, prepared_args, &block)
|
|
109
|
+
_, frags, final_sql, _ = process(dataset, &block)
|
|
110
|
+
|
|
111
|
+
frags = frags.map(&:first)
|
|
112
|
+
prepared_sql = String.new
|
|
113
|
+
frags.each_with_index do |sql, i|
|
|
114
|
+
prepared_sql << sql
|
|
115
|
+
prepared_sql << "$#{prepared_args[i]}"
|
|
116
|
+
end
|
|
117
|
+
frags << final_sql
|
|
118
|
+
prepared_sql << final_sql
|
|
119
|
+
|
|
120
|
+
[prepared_sql, frags]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Internals of #loader and #prepared_sql_and_frags.
|
|
124
|
+
def process(dataset)
|
|
125
|
+
@argn = -1
|
|
126
|
+
@args = []
|
|
127
|
+
ds = yield self, dataset
|
|
128
|
+
sql = ds.clone(:placeholder_literalizer=>self).sql
|
|
129
|
+
|
|
130
|
+
last_offset = 0
|
|
131
|
+
fragments = @args.map do |used_sql, offset, arg, t|
|
|
132
|
+
raise Error, "placeholder literalizer argument literalized into different string than dataset returned" unless used_sql.equal?(sql)
|
|
133
|
+
a = [sql[last_offset...offset], arg, t]
|
|
134
|
+
last_offset = offset
|
|
135
|
+
a
|
|
136
|
+
end
|
|
137
|
+
final_sql = sql[last_offset..-1]
|
|
138
|
+
|
|
139
|
+
arity = @argn+1
|
|
140
|
+
[ds, fragments, final_sql, arity]
|
|
141
|
+
end
|
|
111
142
|
end
|
|
112
143
|
|
|
113
144
|
# Create a PlaceholderLiteralizer by yielding a Recorder and dataset to the
|
|
@@ -123,13 +154,24 @@ module Sequel
|
|
|
123
154
|
@fragments = fragments
|
|
124
155
|
@final_sql = final_sql
|
|
125
156
|
@arity = arity
|
|
157
|
+
freeze
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Freeze the fragments and final SQL when freezing the literalizer.
|
|
161
|
+
def freeze
|
|
162
|
+
@fragments.freeze
|
|
163
|
+
@final_sql.freeze
|
|
164
|
+
super
|
|
126
165
|
end
|
|
127
166
|
|
|
128
167
|
# Return a new PlaceholderLiteralizer with a modified dataset. This yields the
|
|
129
168
|
# receiver's dataset to the block, and the block should return the new dataset
|
|
130
169
|
# to use.
|
|
131
170
|
def with_dataset
|
|
132
|
-
|
|
171
|
+
dataset = yield @dataset
|
|
172
|
+
other = dup
|
|
173
|
+
other.instance_variable_set(:@dataset, dataset)
|
|
174
|
+
other.freeze
|
|
133
175
|
end
|
|
134
176
|
|
|
135
177
|
# Return an array of all objects by running the SQL query for the given arguments.
|
|
@@ -157,7 +199,7 @@ module Sequel
|
|
|
157
199
|
# Return the SQL query to use for the given arguments.
|
|
158
200
|
def sql(*args)
|
|
159
201
|
raise Error, "wrong number of arguments (#{args.length} for #{@arity})" unless args.length == @arity
|
|
160
|
-
s =
|
|
202
|
+
s = String.new
|
|
161
203
|
ds = @dataset
|
|
162
204
|
@fragments.each do |sql, i, transformer|
|
|
163
205
|
s << sql
|
|
@@ -169,9 +211,7 @@ module Sequel
|
|
|
169
211
|
end
|
|
170
212
|
ds.literal_append(s, v)
|
|
171
213
|
end
|
|
172
|
-
|
|
173
|
-
s << sql
|
|
174
|
-
end
|
|
214
|
+
s << @final_sql
|
|
175
215
|
s
|
|
176
216
|
end
|
|
177
217
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
class Dataset
|
|
3
5
|
# ---------------------
|
|
@@ -34,33 +36,44 @@ module Sequel
|
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
private_class_method :prepared_statements_module
|
|
37
|
-
|
|
39
|
+
|
|
38
40
|
# Default implementation of the argument mapper to allow
|
|
39
41
|
# native database support for bind variables and prepared
|
|
40
42
|
# statements (as opposed to the emulated ones used by default).
|
|
41
43
|
module ArgumentMapper
|
|
42
44
|
# The name of the prepared statement, if any.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
def prepared_statement_name
|
|
46
|
+
@opts[:prepared_statement_name]
|
|
47
|
+
end
|
|
48
|
+
|
|
45
49
|
# The bind arguments to use for running this prepared statement
|
|
46
|
-
|
|
50
|
+
def bind_arguments
|
|
51
|
+
@opts[:bind_arguments]
|
|
52
|
+
end
|
|
47
53
|
|
|
48
54
|
# Set the bind arguments based on the hash and call super.
|
|
49
|
-
def call(bind_vars=
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
def call(bind_vars=OPTS, &block)
|
|
56
|
+
sql = prepared_sql
|
|
57
|
+
prepared_args.freeze
|
|
58
|
+
ps = bind(bind_vars)
|
|
59
|
+
ps.clone(:bind_arguments=>ps.map_to_prepared_args(ps.opts[:bind_vars]), :sql=>sql, :prepared_sql=>sql).run(&block)
|
|
54
60
|
end
|
|
55
61
|
|
|
56
62
|
# Override the given *_sql method based on the type, and
|
|
57
63
|
# cache the result of the sql.
|
|
58
64
|
def prepared_sql
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
if sql = @opts[:prepared_sql] || cache_get(:_prepared_sql)
|
|
66
|
+
return sql
|
|
67
|
+
end
|
|
68
|
+
cache_set(:_prepared_sql, super)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
# Report that prepared statements are not emulated, since
|
|
74
|
+
# all adapters that use this use native prepared statements.
|
|
75
|
+
def emulate_prepared_statements?
|
|
76
|
+
false
|
|
64
77
|
end
|
|
65
78
|
end
|
|
66
79
|
|
|
@@ -71,29 +84,37 @@ module Sequel
|
|
|
71
84
|
# into the query, which works on all databases, as it is no different
|
|
72
85
|
# from using the dataset without bind variables.
|
|
73
86
|
module PreparedStatementMethods
|
|
74
|
-
PLACEHOLDER_RE = /\A\$(.*)\z/
|
|
75
|
-
|
|
76
87
|
# Whether to log the full SQL query. By default, just the prepared statement
|
|
77
88
|
# name is generally logged on adapters that support native prepared statements.
|
|
78
|
-
|
|
89
|
+
def log_sql
|
|
90
|
+
@opts[:log_sql]
|
|
91
|
+
end
|
|
79
92
|
|
|
80
93
|
# The type of prepared statement, should be one of :select, :first,
|
|
81
|
-
# :insert, :update, or :
|
|
82
|
-
|
|
94
|
+
# :insert, :update, :delete, or :single_value
|
|
95
|
+
def prepared_type
|
|
96
|
+
@opts[:prepared_type]
|
|
97
|
+
end
|
|
83
98
|
|
|
84
99
|
# The array/hash of bound variable placeholder names.
|
|
85
|
-
|
|
100
|
+
def prepared_args
|
|
101
|
+
@opts[:prepared_args]
|
|
102
|
+
end
|
|
86
103
|
|
|
87
104
|
# The dataset that created this prepared statement.
|
|
88
|
-
|
|
105
|
+
def orig_dataset
|
|
106
|
+
@opts[:orig_dataset]
|
|
107
|
+
end
|
|
89
108
|
|
|
90
109
|
# The argument to supply to insert and update, which may use
|
|
91
110
|
# placeholders specified by prepared_args
|
|
92
|
-
|
|
111
|
+
def prepared_modify_values
|
|
112
|
+
@opts[:prepared_modify_values]
|
|
113
|
+
end
|
|
93
114
|
|
|
94
115
|
# Sets the prepared_args to the given hash and runs the
|
|
95
116
|
# prepared statement.
|
|
96
|
-
def call(bind_vars=
|
|
117
|
+
def call(bind_vars=OPTS, &block)
|
|
97
118
|
bind(bind_vars).run(&block)
|
|
98
119
|
end
|
|
99
120
|
|
|
@@ -110,21 +131,27 @@ module Sequel
|
|
|
110
131
|
orig_dataset.columns
|
|
111
132
|
end
|
|
112
133
|
|
|
134
|
+
# Disallow use of delayed evaluations in prepared statements.
|
|
135
|
+
def delayed_evaluation_sql_append(sql, delay)
|
|
136
|
+
raise Error, "delayed evaluations cannot be used in prepared statements" if @opts[:no_delayed_evaluations]
|
|
137
|
+
super
|
|
138
|
+
end
|
|
139
|
+
|
|
113
140
|
# Returns the SQL for the prepared statement, depending on
|
|
114
141
|
# the type of the statement and the prepared_modify_values.
|
|
115
142
|
def prepared_sql
|
|
116
|
-
case
|
|
143
|
+
case prepared_type
|
|
117
144
|
when :select, :all, :each
|
|
118
145
|
# Most common scenario, so listed first.
|
|
119
146
|
select_sql
|
|
120
|
-
when :first
|
|
147
|
+
when :first, :single_value
|
|
121
148
|
clone(:limit=>1).select_sql
|
|
122
149
|
when :insert_select
|
|
123
|
-
insert_select_sql(
|
|
124
|
-
when :insert
|
|
125
|
-
insert_sql(
|
|
150
|
+
insert_select_sql(*prepared_modify_values)
|
|
151
|
+
when :insert, :insert_pk
|
|
152
|
+
insert_sql(*prepared_modify_values)
|
|
126
153
|
when :update
|
|
127
|
-
update_sql(
|
|
154
|
+
update_sql(*prepared_modify_values)
|
|
128
155
|
when :delete
|
|
129
156
|
delete_sql
|
|
130
157
|
else
|
|
@@ -136,13 +163,8 @@ module Sequel
|
|
|
136
163
|
# prepared_args is present. If so, they are considered placeholders,
|
|
137
164
|
# and they are substituted using prepared_arg.
|
|
138
165
|
def literal_symbol_append(sql, v)
|
|
139
|
-
if @opts[:bind_vars]
|
|
140
|
-
|
|
141
|
-
if prepared_arg?(s)
|
|
142
|
-
literal_append(sql, prepared_arg(s))
|
|
143
|
-
else
|
|
144
|
-
sql << v.to_s
|
|
145
|
-
end
|
|
166
|
+
if @opts[:bind_vars] && /\A\$(.*)\z/ =~ v
|
|
167
|
+
literal_append(sql, prepared_arg($1.to_sym))
|
|
146
168
|
else
|
|
147
169
|
super
|
|
148
170
|
end
|
|
@@ -157,13 +179,10 @@ module Sequel
|
|
|
157
179
|
|
|
158
180
|
protected
|
|
159
181
|
|
|
160
|
-
# Run the method based on the type of prepared statement
|
|
161
|
-
# :select running #all to get all of the rows, and the other
|
|
162
|
-
# types running the method with the same name as the type.
|
|
182
|
+
# Run the method based on the type of prepared statement.
|
|
163
183
|
def run(&block)
|
|
164
|
-
case
|
|
184
|
+
case prepared_type
|
|
165
185
|
when :select, :all
|
|
166
|
-
# Most common scenario, so listed first
|
|
167
186
|
all(&block)
|
|
168
187
|
when :each
|
|
169
188
|
each(&block)
|
|
@@ -172,20 +191,24 @@ module Sequel
|
|
|
172
191
|
when :first
|
|
173
192
|
first
|
|
174
193
|
when :insert, :update, :delete
|
|
175
|
-
if opts[:returning] && supports_returning?(
|
|
194
|
+
if opts[:returning] && supports_returning?(prepared_type)
|
|
176
195
|
returning_fetch_rows(prepared_sql)
|
|
177
|
-
elsif
|
|
196
|
+
elsif prepared_type == :delete
|
|
178
197
|
delete
|
|
179
198
|
else
|
|
180
|
-
|
|
199
|
+
public_send(prepared_type, *prepared_modify_values)
|
|
181
200
|
end
|
|
201
|
+
when :insert_pk
|
|
202
|
+
fetch_rows(prepared_sql){|r| return r.values.first}
|
|
182
203
|
when Array
|
|
183
|
-
case
|
|
184
|
-
when :map, :to_hash, :to_hash_groups
|
|
185
|
-
|
|
204
|
+
case prepared_type[0]
|
|
205
|
+
when :map, :as_hash, :to_hash, :to_hash_groups
|
|
206
|
+
public_send(*prepared_type, &block)
|
|
186
207
|
end
|
|
208
|
+
when :single_value
|
|
209
|
+
single_value
|
|
187
210
|
else
|
|
188
|
-
|
|
211
|
+
raise Error, "unsupported prepared statement type used: #{prepared_type.inspect}"
|
|
189
212
|
end
|
|
190
213
|
end
|
|
191
214
|
|
|
@@ -196,13 +219,7 @@ module Sequel
|
|
|
196
219
|
@opts[:bind_vars][k]
|
|
197
220
|
end
|
|
198
221
|
|
|
199
|
-
#
|
|
200
|
-
def prepared_arg?(k)
|
|
201
|
-
@opts[:bind_vars].has_key?(k)
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
# The symbol cache should always be skipped, since placeholders
|
|
205
|
-
# are symbols.
|
|
222
|
+
# The symbol cache should always be skipped, since placeholders are symbols.
|
|
206
223
|
def skip_symbol_cache?
|
|
207
224
|
true
|
|
208
225
|
end
|
|
@@ -211,10 +228,12 @@ module Sequel
|
|
|
211
228
|
# support and using the same argument hash so that you can use
|
|
212
229
|
# bind variables/prepared arguments in subselects.
|
|
213
230
|
def subselect_sql_append(sql, ds)
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
231
|
+
subselect_sql_dataset(sql, ds).prepared_sql
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def subselect_sql_dataset(sql, ds)
|
|
235
|
+
super.clone(:prepared_args=>prepared_args, :bind_vars=>@opts[:bind_vars]).
|
|
236
|
+
send(:to_prepared_statement, :select, nil, :extend=>prepared_statement_modules)
|
|
218
237
|
end
|
|
219
238
|
end
|
|
220
239
|
|
|
@@ -242,56 +261,126 @@ module Sequel
|
|
|
242
261
|
prepared_args << k
|
|
243
262
|
prepared_arg_placeholder
|
|
244
263
|
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Prepared statements emulation support for adapters that don't
|
|
267
|
+
# support native prepared statements. Uses a placeholder
|
|
268
|
+
# literalizer to hold the prepared sql with the ability to
|
|
269
|
+
# interpolate arguments to prepare the final SQL string.
|
|
270
|
+
module EmulatePreparedStatementMethods
|
|
271
|
+
include UnnumberedArgumentMapper
|
|
272
|
+
|
|
273
|
+
def run(&block)
|
|
274
|
+
if @opts[:prepared_sql_frags]
|
|
275
|
+
sql = literal(Sequel::SQL::PlaceholderLiteralString.new(@opts[:prepared_sql_frags], @opts[:bind_arguments], false))
|
|
276
|
+
clone(:prepared_sql_frags=>nil, :sql=>sql, :prepared_sql=>sql).run(&block)
|
|
277
|
+
else
|
|
278
|
+
super
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
private
|
|
245
283
|
|
|
246
|
-
#
|
|
247
|
-
|
|
284
|
+
# Turn emulation of prepared statements back on, since ArgumentMapper
|
|
285
|
+
# turns it off.
|
|
286
|
+
def emulate_prepared_statements?
|
|
248
287
|
true
|
|
249
288
|
end
|
|
289
|
+
|
|
290
|
+
def emulated_prepared_statement(type, name, values)
|
|
291
|
+
prepared_sql, frags = Sequel::Dataset::PlaceholderLiteralizer::Recorder.new.send(:prepared_sql_and_frags, self, prepared_args) do |pl, ds|
|
|
292
|
+
ds = ds.clone(:recorder=>pl)
|
|
293
|
+
|
|
294
|
+
case type
|
|
295
|
+
when :first, :single_value
|
|
296
|
+
ds.limit(1)
|
|
297
|
+
when :update, :insert, :insert_select, :delete
|
|
298
|
+
ds.with_sql(:"#{type}_sql", *values)
|
|
299
|
+
when :insert_pk
|
|
300
|
+
ds.with_sql(:insert_sql, *values)
|
|
301
|
+
else
|
|
302
|
+
ds
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
prepared_args.freeze
|
|
307
|
+
clone(:prepared_sql_frags=>frags, :prepared_sql=>prepared_sql, :sql=>prepared_sql)
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
# Associates the argument with name k with the next position in
|
|
311
|
+
# the output array.
|
|
312
|
+
def prepared_arg(k)
|
|
313
|
+
prepared_args << k
|
|
314
|
+
@opts[:recorder].arg
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def subselect_sql_dataset(sql, ds)
|
|
318
|
+
super.clone(:recorder=>@opts[:recorder]).
|
|
319
|
+
with_extend(EmulatePreparedStatementMethods)
|
|
320
|
+
end
|
|
250
321
|
end
|
|
251
322
|
|
|
252
323
|
# Set the bind variables to use for the call. If bind variables have
|
|
253
324
|
# already been set for this dataset, they are updated with the contents
|
|
254
325
|
# of bind_vars.
|
|
255
326
|
#
|
|
256
|
-
# DB[:table].
|
|
327
|
+
# DB[:table].where(id: :$id).bind(id: 1).call(:first)
|
|
257
328
|
# # SELECT * FROM table WHERE id = ? LIMIT 1 -- (1)
|
|
258
329
|
# # => {:id=>1}
|
|
259
|
-
def bind(bind_vars=
|
|
260
|
-
|
|
330
|
+
def bind(bind_vars=OPTS)
|
|
331
|
+
bind_vars = if bv = @opts[:bind_vars]
|
|
332
|
+
bv.merge(bind_vars).freeze
|
|
333
|
+
else
|
|
334
|
+
if bind_vars.frozen?
|
|
335
|
+
bind_vars
|
|
336
|
+
else
|
|
337
|
+
Hash[bind_vars]
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
clone(:bind_vars=>bind_vars)
|
|
261
342
|
end
|
|
262
343
|
|
|
263
|
-
# For the given type (:select, :first, :insert, :insert_select, :update, or :
|
|
344
|
+
# For the given type (:select, :first, :insert, :insert_select, :update, :delete, or :single_value),
|
|
264
345
|
# run the sql with the bind variables specified in the hash. +values+ is a hash passed to
|
|
265
346
|
# insert or update (if one of those types is used), which may contain placeholders.
|
|
266
347
|
#
|
|
267
|
-
# DB[:table].
|
|
348
|
+
# DB[:table].where(id: :$id).call(:first, id: 1)
|
|
268
349
|
# # SELECT * FROM table WHERE id = ? LIMIT 1 -- (1)
|
|
269
350
|
# # => {:id=>1}
|
|
270
|
-
def call(type, bind_variables=
|
|
271
|
-
|
|
351
|
+
def call(type, bind_variables=OPTS, *values, &block)
|
|
352
|
+
to_prepared_statement(type, values, :extend=>bound_variable_modules).call(bind_variables, &block)
|
|
272
353
|
end
|
|
273
354
|
|
|
274
355
|
# Prepare an SQL statement for later execution. Takes a type similar to #call,
|
|
275
|
-
# and the +name+ symbol of the prepared statement.
|
|
276
|
-
# it should always be provided as a symbol for the name of the prepared statement,
|
|
277
|
-
# as some databases require that prepared statements have names.
|
|
356
|
+
# and the +name+ symbol of the prepared statement.
|
|
278
357
|
#
|
|
279
358
|
# This returns a clone of the dataset extended with PreparedStatementMethods,
|
|
280
359
|
# which you can +call+ with the hash of bind variables to use.
|
|
281
360
|
# The prepared statement is also stored in
|
|
282
|
-
# the associated
|
|
361
|
+
# the associated Database, where it can be called by name.
|
|
283
362
|
# The following usage is identical:
|
|
284
363
|
#
|
|
285
|
-
# ps = DB[:table].
|
|
364
|
+
# ps = DB[:table].where(name: :$name).prepare(:first, :select_by_name)
|
|
286
365
|
#
|
|
287
|
-
# ps.call(:
|
|
366
|
+
# ps.call(name: 'Blah')
|
|
288
367
|
# # SELECT * FROM table WHERE name = ? -- ('Blah')
|
|
289
368
|
# # => {:id=>1, :name=>'Blah'}
|
|
290
369
|
#
|
|
291
|
-
# DB.call(:select_by_name, :
|
|
292
|
-
def prepare(type, name
|
|
293
|
-
ps = to_prepared_statement(type, values)
|
|
294
|
-
|
|
370
|
+
# DB.call(:select_by_name, name: 'Blah') # Same thing
|
|
371
|
+
def prepare(type, name, *values)
|
|
372
|
+
ps = to_prepared_statement(type, values, :name=>name, :extend=>prepared_statement_modules, :no_delayed_evaluations=>true)
|
|
373
|
+
|
|
374
|
+
ps = if ps.send(:emulate_prepared_statements?)
|
|
375
|
+
ps = ps.with_extend(EmulatePreparedStatementMethods)
|
|
376
|
+
ps.send(:emulated_prepared_statement, type, name, values)
|
|
377
|
+
else
|
|
378
|
+
sql = ps.prepared_sql
|
|
379
|
+
ps.prepared_args.freeze
|
|
380
|
+
ps.clone(:prepared_sql=>sql, :sql=>sql)
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
db.set_prepared_statement(name, ps)
|
|
295
384
|
ps
|
|
296
385
|
end
|
|
297
386
|
|
|
@@ -299,13 +388,13 @@ module Sequel
|
|
|
299
388
|
|
|
300
389
|
# Return a cloned copy of the current dataset extended with
|
|
301
390
|
# PreparedStatementMethods, setting the type and modify values.
|
|
302
|
-
def to_prepared_statement(type, values=nil)
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
391
|
+
def to_prepared_statement(type, values=nil, opts=OPTS)
|
|
392
|
+
mods = opts[:extend] || []
|
|
393
|
+
mods += [PreparedStatementMethods]
|
|
394
|
+
|
|
395
|
+
bind.
|
|
396
|
+
clone(:prepared_statement_name=>opts[:name], :prepared_type=>type, :prepared_modify_values=>values, :orig_dataset=>self, :no_cache_sql=>true, :prepared_args=>@opts[:prepared_args]||[], :no_delayed_evaluations=>opts[:no_delayed_evaluations]).
|
|
397
|
+
with_extend(*mods)
|
|
309
398
|
end
|
|
310
399
|
|
|
311
400
|
private
|
|
@@ -315,6 +404,20 @@ module Sequel
|
|
|
315
404
|
false
|
|
316
405
|
end
|
|
317
406
|
|
|
407
|
+
def bound_variable_modules
|
|
408
|
+
prepared_statement_modules
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
# Whether prepared statements should be emulated. True by
|
|
412
|
+
# default so that adapters have to opt in.
|
|
413
|
+
def emulate_prepared_statements?
|
|
414
|
+
true
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
def prepared_statement_modules
|
|
418
|
+
[]
|
|
419
|
+
end
|
|
420
|
+
|
|
318
421
|
# The argument placeholder. Most databases used unnumbered
|
|
319
422
|
# arguments with question marks, so that is the default.
|
|
320
423
|
def prepared_arg_placeholder
|