class Sequel::SQLite::Database
Attributes
The conversion procs to use for this database
Public Class Methods
Source
# File lib/sequel/adapters/sqlite.rb 101 def initialize(opts = OPTS) 102 super 103 @allow_regexp = typecast_value_boolean(opts[:setup_regexp_function]) 104 end
Sequel::Database::new
Public Instance Methods
Source
Source
# File lib/sequel/adapters/sqlite.rb 128 def connect(server) 129 opts = server_opts(server) 130 opts[:database] = ':memory:' if blank_object?(opts[:database]) 131 sqlite3_opts = {} 132 sqlite3_opts[:readonly] = typecast_value_boolean(opts[:readonly]) if opts.has_key?(:readonly) 133 # SEQUEL6: Make strict: true the default behavior 134 sqlite3_opts[:strict] = typecast_value_boolean(opts[:disable_dqs]) if opts.has_key?(:disable_dqs) 135 db = ::SQLite3::Database.new(opts[:database].to_s, sqlite3_opts) 136 db.busy_timeout(typecast_value_integer(opts.fetch(:timeout, 5000))) 137 138 if USE_EXTENDED_RESULT_CODES 139 db.extended_result_codes = true 140 end 141 142 connection_pragmas.each{|s| log_connection_yield(s, db){db.execute_batch(s)}} 143 144 if typecast_value_boolean(opts[:setup_regexp_function]) 145 setup_regexp_function(db, opts[:setup_regexp_function]) 146 end 147 148 class << db 149 attr_reader :prepared_statements 150 end 151 db.instance_variable_set(:@prepared_statements, {}) 152 153 db 154 end
Connect to the database. Since SQLite
is a file based database, available options are limited:
- :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
'REGEXP' operator. If the value is :cached or "cached", caches the generated regexps, which can result in a memory leak if dynamic regexps are used. If the value is a Proc, it will be called with a string for the regexp and a string for the value to compare, and should return whether the regexp matches.
- :regexp_function_cache
-
If setting
setup_regexp_function
tocached
, this
determines the cache to use. It should either be a proc or a class, and it defaults to +Hash+. You can use +ObjectSpace::WeakKeyMap+ on Ruby 3.3+ to have the VM automatically remove regexps from the cache after they are no longer used.
Source
# File lib/sequel/adapters/sqlite.rb 163 def disconnect_connection(c) 164 c.prepared_statements.each_value{|v| v.first.close} 165 c.close 166 end
Disconnect given connections from the database.
Source
# File lib/sequel/adapters/sqlite.rb 169 def execute(sql, opts=OPTS, &block) 170 _execute(:select, sql, opts, &block) 171 end
Run the given SQL
with the given arguments and yield each row.
Source
# File lib/sequel/adapters/sqlite.rb 181 def execute_ddl(sql, opts=OPTS) 182 synchronize(opts[:server]) do |conn| 183 conn.prepared_statements.values.each{|cps, s| cps.close} 184 conn.prepared_statements.clear 185 super 186 end 187 end
Drop any prepared statements on the connection when executing DDL. This is because prepared statements lock the table in such a way that you can’t drop or alter the table while a prepared statement that references it still exists.
Sequel::Database#execute_ddl
Source
# File lib/sequel/adapters/sqlite.rb 174 def execute_dui(sql, opts=OPTS) 175 _execute(:update, sql, opts) 176 end
Run the given SQL
with the given arguments and return the number of changed rows.
Source
# File lib/sequel/adapters/sqlite.rb 189 def execute_insert(sql, opts=OPTS) 190 _execute(:insert, sql, opts) 191 end
Source
# File lib/sequel/adapters/sqlite.rb 193 def freeze 194 @conversion_procs.freeze 195 super 196 end
Sequel::SQLite::DatabaseMethods#freeze
Source
# File lib/sequel/adapters/sqlite.rb 199 def to_application_timestamp(s) 200 case s 201 when String 202 super 203 when Integer 204 super(Time.at(s).to_s) 205 when Float 206 super(DateTime.jd(s).to_s) 207 else 208 raise Sequel::Error, "unhandled type when converting to : #{s.inspect} (#{s.class.inspect})" 209 end 210 end
Handle Integer and Float arguments, since SQLite
can store timestamps as integers and floats.
Sequel::Database#to_application_timestamp
Private Instance Methods
Source
# File lib/sequel/adapters/sqlite.rb 251 def _execute(type, sql, opts, &block) 252 synchronize(opts[:server]) do |conn| 253 return execute_prepared_statement(conn, type, sql, opts, &block) if sql.is_a?(Symbol) 254 log_args = opts[:arguments] 255 args = {} 256 opts.fetch(:arguments, OPTS).each{|k, v| args[k] = prepared_statement_argument(v)} 257 case type 258 when :select 259 log_connection_yield(sql, conn, log_args){conn.query(sql, args, &block)} 260 when :insert 261 log_connection_yield(sql, conn, log_args){conn.execute(sql, args)} 262 conn.last_insert_row_id 263 when :update 264 log_connection_yield(sql, conn, log_args){conn.execute_batch(sql, args)} 265 conn.changes 266 end 267 end 268 rescue SQLite3::Exception => e 269 raise_error(e) 270 end
Yield an available connection. Rescue any SQLite3::Exceptions and turn them into DatabaseErrors.
Source
# File lib/sequel/adapters/sqlite.rb 214 def adapter_initialize 215 @conversion_procs = SQLITE_TYPES.dup 216 @conversion_procs['datetime'] = @conversion_procs['timestamp'] = method(:to_application_timestamp) 217 set_integer_booleans 218 end
Source
# File lib/sequel/adapters/sqlite.rb 275 def connection_pool_default_options 276 o = super.dup 277 # Default to only a single connection if a memory database is used, 278 # because otherwise each connection will get a separate database 279 o[:max_connections] = 1 if @opts[:database] == ':memory:' || blank_object?(@opts[:database]) 280 o 281 end
The SQLite
adapter does not need the pool to convert exceptions. Also, force the max connections to 1 if a memory database is being used, as otherwise each connection gets a separate database.
Sequel::Database#connection_pool_default_options
Source
# File lib/sequel/adapters/sqlite.rb 340 def database_error_classes 341 [SQLite3::Exception, ArgumentError] 342 end
SQLite3 raises ArgumentError in addition to SQLite3::Exception in some cases, such as operations on a closed database.
Source
# File lib/sequel/adapters/sqlite.rb 344 def dataset_class_default 345 Dataset 346 end
Source
# File lib/sequel/adapters/sqlite.rb 301 def execute_prepared_statement(conn, type, name, opts, &block) 302 ps = prepared_statement(name) 303 sql = ps.prepared_sql 304 args = opts[:arguments] 305 ps_args = {} 306 args.each{|k, v| ps_args[k] = prepared_statement_argument(v)} 307 if cpsa = conn.prepared_statements[name] 308 cps, cps_sql = cpsa 309 if cps_sql != sql 310 cps.close 311 cps = nil 312 end 313 end 314 unless cps 315 cps = log_connection_yield("PREPARE #{name}: #{sql}", conn){conn.prepare(sql)} 316 conn.prepared_statements[name] = [cps, sql] 317 end 318 log_sql = String.new 319 log_sql << "EXECUTE #{name}" 320 if ps.log_sql 321 log_sql << " (" 322 log_sql << sql 323 log_sql << ")" 324 end 325 if block 326 log_connection_yield(log_sql, conn, args){cps.execute(ps_args, &block)} 327 else 328 log_connection_yield(log_sql, conn, args){cps.execute!(ps_args){|r|}} 329 case type 330 when :insert 331 conn.last_insert_row_id 332 when :update 333 conn.changes 334 end 335 end 336 end
Execute a prepared statement on the database using the given name.
Source
# File lib/sequel/adapters/sqlite.rb 283 def prepared_statement_argument(arg) 284 case arg 285 when Date, DateTime, Time 286 literal(arg)[1...-1] 287 when SQL::Blob 288 arg.to_blob 289 when true, false 290 if integer_booleans 291 arg ? 1 : 0 292 else 293 literal(arg)[1...-1] 294 end 295 else 296 arg 297 end 298 end
Source
# File lib/sequel/adapters/sqlite.rb 220 def setup_regexp_function(db, how) 221 case how 222 when Proc 223 # nothing 224 when :cached, "cached" 225 cache = @opts[:regexp_function_cache] || Hash 226 cache = cache.is_a?(Proc) ? cache.call : cache.new 227 how = if RUBY_VERSION >= '2.4' 228 lambda do |regexp_str, str| 229 (cache[regexp_str] ||= Regexp.new(regexp_str)).match?(str) 230 end 231 else 232 lambda do |regexp_str, str| 233 (cache[regexp_str] ||= Regexp.new(regexp_str)).match(str) 234 end 235 end 236 else 237 how = if RUBY_VERSION >= '2.4' 238 lambda{|regexp_str, str| Regexp.new(regexp_str).match?(str)} 239 else 240 lambda{|regexp_str, str| Regexp.new(regexp_str).match(str)} 241 end 242 end 243 244 db.create_function("regexp", 2) do |func, regexp_str, str| 245 func.result = how.call(regexp_str, str) ? 1 : 0 246 end 247 end
Source
# File lib/sequel/adapters/sqlite.rb 350 def sqlite_error_code(exception) 351 exception.code if exception.respond_to?(:code) 352 end
Support SQLite
exception codes if ruby-sqlite3 supports them.