Class: ActiveRecord::ConnectionAdapters::SQLite3Adapter

Inherits:
AbstractAdapter show all
Includes:
ActiveRecord::ConnectionAdapters::SQLite3::DatabaseStatements, ActiveRecord::ConnectionAdapters::SQLite3::Quoting, ActiveRecord::ConnectionAdapters::SQLite3::SchemaStatements
Defined in:
activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb

Overview

Active Record SQLite3 Adapter

The SQLite3 adapter works with the sqlite3 driver.

Options

  • :database (String): Filesystem path to the database file.

  • :statement_limit (Integer): Maximum number of prepared statements to cache per database connection. (default: 1000)

  • :timeout (Integer): Timeout in milliseconds to use when waiting for a lock. (default: no wait)

  • :strict (Boolean): Enable or disable strict mode. When enabled, this will disallow double-quoted string literals in SQL statements. (default: see strict_strings_by_default)

  • :extensions (Array): (requires sqlite3 v2.4.0) Each entry specifies a sqlite extension to load for this database. The entry may be a filesystem path, or the name of a class that responds to .to_path to provide the filesystem path for the extension. See sqlite3-ruby documentation for more information.

There may be other options available specific to the SQLite3 driver. Please read the documentation for SQLite3::Database.new

Defined Under Namespace

Classes: SQLite3Integer, StatementPool

Constant Summary collapse

ADAPTER_NAME =
"SQLite"
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" },
  json:         { name: "json" },
}
DEFAULT_PRAGMAS =
{
  "foreign_keys"        => true,
  "journal_mode"        => :wal,
  "synchronous"         => :normal,
  "mmap_size"           => 134217728, # 128 megabytes
  "journal_size_limit"  => 67108864, # 64 megabytes
  "cache_size"          => 2000
}
VIRTUAL_TABLE_REGEX =
/USING\s+(\w+)\s*\((.+)\)/i
FK_REGEX =
/.*FOREIGN KEY\s+\("([^"]+)"\)\s+REFERENCES\s+"(\w+)"\s+\("(\w+)"\)/
DEFERRABLE_REGEX =
/DEFERRABLE INITIALLY (\w+)/
TYPE_MAP =
Type::TypeMap.new.tap { |m| initialize_type_map(m) }
EXTENDED_TYPE_MAPS =
Concurrent::Map.new

Constants included from ActiveRecord::ConnectionAdapters::SQLite3::Quoting

ActiveRecord::ConnectionAdapters::SQLite3::Quoting::QUOTED_COLUMN_NAMES, ActiveRecord::ConnectionAdapters::SQLite3::Quoting::QUOTED_TABLE_NAMES

Constants inherited from AbstractAdapter

AbstractAdapter::COMMENT_REGEX, AbstractAdapter::MAX_JITTER, AbstractAdapter::SIMPLE_INT

Constants included from QueryCache

QueryCache::DEFAULT_SIZE

Constants included from ActiveSupport::Callbacks

ActiveSupport::Callbacks::CALLBACK_FILTER_TYPES

Instance Attribute Summary

Attributes inherited from AbstractAdapter

#allow_preconnect, #lock, #logger, #owner, #pinned, #pool, #visitor

Attributes included from QueryCache

#query_cache

Attributes included from DatabaseStatements

#transaction_manager

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ActiveRecord::ConnectionAdapters::SQLite3::DatabaseStatements

#begin_db_transaction, #begin_deferred_transaction, #begin_isolated_db_transaction, #commit_db_transaction, #default_insert_value, #exec_rollback_db_transaction, #execute, #execute_batch, #explain, #high_precision_current_timestamp, #reset_isolation_level, #write_query?

Methods included from ActiveRecord::ConnectionAdapters::SQLite3::SchemaStatements

#add_check_constraint, #add_foreign_key, #check_constraints, #create_schema_dumper, #indexes, #remove_check_constraint, #remove_foreign_key, #schema_creation, #virtual_table_exists?

Methods included from ActiveRecord::ConnectionAdapters::SQLite3::Quoting

#quote, #quote_default_expression, #quote_string, #quote_table_name_for_assignment, #quoted_binary, #quoted_time, #type_cast, #unquoted_false, #unquoted_true

Methods included from ActiveSupport::Concern

