UNPKG

@opengis/fastify-table

Version:

core-plugins

113 lines (112 loc) 4.52 kB
import { getTemplate, getMeta, metaFormat, applyHook, handlebars, pgClients, } from "../../../../utils.js"; export default async function tableInfo({ pg = pgClients.client, params, query = {}, user = {}, }, reply) { const time = Date.now(); const { uid } = user; if (!uid) { return reply.status(403).send("access restricted: uid"); } if (!params?.id || !params?.table) { return reply.status(400).send("not enougn params"); } const loadTable = await getTemplate("table", params.table); if (!loadTable) { return reply.status(404).send("template not found"); } const { table, columns = [], sql, cardSql, filters, form, meta, public: ispublic, } = loadTable; if (!meta?.info) { return reply.status(400).send("empty meta info"); } const tableMeta = await getMeta({ pg, table }); if (tableMeta?.view) { if (!loadTable?.key) { return reply.status(404).send(`key not found: ${table}`); } Object.assign(tableMeta, { pk: loadTable?.key }); } const { pk } = tableMeta || {}; if (!pk) { return reply.status(404).send(`table not found: ${table}`); } const sqlTable = sql ?.filter?.((el) => !el?.disabled && el?.sql?.replace) ?.map((el, i) => ` left join lateral (${el.sql.replace("{{uid}}", uid)}) ${el.name || `t${i}`} on 1=1 `) ?.join("") || ""; const cardSqlFiltered = params.id ? cardSql?.filter?.((el) => !el?.disabled && el?.name && el?.sql?.replace) || [] : []; const cardSqlTable = cardSqlFiltered.length ? cardSqlFiltered .map((el, i) => ` left join lateral (${el.sql.replace("{{uid}}", uid)}) ct${i} on 1=1 `) .join("\n") || "" : ""; const interfaceQuery = params?.query ? await handlebars.compile(params?.query)({ user, uid }) : undefined; const where = [ params.id ? `"${pk}" = $1` : null, loadTable.query, interfaceQuery, ] .filter((el) => el) .filter((el) => user?.user_type === "superadmin" ? !el.includes("{{uid}}") : true); const { fields = [] } = await pg.query(`select * from ${table} where ${sqlTable ? "true" : where.join(" and ") || "true"} limit 0`, [sqlTable ? null : params.id].filter((el) => el)); const columnList = fields.map((el) => el.name); const metaInfoCols = meta.info .split(",") .filter((el) => columnList.includes(el)) .map((el) => `"${el}"`); if (!metaInfoCols.length) { return reply.status(400).send("invalid meta info: columns not found"); } const q = `select ${pk ? `"${pk}" as id,` : ""} ${metaInfoCols.join(",")} from (select * from ${table} where ${sqlTable ? "true" : where.join(" and ") || "true"}) t ${sqlTable} ${cardSqlTable} where ${where.join(" and ") || "true"} limit 1`.replace(/{{uid}}/g, uid); if (query.sql === "1") { return q; } const { rows } = await pg.query(q, [params.id]); const qCount = `select count(*)::int as total, count(*) FILTER(WHERE ${[interfaceQuery].filter((el) => el).join(" and ") || "true"})::int as filtered from ${table} t ${sqlTable} where ${[loadTable.query].filter((el) => el).join(" and ") || "true"} `.replace(/{{uid}}/g, uid); const { total, filtered } = params.id ? rows.length : await pg .queryCache?.(qCount, { table: loadTable.table, time: 5 }) .then((el) => el?.rows?.[0] || {}); const cls = meta.info .split(",") .filter((el) => columnList.includes(el)) .map((el) => ({ name: el, data: columns.find((col) => col.name === el)?.data, })) .filter((el) => el.data) .reduce((acc, curr) => Object.assign(acc, { [curr.name]: curr.data }), {}); await metaFormat({ rows, cls /* , sufix: false */ }, pg); const res = { time: Date.now() - time, public: ispublic, card: loadTable.card, total, filtered, count: rows.length, pk, form, rows, meta, columns, filters, }; const result = await applyHook("afterData", { table: loadTable.table, payload: res, user, }); return result || res; }