module
Prostore::Adapter::SQLite::Rebuild
Overview
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.
Extended Modules
Defined in:
prostore/adapter/sqlite/rebuild.cr
Constant Summary
-
REBUILD_SUFFIX =
"__prostore_rebuild"
Instance Method Summary
-
#capture_index_statements(executor : Prostore::Adapter::Base::Executor, table : String) : Array(String)
Capture each non-PK index's CREATE INDEX statement from sqlite_master so we can re-issue after rebuild.
-
#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)) : Nil
Rebuild
tableso that its column DDL matchesnew_columns_sql(an array of pre-rendered column-def fragments).
Instance Method Detail
def capture_index_statements(executor : Prostore::Adapter::Base::Executor, table : String) : Array(String) #Capture 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.
def 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)) : Nil #Rebuild
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