sequel 4.36.0 → 5.61.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 +548 -5749
- data/MIT-LICENSE +1 -1
- data/README.rdoc +265 -159
- data/bin/sequel +34 -12
- data/doc/advanced_associations.rdoc +228 -187
- data/doc/association_basics.rdoc +281 -291
- data/doc/bin_sequel.rdoc +5 -3
- data/doc/cheat_sheet.rdoc +86 -51
- data/doc/code_order.rdoc +25 -19
- 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/fork_safety.rdoc +84 -0
- data/doc/mass_assignment.rdoc +74 -31
- data/doc/migration.rdoc +59 -51
- 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 +58 -68
- data/doc/opening_databases.rdoc +85 -95
- data/doc/postgresql.rdoc +263 -38
- data/doc/prepared_statements.rdoc +29 -24
- data/doc/querying.rdoc +189 -167
- 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.38.0.txt +28 -0
- data/doc/release_notes/5.39.0.txt +19 -0
- data/doc/release_notes/5.4.0.txt +80 -0
- data/doc/release_notes/5.40.0.txt +40 -0
- data/doc/release_notes/5.41.0.txt +25 -0
- data/doc/release_notes/5.42.0.txt +136 -0
- data/doc/release_notes/5.43.0.txt +98 -0
- data/doc/release_notes/5.44.0.txt +32 -0
- data/doc/release_notes/5.45.0.txt +34 -0
- data/doc/release_notes/5.46.0.txt +87 -0
- data/doc/release_notes/5.47.0.txt +59 -0
- data/doc/release_notes/5.48.0.txt +14 -0
- data/doc/release_notes/5.49.0.txt +59 -0
- data/doc/release_notes/5.5.0.txt +61 -0
- data/doc/release_notes/5.50.0.txt +78 -0
- data/doc/release_notes/5.51.0.txt +47 -0
- data/doc/release_notes/5.52.0.txt +87 -0
- data/doc/release_notes/5.53.0.txt +23 -0
- data/doc/release_notes/5.54.0.txt +27 -0
- data/doc/release_notes/5.55.0.txt +21 -0
- data/doc/release_notes/5.56.0.txt +51 -0
- data/doc/release_notes/5.57.0.txt +23 -0
- data/doc/release_notes/5.58.0.txt +31 -0
- data/doc/release_notes/5.59.0.txt +73 -0
- data/doc/release_notes/5.6.0.txt +31 -0
- data/doc/release_notes/5.60.0.txt +22 -0
- data/doc/release_notes/5.61.0.txt +43 -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 +95 -75
- data/doc/security.rdoc +109 -80
- data/doc/sharding.rdoc +74 -47
- data/doc/sql.rdoc +147 -122
- data/doc/testing.rdoc +43 -20
- data/doc/thread_safety.rdoc +2 -4
- data/doc/transactions.rdoc +97 -18
- data/doc/validations.rdoc +52 -50
- data/doc/virtual_rows.rdoc +90 -109
- data/lib/sequel/adapters/ado/access.rb +15 -17
- data/lib/sequel/adapters/ado/mssql.rb +6 -15
- data/lib/sequel/adapters/ado.rb +150 -20
- data/lib/sequel/adapters/amalgalite.rb +11 -23
- data/lib/sequel/adapters/ibmdb.rb +47 -55
- data/lib/sequel/adapters/jdbc/db2.rb +29 -39
- data/lib/sequel/adapters/jdbc/derby.rb +58 -54
- data/lib/sequel/adapters/jdbc/h2.rb +93 -35
- data/lib/sequel/adapters/jdbc/hsqldb.rb +24 -31
- data/lib/sequel/adapters/jdbc/jtds.rb +2 -10
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -11
- data/lib/sequel/adapters/jdbc/mysql.rb +17 -20
- data/lib/sequel/adapters/jdbc/oracle.rb +22 -18
- data/lib/sequel/adapters/jdbc/postgresql.rb +69 -71
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +11 -23
- data/lib/sequel/adapters/jdbc/sqlite.rb +47 -11
- data/lib/sequel/adapters/jdbc/sqlserver.rb +34 -9
- data/lib/sequel/adapters/jdbc/transactions.rb +22 -38
- data/lib/sequel/adapters/jdbc.rb +145 -130
- data/lib/sequel/adapters/mock.rb +100 -111
- data/lib/sequel/adapters/mysql.rb +114 -122
- data/lib/sequel/adapters/mysql2.rb +147 -63
- data/lib/sequel/adapters/odbc/db2.rb +1 -1
- data/lib/sequel/adapters/odbc/mssql.rb +8 -14
- data/lib/sequel/adapters/odbc/oracle.rb +11 -0
- data/lib/sequel/adapters/odbc.rb +20 -25
- data/lib/sequel/adapters/oracle.rb +50 -56
- data/lib/sequel/adapters/postgres.rb +305 -327
- data/lib/sequel/adapters/postgresql.rb +1 -1
- data/lib/sequel/adapters/shared/access.rb +74 -78
- data/lib/sequel/adapters/shared/db2.rb +118 -71
- data/lib/sequel/adapters/shared/mssql.rb +301 -220
- data/lib/sequel/adapters/shared/mysql.rb +299 -217
- data/lib/sequel/adapters/shared/oracle.rb +226 -65
- data/lib/sequel/adapters/shared/postgres.rb +935 -395
- data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -126
- data/lib/sequel/adapters/shared/sqlite.rb +447 -173
- data/lib/sequel/adapters/sqlanywhere.rb +48 -35
- data/lib/sequel/adapters/sqlite.rb +156 -111
- data/lib/sequel/adapters/tinytds.rb +30 -38
- data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +3 -6
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +2 -2
- 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 +1 -4
- data/lib/sequel/adapters/utils/stored_procedures.rb +7 -22
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
- data/lib/sequel/ast_transformer.rb +17 -89
- data/lib/sequel/connection_pool/sharded_single.rb +18 -15
- data/lib/sequel/connection_pool/sharded_threaded.rb +130 -111
- data/lib/sequel/connection_pool/single.rb +18 -13
- data/lib/sequel/connection_pool/threaded.rb +121 -120
- data/lib/sequel/connection_pool.rb +48 -29
- data/lib/sequel/core.rb +351 -301
- data/lib/sequel/database/connecting.rb +69 -57
- data/lib/sequel/database/dataset.rb +13 -5
- data/lib/sequel/database/dataset_defaults.rb +18 -102
- data/lib/sequel/database/features.rb +18 -4
- data/lib/sequel/database/logging.rb +12 -11
- data/lib/sequel/database/misc.rb +180 -122
- data/lib/sequel/database/query.rb +47 -27
- data/lib/sequel/database/schema_generator.rb +178 -84
- data/lib/sequel/database/schema_methods.rb +172 -97
- data/lib/sequel/database/transactions.rb +205 -44
- data/lib/sequel/database.rb +17 -2
- data/lib/sequel/dataset/actions.rb +339 -155
- data/lib/sequel/dataset/dataset_module.rb +46 -0
- data/lib/sequel/dataset/features.rb +90 -35
- data/lib/sequel/dataset/graph.rb +80 -58
- data/lib/sequel/dataset/misc.rb +137 -47
- data/lib/sequel/dataset/placeholder_literalizer.rb +63 -25
- data/lib/sequel/dataset/prepared_statements.rb +188 -85
- data/lib/sequel/dataset/query.rb +530 -222
- data/lib/sequel/dataset/sql.rb +590 -368
- data/lib/sequel/dataset.rb +26 -16
- data/lib/sequel/deprecated.rb +12 -2
- data/lib/sequel/exceptions.rb +46 -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 +2 -5
- data/lib/sequel/extensions/any_not_empty.rb +45 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +10 -10
- data/lib/sequel/extensions/async_thread_pool.rb +438 -0
- data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
- data/lib/sequel/extensions/blank.rb +8 -0
- data/lib/sequel/extensions/caller_logging.rb +79 -0
- data/lib/sequel/extensions/columns_introspection.rb +4 -3
- data/lib/sequel/extensions/connection_expiration.rb +20 -10
- data/lib/sequel/extensions/connection_validator.rb +11 -10
- data/lib/sequel/extensions/constant_sql_override.rb +65 -0
- data/lib/sequel/extensions/constraint_validations.rb +62 -39
- data/lib/sequel/extensions/core_extensions.rb +42 -48
- data/lib/sequel/extensions/core_refinements.rb +80 -59
- data/lib/sequel/extensions/current_datetime_timestamp.rb +1 -4
- data/lib/sequel/extensions/date_arithmetic.rb +98 -39
- data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
- data/lib/sequel/extensions/datetime_parse_to_time.rb +41 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +21 -14
- data/lib/sequel/extensions/empty_array_consider_nulls.rb +2 -2
- data/lib/sequel/extensions/escaped_like.rb +100 -0
- data/lib/sequel/extensions/eval_inspect.rb +12 -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 +1 -34
- data/lib/sequel/extensions/graph_each.rb +4 -4
- 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 +13 -5
- data/lib/sequel/extensions/integer64.rb +32 -0
- data/lib/sequel/extensions/is_distinct_from.rb +141 -0
- data/lib/sequel/extensions/looser_typecasting.rb +17 -8
- data/lib/sequel/extensions/migration.rb +119 -78
- data/lib/sequel/extensions/named_timezones.rb +88 -23
- data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -82
- data/lib/sequel/extensions/null_dataset.rb +8 -8
- data/lib/sequel/extensions/pagination.rb +32 -29
- data/lib/sequel/extensions/pg_array.rb +221 -287
- data/lib/sequel/extensions/pg_array_ops.rb +17 -9
- data/lib/sequel/extensions/pg_enum.rb +63 -23
- data/lib/sequel/extensions/pg_extended_date_support.rb +241 -0
- data/lib/sequel/extensions/pg_hstore.rb +45 -54
- data/lib/sequel/extensions/pg_hstore_ops.rb +58 -6
- data/lib/sequel/extensions/pg_inet.rb +31 -12
- data/lib/sequel/extensions/pg_inet_ops.rb +2 -2
- data/lib/sequel/extensions/pg_interval.rb +56 -29
- data/lib/sequel/extensions/pg_json.rb +417 -140
- data/lib/sequel/extensions/pg_json_ops.rb +270 -18
- data/lib/sequel/extensions/pg_loose_count.rb +4 -2
- data/lib/sequel/extensions/pg_multirange.rb +372 -0
- data/lib/sequel/extensions/pg_range.rb +131 -191
- data/lib/sequel/extensions/pg_range_ops.rb +42 -13
- data/lib/sequel/extensions/pg_row.rb +48 -81
- data/lib/sequel/extensions/pg_row_ops.rb +33 -14
- data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
- data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
- data/lib/sequel/extensions/query.rb +9 -7
- data/lib/sequel/extensions/round_timestamps.rb +0 -6
- data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
- data/lib/sequel/extensions/s.rb +60 -0
- data/lib/sequel/extensions/schema_caching.rb +10 -1
- data/lib/sequel/extensions/schema_dumper.rb +71 -48
- data/lib/sequel/extensions/select_remove.rb +4 -4
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
- data/lib/sequel/extensions/server_block.rb +51 -27
- data/lib/sequel/extensions/split_array_nil.rb +4 -4
- data/lib/sequel/extensions/sql_comments.rb +119 -7
- data/lib/sequel/extensions/sql_expr.rb +2 -1
- data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
- data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
- data/lib/sequel/extensions/string_agg.rb +11 -8
- data/lib/sequel/extensions/string_date_time.rb +19 -23
- data/lib/sequel/extensions/symbol_aref.rb +55 -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/to_dot.rb +10 -4
- data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
- data/lib/sequel/model/associations.rb +1006 -284
- data/lib/sequel/model/base.rb +560 -805
- data/lib/sequel/model/dataset_module.rb +11 -10
- data/lib/sequel/model/default_inflections.rb +1 -1
- data/lib/sequel/model/errors.rb +10 -3
- data/lib/sequel/model/exceptions.rb +8 -10
- data/lib/sequel/model/inflections.rb +7 -20
- data/lib/sequel/model/plugins.rb +114 -0
- data/lib/sequel/model.rb +32 -82
- data/lib/sequel/plugins/active_model.rb +30 -14
- data/lib/sequel/plugins/after_initialize.rb +1 -1
- data/lib/sequel/plugins/association_dependencies.rb +25 -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 +147 -70
- data/lib/sequel/plugins/association_proxies.rb +33 -9
- data/lib/sequel/plugins/async_thread_pool.rb +39 -0
- data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
- data/lib/sequel/plugins/auto_validations.rb +95 -28
- data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
- data/lib/sequel/plugins/before_after_save.rb +0 -42
- data/lib/sequel/plugins/blacklist_security.rb +21 -12
- data/lib/sequel/plugins/boolean_readers.rb +5 -5
- data/lib/sequel/plugins/boolean_subsets.rb +13 -8
- data/lib/sequel/plugins/caching.rb +25 -16
- data/lib/sequel/plugins/class_table_inheritance.rb +179 -100
- data/lib/sequel/plugins/column_conflicts.rb +16 -3
- data/lib/sequel/plugins/column_encryption.rb +728 -0
- data/lib/sequel/plugins/column_select.rb +7 -5
- data/lib/sequel/plugins/columns_updated.rb +42 -0
- data/lib/sequel/plugins/composition.rb +42 -26
- data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
- data/lib/sequel/plugins/constraint_validations.rb +20 -14
- data/lib/sequel/plugins/csv_serializer.rb +56 -35
- data/lib/sequel/plugins/dataset_associations.rb +40 -17
- data/lib/sequel/plugins/def_dataset_method.rb +90 -0
- data/lib/sequel/plugins/defaults_setter.rb +65 -10
- data/lib/sequel/plugins/delay_add_association.rb +1 -1
- data/lib/sequel/plugins/dirty.rb +62 -24
- data/lib/sequel/plugins/eager_each.rb +3 -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/enum.rb +124 -0
- data/lib/sequel/plugins/error_splitter.rb +17 -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 +7 -12
- data/lib/sequel/plugins/hook_class_methods.rb +37 -54
- data/lib/sequel/plugins/input_transformer.rb +18 -10
- data/lib/sequel/plugins/insert_conflict.rb +76 -0
- data/lib/sequel/plugins/insert_returning_select.rb +2 -2
- data/lib/sequel/plugins/instance_filters.rb +10 -8
- data/lib/sequel/plugins/instance_hooks.rb +34 -17
- data/lib/sequel/plugins/instance_specific_default.rb +113 -0
- data/lib/sequel/plugins/inverted_subsets.rb +22 -13
- data/lib/sequel/plugins/json_serializer.rb +124 -64
- data/lib/sequel/plugins/lazy_attributes.rb +21 -14
- data/lib/sequel/plugins/list.rb +35 -21
- data/lib/sequel/plugins/many_through_many.rb +134 -21
- data/lib/sequel/plugins/modification_detection.rb +15 -5
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +6 -5
- data/lib/sequel/plugins/nested_attributes.rb +61 -31
- data/lib/sequel/plugins/optimistic_locking.rb +3 -3
- data/lib/sequel/plugins/pg_array_associations.rb +103 -53
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +350 -0
- data/lib/sequel/plugins/pg_row.rb +5 -51
- data/lib/sequel/plugins/prepared_statements.rb +60 -72
- data/lib/sequel/plugins/prepared_statements_safe.rb +9 -4
- data/lib/sequel/plugins/rcte_tree.rb +68 -82
- data/lib/sequel/plugins/require_valid_schema.rb +67 -0
- data/lib/sequel/plugins/serialization.rb +43 -46
- data/lib/sequel/plugins/serialization_modification_detection.rb +3 -2
- data/lib/sequel/plugins/sharding.rb +15 -10
- data/lib/sequel/plugins/single_table_inheritance.rb +67 -28
- data/lib/sequel/plugins/skip_create_refresh.rb +3 -3
- data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
- data/lib/sequel/plugins/split_values.rb +11 -6
- data/lib/sequel/plugins/sql_comments.rb +189 -0
- data/lib/sequel/plugins/static_cache.rb +77 -53
- data/lib/sequel/plugins/static_cache_cache.rb +53 -0
- data/lib/sequel/plugins/string_stripper.rb +3 -3
- data/lib/sequel/plugins/subclasses.rb +43 -10
- data/lib/sequel/plugins/subset_conditions.rb +15 -5
- data/lib/sequel/plugins/table_select.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +96 -12
- data/lib/sequel/plugins/throw_failures.rb +110 -0
- data/lib/sequel/plugins/timestamps.rb +20 -8
- data/lib/sequel/plugins/touch.rb +19 -8
- data/lib/sequel/plugins/tree.rb +62 -32
- data/lib/sequel/plugins/typecast_on_load.rb +12 -4
- data/lib/sequel/plugins/unlimited_update.rb +1 -7
- data/lib/sequel/plugins/unused_associations.rb +521 -0
- data/lib/sequel/plugins/update_or_create.rb +4 -4
- data/lib/sequel/plugins/update_primary_key.rb +1 -1
- data/lib/sequel/plugins/update_refresh.rb +26 -15
- data/lib/sequel/plugins/uuid.rb +7 -11
- data/lib/sequel/plugins/validate_associated.rb +18 -0
- data/lib/sequel/plugins/validation_class_methods.rb +38 -19
- data/lib/sequel/plugins/validation_contexts.rb +49 -0
- data/lib/sequel/plugins/validation_helpers.rb +57 -41
- data/lib/sequel/plugins/whitelist_security.rb +122 -0
- data/lib/sequel/plugins/xml_serializer.rb +30 -31
- data/lib/sequel/sql.rb +471 -331
- data/lib/sequel/timezones.rb +78 -47
- data/lib/sequel/version.rb +7 -2
- data/lib/sequel.rb +1 -1
- metadata +217 -521
- data/Rakefile +0 -164
- data/doc/active_record.rdoc +0 -928
- 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.27.0.txt +0 -78
- data/doc/release_notes/4.28.0.txt +0 -57
- data/doc/release_notes/4.29.0.txt +0 -41
- data/doc/release_notes/4.3.0.txt +0 -40
- data/doc/release_notes/4.30.0.txt +0 -37
- data/doc/release_notes/4.31.0.txt +0 -57
- data/doc/release_notes/4.32.0.txt +0 -132
- data/doc/release_notes/4.33.0.txt +0 -88
- data/doc/release_notes/4.34.0.txt +0 -86
- data/doc/release_notes/4.35.0.txt +0 -130
- data/doc/release_notes/4.36.0.txt +0 -116
- data/doc/release_notes/4.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 -144
- data/lib/sequel/adapters/do/mysql.rb +0 -66
- data/lib/sequel/adapters/do/postgres.rb +0 -44
- data/lib/sequel/adapters/do/sqlite3.rb +0 -42
- data/lib/sequel/adapters/do.rb +0 -158
- data/lib/sequel/adapters/jdbc/as400.rb +0 -84
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -64
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -36
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -33
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -33
- data/lib/sequel/adapters/odbc/progress.rb +0 -10
- data/lib/sequel/adapters/shared/cubrid.rb +0 -245
- data/lib/sequel/adapters/shared/firebird.rb +0 -247
- data/lib/sequel/adapters/shared/informix.rb +0 -54
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -152
- data/lib/sequel/adapters/shared/progress.rb +0 -40
- data/lib/sequel/adapters/swift/mysql.rb +0 -49
- data/lib/sequel/adapters/swift/postgres.rb +0 -47
- data/lib/sequel/adapters/swift/sqlite.rb +0 -49
- data/lib/sequel/adapters/swift.rb +0 -160
- data/lib/sequel/adapters/utils/pg_types.rb +0 -70
- data/lib/sequel/dataset/mutation.rb +0 -111
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -5
- data/lib/sequel/extensions/filter_having.rb +0 -63
- data/lib/sequel/extensions/hash_aliases.rb +0 -49
- data/lib/sequel/extensions/meta_def.rb +0 -35
- data/lib/sequel/extensions/query_literals.rb +0 -84
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -24
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -122
- data/lib/sequel/extensions/set_overrides.rb +0 -76
- data/lib/sequel/no_core_ext.rb +0 -3
- data/lib/sequel/plugins/association_autoreloading.rb +0 -9
- data/lib/sequel/plugins/identifier_columns.rb +0 -47
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -9
- data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -81
- data/lib/sequel/plugins/prepared_statements_associations.rb +0 -119
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -61
- data/lib/sequel/plugins/schema.rb +0 -82
- data/lib/sequel/plugins/scissors.rb +0 -35
- data/spec/adapter_spec.rb +0 -4
- 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 -733
- data/spec/adapters/mysql_spec.rb +0 -1319
- data/spec/adapters/oracle_spec.rb +0 -313
- data/spec/adapters/postgres_spec.rb +0 -3790
- data/spec/adapters/spec_helper.rb +0 -49
- data/spec/adapters/sqlanywhere_spec.rb +0 -170
- data/spec/adapters/sqlite_spec.rb +0 -688
- data/spec/bin_spec.rb +0 -258
- data/spec/core/connection_pool_spec.rb +0 -1045
- data/spec/core/database_spec.rb +0 -2636
- data/spec/core/dataset_spec.rb +0 -5175
- data/spec/core/deprecated_spec.rb +0 -70
- data/spec/core/expression_filters_spec.rb +0 -1247
- data/spec/core/mock_adapter_spec.rb +0 -464
- 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 -203
- data/spec/core/schema_spec.rb +0 -1676
- 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/core_model_spec.rb +0 -2
- data/spec/core_spec.rb +0 -1
- data/spec/extensions/accessed_columns_spec.rb +0 -51
- data/spec/extensions/active_model_spec.rb +0 -85
- 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 -405
- data/spec/extensions/association_proxies_spec.rb +0 -86
- data/spec/extensions/auto_validations_spec.rb +0 -192
- data/spec/extensions/before_after_save_spec.rb +0 -40
- 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/boolean_subsets_spec.rb +0 -47
- data/spec/extensions/caching_spec.rb +0 -270
- data/spec/extensions/class_table_inheritance_spec.rb +0 -444
- 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_expiration_spec.rb +0 -121
- data/spec/extensions/connection_validator_spec.rb +0 -127
- data/spec/extensions/constraint_validations_plugin_spec.rb +0 -288
- data/spec/extensions/constraint_validations_spec.rb +0 -389
- data/spec/extensions/core_refinements_spec.rb +0 -519
- data/spec/extensions/csv_serializer_spec.rb +0 -180
- data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
- data/spec/extensions/dataset_associations_spec.rb +0 -343
- data/spec/extensions/dataset_source_alias_spec.rb +0 -51
- data/spec/extensions/date_arithmetic_spec.rb +0 -167
- data/spec/extensions/defaults_setter_spec.rb +0 -102
- data/spec/extensions/delay_add_association_spec.rb +0 -74
- data/spec/extensions/dirty_spec.rb +0 -180
- data/spec/extensions/duplicate_columns_handler_spec.rb +0 -110
- data/spec/extensions/eager_each_spec.rb +0 -66
- 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 -119
- data/spec/extensions/hash_aliases_spec.rb +0 -24
- data/spec/extensions/hook_class_methods_spec.rb +0 -429
- data/spec/extensions/identifier_columns_spec.rb +0 -17
- 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 -304
- data/spec/extensions/lazy_attributes_spec.rb +0 -170
- data/spec/extensions/list_spec.rb +0 -278
- 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 -728
- 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/no_auto_literal_strings_spec.rb +0 -65
- 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 -390
- 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 -275
- 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 -473
- 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 -814
- 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/server_logging_spec.rb +0 -45
- 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_comments_spec.rb +0 -27
- data/spec/extensions/sql_expr_spec.rb +0 -60
- data/spec/extensions/static_cache_spec.rb +0 -361
- data/spec/extensions/string_agg_spec.rb +0 -85
- 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/subset_conditions_spec.rb +0 -38
- data/spec/extensions/table_select_spec.rb +0 -71
- data/spec/extensions/tactical_eager_loading_spec.rb +0 -136
- 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/uuid_spec.rb +0 -106
- 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 -554
- 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/double_migration/001_create_sessions.rb +0 -9
- data/spec/files/double_migration/002_create_nodes.rb +0 -19
- data/spec/files/double_migration/003_3_create_users.rb +0 -4
- data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
- data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
- data/spec/files/empty_migration/001_create_sessions.rb +0 -9
- data/spec/files/empty_migration/002_create_nodes.rb +0 -0
- data/spec/files/empty_migration/003_3_create_users.rb +0 -4
- data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
- data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
- data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
- data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
- data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/reversible_migrations/001_reversible.rb +0 -5
- data/spec/files/reversible_migrations/002_reversible.rb +0 -5
- data/spec/files/reversible_migrations/003_reversible.rb +0 -5
- data/spec/files/reversible_migrations/004_reversible.rb +0 -5
- data/spec/files/reversible_migrations/005_reversible.rb +0 -10
- data/spec/files/reversible_migrations/006_reversible.rb +0 -10
- data/spec/files/reversible_migrations/007_reversible.rb +0 -10
- data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
- data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
- data/spec/guards_helper.rb +0 -55
- data/spec/integration/associations_test.rb +0 -2506
- data/spec/integration/database_test.rb +0 -113
- data/spec/integration/dataset_test.rb +0 -1858
- data/spec/integration/eager_loader_test.rb +0 -687
- data/spec/integration/migrator_test.rb +0 -262
- data/spec/integration/model_test.rb +0 -230
- data/spec/integration/plugin_test.rb +0 -2297
- data/spec/integration/prepared_statement_test.rb +0 -467
- data/spec/integration/schema_test.rb +0 -815
- data/spec/integration/spec_helper.rb +0 -56
- data/spec/integration/timezone_test.rb +0 -86
- data/spec/integration/transaction_test.rb +0 -406
- data/spec/integration/type_test.rb +0 -133
- data/spec/model/association_reflection_spec.rb +0 -565
- data/spec/model/associations_spec.rb +0 -4589
- data/spec/model/base_spec.rb +0 -759
- data/spec/model/class_dataset_methods_spec.rb +0 -150
- data/spec/model/dataset_methods_spec.rb +0 -149
- data/spec/model/eager_loading_spec.rb +0 -2197
- data/spec/model/hooks_spec.rb +0 -604
- data/spec/model/inflector_spec.rb +0 -26
- data/spec/model/model_spec.rb +0 -1097
- data/spec/model/plugins_spec.rb +0 -299
- data/spec/model/record_spec.rb +0 -2162
- data/spec/model/spec_helper.rb +0 -46
- data/spec/model/validations_spec.rb +0 -193
- data/spec/model_no_assoc_spec.rb +0 -1
- data/spec/model_spec.rb +0 -1
- data/spec/plugin_spec.rb +0 -1
- data/spec/sequel_coverage.rb +0 -15
- data/spec/spec_config.rb +0 -10
@@ -1,51 +1,46 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative '../utils/replace'
|
4
|
+
require_relative '../utils/unmodified_identifiers'
|
4
5
|
|
5
6
|
module Sequel
|
6
7
|
module SQLite
|
8
|
+
Sequel::Database.set_shared_adapter_scheme(:sqlite, self)
|
9
|
+
|
10
|
+
def self.mock_adapter_setup(db)
|
11
|
+
db.instance_exec do
|
12
|
+
@sqlite_version = 30903
|
13
|
+
|
14
|
+
def schema_parse_table(*)
|
15
|
+
[]
|
16
|
+
end
|
17
|
+
singleton_class.send(:private, :schema_parse_table)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
7
21
|
# No matter how you connect to SQLite, the following Database options
|
8
22
|
# can be used to set PRAGMAs on connections in a thread-safe manner:
|
9
23
|
# :auto_vacuum, :foreign_keys, :synchronous, and :temp_store.
|
10
24
|
module DatabaseMethods
|
11
|
-
|
25
|
+
include UnmodifiedIdentifiers::DatabaseMethods
|
12
26
|
|
13
27
|
AUTO_VACUUM = [:none, :full, :incremental].freeze
|
14
|
-
PRIMARY_KEY_INDEX_RE = /\Asqlite_autoindex_/.freeze
|
15
28
|
SYNCHRONOUS = [:off, :normal, :full].freeze
|
16
|
-
TABLES_FILTER = Sequel.~(:name=>'sqlite_sequence'.freeze) & {:type => 'table'.freeze}
|
17
29
|
TEMP_STORE = [:default, :file, :memory].freeze
|
18
|
-
VIEWS_FILTER = {:type => 'view'.freeze}.freeze
|
19
30
|
TRANSACTION_MODE = {
|
20
31
|
:deferred => "BEGIN DEFERRED TRANSACTION".freeze,
|
21
32
|
:immediate => "BEGIN IMMEDIATE TRANSACTION".freeze,
|
22
33
|
:exclusive => "BEGIN EXCLUSIVE TRANSACTION".freeze,
|
23
|
-
nil =>
|
34
|
+
nil => "BEGIN".freeze
|
24
35
|
}.freeze
|
25
36
|
|
26
37
|
# Whether to use integers for booleans in the database. SQLite recommends
|
27
38
|
# booleans be stored as integers, but historically Sequel has used 't'/'f'.
|
28
39
|
attr_accessor :integer_booleans
|
29
40
|
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
# Set the auto_vacuum PRAGMA using the given symbol (:none, :full, or
|
36
|
-
# :incremental). See pragma_set. Consider using the :auto_vacuum
|
37
|
-
# Database option instead.
|
38
|
-
def auto_vacuum=(value)
|
39
|
-
value = AUTO_VACUUM.index(value) || (raise Error, "Invalid value for auto_vacuum option. Please specify one of :none, :full, :incremental.")
|
40
|
-
pragma_set(:auto_vacuum, value)
|
41
|
-
end
|
42
|
-
|
43
|
-
# Set the case_sensitive_like PRAGMA using the given boolean value, if using
|
44
|
-
# SQLite 3.2.3+. If not using 3.2.3+, no error is raised. See pragma_set.
|
45
|
-
# Consider using the :case_sensitive_like Database option instead.
|
46
|
-
def case_sensitive_like=(value)
|
47
|
-
pragma_set(:case_sensitive_like, !!value ? 'on' : 'off') if sqlite_version >= 30203
|
48
|
-
end
|
41
|
+
# Whether to keep CURRENT_TIMESTAMP and similar expressions in UTC. By
|
42
|
+
# default, the expressions are converted to localtime.
|
43
|
+
attr_accessor :current_timestamp_utc
|
49
44
|
|
50
45
|
# A symbol signifying the value of the default transaction mode
|
51
46
|
attr_reader :transaction_mode
|
@@ -64,17 +59,9 @@ module Sequel
|
|
64
59
|
:sqlite
|
65
60
|
end
|
66
61
|
|
67
|
-
#
|
68
|
-
|
69
|
-
|
70
|
-
pragma_get(:foreign_keys).to_i == 1 if sqlite_version >= 30619
|
71
|
-
end
|
72
|
-
|
73
|
-
# Set the foreign_keys PRAGMA using the given boolean value, if using
|
74
|
-
# SQLite 3.6.19+. If not using 3.6.19+, no error is raised. See pragma_set.
|
75
|
-
# Consider using the :foreign_keys Database option instead.
|
76
|
-
def foreign_keys=(value)
|
77
|
-
pragma_set(:foreign_keys, !!value ? 'on' : 'off') if sqlite_version >= 30619
|
62
|
+
# Set the integer_booleans option using the passed in :integer_boolean option.
|
63
|
+
def set_integer_booleans
|
64
|
+
@integer_booleans = @opts.has_key?(:integer_booleans) ? typecast_value_boolean(@opts[:integer_booleans]) : true
|
78
65
|
end
|
79
66
|
|
80
67
|
# Return the array of foreign key info hashes using the foreign_key_list PRAGMA,
|
@@ -82,7 +69,7 @@ module Sequel
|
|
82
69
|
def foreign_key_list(table, opts=OPTS)
|
83
70
|
m = output_identifier_meth
|
84
71
|
h = {}
|
85
|
-
|
72
|
+
_foreign_key_list_ds(table).each do |row|
|
86
73
|
if r = h[row[:id]]
|
87
74
|
r[:columns] << m.call(row[:from])
|
88
75
|
r[:key] << m.call(row[:to]) if r[:key]
|
@@ -93,14 +80,31 @@ module Sequel
|
|
93
80
|
h.values
|
94
81
|
end
|
95
82
|
|
83
|
+
def freeze
|
84
|
+
sqlite_version
|
85
|
+
use_timestamp_timezones?
|
86
|
+
super
|
87
|
+
end
|
88
|
+
|
96
89
|
# Use the index_list and index_info PRAGMAs to determine the indexes on the table.
|
97
90
|
def indexes(table, opts=OPTS)
|
98
91
|
m = output_identifier_meth
|
99
92
|
im = input_identifier_meth
|
100
93
|
indexes = {}
|
94
|
+
table = table.value if table.is_a?(Sequel::SQL::Identifier)
|
101
95
|
metadata_dataset.with_sql("PRAGMA index_list(?)", im.call(table)).each do |r|
|
102
|
-
|
103
|
-
|
96
|
+
if opts[:only_autocreated]
|
97
|
+
# If specifically asked for only autocreated indexes, then return those an only those
|
98
|
+
next unless r[:name] =~ /\Asqlite_autoindex_/
|
99
|
+
elsif r.has_key?(:origin)
|
100
|
+
# If origin is set, then only exclude primary key indexes and partial indexes
|
101
|
+
next if r[:origin] == 'pk'
|
102
|
+
next if r[:partial].to_i == 1
|
103
|
+
else
|
104
|
+
# When :origin key not present, assume any autoindex could be a primary key one and exclude it
|
105
|
+
next if r[:name] =~ /\Asqlite_autoindex_/
|
106
|
+
end
|
107
|
+
|
104
108
|
indexes[m.call(r[:name])] = {:unique=>r[:unique].to_i==1}
|
105
109
|
end
|
106
110
|
indexes.each do |k, v|
|
@@ -109,26 +113,6 @@ module Sequel
|
|
109
113
|
indexes
|
110
114
|
end
|
111
115
|
|
112
|
-
# Get the value of the given PRAGMA.
|
113
|
-
def pragma_get(name)
|
114
|
-
self["PRAGMA #{name}"].single_value
|
115
|
-
end
|
116
|
-
|
117
|
-
# Set the value of the given PRAGMA to value.
|
118
|
-
#
|
119
|
-
# This method is not thread safe, and will not work correctly if there
|
120
|
-
# are multiple connections in the Database's connection pool. PRAGMA
|
121
|
-
# modifications should be done when the connection is created, using
|
122
|
-
# an option provided when creating the Database object.
|
123
|
-
def pragma_set(name, value)
|
124
|
-
execute_ddl("PRAGMA #{name} = #{value}")
|
125
|
-
end
|
126
|
-
|
127
|
-
# Set the integer_booleans option using the passed in :integer_boolean option.
|
128
|
-
def set_integer_booleans
|
129
|
-
@integer_booleans = @opts.has_key?(:integer_booleans) ? typecast_value_boolean(@opts[:integer_booleans]) : true
|
130
|
-
end
|
131
|
-
|
132
116
|
# The version of the server as an integer, where 3.6.19 = 30619.
|
133
117
|
# If the server version can't be determined, 0 is used.
|
134
118
|
def sqlite_version
|
@@ -172,55 +156,57 @@ module Sequel
|
|
172
156
|
defined?(@use_timestamp_timezones) ? @use_timestamp_timezones : (@use_timestamp_timezones = false)
|
173
157
|
end
|
174
158
|
|
175
|
-
# A symbol signifying the value of the synchronous PRAGMA.
|
176
|
-
def synchronous
|
177
|
-
SYNCHRONOUS[pragma_get(:synchronous).to_i]
|
178
|
-
end
|
179
|
-
|
180
|
-
# Set the synchronous PRAGMA using the given symbol (:off, :normal, or :full). See pragma_set.
|
181
|
-
# Consider using the :synchronous Database option instead.
|
182
|
-
def synchronous=(value)
|
183
|
-
value = SYNCHRONOUS.index(value) || (raise Error, "Invalid value for synchronous option. Please specify one of :off, :normal, :full.")
|
184
|
-
pragma_set(:synchronous, value)
|
185
|
-
end
|
186
|
-
|
187
159
|
# Array of symbols specifying the table names in the current database.
|
188
160
|
#
|
189
161
|
# Options:
|
190
162
|
# :server :: Set the server to use.
|
191
163
|
def tables(opts=OPTS)
|
192
|
-
tables_and_views(
|
164
|
+
tables_and_views(Sequel.~(:name=>'sqlite_sequence') & {:type => 'table'}, opts)
|
193
165
|
end
|
194
166
|
|
195
|
-
#
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
# Consider using the :temp_store Database option instead.
|
202
|
-
def temp_store=(value)
|
203
|
-
value = TEMP_STORE.index(value) || (raise Error, "Invalid value for temp_store option. Please specify one of :default, :file, :memory.")
|
204
|
-
pragma_set(:temp_store, value)
|
167
|
+
# Creates a dataset that uses the VALUES clause:
|
168
|
+
#
|
169
|
+
# DB.values([[1, 2], [3, 4]])
|
170
|
+
# # VALUES ((1, 2), (3, 4))
|
171
|
+
def values(v)
|
172
|
+
@default_dataset.clone(:values=>v)
|
205
173
|
end
|
206
|
-
|
174
|
+
|
207
175
|
# Array of symbols specifying the view names in the current database.
|
208
176
|
#
|
209
177
|
# Options:
|
210
178
|
# :server :: Set the server to use.
|
211
179
|
def views(opts=OPTS)
|
212
|
-
tables_and_views(
|
180
|
+
tables_and_views({:type => 'view'}, opts)
|
213
181
|
end
|
214
182
|
|
215
183
|
private
|
216
184
|
|
185
|
+
# Dataset used for parsing foreign key lists
|
186
|
+
def _foreign_key_list_ds(table)
|
187
|
+
metadata_dataset.with_sql("PRAGMA foreign_key_list(?)", input_identifier_meth.call(table))
|
188
|
+
end
|
189
|
+
|
190
|
+
# Dataset used for parsing schema
|
191
|
+
def _parse_pragma_ds(table_name, opts)
|
192
|
+
metadata_dataset.with_sql("PRAGMA table_#{'x' if sqlite_version > 33100}info(?)", input_identifier_meth(opts[:dataset]).call(table_name))
|
193
|
+
end
|
194
|
+
|
217
195
|
# Run all alter_table commands in a transaction. This is technically only
|
218
196
|
# needed for drop column.
|
219
197
|
def apply_alter_table(table, ops)
|
220
|
-
fks = foreign_keys
|
221
|
-
|
198
|
+
fks = fetch("PRAGMA foreign_keys")
|
199
|
+
if fks
|
200
|
+
run "PRAGMA foreign_keys = 0"
|
201
|
+
run "PRAGMA legacy_alter_table = 1" if sqlite_version >= 32600
|
202
|
+
end
|
222
203
|
transaction do
|
223
|
-
if ops.length > 1 && ops.all?{|op| op[:op] == :add_constraint}
|
204
|
+
if ops.length > 1 && ops.all?{|op| op[:op] == :add_constraint || op[:op] == :set_column_null}
|
205
|
+
null_ops, ops = ops.partition{|op| op[:op] == :set_column_null}
|
206
|
+
|
207
|
+
# Apply NULL/NOT NULL ops first, since those should be purely idependent of the constraints.
|
208
|
+
null_ops.each{|op| alter_table_sql_list(table, [op]).flatten.each{|sql| execute_ddl(sql)}}
|
209
|
+
|
224
210
|
# If you are just doing constraints, apply all of them at the same time,
|
225
211
|
# as otherwise all but the last one get lost.
|
226
212
|
alter_table_sql_list(table, [{:op=>:add_constraints, :ops=>ops}]).flatten.each{|sql| execute_ddl(sql)}
|
@@ -230,8 +216,12 @@ module Sequel
|
|
230
216
|
ops.each{|op| alter_table_sql_list(table, [op]).flatten.each{|sql| execute_ddl(sql)}}
|
231
217
|
end
|
232
218
|
end
|
219
|
+
remove_cached_schema(table)
|
233
220
|
ensure
|
234
|
-
|
221
|
+
if fks
|
222
|
+
run "PRAGMA foreign_keys = 1"
|
223
|
+
run "PRAGMA legacy_alter_table = 0" if sqlite_version >= 32600
|
224
|
+
end
|
235
225
|
end
|
236
226
|
|
237
227
|
# SQLite supports limited table modification. You can add a column
|
@@ -249,11 +239,19 @@ module Sequel
|
|
249
239
|
super
|
250
240
|
end
|
251
241
|
when :drop_column
|
252
|
-
|
253
|
-
|
242
|
+
if sqlite_version >= 33500
|
243
|
+
super
|
244
|
+
else
|
245
|
+
ocp = lambda{|oc| oc.delete_if{|c| c.to_s == op[:name].to_s}}
|
246
|
+
duplicate_table(table, :old_columns_proc=>ocp){|columns| columns.delete_if{|s| s[:name].to_s == op[:name].to_s}}
|
247
|
+
end
|
254
248
|
when :rename_column
|
255
|
-
|
256
|
-
|
249
|
+
if sqlite_version >= 32500
|
250
|
+
super
|
251
|
+
else
|
252
|
+
ncp = lambda{|nc| nc.map!{|c| c.to_s == op[:name].to_s ? op[:new_name] : c}}
|
253
|
+
duplicate_table(table, :new_columns_proc=>ncp){|columns| columns.each{|s| s[:name] = op[:new_name] if s[:name].to_s == op[:name].to_s}}
|
254
|
+
end
|
257
255
|
when :set_column_default
|
258
256
|
duplicate_table(table){|columns| columns.each{|s| s[:default] = op[:default] if s[:name].to_s == op[:name].to_s}}
|
259
257
|
when :set_column_null
|
@@ -263,13 +261,20 @@ module Sequel
|
|
263
261
|
when :drop_constraint
|
264
262
|
case op[:type]
|
265
263
|
when :primary_key
|
266
|
-
duplicate_table(table)
|
264
|
+
duplicate_table(table) do |columns|
|
265
|
+
columns.each do |s|
|
266
|
+
s[:unique] = false if s[:primary_key]
|
267
|
+
s[:primary_key] = s[:auto_increment] = nil
|
268
|
+
end
|
269
|
+
end
|
267
270
|
when :foreign_key
|
268
271
|
if op[:columns]
|
269
272
|
duplicate_table(table, :skip_foreign_key_columns=>op[:columns])
|
270
273
|
else
|
271
274
|
duplicate_table(table, :no_foreign_keys=>true)
|
272
275
|
end
|
276
|
+
when :unique
|
277
|
+
duplicate_table(table, :no_unique=>true)
|
273
278
|
else
|
274
279
|
duplicate_table(table)
|
275
280
|
end
|
@@ -298,15 +303,21 @@ module Sequel
|
|
298
303
|
end
|
299
304
|
end
|
300
305
|
|
301
|
-
#
|
306
|
+
# SQLite allows adding primary key constraints on NULLABLE columns, but then
|
307
|
+
# does not enforce NOT NULL for such columns, so force setting the columns NOT NULL.
|
308
|
+
def can_add_primary_key_constraint_on_nullable_columns?
|
309
|
+
false
|
310
|
+
end
|
311
|
+
|
312
|
+
# Surround default with parens to appease SQLite. Add support for GENERATED ALWAYS AS.
|
302
313
|
def column_definition_default_sql(sql, column)
|
303
314
|
sql << " DEFAULT (#{literal(column[:default])})" if column.include?(:default)
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
315
|
+
if (generated = column[:generated_always_as])
|
316
|
+
if (generated_type = column[:generated_type]) && (generated_type == :stored || generated_type == :virtual)
|
317
|
+
generated_type = generated_type.to_s.upcase
|
318
|
+
end
|
319
|
+
sql << " GENERATED ALWAYS AS (#{literal(generated)}) #{generated_type}"
|
320
|
+
end
|
310
321
|
end
|
311
322
|
|
312
323
|
# Array of PRAGMA SQL statements based on the Database options that should be applied to
|
@@ -326,16 +337,22 @@ module Sequel
|
|
326
337
|
ps
|
327
338
|
end
|
328
339
|
|
340
|
+
# Support creating STRICT tables via :strict option
|
341
|
+
def create_table_sql(name, generator, options)
|
342
|
+
"#{super}#{' STRICT' if options[:strict]}"
|
343
|
+
end
|
344
|
+
|
329
345
|
# SQLite support creating temporary views.
|
330
346
|
def create_view_prefix_sql(name, options)
|
331
|
-
"CREATE #{'TEMPORARY 'if options[:temp]}VIEW #{quote_schema_table(name)}"
|
347
|
+
create_view_sql_append_columns("CREATE #{'TEMPORARY 'if options[:temp]}VIEW #{quote_schema_table(name)}", options[:columns])
|
332
348
|
end
|
333
349
|
|
334
350
|
DATABASE_ERROR_REGEXPS = {
|
335
351
|
/(is|are) not unique\z|PRIMARY KEY must be unique\z|UNIQUE constraint failed: .+\z/ => UniqueConstraintViolation,
|
336
352
|
/foreign key constraint failed\z/i => ForeignKeyConstraintViolation,
|
337
|
-
/\
|
353
|
+
/\A(SQLITE ERROR 275 \(CONSTRAINT_CHECK\) : )?CHECK constraint failed/ => CheckConstraintViolation,
|
338
354
|
/\A(SQLITE ERROR 19 \(CONSTRAINT\) : )?constraint failed\z/ => ConstraintViolation,
|
355
|
+
/\Acannot store [A-Z]+ value in [A-Z]+ column / => ConstraintViolation,
|
339
356
|
/may not be NULL\z|NOT NULL constraint failed: .+\z/ => NotNullConstraintViolation,
|
340
357
|
/\ASQLITE ERROR \d+ \(\) : CHECK constraint failed: / => CheckConstraintViolation
|
341
358
|
}.freeze
|
@@ -343,13 +360,32 @@ module Sequel
|
|
343
360
|
DATABASE_ERROR_REGEXPS
|
344
361
|
end
|
345
362
|
|
363
|
+
# Recognize SQLite error codes if the exception provides access to them.
|
364
|
+
def database_specific_error_class(exception, opts)
|
365
|
+
case sqlite_error_code(exception)
|
366
|
+
when 1299
|
367
|
+
NotNullConstraintViolation
|
368
|
+
when 1555, 2067, 2579
|
369
|
+
UniqueConstraintViolation
|
370
|
+
when 787
|
371
|
+
ForeignKeyConstraintViolation
|
372
|
+
when 275
|
373
|
+
CheckConstraintViolation
|
374
|
+
when 19
|
375
|
+
ConstraintViolation
|
376
|
+
when 517
|
377
|
+
SerializationFailure
|
378
|
+
else
|
379
|
+
super
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
346
383
|
# The array of column schema hashes for the current columns in the table
|
347
384
|
def defined_columns_for(table)
|
348
|
-
cols = parse_pragma(table,
|
385
|
+
cols = parse_pragma(table, OPTS)
|
349
386
|
cols.each do |c|
|
350
387
|
c[:default] = LiteralString.new(c[:default]) if c[:default]
|
351
388
|
c[:type] = c[:db_type]
|
352
|
-
c.delete(:auto_increment)
|
353
389
|
end
|
354
390
|
cols
|
355
391
|
end
|
@@ -363,7 +399,7 @@ module Sequel
|
|
363
399
|
old_columns = def_columns.map{|c| c[:name]}
|
364
400
|
opts[:old_columns_proc].call(old_columns) if opts[:old_columns_proc]
|
365
401
|
|
366
|
-
yield def_columns if
|
402
|
+
yield def_columns if defined?(yield)
|
367
403
|
|
368
404
|
constraints = (opts[:constraints] || []).dup
|
369
405
|
pks = []
|
@@ -395,14 +431,22 @@ module Sequel
|
|
395
431
|
|
396
432
|
# Determine unique constraints and make sure the new columns have them
|
397
433
|
unique_columns = []
|
398
|
-
|
399
|
-
|
434
|
+
skip_indexes = []
|
435
|
+
indexes(table, :only_autocreated=>true).each do |name, h|
|
436
|
+
skip_indexes << name
|
437
|
+
if h[:unique] && !opts[:no_unique]
|
438
|
+
if h[:columns].length == 1
|
439
|
+
unique_columns.concat(h[:columns])
|
440
|
+
elsif h[:columns].map(&:to_s) != pks
|
441
|
+
constraints << {:type=>:unique, :columns=>h[:columns]}
|
442
|
+
end
|
443
|
+
end
|
400
444
|
end
|
401
445
|
unique_columns -= pks
|
402
446
|
unless unique_columns.empty?
|
403
447
|
unique_columns.map!{|c| quote_identifier(c)}
|
404
448
|
def_columns.each do |c|
|
405
|
-
c[:unique] = true if unique_columns.include?(quote_identifier(c[:name]))
|
449
|
+
c[:unique] = true if unique_columns.include?(quote_identifier(c[:name])) && c[:unique] != false
|
406
450
|
end
|
407
451
|
end
|
408
452
|
|
@@ -419,6 +463,7 @@ module Sequel
|
|
419
463
|
"DROP TABLE #{bt}"
|
420
464
|
]
|
421
465
|
indexes(table).each do |name, h|
|
466
|
+
next if skip_indexes.include?(name)
|
422
467
|
if (h[:columns].map(&:to_s) - new_columns).empty?
|
423
468
|
a << alter_table_sql(table, h.merge(:op=>:add_index, :name=>name))
|
424
469
|
end
|
@@ -426,19 +471,9 @@ module Sequel
|
|
426
471
|
a
|
427
472
|
end
|
428
473
|
|
429
|
-
# SQLite folds unquoted identifiers to lowercase, so it shouldn't need to upcase identifiers on input.
|
430
|
-
def identifier_input_method_default
|
431
|
-
nil
|
432
|
-
end
|
433
|
-
|
434
|
-
# SQLite folds unquoted identifiers to lowercase, so it shouldn't need to upcase identifiers on output.
|
435
|
-
def identifier_output_method_default
|
436
|
-
nil
|
437
|
-
end
|
438
|
-
|
439
474
|
# Does the reverse of on_delete_clause, eg. converts strings like +'SET NULL'+
|
440
475
|
# to symbols +:set_null+.
|
441
|
-
def on_delete_sql_to_sym
|
476
|
+
def on_delete_sql_to_sym(str)
|
442
477
|
case str
|
443
478
|
when 'RESTRICT'
|
444
479
|
:restrict
|
@@ -455,18 +490,43 @@ module Sequel
|
|
455
490
|
|
456
491
|
# Parse the output of the table_info pragma
|
457
492
|
def parse_pragma(table_name, opts)
|
458
|
-
|
493
|
+
pks = 0
|
494
|
+
sch = _parse_pragma_ds(table_name, opts).map do |row|
|
495
|
+
if sqlite_version > 33100
|
496
|
+
# table_xinfo PRAGMA used, remove hidden columns
|
497
|
+
# that are not generated columns
|
498
|
+
if row[:generated] = (row.delete(:hidden) != 0)
|
499
|
+
next unless row[:type].end_with?(' GENERATED ALWAYS')
|
500
|
+
row[:type] = row[:type].sub(' GENERATED ALWAYS', '')
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
459
504
|
row.delete(:cid)
|
460
505
|
row[:allow_null] = row.delete(:notnull).to_i == 0
|
461
506
|
row[:default] = row.delete(:dflt_value)
|
462
507
|
row[:default] = nil if blank_object?(row[:default]) || row[:default] == 'NULL'
|
463
508
|
row[:db_type] = row.delete(:type)
|
464
509
|
if row[:primary_key] = row.delete(:pk).to_i > 0
|
510
|
+
pks += 1
|
511
|
+
# Guess that an integer primary key uses auto increment,
|
512
|
+
# since that is Sequel's default and SQLite does not provide
|
513
|
+
# a way to introspect whether it is actually autoincrementing.
|
465
514
|
row[:auto_increment] = row[:db_type].downcase == 'integer'
|
466
515
|
end
|
467
516
|
row[:type] = schema_column_type(row[:db_type])
|
468
517
|
row
|
469
518
|
end
|
519
|
+
|
520
|
+
sch.compact!
|
521
|
+
|
522
|
+
if pks > 1
|
523
|
+
# SQLite does not allow use of auto increment for tables
|
524
|
+
# with composite primary keys, so remove auto_increment
|
525
|
+
# if composite primary keys are detected.
|
526
|
+
sch.each{|r| r.delete(:auto_increment)}
|
527
|
+
end
|
528
|
+
|
529
|
+
sch
|
470
530
|
end
|
471
531
|
|
472
532
|
# SQLite supports schema parsing using the table_info PRAGMA, so
|
@@ -478,10 +538,15 @@ module Sequel
|
|
478
538
|
end
|
479
539
|
end
|
480
540
|
|
541
|
+
# Don't support SQLite error codes for exceptions by default.
|
542
|
+
def sqlite_error_code(exception)
|
543
|
+
nil
|
544
|
+
end
|
545
|
+
|
481
546
|
# Backbone of the tables and views support.
|
482
547
|
def tables_and_views(filter, opts)
|
483
548
|
m = output_identifier_meth
|
484
|
-
metadata_dataset.from(:sqlite_master).server(opts[:server]).
|
549
|
+
metadata_dataset.from(:sqlite_master).server(opts[:server]).where(filter).map{|r| m.call(r[:name])}
|
485
550
|
end
|
486
551
|
|
487
552
|
# SQLite only supports AUTOINCREMENT on integer columns, not
|
@@ -492,65 +557,76 @@ module Sequel
|
|
492
557
|
end
|
493
558
|
end
|
494
559
|
|
495
|
-
# Instance methods for datasets that connect to an SQLite database
|
496
560
|
module DatasetMethods
|
497
561
|
include Dataset::Replace
|
562
|
+
include UnmodifiedIdentifiers::DatasetMethods
|
563
|
+
|
564
|
+
# The allowed values for insert_conflict
|
565
|
+
INSERT_CONFLICT_RESOLUTIONS = %w'ROLLBACK ABORT FAIL IGNORE REPLACE'.each(&:freeze).freeze
|
498
566
|
|
499
|
-
CONSTANT_MAP = {:CURRENT_DATE=>"date(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIMESTAMP=>"datetime(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIME=>"time(CURRENT_TIMESTAMP, 'localtime')".freeze}
|
500
|
-
|
501
|
-
EXTRACT_MAP
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
EXTRACT_OPEN = "CAST(strftime(".freeze
|
508
|
-
EXTRACT_CLOSE = ') AS '.freeze
|
509
|
-
NUMERIC = 'NUMERIC'.freeze
|
510
|
-
INTEGER = 'INTEGER'.freeze
|
511
|
-
BACKTICK = '`'.freeze
|
512
|
-
BACKTICK_RE = /`/.freeze
|
513
|
-
DOUBLE_BACKTICK = '``'.freeze
|
514
|
-
BLOB_START = "X'".freeze
|
515
|
-
HSTAR = "H*".freeze
|
516
|
-
DATE_OPEN = "date(".freeze
|
517
|
-
DATETIME_OPEN = "datetime(".freeze
|
518
|
-
ONLY_OFFSET = " LIMIT -1 OFFSET ".freeze
|
519
|
-
OR = " OR ".freeze
|
520
|
-
|
521
|
-
Dataset.def_sql_method(self, :delete, [['if db.sqlite_version >= 30803', %w'with delete from where'], ["else", %w'delete from where']])
|
522
|
-
Dataset.def_sql_method(self, :insert, [['if db.sqlite_version >= 30803', %w'with insert conflict into columns values'], ["else", %w'insert conflict into columns values']])
|
523
|
-
Dataset.def_sql_method(self, :update, [['if db.sqlite_version >= 30803', %w'with update table set where'], ["else", %w'update table set where']])
|
567
|
+
CONSTANT_MAP = {:CURRENT_DATE=>"date(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIMESTAMP=>"datetime(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIME=>"time(CURRENT_TIMESTAMP, 'localtime')".freeze}.freeze
|
568
|
+
EXTRACT_MAP = {:year=>"'%Y'", :month=>"'%m'", :day=>"'%d'", :hour=>"'%H'", :minute=>"'%M'", :second=>"'%f'"}.freeze
|
569
|
+
EXTRACT_MAP.each_value(&:freeze)
|
570
|
+
|
571
|
+
Dataset.def_sql_method(self, :delete, [['if db.sqlite_version >= 33500', %w'with delete from where returning'], ['elsif db.sqlite_version >= 30803', %w'with delete from where'], ["else", %w'delete from where']])
|
572
|
+
Dataset.def_sql_method(self, :insert, [['if db.sqlite_version >= 33500', %w'with insert conflict into columns values on_conflict returning'], ['elsif db.sqlite_version >= 30803', %w'with insert conflict into columns values on_conflict'], ["else", %w'insert conflict into columns values']])
|
573
|
+
Dataset.def_sql_method(self, :select, [['if opts[:values]', %w'with values compounds'], ['else', %w'with select distinct columns from join where group having window compounds order limit lock']])
|
574
|
+
Dataset.def_sql_method(self, :update, [['if db.sqlite_version >= 33500', %w'with update table set from where returning'], ['elsif db.sqlite_version >= 33300', %w'with update table set from where'], ['elsif db.sqlite_version >= 30803', %w'with update table set where'], ["else", %w'update table set where']])
|
524
575
|
|
525
576
|
def cast_sql_append(sql, expr, type)
|
526
577
|
if type == Time or type == DateTime
|
527
|
-
sql <<
|
578
|
+
sql << "datetime("
|
528
579
|
literal_append(sql, expr)
|
529
|
-
sql <<
|
580
|
+
sql << ')'
|
530
581
|
elsif type == Date
|
531
|
-
sql <<
|
582
|
+
sql << "date("
|
532
583
|
literal_append(sql, expr)
|
533
|
-
sql <<
|
584
|
+
sql << ')'
|
534
585
|
else
|
535
586
|
super
|
536
587
|
end
|
537
588
|
end
|
538
589
|
|
539
590
|
# SQLite doesn't support a NOT LIKE b, you need to use NOT (a LIKE b).
|
540
|
-
# It doesn't support xor or the extract function natively, so those have to be emulated.
|
591
|
+
# It doesn't support xor, power, or the extract function natively, so those have to be emulated.
|
541
592
|
def complex_expression_sql_append(sql, op, args)
|
542
593
|
case op
|
543
594
|
when :"NOT LIKE", :"NOT ILIKE"
|
544
|
-
sql <<
|
595
|
+
sql << 'NOT '
|
545
596
|
complex_expression_sql_append(sql, (op == :"NOT ILIKE" ? :ILIKE : :LIKE), args)
|
546
597
|
when :^
|
547
598
|
complex_expression_arg_pairs_append(sql, args){|a, b| Sequel.lit(["((~(", " & ", ")) & (", " | ", "))"], a, b, a, b)}
|
599
|
+
when :**
|
600
|
+
unless (exp = args[1]).is_a?(Integer)
|
601
|
+
raise(Sequel::Error, "can only emulate exponentiation on SQLite if exponent is an integer, given #{exp.inspect}")
|
602
|
+
end
|
603
|
+
case exp
|
604
|
+
when 0
|
605
|
+
sql << '1'
|
606
|
+
else
|
607
|
+
sql << '('
|
608
|
+
arg = args[0]
|
609
|
+
if exp < 0
|
610
|
+
invert = true
|
611
|
+
exp = exp.abs
|
612
|
+
sql << '(1.0 / ('
|
613
|
+
end
|
614
|
+
(exp - 1).times do
|
615
|
+
literal_append(sql, arg)
|
616
|
+
sql << " * "
|
617
|
+
end
|
618
|
+
literal_append(sql, arg)
|
619
|
+
sql << ')'
|
620
|
+
if invert
|
621
|
+
sql << "))"
|
622
|
+
end
|
623
|
+
end
|
548
624
|
when :extract
|
549
|
-
part = args
|
625
|
+
part = args[0]
|
550
626
|
raise(Sequel::Error, "unsupported extract argument: #{part.inspect}") unless format = EXTRACT_MAP[part]
|
551
|
-
sql <<
|
552
|
-
literal_append(sql, args
|
553
|
-
sql <<
|
627
|
+
sql << "CAST(strftime(" << format << ', '
|
628
|
+
literal_append(sql, args[1])
|
629
|
+
sql << ') AS ' << (part == :second ? 'NUMERIC' : 'INTEGER') << ')'
|
554
630
|
else
|
555
631
|
super
|
556
632
|
end
|
@@ -559,7 +635,7 @@ module Sequel
|
|
559
635
|
# SQLite has CURRENT_TIMESTAMP and related constants in UTC instead
|
560
636
|
# of in localtime, so convert those constants to local time.
|
561
637
|
def constant_sql_append(sql, constant)
|
562
|
-
if c = CONSTANT_MAP[constant]
|
638
|
+
if (c = CONSTANT_MAP[constant]) && !db.current_timestamp_utc
|
563
639
|
sql << c
|
564
640
|
else
|
565
641
|
super
|
@@ -569,12 +645,12 @@ module Sequel
|
|
569
645
|
# SQLite performs a TRUNCATE style DELETE if no filter is specified.
|
570
646
|
# Since we want to always return the count of records, add a condition
|
571
647
|
# that is always true and then delete.
|
572
|
-
def delete
|
573
|
-
@opts[:where] ? super : where(1=>1).delete
|
648
|
+
def delete(&block)
|
649
|
+
@opts[:where] ? super : where(1=>1).delete(&block)
|
574
650
|
end
|
575
651
|
|
576
652
|
# Return an array of strings specifying a query explanation for a SELECT of the
|
577
|
-
# current dataset. Currently, the options are
|
653
|
+
# current dataset. Currently, the options are ignored, but it accepts options
|
578
654
|
# to be compatible with other adapters.
|
579
655
|
def explain(opts=nil)
|
580
656
|
# Load the PrettyTable class, needed for explain output
|
@@ -587,13 +663,28 @@ module Sequel
|
|
587
663
|
|
588
664
|
# HAVING requires GROUP BY on SQLite
|
589
665
|
def having(*cond)
|
590
|
-
raise(InvalidOperation, "Can only specify a HAVING clause on a grouped dataset")
|
666
|
+
raise(InvalidOperation, "Can only specify a HAVING clause on a grouped dataset") if !@opts[:group] && db.sqlite_version < 33900
|
591
667
|
super
|
592
668
|
end
|
593
669
|
|
670
|
+
# Support insert select for associations, so that the model code can use
|
671
|
+
# returning instead of a separate query.
|
672
|
+
def insert_select(*values)
|
673
|
+
return unless supports_insert_select?
|
674
|
+
# Handle case where query does not return a row
|
675
|
+
server?(:default).with_sql_first(insert_select_sql(*values)) || false
|
676
|
+
end
|
677
|
+
|
678
|
+
# The SQL to use for an insert_select, adds a RETURNING clause to the insert
|
679
|
+
# unless the RETURNING clause is already present.
|
680
|
+
def insert_select_sql(*values)
|
681
|
+
ds = opts[:returning] ? self : returning
|
682
|
+
ds.insert_sql(*values)
|
683
|
+
end
|
684
|
+
|
594
685
|
# SQLite uses the nonstandard ` (backtick) for quoting identifiers.
|
595
686
|
def quoted_identifier_append(sql, c)
|
596
|
-
sql <<
|
687
|
+
sql << '`' << c.to_s.gsub('`', '``') << '`'
|
597
688
|
end
|
598
689
|
|
599
690
|
# When a qualified column is selected on SQLite and the qualifier
|
@@ -613,36 +704,92 @@ module Sequel
|
|
613
704
|
# supports the following conflict resolution algoriths: ROLLBACK, ABORT,
|
614
705
|
# FAIL, IGNORE and REPLACE.
|
615
706
|
#
|
707
|
+
# On SQLite 3.24.0+, you can pass a hash to use an ON CONFLICT clause.
|
708
|
+
# With out :update option, uses ON CONFLICT DO NOTHING. Options:
|
709
|
+
#
|
710
|
+
# :conflict_where :: The index filter, when using a partial index to determine uniqueness.
|
711
|
+
# :target :: The column name or expression to handle uniqueness violations on.
|
712
|
+
# :update :: A hash of columns and values to set. Uses ON CONFLICT DO UPDATE.
|
713
|
+
# :update_where :: A WHERE condition to use for the update.
|
714
|
+
#
|
616
715
|
# Examples:
|
617
716
|
#
|
618
|
-
# DB[:table].insert_conflict.insert(:
|
717
|
+
# DB[:table].insert_conflict.insert(a: 1, b: 2)
|
619
718
|
# # INSERT OR IGNORE INTO TABLE (a, b) VALUES (1, 2)
|
620
719
|
#
|
621
|
-
# DB[:table].insert_conflict(:replace).insert(:
|
720
|
+
# DB[:table].insert_conflict(:replace).insert(a: 1, b: 2)
|
622
721
|
# # INSERT OR REPLACE INTO TABLE (a, b) VALUES (1, 2)
|
623
|
-
|
624
|
-
|
722
|
+
#
|
723
|
+
# DB[:table].insert_conflict({}).insert(a: 1, b: 2)
|
724
|
+
# # INSERT INTO TABLE (a, b) VALUES (1, 2)
|
725
|
+
# # ON CONFLICT DO NOTHING
|
726
|
+
#
|
727
|
+
# DB[:table].insert_conflict(target: :a).insert(a: 1, b: 2)
|
728
|
+
# # INSERT INTO TABLE (a, b) VALUES (1, 2)
|
729
|
+
# # ON CONFLICT (a) DO NOTHING
|
730
|
+
#
|
731
|
+
# DB[:table].insert_conflict(target: :a, conflict_where: {c: true}).insert(a: 1, b: 2)
|
732
|
+
# # INSERT INTO TABLE (a, b) VALUES (1, 2)
|
733
|
+
# # ON CONFLICT (a) WHERE (c IS TRUE) DO NOTHING
|
734
|
+
#
|
735
|
+
# DB[:table].insert_conflict(target: :a, update: {b: Sequel[:excluded][:b]}).insert(a: 1, b: 2)
|
736
|
+
# # INSERT INTO TABLE (a, b) VALUES (1, 2)
|
737
|
+
# # ON CONFLICT (a) DO UPDATE SET b = excluded.b
|
738
|
+
#
|
739
|
+
# DB[:table].insert_conflict(target: :a,
|
740
|
+
# update: {b: Sequel[:excluded][:b]}, update_where: {Sequel[:table][:status_id] => 1}).insert(a: 1, b: 2)
|
741
|
+
# # INSERT INTO TABLE (a, b) VALUES (1, 2)
|
742
|
+
# # ON CONFLICT (a) DO UPDATE SET b = excluded.b WHERE (table.status_id = 1)
|
743
|
+
def insert_conflict(opts = :ignore)
|
744
|
+
case opts
|
745
|
+
when Symbol, String
|
746
|
+
unless INSERT_CONFLICT_RESOLUTIONS.include?(opts.to_s.upcase)
|
747
|
+
raise Error, "Invalid symbol or string passed to Dataset#insert_conflict: #{opts.inspect}. The allowed values are: :rollback, :abort, :fail, :ignore, or :replace"
|
748
|
+
end
|
749
|
+
clone(:insert_conflict => opts)
|
750
|
+
when Hash
|
751
|
+
clone(:insert_on_conflict => opts)
|
752
|
+
else
|
753
|
+
raise Error, "Invalid value passed to Dataset#insert_conflict: #{opts.inspect}, should use a symbol or a hash"
|
754
|
+
end
|
625
755
|
end
|
626
756
|
|
627
757
|
# Ignore uniqueness/exclusion violations when inserting, using INSERT OR IGNORE.
|
628
758
|
# Exists mostly for compatibility to MySQL's insert_ignore. Example:
|
629
759
|
#
|
630
|
-
# DB[:table].insert_ignore.insert(:
|
760
|
+
# DB[:table].insert_ignore.insert(a: 1, b: 2)
|
631
761
|
# # INSERT OR IGNORE INTO TABLE (a, b) VALUES (1, 2)
|
632
762
|
def insert_ignore
|
633
763
|
insert_conflict(:ignore)
|
634
764
|
end
|
635
765
|
|
766
|
+
# Automatically add aliases to RETURNING values to work around SQLite bug.
|
767
|
+
def returning(*values)
|
768
|
+
return super if values.empty?
|
769
|
+
raise Error, "RETURNING is not supported on #{db.database_type}" unless supports_returning?(:insert)
|
770
|
+
clone(:returning=>_returning_values(values).freeze)
|
771
|
+
end
|
772
|
+
|
636
773
|
# SQLite 3.8.3+ supports common table expressions.
|
637
774
|
def supports_cte?(type=:select)
|
638
775
|
db.sqlite_version >= 30803
|
639
776
|
end
|
640
777
|
|
778
|
+
# SQLite supports CTEs in subqueries if it supports CTEs.
|
779
|
+
def supports_cte_in_subqueries?
|
780
|
+
supports_cte?
|
781
|
+
end
|
782
|
+
|
641
783
|
# SQLite does not support table aliases with column aliases
|
642
784
|
def supports_derived_column_lists?
|
643
785
|
false
|
644
786
|
end
|
645
787
|
|
788
|
+
# SQLite does not support deleting from a joined dataset
|
789
|
+
def supports_deleting_joins?
|
790
|
+
false
|
791
|
+
end
|
792
|
+
|
646
793
|
# SQLite does not support INTERSECT ALL or EXCEPT ALL
|
647
794
|
def supports_intersect_except_all?
|
648
795
|
false
|
@@ -653,11 +800,21 @@ module Sequel
|
|
653
800
|
false
|
654
801
|
end
|
655
802
|
|
803
|
+
# SQLite 3.33.0 supports modifying joined datasets
|
804
|
+
def supports_modifying_joins?
|
805
|
+
db.sqlite_version >= 33300
|
806
|
+
end
|
807
|
+
|
656
808
|
# SQLite does not support multiple columns for the IN/NOT IN operators
|
657
809
|
def supports_multiple_column_in?
|
658
810
|
false
|
659
811
|
end
|
660
812
|
|
813
|
+
# SQLite 3.35.0 supports RETURNING on INSERT/UPDATE/DELETE.
|
814
|
+
def supports_returning?(_)
|
815
|
+
db.sqlite_version >= 33500
|
816
|
+
end
|
817
|
+
|
661
818
|
# SQLite supports timezones in literal timestamps, since it stores them
|
662
819
|
# as text. But using timezones in timestamps breaks SQLite datetime
|
663
820
|
# functions, so we allow the user to override the default per database.
|
@@ -669,14 +826,47 @@ module Sequel
|
|
669
826
|
def supports_where_true?
|
670
827
|
false
|
671
828
|
end
|
829
|
+
|
830
|
+
# SQLite 3.28+ supports the WINDOW clause.
|
831
|
+
def supports_window_clause?
|
832
|
+
db.sqlite_version >= 32800
|
833
|
+
end
|
672
834
|
|
835
|
+
# SQLite 3.25+ supports window functions. However, support is only enabled
|
836
|
+
# on SQLite 3.26.0+ because internal Sequel usage of window functions
|
837
|
+
# to implement eager loading of limited associations triggers
|
838
|
+
# an SQLite crash bug in versions 3.25.0-3.25.3.
|
839
|
+
def supports_window_functions?
|
840
|
+
db.sqlite_version >= 32600
|
841
|
+
end
|
842
|
+
|
843
|
+
# SQLite 3.28.0+ supports all window frame options that Sequel supports
|
844
|
+
def supports_window_function_frame_option?(option)
|
845
|
+
db.sqlite_version >= 32800 ? true : super
|
846
|
+
end
|
847
|
+
|
673
848
|
private
|
674
849
|
|
850
|
+
# Add aliases to symbols and identifiers to work around SQLite bug.
|
851
|
+
def _returning_values(values)
|
852
|
+
values.map do |v|
|
853
|
+
case v
|
854
|
+
when Symbol
|
855
|
+
_, c, a = split_symbol(v)
|
856
|
+
a ? v : Sequel.as(v, c)
|
857
|
+
when SQL::Identifier, SQL::QualifiedIdentifier
|
858
|
+
Sequel.as(v, unqualified_column_for(v))
|
859
|
+
else
|
860
|
+
v
|
861
|
+
end
|
862
|
+
end
|
863
|
+
end
|
864
|
+
|
675
865
|
# SQLite uses string literals instead of identifiers in AS clauses.
|
676
866
|
def as_sql_append(sql, aliaz, column_aliases=nil)
|
677
867
|
raise Error, "sqlite does not support derived column lists" if column_aliases
|
678
868
|
aliaz = aliaz.value if aliaz.is_a?(SQL::Identifier)
|
679
|
-
sql << AS
|
869
|
+
sql << ' AS '
|
680
870
|
literal_append(sql, aliaz.to_s)
|
681
871
|
end
|
682
872
|
|
@@ -697,6 +887,13 @@ module Sequel
|
|
697
887
|
end
|
698
888
|
end
|
699
889
|
|
890
|
+
# Raise an InvalidOperation exception if insert is not allowed for this dataset.
|
891
|
+
def check_insert_allowed!
|
892
|
+
raise(InvalidOperation, "Grouped datasets cannot be modified") if opts[:group]
|
893
|
+
raise(InvalidOperation, "Joined datasets cannot be modified") if joined_dataset?
|
894
|
+
end
|
895
|
+
alias check_delete_allowed! check_insert_allowed!
|
896
|
+
|
700
897
|
# SQLite supports a maximum of 500 rows in a VALUES clause.
|
701
898
|
def default_import_slice
|
702
899
|
500
|
@@ -704,19 +901,49 @@ module Sequel
|
|
704
901
|
|
705
902
|
# SQL fragment specifying a list of identifiers
|
706
903
|
def identifier_list(columns)
|
707
|
-
columns.map{|i| quote_identifier(i)}.join(
|
904
|
+
columns.map{|i| quote_identifier(i)}.join(', ')
|
708
905
|
end
|
709
906
|
|
710
907
|
# Add OR clauses to SQLite INSERT statements
|
711
908
|
def insert_conflict_sql(sql)
|
712
909
|
if resolution = @opts[:insert_conflict]
|
713
|
-
sql << OR << resolution.to_s.upcase
|
910
|
+
sql << " OR " << resolution.to_s.upcase
|
911
|
+
end
|
912
|
+
end
|
913
|
+
|
914
|
+
# Add ON CONFLICT clause if it should be used
|
915
|
+
def insert_on_conflict_sql(sql)
|
916
|
+
if opts = @opts[:insert_on_conflict]
|
917
|
+
sql << " ON CONFLICT"
|
918
|
+
|
919
|
+
if target = opts[:constraint]
|
920
|
+
sql << " ON CONSTRAINT "
|
921
|
+
identifier_append(sql, target)
|
922
|
+
elsif target = opts[:target]
|
923
|
+
sql << ' '
|
924
|
+
identifier_append(sql, Array(target))
|
925
|
+
if conflict_where = opts[:conflict_where]
|
926
|
+
sql << " WHERE "
|
927
|
+
literal_append(sql, conflict_where)
|
928
|
+
end
|
929
|
+
end
|
930
|
+
|
931
|
+
if values = opts[:update]
|
932
|
+
sql << " DO UPDATE SET "
|
933
|
+
update_sql_values_hash(sql, values)
|
934
|
+
if update_where = opts[:update_where]
|
935
|
+
sql << " WHERE "
|
936
|
+
literal_append(sql, update_where)
|
937
|
+
end
|
938
|
+
else
|
939
|
+
sql << " DO NOTHING"
|
940
|
+
end
|
714
941
|
end
|
715
942
|
end
|
716
943
|
|
717
944
|
# SQLite uses a preceding X for hex escaping strings
|
718
945
|
def literal_blob_append(sql, v)
|
719
|
-
sql <<
|
946
|
+
sql << "X'" << v.unpack("H*").first << "'"
|
720
947
|
end
|
721
948
|
|
722
949
|
# Respect the database integer_booleans setting, using 0 or 'f'.
|
@@ -735,6 +962,20 @@ module Sequel
|
|
735
962
|
db.sqlite_version >= 30711 ? :values : :union
|
736
963
|
end
|
737
964
|
|
965
|
+
# Emulate the char_length function with length
|
966
|
+
def native_function_name(emulated_function)
|
967
|
+
if emulated_function == :char_length
|
968
|
+
'length'
|
969
|
+
else
|
970
|
+
super
|
971
|
+
end
|
972
|
+
end
|
973
|
+
|
974
|
+
# SQLite supports NULLS FIRST/LAST natively in 3.30+.
|
975
|
+
def requires_emulating_nulls_first?
|
976
|
+
db.sqlite_version < 33000
|
977
|
+
end
|
978
|
+
|
738
979
|
# SQLite does not support FOR UPDATE, but silently ignore it
|
739
980
|
# instead of raising an error for compatibility with other
|
740
981
|
# databases.
|
@@ -743,10 +984,26 @@ module Sequel
|
|
743
984
|
end
|
744
985
|
|
745
986
|
def select_only_offset_sql(sql)
|
746
|
-
sql <<
|
987
|
+
sql << " LIMIT -1 OFFSET "
|
747
988
|
literal_append(sql, @opts[:offset])
|
748
989
|
end
|
749
990
|
|
991
|
+
# Support VALUES clause instead of the SELECT clause to return rows.
|
992
|
+
def select_values_sql(sql)
|
993
|
+
sql << "VALUES "
|
994
|
+
expression_list_append(sql, opts[:values])
|
995
|
+
end
|
996
|
+
|
997
|
+
# SQLite does not support CTEs directly inside UNION/INTERSECT/EXCEPT.
|
998
|
+
def supports_cte_in_compounds?
|
999
|
+
false
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
# SQLite 3.30 supports the FILTER clause for aggregate functions.
|
1003
|
+
def supports_filtered_aggregates?
|
1004
|
+
db.sqlite_version >= 33000
|
1005
|
+
end
|
1006
|
+
|
750
1007
|
# SQLite supports quoted function names.
|
751
1008
|
def supports_quoted_function_names?
|
752
1009
|
true
|
@@ -756,6 +1013,23 @@ module Sequel
|
|
756
1013
|
def _truncate_sql(table)
|
757
1014
|
"DELETE FROM #{table}"
|
758
1015
|
end
|
1016
|
+
|
1017
|
+
# Use FROM to specify additional tables in an update query
|
1018
|
+
def update_from_sql(sql)
|
1019
|
+
if(from = @opts[:from][1..-1]).empty?
|
1020
|
+
raise(Error, 'Need multiple FROM tables if updating/deleting a dataset with JOINs') if @opts[:join]
|
1021
|
+
else
|
1022
|
+
sql << ' FROM '
|
1023
|
+
source_list_append(sql, from)
|
1024
|
+
select_join_sql(sql)
|
1025
|
+
end
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
# Only include the primary table in the main update clause
|
1029
|
+
def update_table_sql(sql)
|
1030
|
+
sql << ' '
|
1031
|
+
source_list_append(sql, @opts[:from][0..0])
|
1032
|
+
end
|
759
1033
|
end
|
760
1034
|
end
|
761
1035
|
end
|