UNPKG

@opengis/fastify-table

Version:

core-plugins

111 lines (81 loc) 4.37 kB
import { getTemplate, getMeta, metaFormat, applyHook, handlebars, pgClients, } from '../../../../utils.js'; export default async function tableInfo(req, reply) { const { pg = pgClients.client, params = {}, query = {}, user = {}, } = req; const time = Date.now(); const { uid } = user; if (!uid) { return reply.status(403).send('access restricted: uid'); } if (!params?.id || !params?.table) { return reply.status(400).send('not enougn params'); } const loadTable = await getTemplate('table', params.table); if (!loadTable) { return reply.status(404).send('template not found'); } const { table, columns = [], sql, cardSql, filters, form, meta, public: ispublic, } = loadTable; if (!meta?.info) { return reply.status(400).send('empty meta info'); } const tableMeta = await getMeta({ pg, table }); if (tableMeta?.view) { if (!loadTable?.key) { return reply.status(404).send(`key not found: ${table}`); } Object.assign(tableMeta, { pk: loadTable?.key }); } const { pk } = tableMeta || {}; if (!pk) { return reply.status(404).send(`table not found: ${table}`); } const sqlTable = sql ?.filter?.((el) => !el?.disabled && el?.sql?.replace) ?.map((el, i) => ` left join lateral (${el.sql.replace('{{uid}}', uid)}) ${el.name || `t${i}`} on 1=1 `) ?.join('') || ''; const cardSqlFiltered = params.id ? (cardSql?.filter?.((el) => !el?.disabled && el?.name && el?.sql?.replace) || []) : []; const cardSqlTable = cardSqlFiltered.length ? cardSqlFiltered.map((el, i) => ` left join lateral (${el.sql.replace('{{uid}}', uid)}) ct${i} on 1=1 `).join('\n') || '' : ''; const interfaceQuery = params?.query ? await handlebars.compile(params?.query)({ user, uid }) : undefined; const where = [params.id ? `"${pk}" = $1` : null, loadTable.query, interfaceQuery].filter((el) => el).filter((el) => (user?.user_type === 'superadmin' ? !el.includes('{{uid}}') : true)); const { fields = [] } = await pg.query(`select * from ${table} where ${sqlTable ? 'true' : (where.join(' and ') || 'true')} limit 0`, ([sqlTable ? null : params.id].filter(el => el)) ); const columnList = fields.map(el => el.name); const metaInfoCols = meta.info.split(',').filter(el => columnList.includes(el)).map((el) => `"${el}"`); if (!metaInfoCols.length) { return reply.status(400).send('invalid meta info: columns not found'); } const q = `select ${pk ? `"${pk}" as id,` : ''} ${metaInfoCols.join(',')} from (select * from ${table} where ${sqlTable ? 'true' : (where.join(' and ') || 'true')}) t ${sqlTable} ${cardSqlTable} where ${where.join(' and ') || 'true'} limit 1` .replace(/{{uid}}/g, uid); if (query.sql === '1') { return q; } const { rows } = await pg.query(q, [params.id]); const qCount = `select count(*)::int as total, count(*) FILTER(WHERE ${[interfaceQuery].filter(el => el).join(' and ') || 'true'})::int as filtered from ${table} t ${sqlTable} where ${[loadTable.query].filter(el => el).join(' and ') || 'true'} ` .replace(/{{uid}}/g, uid); const { total, filtered } = params.id ? rows.length : await pg.queryCache(qCount, { table: loadTable.table, time: 5 }).then(el => el?.rows?.[0] || {}); const cls = meta.info.split(',').filter(el => columnList.includes(el)) .map(el => ({ name: el, data: columns.find(col => col.name === el)?.data })) .filter(el => el.data) .reduce((acc, curr) => Object.assign(acc, { [curr.name]: curr.data }), {}); await metaFormat({ rows, cls /* , sufix: false */ }, pg); const res = { time: Date.now() - time, public: ispublic, card: loadTable.card, total, filtered, count: rows.length, pk, form, rows, meta, columns, filters, }; const result = await applyHook('afterData', { table: loadTable.table, payload: res, user, }); return result || res; }