Module: ArJdbc::SQLite3

Includes:
MissingFunctionalityHelper
Included in:
ActiveRecord::ConnectionAdapters::SQLite3Adapter
Defined in:
lib/arjdbc/sqlite3/adapter.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

.column_selectorObject



9
10
11
# File 'lib/arjdbc/sqlite3/adapter.rb', line 9

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

.jdbc_connection_classObject



13
14
15
# File 'lib/arjdbc/sqlite3/adapter.rb', line 13

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

Instance Method Details

#_execute(sql, name = nil) ⇒ Object



172
173
174
175
# File 'lib/arjdbc/sqlite3/adapter.rb', line 172

def _execute(sql, name = nil)
  result = super
  ActiveRecord::ConnectionAdapters::JdbcConnection::insert?(sql) ? last_insert_id : result
end

#adapter_nameObject

:nodoc:



74
75
76
# File 'lib/arjdbc/sqlite3/adapter.rb', line 74

def adapter_name #:nodoc:
  'SQLite'
end

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

:nodoc:



222
223
224
225
226
227
228
229
230
# File 'lib/arjdbc/sqlite3/adapter.rb', line 222

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

#add_lock!(sql, options) ⇒ Object

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



277
278
279
# File 'lib/arjdbc/sqlite3/adapter.rb', line 277

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

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

:nodoc:



257
258
259
260
261
262
263
264
265
266
267
# File 'lib/arjdbc/sqlite3/adapter.rb', line 257

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:



242
243
244
245
246
# File 'lib/arjdbc/sqlite3/adapter.rb', line 242

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

#change_column_null(table_name, column_name, null, default = nil) ⇒ Object



248
249
250
251
252
253
254
255
# File 'lib/arjdbc/sqlite3/adapter.rb', line 248

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

:nodoc:



195
196
197
198
199
# File 'lib/arjdbc/sqlite3/adapter.rb', line 195

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

#empty_insert_statement_valueObject



281
282
283
# File 'lib/arjdbc/sqlite3/adapter.rb', line 281

def empty_insert_statement_value
  "VALUES(NULL)"
end

#indexes(table_name, name = nil) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/arjdbc/sqlite3/adapter.rb', line 149

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.map do |c|
      match = /^"(.+)"$/.match(c); match ? match[1] : c
    end
    ::ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, name, unique, cols)
  end
end

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

:nodoc:



124
125
126
127
# File 'lib/arjdbc/sqlite3/adapter.rb', line 124

def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
  @connection.execute_update(sql)
  id_value || last_insert_id
end

#last_insert_idObject



129
130
131
# File 'lib/arjdbc/sqlite3/adapter.rb', line 129

def last_insert_id
  Integer(select_value("SELECT last_insert_rowid()"))
end

#modify_types(tp) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/arjdbc/sqlite3/adapter.rb', line 94

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[:binary] = { :name => "BLOB" }
  tp
end

#primary_key(table_name) ⇒ Object

:nodoc:



163
164
165
166
# File 'lib/arjdbc/sqlite3/adapter.rb', line 163

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

#quote_column_name(name) ⇒ Object

:nodoc:



108
109
110
# File 'lib/arjdbc/sqlite3/adapter.rb', line 108

def quote_column_name(name) #:nodoc:
  %Q("#{name}")
end

#quote_string(str) ⇒ Object



112
113
114
# File 'lib/arjdbc/sqlite3/adapter.rb', line 112

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

#quoted_falseObject



120
121
122
# File 'lib/arjdbc/sqlite3/adapter.rb', line 120

def quoted_false
  %Q{'f'}
end

#quoted_trueObject



116
117
118
# File 'lib/arjdbc/sqlite3/adapter.rb', line 116

def quoted_true
  %Q{'t'}
end

#recreate_database(name) ⇒ Object



168
169
170
# File 'lib/arjdbc/sqlite3/adapter.rb', line 168

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

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

:nodoc:

Raises:

  • (ArgumentError)


232
233
234
235
236
237
238
239
# File 'lib/arjdbc/sqlite3/adapter.rb', line 232

def remove_column(table_name, *column_names) #:nodoc:
  raise ArgumentError.new("You must specify at least one column name.  Example: remove_column(:people, :first_name)") if column_names.empty?
  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



145
146
147
# File 'lib/arjdbc/sqlite3/adapter.rb', line 145

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

#remove_index!(table_name, index_name) ⇒ Object

:nodoc:



208
209
210
# File 'lib/arjdbc/sqlite3/adapter.rb', line 208

def remove_index!(table_name, index_name) #:nodoc:
  execute "DROP INDEX #{quote_column_name(index_name)}"
end

#rename_column(table_name, column_name, new_column_name) ⇒ Object

:nodoc:



269
270
271
272
273
274
# File 'lib/arjdbc/sqlite3/adapter.rb', line 269

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



212
213
214
# File 'lib/arjdbc/sqlite3/adapter.rb', line 212

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

#select(sql, name = nil) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
# File 'lib/arjdbc/sqlite3/adapter.rb', line 177

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



90
91
92
# File 'lib/arjdbc/sqlite3/adapter.rb', line 90

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

#supports_add_column?Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/arjdbc/sqlite3/adapter.rb', line 78

def supports_add_column?
  sqlite_version >= '3.1.6'
end

#supports_autoincrement?Boolean

:nodoc:

Returns:

  • (Boolean)


86
87
88
# File 'lib/arjdbc/sqlite3/adapter.rb', line 86

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

#supports_count_distinct?Boolean

:nodoc:

Returns:

  • (Boolean)


82
83
84
# File 'lib/arjdbc/sqlite3/adapter.rb', line 82

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

#table_structure(table_name) ⇒ Object

Raises:

  • (ActiveRecord::StatementInvalid)


189
190
191
192
193
# File 'lib/arjdbc/sqlite3/adapter.rb', line 189

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:



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/arjdbc/sqlite3/adapter.rb', line 133

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

#valid_alter_table_options(type, options) ⇒ Object

See: www.sqlite.org/lang_altertable.html SQLite has an additional restriction on the ALTER TABLE statement



218
219
220
# File 'lib/arjdbc/sqlite3/adapter.rb', line 218

def valid_alter_table_options( type, options)
  type.to_sym != :primary_key
end