import createTable from "./create-table"; import MariaDBQuoteGen from "./mariadb-quote-gen"; import resolveTable from "./resolve-table"; import runSchemaQuery, { querySchemaRows } from "./run-schema-query"; import schemaCondition from "./schema-condition"; import { dropObsoleteForeignKeys, ensureForeignKeys, } from "./sync-foreign-keys"; import syncIndexes from "./sync-indexes"; import syncPrimaryKey from "./sync-primary-key"; import syncTableOptions from "./sync-table-options"; import syncUniqueConstraints from "./sync-unique-constraints"; import updateTable from "./update-table"; import upsertDbManagerTable, { removeDbManagerTable, } from "./upsert-db-manager-table"; export default async function handleDBSchemaTable({ db_schema, config, table, db_manager_table_name, existing_live_table, }) { const resolvedTable = resolveTable(table, db_schema); let tableExistsTracked = Boolean(db_manager_table_name); let tableExistsLive = Boolean(existing_live_table?.TABLE_NAME); if (resolvedTable.tableNameOld && resolvedTable.tableNameOld !== resolvedTable.tableName) { // Only hit information_schema when a rename is declared const schemaCond = schemaCondition(config); const liveTables = await querySchemaRows({ query: `SELECT TABLE_NAME FROM information_schema.TABLES WHERE ${schemaCond.where} AND TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = ?`, values: [...schemaCond.values, resolvedTable.tableNameOld], config, }); if (liveTables.length > 0) { console.log(`Renaming table: ${resolvedTable.tableNameOld} -> ${resolvedTable.tableName}`); await runSchemaQuery({ query: `RENAME TABLE ${MariaDBQuoteGen(resolvedTable.tableNameOld)} TO ${MariaDBQuoteGen(resolvedTable.tableName)}`, config, }); await upsertDbManagerTable({ tableName: resolvedTable.tableName, config, }); await removeDbManagerTable({ tableName: resolvedTable.tableNameOld, config, }); tableExistsTracked = true; tableExistsLive = true; } } if (!tableExistsTracked && !tableExistsLive) { await createTable({ table: resolvedTable, config }); await upsertDbManagerTable({ tableName: resolvedTable.tableName, config, }); } else { // Columns first (also drops FKs on removed/modified columns) await updateTable({ table: resolvedTable, config, }); await upsertDbManagerTable({ tableName: resolvedTable.tableName, config, }); } // Order matters: // 1. Table options (engine/collation) // 2. Drop obsolete/changed FKs (unlocks index cleanup) // 3. Primary key // 4. Indexes / uniques (FK columns need supporting indexes) // 5. Ensure foreign keys exist await syncTableOptions({ table: resolvedTable, config }); await dropObsoleteForeignKeys({ table: resolvedTable, config }); await syncPrimaryKey({ table: resolvedTable, config }); await syncIndexes({ table: resolvedTable, config }); await syncUniqueConstraints({ table: resolvedTable, config }); await ensureForeignKeys({ table: resolvedTable, config }); }