@opengis/fastify-table
Version:
core-plugins
111 lines (81 loc) • 4.37 kB
JavaScript
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;
}