datasquirel/package-shared/utils/db/schema/resolve-schema-children-handle-children-tables.ts
Benjamin Toby 7e8bb37c09 Updates
2025-07-05 14:59:30 +01:00

230 lines
8.0 KiB
TypeScript

import {
grabPrimaryRequiredDbSchema,
writeUpdatedDbSchema,
} from "../../../shell/createDbFromSchema/grab-required-database-schemas";
import {
DSQL_ChildrenTablesType,
DSQL_DatabaseSchemaType,
DSQL_TableSchemaType,
} from "../../../types";
import _ from "lodash";
import uniqueByKey from "../../unique-by-key";
type Params = {
currentDbSchema: DSQL_DatabaseSchemaType;
currentTableSchema: DSQL_TableSchemaType;
currentTableSchemaIndex: number;
userId: string | number;
};
export default function ({
currentDbSchema,
currentTableSchema,
currentTableSchemaIndex,
userId,
}: Params): DSQL_DatabaseSchemaType {
if (!currentDbSchema.dbFullName) {
throw new Error(
`Resolve Children tables ERROR => currentDbSchema.dbFullName not found!`
);
}
const newCurrentDbSchema = _.cloneDeep(currentDbSchema);
if (newCurrentDbSchema.tables[currentTableSchemaIndex].childrenTables) {
for (
let ch = 0;
ch <
newCurrentDbSchema.tables[currentTableSchemaIndex].childrenTables
.length;
ch++
) {
const childTable =
newCurrentDbSchema.tables[currentTableSchemaIndex]
.childrenTables[ch];
if (!childTable.dbId || !childTable.tableId) {
newCurrentDbSchema.tables[
currentTableSchemaIndex
].childrenTables?.splice(ch, 1, {});
continue;
}
const targetChildTableParentDatabase = grabPrimaryRequiredDbSchema({
dbId: childTable.dbId,
userId,
});
/**
* Delete child table from array if the parent database
* of said child table has been deleted or doesn't exist
*/
if (!targetChildTableParentDatabase?.dbFullName) {
newCurrentDbSchema.tables[
currentTableSchemaIndex
].childrenTables?.splice(ch, 1, {});
} else {
/**
* Delete child table from array if the parent database
* exists but the target tabled has been deleted or doesn't
* exist
*/
const targetChildTableParentDatabaseTableIndex =
targetChildTableParentDatabase.tables.findIndex(
(tbl) => tbl.id == childTable.tableId
);
const targetChildTableParentDatabaseTable =
targetChildTableParentDatabase.tables[
targetChildTableParentDatabaseTableIndex
];
if (targetChildTableParentDatabaseTable?.childTable) {
targetChildTableParentDatabase.tables[
targetChildTableParentDatabaseTableIndex
].fields = [...currentTableSchema.fields];
targetChildTableParentDatabase.tables[
targetChildTableParentDatabaseTableIndex
].indexes = [...(currentTableSchema.indexes || [])];
writeUpdatedDbSchema({
dbSchema: targetChildTableParentDatabase,
userId,
});
} else {
newCurrentDbSchema.tables[
currentTableSchemaIndex
].childrenTables?.splice(ch, 1, {});
}
}
}
if (
newCurrentDbSchema.tables[currentTableSchemaIndex]
.childrenTables?.[0]
) {
newCurrentDbSchema.tables[currentTableSchemaIndex].childrenTables =
uniqueByKey<DSQL_ChildrenTablesType>(
newCurrentDbSchema.tables[
currentTableSchemaIndex
].childrenTables.filter(
(tbl) => Boolean(tbl.dbId) && Boolean(tbl.tableId)
),
"dbId"
);
} else {
delete newCurrentDbSchema.tables[currentTableSchemaIndex]
.childrenTables;
}
}
/**
* Handle scenario where this table is a child of another
*/
if (
currentTableSchema.childTable &&
currentTableSchema.childTableDbId &&
currentTableSchema.childTableDbId
) {
const targetParentDatabase = grabPrimaryRequiredDbSchema({
dbId: currentTableSchema.childTableDbId,
userId,
});
const targetParentDatabaseTableIndex =
targetParentDatabase?.tables.findIndex(
(tbl) => tbl.id == currentTableSchema.childTableId
);
const targetParentDatabaseTable =
typeof targetParentDatabaseTableIndex == "number"
? targetParentDatabaseTableIndex < 0
? undefined
: targetParentDatabase?.tables[
targetParentDatabaseTableIndex
]
: undefined;
/**
* Delete child Table key/values from current database if
* the parent database doesn't esit
*/
if (
!targetParentDatabase?.dbFullName ||
!targetParentDatabaseTable?.tableName
) {
delete newCurrentDbSchema.tables[currentTableSchemaIndex]
.childTable;
delete newCurrentDbSchema.tables[currentTableSchemaIndex]
.childTableDbId;
delete newCurrentDbSchema.tables[currentTableSchemaIndex]
.childTableId;
delete newCurrentDbSchema.tables[currentTableSchemaIndex]
.childTableDbId;
return newCurrentDbSchema;
}
/**
* New Child Database Table Object to be appended
*/
const newChildDatabaseTableObject: DSQL_ChildrenTablesType = {
tableId: currentTableSchema.id,
dbId: newCurrentDbSchema.id,
};
/**
* Add a new Children array in the target table schema if this is the
* first child to be added to said table schema. Else append to array
* if it exists
*/
if (
typeof targetParentDatabaseTableIndex == "number" &&
!targetParentDatabaseTable.childrenTables?.[0]
) {
targetParentDatabase.tables[
targetParentDatabaseTableIndex
].childrenTables = [newChildDatabaseTableObject];
} else if (
typeof targetParentDatabaseTableIndex == "number" &&
targetParentDatabaseTable.childrenTables?.[0]
) {
const existingChildDbTable =
targetParentDatabaseTable.childrenTables.find(
(tbl) =>
tbl.dbId == newCurrentDbSchema.id &&
tbl.tableId == currentTableSchema.id
);
if (!existingChildDbTable?.tableId) {
targetParentDatabase.tables[
targetParentDatabaseTableIndex
].childrenTables?.push(newChildDatabaseTableObject);
}
targetParentDatabase.tables[
targetParentDatabaseTableIndex
].childrenTables = uniqueByKey(
targetParentDatabase.tables[targetParentDatabaseTableIndex]
.childrenTables || [],
["dbId", "tableId"]
);
}
/**
* Update fields and indexes for child table, which is the
* current table
*/
if (targetParentDatabaseTable?.tableName) {
newCurrentDbSchema.tables[currentTableSchemaIndex].fields =
targetParentDatabaseTable.fields;
newCurrentDbSchema.tables[currentTableSchemaIndex].indexes =
targetParentDatabaseTable.indexes;
writeUpdatedDbSchema({ dbSchema: targetParentDatabase, userId });
}
}
return newCurrentDbSchema;
}