Module: JdbcSpec::SQLite3

Includes:
MissingFunctionalityHelper
Defined in:
lib/jdbc_adapter/jdbc_sqlite3.rb

Defined Under Namespace

Modules: Column

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MissingFunctionalityHelper

#alter_table, #copy_table, #copy_table_contents, #copy_table_indexes, #move_table

Class Method Details

.adapter_matcher(name) ⇒ Object



39
40
41
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 39

def self.adapter_matcher(name, *)
  name =~ /sqlite/i ? self : false
end

.column_selectorObject



43
44
45
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 43

def self.column_selector
  [/sqlite/i, lambda {|cfg,col| col.extend(::JdbcSpec::SQLite3::Column)}]
end

.extended(base) ⇒ Object



33
34
35
36
37
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 33

def self.extended(base)
  base.class.class_eval do
    alias_chained_method :insert, :query_dirty, :insert
  end
end

.jdbc_connection_classObject



47
48
49
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 47

def self.jdbc_connection_class
  ::ActiveRecord::ConnectionAdapters::Sqlite3JdbcConnection
end

Instance Method Details

#_execute(sql, name = nil) ⇒ Object



321
322
323
324
325
326
327
328
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 321

def _execute(sql, name = nil)
  if ActiveRecord::ConnectionAdapters::JdbcConnection::select?(sql)
    @connection.execute_query(sql)
  else
    affected_rows = @connection.execute_update(sql)
    ActiveRecord::ConnectionAdapters::JdbcConnection::insert?(sql) ? last_insert_id(sql.split(" ", 4)[2], nil) : affected_rows
  end
end

#adapter_nameObject

:nodoc:



146
147
148
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 146

def adapter_name #:nodoc:
  'SQLite'
end

#add_column(table_name, column_name, type, options = {}) ⇒ Object



215
216
217
218
219
220
221
222
223
224
225
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 215

def add_column(table_name, column_name, type, options = {})
  if option_not_null = options[:null] == false
    option_not_null = options.delete(:null)
  end
  add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
  add_column_options!(add_column_sql, options)
  execute(add_column_sql)
  if option_not_null
    alter_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} NOT NULL"
  end
end

#add_limit_offset!(sql, options) ⇒ Object

:nodoc:



277
278
279
280
281
282
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 277

def add_limit_offset!(sql, options) #:nodoc:
  if options[:limit]
    sql << " LIMIT #{options[:limit]}"
    sql << " OFFSET #{options[:offset]}" if options[:offset]
  end
end

#add_lock!(sql, options) ⇒ Object

SELECT … FOR UPDATE is redundant since the table is locked.



355
356
357
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 355

def add_lock!(sql, options) #:nodoc:
  sql
end

#change_column(table_name, column_name, type, options = {}) ⇒ Object

:nodoc:



236
237
238
239
240
241
242
243
244
245
246
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 236

def change_column(table_name, column_name, type, options = {}) #:nodoc:
  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)
    end
  end
end

#change_column_default(table_name, column_name, default) ⇒ Object

:nodoc:



248
249
250
251
252
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 248

def change_column_default(table_name, column_name, default) #:nodoc:
  alter_table(table_name) do |definition|
    definition[column_name].default = default
  end
end

#columns(table_name, name = nil) ⇒ Object

:nodoc:



348
349
350
351
352
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 348

def columns(table_name, name = nil) #:nodoc:        
  table_structure(table_name).map do |field|
    ::ActiveRecord::ConnectionAdapters::JdbcColumn.new(@config, field['name'], field['dflt_value'], field['type'], field['notnull'] == 0)
  end
end

#indexes(table_name, name = nil) ⇒ Object



300
301
302
303
304
305
306
307
308
309
310
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 300

def indexes(table_name, name = nil)
  result = select_rows("SELECT name, sql FROM sqlite_master WHERE tbl_name = '#{table_name}' AND type = 'index'", name)

  result.collect do |row|
    name = row[0]
    index_sql = row[1]
    unique = (index_sql =~ /unique/i)
    cols = index_sql.match(/\((.*)\)/)[1].gsub(/,/,' ').split
    ::ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, name, unique, cols)
  end
end

#insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) ⇒ Object

:nodoc:



265
266
267
268
269
270
271
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 265

def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
  log(sql,name) do
    @connection.execute_update(sql)
  end
  table = sql.split(" ", 4)[2]
  id_value || last_insert_id(table, nil)
end

#last_insert_id(table, sequence_name) ⇒ Object



273
274
275
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 273

def last_insert_id(table, sequence_name)
  Integer(select_value("SELECT SEQ FROM SQLITE_SEQUENCE WHERE NAME = '#{table}'"))
end

