#5-intelligent-groups #23

Merged
jkeffects merged 16 commits from #5-intelligent-groups into main 2024-12-19 09:50:45 +00:00
7 changed files with 128 additions and 16 deletions
Showing only changes of commit ee0d6ddcce - Show all commits

View file

@ -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<any> {
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<any> {
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<any> {
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,
});
}

View file

@ -1,14 +1,23 @@
import { dataSource } from "../data-source"; import { dataSource } from "../data-source";
import { DynamicQueryStructure } from "../type/dynamicQueries"; import { DynamicQueryStructure } from "../type/dynamicQueries";
import { TableMeta } from "../type/tableMeta";
export default abstract class DynamicQueryBuilder { export default abstract class DynamicQueryBuilder {
public static buildQuery(query: DynamicQueryStructure) {} public static allowedTables: Array<string> = [
"award",
"communication",
"communicationType",
"executivePosition",
"membershipStatus",
"qualification",
"member",
"memberAwards",
"memberExecutivePositions",
"memberQualifications",
"membership",
];
// use switch... for compare functions public static getTableMeta(tableName: string): TableMeta {
// use NotBrackets/Brackets for nested conditions
// use joins by requesting table schema and setting correct column
public static getTableMeta(tableName: string) {
let { name, columns, relations } = dataSource.getMetadata(tableName); let { name, columns, relations } = dataSource.getMetadata(tableName);
const uniqueColumns = columns.map((c) => ({ column: c.propertyName, type: c.type })); const uniqueColumns = columns.map((c) => ({ column: c.propertyName, type: c.type }));
@ -31,4 +40,19 @@ export default abstract class DynamicQueryBuilder {
})), })),
}; };
} }
public static getAllTableMeta(): Array<TableMeta> {
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
} }

View file

@ -25,7 +25,7 @@ router.get("/:id", async (req: Request, res: Response) => {
router.post( router.post(
"/", "/",
PermissionHelper.passCheckMiddleware("create", "settings", "communication"), PermissionHelper.passCheckMiddleware("create", "settings", "communication_type"),
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
await createCommunicationType(req, res); await createCommunicationType(req, res);
} }
@ -33,7 +33,7 @@ router.post(
router.patch( router.patch(
"/:id", "/:id",
PermissionHelper.passCheckMiddleware("update", "settings", "communication"), PermissionHelper.passCheckMiddleware("update", "settings", "communication_type"),
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
await updateCommunicationType(req, res); await updateCommunicationType(req, res);
} }
@ -41,7 +41,7 @@ router.patch(
router.delete( router.delete(
"/:id", "/:id",
PermissionHelper.passCheckMiddleware("delete", "settings", "communication"), PermissionHelper.passCheckMiddleware("delete", "settings", "communication_type"),
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
await deleteCommunicationType(req, res); await deleteCommunicationType(req, res);
} }

View file

@ -10,8 +10,8 @@ import calendarType from "./calendarType";
import member from "./member"; import member from "./member";
import protocol from "./protocol"; import protocol from "./protocol";
import calendar from "./calendar"; import calendar from "./calendar";
import queryBuilder from "./queryBuilder";
import role from "./role"; import role from "./role";
import user from "./user"; 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("/award", PermissionHelper.passCheckMiddleware("read", "settings", "award"), award);
router.use( router.use(
"/communicationtype", "/communicationtype",
PermissionHelper.passCheckMiddleware("read", "settings", "communication"), PermissionHelper.passCheckMiddleware("read", "settings", "communication_type"),
communicationType communicationType
); );
router.use( router.use(
@ -41,6 +41,7 @@ router.use("/calendartype", PermissionHelper.passCheckMiddleware("read", "settin
router.use("/member", PermissionHelper.passCheckMiddleware("read", "club", "member"), member); router.use("/member", PermissionHelper.passCheckMiddleware("read", "club", "member"), member);
router.use("/protocol", PermissionHelper.passCheckMiddleware("read", "club", "protocol"), protocol); router.use("/protocol", PermissionHelper.passCheckMiddleware("read", "club", "protocol"), protocol);
router.use("/calendar", PermissionHelper.passCheckMiddleware("read", "club", "calendar"), calendar); 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("/role", PermissionHelper.passCheckMiddleware("read", "user", "role"), role);
router.use("/user", PermissionHelper.passCheckMiddleware("read", "user", "user"), user); router.use("/user", PermissionHelper.passCheckMiddleware("read", "user", "user"), user);

View file

@ -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;

View file

@ -8,11 +8,13 @@ export type PermissionModule =
| "qualification" | "qualification"
| "award" | "award"
| "executive_position" | "executive_position"
| "communication" | "communication_type"
| "membership_status" | "membership_status"
| "calendar_type" | "calendar_type"
| "user" | "user"
| "role"; | "role"
| "query"
| "query_store";
export type PermissionType = "read" | "create" | "update" | "delete"; export type PermissionType = "read" | "create" | "update" | "delete";
@ -44,15 +46,25 @@ export const permissionModules: Array<PermissionModule> = [
"qualification", "qualification",
"award", "award",
"executive_position", "executive_position",
"communication", "communication_type",
"membership_status", "membership_status",
"calendar_type", "calendar_type",
"user", "user",
"role", "role",
"query",
"query_store",
]; ];
export const permissionTypes: Array<PermissionType> = ["read", "create", "update", "delete"]; export const permissionTypes: Array<PermissionType> = ["read", "create", "update", "delete"];
export const sectionsAndModules: SectionsAndModulesObject = { export const sectionsAndModules: SectionsAndModulesObject = {
club: ["member", "calendar", "newsletter", "protocol"], club: ["member", "calendar", "newsletter", "protocol", "query"],
settings: ["qualification", "award", "executive_position", "communication", "membership_status", "calendar_type"], settings: [
"qualification",
"award",
"executive_position",
"communication_type",
"membership_status",
"calendar_type",
"query_store",
],
user: ["user", "role"], user: ["user", "role"],
}; };

7
src/type/tableMeta.ts Normal file
View file

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