Class: ActiveRecord::Tasks::VirgodbDatabaseTasks
- Inherits:
-
SQLiteDatabaseTasks
- Object
- SQLiteDatabaseTasks
- ActiveRecord::Tasks::VirgodbDatabaseTasks
- Defined in:
- lib/active_record/tasks/virgodb_database_tasks.rb
Overview
ActiveRecord::Tasks::SQLiteDatabaseTasks#structure_dump just shells
out to the real sqlite3 CLI (.schema --nosys, or a raw SELECT sql FROM sqlite_master when a host app has any
ActiveRecord::SchemaDumper.ignore_tables configured -- e.g. excluding
tables owned by a separate replication/backup mechanism) against the
configured database file --
DDL only. ActiveRecord::Tasks::DatabaseTasks.dump_schema then
special-cases exactly one table on top of that: if schema_migrations
exists, it appends that table's real row data (connection .dump_schema_versions) to the same dump file, because Rails' own
migration bookkeeping needs those rows to survive a db:schema:load/
structure_load, not just the table shape.
schema_versions (this adapter's own bookkeeping table, plural,
distinct from Rails' singular schema_migrations) needs exactly the
same treatment and doesn't get it for free: it holds real data (the
versioned column list compact::schema_from_columns on the Rust side
depends on), not just structure, and Rails has no way to know that a
table it didn't create needs the same row-preserving special case.
Confirmed empirically: without this, a fresh database prepared via
structure_load (which Rails does automatically whenever a db:migrate
invocation for a later environment/connection finds an existing,
version-matching dump already on disk from an earlier one -- not
something this adapter can opt out of) ends up with the real
host-app table but an EMPTY schema_versions, so
Manifest::current_schema_version() on the Rust side returns None
even though the SQLite table itself is correct.
Constant Summary collapse
- DEFAULT_DATA_DIR_PROVIDER =
lambda do |sql_table_name| Rails.root.join("storage", "#{Rails.env}_virgodb_#{sql_table_name}_data").to_s end
Class Attribute Summary collapse
-
.data_dir_provider ⇒ Object
Optional host-app hook:
->(sql_table_name) { path_or_nil }. -
.table_layout_provider ⇒ Object
Optional host-app hook:
->(sql_table_name) { {sort_by:, key_column:, partition_column:} or nil }.
Instance Method Summary collapse
-
#drop ⇒ Object
Overridden (not just inherited from SQLiteDatabaseTasks) so dropping the manifest also cleans up whatever data_dir_provider says each of its tables' physical files live under.
- #structure_dump(filename, extra_flags) ⇒ Object
Class Attribute Details
.data_dir_provider ⇒ Object
Optional host-app hook: ->(sql_table_name) { path_or_nil }.
Convention over configuration, not opt-in like table_layout_provider
above: this gem is Rails-specific (see the class doc comment
above -- "Lets any Rails app..."), so it bakes in the same
convention Rails' own generators use for SQLite's storage location
(config/database.yml's generated storage/#{Rails.env}.sqlite3)
-- storage/#{Rails.env}_virgodb_#{sql_table_name}_data, right
next to the manifest. A host app gets working data-dir cleanup
with zero setup. One with its own directory convention calls
data_dir_provider = to override; = nil opts every table out
entirely, same as plain SQLiteDatabaseTasks -- distinguished from
"never touched this accessor" via defined? below so an explicit
opt-out can't be silently overridden by the default.
63 64 65 |
# File 'lib/active_record/tasks/virgodb_database_tasks.rb', line 63 def data_dir_provider defined?(@data_dir_provider) ? @data_dir_provider : DEFAULT_DATA_DIR_PROVIDER end |
.table_layout_provider ⇒ Object
Optional host-app hook: ->(sql_table_name) { {sort_by:, key_column:, partition_column:} or nil }. Purely a documentation comment written
above CREATE TABLE at dump time -- nothing on the Rust or Ruby side
ever reads it back. This adapter gem stays host-app-agnostic (see
the class doc comment above: "lets any Rails app..."), so it can't
hardcode any one host app's sort_by/key_column config (that's
app/services/virgodb/registry.rb's job, which already has this
exact data for real -- passed to Virgodb.start_maintenance on every
boot). A host app that wants it surfaced sets this once, e.g. in an
initializer; left nil, structure_dump behaves exactly as before.
48 49 50 |
# File 'lib/active_record/tasks/virgodb_database_tasks.rb', line 48 def table_layout_provider @table_layout_provider end |
Instance Method Details
#drop ⇒ Object
Overridden (not just inherited from SQLiteDatabaseTasks) so dropping the manifest also cleans up whatever data_dir_provider says each of its tables' physical files live under. db:drop only ever knew about the ONE file database.yml declares -- left alone, it silently orphans every Parquet run file and Tier 1 inline-batch pointer file forever, since there's no catalog left afterward to even reference them (compact::vacuum, which cleans those up via the manifest's own orphaned_files table, can't reach them either once the manifest's gone).
Reads which tables exist via a fresh, read-only, raw SQLite3
connection (not connection/ActiveRecord::Base.lease_connection
-- unlike structure_dump, drop doesn't establish one for this
specific db_config, and this shouldn't depend on whatever happens
to be currently leased) BEFORE calling super, since super deletes
the manifest file -- schema_versions goes with it.
96 97 98 99 100 101 102 103 104 |
# File 'lib/active_record/tasks/virgodb_database_tasks.rb', line 96 def drop provider = self.class.data_dir_provider table_names = provider ? table_names_for_data_dir_cleanup : [] super table_names.each do |table_name| dir = provider.call(table_name) FileUtils.rm_rf(dir) if dir end end |
#structure_dump(filename, extra_flags) ⇒ Object
73 74 75 76 77 78 |
# File 'lib/active_record/tasks/virgodb_database_tasks.rb', line 73 def structure_dump(filename, extra_flags) super reformat_create_table_statements!(filename) annotate_physical_layout!(filename) dump_schema_versions!(filename) end |