From f4f293846bbefdaa0531b0ef7c7e132da8e9c9ab Mon Sep 17 00:00:00 2001 From: Julian Krauser Date: Tue, 17 Dec 2024 16:52:15 +0100 Subject: [PATCH] sql query usage --- .../admin/queryBuilderController.ts | 82 +++++++++++++++---- src/helpers/dynamicQueryBuilder.ts | 6 +- 2 files changed, 71 insertions(+), 17 deletions(-) diff --git a/src/controller/admin/queryBuilderController.ts b/src/controller/admin/queryBuilderController.ts index 312de93..be4a68e 100644 --- a/src/controller/admin/queryBuilderController.ts +++ b/src/controller/admin/queryBuilderController.ts @@ -1,5 +1,6 @@ import { Request, Response } from "express"; import DynamicQueryBuilder from "../../helpers/dynamicQueryBuilder"; +import { dataSource } from "../../data-source"; /** * @description get all table metas @@ -37,22 +38,71 @@ export async function executeQuery(req: Request, res: Response): Promise { let count = parseInt((req.query.count as string) ?? "25"); const query = req.body.query; - try { - let [rows, total] = await DynamicQueryBuilder.buildQuery(query, offset, count).getManyAndCount(); + if (typeof query == "string") { + const upperQuery = query.trim().toUpperCase(); + if (!upperQuery.startsWith("SELECT") || /INSERT|UPDATE|DELETE|ALTER|DROP|CREATE|TRUNCATE/.test(upperQuery)) { + return res.json({ + stats: "error", + sql: query, + code: "UNALLOWED", + msg: "Not allowed to change rows", + }); + } - res.json({ - stats: "success", - rows: rows, - total: total, - offset: offset, - count: count, - }); - } catch (error) { - res.json({ - stats: "error", - sql: error.sql, - code: error.code, - msg: error.sqlMessage, - }); + try { + let data: Array = []; + + const result = await dataSource + .transaction(async (manager) => { + data = await manager.query(query); + + throw new Error("AllwaysRollbackQuery"); + }) + .catch((error) => { + if (error.message === "AllwaysRollbackQuery") { + return { + stats: "success", + rows: data, + total: data.length, + offset: offset, + count: count, + }; + } else { + return { + stats: "error", + sql: error.sql, + code: error.code, + msg: error.sqlMessage, + }; + } + }); + res.send(result); + } catch (error) { + res.json({ + stats: "error", + sql: error.sql, + code: error.code, + msg: error.sqlMessage, + }); + } + } else { + try { + let [rows, total] = await DynamicQueryBuilder.buildQuery(query, offset, count).getManyAndCount(); + + res.json({ + stats: "success", + rows: rows, + total: total, + offset: offset, + count: count, + }); + } catch (error) { + res.json({ + stats: "error", + sql: error.sql, + code: error.code, + msg: error.sqlMessage, + }); + } } } diff --git a/src/helpers/dynamicQueryBuilder.ts b/src/helpers/dynamicQueryBuilder.ts index 6bab2dc..effab6e 100644 --- a/src/helpers/dynamicQueryBuilder.ts +++ b/src/helpers/dynamicQueryBuilder.ts @@ -79,7 +79,7 @@ export default abstract class DynamicQueryBuilder { } for (const select of selects) { - if (firstSelect) { + if (firstSelect && depth == 0) { query.select(`${alias}.${select}`); firstSelect = false; } else { @@ -214,6 +214,10 @@ export default abstract class DynamicQueryBuilder { query += ` LIKE :${parameterKey}`; parameters[parameterKey] = `%${condition.value}`; break; + case "timespanEq": + query += ` BETWEEN :${parameterKey}_start AND :${parameterKey}_end`; + parameters[`${parameterKey}_start`] = new Date(new Date().getFullYear() - (condition.value as number), 0, 1); + parameters[`${parameterKey}_end`] = new Date(new Date().getFullYear() - (condition.value as number), 11, 31); } return { query, parameters };