UNPKG

@opengis/fastify-table

Version:

core-plugins

103 lines (102 loc) 3.68 kB
import { getMeta, metaFormat, getTemplates, getTemplate, handlebarsSync, pgClients, } from "../../../../utils.js"; function sequence(tables, data, fn) { return tables.reduce((promise, table) => promise.then(() => fn({ ...data, tableName: table.replace(".json", ""), })), Promise.resolve()); } async function getData({ pg = pgClients.client, tableName, query = {}, maxLimit, res, }) { const loadTable = await getTemplate("table", tableName); if (!loadTable) { return null; } const { table, columns, meta } = loadTable; const { pk, view } = await getMeta({ pg, table }); if (!pk && !view) { return null; } const cols = columns.map((el) => el.name || el).join(","); const [orderColumn, orderDir] = (query.order || loadTable.order || "").split("-"); const order = cols.includes(orderColumn) && orderColumn?.length ? `order by ${orderColumn} ${query.desc || orderDir === "desc" ? "desc" : ""}` : ""; const limit = Math.max(maxLimit - res.rows.length, 0); // Math.max(query.offset - res.rows.length,0) const offset = query.page && query.page > 0 ? ` offset ${(query.page - 1) * limit}` : ""; const search1 = meta?.search && query.key ? `(${meta?.search .concat(meta?.title ? `,${meta?.title}` : "") .split(",") .map((el) => `${el}::text ilike '%${query.key}%'`) .join(" or ")})` : "false"; const where = [!pk ? "false" : "true", loadTable.query, search1].filter(Boolean); const sqlTable = loadTable.sql ?.filter?.((el) => !el?.disabled) ?.map((el, i) => ` left join lateral (${el.sql}) ${el.name || `t${i}`} on 1=1 `) ?.join?.("") || ""; const q = `select ${[ `"${pk}" as id`, meta?.title ? `${meta.title} as title` : "", ] .filter((el) => el) .join(",")} from ${table} t ${sqlTable} where ${where.join(" and ") || "true"} ${order} ${offset} limit ${limit}`; if (query.sql) { res.sql.push(q); return null; } const rows = await pg.query(q).then((el) => el.rows || []); const filtered = pg.queryCache ? await pg .queryCache(`select count(*) from ${table} t ${sqlTable} where ${where.join(" and ") || "true"}`) .then((el) => +(el?.rows[0]?.count || 0)) : 0; const total = pg.queryCache ? await pg .queryCache(`select count(*) from ${table}`) .then((el) => +(el?.rows[0]?.count || 0)) : 0; await metaFormat({ rows, table: tableName }); res.total += +total; res.filtered += +filtered; rows.forEach((row) => { const href = meta?.href ? handlebarsSync.compile(meta.href)({ ...row, [pk]: row.id }) : undefined; res.rows.push({ ...row, register: tableName, register_title: loadTable.ua, href, }); }); return null; } export default async function search({ pg = pgClients.client, query = {}, }) { const t1 = Date.now(); const tables = query.table ? [query.table] : getTemplates("table")?.map?.((el) => el[0]); const res = { rows: [], sql: [], total: 0, filtered: 0, }; const maxLimit = Math.min(100, query.limit || "16"); await sequence(tables, { pg, query, maxLimit, res, }, getData); if (query.sql) return res.sql.join(";\n"); return { time: Date.now() - t1, total: res.total, filtered: res.filtered, count: res.rows.length, rows: res.rows, }; }