Class: ActiveRecord::ConnectionAdapters::SQLite3Adapter
- Inherits:
-
AbstractAdapter
- Object
- AbstractAdapter
- ActiveRecord::ConnectionAdapters::SQLite3Adapter
- Includes:
- ActiveRecord::ConnectionAdapters::SQLite3::ColumnDumper, ActiveRecord::ConnectionAdapters::SQLite3::Quoting, ActiveRecord::ConnectionAdapters::SQLite3::SchemaStatements
- Defined in:
- lib/active_record/connection_adapters/sqlite3_adapter.rb
Overview
The SQLite3 adapter works SQLite 3.6.16 or newer with the sqlite3-ruby drivers (available as gem from rubygems.org/gems/sqlite3).
Options:
-
:database
- Path to the database file.
Defined Under Namespace
Classes: StatementPool
Constant Summary collapse
- ADAPTER_NAME =
"SQLite".freeze
- NATIVE_DATABASE_TYPES =
{ primary_key: "INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL", string: { name: "varchar" }, text: { name: "text" }, integer: { name: "integer" }, float: { name: "float" }, decimal: { name: "decimal" }, datetime: { name: "datetime" }, time: { name: "time" }, date: { name: "date" }, binary: { name: "blob" }, boolean: { name: "boolean" } }
Constants inherited from AbstractAdapter
Instance Attribute Summary
Attributes inherited from AbstractAdapter
#lock, #logger, #owner, #pool, #prepared_statements, #schema_cache, #visitor
Attributes included from QueryCache
#query_cache, #query_cache_enabled
Attributes included from DatabaseStatements
Instance Method Summary collapse
- #active? ⇒ Boolean
-
#add_column(table_name, column_name, type, options = {}) ⇒ Object
:nodoc:.
-
#add_reference(table_name, ref_name, **options) ⇒ Object
(also: #add_belongs_to)
:nodoc:.
-
#allowed_index_name_length ⇒ Object
Returns 62.
-
#arel_visitor ⇒ Object
:nodoc:.
-
#begin_db_transaction ⇒ Object
:nodoc:.
-
#change_column(table_name, column_name, type, options = {}) ⇒ Object
:nodoc:.
-
#change_column_default(table_name, column_name, default_or_changes) ⇒ Object
:nodoc:.
-
#change_column_null(table_name, column_name, null, default = nil) ⇒ Object
:nodoc:.
-
#clear_cache! ⇒ Object
Clears the prepared statements cache.
-
#commit_db_transaction ⇒ Object
:nodoc:.
-
#disable_referential_integrity ⇒ Object
REFERENTIAL INTEGRITY ====================================.
-
#disconnect! ⇒ Object
Disconnects from the database if already connected.
-
#encoding ⇒ Object
Returns the current database encoding format as a string, eg: ‘UTF-8’.
- #exec_delete(sql, name = "SQL", binds = []) ⇒ Object (also: #exec_update)
- #exec_query(sql, name = nil, binds = [], prepare: false) ⇒ Object
-
#exec_rollback_db_transaction ⇒ Object
:nodoc:.
-
#execute(sql, name = nil) ⇒ Object
:nodoc:.
-
#explain(arel, binds = []) ⇒ Object
– DATABASE STATEMENTS ====================================== ++.
- #foreign_keys(table_name) ⇒ Object
-
#indexes(table_name, name = nil) ⇒ Object
Returns an array of indexes for the given table.
-
#initialize(connection, logger, connection_options, config) ⇒ SQLite3Adapter
constructor
A new instance of SQLite3Adapter.
- #last_inserted_id(result) ⇒ Object
-
#native_database_types ⇒ Object
:nodoc:.
-
#new_column_from_field(table_name, field) ⇒ Object
SCHEMA STATEMENTS ========================================.
-
#primary_keys(table_name) ⇒ Object
:nodoc:.
-
#remove_column(table_name, column_name, type = nil, options = {}) ⇒ Object
:nodoc:.
-
#remove_index(table_name, options = {}) ⇒ Object
:nodoc:.
-
#rename_column(table_name, column_name, new_column_name) ⇒ Object
:nodoc:.
-
#rename_table(table_name, new_name) ⇒ Object
Renames a table.
- #requires_reloading? ⇒ Boolean
-
#schema_creation ⇒ Object
:nodoc:.
- #supports_datetime_with_precision? ⇒ Boolean
- #supports_ddl_transactions? ⇒ Boolean
- #supports_explain? ⇒ Boolean
- #supports_foreign_keys_in_create? ⇒ Boolean
- #supports_index_sort_order? ⇒ Boolean
- #supports_multi_insert? ⇒ Boolean
- #supports_partial_index? ⇒ Boolean
- #supports_savepoints? ⇒ Boolean
-
#supports_statement_cache? ⇒ Boolean
Returns true, since this connection adapter supports prepared statement caching.
- #supports_views? ⇒ Boolean
-
#update_table_definition(table_name, base) ⇒ Object
:nodoc:.
-
#valid_alter_table_type?(type) ⇒ Boolean
See: www.sqlite.org/lang_altertable.html SQLite has an additional restriction on the ALTER TABLE statement.
Methods included from ActiveRecord::ConnectionAdapters::SQLite3::Quoting
#quote_column_name, #quote_string, #quote_table_name_for_assignment, #quoted_binary, #quoted_time
Methods inherited from AbstractAdapter
#adapter_name, #case_insensitive_comparison, #case_sensitive_comparison, #close, #collector, #column_name_for_operation, #columns, #combine_bind_parameters, #default_index_type?, #disable_extension, #enable_extension, #expire, #extensions, #get_advisory_lock, #index_algorithms, #lease, #lookup_cast_type, #new_column, #prefetch_primary_key?, #raw_connection, #reconnect!, #release_advisory_lock, #reset!, #steal!, #supports_advisory_locks?, #supports_bulk_alter?, #supports_comments?, #supports_comments_in_create?, #supports_expression_index?, #supports_extensions?, #supports_foreign_keys?, #supports_json?, #supports_migrations?, #supports_primary_key?, #supports_transaction_isolation?, #supports_virtual_columns?, type_cast_config_to_boolean, type_cast_config_to_integer, #type_map, #unprepared_statement, #valid_type?, #verify!
Methods included from Savepoints
#create_savepoint, #current_savepoint_name, #exec_rollback_to_savepoint, #release_savepoint
Methods included from ColumnDumper
#column_spec, #column_spec_for_primary_key, #migration_keys, #prepare_column_options
Methods included from QueryCache
#cache, #clear_query_cache, dirties_query_cache, #disable_query_cache!, #enable_query_cache!, included, #select_all, #uncached
Methods included from DatabaseLimits
#column_name_length, #columns_per_multicolumn_index, #columns_per_table, #in_clause_length, #index_name_length, #indexes_per_table, #joins_per_query, #sql_query_length, #table_alias_length, #table_name_length
Methods included from Quoting
#fetch_type_metadata, #lookup_cast_type_from_column, #quote, #quote_column_name, #quote_default_expression, #quote_string, #quote_table_name, #quote_table_name_for_assignment, #quoted_binary, #quoted_date, #quoted_false, #quoted_time, #quoted_true, #type_cast, #type_cast_from_column, #type_casted_binds, #unquoted_false, #unquoted_true
Methods included from DatabaseStatements
#add_transaction_record, #begin_isolated_db_transaction, #cacheable_query, #default_sequence_name, #delete, #empty_insert_statement_value, #exec_insert, #insert, #insert_fixture, #join_to_update, #reset_sequence!, #reset_transaction, #rollback_db_transaction, #rollback_to_savepoint, #sanitize_limit, #select_all, #select_one, #select_rows, #select_value, #select_values, #to_sql, #transaction, #transaction_isolation_levels, #transaction_open?, #transaction_state, #truncate, #update
Methods included from SchemaStatements
#add_foreign_key, #add_index, #add_index_options, #add_timestamps, #assume_migrated_upto_version, #change_column_comment, #change_table, #change_table_comment, #column_exists?, #columns, #columns_for_distinct, #create_join_table, #create_table, #data_source_exists?, #data_sources, #drop_join_table, #drop_table, #dump_schema_information, #foreign_key_column_for, #foreign_key_exists?, #foreign_key_for, #foreign_key_for!, #foreign_key_options, #index_exists?, #index_name, #index_name_exists?, #initialize_internal_metadata_table, #initialize_schema_migrations_table, #insert_versions_sql, #internal_string_options_for_primary_key, #options_include_default?, #primary_key, #remove_columns, #remove_foreign_key, #remove_reference, #remove_timestamps, #rename_index, #table_alias_for, #table_comment, #table_exists?, #table_options, #tables, #type_to_sql, #view_exists?, #views
Constructor Details
#initialize(connection, logger, connection_options, config) ⇒ SQLite3Adapter
Returns a new instance of SQLite3Adapter.
95 96 97 98 99 100 101 102 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 95 def initialize(connection, logger, , config) super(connection, logger, config) @active = nil @statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit])) configure_connection end |
Instance Method Details
#active? ⇒ Boolean
142 143 144 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 142 def active? @active != false end |
#add_column(table_name, column_name, type, options = {}) ⇒ Object
:nodoc:
342 343 344 345 346 347 348 349 350 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 342 def add_column(table_name, column_name, type, = {}) #:nodoc: if valid_alter_table_type?(type) super(table_name, column_name, type, ) else alter_table(table_name) do |definition| definition.column(column_name, type, ) end end end |
#add_reference(table_name, ref_name, **options) ⇒ Object Also known as: add_belongs_to
:nodoc:
395 396 397 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 395 def add_reference(table_name, ref_name, **) # :nodoc: super(table_name, ref_name, type: :integer, **) end |
#allowed_index_name_length ⇒ Object
Returns 62. SQLite supports index names up to 64 characters. The rest is used by Rails internally to perform temporary rename operations
166 167 168 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 166 def allowed_index_name_length index_name_length - 2 end |
#arel_visitor ⇒ Object
:nodoc:
91 92 93 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 91 def arel_visitor # :nodoc: Arel::Visitors::SQLite.new(self) end |
#begin_db_transaction ⇒ Object
:nodoc:
256 257 258 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 256 def begin_db_transaction #:nodoc: log("begin transaction", nil) { @connection.transaction } end |
#change_column(table_name, column_name, type, options = {}) ⇒ Object
:nodoc:
375 376 377 378 379 380 381 382 383 384 385 386 387 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 375 def change_column(table_name, column_name, type, = {}) #:nodoc: alter_table(table_name) do |definition| definition[column_name].instance_eval do self.type = type self.limit = [:limit] if .include?(:limit) self.default = [:default] if .include?(:default) self.null = [:null] if .include?(:null) self.precision = [:precision] if .include?(:precision) self.scale = [:scale] if .include?(:scale) self.collation = [:collation] if .include?(:collation) end end end |
#change_column_default(table_name, column_name, default_or_changes) ⇒ Object
:nodoc:
358 359 360 361 362 363 364 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 358 def change_column_default(table_name, column_name, default_or_changes) #:nodoc: default = extract_new_default_value(default_or_changes) alter_table(table_name) do |definition| definition[column_name].default = default end end |
#change_column_null(table_name, column_name, null, default = nil) ⇒ Object
:nodoc:
366 367 368 369 370 371 372 373 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 366 def change_column_null(table_name, column_name, null, default = nil) #:nodoc: unless null || default.nil? exec_query("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 |
#clear_cache! ⇒ Object
Clears the prepared statements cache.
155 156 157 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 155 def clear_cache! @statements.clear end |
#commit_db_transaction ⇒ Object
:nodoc:
260 261 262 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 260 def commit_db_transaction #:nodoc: log("commit transaction", nil) { @connection.commit } end |
#disable_referential_integrity ⇒ Object
REFERENTIAL INTEGRITY ====================================
185 186 187 188 189 190 191 192 193 194 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 185 def disable_referential_integrity # :nodoc: old = select_value("PRAGMA foreign_keys") begin execute("PRAGMA foreign_keys = OFF") yield ensure execute("PRAGMA foreign_keys = #{old}") end end |
#disconnect! ⇒ Object
Disconnects from the database if already connected. Otherwise, this method does nothing.
148 149 150 151 152 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 148 def disconnect! super @active = false @connection.close rescue nil end |
#encoding ⇒ Object
Returns the current database encoding format as a string, eg: ‘UTF-8’
175 176 177 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 175 def encoding @connection.encoding.to_s end |
#exec_delete(sql, name = "SQL", binds = []) ⇒ Object Also known as: exec_update
238 239 240 241 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 238 def exec_delete(sql, name = "SQL", binds = []) exec_query(sql, name, binds) @connection.changes end |
#exec_query(sql, name = nil, binds = [], prepare: false) ⇒ Object
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 205 def exec_query(sql, name = nil, binds = [], prepare: false) type_casted_binds = type_casted_binds(binds) log(sql, name, binds, type_casted_binds) do ActiveSupport::Dependencies.interlock.permit_concurrent_loads do # Don't cache statements if they are not prepared unless prepare stmt = @connection.prepare(sql) begin cols = stmt.columns unless without_prepared_statement?(binds) stmt.bind_params(type_casted_binds) end records = stmt.to_a ensure stmt.close end else cache = @statements[sql] ||= { stmt: @connection.prepare(sql) } stmt = cache[:stmt] cols = cache[:cols] ||= stmt.columns stmt.reset! stmt.bind_params(type_casted_binds) records = stmt.to_a end ActiveRecord::Result.new(cols, records) end end end |
#exec_rollback_db_transaction ⇒ Object
:nodoc:
264 265 266 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 264 def exec_rollback_db_transaction #:nodoc: log("rollback transaction", nil) { @connection.rollback } end |
#execute(sql, name = nil) ⇒ Object
:nodoc:
248 249 250 251 252 253 254 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 248 def execute(sql, name = nil) #:nodoc: log(sql, name) do ActiveSupport::Dependencies.interlock.permit_concurrent_loads do @connection.execute(sql) end end end |
#explain(arel, binds = []) ⇒ Object
– DATABASE STATEMENTS ====================================== ++
200 201 202 203 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 200 def explain(arel, binds = []) sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}" SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", [])) end |
#foreign_keys(table_name) ⇒ Object
400 401 402 403 404 405 406 407 408 409 410 411 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 400 def foreign_keys(table_name) fk_info = select_all("PRAGMA foreign_key_list(#{quote(table_name)})", "SCHEMA") fk_info.map do |row| = { column: row["from"], primary_key: row["to"], on_delete: extract_foreign_key_action(row["on_delete"]), on_update: extract_foreign_key_action(row["on_update"]) } ForeignKeyDefinition.new(table_name, row["table"], ) end end |
#indexes(table_name, name = nil) ⇒ Object
Returns an array of indexes for the given table.
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 287 def indexes(table_name, name = nil) #:nodoc: if name ActiveSupport::Deprecation.warn(<<-MSG.squish) Passing name to #indexes is deprecated without replacement. MSG end exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", "SCHEMA").map do |row| sql = <<-SQL SELECT sql FROM sqlite_master WHERE name=#{quote(row['name'])} AND type='index' UNION ALL SELECT sql FROM sqlite_temp_master WHERE name=#{quote(row['name'])} AND type='index' SQL index_sql = exec_query(sql).first["sql"] match = /\sWHERE\s+(.+)$/i.match(index_sql) where = match[1] if match IndexDefinition.new( table_name, row["name"], row["unique"] != 0, exec_query("PRAGMA index_info('#{row['name']}')", "SCHEMA").map { |col| col["name"] }, nil, nil, where) end end |
#last_inserted_id(result) ⇒ Object
244 245 246 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 244 def last_inserted_id(result) @connection.last_insert_row_id end |
#native_database_types ⇒ Object
:nodoc:
170 171 172 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 170 def native_database_types #:nodoc: NATIVE_DATABASE_TYPES end |
#new_column_from_field(table_name, field) ⇒ Object
SCHEMA STATEMENTS ========================================
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 270 def new_column_from_field(table_name, field) # :nondoc: case field["dflt_value"] when /^null$/i field["dflt_value"] = nil when /^'(.*)'$/m field["dflt_value"] = $1.gsub("''", "'") when /^"(.*)"$/m field["dflt_value"] = $1.gsub('""', '"') end collation = field["collation"] sql_type = field["type"] = (sql_type) new_column(field["name"], field["dflt_value"], , field["notnull"].to_i == 0, table_name, nil, collation) end |
#primary_keys(table_name) ⇒ Object
:nodoc:
317 318 319 320 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 317 def primary_keys(table_name) # :nodoc: pks = table_structure(table_name).select { |f| f["pk"] > 0 } pks.sort_by { |f| f["pk"] }.map { |f| f["name"] } end |
#remove_column(table_name, column_name, type = nil, options = {}) ⇒ Object
:nodoc:
352 353 354 355 356 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 352 def remove_column(table_name, column_name, type = nil, = {}) #:nodoc: alter_table(table_name) do |definition| definition.remove_column column_name end end |
#remove_index(table_name, options = {}) ⇒ Object
:nodoc:
322 323 324 325 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 322 def remove_index(table_name, = {}) #:nodoc: index_name = index_name_for_remove(table_name, ) exec_query "DROP INDEX #{quote_column_name(index_name)}" end |
#rename_column(table_name, column_name, new_column_name) ⇒ Object
:nodoc:
389 390 391 392 393 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 389 def rename_column(table_name, column_name, new_column_name) #:nodoc: column = column_for(table_name, column_name) alter_table(table_name, rename: { column.name => new_column_name.to_s }) rename_column_indexes(table_name, column.name, new_column_name) end |
#rename_table(table_name, new_name) ⇒ Object
Renames a table.
Example:
rename_table('octopuses', 'octopi')
331 332 333 334 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 331 def rename_table(table_name, new_name) exec_query "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}" rename_table_indexes(table_name, new_name) end |
#requires_reloading? ⇒ Boolean
122 123 124 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 122 def requires_reloading? true end |
#schema_creation ⇒ Object
:nodoc:
87 88 89 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 87 def schema_creation # :nodoc: SQLite3::SchemaCreation.new self end |
#supports_datetime_with_precision? ⇒ Boolean
134 135 136 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 134 def supports_datetime_with_precision? true end |
#supports_ddl_transactions? ⇒ Boolean
104 105 106 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 104 def supports_ddl_transactions? true end |
#supports_explain? ⇒ Boolean
179 180 181 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 179 def supports_explain? true end |
#supports_foreign_keys_in_create? ⇒ Boolean
126 127 128 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 126 def supports_foreign_keys_in_create? sqlite_version >= "3.6.19" end |
#supports_index_sort_order? ⇒ Boolean
159 160 161 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 159 def supports_index_sort_order? true end |
#supports_multi_insert? ⇒ Boolean
138 139 140 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 138 def supports_multi_insert? sqlite_version >= "3.7.11" end |
#supports_partial_index? ⇒ Boolean
112 113 114 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 112 def supports_partial_index? sqlite_version >= "3.8.0" end |
#supports_savepoints? ⇒ Boolean
108 109 110 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 108 def supports_savepoints? true end |
#supports_statement_cache? ⇒ Boolean
Returns true, since this connection adapter supports prepared statement caching.
118 119 120 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 118 def supports_statement_cache? true end |
#supports_views? ⇒ Boolean
130 131 132 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 130 def supports_views? true end |
#update_table_definition(table_name, base) ⇒ Object
:nodoc:
83 84 85 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 83 def update_table_definition(table_name, base) # :nodoc: SQLite3::Table.new(table_name, base) end |
#valid_alter_table_type?(type) ⇒ Boolean
See: www.sqlite.org/lang_altertable.html SQLite has an additional restriction on the ALTER TABLE statement
338 339 340 |
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 338 def valid_alter_table_type?(type) type.to_sym != :primary_key end |