UNPKG

@opengis/fastify-table

Version:

core-plugins

94 lines (93 loc) 3.64 kB
import logger from "../../logger/getLogger.js"; import autoIndex from "../../pg/funcs/autoIndex.js"; import getPGAsync from "../../pg/funcs/getPGAsync.js"; import pgClients from "../../pg/pgClients.js"; import getSelect from "./getSelect.js"; const limit = 50; const selectMeta = {}; export default async function getSelectMeta({ name, startsWith, key, nocache, parent, pg = pgClients.client, }) { if (selectMeta[name] && !startsWith && !nocache) return selectMeta[name]; if (selectMeta[name] && startsWith && key && !nocache) { const searchQuery = `(${selectMeta[name].searchColumn .split(",") .map((el) => `left(lower("${el}"),${key.length}) = $1`) .join(" or ")})`; return { ...selectMeta[name], searchQuery }; } const cls = await getSelect(name, pg, nocache); const db = typeof cls?.db === "string" ? { database: cls.db } : cls?.db; const pg1 = cls?.db ? await getPGAsync({ database: db, port: cls?.port }) : pg; if (!cls) return null; if (cls.arr) return cls; if (!cls.sql) return null; const { sql: original } = cls; if (!original.toLowerCase) { console.log(`sql select null: ${name}`); return null; } const sql = `with c(id,text) as (select * from (${original.replace("{{parent}}", parent)})q limit ${limit}) select * from c`; /*= == meta table === */ const tableNew = original .toLowerCase() .replace(/\n/g, " ") .split(" from ") .filter((el) => /^[a-z0-9_]+\.[a-z0-9_]+/.test(el)) .map((el) => el.split(/[ )]/)[0].replace(/[\r\n]+/g, "")); const dataOrigin = await pg1.query(sql?.replace(`limit ${limit}`, "limit 0")); const dataOrigin1 = await pg1.query(`${original.replace("{{parent}}", parent)} limit 0`); // const table = getTable(original); const count = cls?.count ?? (await pg1 .query(`select count(*) from (${original.replace("{{parent}}", parent)})q`) .then((el) => el?.rows?.[0].count)); // column name const cols = dataOrigin.fields.map((el) => el.name); const originalCols = dataOrigin1.fields.map((el) => el.name); const type = dataOrigin.fields.map((el) => pg1.pgType?.[el.dataTypeID] || "text"); autoIndex({ table: tableNew[0], columns: [originalCols[1]].concat(cls?.searchColumn?.split(",")), gin: 1, }).catch((err) => logger.error(err)); const searchColumn = cls?.searchColumn || (dataOrigin.fields.find((el) => el.name === "search") ? "search" : dataOrigin1.fields[1].name); // by default - search by like %value% const searchQuery = `(${searchColumn .split(",") .map((el) => `lower("${el}") ~ $1 `) .join(" or ")})`; const data = { searchColumn, minLength: cls.minLength, limit: cls.limit, type: type.join(","), cols: cols.join(","), originalCols: originalCols.join(","), pk: originalCols[0], db: cls.db, original: `select * from (${original})q`, sql, count, searchQuery, table: tableNew.join(","), time: new Date().toISOString(), }; selectMeta[name] = data; // on demand - search by "start with these characters" if (startsWith && key?.length) { const searchQuery = `(${selectMeta[name].searchColumn .split(",") .map((el) => `left(lower("${el}"),${key.length}) = $1`) .join(" or ")})`; return { ...data, searchQuery }; } return data; }