Major version update. Major bugfixes. Security vulnerabilites fixed
This commit is contained in:
Vendored
+66
@@ -0,0 +1,66 @@
|
||||
import _ from "lodash";
|
||||
import createDBManagerTable from "./create-db-manager-table";
|
||||
import dropRemovedTables from "./drop-removed-tables";
|
||||
import getExistingTablesFromTablesManagerTable from "./get-existing-tables-from-tables-manager-table";
|
||||
import handleDBSchemaTable from "./handle-db-schema-table";
|
||||
import orderDBSchema from "./order-db-schema";
|
||||
/**
|
||||
* # Sync the database to the schema
|
||||
* @description Changed tables are rebuilt by copying into a new table and
|
||||
* dropping the old one. With foreign keys ON, `DROP TABLE` runs an implicit
|
||||
* `DELETE FROM` that fires `ON DELETE CASCADE` on child tables, so keys are
|
||||
* disabled for the sync and checked before committing. (`PRAGMA
|
||||
* foreign_keys` is a no-op inside a transaction.) With `dry_run` the
|
||||
* transaction is rolled back, so `changes` is the exact plan.
|
||||
*/
|
||||
export default function createDBSchema(params) {
|
||||
const { db, dry_run } = params;
|
||||
/**
|
||||
* Reorder Tables (parents before children with FKs)
|
||||
*/
|
||||
const db_schema = orderDBSchema(params);
|
||||
db.run("PRAGMA foreign_keys = OFF;");
|
||||
db.run("BEGIN");
|
||||
try {
|
||||
/**
|
||||
* Create Schema Manager Table
|
||||
*/
|
||||
createDBManagerTable({ db });
|
||||
const existing_tables = getExistingTablesFromTablesManagerTable({
|
||||
db,
|
||||
});
|
||||
/**
|
||||
* Create or update tables
|
||||
*/
|
||||
for (const table of db_schema.tables) {
|
||||
handleDBSchemaTable({
|
||||
...params,
|
||||
db_schema,
|
||||
table,
|
||||
existing_tables,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Drop tables that no longer exist in schema
|
||||
*/
|
||||
dropRemovedTables({
|
||||
...params,
|
||||
existing_tables,
|
||||
schema_tables: db_schema.tables.map((t) => t.tableName),
|
||||
});
|
||||
const fkViolations = db.query(`PRAGMA foreign_key_check`).all();
|
||||
if (fkViolations.length) {
|
||||
const tables = _.uniq(fkViolations.map((v) => `${v.table} -> ${v.parent}`));
|
||||
throw new Error(`Foreign key violations after schema sync: ${tables.join(", ")}`);
|
||||
}
|
||||
db.run(dry_run ? "ROLLBACK" : "COMMIT");
|
||||
}
|
||||
catch (error) {
|
||||
if (db.inTransaction)
|
||||
db.run("ROLLBACK");
|
||||
throw error;
|
||||
}
|
||||
finally {
|
||||
db.run("PRAGMA foreign_keys = ON;");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user