#append_features, #class_methods, extended, #included, #prepend_features, #prepended

Methods inherited from AbstractAdapter

#adapter_name, #add_enum_value, #advisory_locks_enabled?, #async_enabled?, build_read_query_regexp, #case_insensitive_comparison, #case_sensitive_comparison, #clean!, #clear_cache!, #close, #connect!, #connection_age, #connection_descriptor, #connection_retries, #create_enum, database_exists?, #database_version, #default_index_type?, #default_timezone, #disable_extension, #discard!, #drop_enum, #enable_extension, #expire, extended_type_map, #extensions, find_cmd_and_exec, #force_retirement, #get_advisory_lock, #index_algorithms, #inspect, #lease, #lock_thread=, #max_jitter, #migration_strategy, #native_database_types, #pool_jitter, #prefetch_primary_key?, #prepared_statements?, #prepared_statements_disabled_cache, #preventing_writes?, #raw_connection, #reconnect!, register_class_with_precision, #release_advisory_lock, #rename_enum, #rename_enum_value, #replica?, #retry_deadline, #return_value_after_insert?, #role, #savepoint_errors_invalidate_transactions?, #schema_cache, #schema_version, #seconds_idle, #seconds_since_last_activity, #shard, #steal!, #supports_advisory_locks?, #supports_bulk_alter?, #supports_comments?, #supports_comments_in_create?, #supports_disabling_indexes?, #supports_exclusion_constraints?, #supports_extensions?, #supports_foreign_tables?, #supports_index_include?, #supports_indexes_in_create?, #supports_materialized_views?, #supports_nulls_not_distinct?, #supports_optimizer_hints?, #supports_partitioned_indexes?, #supports_restart_db_transaction?, #supports_unique_constraints?, #supports_validate_constraints?, #throw_away!, type_cast_config_to_boolean, type_cast_config_to_integer, #unprepared_statement, #valid_type?, valid_type?, validate_default_timezone, #verified?, #verify!, #verify_timeout

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, #query_cache_enabled, #select_all, #uncached

Methods included from DatabaseLimits

#index_name_length, #max_identifier_length, #table_alias_length, #table_name_length

Methods included from Quoting

#cast_bound_value, #lookup_cast_type, #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, #sanitize_as_sql_comment, #type_cast, #type_casted_binds, #unquoted_false, #unquoted_true

Methods included from DatabaseStatements

#_exec_insert, #add_transaction_record, #begin_db_transaction, #begin_deferred_transaction, #begin_isolated_db_transaction, #cacheable_query, #commit_db_transaction, #default_insert_value, #default_sequence_name, #delete, #empty_all_tables, #empty_insert_statement_value, #exec_delete, #exec_insert, #exec_insert_all, #exec_query, #exec_restart_db_transaction, #exec_rollback_db_transaction, #exec_update, #execute, #execute_batch, #execute_intent, #explain, #high_precision_current_timestamp, #insert, #insert_fixture, #insert_fixtures_set, #query_all, #query_command, #query_one, #query_rows, #query_value, #query_values, #reset_isolation_level, #reset_sequence!, #reset_transaction, #restart_db_transaction, #rollback_db_transaction, #rollback_to_savepoint, #select_all, #select_one, #select_rows, #select_value, #select_values, #to_sql, #to_sql_and_binds, #transaction, #transaction_isolation_levels, #transaction_open?, #truncate, #truncate_tables, #update, #with_yaml_fallback, #write_query?

Methods included from SchemaStatements

#add_check_constraint, #add_columns, #add_foreign_key, #add_index, #add_index_options, #assume_migrated_upto_version, #build_add_column_definition, #build_change_column_default_definition, #build_create_index_definition, #build_create_join_table_definition, #build_create_table_definition, #bulk_change_table, #change_column_comment, #change_table, #change_table_comment, #check_constraint_exists?, #check_constraint_options, #check_constraints, #column_exists?, #columns, #columns_for_distinct, #create_join_table, #create_schema_dumper, #create_table, #data_source_exists?, #data_sources, #disable_index, #distinct_relation_for_primary_key, #drop_join_table, #drop_table, #dump_schema_versions, #enable_index, #foreign_key_column_for, #foreign_key_exists?, #foreign_key_options, #index_algorithm, #index_exists?, #index_name, #index_name_exists?, #indexes, #internal_string_options_for_primary_key, #max_index_name_size, #native_database_types, #options_include_default?, #primary_key, #quoted_columns_for_index, #remove_check_constraint, #remove_constraint, #remove_foreign_key, #remove_reference, #remove_timestamps, #rename_index, #schema_creation, #table_alias_for, #table_comment, #table_exists?, #table_options, #tables, #type_to_sql, #update_table_definition, #use_foreign_keys?, #valid_column_definition_options, #valid_primary_key_options, #valid_table_definition_options, #view_exists?, #views

