@opengis/bi
Version:
BI data visualization module
135 lines (106 loc) • 4.74 kB
JavaScript
import path from 'node:path';
import { existsSync } from 'node:fs';
import { config, pgClients, getFolder, file2json } from '@opengis/fastify-table/utils.js';
import createTableQuery from '../utils/createTableQuery.js';
import executeQuery from '../utils/executeQuery.js';
import downloadRemoteFile from '../utils/downloadRemoteFile.js';
const insertDataset = `insert into bi.dataset
(name, table_name, dataset_file_path, column_list, pk, data_source, uid)
values($1,$2,$3,$4,$5,$6,$7) returning dataset_id`;
export default async function createDatasetPost({
pg = pgClients.client, body = {}, user = {},
}) {
if (!user?.uid) {
return { message: 'access restricted', status: 403 };
}
if (!body?.name) {
return { message: 'not enough query params: name', status: 400 };
}
if (!body?.table_name && !body?.file && !body?.column_list?.length && !body?.dataset_url) {
return { message: 'not enough query params: table / file / column_list/ url', status: 400 };
}
const {
name,
table_name: existingTable,
column_list: columns = [],
dataset_url: datasetUrl,
encoding,
} = body;
const rootDir = getFolder(config, 'local');
if (datasetUrl) {
const { filePath, error } = await downloadRemoteFile({
rootDir, url: datasetUrl, table: name || datasetUrl,
});
if (error || !filePath) {
return { message: error || 'file request URL error', status: 500 };
}
Object.assign(body, { file: filePath });
}
const { file: relPath } = body;
if (relPath) {
const filepath = path.join(rootDir, relPath);
const exists = existsSync(filepath);
if (!exists) {
return { message: 'Файл з вихідними даними не знайдено', status: 404 };
}
const json = await file2json({ filepath, encoding });
// excel sheets fix?
const data1 = (['.xls', '.xlsx'].includes(path.extname(filepath)) && !Array.isArray(json)) ? json[Object.keys(json)[0]] : json;
const data = path.extname(filepath) === '.json' && body?.key ? data1?.[body.key] : data1;
const features = ['.csv', '.xlsx', '.xls'].includes(path.extname(filepath))
? data?.map?.((el) => ({ type: 'Feature', properties: Object.keys(el).reduce((acc, curr) => Object.assign(acc, { [curr]: el[curr] }), {}) }))
: data?.features || data?.map?.((el) => ({ type: 'Feature', geometry: el.geom, properties: Object.keys(el).filter((key) => key !== 'geom').reduce((acc, curr) => Object.assign(acc, { [curr]: el[curr] }), {}) }));
if (!Array.isArray(features) || !features?.length) {
return { message: 'Файл з вихідними даними порожній', status: 400 };
}
Object.assign(data, { features });
const fileColumns = Object.keys(data?.features[0]?.properties)
?.filter((el) => !['editor_date', 'cdate', 'uid', 'editor_id', 'files'].includes(el.toLowerCase()))
?.map((el) => ({ title: el, format: 'text' }));
const { sql, pkey, table } = createTableQuery(fileColumns, name);
const { datasetId, error } = await executeQuery({
pg,
sql,
data,
name,
table,
relPath,
columns: fileColumns,
pkey,
source: datasetUrl ? 'url' : 'file',
url: datasetUrl,
user,
dataKey: body?.key,
});
if (error) return { error, status: 500 };
pg.pk[table] = pkey;
pg.tlist.push(table);
return { message: { id: datasetId, table, source: datasetUrl ? 'url' : 'file' }, status: 200 };
}
if (existingTable) {
await pg.query(`alter table ${existingTable} add column if not exists geom public.geometry;
alter table ${existingTable} add column if not exists files json`);
const args = [name, existingTable, null, null, pg.pk?.[existingTable], JSON.stringify({ type: 'table' }), user?.uid];
const datasetId = await pg.query(insertDataset, args).then(el => el.rows?.[0]?.dataset_id);
return { message: { id: datasetId, table: existingTable, source: 'table' }, status: 200 };
}
if (!columns?.length) {
return { message: 'У даній заяві відсутні налаштування структури набору даних', status: 400 };
}
const { sql, pkey, table } = createTableQuery(columns, name);
const { datasetId, error } = await executeQuery({
pg,
sql,
name,
table,
relPath,
columns,
pkey,
source: 'newtable',
user,
});
if (error) return { error, status: 500 };
pg.pk[table] = pkey;
pg.tlist.push(table);
return { message: { id: datasetId, table, source: 'newtable' }, status: 200 };
}