@opengis/fastify-table
Version:
core-plugins
94 lines (93 loc) • 3.64 kB
JavaScript
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;
}