UNPKG

@opengis/fastify-table

Version:

core-plugins

168 lines (167 loc) 6.82 kB
import { NotFoundError } from "../../types/errors.js"; import pgClients from "../pg/pgClients.js"; import dataInsert from "../crud/funcs/dataInsert.js"; import dataUpdate from "../crud/funcs/dataUpdate.js"; export async function addCustomCls({ name, description, alias, table, uid, data = [], }, pg = pgClients.client) { if (!table || !pg.pk?.[table]) { throw new Error("custom cls table not exists"); } const codes = await pg .query(`select array_agg(code) from ${table}`) .then((el) => el.rows?.[0]?.array_agg || []); const ids = await pg .query(`select json_object_agg(code, id) from ${table}`) .then((el) => el.rows?.[0]?.json_object_agg || {}); const client = await pg.connect(); try { await client.query("BEGIN"); // overwrite old if exists await client.query("delete from admin.user_cls where name=$1", [name]); // disable old await client.query(`update ${table} set active=case when code=any($1) then true else false end`, [data.map((el) => el.id)]); // insert new await Promise.all(data .filter((el) => el.id && !codes.includes(el.id)) .map(async (el) => dataInsert({ pg: client, table, data: { ...el, code: el.id, name: el.text, id: undefined }, uid, }))); // update existing await Promise.all(data .filter((el) => el.id && codes.includes(el.id) && ids[el.id]) .map(async (el) => dataUpdate({ pg: client, id: ids[el.id], table, data: { ...el, code: el.id, name: el.text, id: ids[el.id] }, uid, }))); await dataInsert({ pg: client, table: "admin.user_cls", id: table, data: { name, alias, description, code: "custom", type: "sql", data: `select code, name, description, color, icon from ${table} where active`, }, }); await client.query("COMMIT"); return "ok"; } catch (err) { await client.query("ROLLBACK"); throw err; } finally { client.release(); } } export async function deleteUserCls(name, pg = pgClients.client) { const exists = await getUserCls(name, pg); if (!exists) { throw new NotFoundError("user classifier not found"); } await pg.query("delete from admin.user_cls where (name=$1 and parent is null) or parent=$1 ", [name]); return "ok"; } export async function addUserCls({ name, alias, data, description, }, pg = pgClients.client) { const type = typeof data === "string" ? "sql" : "json"; if (type === "json" && !Array.isArray(data)) { throw new Error("param data must be an array"); } if (type === "json" && typeof data === "object" && !data.find((item) => item.id && item.text)) { throw new Error("param data must have items"); } const client = await pg.connect(); try { await client.query("begin"); if (type === "sql") { await dataInsert({ pg: client, table: "admin.user_cls", data: { name, alias, description, type, data }, }); } else if (type === "json" && Array.isArray(data)) { await dataInsert({ pg: client, table: "admin.user_cls", data: { name, alias, description, type }, }); await Promise.all(data.map(async (item) => { await dataInsert({ pg: client, table: "admin.user_cls", data: { ...item, code: item.id, name: item.text, parent: name }, }); })); } await client.query("commit"); return "ok"; } catch (err) { await client.query("rollback"); throw err; } finally { client.release(); } } export async function editUserCls({ name, alias, description, data, }, pg = pgClients.client) { await deleteUserCls(name, pg); await addUserCls({ name, alias, description, data }, pg); return "ok"; } export async function getUserClsList({ name, search, sql, custom, type, }, pg = pgClients.client) { const args = name ? [name.split(",")] : [search].filter(Boolean); const subQuery = search ? `case when parent<>$1 then name ilike '%'||$1||'%' else true end` : "true"; const typeStr = type ? { cls: "json", select: "sql" }[type] : null; const where = (name ? "name=any($1::text[])" : null) || (search ? `( name ilike '%'||$1||'%' or name in (select parent from admin.user_cls where name ilike '%'||$1||'%') )` : "1=1"); const customQuery = `select true as custom, name, type, description, alias, (select count(*) filter(where ${subQuery}) from admin.user_cls where parent=t.name limit 1) as count from admin.user_cls t where parent is null and ${where} and ${typeStr ? `type='${typeStr}'` : "true"}`; const gitQuery = `select false as custom, name, type, null as description, null as alias, (select count(*) filter(where ${subQuery}) from admin.cls where parent=t.name limit 1) as count from admin.cls t where parent is null and ${where.replace(/admin.user_cls/g, "admin.cls")} and ${typeStr ? `type='${typeStr}'` : "true"}`; const q = [ custom !== "0" ? customQuery : null, custom !== "1" ? gitQuery : null, ] .filter(Boolean) .join(" union all ") .concat(" order by name"); if (sql) return q; const rows = await pg.query(q, args).then((el) => el.rows || []); const customRows = rows.filter((row) => row.custom); const customClsNames = customRows.map((row) => row.name); const filteredRows = rows.filter((row) => !customClsNames.includes(row.name)); return customRows.concat(filteredRows); } export async function getUserCls(name, pg = pgClients.client) { const { type, data, description, alias } = await pg .query("select type, data, description, alias from admin.user_cls where parent is null and name=$1", [name]) .then((el) => el.rows?.[0] || {}); if (type === "sql") { return { type, data, description, alias }; } if (type === "json") { const options = await pg .query(`select json_agg(json_build_object('id', code, 'text', name, 'icon', icon, 'color', color)) from admin.user_cls where parent=$1`, [name]) .then((el) => el.rows?.[0]?.json_agg || []); return { type, data: options, description, alias }; } return null; } export default null;