@opengis/fastify-table
Version:
core-plugins
131 lines (109 loc) • 3.96 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.incr(`pg:${table}:crud`); }
if (!isClient) {
await client.query('commit;');
}
return res;
}
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();
}
}
}