diff --git a/packages/api/src/shell/archiveReader.js b/packages/api/src/shell/archiveReader.js new file mode 100644 index 000000000..090597f7b --- /dev/null +++ b/packages/api/src/shell/archiveReader.js @@ -0,0 +1,11 @@ +const path = require('path'); +const { archivedir } = require('../utility/directories'); +const jsonLinesReader = require('./jsonLinesReader'); + +function archiveReader({ folderName, fileName }) { + const jsonlFile = path.join(archivedir(), folderName, `${fileName}.jsonl`); + const res = jsonLinesReader({ fileName: jsonlFile }); + return res; +} + +module.exports = archiveReader; diff --git a/packages/api/src/shell/index.js b/packages/api/src/shell/index.js index b60af005a..5b4bcb3e3 100644 --- a/packages/api/src/shell/index.js +++ b/packages/api/src/shell/index.js @@ -12,6 +12,7 @@ const jsonLinesWriter = require('./jsonLinesWriter'); const jsonLinesReader = require('./jsonLinesReader'); const jslDataReader = require('./jslDataReader'); const archiveWriter = require('./archiveWriter'); +const archiveReader = require('./archiveReader'); module.exports = { queryReader, @@ -28,4 +29,5 @@ module.exports = { consoleObjectWriter, jslDataReader, archiveWriter, + archiveReader, }; diff --git a/packages/web/src/datagrid/DataGridCore.js b/packages/web/src/datagrid/DataGridCore.js index b20397a98..e7e5791a9 100644 --- a/packages/web/src/datagrid/DataGridCore.js +++ b/packages/web/src/datagrid/DataGridCore.js @@ -618,25 +618,26 @@ export default function DataGridCore(props) { } function exportGrid() { - showModal((modalState) => ( - - )); + const initialValues = {}; + if (jslid) { + const archiveMatch = jslid.match(/^archive:\/\/([^/]+)\/(.*)$/); + if (archiveMatch) { + initialValues.sourceStorageType = 'archive'; + initialValues.sourceArchiveFolder = archiveMatch[1]; + initialValues.sourceList = [archiveMatch[2]]; + } else { + initialValues.sourceStorageType = 'jsldata'; + initialValues.sourceJslId = jslid; + initialValues.sourceList = ['query-data']; + } + } else { + initialValues.sourceStorageType = 'query'; + initialValues.sourceConnectionId = conid; + initialValues.sourceDatabaseName = database; + initialValues.sourceSql = display.getExportQuery(); + initialValues.sourceList = display.baseTable ? [display.baseTable.pureName] : []; + } + showModal((modalState) => ); } function setCellValue(chs, cell, value) { diff --git a/packages/web/src/impexp/ImportExportConfigurator.js b/packages/web/src/impexp/ImportExportConfigurator.js index 9d12acdb0..58341aa60 100644 --- a/packages/web/src/impexp/ImportExportConfigurator.js +++ b/packages/web/src/impexp/ImportExportConfigurator.js @@ -10,8 +10,9 @@ import { FormTablesSelect, FormSchemaSelect, FormArchiveFolderSelect, + FormArchiveFilesSelect, } from '../utility/forms'; -import { useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders'; +import { useArchiveFiles, useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders'; import TableControl, { TableColumn } from '../utility/TableControl'; import { TextField, SelectField } from '../utility/inputs'; import { getActionOptions, getTargetName, isFileStorage } from './createImpExpScript'; @@ -167,6 +168,7 @@ function SourceTargetConfig({ ]; const storageType = values[storageTypeField]; const dbinfo = useDatabaseInfo({ conid: values[connectionIdField], database: values[databaseNameField] }); + const archiveFiles = useArchiveFiles({ folder: values[archiveFolderField] }); return ( {direction == 'source' && } @@ -241,6 +243,26 @@ function SourceTargetConfig({ )} + {storageType == 'archive' && direction == 'source' && ( + <> + + +
+ + setFieldValue( + 'sourceList', + _.uniq([...(values.sourceList || []), ...(archiveFiles && archiveFiles.map((x) => x.name))]) + ) + } + /> + setFieldValue('sourceList', [])} /> +
+ + )} + {isFileStorage(storageType) && direction == 'source' && }
); diff --git a/packages/web/src/impexp/createImpExpScript.js b/packages/web/src/impexp/createImpExpScript.js index 16c38ac64..5cbacd522 100644 --- a/packages/web/src/impexp/createImpExpScript.js +++ b/packages/web/src/impexp/createImpExpScript.js @@ -68,6 +68,15 @@ function getSourceExpr(sourceName, values, sourceConnection, sourceDriver) { if (sourceStorageType == 'jsldata') { return ['jslDataReader', { jslid: values.sourceJslId }]; } + if (sourceStorageType == 'archive') { + return [ + 'archiveReader', + { + folderName: values.sourceArchiveFolder, + fileName: sourceName, + }, + ]; + } throw new Error(`Unknown source storage type: ${sourceStorageType}`); } diff --git a/packages/web/src/utility/forms.js b/packages/web/src/utility/forms.js index 7a3d07d2e..9079c3dbe 100644 --- a/packages/web/src/utility/forms.js +++ b/packages/web/src/utility/forms.js @@ -5,7 +5,13 @@ import Creatable from 'react-select/creatable'; import { TextField, SelectField } from './inputs'; import { Field, useFormikContext } from 'formik'; import FormStyledButton from '../widgets/FormStyledButton'; -import { useConnectionList, useDatabaseList, useDatabaseInfo, useArchiveFolders } from './metadataLoaders'; +import { + useConnectionList, + useDatabaseList, + useDatabaseInfo, + useArchiveFolders, + useArchiveFiles, +} from './metadataLoaders'; import useSocket from './SocketProvider'; import getAsArray from './getAsArray'; import axios from './axios'; @@ -174,6 +180,22 @@ export function FormTablesSelect({ conidName, databaseName, schemaName, name }) return ; } +export function FormArchiveFilesSelect({ folderName, name }) { + // const { values } = useFormikContext(); + const files = useArchiveFiles({ folder: folderName }); + const filesOptions = React.useMemo( + () => + (files || []).map((x) => ({ + value: x.name, + label: x.name, + })), + [files] + ); + + if (filesOptions.length == 0) return
Not available
; + return ; +} + export function FormArchiveFolderSelect({ name }) { const { setFieldValue } = useFormikContext(); const folders = useArchiveFolders();