Methods included from ActiveSupport::Callbacks

#run_callbacks

Constructor Details

#initializeSQLite3Adapter

Returns a new instance of SQLite3Adapter.



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 156

def initialize(...)
  super

  @memory_database = false
  case @config[:database].to_s
  when ""
    raise ArgumentError, "No database file specified. Missing argument: database"
  when ":memory:"
    @memory_database = true
  else
    database_path = SQLite3Adapter.resolve_path(@config[:database])
    @config[:database] = database_path unless @config[:database].to_s.start_with?("file:")
    dirname = File.dirname(database_path)
    unless File.directory?(dirname)
      begin
        FileUtils.mkdir_p(dirname)
      rescue SystemCallError
        raise ActiveRecord::NoDatabaseError.new(connection_pool: @pool)
      end
    end
  end

  @previous_read_uncommitted = nil
  @config[:strict] = ConnectionAdapters::SQLite3Adapter.strict_strings_by_default unless @config.key?(:strict)

  extensions = @config.fetch(:extensions, []).map do |extension|
    extension.safe_constantize || extension
  end

  @connection_parameters = @config.merge(
    database: @config[:database].to_s,
    results_as_hash: true,
    default_transaction_mode: :immediate,
    extensions: extensions
  )
end

Class Method Details

.dbconsole(config, options = {}) ⇒ Object



60
61
62
63
64
65
66
67
68
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 60

def dbconsole(config, options = {})
  args = []

  args << "-#{options[:mode]}" if options[:mode]
  args << "-header" if options[:header]
  args << File.expand_path(config.database, defined?(Rails.root) ? Rails.root : nil)

  find_cmd_and_exec(ActiveRecord.database_cli[:sqlite], *args)
end

.native_database_typesObject

:nodoc:



70
71
72
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 70

def native_database_types # :nodoc:
  NATIVE_DATABASE_TYPES
end

.new_client(config) ⇒ Object



50
51
52
53
54
55
56
57
58
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 50

def new_client(config)
  ::SQLite3::Database.new(config[:database].to_s, config)
rescue Errno::ENOENT => error
  if error.message.include?("No such file or directory")
    raise ActiveRecord::NoDatabaseError
  else
    raise
  end
end

.resolve_path(database, root: nil) ⇒ Object

Returns a filesystem path to the database.

The configuration’s :database value may be a (slightly nonstandard) SQLite URI, so this method will resolve those URIs to a string path.

If Rails.root is available, this is guaranteed to be an absolute path.

See www.sqlite.org/uri.html



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 82

def resolve_path(database, root: nil)
  database = database.to_s
  root ||= defined?(Rails.root) ? Rails.root : nil

  path = if database.start_with?("file:/")
    URI.parse(database).path
  elsif database.start_with?("file:")
    URI.parse(database.split("?").first).opaque
  else
    database
  end

  if root.present?
    File.expand_path(path, root)
  else
    path
  end
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


268
269
270
271
272
273
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 268

def active?
  if connected?
    verified!
    true
  end
end

#add_column(table_name, column_name, type, **options) ⇒ Object

:nodoc:



391
392
393
394
395
396
397
398
399
400
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 391

def add_column(table_name, column_name, type, **options) # :nodoc:
  type = type.to_sym
  if invalid_alter_table_type?(type, options)
    alter_table(table_name) do |definition|
      definition.column(column_name, type, **options)
    end
  else
    super
  end
end

#add_reference(table_name, ref_name, **options) ⇒ Object Also known as: add_belongs_to

:nodoc:



463
464
465
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 463

def add_reference(table_name, ref_name, **options) # :nodoc:
  super(table_name, ref_name, type: :integer, **options)
end

#add_timestamps(table_name, **options) ⇒ Object



