UNPKG

@opengis/fastify-table

Version:

core-plugins

131 lines (109 loc) 3.96 kB
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(); } } }