318 lines
8.9 KiB
TypeScript
318 lines
8.9 KiB
TypeScript
import fs from "fs";
|
|
import path from "path";
|
|
import grabDirNames from "../../utils/backend/names/grab-dir-names";
|
|
import EJSON from "../../utils/ejson";
|
|
import { DSQL_DatabaseSchemaType } from "../../types";
|
|
import numberfy from "../../utils/numberfy";
|
|
import _ from "lodash";
|
|
import uniqueByKey from "../../utils/unique-by-key";
|
|
|
|
type Params = {
|
|
userId?: string | number | null;
|
|
dbId?: string | number;
|
|
dbSlug?: string;
|
|
};
|
|
|
|
export default function grabRequiredDatabaseSchemas(
|
|
params: Params
|
|
): DSQL_DatabaseSchemaType[] | undefined {
|
|
const primaryDbSchema = grabPrimaryRequiredDbSchema(params);
|
|
if (!primaryDbSchema) return undefined;
|
|
|
|
let relatedDatabases: DSQL_DatabaseSchemaType[] = [];
|
|
|
|
const childrenDatabases = primaryDbSchema.childrenDatabases || [];
|
|
const childrenTables =
|
|
primaryDbSchema.tables
|
|
.map((tbl) => {
|
|
return tbl.childrenTables || [];
|
|
})
|
|
.flat() || [];
|
|
|
|
for (let i = 0; i < childrenDatabases.length; i++) {
|
|
const childDb = childrenDatabases[i];
|
|
const childDbSchema = grabPrimaryRequiredDbSchema({
|
|
userId: params.userId,
|
|
dbId: childDb.dbId,
|
|
});
|
|
if (!childDbSchema?.dbSlug) continue;
|
|
relatedDatabases.push(childDbSchema);
|
|
}
|
|
|
|
for (let i = 0; i < childrenTables.length; i++) {
|
|
const childTbl = childrenTables[i];
|
|
const childTableDbSchema = grabPrimaryRequiredDbSchema({
|
|
userId: params.userId,
|
|
dbId: childTbl.dbId,
|
|
});
|
|
if (!childTableDbSchema?.dbSlug) continue;
|
|
relatedDatabases.push(childTableDbSchema);
|
|
}
|
|
|
|
return uniqueByKey([primaryDbSchema, ...relatedDatabases], "dbFullName");
|
|
}
|
|
|
|
export function grabPrimaryRequiredDbSchema({ userId, dbId, dbSlug }: Params) {
|
|
let finalDbId = dbId;
|
|
|
|
if (!finalDbId && userId && dbSlug) {
|
|
const searchedDb = findDbNameInSchemaDir({ dbName: dbSlug, userId });
|
|
|
|
if (searchedDb?.id) {
|
|
finalDbId = searchedDb.id;
|
|
}
|
|
}
|
|
|
|
if (!finalDbId) {
|
|
return undefined;
|
|
}
|
|
|
|
const { targetUserPrivateDir, oldSchemasDir } = grabDirNames({
|
|
userId,
|
|
});
|
|
|
|
const finalSchemaDir = targetUserPrivateDir || oldSchemasDir;
|
|
|
|
if (!finalSchemaDir) {
|
|
console.log(`finalSchemaDir not found!`);
|
|
return undefined;
|
|
}
|
|
|
|
if (finalDbId) {
|
|
const dbIdSchema = path.resolve(finalSchemaDir, `${finalDbId}.json`);
|
|
if (fs.existsSync(dbIdSchema)) {
|
|
const dbIdSchemaObject = EJSON.parse(
|
|
fs.readFileSync(dbIdSchema, "utf-8")
|
|
) as DSQL_DatabaseSchemaType | undefined;
|
|
return dbIdSchemaObject;
|
|
}
|
|
}
|
|
|
|
const dbSchemasFiles = fs.readdirSync(finalSchemaDir);
|
|
|
|
let targetDbSchema: DSQL_DatabaseSchemaType | undefined;
|
|
|
|
try {
|
|
for (let i = 0; i < dbSchemasFiles.length; i++) {
|
|
const fileOrPath = dbSchemasFiles[i];
|
|
if (!fileOrPath.endsWith(`.json`)) continue;
|
|
if (!fileOrPath.match(/^\d+.json/)) continue;
|
|
|
|
const targetFileJSONPath = path.join(finalSchemaDir, fileOrPath);
|
|
const targetSchema = EJSON.parse(
|
|
fs.readFileSync(targetFileJSONPath, "utf-8")
|
|
) as DSQL_DatabaseSchemaType | undefined;
|
|
|
|
if (targetSchema && finalDbId && targetSchema?.id == finalDbId) {
|
|
targetDbSchema = targetSchema;
|
|
}
|
|
}
|
|
} catch (error) {}
|
|
|
|
if (targetDbSchema) {
|
|
return targetDbSchema;
|
|
}
|
|
// else if ( dbFullName) {
|
|
// let existingSchemaInMainJSON = findTargetDbSchemaFromMainSchema(
|
|
// dbFullName
|
|
// );
|
|
|
|
// const nextID = grabLatestDbSchemaID(finalSchemaDir);
|
|
|
|
// if (existingSchemaInMainJSON) {
|
|
// existingSchemaInMainJSON.id = nextID;
|
|
// fs.writeFileSync(
|
|
// path.join(finalSchemaDir, `${nextID}.json`),
|
|
// EJSON.stringify(existingSchemaInMainJSON) || "[]"
|
|
// );
|
|
// return existingSchemaInMainJSON;
|
|
// }
|
|
// }
|
|
|
|
console.log(`userSchemaDir not found!`);
|
|
console.log(`userId`, userId);
|
|
return undefined;
|
|
}
|
|
|
|
export function findDbNameInSchemaDir({
|
|
userId,
|
|
dbName,
|
|
}: {
|
|
userId?: string | number;
|
|
dbName?: string;
|
|
}) {
|
|
if (!userId) {
|
|
console.log(`userId not provided!`);
|
|
return undefined;
|
|
}
|
|
|
|
if (!dbName) {
|
|
console.log(`dbName not provided!`);
|
|
return undefined;
|
|
}
|
|
|
|
const { targetUserPrivateDir } = grabDirNames({
|
|
userId,
|
|
});
|
|
|
|
if (!targetUserPrivateDir) {
|
|
console.log(`targetUserPrivateDir not found!`);
|
|
return undefined;
|
|
}
|
|
|
|
const dbSchemasFiles = fs.readdirSync(targetUserPrivateDir);
|
|
|
|
let targetDbSchema: DSQL_DatabaseSchemaType | undefined;
|
|
|
|
try {
|
|
for (let i = 0; i < dbSchemasFiles.length; i++) {
|
|
const fileOrPath = dbSchemasFiles[i];
|
|
if (!fileOrPath.endsWith(`.json`)) continue;
|
|
if (!fileOrPath.match(/^\d+.json/)) continue;
|
|
|
|
const targetFileJSONPath = path.join(
|
|
targetUserPrivateDir,
|
|
fileOrPath
|
|
);
|
|
const targetSchema = EJSON.parse(
|
|
fs.readFileSync(targetFileJSONPath, "utf-8")
|
|
) as DSQL_DatabaseSchemaType | undefined;
|
|
|
|
if (!targetSchema) continue;
|
|
|
|
if (
|
|
targetSchema.dbFullName == dbName ||
|
|
targetSchema.dbSlug == dbName
|
|
) {
|
|
targetDbSchema = targetSchema;
|
|
return targetSchema;
|
|
}
|
|
}
|
|
} catch (error) {}
|
|
|
|
return targetDbSchema;
|
|
}
|
|
|
|
type UpdateDbSchemaParam = {
|
|
dbSchema: DSQL_DatabaseSchemaType;
|
|
userId?: string | number | null;
|
|
};
|
|
|
|
export function writeUpdatedDbSchema({
|
|
dbSchema,
|
|
userId,
|
|
}: UpdateDbSchemaParam): { success?: boolean; dbSchemaId?: string | number } {
|
|
const { targetUserPrivateDir } = grabDirNames({
|
|
userId,
|
|
});
|
|
|
|
if (!targetUserPrivateDir) {
|
|
console.log(`user ${userId} has no targetUserPrivateDir`);
|
|
return {};
|
|
}
|
|
|
|
if (dbSchema.id) {
|
|
const dbIdSchemaPath = path.join(
|
|
targetUserPrivateDir,
|
|
`${dbSchema.id}.json`
|
|
);
|
|
|
|
fs.writeFileSync(dbIdSchemaPath, EJSON.stringify(dbSchema) || "[]");
|
|
|
|
return { success: true };
|
|
} else {
|
|
const nextID = grabLatestDbSchemaID(targetUserPrivateDir);
|
|
|
|
dbSchema.id = nextID;
|
|
|
|
fs.writeFileSync(
|
|
path.join(targetUserPrivateDir, `${nextID}.json`),
|
|
EJSON.stringify(dbSchema) || "[]"
|
|
);
|
|
|
|
return { success: true, dbSchemaId: nextID };
|
|
}
|
|
}
|
|
|
|
export function deleteDbSchema({ dbSchema, userId }: UpdateDbSchemaParam) {
|
|
const { targetUserPrivateDir, userSchemaMainJSONFilePath } = grabDirNames({
|
|
userId,
|
|
});
|
|
|
|
if (!targetUserPrivateDir) return;
|
|
|
|
const targetDbSchema = grabPrimaryRequiredDbSchema({
|
|
dbId: dbSchema.id,
|
|
userId,
|
|
});
|
|
|
|
const schemaFile = path.join(
|
|
targetUserPrivateDir,
|
|
`${targetDbSchema?.id}.json`
|
|
);
|
|
|
|
try {
|
|
fs.unlinkSync(schemaFile);
|
|
} catch (error) {}
|
|
|
|
if (
|
|
userSchemaMainJSONFilePath &&
|
|
fs.existsSync(userSchemaMainJSONFilePath)
|
|
) {
|
|
try {
|
|
let allDbSchemas = EJSON.parse(
|
|
fs.readFileSync(userSchemaMainJSONFilePath, "utf-8")
|
|
) as DSQL_DatabaseSchemaType[] | undefined;
|
|
|
|
if (allDbSchemas?.[0]) {
|
|
for (let i = 0; i < allDbSchemas.length; i++) {
|
|
const dbSch = allDbSchemas[i];
|
|
if (
|
|
dbSch.dbFullName == dbSchema.dbFullName ||
|
|
dbSch.id == dbSchema.id
|
|
) {
|
|
allDbSchemas.splice(i, 1);
|
|
}
|
|
}
|
|
|
|
fs.writeFileSync(
|
|
userSchemaMainJSONFilePath,
|
|
EJSON.stringify(allDbSchemas) || "[]"
|
|
);
|
|
}
|
|
} catch (error) {}
|
|
}
|
|
}
|
|
|
|
export function findTargetDbSchemaFromMainSchema(
|
|
schemas: DSQL_DatabaseSchemaType[],
|
|
dbFullName?: string,
|
|
dbId?: string | number
|
|
): DSQL_DatabaseSchemaType | undefined {
|
|
const targetDbSchema = schemas.find(
|
|
(sch) => sch.dbFullName == dbFullName || (dbId && sch.id == dbId)
|
|
);
|
|
return targetDbSchema;
|
|
}
|
|
|
|
export function grabLatestDbSchemaID(userSchemaDir: string) {
|
|
const dbSchemasFiles = fs.readdirSync(userSchemaDir);
|
|
const dbNumbers = dbSchemasFiles
|
|
.filter((dbSch) => {
|
|
if (!dbSch.endsWith(`.json`)) return false;
|
|
if (dbSch.match(/^\d+\.json/)) return true;
|
|
return false;
|
|
})
|
|
.map((dbSch) => numberfy(dbSch.replace(/[^0-9]/g, "")));
|
|
|
|
if (dbNumbers[0])
|
|
return (
|
|
(dbNumbers
|
|
.sort((a, b) => {
|
|
return a - b;
|
|
})
|
|
.pop() || 0) + 1
|
|
);
|
|
return 1;
|
|
}
|