class Sequel::SQLite::Database

Attributes

conversion_procs[R]

The conversion procs to use for this database

Public Class Methods

new(opts = OPTS) click to toggle source
Calls superclass method Sequel::Database::new
    # 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

Public Instance Methods

allow_regexp?() click to toggle source

Whether this Database instance is setup to allow regexp matching. True if the :setup_regexp_function option was passed when creating the Database.

    # File lib/sequel/adapters/sqlite.rb
149 def allow_regexp?
150   @allow_regexp
151 end
connect(server) click to toggle source

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

: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.
    # File lib/sequel/adapters/sqlite.rb
121 def connect(server)
122   opts = server_opts(server)
123   opts[:database] = ':memory:' if blank_object?(opts[:database])
124   sqlite3_opts = {}
125   sqlite3_opts[:readonly] = typecast_value_boolean(opts[:readonly]) if opts.has_key?(:readonly)
126   db = ::SQLite3::Database.new(opts[:database].to_s, sqlite3_opts)
127   db.busy_timeout(typecast_value_integer(opts.fetch(:timeout, 5000)))
128 
129   if USE_EXTENDED_RESULT_CODES
130     db.extended_result_codes = true
131   end
132   
133   connection_pragmas.each{|s| log_connection_yield(s, db){db.execute_batch(s)}}
134 
135   if typecast_value_boolean(opts[:setup_regexp_function])
136     setup_regexp_function(db, opts[:setup_regexp_function])
137   end
138   
139   class << db
140     attr_reader :prepared_statements
141   end
142   db.instance_variable_set(:@prepared_statements, {})
143   
144   db
145 end
disconnect_connection(c) click to toggle source

Disconnect given connections from the database.

    # File lib/sequel/adapters/sqlite.rb
154 def disconnect_connection(c)
155   c.prepared_statements.each_value{|v| v.first.close}
156   c.close
157 end
execute(sql, opts=OPTS, &block) click to toggle source

Run the given SQL with the given arguments and yield each row.

    # File lib/sequel/adapters/sqlite.rb
160 def execute(sql, opts=OPTS, &block)
161   _execute(:select, sql, opts, &block)
162 end
execute_ddl(sql, opts=OPTS) click to toggle source

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.

Calls superclass method Sequel::Database#execute_ddl
    # File lib/sequel/adapters/sqlite.rb
172 def execute_ddl(sql, opts=OPTS)
173   synchronize(opts[:server]) do |conn|
174     conn.prepared_statements.values.each{|cps, s| cps.close}
175     conn.prepared_statements.clear
176     super
177   end
178 end
execute_dui(sql, opts=OPTS) click to toggle source

Run the given SQL with the given arguments and return the number of changed rows.

    # File lib/sequel/adapters/sqlite.rb
165 def execute_dui(sql, opts=OPTS)
166   _execute(:update, sql, opts)
167 end
execute_insert(sql, opts=OPTS) click to toggle source
    # File lib/sequel/adapters/sqlite.rb
180 def execute_insert(sql, opts=OPTS)
181   _execute(:insert, sql, opts)
182 end
freeze() click to toggle source
Calls superclass method Sequel::SQLite::DatabaseMethods#freeze
    # File lib/sequel/adapters/sqlite.rb
184 def freeze
185   @conversion_procs.freeze
186   super
187 end
to_application_timestamp(s) click to toggle source

Handle Integer and Float arguments, since SQLite can store timestamps as integers and floats.

    # File lib/sequel/adapters/sqlite.rb
190 def to_application_timestamp(s)
191   case s
192   when String
193     super
194   when Integer
195     super(Time.at(s).to_s)
196   when Float
197     super(DateTime.jd(s).to_s)
198   else
199     raise Sequel::Error, "unhandled type when converting to : #{s.inspect} (#{s.class.inspect})"
200   end
201 end

Private Instance Methods

_execute(type, sql, opts, &block) click to toggle source

Yield an available connection. Rescue any SQLite3::Exceptions and turn them into DatabaseErrors.

    # File lib/sequel/adapters/sqlite.rb
