Grok 5 updates
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
import _ from "lodash";
|
||||
import { AppData } from "../../data/app-data";
|
||||
import type {
|
||||
BUN_MARIADB_INFORMATION_SCHEMA_TABLES,
|
||||
CreateDBSchemaParams,
|
||||
} from "../../types";
|
||||
import dbHandler from "../db-handler";
|
||||
import getExistingTablesFromTablesManagerTable from "./get-existing-tables-from-tables-manager-table";
|
||||
import handleDBSchemaTable from "./handle-db-schema-table";
|
||||
import getExistingTablesFromTablesManagerTable from "./get-existing-tables-from-tables-manager-table";
|
||||
import MariaDBQuoteGen from "./mariadb-quote-gen";
|
||||
import runSchemaQuery, { querySchemaRows } from "./run-schema-query";
|
||||
import schemaCondition from "./schema-condition";
|
||||
import { removeDbManagerTable } from "./upsert-db-manager-table";
|
||||
|
||||
export default async function handleDBSchemaTables(
|
||||
params: CreateDBSchemaParams,
|
||||
@@ -19,34 +23,26 @@ export default async function handleDBSchemaTables(
|
||||
const existing_schema_tables =
|
||||
await getExistingTablesFromTablesManagerTable(params);
|
||||
|
||||
const schemaCond = schemaCondition(config);
|
||||
const existing_live_tables =
|
||||
await dbHandler<BUN_MARIADB_INFORMATION_SCHEMA_TABLES>({
|
||||
query: `SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME != ?`,
|
||||
config: params.config,
|
||||
values: [AppData["DbSchemaManagerTableName"]],
|
||||
await querySchemaRows<BUN_MARIADB_INFORMATION_SCHEMA_TABLES>({
|
||||
query: `SELECT TABLE_NAME FROM information_schema.TABLES WHERE ${schemaCond.where} AND TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME != ?`,
|
||||
values: [...schemaCond.values, AppData["DbSchemaManagerTableName"]],
|
||||
config,
|
||||
});
|
||||
|
||||
for (let i = 0; i < db_schema.tables.length; i++) {
|
||||
const table = db_schema.tables[i];
|
||||
if (!table) continue;
|
||||
|
||||
const existing_table = existing_schema_tables.find(
|
||||
(t) => t == table?.tableName,
|
||||
(t) => t == table.tableName,
|
||||
);
|
||||
|
||||
const existing_live_table = existing_live_tables.payload?.find(
|
||||
(t) => t.TABLE_NAME == table?.tableName,
|
||||
const existing_live_table = existing_live_tables.find(
|
||||
(t) => t.TABLE_NAME == table.tableName,
|
||||
);
|
||||
|
||||
if (!table) {
|
||||
if (existing_live_table?.TABLE_NAME) {
|
||||
await dbHandler<BUN_MARIADB_INFORMATION_SCHEMA_TABLES>({
|
||||
query: `DROP TABLE ${existing_live_table.TABLE_NAME}`,
|
||||
config: params.config,
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
await handleDBSchemaTable({
|
||||
...params,
|
||||
table,
|
||||
@@ -54,4 +50,84 @@ export default async function handleDBSchemaTables(
|
||||
existing_live_table,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop tables tracked by the manager but no longer in the schema.
|
||||
* Skip drops when remaining schema tables still reference the table via FK
|
||||
* (e.g. external tables like `users` that are referenced but not managed).
|
||||
*/
|
||||
const schemaTableNames = db_schema.tables.map((t) => t.tableName);
|
||||
const tablesToDrop = _.uniq(
|
||||
existing_schema_tables.filter(
|
||||
(tableName): tableName is string =>
|
||||
Boolean(tableName) && !schemaTableNames.includes(tableName!),
|
||||
),
|
||||
);
|
||||
|
||||
if (tablesToDrop.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fkRows = await querySchemaRows<{
|
||||
TABLE_NAME: string;
|
||||
REFERENCED_TABLE_NAME: string;
|
||||
}>({
|
||||
query: `SELECT TABLE_NAME, REFERENCED_TABLE_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE ${schemaCond.where} AND REFERENCED_TABLE_NAME IS NOT NULL`,
|
||||
values: schemaCond.values,
|
||||
config,
|
||||
});
|
||||
|
||||
const referencedByRemaining = new Map<string, string[]>();
|
||||
for (const row of fkRows) {
|
||||
if (
|
||||
!row.REFERENCED_TABLE_NAME ||
|
||||
!tablesToDrop.includes(row.REFERENCED_TABLE_NAME)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Referenced by a table we are keeping
|
||||
if (
|
||||
schemaTableNames.includes(row.TABLE_NAME) ||
|
||||
!tablesToDrop.includes(row.TABLE_NAME)
|
||||
) {
|
||||
const list = referencedByRemaining.get(row.REFERENCED_TABLE_NAME) || [];
|
||||
if (!list.includes(row.TABLE_NAME)) {
|
||||
list.push(row.TABLE_NAME);
|
||||
}
|
||||
referencedByRemaining.set(row.REFERENCED_TABLE_NAME, list);
|
||||
}
|
||||
}
|
||||
|
||||
const safeToDrop: string[] = [];
|
||||
|
||||
for (const tableName of tablesToDrop) {
|
||||
const dependents = referencedByRemaining.get(tableName);
|
||||
if (dependents && dependents.length > 0) {
|
||||
console.warn(
|
||||
`Skipping drop of table \`${tableName}\`: still referenced by ${dependents.join(", ")}. Removing from schema manager tracking only.`,
|
||||
);
|
||||
await removeDbManagerTable({ tableName, config });
|
||||
continue;
|
||||
}
|
||||
safeToDrop.push(tableName);
|
||||
}
|
||||
|
||||
if (safeToDrop.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
await runSchemaQuery({ query: `SET FOREIGN_KEY_CHECKS = 0`, config });
|
||||
try {
|
||||
for (const tableName of safeToDrop) {
|
||||
console.log(`Dropping table: ${tableName}`);
|
||||
await runSchemaQuery({
|
||||
query: `DROP TABLE IF EXISTS ${MariaDBQuoteGen(tableName)}`,
|
||||
config,
|
||||
});
|
||||
await removeDbManagerTable({ tableName, config });
|
||||
}
|
||||
} finally {
|
||||
await runSchemaQuery({ query: `SET FOREIGN_KEY_CHECKS = 1`, config });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user