Prostore::Adapter::SQLite::Rebuild
Generic table-rebuild helper for SQLite operations that have no native ALTER counterpart: tightening a column to NOT NULL, adding/removing/changing FK semantics on a non-empty table, etc.
The dance:
- CREATE TABLE
__prostore_rebuild (... new schema ...)
- INSERT INTO __prostore_rebuild SELECT ... FROM
- DROP TABLE
- ALTER TABLE __prostore_rebuild RENAME TO
- Re-create every index that existed on the old table.
SQLite can rename a table in place (RENAME TO), and indexes on the rebuilt table are dropped along with the original table. We capture them before the drop and re-issue CREATE INDEX statements on the new table afterward.
Used by ApplyNotNull and by foreign-key changes against non-empty tables.
Constants
REBUILD_SUFFIX = "__prostore_rebuild"Instance methods
capture_index_statements(executor : Prostore::Adapter::Base::Executor, table : String) : Array(String)SourceCapture each non-PK index's CREATE INDEX statement from sqlite_master so we can re-issue after rebuild. PK indexes are implicit and don't appear here.
rebuild(adapter : Prostore::Adapter::SQLite::Adapter, executor : Prostore::Adapter::Base::Executor, table : String, new_columns_sql : Array(String), new_constraints_sql : Array(String), column_mapping : Array(NamedTuple(old_expr: String, new_name: String)), existing_indexes_sql : Array(String)) : NilSourceRebuild
tableso that its column DDL matchesnew_columns_sql(an array of pre-rendered column-def fragments). Foreign-key and other table-level constraints are passed vianew_constraints_sql. Indexes are re-created from the capturedexisting_indexes.column_mappingmaps OLD column names to expressions used in the SELECT that copies data: typicallyOLD.colfor unchanged columns and a literal/expression for transformed ones. If a column's value need not change between old and new, just pass its name. - INSERT INTO __prostore_rebuild SELECT ... FROM