450
451
452
453
454
455
456
457
458
459
460
461
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 450

def add_timestamps(table_name, **options)
  options[:null] = false if options[:null].nil?

  if !options.key?(:precision)
    options[:precision] = 6
  end

  alter_table(table_name) do |definition|
    definition.column :created_at, :datetime, **options
    definition.column :updated_at, :datetime, **options
  end
end

#build_insert_sql(insert) ⇒ Object

:nodoc:



506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 506

def build_insert_sql(insert) # :nodoc:
  sql = +"INSERT #{insert.into} #{insert.values_list}"

  if insert.skip_duplicates?
    sql << " ON CONFLICT #{insert.conflict_target} DO NOTHING"
  elsif insert.update_duplicates?
    sql << " ON CONFLICT #{insert.conflict_target} DO UPDATE SET "
    if insert.raw_update_sql?
      sql << insert.raw_update_sql
    else
      sql << insert.touch_model_timestamps_unless { |column| "#{column} IS excluded.#{column}" }
      sql << insert.updatable_columns.map { |column| "#{column}=excluded.#{column}" }.join(",")
    end
  end

  sql << " RETURNING #{insert.returning}" if insert.returning
  sql
end

#change_column(table_name, column_name, type, **options) ⇒ Object

:nodoc:



438
439
440
441
442
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 438

def change_column(table_name, column_name, type, **options) # :nodoc:
  alter_table(table_name) do |definition|
    definition.change_column(column_name, type, **options)
  end
end

#change_column_default(table_name, column_name, default_or_changes) ⇒ Object

:nodoc:



419
420
421
422
423
424
425
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 419

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:



427
428
429
430
431
432
433
434
435
436
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 427

