@opengis/fastify-table
Version:
core-plugins
86 lines (85 loc) • 3.2 kB
JavaScript
import getSelect from "../getSelect.js";
import pgClients from "../../../pg/pgClients.js";
import rclient from "../../../redis/client.js";
import config from "../../../../../config.js";
const selectIds = {};
export default async function getSelectVal({ pg = pgClients.client, name, values: valuesOrigin, ar = false, }) {
if (!valuesOrigin?.length)
return null;
const values = valuesOrigin
.filter((el) => (typeof el === "boolean" ? true : el))
.map((el) => el.toString());
const cls = await getSelect(name, pg);
// === array ===
if (cls?.arr && Array.isArray(cls?.arr)) {
const resultArr = cls.arr.filter((el) => values.includes(el.id.toString()));
if (ar)
return resultArr;
return resultArr.reduce((p, el) => ({
...p,
[el.id.toString()]: el.color ? el : el.text,
}), {});
}
// === sql ===
if (!cls?.sql)
return null;
// select id column name
if (!selectIds[name]) {
selectIds[name] = await pg
.query(`select * from (${cls.sql})q limit 0`)
.then((el) => el.fields?.[0]?.name)
.catch((err) => console.error("getSelectVal error: 1", name, cls.sql, err.toString()));
}
const id = selectIds[name];
// cache
const table = cls.sql
?.toLowerCase?.()
?.replace?.(/[\n\r]+/g, " ")
?.split?.(" from ")
?.filter?.((el) => /^[a-z0-9_]+\.[a-z0-9_]+/.test(el))
?.map?.((el) => el.split(/[ )]/)[0])?.[0];
const crudInc = table && config.redis ? (await rclient.get(`pg:${table}:crud`)) || 0 : 0;
const key = `select:${name}:${crudInc}`;
const cache = values?.length && config.redis && !config.disableCache
? (await rclient.hmget(key, values)).reduce((p, el, i) => ({
...p,
[values[i]]: el,
}), {})
: {};
const filteredValues = values.filter((el) => !cache[el]);
// query select
const q = `with c(id,text) as (select * from (${cls.sql})q where ${id}::text = any($1::text[])) select * from c`;
const data = filteredValues.length
? await pg
.query(q, [filteredValues])
.then((el) => el.rows || [])
.catch((err) => {
console.error("getSelectVal error: 2", name, q, err.toString());
return [];
})
: [];
const clsObj = {
...cache,
...data.reduce((p, el) => ({
...p,
[el.id.toString()]: el.color ? el : el.text,
}), {}),
};
const cacheableValues = Object.entries(clsObj).find(([key, val]) => typeof val !== "object")
? Object.fromEntries(Object.entries(clsObj).filter(([key, val]) => typeof val !== "object"))
: null;
if (data?.length && config.redis && cacheableValues) {
rclient.hmset(key, clsObj);
}
if (ar) {
return Object.keys(clsObj).reduce((acc, el) => {
acc.push({
id: el,
text: typeof clsObj[el] === "string" ? clsObj[el] : clsObj[el]?.text,
color: clsObj[el]?.color,
});
return acc;
}, []);
}
return clsObj;
}