@opengis/fastify-table
Version:
core-plugins
168 lines (167 loc) • 6.82 kB
JavaScript
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;