def change_column_null(table_name, column_name, null, default = nil) # :nodoc:
  validate_change_column_null_argument!(null)

  unless null || default.nil?
    query_command("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

#check_all_foreign_keys_valid!Object

:nodoc:



323
324
325
326
327
328
329
330
331
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 323

def check_all_foreign_keys_valid! # :nodoc:
  sql = "PRAGMA foreign_key_check"
  result = execute(sql)

  unless result.blank?
    tables = result.map { |row| row["table"] }
    raise ActiveRecord::StatementInvalid.new("Foreign key violations found: #{tables.join(", ")}", sql: sql, connection_pool: @pool)
  end
end

#check_versionObject

:nodoc:



533
534
535
536
537
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 533

def check_version # :nodoc:
  if database_version < "3.23.0"
    raise "Your version of SQLite (#{database_version}) is too old. Active Record supports SQLite >= 3.23.0."
  end
end

#connected?Boolean

Returns:

  • (Boolean)


264
265
266
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 264

def connected?
  !(@raw_connection.nil? || @raw_connection.closed?)
end

#create_virtual_table(table_name, module_name, values) ⇒ Object

Creates a virtual table

Example:

create_virtual_table :emails, :fts5, ['sender', 'title', 'body']


366
367
368
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 366

def create_virtual_table(table_name, module_name, values)
  exec_query "CREATE VIRTUAL TABLE IF NOT EXISTS #{table_name} USING #{module_name} (#{values.join(", ")})"
end

#database_exists?Boolean

Returns:

  • (Boolean)


193
194
195
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 193

def database_exists?
  @config[:database] == ":memory:" || File.exist?(@config[:database].to_s)
end

#disable_referential_integrityObject

REFERENTIAL INTEGRITY ====================================



309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 309

def disable_referential_integrity # :nodoc:
  old_foreign_keys = query_value("PRAGMA foreign_keys", nil)
  old_defer_foreign_keys = query_value("PRAGMA defer_foreign_keys", nil)

  begin
    execute("PRAGMA defer_foreign_keys = ON")
    execute("PRAGMA foreign_keys = OFF")
    yield
  ensure
    execute("PRAGMA defer_foreign_keys = #{old_defer_foreign_keys}")
    execute("PRAGMA foreign_keys = #{old_foreign_keys}")
  end
end

#disconnect!Object

Disconnects from the database if already connected. Otherwise, this method does nothing.



279
280
281
282
283
284
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 279

def disconnect!
  super

  @raw_connection&.close rescue nil
  @raw_connection = nil
end

#drop_virtual_table(table_name, module_name, values, **options) ⇒ Object

Drops a virtual table

Although this command ignores module_name and values, it can be helpful to provide these in a migration’s change method so it can be reverted. In that case, module_name, values and options will be used by #create_virtual_table.



375
376
377
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 375

def drop_virtual_table(table_name, module_name, values, **options)
  drop_table(table_name)
end

#encodingObject

Returns the current database encoding format as a string, e.g. ‘UTF-8’



291
292
293
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 291

def encoding
  any_raw_connection.encoding.to_s
end

#foreign_keys(table_name) ⇒ Object



470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 470

def foreign_keys(table_name)
  # SQLite returns 1 row for each column of composite foreign keys.
  fk_info = query_all("PRAGMA foreign_key_list(#{quote(table_name)})")
  # Deferred or immediate foreign keys can only be seen in the CREATE TABLE sql
  fk_defs = table_structure_sql(table_name)
              .select do |column_string|
                column_string.start_with?("CONSTRAINT") &&
                column_string.include?("FOREIGN KEY")
              end
              .to_h do |fk_string|
                _, from, table, to = fk_string.match(FK_REGEX).to_a
                _, mode = fk_string.match(DEFERRABLE_REGEX).to_a
                deferred = mode&.downcase&.to_sym || false
                [[table, from, to], deferred]
              end

  grouped_fk = fk_info.group_by { |row| row["id"] }.values.each { |group| group.sort_by! { |row| row["seq"] } }
  grouped_fk.map do |group|
    row = group.first
    options = {
      on_delete: extract_foreign_key_action(row["on_delete"]),
      on_update: extract_foreign_key_action(row["on_update"]),
      deferrable: fk_defs[[row["table"], row["from"], row["to"]]]
    }

    if group.one?
      options[:column] = row["from"]
      options[:primary_key] = row["to"]
    else
      options[:column] = group.map { |row| row["from"] }
      options[:primary_key] = group.map { |row| row["to"] }
    end
    ForeignKeyDefinition.new(table_name, row["table"], options)
  end
end

#get_database_versionObject

:nodoc:



529
530
531
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 529

def get_database_version # :nodoc:
  SQLite3Adapter::Version.new(query_value("SELECT sqlite_version(*)"))
end

#primary_keys(table_name) ⇒ Object

SCHEMA STATEMENTS ========================================



335
336
337
338
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 335

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:



402
403
404
405
406
407
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 402

def remove_column(table_name, column_name, type = nil, **options) # :nodoc:
  alter_table(table_name) do |definition|
    definition.remove_column column_name
    definition.foreign_keys.delete_if { |fk| fk.column == column_name.to_s }
  end
end

#remove_columns(table_name, *column_names, type: nil, **options) ⇒ Object

:nodoc:



409
410
411
412
413
414
415
416
417
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 409

def remove_columns(table_name, *column_names, type: nil, **options) # :nodoc:
  alter_table(table_name) do |definition|
    column_names.each do |column_name|
      definition.remove_column column_name
    end
    column_names = column_names.map(&:to_s)
    definition.foreign_keys.delete_if { |fk| column_names.include?(fk.column) }
  end
end

#remove_index(table_name, column_name = nil, **options) ⇒ Object

:nodoc:



340
341
342
343
344
345
346
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 340

def remove_index(table_name, column_name = nil, **options) # :nodoc:
  return if options[:if_exists] && !index_exists?(table_name, column_name, **options)

  index_name = index_name_for_remove(table_name, column_name, options)

  exec_query "DROP INDEX #{quote_column_name(index_name)}"
end

#rename_column(table_name, column_name, new_column_name) ⇒ Object

:nodoc:



444
445
446
447
448
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 444

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, **options) ⇒ Object

Renames a table.

Example:

rename_table('octopuses', 'octopi')


383
384
385
386
387
388
389
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 383

def rename_table(table_name, new_name, **options)
  validate_table_length!(new_name) unless options[:_uses_legacy_table_name]
  schema_cache.clear_data_source_cache!(table_name.to_s)
  schema_cache.clear_data_source_cache!(new_name.to_s)
  exec_query "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}"
  rename_table_indexes(table_name, new_name, **options)
end

#requires_reloading?Boolean

Returns:

  • (Boolean)


