From 8e5a8a92cadfa36ebec01c70340ef8e8ee1feff6 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Sun, 27 Oct 2024 20:46:19 -0700 Subject: [PATCH] Support the :disable_dqs Database option in the sqlite adapter to disable treating double quoted values as strings As described by the SQLite documentation, treating double quoted values as strings instead of identifiers is a misfeature. Unfortunately, the sqlite3 gem implements this using a :strict option, which is poorly named, as you would think it would have something to do with STRICT tables and it does not. Considering SQLite already supported STRICT for tables before the sqlite3 gem added support for the :strict option, I'm not sure why the option name was selected. Use :disable_dqs as the name of this option in Sequel, following the SQLite naming of the config options. This currently does not default to true for backwards compatibility, but I expect to change that in Sequel 6. --- CHANGELOG | 2 ++ doc/opening_databases.rdoc | 2 ++ lib/sequel/adapters/sqlite.rb | 4 ++++ spec/adapters/sqlite_spec.rb | 8 ++++++++ 4 files changed, 16 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 998e94c16..d6b3445e7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ === master +* Support the :disable_dqs Database option in the sqlite adapter to disable treating double quoted values as strings (jeremyevans) (#2233) + * Have the subset_conditions plugin support where_all and where_any methods to combine existing subsets with AND or OR (jeremyevans) * Have the subset_conditions plugin add *_conditions methods for exclude method calls in addition to where and subset (jeremyevans) diff --git a/doc/opening_databases.rdoc b/doc/opening_databases.rdoc index 231a072e4..2c57391fc 100644 --- a/doc/opening_databases.rdoc +++ b/doc/opening_databases.rdoc @@ -390,6 +390,8 @@ Examples: The following additional options are supported: +:disable_dqs :: Disable treating double quoted values as strings in DDL and DML statements + (requires SQLite 3.29.0+ and sqlite3 gem version 1.4.3+). :readonly :: open database in read-only mode :timeout :: the busy timeout to use in milliseconds (default: 5000). :setup_regexp_function :: Whether to setup a REGEXP function in the underlying SQLite3::Database object. Doing so diff --git a/lib/sequel/adapters/sqlite.rb b/lib/sequel/adapters/sqlite.rb index 1d479418e..1c619d5f9 100644 --- a/lib/sequel/adapters/sqlite.rb +++ b/lib/sequel/adapters/sqlite.rb @@ -109,6 +109,8 @@ def initialize(opts = OPTS) # :database :: database name (filename or ':memory:' or file: URI) # :readonly :: open database in read-only mode; useful for reading # static data that you do not want to modify + # :disable_dqs :: disable double quoted strings in DDL and DML statements + # (requires SQLite 3.29.0+ and sqlite3 gem version 1.4.3+). # :timeout :: how long to wait for the database to be available if it # is locked, given in milliseconds (default is 5000) # :setup_regexp_function :: enable use of Regexp objects with SQL @@ -128,6 +130,8 @@ def connect(server) opts[:database] = ':memory:' if blank_object?(opts[:database]) sqlite3_opts = {} sqlite3_opts[:readonly] = typecast_value_boolean(opts[:readonly]) if opts.has_key?(:readonly) + # SEQUEL6: Make strict: true the default behavior + sqlite3_opts[:strict] = typecast_value_boolean(opts[:disable_dqs]) if opts.has_key?(:disable_dqs) db = ::SQLite3::Database.new(opts[:database].to_s, sqlite3_opts) db.busy_timeout(typecast_value_integer(opts.fetch(:timeout, 5000))) diff --git a/spec/adapters/sqlite_spec.rb b/spec/adapters/sqlite_spec.rb index 1258121db..40b2f4e36 100644 --- a/spec/adapters/sqlite_spec.rb +++ b/spec/adapters/sqlite_spec.rb @@ -29,6 +29,14 @@ @db.sqlite_version.must_be_kind_of(Integer) end + it "should provide the SQLite version as an integer" do + db = Sequel.sqlite + db['SELECT "1" as a'].get.must_equal '1' + + db = Sequel.connect('sqlite://?disable_dqs=t') + proc{db['SELECT "1" as a'].get}.must_raise Sequel::DatabaseError + end if defined?(SQLite3::VERSION) && SQLite3::VERSION >= '1.4.3' && DB.sqlite_version >= 32900 + it "should support creating virtual tables via the create_table :using option" do if @db['PRAGMA compile_options'].map(:compile_options).include?('ENABLE_FTS5') @db.create_table(:fk, using: 'fts5(c)')