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( 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; }