mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-30 22:03:58 +00:00
file format refactor
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import { fileformats } from './fileformats';
|
||||||
import { FontIcon } from './icons';
|
import { FontIcon } from './icons';
|
||||||
import useTheme from './theme/useTheme';
|
import useTheme from './theme/useTheme';
|
||||||
|
|
||||||
@@ -47,7 +48,13 @@ export default function DragAndDropFileTarget({ isDragActive, inputProps }) {
|
|||||||
<FontIcon icon="icon cloud-upload" />
|
<FontIcon icon="icon cloud-upload" />
|
||||||
</IconWrapper>
|
</IconWrapper>
|
||||||
<TitleWrapper>Drop the files to upload to DbGate</TitleWrapper>
|
<TitleWrapper>Drop the files to upload to DbGate</TitleWrapper>
|
||||||
<InfoWrapper>Supported file types: csv, MS Excel, json-lines</InfoWrapper>
|
<InfoWrapper>
|
||||||
|
Supported file types:{' '}
|
||||||
|
{fileformats
|
||||||
|
.filter((x) => x.readerFunc)
|
||||||
|
.map((x) => x.name)
|
||||||
|
.join(', ')}
|
||||||
|
</InfoWrapper>
|
||||||
</InfoBox>
|
</InfoBox>
|
||||||
<input {...inputProps} />
|
<input {...inputProps} />
|
||||||
</TargetStyled>
|
</TargetStyled>
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
export default {
|
import fileFormatBase from './fileFormatBase';
|
||||||
|
import { FileFormatDefinition } from './types';
|
||||||
|
|
||||||
|
const csvFormat: FileFormatDefinition = {
|
||||||
|
...fileFormatBase,
|
||||||
storageType: 'csv',
|
storageType: 'csv',
|
||||||
extension: 'csv',
|
extension: 'csv',
|
||||||
name: 'CSV files',
|
name: 'CSV',
|
||||||
readerFunc: 'csvReader',
|
readerFunc: 'csvReader',
|
||||||
writerFunc: 'csvWriter',
|
writerFunc: 'csvWriter',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default csvFormat;
|
||||||
|
|||||||
@@ -1,6 +1,27 @@
|
|||||||
export default {
|
import { DatabaseInfo } from 'dbgate-types';
|
||||||
|
import axios from '../utility/axios';
|
||||||
|
import fileFormatBase from './fileFormatBase';
|
||||||
|
import { FileFormatDefinition } from './types';
|
||||||
|
|
||||||
|
const excelFormat: FileFormatDefinition = {
|
||||||
|
...fileFormatBase,
|
||||||
storageType: 'excel',
|
storageType: 'excel',
|
||||||
extension: 'xlsx',
|
extension: 'xlsx',
|
||||||
name: 'MS Excel files',
|
name: 'MS Excel',
|
||||||
readerFunc: 'excelSheetReader',
|
readerFunc: 'excelSheetReader',
|
||||||
|
|
||||||
|
addFilesToSourceList: async (file, newSources, newValues) => {
|
||||||
|
const resp = await axios.get(`files/analyse-excel?filePath=${encodeURIComponent(file.full)}`);
|
||||||
|
const structure: DatabaseInfo = resp.data;
|
||||||
|
for (const table of structure.tables) {
|
||||||
|
const sourceName = table.pureName;
|
||||||
|
newSources.push(sourceName);
|
||||||
|
newValues[`sourceFile_${sourceName}`] = {
|
||||||
|
fileName: file.full,
|
||||||
|
sheetName: table.pureName,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default excelFormat;
|
||||||
|
|||||||
11
packages/web/src/fileformats/fileFormatBase.ts
Normal file
11
packages/web/src/fileformats/fileFormatBase.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
const fileFormatBase = {
|
||||||
|
addFilesToSourceList: async (file, newSources, newValues) => {
|
||||||
|
const sourceName = file.name;
|
||||||
|
newSources.push(sourceName);
|
||||||
|
newValues[`sourceFile_${sourceName}`] = {
|
||||||
|
fileName: file.full,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default fileFormatBase;
|
||||||
@@ -1,7 +1,13 @@
|
|||||||
export default {
|
import fileFormatBase from './fileFormatBase';
|
||||||
|
import { FileFormatDefinition } from './types';
|
||||||
|
|
||||||
|
const jsonlFormat: FileFormatDefinition = {
|
||||||
|
...fileFormatBase,
|
||||||
storageType: 'jsonl',
|
storageType: 'jsonl',
|
||||||
extension: 'jsonl',
|
extension: 'jsonl',
|
||||||
name: 'JSON lines',
|
name: 'JSON lines',
|
||||||
readerFunc: 'jsonLinesReader',
|
readerFunc: 'jsonLinesReader',
|
||||||
writerFunc: 'jsonLinesWriter',
|
writerFunc: 'jsonLinesWriter',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default jsonlFormat;
|
||||||
|
|||||||
@@ -4,4 +4,13 @@ export interface FileFormatDefinition {
|
|||||||
name: string;
|
name: string;
|
||||||
readerFunc?: string;
|
readerFunc?: string;
|
||||||
writerFunc?: string;
|
writerFunc?: string;
|
||||||
|
addFilesToSourceList: (
|
||||||
|
file: {
|
||||||
|
full: string;
|
||||||
|
},
|
||||||
|
newSources: string[],
|
||||||
|
newValues: {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
) => void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,43 +96,31 @@ function getFileFilters(storageType) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addFilesToSourceList(files, values, setFieldValue, preferedStorageType, setPreviewSource) {
|
async function addFilesToSourceList(files, values, setValues, preferedStorageType, setPreviewSource) {
|
||||||
const newSources = [];
|
const newSources = [];
|
||||||
|
const newValues = {};
|
||||||
const storage = preferedStorageType || values.sourceStorageType;
|
const storage = preferedStorageType || values.sourceStorageType;
|
||||||
for (const file of getAsArray(files)) {
|
for (const file of getAsArray(files)) {
|
||||||
if (isFileStorage(storage)) {
|
const format = findFileFormat(storage);
|
||||||
if (storage == 'excel') {
|
if (format && format.addFilesToSourceList) {
|
||||||
const resp = await axios.get(`files/analyse-excel?filePath=${encodeURIComponent(file.full)}`);
|
await format.addFilesToSourceList(file, newSources, newValues);
|
||||||
/** @type {import('dbgate-types').DatabaseInfo} */
|
|
||||||
const structure = resp.data;
|
|
||||||
for (const table of structure.tables) {
|
|
||||||
const sourceName = table.pureName;
|
|
||||||
newSources.push(sourceName);
|
|
||||||
setFieldValue(`sourceFile_${sourceName}`, {
|
|
||||||
fileName: file.full,
|
|
||||||
sheetName: table.pureName,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const sourceName = file.name;
|
|
||||||
newSources.push(sourceName);
|
|
||||||
setFieldValue(`sourceFile_${sourceName}`, {
|
|
||||||
fileName: file.full,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
newValues['sourceList'] = [...(values.sourceList || []).filter((x) => !newSources.includes(x)), ...newSources];
|
||||||
setFieldValue('sourceList', [...(values.sourceList || []).filter((x) => !newSources.includes(x)), ...newSources]);
|
|
||||||
if (preferedStorageType && preferedStorageType != values.sourceStorageType) {
|
if (preferedStorageType && preferedStorageType != values.sourceStorageType) {
|
||||||
setFieldValue('sourceStorageType', preferedStorageType);
|
newValues['sourceStorageType'] = preferedStorageType;
|
||||||
}
|
}
|
||||||
|
setValues({
|
||||||
|
...values,
|
||||||
|
...newValues,
|
||||||
|
});
|
||||||
if (setPreviewSource && newSources.length == 1) {
|
if (setPreviewSource && newSources.length == 1) {
|
||||||
setPreviewSource(newSources[0]);
|
setPreviewSource(newSources[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ElectronFilesInput() {
|
function ElectronFilesInput() {
|
||||||
const { values, setFieldValue } = useFormikContext();
|
const { values, setValues } = useFormikContext();
|
||||||
const electron = getElectron();
|
const electron = getElectron();
|
||||||
const [isLoading, setIsLoading] = React.useState(false);
|
const [isLoading, setIsLoading] = React.useState(false);
|
||||||
|
|
||||||
@@ -151,7 +139,7 @@ function ElectronFilesInput() {
|
|||||||
...path.parse(full),
|
...path.parse(full),
|
||||||
})),
|
})),
|
||||||
values,
|
values,
|
||||||
setFieldValue
|
setValues
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -195,7 +183,7 @@ function SourceTargetConfig({
|
|||||||
{ value: 'database', label: 'Database', directions: ['source', 'target'] },
|
{ value: 'database', label: 'Database', directions: ['source', 'target'] },
|
||||||
...fileformats.map((format) => ({
|
...fileformats.map((format) => ({
|
||||||
value: format.storageType,
|
value: format.storageType,
|
||||||
label: format.name,
|
label: `${format.name} files(s)`,
|
||||||
directions: getFileFormatDirections(format),
|
directions: getFileFormatDirections(format),
|
||||||
})),
|
})),
|
||||||
{ value: 'query', label: 'SQL Query', directions: ['source'] },
|
{ value: 'query', label: 'SQL Query', directions: ['source'] },
|
||||||
@@ -335,7 +323,7 @@ function SourceName({ name }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function ImportExportConfigurator({ uploadedFile = undefined, onChangePreview = undefined }) {
|
export default function ImportExportConfigurator({ uploadedFile = undefined, onChangePreview = undefined }) {
|
||||||
const { values, setFieldValue } = useFormikContext();
|
const { values, setFieldValue, setValues } = useFormikContext();
|
||||||
const targetDbinfo = useDatabaseInfo({ conid: values.targetConnectionId, database: values.targetDatabaseName });
|
const targetDbinfo = useDatabaseInfo({ conid: values.targetConnectionId, database: values.targetDatabaseName });
|
||||||
const sourceConnectionInfo = useConnectionInfo({ conid: values.sourceConnectionId });
|
const sourceConnectionInfo = useConnectionInfo({ conid: values.sourceConnectionId });
|
||||||
const { engine: sourceEngine } = sourceConnectionInfo || {};
|
const { engine: sourceEngine } = sourceConnectionInfo || {};
|
||||||
@@ -354,7 +342,7 @@ export default function ImportExportConfigurator({ uploadedFile = undefined, onC
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
values,
|
values,
|
||||||
setFieldValue,
|
setValues,
|
||||||
!sourceList || sourceList.length == 0 ? file.storageType : null,
|
!sourceList || sourceList.length == 0 ? file.storageType : null,
|
||||||
setPreviewSource
|
setPreviewSource
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user