Module: ArJdbc::SQLite3
Defined Under Namespace
Modules: Column, ExplainSupport
Constant Summary
collapse
- ADAPTER_NAME =
'SQLite'.freeze
- NATIVE_DATABASE_TYPES =
{
:primary_key => nil,
:string => { :name => "varchar", :limit => 255 },
:text => { :name => "text" },
:integer => { :name => "integer" },
:float => { :name => "float" },
:decimal => { :name => "decimal" },
:datetime => { :name => "datetime" },
:timestamp => { :name => "datetime" },
:time => { :name => "time" },
:date => { :name => "date" },
:binary => { :name => "blob" },
:boolean => { :name => "boolean" }
}
Class Method Summary
collapse
Instance Method Summary
collapse
-
#adapter_name ⇒ Object
-
#add_column(table_name, column_name, type, options = {}) ⇒ Object
-
#allowed_index_name_length ⇒ Fixnum
-
#change_column(table_name, column_name, type, options = {}) ⇒ Object
-
#change_column_default(table_name, column_name, default) ⇒ Object
-
#change_column_null(table_name, column_name, null, default = nil) ⇒ Object
-
#columns(table_name, name = nil) ⇒ Object
-
#create_savepoint(name = current_savepoint_name(true)) ⇒ Object
-
#default_primary_key_type ⇒ Object
-
#empty_insert_statement_value ⇒ Object
-
#encoding ⇒ Object
-
#exec_insert(sql, name, binds, pk = nil, sequence_name = nil) ⇒ Object
-
#insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) ⇒ Object
-
#last_insert_id ⇒ Object
-
#last_inserted_id(result) ⇒ Object
protected
-
#native_database_types ⇒ Object
-
#primary_key(table_name) ⇒ Object
-
#quote(value, column = nil) ⇒ Object
-
#quote_column_name(name) ⇒ Object
-
#quote_table_name_for_assignment(table, attr) ⇒ Object
-
#quoted_date(value) ⇒ Object
Quote date/time values for use in SQL input.
-
#release_savepoint(name = current_savepoint_name) ⇒ Object
-
#remove_index!(table_name, index_name) ⇒ Object
-
#rename_column(table_name, column_name, new_column_name) ⇒ Object
-
#rename_table(table_name, new_name) ⇒ Object
-
#rollback_to_savepoint(name = current_savepoint_name) ⇒ Object
-
#select(sql, name = nil, binds = []) ⇒ Object
-
#supports_add_column? ⇒ Boolean
-
#supports_autoincrement? ⇒ Boolean
-
#supports_count_distinct? ⇒ Boolean
-
#supports_ddl_transactions? ⇒ Boolean
-
#supports_index_sort_order? ⇒ Boolean
-
#supports_migrations? ⇒ Boolean
-
#supports_primary_key? ⇒ Boolean
-
#supports_savepoints? ⇒ Boolean
-
#table_exists?(table_name) ⇒ Boolean
-
#table_structure(table_name) ⇒ Object
-
#tables(name = nil, table_name = nil) ⇒ Object
-
#translate_exception(exception, message) ⇒ Object
protected
-
#valid_alter_table_options(type, options) ⇒ Object
SQLite has an additional restriction on the ALTER TABLE statement.
#alter_table, #copy_table, #copy_table_contents, #copy_table_indexes, #move_table
Class Method Details
.arel_visitor_type(config = nil) ⇒ Object
98
99
100
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 98
def self.arel_visitor_type(config = nil)
::Arel::Visitors::SQLite
end
|
.column_selector ⇒ Object
16
17
18
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 16
def self.column_selector
[ /sqlite/i, lambda { |config, column| column.extend(Column) } ]
end
|
.jdbc_connection_class ⇒ Object
Instance Method Details
#adapter_name ⇒ Object
110
111
112
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 110
def adapter_name
ADAPTER_NAME
end
|
#add_column(table_name, column_name, type, options = {}) ⇒ Object
375
376
377
378
379
380
381
382
383
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 375
def add_column(table_name, column_name, type, options = {})
if supports_add_column? && valid_alter_table_options( type, options )
super(table_name, column_name, type, options)
else
alter_table(table_name) do |definition|
definition.column(column_name, type, options)
end
end
end
|
#allowed_index_name_length ⇒ Fixnum
Returns 62. SQLite supports index names up to 64 characters.
The rest is used by Rails internally to perform temporary rename operations.
266
267
268
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 266
def allowed_index_name_length
index_name_length - 2
end
|
#change_column(table_name, column_name, type, options = {}) ⇒ Object
429
430
431
432
433
434
435
436
437
438
439
440
441
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 429
def change_column(table_name, column_name, type, options = {})
alter_table(table_name) do |definition|
include_default = options_include_default?(options)
definition[column_name].instance_eval do
self.type = type
self.limit = options[:limit] if options.include?(:limit)
self.default = options[:default] if include_default
self.null = options[:null] if options.include?(:null)
self.precision = options[:precision] if options.include?(:precision)
self.scale = options[:scale] if options.include?(:scale)
end
end
end
|
#change_column_default(table_name, column_name, default) ⇒ Object
414
415
416
417
418
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 414
def change_column_default(table_name, column_name, default) alter_table(table_name) do |definition|
definition[column_name].default = default
end
end
|
#change_column_null(table_name, column_name, null, default = nil) ⇒ Object
420
421
422
423
424
425
426
427
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 420
def change_column_null(table_name, column_name, null, default = nil)
unless null || default.nil?
execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
end
alter_table(table_name) do |definition|
definition[column_name].null = null
end
end
|
#columns(table_name, name = nil) ⇒ Object
345
346
347
348
349
350
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 345
def columns(table_name, name = nil)
klass = ::ActiveRecord::ConnectionAdapters::SQLite3Column
table_structure(table_name).map do |field|
klass.new(field['name'], field['dflt_value'], field['type'], field['notnull'] == 0)
end
end
|
#create_savepoint(name = current_savepoint_name(true)) ⇒ Object
271
272
273
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 271
def create_savepoint(name = current_savepoint_name(true))
log("SAVEPOINT #{name}", 'Savepoint') { super }
end
|
#default_primary_key_type ⇒ Object
137
138
139
140
141
142
143
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 137
def default_primary_key_type
if supports_autoincrement?
'integer PRIMARY KEY AUTOINCREMENT NOT NULL'
else
'integer PRIMARY KEY NOT NULL'
end
end
|
#empty_insert_statement_value ⇒ Object
456
457
458
459
460
461
462
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 456
def empty_insert_statement_value
"DEFAULT VALUES"
end
|
#encoding ⇒ Object
464
465
466
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 464
def encoding
select_value 'PRAGMA encoding'
end
|
#exec_insert(sql, name, binds, pk = nil, sequence_name = nil) ⇒ Object
Note:
Does not support prepared statements for INSERT statements.
329
330
331
332
333
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 329
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
execute(sql, name, binds)
end
|
#insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) ⇒ Object
Note:
We have an extra binds argument at the end due AR-2.3 support.
322
323
324
325
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 322
def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
result = execute(sql, name, binds)
id_value || last_inserted_id(result)
end
|
#last_insert_id ⇒ Object
468
469
470
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 468
def last_insert_id
@connection.last_insert_rowid
end
|
#last_inserted_id(result) ⇒ Object
474
475
476
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 474
def last_inserted_id(result)
super || last_insert_id end
|
#native_database_types ⇒ Object
131
132
133
134
135
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 131
def native_database_types
types = NATIVE_DATABASE_TYPES.dup
types[:primary_key] = default_primary_key_type
types
end
|
#primary_key(table_name) ⇒ Object
353
354
355
356
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 353
def primary_key(table_name)
column = table_structure(table_name).find { |field| field['pk'].to_i == 1 }
column && column['name']
end
|
#quote(value, column = nil) ⇒ Object
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 211
def quote(value, column = nil)
return value if sql_literal?(value)
if value.kind_of?(String)
column_type = column && column.type
if column_type == :binary && column.class.respond_to?(:string_to_binary)
"x'#{column.class.string_to_binary(value).unpack("H*")[0]}'"
else
super
end
else
super
end
end
|
#quote_column_name(name) ⇒ Object
231
232
233
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 231
def quote_column_name(name)
%Q("#{name.to_s.gsub('"', '""')}") end
|
#quote_table_name_for_assignment(table, attr) ⇒ Object
226
227
228
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 226
def quote_table_name_for_assignment(table, attr)
quote_column_name(attr)
end
|
#quoted_date(value) ⇒ Object
Quote date/time values for use in SQL input.
Includes microseconds if the value is a Time responding to usec.
238
239
240
241
242
243
244
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 238
def quoted_date(value)
if value.acts_like?(:time) && value.respond_to?(:usec)
"#{super}.#{sprintf("%06d", value.usec)}"
else
super
end
end
|
#release_savepoint(name = current_savepoint_name) ⇒ Object
281
282
283
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 281
def release_savepoint(name = current_savepoint_name)
log("RELEASE SAVEPOINT #{name}", 'Savepoint') { super }
end
|
#remove_index!(table_name, index_name) ⇒ Object
359
360
361
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 359
def remove_index!(table_name, index_name)
execute "DROP INDEX #{quote_column_name(index_name)}"
end
|
#rename_column(table_name, column_name, new_column_name) ⇒ Object
443
444
445
446
447
448
449
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 443
def rename_column(table_name, column_name, new_column_name)
unless columns(table_name).detect{|c| c.name == column_name.to_s }
raise ActiveRecord::ActiveRecordError, "Missing column #{table_name}.#{column_name}"
end
alter_table(table_name, :rename => {column_name.to_s => new_column_name.to_s})
rename_column_indexes(table_name, column_name, new_column_name) if respond_to?(:rename_column_indexes) end
|
#rename_table(table_name, new_name) ⇒ Object
364
365
366
367
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 364
def rename_table(table_name, new_name)
execute "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}"
rename_table_indexes(table_name, new_name) if respond_to?(:rename_table_indexes) end
|
#rollback_to_savepoint(name = current_savepoint_name) ⇒ Object
276
277
278
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 276
def rollback_to_savepoint(name = current_savepoint_name)
log("ROLLBACK TO SAVEPOINT #{name}", 'Savepoint') { super }
end
|
#select(sql, name = nil, binds = []) ⇒ Object
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 300
def select(sql, name = nil, binds = [])
result = super if result.respond_to?(:columns) result.columns.map! do |key| key.is_a?(String) ? key.sub(/^"?\w+"?\./, '') : key
end
else
result.map! do |row| record = {}
row.each_key do |key|
if key.is_a?(String)
record[key.sub(/^"?\w+"?\./, '')] = row[key]
end
end
record
end
end
result
end
|
#supports_add_column? ⇒ Boolean
156
157
158
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 156
def supports_add_column?
true
end
|
#supports_autoincrement? ⇒ Boolean
166
167
168
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 166
def supports_autoincrement?
true
end
|
#supports_count_distinct? ⇒ Boolean
161
162
163
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 161
def supports_count_distinct?
true
end
|
#supports_ddl_transactions? ⇒ Boolean
146
147
148
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 146
def supports_ddl_transactions?
true
end
|
#supports_index_sort_order? ⇒ Boolean
171
172
173
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 171
def supports_index_sort_order?
true
end
|
#supports_migrations? ⇒ Boolean
176
177
178
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 176
def supports_migrations?
true
end
|
#supports_primary_key? ⇒ Boolean
181
182
183
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 181
def supports_primary_key?
true
end
|
#supports_savepoints? ⇒ Boolean
151
152
153
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 151
def supports_savepoints?
sqlite_version >= '3.6.8'
end
|
#table_exists?(table_name) ⇒ Boolean
259
260
261
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 259
def table_exists?(table_name)
table_name && tables(nil, table_name).any?
end
|
#table_structure(table_name) ⇒ Object
335
336
337
338
339
340
341
342
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 335
def table_structure(table_name)
sql = "PRAGMA table_info(#{quote_table_name(table_name)})"
log(sql, 'SCHEMA') { @connection.execute_query_raw(sql) }
rescue ActiveRecord::JDBCError => error
e = ActiveRecord::StatementInvalid.new("Could not find table '#{table_name}'")
e.set_backtrace error.backtrace
raise e
end
|
#tables(name = nil, table_name = nil) ⇒ Object
247
248
249
250
251
252
253
254
255
256
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 247
def tables(name = nil, table_name = nil)
sql = "SELECT name FROM sqlite_master WHERE type = 'table'"
if table_name
sql << " AND name = #{quote_table_name(table_name)}"
else
sql << " AND NOT name = 'sqlite_sequence'"
end
select_rows(sql, name).map { |row| row[0] }
end
|
#translate_exception(exception, message) ⇒ Object
478
479
480
481
482
483
484
485
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 478
def translate_exception(exception, message)
case exception.message
when /column(s)? .* (is|are) not unique/
ActiveRecord::RecordNotUnique.new(message, exception)
else
super
end
end
|
#valid_alter_table_options(type, options) ⇒ Object
SQLite has an additional restriction on the ALTER TABLE statement.
371
372
373
|
# File 'lib/arjdbc/sqlite3/adapter.rb', line 371
def valid_alter_table_options( type, options)
type.to_sym != :primary_key
end
|