import { DSQL_DatabaseSchemaType, DSQL_MARIADB_SHOW_INDEXES_TYPE, DSQL_MYSQL_FOREIGN_KEYS_Type, DSQL_TableSchemaType, } from "../../types"; import createTableHandleTableRecord from "./create-table-handle-table-record"; import { DSQL_DATASQUIREL_USER_DATABASES } from "../../types/dsql"; import _ from "lodash"; import dbHandler from "../../functions/backend/dbHandler"; type Params = { dbFullName: string; tableName: string; tableSchema: DSQL_TableSchemaType; dbSchema: DSQL_DatabaseSchemaType; recordedDbEntry?: DSQL_DATASQUIREL_USER_DATABASES; isMain?: boolean; }; /** * # Update table function */ export default async function updateTableInit({ dbFullName, tableName, tableSchema, recordedDbEntry, isMain, }: Params) { /** * @description Grab Table Record */ if (!recordedDbEntry && !isMain) { throw new Error("Recorded Db entry not found!"); } let tableID = await createTableHandleTableRecord({ recordedDbEntry, tableSchema, update: true, isMain, }); if (!tableID && !isMain) { throw new Error("Recorded Table entry not found!"); } /** * Handle Table Default Collation * * @description Update Column Collation */ if (tableSchema.collation) { try { const existingCollation = (await dbHandler({ query: `SHOW TABLE STATUS LIKE '${tableName}'`, config: { database: dbFullName }, })) as any[]; const existingCollationStr = existingCollation?.[0].Collation; if (existingCollationStr !== tableSchema.collation) { await dbHandler({ query: `ALTER TABLE \`${dbFullName}\`.\`${tableName}\` CONVERT TO CHARACTER SET utf8mb4 COLLATE ${tableSchema.collation}`, }); } } catch (error) {} } /** * Drop All Foreign Keys * =================================================== * @description Find all existing foreign keys and drop * them */ const allForeignKeys = (await dbHandler({ query: `SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = '${dbFullName}' AND TABLE_NAME='${tableName}' AND CONSTRAINT_TYPE='FOREIGN KEY'`, })) as DSQL_MYSQL_FOREIGN_KEYS_Type[] | null; if (allForeignKeys?.[0]) { let dropFkSQL = `ALTER TABLE \`${dbFullName}\`.\`${tableName}\``; for (let c = 0; c < allForeignKeys.length; c++) { const { CONSTRAINT_NAME } = allForeignKeys[c]; if (CONSTRAINT_NAME.match(/PRIMARY/)) continue; dropFkSQL += ` DROP FOREIGN KEY \`${CONSTRAINT_NAME}\`,`; } const finalSQL = dropFkSQL.endsWith(",") ? dropFkSQL.replace(/\,$/, "") : undefined; if (finalSQL) { await dbHandler({ query: finalSQL, }); } } /** * Drop All Unique Constraints * =================================================== * @description Find all existing unique field constraints * and remove them */ const allUniqueConstraints = (await dbHandler({ query: `SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = '${dbFullName}' AND TABLE_NAME='${tableName}' AND CONSTRAINT_TYPE='UNIQUE'`, })) as DSQL_MYSQL_FOREIGN_KEYS_Type[] | null; if (allUniqueConstraints?.[0]) { let dropIndxSQL = `ALTER TABLE \`${dbFullName}\`.\`${tableName}\``; for (let c = 0; c < allUniqueConstraints.length; c++) { const { CONSTRAINT_NAME } = allUniqueConstraints[c]; dropIndxSQL += ` DROP INDEX ${CONSTRAINT_NAME},`; } const finalDropIndxSQL = dropIndxSQL.endsWith(",") ? dropIndxSQL.replace(/\,$/, "") : undefined; if (finalDropIndxSQL) { await dbHandler({ query: finalDropIndxSQL, }); } } /** * Drop All Indexes * =================================================== * @description Find all existing foreign keys and drop * them */ const allMariadbIndexes = (await dbHandler({ query: `SHOW INDEXES FROM \`${dbFullName}\`.\`${tableName}\``, })) as DSQL_MARIADB_SHOW_INDEXES_TYPE[] | null; if (allMariadbIndexes?.[0]) { let dropIndxs = `ALTER TABLE \`${dbFullName}\`.\`${tableName}\``; for (let c = 0; c < allMariadbIndexes.length; c++) { const { Key_name } = allMariadbIndexes[c]; if (Key_name.match(/PRIMARY/)) continue; dropIndxs += ` DROP INDEX \`${Key_name}\`,`; } const finalDropIndxs = dropIndxs.endsWith(",") ? dropIndxs.replace(/\,$/, "") : undefined; if (finalDropIndxs) { const dropFkRes = await dbHandler({ query: finalDropIndxs, }); } } return { tableID }; }