class Sequel::SQLite::Database
Attributes
The conversion procs to use for this database
Public Instance Methods
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)
# File lib/sequel/adapters/sqlite.rb 100 def connect(server) 101 opts = server_opts(server) 102 opts[:database] = ':memory:' if blank_object?(opts[:database]) 103 sqlite3_opts = {} 104 sqlite3_opts[:readonly] = typecast_value_boolean(opts[:readonly]) if opts.has_key?(:readonly) 105 db = ::SQLite3::Database.new(opts[:database].to_s, sqlite3_opts) 106 db.busy_timeout(opts.fetch(:timeout, 5000)) 107 108 connection_pragmas.each{|s| log_connection_yield(s, db){db.execute_batch(s)}} 109 110 class << db 111 attr_reader :prepared_statements 112 end 113 db.instance_variable_set(:@prepared_statements, {}) 114 115 db 116 end
Disconnect given connections from the database.
# File lib/sequel/adapters/sqlite.rb 119 def disconnect_connection(c) 120 c.prepared_statements.each_value{|v| v.first.close} 121 c.close 122 end
Run the given SQL
with the given arguments and yield each row.
# File lib/sequel/adapters/sqlite.rb 125 def execute(sql, opts=OPTS, &block) 126 _execute(:select, sql, opts, &block) 127 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
# File lib/sequel/adapters/sqlite.rb 137 def execute_ddl(sql, opts=OPTS) 138 synchronize(opts[:server]) do |conn| 139 conn.prepared_statements.values.each{|cps, s| cps.close} 140 conn.prepared_statements.clear 141 super 142 end 143 end
Run the given SQL
with the given arguments and return the number of changed rows.
# File lib/sequel/adapters/sqlite.rb 130 def execute_dui(sql, opts=OPTS) 131 _execute(:update, sql, opts) 132 end
# File lib/sequel/adapters/sqlite.rb 145 def execute_insert(sql, opts=OPTS) 146 _execute(:insert, sql, opts) 147 end
Sequel::SQLite::DatabaseMethods#freeze
# File lib/sequel/adapters/sqlite.rb 149 def freeze 150 @conversion_procs.freeze 151 super 152 end
Handle Integer and Float arguments, since SQLite
can store timestamps as integers and floats.
Sequel::Database#to_application_timestamp
# File lib/sequel/adapters/sqlite.rb 155 def to_application_timestamp(s) 156 case s 157 when String 158 super 159 when Integer 160 super(Time.at(s).to_s) 161 when Float 162 super(DateTime.jd(s).to_s) 163 else 164 raise Sequel::Error, "unhandled type when converting to : #{s.inspect} (#{s.class.inspect})" 165 end 166 end
Private Instance Methods
Yield an available connection. Rescue any SQLite3::Exceptions and turn them into DatabaseErrors.
# File lib/sequel/adapters/sqlite.rb 178 def _execute(type, sql, opts, &block) 179 begin 180 synchronize(opts[:server]) do |conn| 181 return execute_prepared_statement(conn, type, sql, opts, &block) if sql.is_a?(Symbol) 182 log_args = opts[:arguments] 183 args = {} 184 opts.fetch(:arguments, OPTS).each{|k, v| args[k] = prepared_statement_argument(v)} 185 case type 186 when :select 187 log_connection_yield(sql, conn, log_args){conn.query(sql, args, &block)} 188 when :insert 189 log_connection_yield(sql, conn, log_args){conn.execute(sql, args)} 190 conn.last_insert_row_id 191 when :update 192 log_connection_yield(sql, conn, log_args){conn.execute_batch(sql, args)} 193 conn.changes 194 end 195 end 196 rescue SQLite3::Exception => e 197 raise_error(e) 198 end 199 end
# File lib/sequel/adapters/sqlite.rb 170 def adapter_initialize 171 @conversion_procs = SQLITE_TYPES.dup 172 @conversion_procs['datetime'] = @conversion_procs['timestamp'] = method(:to_application_timestamp) 173 set_integer_booleans 174 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
# File lib/sequel/adapters/sqlite.rb 204 def connection_pool_default_options 205 o = super.dup 206 # Default to only a single connection if a memory database is used, 207 # because otherwise each connection will get a separate database 208 o[:max_connections] = 1 if @opts[:database] == ':memory:' || blank_object?(@opts[:database]) 209 o 210 end
SQLite3 raises ArgumentError in addition to SQLite3::Exception in some cases, such as operations on a closed database.
# File lib/sequel/adapters/sqlite.rb 269 def database_error_classes 270 [SQLite3::Exception, ArgumentError] 271 end
# File lib/sequel/adapters/sqlite.rb 273 def dataset_class_default 274 Dataset 275 end
Execute a prepared statement on the database using the given name.
# File lib/sequel/adapters/sqlite.rb 230 def execute_prepared_statement(conn, type, name, opts, &block) 231 ps = prepared_statement(name) 232 sql = ps.prepared_sql 233 args = opts[:arguments] 234 ps_args = {} 235 args.each{|k, v| ps_args[k] = prepared_statement_argument(v)} 236 if cpsa = conn.prepared_statements[name] 237 cps, cps_sql = cpsa 238 if cps_sql != sql 239 cps.close 240 cps = nil 241 end 242 end 243 unless cps 244 cps = log_connection_yield("PREPARE #{name}: #{sql}", conn){conn.prepare(sql)} 245 conn.prepared_statements[name] = [cps, sql] 246 end 247 log_sql = String.new 248 log_sql << "EXECUTE #{name}" 249 if ps.log_sql 250 log_sql << " (" 251 log_sql << sql 252 log_sql << ")" 253 end 254 if block 255 log_connection_yield(log_sql, conn, args){cps.execute(ps_args, &block)} 256 else 257 log_connection_yield(log_sql, conn, args){cps.execute!(ps_args){|r|}} 258 case type 259 when :insert 260 conn.last_insert_row_id 261 when :update 262 conn.changes 263 end 264 end 265 end
# File lib/sequel/adapters/sqlite.rb 212 def prepared_statement_argument(arg) 213 case arg 214 when Date, DateTime, Time 215 literal(arg)[1...-1] 216 when SQL::Blob 217 arg.to_blob 218 when true, false 219 if integer_booleans 220 arg ? 1 : 0 221 else 222 literal(arg)[1...-1] 223 end 224 else 225 arg 226 end 227 end