229 def _execute(type, sql, opts, &block)
230   synchronize(opts[:server]) do |conn|
231     return execute_prepared_statement(conn, type, sql, opts, &block) if sql.is_a?(Symbol)
232     log_args = opts[:arguments]
233     args = {}
234     opts.fetch(:arguments, OPTS).each{|k, v| args[k] = prepared_statement_argument(v)}
235     case type
236     when :select
237       log_connection_yield(sql, conn, log_args){conn.query(sql, args, &block)}
238     when :insert
239       log_connection_yield(sql, conn, log_args){conn.execute(sql, args)}
240       conn.last_insert_row_id
241     when :update
242       log_connection_yield(sql, conn, log_args){conn.execute_batch(sql, args)}
243       conn.changes
244     end
245   end
246 rescue SQLite3::Exception => e
247   raise_error(e)
248 end
adapter_initialize() click to toggle source
    # File lib/sequel/adapters/sqlite.rb
205 def adapter_initialize
206   @conversion_procs = SQLITE_TYPES.dup
207   @conversion_procs['datetime'] = @conversion_procs['timestamp'] = method(:to_application_timestamp)
208   set_integer_booleans
209 end
connection_pool_default_options() click to toggle source

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.

    # File lib/sequel/adapters/sqlite.rb
253 def connection_pool_default_options
254   o = super.dup
255   # Default to only a single connection if a memory database is used,
256   # because otherwise each connection will get a separate database
257   o[:max_connections] = 1 if @opts[:database] == ':memory:' || blank_object?(@opts[:database])
258   o
259 end
database_error_classes() click to toggle source

SQLite3 raises ArgumentError in addition to SQLite3::Exception in some cases, such as operations on a closed database.

    # File lib/sequel/adapters/sqlite.rb
318 def database_error_classes
319   [SQLite3::Exception, ArgumentError]
320 end
dataset_class_default() click to toggle source
    # File lib/sequel/adapters/sqlite.rb
322 def dataset_class_default
323   Dataset
324 end
execute_prepared_statement(conn, type, name, opts, &block) click to toggle source

Execute a prepared statement on the database using the given name.

    # File lib/sequel/adapters/sqlite.rb
279 def execute_prepared_statement(conn, type, name, opts, &block)
280   ps = prepared_statement(name)
281   sql = ps.prepared_sql
282   args = opts[:arguments]
283   ps_args = {}
284   args.each{|k, v| ps_args[k] = prepared_statement_argument(v)}
285   if cpsa = conn.prepared_statements[name]
286     cps, cps_sql = cpsa
287     if cps_sql != sql
288       cps.close
289       cps = nil
290     end
291   end
292   unless cps
293     cps = log_connection_yield("PREPARE #{name}: #{sql}", conn){conn.prepare(sql)}
294     conn.prepared_statements[name] = [cps, sql]
295   end
296   log_sql = String.new
297   log_sql << "EXECUTE #{name}"
298   if ps.log_sql
299     log_sql << " ("
300     log_sql << sql
301     log_sql << ")"
302   end
303   if block
304     log_connection_yield(log_sql, conn, args){cps.execute(ps_args, &block)}
305   else
306     log_connection_yield(log_sql, conn, args){cps.execute!(ps_args){|r|}}
307     case type
308     when :insert
309       conn.last_insert_row_id
310     when :update
311       conn.changes
312     end
313   end
314 end
prepared_statement_argument(arg) click to toggle source
    # File lib/sequel/adapters/sqlite.rb
261 def prepared_statement_argument(arg)
262   case arg
263   when Date, DateTime, Time
264     literal(arg)[1...-1]
265   when SQL::Blob
266     arg.to_blob
267   when true, false
268     if integer_booleans
269       arg ? 1 : 0
270     else
271       literal(arg)[1...-1]
272     end
273   else
274     arg
275   end
276 end
setup_regexp_function(db, how) click to toggle source
    # File lib/sequel/adapters/sqlite.rb
211 def setup_regexp_function(db, how)
212   case how
213   when Proc
214     # nothing
215   when :cached, "cached"
216     cache = Hash.new{|h,k| h[k] = Regexp.new(k)}
217     how = lambda{|regexp_str, str| cache[regexp_str].match(str)}
218   else
219     how = lambda{|regexp_str, str| Regexp.new(regexp_str).match(str)}
220   end
221 
222   db.create_function("regexp", 2) do |func, regexp_str, str|
223     func.result = how.call(regexp_str, str) ? 1 : 0
224   end
225 end
sqlite_error_code(exception) click to toggle source

Support SQLite exception codes if ruby-sqlite3 supports them.

    # File lib/sequel/adapters/sqlite.rb
328 def sqlite_error_code(exception)
329   exception.code if exception.respond_to?(:code)
330 end