import fs from "node:fs"; import { eq, sql } from "drizzle-orm"; import { Router } from "express"; import multer from "multer"; import z from "zod"; import { db } from "../db/db.controller.js"; import { datamart } from "../db/schema/datamart.schema.js"; import { apiReturn } from "../utils/returnHelper.utils.js"; import { tryCatch } from "../utils/trycatch.utils.js"; const r = Router(); const upload = multer({ dest: "uploads/" }); const newQuery = z.object({ name: z.string().min(5).optional(), description: z.string().min(30).optional(), query: z.string().min(10).optional(), options: z .string() .describe("This should be a set of keys separated by a comma") .optional(), setActive: z.string().optional(), active: z.boolean().optional(), setPublicActive: z.string().optional(), public: z.boolean().optional(), }); r.patch("/:id", upload.single("queryFile"), async (req, res) => { const { id } = req.params; try { const v = newQuery.parse(req.body); const query = { ...v, }; //console.log(query); if (req.file) { const sqlContents = fs.readFileSync(req.file.path, "utf8"); query.query = sqlContents; // optional: delete temp file afterwards fs.unlink(req.file.path, () => {}); } if (v.name) { query.name = v.name.trim().replaceAll(" ", "_"); } if (v.description) { query.options = v.description; } if (v.options) { query.options = v.options; } if (v.setActive) { query.active = v.setActive === "true"; } if (v.setPublicActive) { query.public = v.setPublicActive === "true"; } // if we forget the file crash out // if (!query.query) { // // no query text anywhere // return apiReturn(res, { // success: true, // level: "info", //connect.success ? "info" : "error", // module: "routes", // subModule: "datamart", // message: `${query.name} missing sql file to parse`, // data: [], // status: 400, //connect.success ? 200 : 400, // }); // } // // if we didn't replace the test1 stuff crash out if (query.query && !query.query.includes("test1")) { return apiReturn(res, { success: true, level: "error", //connect.success ? "info" : "error", module: "routes", subModule: "datamart", message: "All queries must point to test1 this way we can keep it dynamic.", data: [], status: 400, //connect.success ? 200 : 400, }); } const { data, error } = await tryCatch( db .update(datamart) .set({ ...query, version: sql`${datamart.version} + 1`, upd_date: sql`NOW()`, upd_user: "lst_user", }) .where(eq(datamart.id, id as string)) .returning({ name: datamart.name }), ); if (error) { return apiReturn(res, { success: true, level: "error", //connect.success ? "info" : "error", module: "routes", subModule: "datamart", message: `${query.name} encountered an error while being updated`, data: [error.cause], status: 200, //connect.success ? 200 : 400, }); } if (data) { return apiReturn(res, { success: true, level: "info", //connect.success ? "info" : "error", module: "routes", subModule: "datamart", message: `${data[0]?.name} was just updated`, data: [], status: 200, //connect.success ? 200 : 400, }); } } catch (err) { if (err instanceof z.ZodError) { const flattened = z.flattenError(err); // return res.status(400).json({ // error: "Validation failed", // details: flattened, // }); return apiReturn(res, { success: false, level: "error", //connect.success ? "info" : "error", module: "routes", subModule: "auth", message: "Validation failed", data: [flattened], status: 400, //connect.success ? 200 : 400, }); } return apiReturn(res, { success: false, level: "error", module: "routes", subModule: "datamart", message: "There was an error updating the query", data: [err], status: 200, }); } }); export default r;