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
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../utils/emulate_offset_with_row_number'
|
|
4
|
+
require_relative '../utils/split_alter_table'
|
|
2
5
|
|
|
3
6
|
module Sequel
|
|
4
|
-
Dataset::NON_SQL_OPTIONS << :disable_insert_output
|
|
5
7
|
module MSSQL
|
|
8
|
+
Sequel::Database.set_shared_adapter_scheme(:mssql, self)
|
|
9
|
+
|
|
10
|
+
def self.mock_adapter_setup(db)
|
|
11
|
+
db.instance_exec do
|
|
12
|
+
@server_version = 11000000
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
6
16
|
module DatabaseMethods
|
|
7
|
-
extend Sequel::Database::ResetIdentifierMangling
|
|
8
|
-
|
|
9
|
-
AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
|
|
10
|
-
SERVER_VERSION_RE = /^(\d+)\.(\d+)\.(\d+)/.freeze
|
|
11
|
-
SERVER_VERSION_SQL = "SELECT CAST(SERVERPROPERTY('ProductVersion') AS varchar)".freeze
|
|
12
|
-
SQL_BEGIN = "BEGIN TRANSACTION".freeze
|
|
13
|
-
SQL_COMMIT = "COMMIT TRANSACTION".freeze
|
|
14
|
-
SQL_ROLLBACK = "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION".freeze
|
|
15
|
-
SQL_ROLLBACK_TO_SAVEPOINT = 'IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION autopoint_%d'.freeze
|
|
16
|
-
SQL_SAVEPOINT = 'SAVE TRANSACTION autopoint_%d'.freeze
|
|
17
|
-
MSSQL_DEFAULT_RE = /\A(?:\(N?('.*')\)|\(\((-?\d+(?:\.\d+)?)\)\))\z/
|
|
18
17
|
FOREIGN_KEY_ACTION_MAP = {0 => :no_action, 1 => :cascade, 2 => :set_null, 3 => :set_default}.freeze
|
|
19
18
|
|
|
20
19
|
include Sequel::Database::SplitAlterTable
|
|
@@ -23,16 +22,7 @@ module Sequel
|
|
|
23
22
|
# strings. True by default for compatibility, can be set to false for a possible
|
|
24
23
|
# performance increase. This sets the default for all datasets created from this
|
|
25
24
|
# Database object.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def mssql_unicode_strings=(v)
|
|
29
|
-
@mssql_unicode_strings = v
|
|
30
|
-
reset_default_dataset
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# The types to check for 0 scale to transform :decimal types
|
|
34
|
-
# to :integer.
|
|
35
|
-
DECIMAL_TYPE_RE = /number|numeric|decimal/io
|
|
25
|
+
attr_accessor :mssql_unicode_strings
|
|
36
26
|
|
|
37
27
|
# Execute the given stored procedure with the given name.
|
|
38
28
|
#
|
|
@@ -50,13 +40,19 @@ module Sequel
|
|
|
50
40
|
# :numrows :: The number of rows affected by the stored procedure
|
|
51
41
|
# output params :: Values for any output paramters, using the name given for the output parameter
|
|
52
42
|
#
|
|
43
|
+
# Because Sequel datasets only support a single result set per query, and retrieving
|
|
44
|
+
# the result code and number of rows requires a query, this does not support
|
|
45
|
+
# stored procedures which also return result sets. To handle such stored procedures,
|
|
46
|
+
# you should drop down to the connection/driver level by using Sequel::Database#synchronize
|
|
47
|
+
# to get access to the underlying connection object.
|
|
48
|
+
#
|
|
53
49
|
# Examples:
|
|
54
50
|
#
|
|
55
|
-
# DB.call_mssql_sproc(:SequelTest, {:
|
|
56
|
-
# DB.call_mssql_sproc(:SequelTest, {:
|
|
51
|
+
# DB.call_mssql_sproc(:SequelTest, {args: ['input arg', :output]})
|
|
52
|
+
# DB.call_mssql_sproc(:SequelTest, {args: ['input arg', [:output, 'int', 'varname']]})
|
|
57
53
|
#
|
|
58
54
|
# named params:
|
|
59
|
-
# DB.call_mssql_sproc(:SequelTest, :
|
|
55
|
+
# DB.call_mssql_sproc(:SequelTest, args: {
|
|
60
56
|
# 'input_arg1_name' => 'input arg1 value',
|
|
61
57
|
# 'input_arg2_name' => 'input arg2 value',
|
|
62
58
|
# 'output_arg_name' => [:output, 'int', 'varname']
|
|
@@ -75,7 +71,7 @@ module Sequel
|
|
|
75
71
|
method = :each_with_index
|
|
76
72
|
end
|
|
77
73
|
|
|
78
|
-
args.
|
|
74
|
+
args.public_send(method) do |v, i|
|
|
79
75
|
if named_args
|
|
80
76
|
k = v
|
|
81
77
|
v, type, select = i
|
|
@@ -113,7 +109,6 @@ module Sequel
|
|
|
113
109
|
ds.first
|
|
114
110
|
end
|
|
115
111
|
|
|
116
|
-
# Microsoft SQL Server uses the :mssql type.
|
|
117
112
|
def database_type
|
|
118
113
|
:mssql
|
|
119
114
|
end
|
|
@@ -131,20 +126,22 @@ module Sequel
|
|
|
131
126
|
schema, table = schema_and_table(table)
|
|
132
127
|
current_schema = m.call(get(Sequel.function('schema_name')))
|
|
133
128
|
fk_action_map = FOREIGN_KEY_ACTION_MAP
|
|
129
|
+
fk = Sequel[:fk]
|
|
130
|
+
fkc = Sequel[:fkc]
|
|
134
131
|
ds = metadata_dataset.from(Sequel.lit('[sys].[foreign_keys]').as(:fk)).
|
|
135
132
|
join(Sequel.lit('[sys].[foreign_key_columns]').as(:fkc), :constraint_object_id => :object_id).
|
|
136
|
-
join(Sequel.lit('[sys].[all_columns]').as(:pc), :object_id => :
|
|
137
|
-
join(Sequel.lit('[sys].[all_columns]').as(:rc), :object_id => :
|
|
138
|
-
where{{object_schema_name(:
|
|
139
|
-
where{{object_name(:
|
|
140
|
-
select{[:
|
|
141
|
-
:
|
|
142
|
-
:
|
|
143
|
-
:
|
|
144
|
-
:
|
|
145
|
-
object_schema_name(:
|
|
146
|
-
object_name(:
|
|
147
|
-
order(:
|
|
133
|
+
join(Sequel.lit('[sys].[all_columns]').as(:pc), :object_id => fkc[:parent_object_id], :column_id => fkc[:parent_column_id]).
|
|
134
|
+
join(Sequel.lit('[sys].[all_columns]').as(:rc), :object_id => fkc[:referenced_object_id], :column_id => fkc[:referenced_column_id]).
|
|
135
|
+
where{{object_schema_name(fk[:parent_object_id]) => im.call(schema || current_schema)}}.
|
|
136
|
+
where{{object_name(fk[:parent_object_id]) => im.call(table)}}.
|
|
137
|
+
select{[fk[:name],
|
|
138
|
+
fk[:delete_referential_action],
|
|
139
|
+
fk[:update_referential_action],
|
|
140
|
+
pc[:name].as(:column),
|
|
141
|
+
rc[:name].as(:referenced_column),
|
|
142
|
+
object_schema_name(fk[:referenced_object_id]).as(:schema),
|
|
143
|
+
object_name(fk[:referenced_object_id]).as(:table)]}.
|
|
144
|
+
order(fk[:name], fkc[:constraint_column_id])
|
|
148
145
|
h = {}
|
|
149
146
|
ds.each do |row|
|
|
150
147
|
if r = h[row[:name]]
|
|
@@ -164,22 +161,29 @@ module Sequel
|
|
|
164
161
|
h.values
|
|
165
162
|
end
|
|
166
163
|
|
|
164
|
+
def freeze
|
|
165
|
+
server_version
|
|
166
|
+
super
|
|
167
|
+
end
|
|
168
|
+
|
|
167
169
|
# Use the system tables to get index information
|
|
168
170
|
def indexes(table, opts=OPTS)
|
|
169
171
|
m = output_identifier_meth
|
|
170
172
|
im = input_identifier_meth
|
|
171
173
|
indexes = {}
|
|
174
|
+
table = table.value if table.is_a?(Sequel::SQL::Identifier)
|
|
175
|
+
i = Sequel[:i]
|
|
172
176
|
ds = metadata_dataset.from(Sequel.lit('[sys].[tables]').as(:t)).
|
|
173
177
|
join(Sequel.lit('[sys].[indexes]').as(:i), :object_id=>:object_id).
|
|
174
178
|
join(Sequel.lit('[sys].[index_columns]').as(:ic), :object_id=>:object_id, :index_id=>:index_id).
|
|
175
179
|
join(Sequel.lit('[sys].[columns]').as(:c), :object_id=>:object_id, :column_id=>:column_id).
|
|
176
|
-
select(:
|
|
177
|
-
where{{
|
|
178
|
-
where(:
|
|
179
|
-
order(:
|
|
180
|
+
select(i[:name], i[:is_unique], Sequel[:c][:name].as(:column)).
|
|
181
|
+
where{{t[:name]=>im.call(table)}}.
|
|
182
|
+
where(i[:is_primary_key]=>0, i[:is_disabled]=>0).
|
|
183
|
+
order(i[:name], Sequel[:ic][:index_column_id])
|
|
180
184
|
|
|
181
185
|
if supports_partial_indexes?
|
|
182
|
-
ds = ds.where(:
|
|
186
|
+
ds = ds.where(i[:has_filter]=>0)
|
|
183
187
|
end
|
|
184
188
|
|
|
185
189
|
ds.each do |r|
|
|
@@ -200,7 +204,7 @@ module Sequel
|
|
|
200
204
|
(conn.server_version rescue nil) if conn.respond_to?(:server_version)
|
|
201
205
|
end
|
|
202
206
|
unless @server_version
|
|
203
|
-
m =
|
|
207
|
+
m = /^(\d+)\.(\d+)\.(\d+)/.match(fetch("SELECT CAST(SERVERPROPERTY('ProductVersion') AS varchar)").single_value.to_s)
|
|
204
208
|
@server_version = (m[1].to_i * 1000000) + (m[2].to_i * 10000) + m[3].to_i
|
|
205
209
|
end
|
|
206
210
|
@server_version
|
|
@@ -211,7 +215,7 @@ module Sequel
|
|
|
211
215
|
dataset.send(:is_2008_or_later?)
|
|
212
216
|
end
|
|
213
217
|
|
|
214
|
-
# MSSQL supports savepoints, though it doesn't support
|
|
218
|
+
# MSSQL supports savepoints, though it doesn't support releasing them
|
|
215
219
|
def supports_savepoints?
|
|
216
220
|
true
|
|
217
221
|
end
|
|
@@ -250,10 +254,9 @@ module Sequel
|
|
|
250
254
|
|
|
251
255
|
# MSSQL uses the IDENTITY(1,1) column for autoincrementing columns.
|
|
252
256
|
def auto_increment_sql
|
|
253
|
-
|
|
257
|
+
'IDENTITY(1,1)'
|
|
254
258
|
end
|
|
255
259
|
|
|
256
|
-
# MSSQL specific syntax for altering tables.
|
|
257
260
|
def alter_table_sql(table, op)
|
|
258
261
|
case op[:op]
|
|
259
262
|
when :add_column
|
|
@@ -263,7 +266,7 @@ module Sequel
|
|
|
263
266
|
add_drop_default_constraint_sql(sqls, table, op[:name])
|
|
264
267
|
sqls << super
|
|
265
268
|
when :rename_column
|
|
266
|
-
"sp_rename #{literal("#{quote_schema_table(table)}.#{quote_identifier(op[:name])}")}, #{literal(op[:new_name]
|
|
269
|
+
"sp_rename #{literal("#{quote_schema_table(table)}.#{quote_identifier(op[:name])}")}, #{literal(metadata_dataset.with_quote_identifiers(false).quote_identifier(op[:new_name]))}, 'COLUMN'"
|
|
267
270
|
when :set_column_type
|
|
268
271
|
sqls = []
|
|
269
272
|
if sch = schema(table)
|
|
@@ -276,49 +279,53 @@ module Sequel
|
|
|
276
279
|
end
|
|
277
280
|
end
|
|
278
281
|
sqls << "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{column_definition_sql(op)}"
|
|
279
|
-
sqls << alter_table_sql(table, op.merge(:op=>:set_column_default, :default=>default)) if default
|
|
282
|
+
sqls << alter_table_sql(table, op.merge(:op=>:set_column_default, :default=>default, :skip_drop_default=>true)) if default
|
|
280
283
|
sqls
|
|
281
284
|
when :set_column_null
|
|
282
285
|
sch = schema(table).find{|k,v| k.to_s == op[:name].to_s}.last
|
|
283
286
|
type = sch[:db_type]
|
|
284
|
-
if [:string, :decimal].include?(sch[:type])
|
|
287
|
+
if [:string, :decimal].include?(sch[:type]) && !["text", "ntext"].include?(type) && (size = (sch[:max_chars] || sch[:column_size]))
|
|
288
|
+
size = "MAX" if size == -1
|
|
285
289
|
type += "(#{size}#{", #{sch[:scale]}" if sch[:scale] && sch[:scale].to_i > 0})"
|
|
286
290
|
end
|
|
287
291
|
"ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} #{type_literal(:type=>type)} #{'NOT ' unless op[:null]}NULL"
|
|
288
292
|
when :set_column_default
|
|
289
|
-
|
|
293
|
+
sqls = []
|
|
294
|
+
add_drop_default_constraint_sql(sqls, table, op[:name]) unless op[:skip_drop_default]
|
|
295
|
+
sqls << "ALTER TABLE #{quote_schema_table(table)} ADD CONSTRAINT #{quote_identifier("sequel_#{table}_#{op[:name]}_def")} DEFAULT #{literal(op[:default])} FOR #{quote_identifier(op[:name])}"
|
|
290
296
|
else
|
|
291
297
|
super(table, op)
|
|
292
298
|
end
|
|
293
299
|
end
|
|
294
300
|
|
|
295
|
-
# SQL to start a new savepoint
|
|
296
301
|
def begin_savepoint_sql(depth)
|
|
297
|
-
|
|
302
|
+
"SAVE TRANSACTION autopoint_#{depth}"
|
|
298
303
|
end
|
|
299
304
|
|
|
300
|
-
# SQL to BEGIN a transaction.
|
|
301
305
|
def begin_transaction_sql
|
|
302
|
-
|
|
306
|
+
"BEGIN TRANSACTION"
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# MSSQL does not allow adding primary key constraints to NULLable columns.
|
|
310
|
+
def can_add_primary_key_constraint_on_nullable_columns?
|
|
311
|
+
false
|
|
303
312
|
end
|
|
304
313
|
|
|
305
314
|
# Handle MSSQL specific default format.
|
|
306
315
|
def column_schema_normalize_default(default, type)
|
|
307
|
-
if m =
|
|
316
|
+
if m = /\A(?:\(N?('.*')\)|\(\((-?\d+(?:\.\d+)?)\)\))\z/.match(default)
|
|
308
317
|
default = m[1] || m[2]
|
|
309
318
|
end
|
|
310
319
|
super(default, type)
|
|
311
320
|
end
|
|
312
321
|
|
|
313
|
-
# Commit the active transaction on the connection, does not
|
|
314
|
-
# savepoints.
|
|
322
|
+
# Commit the active transaction on the connection, does not release savepoints.
|
|
315
323
|
def commit_transaction(conn, opts=OPTS)
|
|
316
324
|
log_connection_execute(conn, commit_transaction_sql) unless savepoint_level(conn) > 1
|
|
317
325
|
end
|
|
318
326
|
|
|
319
|
-
# SQL to COMMIT a transaction.
|
|
320
327
|
def commit_transaction_sql
|
|
321
|
-
|
|
328
|
+
"COMMIT TRANSACTION"
|
|
322
329
|
end
|
|
323
330
|
|
|
324
331
|
# MSSQL uses the name of the table to decide the difference between
|
|
@@ -338,11 +345,12 @@ module Sequel
|
|
|
338
345
|
end
|
|
339
346
|
|
|
340
347
|
DATABASE_ERROR_REGEXPS = {
|
|
341
|
-
/Violation of UNIQUE KEY constraint|Violation of PRIMARY KEY constraint.+Cannot insert duplicate key/ => UniqueConstraintViolation,
|
|
348
|
+
/Violation of UNIQUE KEY constraint|(Violation of PRIMARY KEY constraint.+)?Cannot insert duplicate key/ => UniqueConstraintViolation,
|
|
342
349
|
/conflicted with the (FOREIGN KEY.*|REFERENCE) constraint/ => ForeignKeyConstraintViolation,
|
|
343
350
|
/conflicted with the CHECK constraint/ => CheckConstraintViolation,
|
|
344
351
|
/column does not allow nulls/ => NotNullConstraintViolation,
|
|
345
352
|
/was deadlocked on lock resources with another process and has been chosen as the deadlock victim/ => SerializationFailure,
|
|
353
|
+
/Lock request time out period exceeded\./ => DatabaseLockTimeout,
|
|
346
354
|
}.freeze
|
|
347
355
|
def database_error_regexps
|
|
348
356
|
DATABASE_ERROR_REGEXPS
|
|
@@ -354,18 +362,16 @@ module Sequel
|
|
|
354
362
|
def default_constraint_name(table, column_name)
|
|
355
363
|
if server_version >= 9000000
|
|
356
364
|
table_name = schema_and_table(table).compact.join('.')
|
|
357
|
-
self[:
|
|
365
|
+
self[Sequel[:sys][:default_constraints]].
|
|
358
366
|
where{{:parent_object_id => Sequel::SQL::Function.new(:object_id, table_name), col_name(:parent_object_id, :parent_column_id) => column_name.to_s}}.
|
|
359
367
|
get(:name)
|
|
360
368
|
end
|
|
361
369
|
end
|
|
362
370
|
|
|
363
|
-
# The SQL to drop an index for the table.
|
|
364
371
|
def drop_index_sql(table, op)
|
|
365
372
|
"DROP INDEX #{quote_identifier(op[:name] || default_index_name(table, op[:columns]))} ON #{quote_schema_table(table)}"
|
|
366
373
|
end
|
|
367
374
|
|
|
368
|
-
# support for clustered index type
|
|
369
375
|
def index_definition_sql(table_name, index)
|
|
370
376
|
index_name = index[:name] || default_index_name(table_name, index[:columns])
|
|
371
377
|
raise Error, "Partial indexes are not supported for this database" if index[:where] && !supports_partial_indexes?
|
|
@@ -379,17 +385,15 @@ module Sequel
|
|
|
379
385
|
# Backbone of the tables and views support.
|
|
380
386
|
def information_schema_tables(type, opts)
|
|
381
387
|
m = output_identifier_meth
|
|
382
|
-
metadata_dataset.from(:
|
|
388
|
+
metadata_dataset.from(Sequel[:information_schema][:tables].as(:t)).
|
|
383
389
|
select(:table_name).
|
|
384
|
-
|
|
390
|
+
where(:table_type=>type, :table_schema=>(opts[:schema]||'dbo').to_s).
|
|
385
391
|
map{|x| m.call(x[:table_name])}
|
|
386
392
|
end
|
|
387
393
|
|
|
388
394
|
# Always quote identifiers in the metadata_dataset, so schema parsing works.
|
|
389
|
-
def
|
|
390
|
-
|
|
391
|
-
ds.quote_identifiers = true
|
|
392
|
-
ds
|
|
395
|
+
def _metadata_dataset
|
|
396
|
+
super.with_quote_identifiers(true)
|
|
393
397
|
end
|
|
394
398
|
|
|
395
399
|
# Use sp_rename to rename the table
|
|
@@ -397,17 +401,14 @@ module Sequel
|
|
|
397
401
|
"sp_rename #{literal(quote_schema_table(name))}, #{quote_identifier(schema_and_table(new_name).pop)}"
|
|
398
402
|
end
|
|
399
403
|
|
|
400
|
-
# SQL to rollback to a savepoint
|
|
401
404
|
def rollback_savepoint_sql(depth)
|
|
402
|
-
|
|
405
|
+
"IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION autopoint_#{depth}"
|
|
403
406
|
end
|
|
404
407
|
|
|
405
|
-
# SQL to ROLLBACK a transaction.
|
|
406
408
|
def rollback_transaction_sql
|
|
407
|
-
|
|
409
|
+
"IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"
|
|
408
410
|
end
|
|
409
411
|
|
|
410
|
-
# The closest MSSQL equivalent of a boolean datatype is the bit type.
|
|
411
412
|
def schema_column_type(db_type)
|
|
412
413
|
case db_type
|
|
413
414
|
when /\A(?:bit)\z/io
|
|
@@ -428,31 +429,30 @@ module Sequel
|
|
|
428
429
|
m = output_identifier_meth(opts[:dataset])
|
|
429
430
|
m2 = input_identifier_meth(opts[:dataset])
|
|
430
431
|
tn = m2.call(table_name.to_s)
|
|
431
|
-
table_id = get(Sequel.function(:object_id, tn))
|
|
432
432
|
info_sch_sch = opts[:information_schema_schema]
|
|
433
|
-
inf_sch_qual = lambda{|s| info_sch_sch ? Sequel.qualify(info_sch_sch, s) : Sequel
|
|
434
|
-
|
|
433
|
+
inf_sch_qual = lambda{|s| info_sch_sch ? Sequel.qualify(info_sch_sch, s) : Sequel[s]}
|
|
434
|
+
table_id = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:objects])).where(:name => tn).select_map(:object_id).first
|
|
435
435
|
|
|
436
|
-
identity_cols = metadata_dataset.from(
|
|
436
|
+
identity_cols = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:columns])).
|
|
437
437
|
where(:object_id=>table_id, :is_identity=>true).
|
|
438
438
|
select_map(:name)
|
|
439
439
|
|
|
440
|
-
pk_index_id = metadata_dataset.from(
|
|
440
|
+
pk_index_id = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:sysindexes])).
|
|
441
441
|
where(:id=>table_id, :indid=>1..254){{(status & 2048)=>2048}}.
|
|
442
442
|
get(:indid)
|
|
443
|
-
pk_cols = metadata_dataset.from(
|
|
444
|
-
join(
|
|
445
|
-
where
|
|
446
|
-
select_order_map
|
|
443
|
+
pk_cols = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:sysindexkeys]).as(:sik)).
|
|
444
|
+
join(inf_sch_qual.call(Sequel[:sys][:syscolumns]).as(:sc), :id=>:id, :colid=>:colid).
|
|
445
|
+
where{{sik[:id]=>table_id, sik[:indid]=>pk_index_id}}.
|
|
446
|
+
select_order_map{sc[:name]}
|
|
447
447
|
|
|
448
|
-
ds = metadata_dataset.from(inf_sch_qual.call(:
|
|
449
|
-
join(inf_sch_qual.call(:
|
|
448
|
+
ds = metadata_dataset.from(inf_sch_qual.call(Sequel[:information_schema][:tables]).as(:t)).
|
|
449
|
+
join(inf_sch_qual.call(Sequel[:information_schema][:columns]).as(:c), :table_catalog=>:table_catalog,
|
|
450
450
|
:table_schema => :table_schema, :table_name => :table_name).
|
|
451
|
-
select(:
|
|
452
|
-
|
|
451
|
+
select{[column_name.as(:column), data_type.as(:db_type), character_maximum_length.as(:max_chars), column_default.as(:default), is_nullable.as(:allow_null), numeric_precision.as(:column_size), numeric_scale.as(:scale)]}.
|
|
452
|
+
where{{c[:table_name]=>tn}}
|
|
453
453
|
|
|
454
454
|
if schema = opts[:schema]
|
|
455
|
-
ds.
|
|
455
|
+
ds = ds.where{{c[:table_schema]=>schema}}
|
|
456
456
|
end
|
|
457
457
|
|
|
458
458
|
ds.map do |row|
|
|
@@ -461,7 +461,7 @@ module Sequel
|
|
|
461
461
|
end
|
|
462
462
|
row[:allow_null] = row[:allow_null] == 'YES' ? true : false
|
|
463
463
|
row[:default] = nil if blank_object?(row[:default])
|
|
464
|
-
row[:type] = if row[:db_type] =~
|
|
464
|
+
row[:type] = if row[:db_type] =~ /number|numeric|decimal/i && row[:scale] == 0
|
|
465
465
|
:integer
|
|
466
466
|
else
|
|
467
467
|
schema_column_type(row[:db_type])
|
|
@@ -482,12 +482,6 @@ module Sequel
|
|
|
482
482
|
:datetime
|
|
483
483
|
end
|
|
484
484
|
|
|
485
|
-
# MSSQL has both datetime and timestamp classes, most people are going
|
|
486
|
-
# to want datetime
|
|
487
|
-
def type_literal_generic_time(column)
|
|
488
|
-
column[:only_time] ? :time : :datetime
|
|
489
|
-
end
|
|
490
|
-
|
|
491
485
|
# MSSQL doesn't have a true boolean class, so it uses bit
|
|
492
486
|
def type_literal_generic_trueclass(column)
|
|
493
487
|
:bit
|
|
@@ -506,93 +500,53 @@ module Sequel
|
|
|
506
500
|
|
|
507
501
|
module DatasetMethods
|
|
508
502
|
include(Module.new do
|
|
509
|
-
Dataset.def_sql_method(self, :select, %w'with select distinct limit columns into from lock join where group having order
|
|
503
|
+
Dataset.def_sql_method(self, :select, %w'with select distinct limit columns into from lock join where group having compounds order')
|
|
510
504
|
end)
|
|
511
505
|
include EmulateOffsetWithRowNumber
|
|
512
506
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
CONSTANT_MAP = {:CURRENT_DATE=>'CAST(CURRENT_TIMESTAMP AS DATE)'.freeze, :CURRENT_TIME=>'CAST(CURRENT_TIMESTAMP AS TIME)'.freeze}
|
|
520
|
-
EXTRACT_MAP = {:year=>"yy", :month=>"m", :day=>"d", :hour=>"hh", :minute=>"n", :second=>"s"}
|
|
521
|
-
BRACKET_CLOSE = Dataset::BRACKET_CLOSE
|
|
522
|
-
BRACKET_OPEN = Dataset::BRACKET_OPEN
|
|
523
|
-
COMMA = Dataset::COMMA
|
|
524
|
-
PAREN_CLOSE = Dataset::PAREN_CLOSE
|
|
525
|
-
PAREN_SPACE_OPEN = Dataset::PAREN_SPACE_OPEN
|
|
526
|
-
SPACE = Dataset::SPACE
|
|
527
|
-
FROM = Dataset::FROM
|
|
528
|
-
APOS = Dataset::APOS
|
|
529
|
-
APOS_RE = Dataset::APOS_RE
|
|
530
|
-
DOUBLE_APOS = Dataset::DOUBLE_APOS
|
|
531
|
-
INTO = Dataset::INTO
|
|
532
|
-
DOUBLE_BRACKET_CLOSE = ']]'.freeze
|
|
533
|
-
DATEPART_SECOND_OPEN = "CAST((datepart(".freeze
|
|
534
|
-
DATEPART_SECOND_MIDDLE = ') + datepart(ns, '.freeze
|
|
535
|
-
DATEPART_SECOND_CLOSE = ")/1000000000.0) AS double precision)".freeze
|
|
536
|
-
DATEPART_OPEN = "datepart(".freeze
|
|
537
|
-
OUTPUT_INSERTED = " OUTPUT INSERTED.*".freeze
|
|
538
|
-
HEX_START = '0x'.freeze
|
|
539
|
-
UNICODE_STRING_START = "N'".freeze
|
|
540
|
-
BACKSLASH_CRLF_RE = /\\((?:\r\n)|\n)/.freeze
|
|
541
|
-
BACKSLASH_CRLF_REPLACE = '\\\\\\\\\\1\\1'.freeze
|
|
542
|
-
TOP_PAREN = " TOP (".freeze
|
|
543
|
-
TOP = " TOP ".freeze
|
|
544
|
-
OUTPUT = " OUTPUT ".freeze
|
|
545
|
-
HSTAR = "H*".freeze
|
|
546
|
-
CASE_SENSITIVE_COLLATION = 'Latin1_General_CS_AS'.freeze
|
|
547
|
-
CASE_INSENSITIVE_COLLATION = 'Latin1_General_CI_AS'.freeze
|
|
548
|
-
DEFAULT_TIMESTAMP_FORMAT = "'%Y-%m-%dT%H:%M:%S%N%z'".freeze
|
|
549
|
-
FORMAT_DATE = "'%Y%m%d'".freeze
|
|
550
|
-
CROSS_APPLY = 'CROSS APPLY'.freeze
|
|
551
|
-
OUTER_APPLY = 'OUTER APPLY'.freeze
|
|
552
|
-
OFFSET = " OFFSET ".freeze
|
|
553
|
-
ROWS = " ROWS".freeze
|
|
554
|
-
ROWS_ONLY = " ROWS ONLY".freeze
|
|
555
|
-
FETCH_NEXT = " FETCH NEXT ".freeze
|
|
556
|
-
|
|
557
|
-
Dataset.def_mutation_method(:disable_insert_output, :output, :module=>self)
|
|
558
|
-
Dataset.def_sql_method(self, :delete, %w'with delete from output from2 where')
|
|
507
|
+
CONSTANT_MAP = {:CURRENT_DATE=>'CAST(CURRENT_TIMESTAMP AS DATE)'.freeze, :CURRENT_TIME=>'CAST(CURRENT_TIMESTAMP AS TIME)'.freeze}.freeze
|
|
508
|
+
EXTRACT_MAP = {:year=>"yy", :month=>"m", :day=>"d", :hour=>"hh", :minute=>"n", :second=>"s"}.freeze
|
|
509
|
+
EXTRACT_MAP.each_value(&:freeze)
|
|
510
|
+
LIMIT_ALL = Object.new.freeze
|
|
511
|
+
|
|
512
|
+
Dataset.def_sql_method(self, :delete, %w'with delete limit from output from2 where')
|
|
559
513
|
Dataset.def_sql_method(self, :insert, %w'with insert into columns output values')
|
|
560
514
|
Dataset.def_sql_method(self, :update, [['if is_2005_or_later?', %w'with update limit table set output from where'], ['else', %w'update table set output from where']])
|
|
561
515
|
|
|
562
|
-
|
|
563
|
-
# Allow overriding of the mssql_unicode_strings option at the dataset level.
|
|
564
|
-
attr_writer :mssql_unicode_strings
|
|
565
|
-
|
|
566
516
|
# Use the database's mssql_unicode_strings setting if the dataset hasn't overridden it.
|
|
567
517
|
def mssql_unicode_strings
|
|
568
|
-
|
|
518
|
+
opts.has_key?(:mssql_unicode_strings) ? opts[:mssql_unicode_strings] : db.mssql_unicode_strings
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
# Return a cloned dataset with the mssql_unicode_strings option set.
|
|
522
|
+
def with_mssql_unicode_strings(v)
|
|
523
|
+
clone(:mssql_unicode_strings=>v)
|
|
569
524
|
end
|
|
570
525
|
|
|
571
|
-
# MSSQL uses + for string concatenation, and LIKE is case insensitive by default.
|
|
572
526
|
def complex_expression_sql_append(sql, op, args)
|
|
573
527
|
case op
|
|
574
528
|
when :'||'
|
|
575
529
|
super(sql, :+, args)
|
|
576
530
|
when :LIKE, :"NOT LIKE"
|
|
577
|
-
super(sql, op, args.map{|a| Sequel.lit(["(", " COLLATE
|
|
531
|
+
super(sql, op, args.map{|a| Sequel.lit(["(", " COLLATE Latin1_General_CS_AS)"], a)})
|
|
578
532
|
when :ILIKE, :"NOT ILIKE"
|
|
579
|
-
super(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), args.map{|a| Sequel.lit(["(", " COLLATE
|
|
533
|
+
super(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), args.map{|a| Sequel.lit(["(", " COLLATE Latin1_General_CI_AS)"], a)})
|
|
580
534
|
when :<<, :>>
|
|
581
535
|
complex_expression_emulate_append(sql, op, args)
|
|
582
536
|
when :extract
|
|
583
|
-
part = args
|
|
537
|
+
part = args[0]
|
|
584
538
|
raise(Sequel::Error, "unsupported extract argument: #{part.inspect}") unless format = EXTRACT_MAP[part]
|
|
585
539
|
if part == :second
|
|
586
|
-
expr = args
|
|
587
|
-
sql <<
|
|
540
|
+
expr = args[1]
|
|
541
|
+
sql << "CAST((datepart(" << format.to_s << ', '
|
|
588
542
|
literal_append(sql, expr)
|
|
589
|
-
sql <<
|
|
543
|
+
sql << ') + datepart(ns, '
|
|
590
544
|
literal_append(sql, expr)
|
|
591
|
-
sql <<
|
|
545
|
+
sql << ")/1000000000.0) AS double precision)"
|
|
592
546
|
else
|
|
593
|
-
sql <<
|
|
594
|
-
literal_append(sql, args
|
|
595
|
-
sql <<
|
|
547
|
+
sql << "datepart(" << format.to_s << ', '
|
|
548
|
+
literal_append(sql, args[1])
|
|
549
|
+
sql << ')'
|
|
596
550
|
end
|
|
597
551
|
else
|
|
598
552
|
super
|
|
@@ -626,13 +580,15 @@ module Sequel
|
|
|
626
580
|
# MSSQL uses the CONTAINS keyword for full text search
|
|
627
581
|
def full_text_search(cols, terms, opts = OPTS)
|
|
628
582
|
terms = "\"#{terms.join('" OR "')}\"" if terms.is_a?(Array)
|
|
629
|
-
|
|
583
|
+
where(Sequel.lit("CONTAINS (?, ?)", cols, terms))
|
|
630
584
|
end
|
|
631
585
|
|
|
632
|
-
#
|
|
586
|
+
# Insert a record, returning the record inserted, using OUTPUT. Always returns nil without
|
|
587
|
+
# running an INSERT statement if disable_insert_output is used. If the query runs
|
|
588
|
+
# but returns no values, returns false.
|
|
633
589
|
def insert_select(*values)
|
|
634
590
|
return unless supports_insert_select?
|
|
635
|
-
with_sql_first(insert_select_sql(*values))
|
|
591
|
+
with_sql_first(insert_select_sql(*values)) || false
|
|
636
592
|
end
|
|
637
593
|
|
|
638
594
|
# Add OUTPUT clause unless there is already an existing output clause, then return
|
|
@@ -667,8 +623,8 @@ module Sequel
|
|
|
667
623
|
#
|
|
668
624
|
# Examples:
|
|
669
625
|
#
|
|
670
|
-
# dataset.output(:output_table, [:
|
|
671
|
-
# dataset.output(:output_table, :
|
|
626
|
+
# dataset.output(:output_table, [Sequel[:deleted][:id], Sequel[:deleted][:name]])
|
|
627
|
+
# dataset.output(:output_table, id: Sequel[:inserted][:id], name: Sequel[:inserted][:name])
|
|
672
628
|
def output(into, values)
|
|
673
629
|
raise(Error, "SQL Server versions 2000 and earlier do not support the OUTPUT clause") unless supports_output_clause?
|
|
674
630
|
output = {}
|
|
@@ -684,7 +640,7 @@ module Sequel
|
|
|
684
640
|
|
|
685
641
|
# MSSQL uses [] to quote identifiers.
|
|
686
642
|
def quoted_identifier_append(sql, name)
|
|
687
|
-
sql <<
|
|
643
|
+
sql << '[' << name.to_s.gsub(/\]/, ']]') << ']'
|
|
688
644
|
end
|
|
689
645
|
|
|
690
646
|
# Emulate RETURNING using the output clause. This only handles values that are simple column references.
|
|
@@ -703,11 +659,11 @@ module Sequel
|
|
|
703
659
|
# case by default, and that also adds a default order, so it's better to just
|
|
704
660
|
# avoid the subquery.
|
|
705
661
|
def select_sql
|
|
706
|
-
if @opts[:offset]
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
super
|
|
662
|
+
if @opts[:offset]
|
|
663
|
+
raise(Error, "Using with_ties is not supported with an offset on Microsoft SQL Server") if @opts[:limit_with_ties]
|
|
664
|
+
return order(1).select_sql if is_2012_or_later? && !@opts[:order]
|
|
710
665
|
end
|
|
666
|
+
super
|
|
711
667
|
end
|
|
712
668
|
|
|
713
669
|
# The version of the database server.
|
|
@@ -729,7 +685,7 @@ module Sequel
|
|
|
729
685
|
is_2005_or_later?
|
|
730
686
|
end
|
|
731
687
|
|
|
732
|
-
# MSSQL
|
|
688
|
+
# MSSQL 2008+ supports GROUPING SETS
|
|
733
689
|
def supports_grouping_sets?
|
|
734
690
|
is_2008_or_later?
|
|
735
691
|
end
|
|
@@ -764,6 +720,11 @@ module Sequel
|
|
|
764
720
|
false
|
|
765
721
|
end
|
|
766
722
|
|
|
723
|
+
# MSSQL supports NOWAIT.
|
|
724
|
+
def supports_nowait?
|
|
725
|
+
true
|
|
726
|
+
end
|
|
727
|
+
|
|
767
728
|
# MSSQL 2012+ supports offsets in correlated subqueries.
|
|
768
729
|
def supports_offsets_in_correlated_subqueries?
|
|
769
730
|
is_2012_or_later?
|
|
@@ -779,6 +740,11 @@ module Sequel
|
|
|
779
740
|
supports_insert_select?
|
|
780
741
|
end
|
|
781
742
|
|
|
743
|
+
# MSSQL uses READPAST to skip locked rows.
|
|
744
|
+
def supports_skip_locked?
|
|
745
|
+
true
|
|
746
|
+
end
|
|
747
|
+
|
|
782
748
|
# MSSQL 2005+ supports window functions
|
|
783
749
|
def supports_window_functions?
|
|
784
750
|
true
|
|
@@ -789,6 +755,12 @@ module Sequel
|
|
|
789
755
|
false
|
|
790
756
|
end
|
|
791
757
|
|
|
758
|
+
# Use WITH TIES when limiting the result set to also include additional
|
|
759
|
+
# rows matching the last row.
|
|
760
|
+
def with_ties
|
|
761
|
+
clone(:limit_with_ties=>true)
|
|
762
|
+
end
|
|
763
|
+
|
|
792
764
|
protected
|
|
793
765
|
|
|
794
766
|
# If returned primary keys are requested, use OUTPUT unless already set on the
|
|
@@ -800,20 +772,45 @@ module Sequel
|
|
|
800
772
|
output(nil, [SQL::QualifiedIdentifier.new(:inserted, first_primary_key)])._import(columns, values, opts)
|
|
801
773
|
elsif @opts[:output]
|
|
802
774
|
statements = multi_insert_sql(columns, values)
|
|
775
|
+
ds = naked
|
|
803
776
|
@db.transaction(opts.merge(:server=>@opts[:server])) do
|
|
804
|
-
statements.map{|st| with_sql(st)}
|
|
777
|
+
statements.map{|st| ds.with_sql(st)}
|
|
805
778
|
end.first.map{|v| v.length == 1 ? v.values.first : v}
|
|
806
779
|
else
|
|
807
780
|
super
|
|
808
781
|
end
|
|
809
782
|
end
|
|
810
783
|
|
|
811
|
-
#
|
|
784
|
+
# If the dataset using a order without a limit or offset or custom SQL,
|
|
785
|
+
# remove the order. Compounds on Microsoft SQL Server have undefined
|
|
786
|
+
# order unless the result is specifically ordered. Applying the current
|
|
787
|
+
# order before the compound doesn't work in all cases, such as when
|
|
788
|
+
# qualified identifiers are used. If you want to ensure a order
|
|
789
|
+
# for a compound dataset, apply the order after all compounds have been
|
|
790
|
+
# added.
|
|
791
|
+
def compound_from_self
|
|
792
|
+
if @opts[:offset] && !@opts[:limit] && !is_2012_or_later?
|
|
793
|
+
clone(:limit=>LIMIT_ALL).from_self
|
|
794
|
+
elsif @opts[:order] && !(@opts[:sql] || @opts[:limit] || @opts[:offset])
|
|
795
|
+
unordered
|
|
796
|
+
else
|
|
797
|
+
super
|
|
798
|
+
end
|
|
799
|
+
end
|
|
800
|
+
|
|
801
|
+
private
|
|
802
|
+
|
|
803
|
+
# MSSQL does not allow ordering in sub-clauses unless TOP (limit) is specified
|
|
812
804
|
def aggregate_dataset
|
|
813
805
|
(options_overlap(Sequel::Dataset::COUNT_FROM_SELF_OPTS) && !options_overlap([:limit])) ? unordered.from_self : super
|
|
814
806
|
end
|
|
815
807
|
|
|
816
|
-
|
|
808
|
+
# Allow update and delete for unordered, limited datasets only.
|
|
809
|
+
def check_not_limited!(type)
|
|
810
|
+
return if @opts[:skip_limit_check] && type != :truncate
|
|
811
|
+
raise Sequel::InvalidOperation, "Dataset##{type} not suppored on ordered, limited datasets" if opts[:order] && opts[:limit]
|
|
812
|
+
super if type == :truncate || @opts[:offset]
|
|
813
|
+
end
|
|
817
814
|
|
|
818
815
|
# Whether we are using SQL Server 2005 or later.
|
|
819
816
|
def is_2005_or_later?
|
|
@@ -834,12 +831,12 @@ module Sequel
|
|
|
834
831
|
# since that is the format that is multilanguage and not
|
|
835
832
|
# DATEFORMAT dependent.
|
|
836
833
|
def default_timestamp_format
|
|
837
|
-
|
|
834
|
+
"'%Y-%m-%dT%H:%M:%S%N%z'"
|
|
838
835
|
end
|
|
839
836
|
|
|
840
837
|
# Only include the primary table in the main delete clause
|
|
841
838
|
def delete_from_sql(sql)
|
|
842
|
-
sql << FROM
|
|
839
|
+
sql << ' FROM '
|
|
843
840
|
source_list_append(sql, @opts[:from][0..0])
|
|
844
841
|
end
|
|
845
842
|
|
|
@@ -873,7 +870,7 @@ module Sequel
|
|
|
873
870
|
end
|
|
874
871
|
end
|
|
875
872
|
|
|
876
|
-
# Microsoft SQL Server 2012 has native support for offsets, but only for ordered datasets.
|
|
873
|
+
# Microsoft SQL Server 2012+ has native support for offsets, but only for ordered datasets.
|
|
877
874
|
def emulate_offset_with_row_number?
|
|
878
875
|
super && !(is_2012_or_later? && @opts[:order])
|
|
879
876
|
end
|
|
@@ -893,9 +890,9 @@ module Sequel
|
|
|
893
890
|
def join_type_sql(join_type)
|
|
894
891
|
case join_type
|
|
895
892
|
when :cross_apply
|
|
896
|
-
|
|
893
|
+
'CROSS APPLY'
|
|
897
894
|
when :outer_apply
|
|
898
|
-
|
|
895
|
+
'OUTER APPLY'
|
|
899
896
|
else
|
|
900
897
|
super
|
|
901
898
|
end
|
|
@@ -903,30 +900,30 @@ module Sequel
|
|
|
903
900
|
|
|
904
901
|
# MSSQL uses a literal hexidecimal number for blob strings
|
|
905
902
|
def literal_blob_append(sql, v)
|
|
906
|
-
sql <<
|
|
903
|
+
sql << '0x' << v.unpack("H*").first
|
|
907
904
|
end
|
|
908
905
|
|
|
909
|
-
# Use YYYYmmdd format, since that's the only
|
|
906
|
+
# Use YYYYmmdd format, since that's the only format that is
|
|
910
907
|
# multilanguage and not DATEFORMAT dependent.
|
|
911
908
|
def literal_date(v)
|
|
912
|
-
v.strftime(
|
|
909
|
+
v.strftime("'%Y%m%d'")
|
|
913
910
|
end
|
|
914
911
|
|
|
915
912
|
# Use 0 for false on MSSQL
|
|
916
913
|
def literal_false
|
|
917
|
-
|
|
914
|
+
'0'
|
|
918
915
|
end
|
|
919
916
|
|
|
920
917
|
# Optionally use unicode string syntax for all strings. Don't double
|
|
921
918
|
# backslashes.
|
|
922
919
|
def literal_string_append(sql, v)
|
|
923
|
-
sql << (mssql_unicode_strings ?
|
|
924
|
-
sql << v.gsub(
|
|
920
|
+
sql << (mssql_unicode_strings ? "N'" : "'")
|
|
921
|
+
sql << v.gsub("'", "''").gsub(/\\((?:\r\n)|\n)/, '\\\\\\\\\\1\\1') << "'"
|
|
925
922
|
end
|
|
926
923
|
|
|
927
924
|
# Use 1 for true on MSSQL
|
|
928
925
|
def literal_true
|
|
929
|
-
|
|
926
|
+
'1'
|
|
930
927
|
end
|
|
931
928
|
|
|
932
929
|
# MSSQL 2008+ supports multiple rows in the VALUES clause, older versions
|
|
@@ -935,38 +932,74 @@ module Sequel
|
|
|
935
932
|
is_2008_or_later? ? :values : :union
|
|
936
933
|
end
|
|
937
934
|
|
|
935
|
+
def non_sql_option?(key)
|
|
936
|
+
super || key == :disable_insert_output || key == :mssql_unicode_strings
|
|
937
|
+
end
|
|
938
|
+
|
|
938
939
|
def select_into_sql(sql)
|
|
939
940
|
if i = @opts[:into]
|
|
940
|
-
sql << INTO
|
|
941
|
+
sql << " INTO "
|
|
941
942
|
identifier_append(sql, i)
|
|
942
943
|
end
|
|
943
944
|
end
|
|
944
945
|
|
|
945
|
-
# MSSQL uses TOP N for limit. For MSSQL 2005+ TOP (N) is used
|
|
946
|
+
# MSSQL 2000 uses TOP N for limit. For MSSQL 2005+ TOP (N) is used
|
|
946
947
|
# to allow the limit to be a bound variable.
|
|
947
948
|
def select_limit_sql(sql)
|
|
948
949
|
if l = @opts[:limit]
|
|
949
950
|
return if is_2012_or_later? && @opts[:order] && @opts[:offset]
|
|
951
|
+
shared_limit_sql(sql, l)
|
|
952
|
+
end
|
|
953
|
+
end
|
|
950
954
|
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
sql <<
|
|
955
|
+
def shared_limit_sql(sql, l)
|
|
956
|
+
if is_2005_or_later?
|
|
957
|
+
if l == LIMIT_ALL
|
|
958
|
+
sql << " TOP (100) PERCENT"
|
|
955
959
|
else
|
|
956
|
-
sql << TOP
|
|
960
|
+
sql << " TOP ("
|
|
957
961
|
literal_append(sql, l)
|
|
962
|
+
sql << ')'
|
|
958
963
|
end
|
|
964
|
+
else
|
|
965
|
+
sql << " TOP "
|
|
966
|
+
literal_append(sql, l)
|
|
967
|
+
end
|
|
968
|
+
|
|
969
|
+
if @opts[:limit_with_ties]
|
|
970
|
+
sql << " WITH TIES"
|
|
971
|
+
end
|
|
972
|
+
end
|
|
973
|
+
|
|
974
|
+
def update_limit_sql(sql)
|
|
975
|
+
if l = @opts[:limit]
|
|
976
|
+
shared_limit_sql(sql, l)
|
|
959
977
|
end
|
|
960
978
|
end
|
|
961
|
-
alias update_limit_sql
|
|
979
|
+
alias delete_limit_sql update_limit_sql
|
|
962
980
|
|
|
963
|
-
#
|
|
981
|
+
# Handle dirty, skip locked, and for update locking
|
|
964
982
|
def select_lock_sql(sql)
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
983
|
+
lock = @opts[:lock]
|
|
984
|
+
skip_locked = @opts[:skip_locked]
|
|
985
|
+
nowait = @opts[:nowait]
|
|
986
|
+
for_update = lock == :update
|
|
987
|
+
dirty = lock == :dirty
|
|
988
|
+
lock_hint = for_update || dirty
|
|
989
|
+
|
|
990
|
+
if lock_hint || skip_locked
|
|
991
|
+
sql << " WITH ("
|
|
992
|
+
|
|
993
|
+
if lock_hint
|
|
994
|
+
sql << (for_update ? 'UPDLOCK' : 'NOLOCK')
|
|
995
|
+
end
|
|
996
|
+
|
|
997
|
+
if skip_locked || nowait
|
|
998
|
+
sql << ', ' if lock_hint
|
|
999
|
+
sql << (skip_locked ? "READPAST" : "NOWAIT")
|
|
1000
|
+
end
|
|
1001
|
+
|
|
1002
|
+
sql << ')'
|
|
970
1003
|
else
|
|
971
1004
|
super
|
|
972
1005
|
end
|
|
@@ -978,20 +1011,19 @@ module Sequel
|
|
|
978
1011
|
super
|
|
979
1012
|
if is_2012_or_later? && @opts[:order]
|
|
980
1013
|
if o = @opts[:offset]
|
|
981
|
-
sql << OFFSET
|
|
1014
|
+
sql << " OFFSET "
|
|
982
1015
|
literal_append(sql, o)
|
|
983
|
-
sql << ROWS
|
|
1016
|
+
sql << " ROWS"
|
|
984
1017
|
|
|
985
1018
|
if l = @opts[:limit]
|
|
986
|
-
sql <<
|
|
1019
|
+
sql << " FETCH NEXT "
|
|
987
1020
|
literal_append(sql, l)
|
|
988
|
-
sql <<
|
|
1021
|
+
sql << " ROWS ONLY"
|
|
989
1022
|
end
|
|
990
1023
|
end
|
|
991
1024
|
end
|
|
992
1025
|
end
|
|
993
1026
|
|
|
994
|
-
# SQL fragment for MSSQL's OUTPUT clause.
|
|
995
1027
|
def output_sql(sql, type)
|
|
996
1028
|
return unless supports_output_clause?
|
|
997
1029
|
if output = @opts[:output]
|
|
@@ -1002,21 +1034,21 @@ module Sequel
|
|
|
1002
1034
|
end
|
|
1003
1035
|
|
|
1004
1036
|
def output_list_sql(sql, output)
|
|
1005
|
-
sql << OUTPUT
|
|
1037
|
+
sql << " OUTPUT "
|
|
1006
1038
|
column_list_append(sql, output[:select_list])
|
|
1007
1039
|
if into = output[:into]
|
|
1008
|
-
sql << INTO
|
|
1040
|
+
sql << " INTO "
|
|
1009
1041
|
identifier_append(sql, into)
|
|
1010
1042
|
if column_list = output[:column_list]
|
|
1011
|
-
sql <<
|
|
1043
|
+
sql << ' ('
|
|
1012
1044
|
source_list_append(sql, column_list)
|
|
1013
|
-
sql <<
|
|
1045
|
+
sql << ')'
|
|
1014
1046
|
end
|
|
1015
1047
|
end
|
|
1016
1048
|
end
|
|
1017
1049
|
|
|
1018
1050
|
def output_returning_sql(sql, type, values)
|
|
1019
|
-
sql << OUTPUT
|
|
1051
|
+
sql << " OUTPUT "
|
|
1020
1052
|
if values.empty?
|
|
1021
1053
|
literal_append(sql, SQL::ColumnAll.new(type))
|
|
1022
1054
|
else
|
|
@@ -1032,14 +1064,27 @@ module Sequel
|
|
|
1032
1064
|
end
|
|
1033
1065
|
end
|
|
1034
1066
|
|
|
1035
|
-
# MSSQL
|
|
1067
|
+
# MSSQL does not natively support NULLS FIRST/LAST.
|
|
1068
|
+
def requires_emulating_nulls_first?
|
|
1069
|
+
true
|
|
1070
|
+
end
|
|
1071
|
+
|
|
1072
|
+
# MSSQL supports 100-nsec precision for time columns, but ruby by
|
|
1073
|
+
# default only supports usec precision.
|
|
1074
|
+
def sqltime_precision
|
|
1075
|
+
6
|
|
1076
|
+
end
|
|
1077
|
+
|
|
1078
|
+
# MSSQL supports millisecond timestamp precision for datetime columns.
|
|
1079
|
+
# 100-nsec precision is supported for datetime2 columns, but Sequel does
|
|
1080
|
+
# not know what the column type is when formatting values.
|
|
1036
1081
|
def timestamp_precision
|
|
1037
1082
|
3
|
|
1038
1083
|
end
|
|
1039
1084
|
|
|
1040
1085
|
# Only include the primary table in the main update clause
|
|
1041
1086
|
def update_table_sql(sql)
|
|
1042
|
-
sql <<
|
|
1087
|
+
sql << ' '
|
|
1043
1088
|
source_list_append(sql, @opts[:from][0..0])
|
|
1044
1089
|
end
|
|
1045
1090
|
|