diff --git a/packages/web/src/appobj/databaseAppObject.js b/packages/web/src/appobj/databaseAppObject.js index 88abc2583..ae4598f49 100644 --- a/packages/web/src/appobj/databaseAppObject.js +++ b/packages/web/src/appobj/databaseAppObject.js @@ -3,6 +3,7 @@ import _ from 'lodash'; import { DropDownMenuItem } from '../modals/DropDownMenu'; import { openNewTab } from '../utility/common'; import ImportExportModal from '../modals/ImportExportModal'; +import { defaultFileFormat } from '../fileformats'; function Menu({ data, setOpenedTabs, showModal }) { const { connection, name } = data; @@ -26,7 +27,7 @@ function Menu({ data, setOpenedTabs, showModal }) { x.storageType == storageType); +} + +export function getFileFormatDirections(format: FileFormatDefinition) { + if (!format) return []; + const res = []; + if (format.readerFunc) res.push('source'); + if (format.writerFunc) res.push('target'); + return res; +} + +export const defaultFileFormat = csv; \ No newline at end of file diff --git a/packages/web/src/fileformats/jsonl.ts b/packages/web/src/fileformats/jsonl.ts new file mode 100644 index 000000000..f386be88e --- /dev/null +++ b/packages/web/src/fileformats/jsonl.ts @@ -0,0 +1,7 @@ +export default { + storageType: 'jsonl', + extension: 'jsonl', + readerFunc: 'jsonLinesReader', + writerFunc: 'jsonLinesWriter', + filesTitle: 'JSON lines', +}; diff --git a/packages/web/src/fileformats/types.ts b/packages/web/src/fileformats/types.ts new file mode 100644 index 000000000..8e01d0c0f --- /dev/null +++ b/packages/web/src/fileformats/types.ts @@ -0,0 +1,7 @@ +export interface FileFormatDefinition { + storageType: string; + extension: string; + readerFunc?: string; + writerFunc?: string; + filesTitle: string; +} diff --git a/packages/web/src/impexp/ImportExportConfigurator.js b/packages/web/src/impexp/ImportExportConfigurator.js index 812edd907..b152afa17 100644 --- a/packages/web/src/impexp/ImportExportConfigurator.js +++ b/packages/web/src/impexp/ImportExportConfigurator.js @@ -25,6 +25,7 @@ import SqlEditor from '../sqleditor/SqlEditor'; import { useUploadsProvider } from '../utility/UploadsProvider'; import { FontIcon } from '../icons'; import useTheme from '../theme/useTheme'; +import { fileformats, findFileFormat, getFileFormatDirections } from '../fileformats'; const Container = styled.div` // max-height: 50vh; @@ -89,9 +90,8 @@ const Title = styled.div` function getFileFilters(storageType) { const res = []; - if (storageType == 'csv') res.push({ name: 'CSV files', extensions: ['csv'] }); - if (storageType == 'jsonl') res.push({ name: 'JSON lines', extensions: ['jsonl'] }); - if (storageType == 'excel') res.push({ name: 'MS Excel files', extensions: ['xlsx'] }); + const format = findFileFormat(storageType); + if (format) res.push({ name: format.filesTitle, extensions: [format.extension] }); res.push({ name: 'All Files', extensions: ['*'] }); return res; } @@ -193,9 +193,11 @@ function SourceTargetConfig({ ? [{ value: 'jsldata', label: 'Query result data', directions: ['source'] }] : [ { value: 'database', label: 'Database', directions: ['source', 'target'] }, - { value: 'csv', label: 'CSV file(s)', directions: ['source', 'target'] }, - { value: 'jsonl', label: 'JSON lines file(s)', directions: ['source', 'target'] }, - { value: 'excel', label: 'MS Excel file(s)', directions: ['source'] }, + ...fileformats.map((format) => ({ + value: format.storageType, + label: format.filesTitle, + directions: getFileFormatDirections(format), + })), { value: 'query', label: 'SQL Query', directions: ['source'] }, { value: 'archive', label: 'Archive', directions: ['source', 'target'] }, ]; @@ -374,7 +376,7 @@ export default function ImportExportConfigurator({ uploadedFile = undefined, onC } }, []); - const supportsPreview = ['csv', 'jsonl', 'excel'].includes(values.sourceStorageType); + const supportsPreview = !!findFileFormat(values.sourceStorageType); const handleChangePreviewSource = async () => { if (previewSource && supportsPreview) { diff --git a/packages/web/src/impexp/createImpExpScript.js b/packages/web/src/impexp/createImpExpScript.js index 28c2f0aa8..8afde4819 100644 --- a/packages/web/src/impexp/createImpExpScript.js +++ b/packages/web/src/impexp/createImpExpScript.js @@ -4,17 +4,18 @@ import getAsArray from '../utility/getAsArray'; import { getConnectionInfo } from '../utility/metadataLoaders'; import engines from 'dbgate-engines'; import { findObjectLike } from 'dbgate-tools'; +import { findFileFormat } from '../fileformats'; export function getTargetName(source, values) { const key = `targetName_${source}`; if (values[key]) return values[key]; - if (values.targetStorageType == 'csv') return `${source}.csv`; - if (values.targetStorageType == 'jsonl') return `${source}.jsonl`; + const format = findFileFormat(values.targetStorageType); + if (format) return `${source}.${format.extension}`; return source; } export function isFileStorage(storageType) { - return storageType == 'csv' || storageType == 'jsonl' || storageType == 'excel'; + return !!findFileFormat(storageType); } async function getConnection(storageType, conid, database) { @@ -55,14 +56,9 @@ function getSourceExpr(sourceName, values, sourceConnection, sourceDriver) { } if (isFileStorage(sourceStorageType)) { const sourceFile = values[`sourceFile_${sourceName}`]; - if (sourceStorageType == 'excel') { - return ['excelSheetReader', sourceFile]; - } - if (sourceStorageType == 'jsonl') { - return ['jsonLinesReader', sourceFile]; - } - if (sourceStorageType == 'csv') { - return ['csvReader', sourceFile]; + const format = findFileFormat(sourceStorageType); + if (format && format.readerFunc) { + return [format.readerFunc, sourceFile]; } } if (sourceStorageType == 'jsldata') { @@ -101,21 +97,15 @@ function getFlagsFroAction(action) { function getTargetExpr(sourceName, values, targetConnection, targetDriver) { const { targetStorageType } = values; - if (targetStorageType == 'csv') { + const format = findFileFormat(targetStorageType); + if (format && format.writerFunc) { return [ - 'csvWriter', - { - fileName: getTargetName(sourceName, values), - }, - ]; - } - if (targetStorageType == 'jsonl') { - return [ - 'jsonLinesWriter', + format.writerFunc, { fileName: getTargetName(sourceName, values), }, ]; + } if (targetStorageType == 'database') { return [ diff --git a/packages/web/src/modals/ImportExportModal.js b/packages/web/src/modals/ImportExportModal.js index 23be758a1..bd62384d8 100644 --- a/packages/web/src/modals/ImportExportModal.js +++ b/packages/web/src/modals/ImportExportModal.js @@ -22,6 +22,7 @@ import useSocket from '../utility/SocketProvider'; import LoadingInfo from '../widgets/LoadingInfo'; import { FontIcon } from '../icons'; import LargeButton from '../widgets/LargeButton'; +import { defaultFileFormat } from '../fileformats'; const headerHeight = '60px'; const footerHeight = '100px'; @@ -193,7 +194,7 @@ export default function ImportExportModal({ onSubmit={handleExecute} initialValues={{ sourceStorageType: 'database', - targetStorageType: importToArchive ? 'archive' : 'csv', + targetStorageType: importToArchive ? 'archive' : defaultFileFormat.storageType, sourceArchiveFolder: archive, targetArchiveFolder, ...initialValues, diff --git a/packages/web/src/utility/UploadsProvider.js b/packages/web/src/utility/UploadsProvider.js index f700f4caf..81a5de7d2 100644 --- a/packages/web/src/utility/UploadsProvider.js +++ b/packages/web/src/utility/UploadsProvider.js @@ -1,5 +1,6 @@ import React from 'react'; import { useDropzone } from 'react-dropzone'; +import { findFileFormat } from '../fileformats'; import ImportExportModal from '../modals/ImportExportModal'; import useShowModal from '../modals/showModal'; import resolveApi from './resolveApi'; @@ -42,7 +43,7 @@ export function useUploadsZone() { if (uploadListener) { uploadListener(fileData); } else { - if (['csv', 'excel', 'jsonl'].includes(fileData.storageType)) { + if (findFileFormat(fileData.storageType)) { showModal((modalState) => (