import express, { Request, Response } from 'express'; import { tediousQuery } from '../../utils/tedious'; import { GeneralDB, GisDB } from '../../constants/db'; const router = express.Router() router.get('/regions/all', async (req: Request, res: Response) => { try { const result = await tediousQuery( ` SELECT * FROM ${GeneralDB}..vRegions; ` ) res.status(200).json(result) } catch (err) { res.status(500) } }) router.get('/districts/all', async (req: Request, res: Response) => { try { const { region_id } = req.query const result = await tediousQuery( ` SELECT c.*, d.name AS district_name FROM ${GeneralDB}..vCities c JOIN ${GeneralDB}..vDistricts d ON d.id_region = c.id_region AND d.id = c.id_district WHERE c.id_region = ${region_id}; ` ) res.status(200).json(result) } catch (err) { res.status(500) } }) router.get('/cities/all', async (req: Request, res: Response) => { try { const { offset, limit, search, id } = req.query const result = await tediousQuery( ` SELECT * FROM ${GeneralDB}..Cities ${id ? `WHERE id = '${id}'` : ''} ${search ? `WHERE name LIKE '%${search || ''}%'` : ''} ORDER BY id OFFSET ${Number(offset) || 0} ROWS FETCH NEXT ${Number(limit) || 10} ROWS ONLY; ` ) res.status(200).json(result) } catch (err) { res.status(500) } }) router.get('/types/all', async (req: Request, res: Response) => { try { const result = await tediousQuery( ` SELECT * FROM ${GeneralDB}..tTypes ORDER BY id ` ) res.status(200).json(result) } catch (err) { res.status(500) } }) router.get('/objects/all', async (req: Request, res: Response) => { try { const { offset, limit, city_id } = req.query const result = await tediousQuery( ` SELECT * FROM ${GeneralDB}..vObjects ${city_id ? `WHERE id_city = ${city_id}` : ''} ORDER BY object_id OFFSET ${Number(offset) || 0} ROWS FETCH NEXT ${Number(limit) || 10} ROWS ONLY; ` ) res.status(200).json(result) } catch (err) { res.status(500) } }) router.get('/objects/list', async (req: Request, res: Response) => { try { const { city_id, year, planning, type } = req.query if (type) { const result = await tediousQuery( // ` // SELECT // * // FROM // vObjects // WHERE // vObjects.id_city = ${city_id} // AND vObjects.year = ${year} // AND type = ${type} // AND // ( // CASE // WHEN TRY_CAST(vObjects.planning AS BIT) IS NOT NULL THEN TRY_CAST(vObjects.planning AS BIT) // WHEN vObjects.planning = 'TRUE' THEN 1 // WHEN vObjects.planning = 'FALSE' THEN 0 // ELSE NULL // END // ) = ${planning}; // ` ` WITH cte_split(type_id, split_value, caption_params) AS ( -- anchor member SELECT DISTINCT type_id, CAST(LEFT(caption_params, CHARINDEX(',', caption_params + ',') - 1) AS VARCHAR(255)), -- Explicitly casting to VARCHAR STUFF(caption_params, 1, CHARINDEX(',', caption_params + ','), '') FROM ${GisDB}..caption_params WHERE city_id = -1 AND user_id = -1 UNION ALL -- recursive member SELECT type_id, CAST(LEFT(caption_params, CHARINDEX(',', caption_params + ',') - 1) AS VARCHAR(255)), -- Explicitly casting to VARCHAR STUFF(caption_params, 1, CHARINDEX(',', caption_params + ','), '') FROM cte_split WHERE caption_params > '' ) SELECT o.object_id, o.type, o.id_city, o.year, o.planning, string_agg(cast(v.value as varchar), ',') as caption FROM ${GeneralDB}..vObjects o JOIN cte_split c ON o.type = c.type_id JOIN ${GeneralDB}..tParameters p ON p.id = split_value LEFT JOIN ${GeneralDB}..tValues v ON v.id_param = split_value AND v.id_object = o.object_id AND (v.date_po IS NULL) AND (v.date_s < DATEFROMPARTS(${Number(year) + 1},01,01)) WHERE o.id_city = ${city_id} AND o.year = ${year} AND o.type = ${type} AND ( CASE WHEN TRY_CAST(o.planning AS BIT) IS NOT NULL THEN TRY_CAST(o.planning AS BIT) WHEN o.planning = 'TRUE' THEN 1 WHEN o.planning = 'FALSE' THEN 0 ELSE NULL END ) = ${planning} GROUP BY object_id, type, id_city, year, planning; ` ) res.status(200).json(result) } else { const result = await tediousQuery( ` SELECT tTypes.id AS id, tTypes.name AS name, COUNT(vObjects.type) AS count FROM vObjects JOIN tTypes ON vObjects.type = tTypes.id WHERE vObjects.id_city = ${city_id} AND vObjects.year = ${year} AND ( CASE WHEN TRY_CAST(vObjects.planning AS BIT) IS NOT NULL THEN TRY_CAST(vObjects.planning AS BIT) WHEN vObjects.planning = 'TRUE' THEN 1 WHEN vObjects.planning = 'FALSE' THEN 0 ELSE NULL END ) = ${planning} GROUP BY tTypes.id, tTypes.name; ` ) res.status(200).json(result) } } catch (err) { res.status(500) } }) router.get('/objects/:id([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})', async (req: Request, res: Response) => { try { const { id } = req.params; const result = await tediousQuery( ` SELECT * FROM ${GeneralDB}..vObjects ${id ? `WHERE object_id = '${id}'` : ''} ` ) if (Array.isArray(result) && result.length > 0) { res.status(200).json(result[0]) } } catch (err) { res.status(500) } }) router.get('/values/all', async (req: Request, res: Response) => { try { const { object_id } = req.query if (!object_id) { res.status(500) } const result = await tediousQuery( ` SELECT id_object, id_param, CAST(v.value AS varchar(max)) AS value, date_s, date_po, id_user FROM ${GeneralDB}..tValues v JOIN ${GeneralDB}..tParameters p ON v.id_param = p.id WHERE id_object = '${object_id}' ` ) res.status(200).json(result) } catch (err) { res.status(500) } }) router.get('/params/all', async (req: Request, res: Response) => { try { const { param_id } = req.query if (!param_id) { res.status(500) } const result = await tediousQuery( ` SELECT * FROM ${GeneralDB}..tParameters WHERE id = '${param_id}' ` ) res.status(200).json(result) } catch (err) { res.status(500) } }) const tcbParamQuery = (vtable: string, id_city: string) => { switch (vtable) { case 'vStreets': return `SELECT * FROM ${GeneralDB}..${vtable} WHERE id_city = ${id_city};` case 'vBoilers': return `SELECT * FROM ${GeneralDB}..${vtable} WHERE id_city = ${id_city};` default: return `SELECT * FROM ${GeneralDB}..${vtable};` } } // Get value from TCB parameter router.get('/params/tcb', async (req: Request, res: Response) => { try { const { vtable, id, offset, limit, id_city } = req.query if (!vtable) { res.status(500) } if (id) { const result = await tediousQuery( ` SELECT * FROM ${GeneralDB}..${vtable} WHERE id = '${id}' ` ) res.status(200).json(result) } else { const result = await tediousQuery( // ` // SELECT * FROM nGeneral..${vtable} // ORDER BY id // OFFSET ${Number(offset) || 0} ROWS // FETCH NEXT ${Number(limit) || 10} ROWS ONLY; // ` tcbParamQuery(vtable as string, id_city as string) ) res.status(200).json(result) } } catch (err) { res.status(500) } }) router.get('/search/objects', async (req: Request, res: Response) => { try { const { q, id_city, year } = req.query if (q && id_city && year) { const result = await tediousQuery( ` WITH RankedValues AS ( SELECT id_object, date_s, CAST(value AS varchar(max)) AS value, ROW_NUMBER() OVER (PARTITION BY id_object ORDER BY date_s DESC) AS rn, o.id_city AS id_city, o.year AS year FROM ${GeneralDB}..tValues JOIN ${GeneralDB}..tObjects o ON o.id = id_object WHERE CAST(value AS varchar(max)) LIKE '%${q}%' ) SELECT id_object, date_s, value, id_city, year FROM RankedValues WHERE rn = 1 AND id_city = ${id_city} AND year = ${year}; ` ) res.status(200).json(result) } else { res.status(400).json("Bad request") } } catch (err) { res.status(500).json({ message: "Error", error: err }) } }) export default router