diff --git a/engine/engine/createDbFromSchema.js b/engine/engine/createDbFromSchema.js index 616a7af..f205568 100644 --- a/engine/engine/createDbFromSchema.js +++ b/engine/engine/createDbFromSchema.js @@ -30,219 +30,228 @@ const updateTable = require("./utils/updateTable"); * @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType[]} dbSchema - An array of database schema objects */ async function createDbFromSchema(dbSchema) { - /** - * Grab Schema - * - * @description Grab Schema - */ - - if (!dbSchema || !Array.isArray(dbSchema) || !dbSchema[0]) { - console.log("Invalid DB schema data"); - return; - } - - for (let i = 0; i < dbSchema.length; i++) { - /** @type {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} */ - const database = dbSchema[i]; - const { dbFullName, tables } = database; - - //////////////////////////////////////// - //////////////////////////////////////// - //////////////////////////////////////// - - /** @type {{ dbFullName: string }[] | null} */ - const dbCheck = await noDatabaseDbHandler({ query: `SELECT SCHEMA_NAME AS dbFullName FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${dbFullName}'` }); - - if (dbCheck && dbCheck[0]?.dbFullName) { - // Database Exists - } else { - const newDatabase = await noDatabaseDbHandler({ query: `CREATE DATABASE IF NOT EXISTS \`${dbFullName}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_bin` }); - } - - //////////////////////////////////////// - //////////////////////////////////////// - //////////////////////////////////////// - + try { /** - * Select all tables - * @type {{ TABLE_NAME: string }[] | null} - * @description Select All tables in target database + * Grab Schema + * + * @description Grab Schema */ - const allTables = await noDatabaseDbHandler({ query: `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='${dbFullName}'` }); + console.log("Starting createDbFromSchema ..."); - let tableDropped; - - if (!allTables) { - console.log("No Tables to Update"); - continue; + if (!dbSchema || !Array.isArray(dbSchema) || !dbSchema[0]) { + console.log("Invalid DB schema data"); + return; } - for (let tb = 0; tb < allTables.length; tb++) { - const { TABLE_NAME } = allTables[tb]; + for (let i = 0; i < dbSchema.length; i++) { + /** @type {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} */ + const database = dbSchema[i]; + const { dbFullName, tables } = database; - /** - * @description Check if TABLE_NAME is part of the tables contained - * in the user schema JSON. If it's not, the table is either deleted - * or the table name has been recently changed - */ - if (!tables.filter((_table) => _table.tableName === TABLE_NAME)[0]) { - const oldTableFilteredArray = tables.filter((_table) => _table.tableNameOld && _table.tableNameOld === TABLE_NAME); - - /** - * @description Check if this table has been recently renamed. Rename - * table id true. Drop table if false - */ - if (oldTableFilteredArray && oldTableFilteredArray[0]) { - console.log("Renaming Table"); - await varDatabaseDbHandler({ - queryString: `RENAME TABLE \`${oldTableFilteredArray[0].tableNameOld}\` TO \`${oldTableFilteredArray[0].tableName}\``, - database: dbFullName, - }); - } else { - console.log(`Dropping Table from ${dbFullName}`); - // deepcode ignore reDOS: - await varDatabaseDbHandler({ - queryString: `DROP TABLE \`${TABLE_NAME}\``, - database: dbFullName, - }); - - tableDropped = true; - } - } - } - - //////////////////////////////////////// - //////////////////////////////////////// - //////////////////////////////////////// - - /** - * @description Iterate through each table and perform table actions - */ - for (let t = 0; t < tables.length; t++) { - const table = tables[t]; - - if (tableDropped) continue; - - const { tableName, fields, indexes } = table; - - /** - * @description Check if table exists - */ - const tableCheck = await varDatabaseDbHandler({ - queryString: ` - SELECT EXISTS ( - SELECT - TABLE_NAME - FROM - information_schema.TABLES - WHERE - TABLE_SCHEMA = ? AND - TABLE_NAME = ? - ) AS tableExists`, - queryValuesArray: [dbFullName, table.tableName], - database: dbFullName, - }); + console.log("Now constructing database =>", database?.dbFullName); + //////////////////////////////////////// + //////////////////////////////////////// //////////////////////////////////////// - if (tableCheck && tableCheck[0]?.tableExists > 0) { + /** @type {{ dbFullName: string }[] | null} */ + const dbCheck = await noDatabaseDbHandler({ query: `SELECT SCHEMA_NAME AS dbFullName FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${dbFullName}'` }); + + console.log("DB CHeck =>", dbCheck); + + if (dbCheck && dbCheck[0]?.dbFullName) { + // Database Exists + } else { + const newDatabase = await noDatabaseDbHandler({ query: `CREATE DATABASE IF NOT EXISTS \`${dbFullName}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_bin` }); + } + + //////////////////////////////////////// + //////////////////////////////////////// + //////////////////////////////////////// + + /** + * Select all tables + * @type {{ TABLE_NAME: string }[] | null} + * @description Select All tables in target database + */ + const allTables = await noDatabaseDbHandler({ query: `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='${dbFullName}'` }); + + let tableDropped; + + if (!allTables) { + console.log("No Tables to Update"); + continue; + } + + for (let tb = 0; tb < allTables.length; tb++) { + const { TABLE_NAME } = allTables[tb]; + /** - * @description Update table if table exists + * @description Check if TABLE_NAME is part of the tables contained + * in the user schema JSON. If it's not, the table is either deleted + * or the table name has been recently changed */ - const updateExistingTable = await updateTable({ - dbFullName: dbFullName, - tableName: tableName, - tableInfoArray: fields, - dbSchema, - tableIndexes: indexes, - tableIndex: t, - }); + if (!tables.filter((_table) => _table.tableName === TABLE_NAME)[0]) { + const oldTableFilteredArray = tables.filter((_table) => _table.tableNameOld && _table.tableNameOld === TABLE_NAME); - if (table.childrenTables && table.childrenTables[0]) { - for (let ch = 0; ch < table.childrenTables.length; ch++) { - const childTable = table.childrenTables[ch]; - - const updateExistingChildTable = await updateTable({ - dbFullName: childTable.dbNameFull, - tableName: childTable.tableName, - tableInfoArray: fields, - dbSchema, - tableIndexes: indexes, - clone: true, + /** + * @description Check if this table has been recently renamed. Rename + * table id true. Drop table if false + */ + if (oldTableFilteredArray && oldTableFilteredArray[0]) { + console.log("Renaming Table"); + await varDatabaseDbHandler({ + queryString: `RENAME TABLE \`${oldTableFilteredArray[0].tableNameOld}\` TO \`${oldTableFilteredArray[0].tableName}\``, + database: dbFullName, + }); + } else { + console.log(`Dropping Table from ${dbFullName}`); + // deepcode ignore reDOS: + await varDatabaseDbHandler({ + queryString: `DROP TABLE \`${TABLE_NAME}\``, + database: dbFullName, }); - // console.log(updateExistingChildTable); + tableDropped = true; } } + } - //////////////////////////////////////// - } else { - //////////////////////////////////////// + //////////////////////////////////////// + //////////////////////////////////////// + //////////////////////////////////////// + + /** + * @description Iterate through each table and perform table actions + */ + for (let t = 0; t < tables.length; t++) { + const table = tables[t]; + + if (tableDropped) continue; + + const { tableName, fields, indexes } = table; /** - * @description Create new Table if table doesnt exist + * @description Check if table exists */ - const createNewTable = await createTable({ - tableName: tableName, - tableInfoArray: fields, - varDatabaseDbHandler, - dbFullName: dbFullName, - dbSchema, + const tableCheck = await varDatabaseDbHandler({ + queryString: ` + SELECT EXISTS ( + SELECT + TABLE_NAME + FROM + information_schema.TABLES + WHERE + TABLE_SCHEMA = ? AND + TABLE_NAME = ? + ) AS tableExists`, + queryValuesArray: [dbFullName, table.tableName], + database: dbFullName, }); - if (indexes && indexes[0]) { + //////////////////////////////////////// + + if (tableCheck && tableCheck[0]?.tableExists > 0) { /** - * Handle DATASQUIREL Table Indexes - * =================================================== - * @description Iterate through each datasquirel schema - * table index(if available), and perform operations + * @description Update table if table exists */ - if (indexes && indexes[0]) { - for (let g = 0; g < indexes.length; g++) { - const { indexType, indexName, indexTableFields, alias } = indexes[g]; + const updateExistingTable = await updateTable({ + dbFullName: dbFullName, + tableName: tableName, + tableInfoArray: fields, + dbSchema, + tableIndexes: indexes, + tableIndex: t, + }); - if (!alias?.match(/./)) continue; + if (table.childrenTables && table.childrenTables[0]) { + for (let ch = 0; ch < table.childrenTables.length; ch++) { + const childTable = table.childrenTables[ch]; - /** - * @type {DSQL_MYSQL_SHOW_INDEXES_Type[] | null} - * @description All indexes from MYSQL db - */ - const allExistingIndexes = await varDatabaseDbHandler({ - queryString: `SHOW INDEXES FROM \`${tableName}\``, - database: dbFullName, + const updateExistingChildTable = await updateTable({ + dbFullName: childTable.dbNameFull, + tableName: childTable.tableName, + tableInfoArray: fields, + dbSchema, + tableIndexes: indexes, + clone: true, }); - /** - * @description Check for existing Index in MYSQL db - */ - try { - const existingKeyInDb = allExistingIndexes ? allExistingIndexes.filter((indexObject) => indexObject.Key_name === alias) : null; - if (!existingKeyInDb?.[0]) throw new Error("This Index Does not Exist"); - } catch (error) { + // console.log(updateExistingChildTable); + } + } + + //////////////////////////////////////// + } else { + //////////////////////////////////////// + + /** + * @description Create new Table if table doesnt exist + */ + const createNewTable = await createTable({ + tableName: tableName, + tableInfoArray: fields, + varDatabaseDbHandler, + dbFullName: dbFullName, + dbSchema, + }); + + if (indexes && indexes[0]) { + /** + * Handle DATASQUIREL Table Indexes + * =================================================== + * @description Iterate through each datasquirel schema + * table index(if available), and perform operations + */ + if (indexes && indexes[0]) { + for (let g = 0; g < indexes.length; g++) { + const { indexType, indexName, indexTableFields, alias } = indexes[g]; + + if (!alias?.match(/./)) continue; + /** - * @description Create new index if determined that it - * doesn't exist in MYSQL db + * @type {any[] | null} + * @description All indexes from MYSQL db */ - await varDatabaseDbHandler({ - queryString: `CREATE${indexType.match(/fullText/i) ? " FULLTEXT" : ""} INDEX \`${alias}\` ON ${tableName}(${indexTableFields - .map((nm) => nm.value) - .map((nm) => `\`${nm}\``) - .join(",")}) COMMENT 'schema_index'`, + const allExistingIndexes = await varDatabaseDbHandler({ + queryString: `SHOW INDEXES FROM \`${tableName}\``, database: dbFullName, }); + + /** + * @description Check for existing Index in MYSQL db + */ + try { + const existingKeyInDb = allExistingIndexes ? allExistingIndexes.filter((indexObject) => indexObject.Key_name === alias) : null; + if (!existingKeyInDb?.[0]) throw new Error("This Index Does not Exist"); + } catch (error) { + /** + * @description Create new index if determined that it + * doesn't exist in MYSQL db + */ + await varDatabaseDbHandler({ + queryString: `CREATE${indexType.match(/fullText/i) ? " FULLTEXT" : ""} INDEX \`${alias}\` ON ${tableName}(${indexTableFields + .map((nm) => nm.value) + .map((nm) => `\`${nm}\``) + .join(",")}) COMMENT 'schema_index'`, + database: dbFullName, + }); + } } } } } + + //////////////////////////////////////// } - - //////////////////////////////////////// } - } - //////////////////////////////////////// - //////////////////////////////////////// - //////////////////////////////////////// + //////////////////////////////////////// + //////////////////////////////////////// + //////////////////////////////////////// + } catch (error) { + console.log("Error in createDbFromSchema => ", error.message); + } } /** ****************************************************************************** */ diff --git a/engine/engine/utils/dbHandler.js b/engine/engine/utils/dbHandler.js index ea6d56b..5329858 100644 --- a/engine/engine/utils/dbHandler.js +++ b/engine/engine/utils/dbHandler.js @@ -15,6 +15,7 @@ const connection = mysql.createConnection({ password: process.env.DSQL_PASS, charset: "utf8mb4", port: process.env.DSQL_PORT?.match(/.../) ? parseInt(process.env.DSQL_PORT) : undefined, + timeout: 5000, }); ////////////////////////////////////////////////////////////////////////////////// @@ -71,36 +72,35 @@ module.exports = async function dbHandler({ query, values, database }) { */ try { results = await new Promise((resolve, reject) => { - if (connection.state !== "disconnected") { - if (values) { - connection.query(query, values, (error, results, fields) => { - if (error) { - console.log("DB handler error:", error.message); - resolve({ - error: error.message, - }); - } else { - resolve(JSON.parse(JSON.stringify(results))); - } - setTimeout(() => { - endConnection(connection); - }, 500); - }); - } else { - connection.query(query, (error, results, fields) => { - if (error) { - console.log("DB handler error:", error.message); - resolve({ - error: error.message, - }); - } else { - resolve(JSON.parse(JSON.stringify(results))); - } - setTimeout(() => { - endConnection(connection); - }, 500); - }); - } + if (values) { + connection.query(query, values, (error, results, fields) => { + if (error) { + console.log("DB handler error:", error.message); + resolve({ + error: error.message, + }); + } else { + resolve(JSON.parse(JSON.stringify(results))); + } + + // setTimeout(() => { + // endConnection(connection); + // }, 500); + }); + } else { + connection.query(query, (error, results, fields) => { + if (error) { + console.log("DB handler error:", error.message); + resolve({ + error: error.message, + }); + } else { + resolve(JSON.parse(JSON.stringify(results))); + } + // setTimeout(() => { + // endConnection(connection); + // }, 500); + }); } }); diff --git a/engine/engine/utils/noDatabaseDbHandler.js b/engine/engine/utils/noDatabaseDbHandler.js index a16d4dc..ee5efcd 100644 --- a/engine/engine/utils/noDatabaseDbHandler.js +++ b/engine/engine/utils/noDatabaseDbHandler.js @@ -11,6 +11,7 @@ const connection = mysql.createConnection({ password: process.env.DSQL_PASS, charset: "utf8mb4", port: process.env.DSQL_PORT?.match(/.../) ? parseInt(process.env.DSQL_PORT) : undefined, + timeout: 5000, }); /** @@ -38,36 +39,34 @@ module.exports = async function noDatabaseDbHandler({ query, values }) { try { /** ********************* Run Query */ results = await new Promise((resolve, reject) => { - if (connection.state !== "disconnected") { - if (values) { - connection.query(query, values, (error, results, fields) => { - if (error) { - console.log("NO-DB handler error:", error.message); - resolve({ - error: error.message, - }); - } else { - resolve(JSON.parse(JSON.stringify(results))); - } - setTimeout(() => { - endConnection(connection); - }, 500); - }); - } else { - connection.query(query, (error, results, fields) => { - if (error) { - console.log("NO-DB handler error:", error.message); - resolve({ - error: error.message, - }); - } else { - resolve(JSON.parse(JSON.stringify(results))); - } - setTimeout(() => { - endConnection(connection); - }, 500); - }); - } + if (values) { + connection.query(query, values, (error, results, fields) => { + if (error) { + console.log("NO-DB handler error:", error.message); + resolve({ + error: error.message, + }); + } else { + resolve(JSON.parse(JSON.stringify(results))); + } + // setTimeout(() => { + // endConnection(connection); + // }, 500); + }); + } else { + connection.query(query, (error, results, fields) => { + if (error) { + console.log("NO-DB handler error:", error.message); + resolve({ + error: error.message, + }); + } else { + resolve(JSON.parse(JSON.stringify(results))); + } + // setTimeout(() => { + // endConnection(connection); + // }, 500); + }); } }); //////////////////////////////////////// diff --git a/package.json b/package.json index 9ac534d..a5859f7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "datasquirel", - "version": "1.5.1", + "version": "1.5.2", "description": "Cloud-based SQL data management tool", "main": "index.js", "bin": {