Class: ActiveRecord::ConnectionAdapters::VirgodbAdapter

Inherits:
SQLite3Adapter
  • Object
show all
Defined in:
lib/active_record/connection_adapters/virgodb_adapter.rb

Constant Summary collapse

ADAPTER_NAME =
"Virgodb"
TYPE_MAP =

type_map (AbstractAdapter) reads self.class::TYPE_MAP -- a plain constant lookup, not a method call -- so merely overriding initialize_type_map above does nothing on its own: without a TYPE_MAP constant of ITS OWN, VirgodbAdapter::TYPE_MAP constant lookup just walks up to the already-frozen SQLite3Adapter::TYPE_MAP (built at THAT class's load time, from the un-overridden method). Confirmed directly: the override above alone left every virgodb column's .type unchanged. SQLite3Adapter builds its own TYPE_MAP constant the exact same way (see its TYPE_MAP = Type::TypeMap.new .tap { |m| initialize_type_map(m) } line) specifically so subclasses can shadow it like this.

Type::TypeMap.new.tap { |m| initialize_type_map(m) }

Instance Method Summary collapse

Instance Method Details

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



218
219
220
221
222
# File 'lib/active_record/connection_adapters/virgodb_adapter.rb', line 218

def add_column(table_name, column_name, type, **options)
  result = super
  record_added_column!(table_name, column_name, type, options)
  result
end

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

Raises:

  • (NotImplementedError)


232
233
234
# File 'lib/active_record/connection_adapters/virgodb_adapter.rb', line 232

def change_column(table_name, column_name, type, **options)
  raise NotImplementedError, "virgodb schemas are additive-only -- an existing column's type can't change"
end

#configure_connectionObject

Real bug, found (not assumed) by testing: setting auto_vacuum = INCREMENTAL from create_table -- even from create_table's very FIRST call on a brand-new manifest, before any table exists -- was already too late. SQLite3Adapter's own configure_connection sets journal_mode = wal via DEFAULT_PRAGMAS (super, below) as part of establishing the connection itself, which happens before this adapter's create_table ever runs -- and switching journal_mode to WAL requires SQLite to actually write to the file (creating the -wal file, an implicit checkpoint), which "poisons" the database from auto_vacuum's perspective the same way any other content would. Confirmed directly: a manual PRAGMA auto_vacuum = INCREMENTAL issued immediately after establish_connection, before ANY table or migration ran, still silently failed. The pragma has to be set before super runs here, not merely before the first CREATE TABLE.

Second real bug, found the same way: configure_connection runs on EVERY new raw connection this adapter's pool ever opens, not just the manifest's first one -- so an unconditional auto_vacuum = unconditionally re-issued PRAGMA auto_vacuum='2' on every single one of them, forever. Once a manifest is genuinely in INCREMENTAL mode (the common case for any real, already-migrated manifest), re-setting it to that SAME value is not the free no-op re-setting an already-NONE manifest is: confirmed directly with a raw SQLite3 connection, re-issuing the SET pragma while a second connection holds an open BEGIN IMMEDIATE write transaction (exactly what virgodb's own maintenance thread does while compacting, see crates/compact/src/maintenance.rs) blocks for the full busy_timeout and then raises SQLite3::BusyException -- surfacing in a host app as an ActiveRecord::StatementTimeout on whatever request happened to need a brand-new pooled connection at that moment. A bare read (PRAGMA auto_vacuum with no argument) does NOT block the same way, confirmed the same way -- so skip the write once it's already reached the target value instead of paying that contention risk on every connection after the first.



133
134
135
136
137
138
# File 'lib/active_record/connection_adapters/virgodb_adapter.rb', line 133

def configure_connection
  if @raw_connection.respond_to?(:auto_vacuum=) && @raw_connection.auto_vacuum != 2
    @raw_connection.auto_vacuum = "incremental"
  end
  super
end

#create_table(table_name, **options, &block) ⇒ Object



212
213
214
215
216
# File 'lib/active_record/connection_adapters/virgodb_adapter.rb', line 212

def create_table(table_name, **options, &block)
  result = super
  record_schema_version!(table_name)
  result
end

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

Raises:

  • (NotImplementedError)


224
225
226
# File 'lib/active_record/connection_adapters/virgodb_adapter.rb', line 224

def remove_column(table_name, column_name, type = nil, **options)
  raise NotImplementedError, "virgodb schemas are additive-only -- columns can be added, never removed (see schema_versions)"
end

#rename_column(table_name, column_name, new_column_name) ⇒ Object

Raises:

  • (NotImplementedError)


228
229
230
# File 'lib/active_record/connection_adapters/virgodb_adapter.rb', line 228

def rename_column(table_name, column_name, new_column_name)
  raise NotImplementedError, "virgodb schemas are additive-only -- columns can't be renamed once created"
end