This commit is contained in:
Benjamin Toby
2025-07-05 14:59:30 +01:00
parent 6e334c2525
commit 7e8bb37c09
526 changed files with 17560 additions and 11386 deletions
@@ -0,0 +1,112 @@
import varDatabaseDbHandler from "./varDatabaseDbHandler";
import { DSQL_TableSchemaType } from "../../types";
import {
DSQL_DATASQUIREL_USER_DATABASE_TABLES,
DSQL_DATASQUIREL_USER_DATABASES,
} from "../../types/dsql";
import numberfy from "../../utils/numberfy";
import updateDbEntry from "../../functions/backend/db/updateDbEntry";
import addDbEntry from "../../functions/backend/db/addDbEntry";
import slugToNormalText from "../../utils/slug-to-normal-text";
import debugLog from "../../utils/logging/debug-log";
import _ from "lodash";
type Param = {
tableSchema?: DSQL_TableSchemaType;
recordedDbEntry?: DSQL_DATASQUIREL_USER_DATABASES;
update?: boolean;
isMain?: boolean;
};
/**
* # Handle Table Record Update and Insert
*/
export default async function ({
tableSchema,
recordedDbEntry,
update,
isMain,
}: Param): Promise<number | undefined> {
if (isMain) return undefined;
let tableId: number | undefined;
const targetDatabase = "datasquirel";
const targetTableName = "user_database_tables";
if (!tableSchema?.tableName) {
return undefined;
}
const newTableSchema = _.cloneDeep(tableSchema);
try {
if (!recordedDbEntry) {
throw new Error("Recorded Db entry not found!");
}
// const existingTableName = newTableSchema.tableNameOld
// ? newTableSchema.tableNameOld
// : newTableSchema.tableName;
const newTableEntry: DSQL_DATASQUIREL_USER_DATABASE_TABLES = {
user_id: recordedDbEntry.user_id,
db_id: recordedDbEntry.id,
db_slug: recordedDbEntry.db_slug,
table_name: slugToNormalText(newTableSchema.tableName),
table_slug: newTableSchema.tableName,
child_table: newTableSchema.childTable ? 1 : 0,
child_table_parent_database_schema_id: newTableSchema.childTableDbId
? numberfy(newTableSchema.childTableDbId)
: 0,
child_table_parent_table_schema_id: newTableSchema.childTableId
? numberfy(newTableSchema.childTableId)
: 0,
table_schema_id: newTableSchema.id
? numberfy(newTableSchema.id)
: 0,
active_data: newTableSchema.updateData ? 1 : 0,
};
const existingTable = await varDatabaseDbHandler({
queryString: `SELECT * FROM ${targetDatabase}.${targetTableName} WHERE db_id = ? AND table_slug = ?`,
queryValuesArray: [
String(recordedDbEntry.id),
String(newTableSchema.tableName),
],
});
const table: DSQL_DATASQUIREL_USER_DATABASE_TABLES = existingTable?.[0];
if (table?.id) {
tableId = table.id;
if (update) {
await updateDbEntry<DSQL_DATASQUIREL_USER_DATABASE_TABLES>({
data: newTableEntry,
identifierColumnName: "id",
identifierValue: table.id,
tableName: targetTableName,
dbFullName: targetDatabase,
});
}
} else {
const newTableEntryRes =
await addDbEntry<DSQL_DATASQUIREL_USER_DATABASE_TABLES>({
data: newTableEntry,
tableName: targetTableName,
dbFullName: targetDatabase,
});
if (newTableEntryRes?.payload?.insertId) {
tableId = newTableEntryRes.payload.insertId;
}
}
if (newTableSchema.tableNameOld) {
}
return tableId;
} catch (error) {
return undefined;
}
}
+33 -129
View File
@@ -1,15 +1,18 @@
import varDatabaseDbHandler from "./varDatabaseDbHandler";
import generateColumnDescription from "./generateColumnDescription";
import supplementTable from "./supplementTable";
import dbHandler from "./dbHandler";
import { DSQL_DatabaseSchemaType, DSQL_TableSchemaType } from "../../types";
import { DSQL_FieldSchemaType, DSQL_TableSchemaType } from "../../types";
import { DSQL_DATASQUIREL_USER_DATABASES } from "../../types/dsql";
import handleTableForeignKey from "./handle-table-foreign-key";
import createTableHandleTableRecord from "./create-table-handle-table-record";
type Param = {
dbFullName: string;
tableName: string;
tableInfoArray: any[];
tableInfoArray: DSQL_FieldSchemaType[];
tableSchema?: DSQL_TableSchemaType;
recordedDbEntry?: any;
recordedDbEntry?: DSQL_DATASQUIREL_USER_DATABASES;
isMain?: boolean;
};
/**
@@ -21,110 +24,28 @@ export default async function createTable({
tableInfoArray,
tableSchema,
recordedDbEntry,
isMain,
}: Param) {
/**
* Format tableInfoArray
*
* @description Format tableInfoArray
*/
const finalTable = supplementTable({ tableInfoArray: tableInfoArray });
/**
* Grab Schema
*
* @description Grab Schema
*/
let tableId = await createTableHandleTableRecord({
recordedDbEntry,
tableSchema,
isMain,
});
if (!tableId && !isMain) throw new Error(`Couldn't grab table ID`);
const createTableQueryArray = [];
createTableQueryArray.push(
`CREATE TABLE IF NOT EXISTS \`${dbFullName}\`.\`${tableName}\` (`
);
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
try {
if (!recordedDbEntry) {
throw new Error("Recorded Db entry not found!");
}
const existingTable = await varDatabaseDbHandler({
queryString: `SELECT * FROM datasquirel.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: import("../../types").MYSQL_user_database_tables_table_def =
existingTable?.[0];
if (!table?.id) {
const newTableEntry = await dbHandler({
query: `INSERT INTO datasquirel.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(),
},
});
}
} catch (error) {}
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
let primaryKeySet = false;
/** @type {import("../../types").DSQL_FieldSchemaType[]} */
let foreignKeys: import("../../types").DSQL_FieldSchemaType[] = [];
////////////////////////////////////////
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,
@@ -133,56 +54,39 @@ export default async function createTable({
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,
});
return newTable;
for (let i = 0; i < finalTable.length; i++) {
const column = finalTable[i];
const { foreignKey, fieldName } = column;
if (!fieldName) continue;
if (foreignKey) {
await handleTableForeignKey({
dbFullName,
foreignKey,
tableName,
fieldName,
});
}
}
return tableId;
}
-58
View File
@@ -1,58 +0,0 @@
import fs from "fs";
import path from "path";
import grabDSQLConnection from "../../utils/grab-dsql-connection";
type Param = {
query: string;
values?: string[] | object;
};
/**
* # Main DB Handler Function
* @requires DSQL_DB_CONN - Gobal Variable for Datasquirel Database
*/
export default async function dbHandler({
query,
values,
}: Param): Promise<any[] | object | null> {
const CONNECTION = grabDSQLConnection();
let results;
try {
if (query && values) {
results = await CONNECTION.query(query, values);
} else {
results = await CONNECTION.query(query);
}
} catch (error: any) {
global.ERROR_CALLBACK?.(`DB Handler Error...`, error as Error);
if (process.env.FIRST_RUN) {
return null;
}
console.log("ERROR in dbHandler =>", error.message);
console.log(error);
console.log(CONNECTION.config());
const tmpFolder = path.resolve(process.cwd(), "./.tmp");
if (!fs.existsSync(tmpFolder))
fs.mkdirSync(tmpFolder, { recursive: true });
fs.appendFileSync(
path.resolve(tmpFolder, "./dbErrorLogs.txt"),
JSON.stringify(error, null, 4) + "\n" + Date() + "\n\n\n",
"utf8"
);
results = null;
} finally {
await CONNECTION?.end();
}
if (results) {
return JSON.parse(JSON.stringify(results));
} else {
return null;
}
}
@@ -0,0 +1,53 @@
import grabSQLKeyName from "../../utils/grab-sql-key-name";
import varDatabaseDbHandler from "./varDatabaseDbHandler";
type Param = {
dbFullName: string;
tableName: string;
};
/**
* # Drop All Foreign Keys
*/
export default async function dropAllForeignKeys({
dbFullName,
tableName,
}: Param) {
try {
// const rows = await varDatabaseDbHandler({
// queryString: `SELECT CONSTRAINT_NAME FROM information_schema.REFERENTIAL_CONSTRAINTS WHERE TABLE_NAME = '${tableName}' AND CONSTRAINT_SCHEMA = '${dbFullName}'`,
// });
// console.log("rows", rows);
// console.log("dbFullName", dbFullName);
// console.log("tableName", tableName);
// for (const row of rows) {
// await varDatabaseDbHandler({
// queryString: `ALTER TABLE \`${dbFullName}\`.\`${tableName}\` DROP FOREIGN KEY \`${row.CONSTRAINT_NAME}\`
// `,
// });
// }
const foreignKeys = await varDatabaseDbHandler({
queryString: `SHOW INDEXES FROM \`${dbFullName}\`.\`${tableName}\` WHERE Key_name LIKE '${grabSQLKeyName(
{ type: "foreign_key" }
)}%'`,
});
for (const fk of foreignKeys) {
if (
fk.Key_name.match(
new RegExp(grabSQLKeyName({ type: "foreign_key" }))
)
) {
await varDatabaseDbHandler({
queryString: `ALTER TABLE \`${dbFullName}\`.\`${tableName}\` DROP INDEX \`${fk.Key_name}\`
`,
});
}
}
} catch (error: any) {
console.log(`dropAllForeignKeys ERROR => ${error.message}`);
}
}
@@ -1,5 +1,9 @@
import { DSQL_FieldSchemaType } from "../../types";
import dataTypeConstructor from "../../utils/db/schema/data-type-constructor";
import dataTypeParser from "../../utils/db/schema/data-type-parser";
type Param = {
columnData: import("../../types").DSQL_FieldSchemaType;
columnData: DSQL_FieldSchemaType;
primaryKeySet?: boolean;
};
@@ -15,11 +19,6 @@ export default function generateColumnDescription({
columnData,
primaryKeySet,
}: Param): Return {
/**
* Format tableInfoArray
*
* @description Format tableInfoArray
*/
const {
fieldName,
dataType,
@@ -30,13 +29,19 @@ export default function generateColumnDescription({
defaultValueLiteral,
onUpdateLiteral,
notNullValue,
unique,
} = columnData;
let fieldEntryText = "";
fieldEntryText += `\`${fieldName}\` ${dataType}`;
const finalDataTypeObject = dataTypeParser(dataType);
const finalDataType = dataTypeConstructor(
finalDataTypeObject.type,
finalDataTypeObject.limit,
finalDataTypeObject.decimal
);
////////////////////////////////////////
fieldEntryText += `\`${fieldName}\` ${finalDataType}`;
if (nullValue) {
fieldEntryText += " DEFAULT NULL";
@@ -46,35 +51,32 @@ export default function generateColumnDescription({
if (String(defaultValue).match(/uuid\(\)/i)) {
fieldEntryText += ` DEFAULT UUID()`;
} else {
fieldEntryText += ` DEFAULT '${defaultValue}'`;
fieldEntryText += ` DEFAULT '${String(defaultValue)
.replace(/^\'|\'$/g, "")
.replace(/\'/g, "\\'")}'`;
}
} else if (notNullValue) {
fieldEntryText += ` NOT NULL`;
}
////////////////////////////////////////
if (onUpdateLiteral) {
fieldEntryText += ` ON UPDATE ${onUpdateLiteral}`;
}
////////////////////////////////////////
if (primaryKey && !primaryKeySet) {
fieldEntryText += " PRIMARY KEY";
primaryKeySet = true;
}
////////////////////////////////////////
if (autoIncrement) {
fieldEntryText += " AUTO_INCREMENT";
primaryKeySet = true;
}
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
if (unique) {
fieldEntryText += " UNIQUE";
primaryKeySet = true;
}
return {
fieldEntryText,
@@ -0,0 +1,3 @@
export default function grabDSQLSchemaIndexComment() {
return `dsql_schema_index`;
}
@@ -0,0 +1,51 @@
import varDatabaseDbHandler from "./varDatabaseDbHandler";
import { DSQL_ForeignKeyType } from "../../types";
type Param = {
dbFullName: string;
tableName: string;
foreignKey: DSQL_ForeignKeyType;
fieldName: string;
errorLogs?: any[];
};
/**
* # Update table function
*/
export default async function handleTableForeignKey({
dbFullName,
tableName,
foreignKey,
errorLogs,
fieldName,
}: Param) {
const {
destinationTableName,
destinationTableColumnName,
cascadeDelete,
cascadeUpdate,
foreignKeyName,
} = foreignKey;
let finalQueryString = `ALTER TABLE \`${dbFullName}\`.\`${tableName}\``;
finalQueryString += ` ADD CONSTRAINT \`${foreignKeyName}\` FOREIGN KEY (\`${fieldName}\`)`;
finalQueryString += ` REFERENCES \`${destinationTableName}\`(\`${destinationTableColumnName}\`)`;
if (cascadeDelete) finalQueryString += ` ON DELETE CASCADE`;
if (cascadeUpdate) finalQueryString += ` ON UPDATE CASCADE`;
// let foreinKeyText = `ADD CONSTRAINT \`${foreignKeyName}\` FOREIGN KEY (\`${destinationTableColumnType}\`) REFERENCES \`${destinationTableName}\`(\`${destinationTableColumnName}\`)${
// cascadeDelete ? " ON DELETE CASCADE" : ""
// }${cascadeUpdate ? " ON UPDATE CASCADE" : ""}`;
// let finalQueryString = `ALTER TABLE \`${dbFullName}\`.\`${tableName}\` ${foreinKeyText}`;
const addForeignKey = await varDatabaseDbHandler({
queryString: finalQueryString,
});
if (!addForeignKey?.serverStatus) {
errorLogs?.push(addForeignKey);
}
}
@@ -1,4 +1,4 @@
import dbHandler from "./dbHandler";
import dbHandler from "../../functions/backend/dbHandler";
export default async function noDatabaseDbHandler(
queryString: string
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,4 @@
import dbHandler from "./dbHandler";
import { DSQL_TableSchemaType } from "../../types";
import dbHandler from "../../functions/backend/dbHandler";
type Param = {
queryString: string;