// @ts-check const varDatabaseDbHandler = require("./varDatabaseDbHandler"); const generateColumnDescription = require("./generateColumnDescription"); const supplementTable = require("./supplementTable"); const dbHandler = require("./dbHandler"); /** ****************************************************************************** */ /** ****************************************************************************** */ /** ****************************************************************************** */ /** ****************************************************************************** */ /** ****************************************************************************** */ /** ****************************************************************************** */ /** * * @param {object} params * @param {string} params.dbFullName * @param {string} params.tableName * @param {any[]} params.tableInfoArray * @param {import("../../types").DSQL_DatabaseSchemaType[]} [params.dbSchema] * @param {import("../../types").DSQL_TableSchemaType} [params.tableSchema] * @param {any} [params.recordedDbEntry] * @param {boolean} [params.clone] - Is this a newly cloned table? * @returns */ module.exports = async function createTable({ dbFullName, tableName, tableInfoArray, dbSchema, clone, tableSchema, recordedDbEntry, }) { /** * Format tableInfoArray * * @description Format tableInfoArray */ const finalTable = supplementTable({ tableInfoArray: tableInfoArray }); /** * Grab Schema * * @description Grab Schema */ const createTableQueryArray = []; createTableQueryArray.push(`CREATE TABLE IF NOT EXISTS \`${tableName}\` (`); //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// try { if (!recordedDbEntry) { throw new Error("Recorded Db entry not found!"); } const existingTable = await varDatabaseDbHandler({ database: "datasquirel", queryString: `SELECT * FROM user_database_tables WHERE db_id = ? AND table_slug = ?`, queryValuesArray: [recordedDbEntry.id, tableSchema?.tableName], }); /** @type {import("../../types").MYSQL_user_database_tables_table_def} */ const table = existingTable?.[0]; if (!table?.id) { const newTableEntry = await dbHandler({ query: `INSERT INTO user_database_tables SET ?`, values: { user_id: recordedDbEntry.user_id, db_id: recordedDbEntry.id, db_slug: recordedDbEntry.db_slug, table_name: tableSchema?.tableFullName, table_slug: tableSchema?.tableName, child_table: tableSchema?.childTable ? "1" : null, child_table_parent_database: tableSchema?.childTableDbFullName || null, child_table_parent_table: tableSchema?.childTableName || null, date_created: Date(), date_created_code: Date.now(), date_updated: Date(), date_updated_code: Date.now(), }, database: "datasquirel", }); } } catch (error) {} //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// let primaryKeySet = false; /** @type {import("../../types").DSQL_FieldSchemaType[]} */ let foreignKeys = []; //////////////////////////////////////// for (let i = 0; i < finalTable.length; i++) { const column = finalTable[i]; const { fieldName, dataType, nullValue, primaryKey, autoIncrement, defaultValue, defaultValueLiteral, foreignKey, updatedField, onUpdate, onUpdateLiteral, onDelete, onDeleteLiteral, defaultField, encrypted, json, newTempField, notNullValue, originName, plainText, pattern, patternFlags, richText, } = column; if (foreignKey) { foreignKeys.push({ ...column, }); } let { fieldEntryText, newPrimaryKeySet } = generateColumnDescription({ columnData: column, primaryKeySet: primaryKeySet, }); primaryKeySet = newPrimaryKeySet; //////////////////////////////////////// const comma = (() => { if (foreignKeys[0]) return ","; if (i === finalTable.length - 1) return ""; return ","; })(); createTableQueryArray.push(" " + fieldEntryText + comma); //////////////////////////////////////// } //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// if (foreignKeys[0]) { foreignKeys.forEach((foreighKey, index, array) => { const fieldName = foreighKey.fieldName; const destinationTableName = foreighKey.foreignKey?.destinationTableName; const destinationTableColumnName = foreighKey.foreignKey?.destinationTableColumnName; const cascadeDelete = foreighKey.foreignKey?.cascadeDelete; const cascadeUpdate = foreighKey.foreignKey?.cascadeUpdate; const foreignKeyName = foreighKey.foreignKey?.foreignKeyName; const comma = (() => { if (index === foreignKeys.length - 1) return ""; return ","; })(); createTableQueryArray.push( ` CONSTRAINT \`${foreignKeyName}\` FOREIGN KEY (\`${fieldName}\`) REFERENCES \`${destinationTableName}\`(${destinationTableColumnName})${ cascadeDelete ? " ON DELETE CASCADE" : "" }${cascadeUpdate ? " ON UPDATE CASCADE" : ""}${comma}` ); }); } //////////////////////////////////////// createTableQueryArray.push( `) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;` ); const createTableQuery = createTableQueryArray.join("\n"); //////////////////////////////////////// const newTable = await varDatabaseDbHandler({ queryString: createTableQuery, database: dbFullName, }); return newTable; //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// }; /** ****************************************************************************** */ /** ****************************************************************************** */ /** ****************************************************************************** */ /** ****************************************************************************** */ /** ****************************************************************************** */