@opengis/fastify-table
Version:
core-plugins
103 lines (102 loc) • 3.68 kB
JavaScript
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,
};
}