UNPKG

@opengis/bi

Version:

BI data visualization module

150 lines (121 loc) 5.29 kB
import { config, pgClients, getMeta, getFilterSQL, setToken, getToken, } from '@opengis/fastify-table/utils.js'; import metaFormat from '../utils/metaFormat.js'; import datasetFormData from './table.js'; import datasetFormBody from './form.js'; const maxLimit = 100; export default async function datasetData(req, reply) { const { pg = pgClients.client, params = {}, query = {}, user = {}, } = req; const time = Date.now(); const { uid, user_type: userType = 'regular' } = user; if (!uid) { // return { message: 'access restricted', status: 403 }; } if (!params?.id) { return { message: 'not enough params: id', status: 404 }; } const tokenData = await getToken({ uid: user?.uid, token: params.id, mode: 'w', json: 1, }); if (tokenData?.dataset && tokenData?.id) { return datasetFormData(req, reply); } const dataset = await pg.query(`select dataset_id as id, table_name as table, column_list as columns, filter_list as filters, sql_list as sql, style, form_setting, pk, access_level, dashboard_list from bi.dataset where dataset_id=$1`, [params.id]).then(el => el.rows[0] || {}); if (!dataset?.id) { return { message: 'dataset not found', status: 404 }; } const tlist = await pg.query(`select array_agg((select nspname from pg_namespace where oid=relnamespace)||'.'||relname) tlist from pg_class where relkind in ('r','v')`).then(el => el.rows[0]?.tlist || []); if (!dataset.table || !tlist.includes(dataset.table.replace(/"/g, '')) || (!pg.pk?.[dataset.table.replace(/"/g, '')] && !dataset.pk)) { return { message: `table not found: ${dataset.table}`, status: 404 }; } const { pk = dataset.pk, columns: dbColumns = [] } = await getMeta(dataset.table) || {}; const cols = dataset.columns?.filter((el) => el.name !== 'geom')?.map((el) => el.name || el)?.join(','); const limit = Math.min(maxLimit, +(query.limit || 20)); const offset = query.page && query.page > 0 ? ` offset ${(query.page - 1) * limit}` : ''; const checkFilter = [query.filter, query.search].filter((el) => el).length; const fData = checkFilter ? await getFilterSQL({ table: dataset.table, filter: query.filter, search: query.search, json: 1, }) : {}; const where = [dataset.query, fData.q].filter((el) => el); const sqlTable = dataset.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 columnList = dbColumns.map((el) => el.name || el).join(','); const order = columnList.includes('cdate') ? (`order by cdate ${query.desc ? 'desc' : ''}`) : ''; const q = `select ${cols || '*'} ${pk ? `,"${pk}" as id` : ''} ${dbColumns.find((el) => el.name === 'files' && pg.pgType[el.dataTypeID] === 'text') ? ',files' : ''} ${dbColumns.find((el) => el.name === 'geom' && pg.pgType[el.dataTypeID] === 'geometry') ? ',st_asgeojson(geom)::json as geom' : ''} from (select * from ${dataset.table} where ${sqlTable ? 'true' : (where.join(' and ') || 'true')} ${order}) t ${sqlTable} where ${where.join(' and ') || 'true'} ${order} ${offset} limit ${limit}`.replace(/{{uid}}/g, uid || ''); if (query.sql === '1' && (config.debug || userType.includes('admin'))) { return q; } // console.log(pg.options.database, q); const { rows = [] } = await pg.query(q); const qCount = `select count(*)::int as total, count(*) FILTER(WHERE ${[fData.q].filter(el => el).join(' and ') || 'true'})::int as filtered from ${dataset.table} t ${sqlTable} where ${[dataset.query].filter(el => el).join(' and ') || 'true'} `.replace(/{{uid}}/g, uid || ''); const { total, filtered } = await pg.queryCache(qCount).then(el => el?.rows?.[0] || {}); await metaFormat({ rows, columns: dataset.columns }); if (rows?.length && uid) { rows.filter((row) => row[pk] || row.id).forEach((row) => Object.assign(row, { token: setToken({ ids: [JSON.stringify({ id: row[pk] || row.id, table: dataset.table, form: `${params.id}.form`, dataset: params.id, })], uid, array: 1, })[0], })); } const res = { time: Date.now() - time, access: dataset.access_level, card: dataset.card, actions: ['add', 'edit', 'del', 'get'], total, filtered, count: rows.length, pk, table: dataset.table, form: `${params.id}.form`, dashboardList: dataset.dashboard_list, rows, columns: dataset.columns || dbColumns.map(col => ({ name: col.name, type: pg.pgType[col.dataTypeID], title: col.name })), filters: dataset.filters, }; if (uid) { const addTokens = setToken({ ids: [JSON.stringify({ table: dataset.table, form: `${params.id}.form`, dataset: dataset.id, })], uid, array: 1, }); Object.assign(res, { addToken: addTokens[0], }); Object.assign(req, { params: { id: addTokens[0] } }); await datasetFormBody(req); // for inline edit } return res; }