diff --git a/packages/datalib/src/nameTools.ts b/packages/datalib/src/nameTools.ts index e000d3c8c..ed962cb3e 100644 --- a/packages/datalib/src/nameTools.ts +++ b/packages/datalib/src/nameTools.ts @@ -1,3 +1,5 @@ +import { DatabaseInfo, DatabaseInfoObjects } from '@dbgate/types'; + export function fullNameFromString(name) { const m = name.match(/\[([^\]]+)\]\.\[([^\]]+)\]/); if (m) { @@ -23,3 +25,23 @@ export function quoteFullName(dialect, { schemaName, pureName }) { if (schemaName) return `${dialect.quoteIdentifier(schemaName)}.${dialect.quoteIdentifier(pureName)}`; return `${dialect.quoteIdentifier(pureName)}`; } + +export function equalStringLike(s1, s2) { + return (s1 || '').toLowerCase().trim() == (s2 || '').toLowerCase().trim(); +} + +export function findObjectLike( + { pureName, schemaName }, + dbinfo: DatabaseInfo, + objectTypeField: keyof DatabaseInfoObjects +) { + if (!dbinfo) return null; + if (schemaName) { + // @ts-ignore + return dbinfo[objectTypeField].find( + (x) => equalStringLike(x.pureName, pureName) && equalStringLike(x.schemaName, schemaName) + ); + } + // @ts-ignore + return dbinfo[objectTypeField].find((x) => equalStringLike(x.pureName, pureName)); +} diff --git a/packages/types/dbinfo.d.ts b/packages/types/dbinfo.d.ts index 46f50158e..c13e4a8ec 100644 --- a/packages/types/dbinfo.d.ts +++ b/packages/types/dbinfo.d.ts @@ -76,11 +76,14 @@ export interface SchemaInfo { schemaName: string; } -export interface DatabaseInfo { +export interface DatabaseInfoObjects { tables: TableInfo[]; views: ViewInfo[]; procedures: ProcedureInfo[]; functions: FunctionInfo[]; triggers: TriggerInfo[]; +} + +export interface DatabaseInfo extends DatabaseInfoObjects { schemas: SchemaInfo[]; } diff --git a/packages/web/src/impexp/ImportExportConfigurator.js b/packages/web/src/impexp/ImportExportConfigurator.js index b21a8ba2c..167ec459a 100644 --- a/packages/web/src/impexp/ImportExportConfigurator.js +++ b/packages/web/src/impexp/ImportExportConfigurator.js @@ -14,9 +14,10 @@ import { FormSelectField, FormSchemaSelect, } from '../utility/forms'; -import { useConnectionList, useDatabaseList } from '../utility/metadataLoaders'; +import { useConnectionList, useDatabaseList, useDatabaseInfo } from '../utility/metadataLoaders'; import TableControl, { TableColumn } from '../utility/TableControl'; import { TextField, SelectField } from '../utility/inputs'; +import { getActionOptions, getTargetName } from './createImpExpScript'; const Container = styled.div``; @@ -69,7 +70,14 @@ function DatabaseSelector() { ); } -function SourceTargetConfig({ direction, storageTypeField, connectionIdField, databaseNameField, schemaNameField,tablesField }) { +function SourceTargetConfig({ + direction, + storageTypeField, + connectionIdField, + databaseNameField, + schemaNameField, + tablesField, +}) { const types = [ { value: 'database', label: 'Database', directions: ['source', 'target'] }, { value: 'csv', label: 'CSV file(s)', directions: ['target'] }, @@ -92,7 +100,12 @@ function SourceTargetConfig({ direction, storageTypeField, connectionIdField, da {direction == 'source' && ( <> - + )} @@ -102,29 +115,10 @@ function SourceTargetConfig({ direction, storageTypeField, connectionIdField, da } export default function ImportExportConfigurator() { - const { values } = useFormikContext(); + const { values, setFieldValue } = useFormikContext(); + const targetDbinfo = useDatabaseInfo({ conid: values.targetConnectionId, database: values.targetDatabaseName }); const sources = values.sourceTables; - const getActionOptions = ()=>{ - } - const actionOptions = [ - { - label: 'Create file', - value: 'createFile', - }, - { - label: 'Create table', - value: 'createTable', - }, - { - label: 'Drop and create table', - value: 'dropCreateFile', - }, - { - label: 'Append data', - value: 'appendData', - }, - ]; return ( @@ -147,8 +141,27 @@ export default function ImportExportConfigurator() { row} /> - } /> - } /> + ( + setFieldValue(`actionType_${row}`, e.target.value)} + /> + )} + /> + ( + setFieldValue(`targetName_${row}`, e.target.value)} + /> + )} + /> ); diff --git a/packages/web/src/impexp/createImpExpScript.js b/packages/web/src/impexp/createImpExpScript.js index e22aaf3da..dbe0108b4 100644 --- a/packages/web/src/impexp/createImpExpScript.js +++ b/packages/web/src/impexp/createImpExpScript.js @@ -3,6 +3,7 @@ import ScriptWriter from './ScriptWriter'; import getAsArray from '../utility/getAsArray'; import { getConnectionInfo } from '../utility/metadataLoaders'; import engines from '@dbgate/engines'; +import { findObjectLike } from '@dbgate/datalib'; import { quoteFullName, fullNameFromString } from '@dbgate/datalib'; export default async function createImpExpScript(values) { @@ -41,3 +42,48 @@ export default async function createImpExpScript(values) { } return script.s; } + +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`; + return source; +} + +export function getActionOptions(source, values,targetDbinfo) { + const res = []; + const targetName = getTargetName(source, values); + if (values.targetStorageType == 'database') { + let existing = findObjectLike( + { schemaName: values.targetSchemaName, pureName: targetName }, + targetDbinfo, + 'tables' + ); + if (existing) { + res.push({ + label: 'Append data', + value: 'appendData', + }); + res.push({ + label: 'Truncate and import', + value: 'truncate', + }); + res.push({ + label: 'Drop and create table', + value: 'dropCreateTable', + }); + } else { + res.push({ + label: 'Create table', + value: 'createTable', + }); + } + } else { + res.push({ + label: 'Create file', + value: 'createFile', + }); + } + return res; +}