Module: ArJdbc::SQLite3
- Includes:
- ActiveRecord::ConnectionAdapters::SQLite3::DatabaseStatements, ActiveRecord::ConnectionAdapters::SQLite3::Quoting, ActiveRecord::ConnectionAdapters::SQLite3::SchemaStatements
- Included in:
- ActiveRecord::ConnectionAdapters::SQLite3Adapter
- Defined in:
- lib/arjdbc/sqlite3/adapter.rb
Overview
All the code in this module is a copy of ConnectionAdapters::SQLite3Adapter from active_record 5. The constants at the front of this file are to allow the rest of the file to remain with no modifications from its original source. If you hack on this file try not to modify this module and instead try and put those overrides in SQL3Adapter below. We try and keep a copy of the Rails this adapter supports with the current goal of being able to diff changes easily over time and to also eventually remove this module from ARJDBC altogether.
Defined Under Namespace
Classes: StatementPool
Constant Summary collapse
- ConnectionAdapters =
DIFFERENCE: Some common constant names to reduce differences in rest of this module from AR5 version
::ActiveRecord::ConnectionAdapters
- IndexDefinition =
::ActiveRecord::ConnectionAdapters::IndexDefinition
- Quoting =
::ActiveRecord::ConnectionAdapters::SQLite3::Quoting
- RecordNotUnique =
::ActiveRecord::RecordNotUnique
- SchemaCreation =
ConnectionAdapters::SQLite3::SchemaCreation
- SQLite3Adapter =
ConnectionAdapters::AbstractAdapter
- 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" }, }
Class Method Summary collapse
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:.
- #add_timestamps(table_name, **options) ⇒ Object
-
#build_insert_sql(insert) ⇒ 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:.
-
#check_all_foreign_keys_valid! ⇒ Object
:nodoc:.
- #check_version ⇒ Object
-
#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'.
- #foreign_keys(table_name) ⇒ Object
-
#get_database_version ⇒ Object
:nodoc:.
-
#native_database_types ⇒ Object
:nodoc:.
-
#new_column_from_field(table_name, field, definitions) ⇒ Object
DIFFERENCE: here to.
-
#primary_keys(table_name) ⇒ Object
SCHEMA STATEMENTS ========================================.
-
#remove_column(table_name, column_name, type = nil, **options) ⇒ Object
:nodoc:.
-
#remove_columns(table_name, *column_names, type: nil, **options) ⇒ Object
:nodoc:.
-
#remove_index(table_name, column_name = nil, **options) ⇒ Object
:nodoc:.
-
#rename_column(table_name, column_name, new_column_name) ⇒ Object
:nodoc:.
-
#rename_table(table_name, new_name, **options) ⇒ Object
Renames a table.
- #requires_reloading? ⇒ Boolean
-
#return_value_after_insert?(column) ⇒ Boolean
:nodoc:.
-
#shared_cache? ⇒ Boolean
:nodoc:.
- #supports_check_constraints? ⇒ Boolean
- #supports_common_table_expressions? ⇒ Boolean
-
#supports_concurrent_connections? ⇒ Boolean
DIFFERENCE: active?, reconnect!, disconnect! handles by arjdbc core.
- #supports_datetime_with_precision? ⇒ Boolean
- #supports_ddl_transactions? ⇒ Boolean
- #supports_explain? ⇒ Boolean
- #supports_expression_index? ⇒ Boolean
- #supports_foreign_keys? ⇒ Boolean
- #supports_index_sort_order? ⇒ Boolean
- #supports_insert_on_conflict? ⇒ Boolean (also: #supports_insert_on_duplicate_skip?, #supports_insert_on_duplicate_update?, #supports_insert_conflict_target?)
- #supports_insert_returning? ⇒ Boolean
- #supports_json? ⇒ Boolean
- #supports_lazy_transactions? ⇒ Boolean
- #supports_partial_index? ⇒ Boolean
- #supports_savepoints? ⇒ Boolean
- #supports_transaction_isolation? ⇒ Boolean
- #supports_views? ⇒ Boolean
- #use_insert_returning? ⇒ Boolean
Class Method Details
.database_exists?(config) ⇒ Boolean
95 96 97 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 95 def self.database_exists?(config) @config[:database] == ":memory:" || File.exist?(@config[:database].to_s) end |
Instance Method Details
#active? ⇒ Boolean
163 164 165 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 163 def active? @raw_connection && !@raw_connection.closed? end |
#add_column(table_name, column_name, type, **options) ⇒ Object
:nodoc:
257 258 259 260 261 262 263 264 265 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 257 def add_column(table_name, column_name, type, **) #:nodoc: if invalid_alter_table_type?(type, ) alter_table(table_name) do |definition| definition.column(column_name, type, **) end else super end end |
#add_reference(table_name, ref_name, **options) ⇒ Object Also known as: add_belongs_to
:nodoc:
328 329 330 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 328 def add_reference(table_name, ref_name, **) # :nodoc: super(table_name, ref_name, type: :integer, **) end |
#add_timestamps(table_name, **options) ⇒ Object
315 316 317 318 319 320 321 322 323 324 325 326 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 315 def (table_name, **) [:null] = false if [:null].nil? if !.key?(:precision) [:precision] = 6 end alter_table(table_name) do |definition| definition.column :created_at, :datetime, ** definition.column :updated_at, :datetime, ** end end |
#build_insert_sql(insert) ⇒ Object
:nodoc:
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 356 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. { |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:
303 304 305 306 307 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 303 def change_column(table_name, column_name, type, **) #:nodoc: alter_table(table_name) do |definition| definition.change_column(column_name, type, **) end end |
#change_column_default(table_name, column_name, default_or_changes) ⇒ Object
:nodoc:
284 285 286 287 288 289 290 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 284 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:
292 293 294 295 296 297 298 299 300 301 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 292 def change_column_null(table_name, column_name, null, default = nil) #:nodoc: validate_change_column_null_argument!(null) unless null || default.nil? internal_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 |
#check_all_foreign_keys_valid! ⇒ Object
:nodoc:
219 220 221 222 223 224 225 226 227 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 219 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) end end |
#check_version ⇒ Object
387 388 389 390 391 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 387 def check_version if database_version < "3.8.0" raise "Your version of SQLite (#{database_version}) is too old. Active Record supports SQLite >= 3.8." end end |
#disable_referential_integrity ⇒ Object
REFERENTIAL INTEGRITY ====================================
205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 205 def disable_referential_integrity # :nodoc: old_foreign_keys = query_value("PRAGMA foreign_keys") old_defer_foreign_keys = query_value("PRAGMA defer_foreign_keys") 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.
175 176 177 178 179 180 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 175 def disconnect! super @raw_connection&.close rescue nil @raw_connection = nil end |
#encoding ⇒ Object
Returns the current database encoding format as a string, eg: 'UTF-8'
191 192 193 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 191 def encoding any_raw_connection.encoding.to_s end |
#foreign_keys(table_name) ⇒ Object
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 333 def foreign_keys(table_name) # SQLite returns 1 row for each column of composite foreign keys. fk_info = internal_exec_query("PRAGMA foreign_key_list(#{quote(table_name)})", "SCHEMA") 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 = { on_delete: extract_foreign_key_action(row["on_delete"]), on_update: extract_foreign_key_action(row["on_update"]) } if group.one? [:column] = row["from"] [:primary_key] = row["to"] else [:column] = group.map { |row| row["from"] } [:primary_key] = group.map { |row| row["to"] } end # DIFFERENCE: FQN ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(table_name, row["table"], ) end end |
#get_database_version ⇒ Object
:nodoc:
383 384 385 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 383 def get_database_version # :nodoc: SQLite3Adapter::Version.new(query_value("SELECT sqlite_version(*)", "SCHEMA")) end |
#native_database_types ⇒ Object
:nodoc:
186 187 188 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 186 def native_database_types #:nodoc: NATIVE_DATABASE_TYPES end |
#new_column_from_field(table_name, field, definitions) ⇒ Object
DIFFERENCE: here to
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 394 def new_column_from_field(table_name, field, definitions) default = field["dflt_value"] = (field["type"]) default_value = extract_value_from_default(default) default_function = extract_default_function(default_value, default) rowid = is_column_the_rowid?(field, definitions) ActiveRecord::ConnectionAdapters::SQLite3Column.new( field["name"], default_value, , field["notnull"].to_i == 0, default_function, collation: field["collation"], auto_increment: field["auto_increment"], rowid: rowid ) end |
#primary_keys(table_name) ⇒ Object
SCHEMA STATEMENTS ========================================
231 232 233 234 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 231 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:
267 268 269 270 271 272 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 267 def remove_column(table_name, column_name, type = nil, **) #: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:
274 275 276 277 278 279 280 281 282 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 274 def remove_columns(table_name, *column_names, type: nil, **) # :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:
236 237 238 239 240 241 242 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 236 def remove_index(table_name, column_name = nil, **) # :nodoc: return if [:if_exists] && !index_exists?(table_name, column_name, **) index_name = index_name_for_remove(table_name, column_name, ) internal_exec_query "DROP INDEX #{quote_column_name(index_name)}" end |
#rename_column(table_name, column_name, new_column_name) ⇒ Object
:nodoc:
309 310 311 312 313 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 309 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')
249 250 251 252 253 254 255 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 249 def rename_table(table_name, new_name, **) validate_table_length!(new_name) unless [:_uses_legacy_table_name] schema_cache.clear_data_source_cache!(table_name.to_s) schema_cache.clear_data_source_cache!(new_name.to_s) internal_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
119 120 121 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 119 def requires_reloading? true end |
#return_value_after_insert?(column) ⇒ Boolean
:nodoc:
167 168 169 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 167 def return_value_after_insert?(column) # :nodoc: column.auto_populated? end |
#shared_cache? ⇒ Boolean
:nodoc:
375 376 377 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 375 def shared_cache? # :nodoc: @config.fetch(:flags, 0).anybits?(::SQLite3::Constants::Open::SHAREDCACHE) end |
#supports_check_constraints? ⇒ Boolean
127 128 129 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 127 def supports_check_constraints? true end |
#supports_common_table_expressions? ⇒ Boolean
143 144 145 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 143 def supports_common_table_expressions? database_version >= "3.8.3" end |
#supports_concurrent_connections? ⇒ Boolean
DIFFERENCE: active?, reconnect!, disconnect! handles by arjdbc core
159 160 161 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 159 def supports_concurrent_connections? !@memory_database end |
#supports_datetime_with_precision? ⇒ Boolean
135 136 137 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 135 def supports_datetime_with_precision? true end |
#supports_ddl_transactions? ⇒ Boolean
99 100 101 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 99 def supports_ddl_transactions? true end |
#supports_explain? ⇒ Boolean
195 196 197 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 195 def supports_explain? true end |
#supports_expression_index? ⇒ Boolean
115 116 117 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 115 def supports_expression_index? database_version >= "3.9.0" end |
#supports_foreign_keys? ⇒ Boolean
123 124 125 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 123 def supports_foreign_keys? true end |
#supports_index_sort_order? ⇒ Boolean
182 183 184 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 182 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?
151 152 153 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 151 def supports_insert_on_conflict? database_version >= "3.24.0" end |
#supports_insert_returning? ⇒ Boolean
147 148 149 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 147 def supports_insert_returning? database_version >= "3.35.0" end |
#supports_json? ⇒ Boolean
139 140 141 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 139 def supports_json? true end |
#supports_lazy_transactions? ⇒ Boolean
199 200 201 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 199 def supports_lazy_transactions? true end |
#supports_partial_index? ⇒ Boolean
111 112 113 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 111 def supports_partial_index? true end |
#supports_savepoints? ⇒ Boolean
103 104 105 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 103 def supports_savepoints? true end |
#supports_transaction_isolation? ⇒ Boolean
107 108 109 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 107 def supports_transaction_isolation? true end |
#supports_views? ⇒ Boolean
131 132 133 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 131 def supports_views? true end |
#use_insert_returning? ⇒ Boolean
379 380 381 |
# File 'lib/arjdbc/sqlite3/adapter.rb', line 379 def use_insert_returning? @use_insert_returning end |