@opengis/fastify-table
Version:
core-plugins
135 lines (134 loc) • 4.66 kB
JavaScript
import getPG from "../../pg/funcs/getPG.js";
import getRedis from "../../redis/funcs/getRedis.js";
import pgClients from "../../pg/pgClients.js";
import getTemplate from "../../table/funcs/getTemplate.js";
import config from "../../../../config.js";
import logChanges from "./utils/logChanges.js";
import getInsertQuery from "./utils/getInsertQuery.js";
import logger from "../../logger/getLogger.js";
import extraData from "../../extra/extraData.js";
const rclient = getRedis();
export default async function dataInsert({ id, table: table1, referer, data, pg: pg1, uid, tokenData = {}, }) {
const pg = pg1 || getPG({ name: "client" });
if (!pg)
return null;
// pg client single transaction support
if (!pg?.pk && config.pg) {
pg.options = pgClients.client?.options;
pg.tlist = pgClients.client?.tlist;
pg.pgType = pgClients.client?.pgType;
pg.relkinds = pgClients.client?.relkinds;
pg.pk = pgClients.client?.pk;
}
const { unittest } = tokenData || {};
if (config.trace || unittest)
console.log("form", tokenData?.form);
const table = pg.pk?.[table1] ? table1 : table1.replace(/"/g, "");
const { insertQuery, args = [] } = (await getInsertQuery({
pg,
table,
data,
id,
uid,
})) || {};
if (!insertQuery || !args.length)
return null;
// for transactions
const isClient = typeof pg.query === "function" && typeof pg.release === "function";
const client = (isClient ? pg : await pg.connect());
if (!isClient) {
// client.caller = 'dataInsert';
}
if (isClient || !client.pk) {
client.options = pg.options;
client.tlist = pg.tlist;
client.pgType = pg.pgType;
client.relkinds = pg.relkinds;
client.pk = pg.pk;
}
try {
if (!isClient) {
await client.query("begin;");
}
const res = await client
.query(insertQuery, args)
.then((el) => el || {});
const id1 = res.rows?.[0]?.[pg.pk?.[table] || ""];
if (!id1)
return null;
await extraData({
table,
form: tokenData?.form,
id: id1,
data,
uid,
row: res.rows[0],
}, client);
// foreign key dataTable (table + parent_id)
const formData = tokenData?.form
? (await getTemplate("form", tokenData.form)) || {}
: {};
const schema = formData?.schema || formData;
const parentKeys = Object.keys(schema || {})?.filter((key) => data[key]?.length &&
Array.isArray(data[key]) &&
schema?.[key]?.table &&
schema?.[key]?.parent_id);
if (parentKeys?.length) {
await Promise.all(parentKeys?.map(async (key) => {
const parentKey = schema[key].parent_id;
const objId = data[parentKey] || data?.id || res?.rows?.[0]?.[parentKey] || id1;
const parentRows = await Promise.all(data[key].map(async (row) => {
Object.assign(row, { [parentKey]: objId });
const parentRes = await getInsertQuery({
pg: client,
table: schema[key].table,
data: row,
uid,
});
if (!parentRes?.insertQuery || !parentRes?.args?.length)
return null;
const { rows = [] } = await client.query(parentRes.insertQuery, parentRes.args);
return rows[0];
}));
Object.assign(res.rows[0], { [key]: parentRows.filter(Boolean) });
}));
}
await logChanges({
pg: client,
table,
tokenData,
referer,
data,
id: id1,
uid,
type: "INSERT",
});
if (config.redis && rclient?.status !== "end") {
rclient.incr(`pg:${table}:crud`);
}
if (!isClient) {
await client.query("commit;");
}
return { ...res, id: id1, data: res.rows[0] };
}
catch (err) {
logger.file("crud/insert", {
error: err.toString(),
stack: err.stack,
table,
id,
referer,
uid,
form: tokenData?.form,
});
if (!isClient) {
await client.query("rollback;");
}
throw err;
}
finally {
if (!isClient) {
client?.release?.();
}
}
}