This commit is contained in:
103
routes/entities.js
Normal file
103
routes/entities.js
Normal file
@@ -0,0 +1,103 @@
|
||||
const express = require("express");
|
||||
const db = require("../db/polygons");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get("/", (req, res) => {
|
||||
const search = typeof req.query.q === "string" ? req.query.q.trim() : "";
|
||||
|
||||
let sql = `
|
||||
SELECT
|
||||
e.*,
|
||||
COUNT(eg.geometry_id) AS geometry_count
|
||||
FROM entities e
|
||||
LEFT JOIN entity_geometries eg
|
||||
ON eg.entity_id = e.id
|
||||
WHERE e.is_deleted = 0
|
||||
`;
|
||||
const params = [];
|
||||
|
||||
if (search) {
|
||||
sql += " AND (e.name LIKE ? OR e.slug LIKE ?)";
|
||||
const pattern = `%${search}%`;
|
||||
params.push(pattern, pattern);
|
||||
}
|
||||
|
||||
sql += `
|
||||
GROUP BY e.id
|
||||
ORDER BY e.name COLLATE NOCASE ASC
|
||||
`;
|
||||
|
||||
const rows = db.prepare(sql).all(...params);
|
||||
res.json(rows.map(normalizeEntityRow));
|
||||
});
|
||||
|
||||
router.get("/search", (req, res) => {
|
||||
const name = typeof req.query.name === "string" ? req.query.name.trim() : "";
|
||||
const limit = normalizeLimit(req.query.limit, 25, 100);
|
||||
|
||||
if (!name) {
|
||||
return res.json([]);
|
||||
}
|
||||
|
||||
const pattern = `%${name}%`;
|
||||
const rows = db.prepare(`
|
||||
SELECT
|
||||
e.*,
|
||||
COUNT(eg.geometry_id) AS geometry_count
|
||||
FROM entities e
|
||||
LEFT JOIN entity_geometries eg
|
||||
ON eg.entity_id = e.id
|
||||
WHERE e.is_deleted = 0
|
||||
AND e.name LIKE ?
|
||||
GROUP BY e.id
|
||||
ORDER BY e.name COLLATE NOCASE ASC
|
||||
LIMIT ?
|
||||
`).all(pattern, limit);
|
||||
|
||||
res.json(rows.map(normalizeEntityRow));
|
||||
});
|
||||
|
||||
router.get("/:id", (req, res) => {
|
||||
const row = db.prepare(`
|
||||
SELECT
|
||||
e.*,
|
||||
COUNT(eg.geometry_id) AS geometry_count
|
||||
FROM entities e
|
||||
LEFT JOIN entity_geometries eg
|
||||
ON eg.entity_id = e.id
|
||||
WHERE e.id = ?
|
||||
AND e.is_deleted = 0
|
||||
GROUP BY e.id
|
||||
`).get(req.params.id);
|
||||
|
||||
if (!row) {
|
||||
return res.status(404).json({ error: "Entity not found" });
|
||||
}
|
||||
|
||||
res.json(normalizeEntityRow(row));
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
function normalizeEntityRow(row) {
|
||||
return {
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
slug: row.slug,
|
||||
description: row.description,
|
||||
type_id: row.type_id,
|
||||
status: row.status,
|
||||
created_at: row.created_at,
|
||||
updated_at: row.updated_at,
|
||||
geometry_count: Number(row.geometry_count || 0),
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeLimit(value, fallback = 25, max = 100) {
|
||||
const num = Number(value);
|
||||
if (!Number.isFinite(num)) return fallback;
|
||||
const intValue = Math.trunc(num);
|
||||
if (intValue <= 0) return fallback;
|
||||
return Math.min(intValue, max);
|
||||
}
|
||||
Reference in New Issue
Block a user