Class: ActiveRecord::ConnectionAdapters::SQLite3Adapter
- Inherits:
-
AbstractAdapter
- Object
- AbstractAdapter
- ActiveRecord::ConnectionAdapters::SQLite3Adapter
- Includes:
- ActiveRecord::ConnectionAdapters::SQLite3::Quoting, ActiveRecord::ConnectionAdapters::SQLite3::SchemaStatements
- Defined in:
- activerecord/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
Constants included from ActiveSupport::Callbacks
ActiveSupport::Callbacks::CALLBACK_FILTER_TYPES
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.
-
#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
-
#initialize(connection, logger, connection_options, config) ⇒ SQLite3Adapter
constructor
A new instance of SQLite3Adapter.
- #insert_fixtures(rows, table_name) ⇒ Object
- #last_inserted_id(result) ⇒ Object
-
#native_database_types ⇒ Object
:nodoc:.
-
#primary_keys(table_name) ⇒ Object
SCHEMA STATEMENTS ========================================.
-
#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.
-
#represent_boolean_as_integer ⇒ Object
:singleton-method: Indicates whether boolean values are stored in sqlite3 databases as 1 and 0 or ‘t’ and ‘f’.
- #requires_reloading? ⇒ Boolean
- #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_views? ⇒ Boolean
-
#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::SchemaStatements
#create_schema_dumper, #indexes, #update_table_definition
Methods included from ActiveRecord::ConnectionAdapters::SQLite3::Quoting
#quote_column_name, #quote_string, #quote_table_name_for_assignment, #quoted_binary, #quoted_false, #quoted_time, #quoted_true, #unquoted_false, #unquoted_true
Methods inherited from AbstractAdapter
#adapter_name, #case_insensitive_comparison, #case_sensitive_comparison, #close, #column_name_for_operation, #default_index_type?, #disable_extension, #enable_extension, #expire, #extensions, #get_advisory_lock, #index_algorithms, #lease, #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, #unprepared_statement, #valid_type?, #verify!
Methods included from Savepoints
#create_savepoint, #current_savepoint_name, #exec_rollback_to_savepoint, #release_savepoint
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
#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, #query, #query_value, #query_values, #reset_sequence!, #reset_transaction, #rollback_db_transaction, #rollback_to_savepoint, #sanitize_limit, #select_all, #select_one, #select_rows, #select_value, #select_values, #supports_statement_cache?, #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_schema_dumper, #create_table, #data_source_exists?, #data_sources, #drop_join_table, #drop_table, #dump_schema_information, #foreign_key_column_for, #foreign_key_exists?, #foreign_key_options, #index_exists?, #index_name, #index_name_exists?, #indexes, #initialize_internal_metadata_table, #initialize_schema_migrations_table, #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, #update_table_definition, #view_exists?, #views
Methods included from ActiveSupport::Callbacks
Methods included from ActiveSupport::Concern
#append_features, #class_methods, extended, #included
Constructor Details
#initialize(connection, logger, connection_options, config) ⇒ SQLite3Adapter
Returns a new instance of SQLite3Adapter.
101 102 103 104 105 106 107 108 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 101 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 'activerecord/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:
295 296 297 298 299 300 301 302 303 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 295 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:
348 349 350 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 348 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 Quails internally to perform temporary rename operations
166 167 168 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 166 def allowed_index_name_length index_name_length - 2 end |
#begin_db_transaction ⇒ Object
:nodoc:
256 257 258 |
# File 'activerecord/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:
328 329 330 331 332 333 334 335 336 337 338 339 340 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 328 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:
311 312 313 314 315 316 317 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 311 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:
319 320 321 322 323 324 325 326 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 319 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 'activerecord/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 'activerecord/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 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 185 def disable_referential_integrity # :nodoc: old = query_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 'activerecord/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 'activerecord/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 'activerecord/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 'activerecord/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 'activerecord/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 'activerecord/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 'activerecord/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
353 354 355 356 357 358 359 360 361 362 363 364 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 353 def foreign_keys(table_name) fk_info = exec_query("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 |
#insert_fixtures(rows, table_name) ⇒ Object
366 367 368 369 370 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 366 def insert_fixtures(rows, table_name) rows.each do |row| insert_fixture(row, table_name) end end |
#last_inserted_id(result) ⇒ Object
244 245 246 |
# File 'activerecord/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 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 170 def native_database_types #:nodoc: NATIVE_DATABASE_TYPES end |
#primary_keys(table_name) ⇒ Object
SCHEMA STATEMENTS ========================================
270 271 272 273 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 270 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:
305 306 307 308 309 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 305 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:
275 276 277 278 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 275 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:
342 343 344 345 346 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 342 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')
284 285 286 287 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 284 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 |
#represent_boolean_as_integer ⇒ Object
:singleton-method: Indicates whether boolean values are stored in sqlite3 databases as 1 and 0 or ‘t’ and ‘f’. Leaving ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer
set to false is deprecated. SQLite databases have used ‘t’ and ‘f’ to serialize boolean values and must have old data converted to 1 and 0 (its native boolean serialization) before setting this flag to true. Conversion can be accomplished by setting up a rake task which runs
ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1)
ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0)
for all models and all boolean columns, after which the flag must be set to true by adding the following to your application.rb
file:
Quails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
91 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 91 class_attribute :represent_boolean_as_integer, default: false |
#requires_reloading? ⇒ Boolean
122 123 124 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 122 def requires_reloading? true end |
#supports_datetime_with_precision? ⇒ Boolean
134 135 136 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 134 def supports_datetime_with_precision? true end |
#supports_ddl_transactions? ⇒ Boolean
110 111 112 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 110 def supports_ddl_transactions? true end |
#supports_explain? ⇒ Boolean
179 180 181 |
# File 'activerecord/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 'activerecord/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 'activerecord/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 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 138 def supports_multi_insert? sqlite_version >= "3.7.11" end |
#supports_partial_index? ⇒ Boolean
118 119 120 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 118 def supports_partial_index? sqlite_version >= "3.8.0" end |
#supports_savepoints? ⇒ Boolean
114 115 116 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 114 def supports_savepoints? true end |
#supports_views? ⇒ Boolean
130 131 132 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 130 def supports_views? true end |
#valid_alter_table_type?(type) ⇒ Boolean
See: www.sqlite.org/lang_altertable.html SQLite has an additional restriction on the ALTER TABLE statement
291 292 293 |
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 291 def valid_alter_table_type?(type) type.to_sym != :primary_key end |