217
218
219
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 217

def requires_reloading?
  true
end

#shared_cache?Boolean

:nodoc:

Returns:

  • (Boolean)


525
526
527
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 525

def shared_cache? # :nodoc:
  @config.fetch(:flags, 0).anybits?(::SQLite3::Constants::Open::SHAREDCACHE)
end

#strict_strings_by_defaultObject

:singleton-method:

Configure the SQLite3Adapter to be used in a “strict strings” mode. When enabled, this will disallow double-quoted string literals in SQL statements, which may prevent some typographical errors like creating an index for a non-existent column. The default is false.

If you wish to enable this mode you can add the following line to your application.rb file:

config.active_record.sqlite3_adapter_strict_strings_by_default = true

This can also be configured on individual databases by setting the strict: option.



121
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 121

class_attribute :strict_strings_by_default, default: false

#supports_check_constraints?Boolean

Returns:

  • (Boolean)


225
226
227
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 225

def supports_check_constraints?
  true
end

#supports_common_table_expressions?Boolean

Returns:

  • (Boolean)


241
242
243
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 241

def supports_common_table_expressions?
  true
end

#supports_concurrent_connections?Boolean

Returns:

  • (Boolean)


256
257
258
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 256

def supports_concurrent_connections?
  !@memory_database
end

#supports_datetime_with_precision?Boolean

Returns:

  • (Boolean)


233
234
235
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 233

def supports_datetime_with_precision?
  true
end

#supports_ddl_transactions?Boolean

Returns:

  • (Boolean)


197
198
199
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 197

def supports_ddl_transactions?
  true
end

#supports_deferrable_constraints?Boolean

Returns:

  • (Boolean)


303
304
305
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 303

def supports_deferrable_constraints?
  true
end

#supports_explain?Boolean

Returns:

  • (Boolean)


295
296
297
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 295

def supports_explain?
  true
end

#supports_expression_index?Boolean

Returns:

  • (Boolean)


213
214
215
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 213

def supports_expression_index?
  true
end

#supports_foreign_keys?Boolean

Returns:

  • (Boolean)


221
222
223
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 221

def supports_foreign_keys?
  true
end

#supports_index_sort_order?Boolean

Returns:

  • (Boolean)


286
287
288
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 286

def supports_index_sort_order?
  true
end

#supports_insert_on_conflict?Boolean Also known as: supports_insert_on_duplicate_skip?, supports_insert_on_duplicate_update?, supports_insert_conflict_target?

Returns:

  • (Boolean)


249
250
251
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 249

def supports_insert_on_conflict?
  database_version >= "3.24.0"
end

#supports_insert_returning?Boolean

Returns:

  • (Boolean)


245
246
247
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 245

def supports_insert_returning?
  database_version >= "3.35.0"
end

#supports_json?Boolean

Returns:

  • (Boolean)


237
238
239
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 237

def supports_json?
  true
end

#supports_lazy_transactions?Boolean

Returns:

  • (Boolean)


299
300
301
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 299

def supports_lazy_transactions?
  true
end

#supports_partial_index?Boolean

Returns:

  • (Boolean)


209
210
211
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 209

def supports_partial_index?
  true
end

#supports_savepoints?Boolean

Returns:

  • (Boolean)


201
202
203
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 201

def supports_savepoints?
  true
end

#supports_transaction_isolation?Boolean

Returns:

  • (Boolean)


205
206
207
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 205

def supports_transaction_isolation?
  true
end

#supports_views?Boolean

Returns:

  • (Boolean)


229
230
231
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 229

def supports_views?
  true
end

#supports_virtual_columns?Boolean

Returns:

  • (Boolean)


260
261
262
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 260

def supports_virtual_columns?
  database_version >= "3.31.0"
end

#virtual_tablesObject

Returns a list of defined virtual tables



351
352
353
354
355
356
357
358
359
360
# File 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb', line 351

def virtual_tables
  query = <<~SQL
    SELECT name, sql FROM sqlite_master WHERE sql LIKE 'CREATE VIRTUAL %';
  SQL

  query_rows(query).each_with_object({}) do |(table_name, sql), memo|
    _, module_name, arguments = sql.match(VIRTUAL_TABLE_REGEX).to_a
    memo[table_name] = [module_name, arguments]
  end.to_a
end