#modify_types(tp) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 162

def modify_types(tp)
  tp[:primary_key] = "INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL"
  tp[:string] = { :name => "VARCHAR", :limit => 255 }
  tp[:float] = { :name => "REAL" }
  tp[:decimal] = { :name => "REAL" }
  tp[:datetime] = { :name => "DATETIME" }
  tp[:timestamp] = { :name => "DATETIME" }
  tp[:time] = { :name => "TIME" }
  tp[:date] = { :name => "DATE" }
  tp[:boolean] = { :name => "BOOLEAN" }
  tp
end

#primary_key(table_name) ⇒ Object

:nodoc:



312
313
314
315
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 312

def primary_key(table_name) #:nodoc:
  column = table_structure(table_name).find {|field| field['pk'].to_i == 1}
  column ? column['name'] : nil
end

#quote(value, column = nil) ⇒ Object

:nodoc:



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 175

def quote(value, column = nil) # :nodoc:
  return value.quoted_id if value.respond_to?(:quoted_id)
  case value
  when String
    if column && column.type == :binary
      "'#{quote_string(column.class.string_to_binary(value))}'"
    elsif column && [:integer, :float].include?(column.type)
      (column.type == :integer ? value.to_i : value.to_f).to_s
    elsif column && column.respond_to?(:primary) && column.primary && column.klass != String
      value.to_i.to_s
    else
      "'#{quote_string(value)}'"
    end
  else super
  end
end

#quote_column_name(name) ⇒ Object

:nodoc:



192
193
194
195
196
197
198
199
200
201
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 192

def quote_column_name(name) #:nodoc:
  name = name.to_s
  # Did not find reference on values needing quoting, but these
  # happen in AR unit tests
  if name == "references" || name =~ /-/
    %Q("#{name}") 
  else
    name
  end
end

#quote_string(str) ⇒ Object



203
204
205
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 203

def quote_string(str)
  str.gsub(/'/, "''")
end

#quoted_falseObject



211
212
213
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 211

def quoted_false
  %Q{'f'}
end

#quoted_trueObject



207
208
209
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 207

def quoted_true
  %Q{'t'}
end

#recreate_database(name) ⇒ Object



317
318
319
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 317

def recreate_database(name)
  tables.each{ |table| drop_table(table) }
end

#remove_column(table_name, *column_names) ⇒ Object Also known as: remove_columns

:nodoc:



227
228
229
230
231
232
233
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 227

def remove_column(table_name, *column_names) #:nodoc:
  column_names.flatten.each do |column_name|
    alter_table(table_name) do |definition|
      definition.columns.delete(definition[column_name])
    end
  end
end

#remove_index(table_name, options = {}) ⇒ Object



296
297
298
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 296

def remove_index(table_name, options = {})
  execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}"
end

#rename_column(table_name, column_name, new_column_name) ⇒ Object

:nodoc:



254
255
256
257
258
259
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 254

def rename_column(table_name, column_name, new_column_name) #:nodoc:
  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})
end

#rename_table(name, new_name) ⇒ Object



261
262
263
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 261

def rename_table(name, new_name)
  execute "ALTER TABLE #{name} RENAME TO #{new_name}"
end

#select(sql, name = nil) ⇒ Object



330
331
332
333
334
335
336
337
338
339
340
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 330

def select(sql, name=nil)
  execute(sql, name).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

#sqlite_versionObject



158
159
160
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 158

def sqlite_version
  @sqlite_version ||= select_value('select sqlite_version(*)')
end

#supports_autoincrement?Boolean

:nodoc:

Returns:

  • (Boolean)


154
155
156
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 154

def supports_autoincrement? #:nodoc:
  sqlite_version >= '3.1.0'
end

#supports_count_distinct?Boolean

:nodoc:

Returns:

  • (Boolean)


150
151
152
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 150

def supports_count_distinct? #:nodoc:
  sqlite_version >= '3.2.6'
end

#table_structure(table_name) ⇒ Object

Raises:

  • (ActiveRecord::StatementInvalid)


342
343
344
345
346
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 342

def table_structure(table_name)
  structure = @connection.execute_query("PRAGMA table_info(#{quote_table_name(table_name)})")
  raise ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'" if structure.empty?
  structure
end

#tables(name = nil) ⇒ Object

:nodoc:



284
285
286
287
288
289
290
291
292
293
294
# File 'lib/jdbc_adapter/jdbc_sqlite3.rb', line 284

def tables(name = nil) #:nodoc:
  sql = <<-SQL
    SELECT name
    FROM sqlite_master
    WHERE type = 'table' AND NOT name = 'sqlite_sequence'
  SQL

  select_rows(sql, name).map do |row|
    row[0]
  end
end