From ee0d6ddcce087580337137dcb9f188d95a986427 Mon Sep 17 00:00:00 2001 From: Julian Krauser Date: Thu, 12 Dec 2024 16:33:51 +0100 Subject: [PATCH] base controller layout --- .../admin/queryBuilderController.ts | 50 +++++++++++++++++++ src/helpers/dynamicQueryBuilder.ts | 36 ++++++++++--- src/routes/admin/communicationType.ts | 6 +-- src/routes/admin/index.ts | 5 +- src/routes/admin/queryBuilder.ts | 18 +++++++ src/type/permissionTypes.ts | 22 ++++++-- src/type/tableMeta.ts | 7 +++ 7 files changed, 128 insertions(+), 16 deletions(-) create mode 100644 src/controller/admin/queryBuilderController.ts create mode 100644 src/routes/admin/queryBuilder.ts create mode 100644 src/type/tableMeta.ts diff --git a/src/controller/admin/queryBuilderController.ts b/src/controller/admin/queryBuilderController.ts new file mode 100644 index 0000000..ccab8df --- /dev/null +++ b/src/controller/admin/queryBuilderController.ts @@ -0,0 +1,50 @@ +import { Request, Response } from "express"; +import DynamicQueryBuilder from "../../helpers/dynamicQueryBuilder"; + +/** + * @description get all table metas + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function getAllTableMeta(req: Request, res: Response): Promise { + let tableMetas = DynamicQueryBuilder.getAllTableMeta(); + + res.json(tableMetas); +} + +/** + * @description get meta by tablename + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function getTableMetaByTablename(req: Request, res: Response): Promise { + const tablename = req.params.tablename; + let tableMeta = DynamicQueryBuilder.getTableMeta(tablename); + + res.json(tableMeta); +} + +/** + * @description execute Query + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function executeQuery(req: Request, res: Response): Promise { + let offset = parseInt((req.query.offset as string) ?? "0"); + let count = parseInt((req.query.count as string) ?? "25"); + const query = req.body.query; + + //build query to sql + //verify sql or return error + //let [rows, total] = await executeQuery(query, offset, count); + + res.json({ + rows: [], + total: 0, + offset: offset, + count: count, + }); +} diff --git a/src/helpers/dynamicQueryBuilder.ts b/src/helpers/dynamicQueryBuilder.ts index ebd9e7a..59eadc6 100644 --- a/src/helpers/dynamicQueryBuilder.ts +++ b/src/helpers/dynamicQueryBuilder.ts @@ -1,14 +1,23 @@ import { dataSource } from "../data-source"; import { DynamicQueryStructure } from "../type/dynamicQueries"; +import { TableMeta } from "../type/tableMeta"; export default abstract class DynamicQueryBuilder { - public static buildQuery(query: DynamicQueryStructure) {} + public static allowedTables: Array = [ + "award", + "communication", + "communicationType", + "executivePosition", + "membershipStatus", + "qualification", + "member", + "memberAwards", + "memberExecutivePositions", + "memberQualifications", + "membership", + ]; - // use switch... for compare functions - // use NotBrackets/Brackets for nested conditions - // use joins by requesting table schema and setting correct column - - public static getTableMeta(tableName: string) { + public static getTableMeta(tableName: string): TableMeta { let { name, columns, relations } = dataSource.getMetadata(tableName); const uniqueColumns = columns.map((c) => ({ column: c.propertyName, type: c.type })); @@ -31,4 +40,19 @@ export default abstract class DynamicQueryBuilder { })), }; } + + public static getAllTableMeta(): Array { + return this.allowedTables.map((table) => this.getTableMeta(table)); + } + + public static buildQuery(query: DynamicQueryStructure, offset: number = 0, count: number = 25) { + // execute: + // .offset(offset) + // .limit(count) + // .getManyAndCount() + } + + // use switch... for compare functions + // use NotBrackets/Brackets for nested conditions + // use joins by requesting table schema and setting correct column } diff --git a/src/routes/admin/communicationType.ts b/src/routes/admin/communicationType.ts index 2a797f6..4fc185f 100644 --- a/src/routes/admin/communicationType.ts +++ b/src/routes/admin/communicationType.ts @@ -25,7 +25,7 @@ router.get("/:id", async (req: Request, res: Response) => { router.post( "/", - PermissionHelper.passCheckMiddleware("create", "settings", "communication"), + PermissionHelper.passCheckMiddleware("create", "settings", "communication_type"), async (req: Request, res: Response) => { await createCommunicationType(req, res); } @@ -33,7 +33,7 @@ router.post( router.patch( "/:id", - PermissionHelper.passCheckMiddleware("update", "settings", "communication"), + PermissionHelper.passCheckMiddleware("update", "settings", "communication_type"), async (req: Request, res: Response) => { await updateCommunicationType(req, res); } @@ -41,7 +41,7 @@ router.patch( router.delete( "/:id", - PermissionHelper.passCheckMiddleware("delete", "settings", "communication"), + PermissionHelper.passCheckMiddleware("delete", "settings", "communication_type"), async (req: Request, res: Response) => { await deleteCommunicationType(req, res); } diff --git a/src/routes/admin/index.ts b/src/routes/admin/index.ts index b4f5d0c..2a292f3 100644 --- a/src/routes/admin/index.ts +++ b/src/routes/admin/index.ts @@ -10,8 +10,8 @@ import calendarType from "./calendarType"; import member from "./member"; import protocol from "./protocol"; - import calendar from "./calendar"; +import queryBuilder from "./queryBuilder"; import role from "./role"; import user from "./user"; @@ -22,7 +22,7 @@ var router = express.Router({ mergeParams: true }); router.use("/award", PermissionHelper.passCheckMiddleware("read", "settings", "award"), award); router.use( "/communicationtype", - PermissionHelper.passCheckMiddleware("read", "settings", "communication"), + PermissionHelper.passCheckMiddleware("read", "settings", "communication_type"), communicationType ); router.use( @@ -41,6 +41,7 @@ router.use("/calendartype", PermissionHelper.passCheckMiddleware("read", "settin router.use("/member", PermissionHelper.passCheckMiddleware("read", "club", "member"), member); router.use("/protocol", PermissionHelper.passCheckMiddleware("read", "club", "protocol"), protocol); router.use("/calendar", PermissionHelper.passCheckMiddleware("read", "club", "calendar"), calendar); +router.use("/querybuilder", PermissionHelper.passCheckMiddleware("read", "club", "query"), queryBuilder); router.use("/role", PermissionHelper.passCheckMiddleware("read", "user", "role"), role); router.use("/user", PermissionHelper.passCheckMiddleware("read", "user", "user"), user); diff --git a/src/routes/admin/queryBuilder.ts b/src/routes/admin/queryBuilder.ts new file mode 100644 index 0000000..d09b9c3 --- /dev/null +++ b/src/routes/admin/queryBuilder.ts @@ -0,0 +1,18 @@ +import express, { Request, Response } from "express"; +import { executeQuery, getAllTableMeta, getTableMetaByTablename } from "../../controller/admin/queryBuilderController"; + +var router = express.Router({ mergeParams: true }); + +router.get("/tables", async (req: Request, res: Response) => { + await getAllTableMeta(req, res); +}); + +router.get("/table/:tablename", async (req: Request, res: Response) => { + await getTableMetaByTablename(req, res); +}); + +router.post("/query", async (req: Request, res: Response) => { + await executeQuery(req, res); +}); + +export default router; diff --git a/src/type/permissionTypes.ts b/src/type/permissionTypes.ts index fc468a9..d5bb35e 100644 --- a/src/type/permissionTypes.ts +++ b/src/type/permissionTypes.ts @@ -8,11 +8,13 @@ export type PermissionModule = | "qualification" | "award" | "executive_position" - | "communication" + | "communication_type" | "membership_status" | "calendar_type" | "user" - | "role"; + | "role" + | "query" + | "query_store"; export type PermissionType = "read" | "create" | "update" | "delete"; @@ -44,15 +46,25 @@ export const permissionModules: Array = [ "qualification", "award", "executive_position", - "communication", + "communication_type", "membership_status", "calendar_type", "user", "role", + "query", + "query_store", ]; export const permissionTypes: Array = ["read", "create", "update", "delete"]; export const sectionsAndModules: SectionsAndModulesObject = { - club: ["member", "calendar", "newsletter", "protocol"], - settings: ["qualification", "award", "executive_position", "communication", "membership_status", "calendar_type"], + club: ["member", "calendar", "newsletter", "protocol", "query"], + settings: [ + "qualification", + "award", + "executive_position", + "communication_type", + "membership_status", + "calendar_type", + "query_store", + ], user: ["user", "role"], }; diff --git a/src/type/tableMeta.ts b/src/type/tableMeta.ts new file mode 100644 index 0000000..a50e115 --- /dev/null +++ b/src/type/tableMeta.ts @@ -0,0 +1,7 @@ +import { ColumnType } from "typeorm"; + +export interface TableMeta { + tableName: string; + columns: Array<{ column: string; type: ColumnType }>; + relations: Array<{ column: string; relationType: string; referencedTableName: string }>; +}