imp exp configurator

This commit is contained in:
Jan Prochazka
2020-06-18 11:42:02 +02:00
parent a9ce93cd67
commit 3f40996d2d
4 changed files with 111 additions and 27 deletions

View File

@@ -1,3 +1,5 @@
import { DatabaseInfo, DatabaseInfoObjects } from '@dbgate/types';
export function fullNameFromString(name) { export function fullNameFromString(name) {
const m = name.match(/\[([^\]]+)\]\.\[([^\]]+)\]/); const m = name.match(/\[([^\]]+)\]\.\[([^\]]+)\]/);
if (m) { if (m) {
@@ -23,3 +25,23 @@ export function quoteFullName(dialect, { schemaName, pureName }) {
if (schemaName) return `${dialect.quoteIdentifier(schemaName)}.${dialect.quoteIdentifier(pureName)}`; if (schemaName) return `${dialect.quoteIdentifier(schemaName)}.${dialect.quoteIdentifier(pureName)}`;
return `${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));
}

View File

@@ -76,11 +76,14 @@ export interface SchemaInfo {
schemaName: string; schemaName: string;
} }
export interface DatabaseInfo { export interface DatabaseInfoObjects {
tables: TableInfo[]; tables: TableInfo[];
views: ViewInfo[]; views: ViewInfo[];
procedures: ProcedureInfo[]; procedures: ProcedureInfo[];
functions: FunctionInfo[]; functions: FunctionInfo[];
triggers: TriggerInfo[]; triggers: TriggerInfo[];
}
export interface DatabaseInfo extends DatabaseInfoObjects {
schemas: SchemaInfo[]; schemas: SchemaInfo[];
} }

View File

@@ -14,9 +14,10 @@ import {
FormSelectField, FormSelectField,
FormSchemaSelect, FormSchemaSelect,
} from '../utility/forms'; } from '../utility/forms';
import { useConnectionList, useDatabaseList } from '../utility/metadataLoaders'; import { useConnectionList, useDatabaseList, useDatabaseInfo } from '../utility/metadataLoaders';
import TableControl, { TableColumn } from '../utility/TableControl'; import TableControl, { TableColumn } from '../utility/TableControl';
import { TextField, SelectField } from '../utility/inputs'; import { TextField, SelectField } from '../utility/inputs';
import { getActionOptions, getTargetName } from './createImpExpScript';
const Container = styled.div``; 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 = [ const types = [
{ value: 'database', label: 'Database', directions: ['source', 'target'] }, { value: 'database', label: 'Database', directions: ['source', 'target'] },
{ value: 'csv', label: 'CSV file(s)', directions: ['target'] }, { value: 'csv', label: 'CSV file(s)', directions: ['target'] },
@@ -92,7 +100,12 @@ function SourceTargetConfig({ direction, storageTypeField, connectionIdField, da
{direction == 'source' && ( {direction == 'source' && (
<> <>
<Label>Tables/views</Label> <Label>Tables/views</Label>
<FormTablesSelect conidName={connectionIdField} schemaName={schemaNameField} databaseName={databaseNameField} name={tablesField} /> <FormTablesSelect
conidName={connectionIdField}
schemaName={schemaNameField}
databaseName={databaseNameField}
name={tablesField}
/>
</> </>
)} )}
</> </>
@@ -102,29 +115,10 @@ function SourceTargetConfig({ direction, storageTypeField, connectionIdField, da
} }
export default function ImportExportConfigurator() { 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 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 ( return (
<Container> <Container>
<Wrapper> <Wrapper>
@@ -147,8 +141,27 @@ export default function ImportExportConfigurator() {
</Wrapper> </Wrapper>
<TableControl rows={sources || []}> <TableControl rows={sources || []}>
<TableColumn fieldName="source" header="Source" formatter={(row) => row} /> <TableColumn fieldName="source" header="Source" formatter={(row) => row} />
<TableColumn fieldName="action" header="Action" formatter={(row) => <SelectField options={actionOptions} />} /> <TableColumn
<TableColumn fieldName="target" header="Target" formatter={(row) => <TextField />} /> fieldName="action"
header="Action"
formatter={(row) => (
<SelectField
options={getActionOptions(row, values, targetDbinfo)}
value={values[`actionType_${row}`] || getActionOptions(row, values, targetDbinfo)[0].value}
onChange={(e) => setFieldValue(`actionType_${row}`, e.target.value)}
/>
)}
/>
<TableColumn
fieldName="target"
header="Target"
formatter={(row) => (
<TextField
value={getTargetName(row, values)}
onChange={(e) => setFieldValue(`targetName_${row}`, e.target.value)}
/>
)}
/>
</TableControl> </TableControl>
</Container> </Container>
); );

View File

@@ -3,6 +3,7 @@ import ScriptWriter from './ScriptWriter';
import getAsArray from '../utility/getAsArray'; import getAsArray from '../utility/getAsArray';
import { getConnectionInfo } from '../utility/metadataLoaders'; import { getConnectionInfo } from '../utility/metadataLoaders';
import engines from '@dbgate/engines'; import engines from '@dbgate/engines';
import { findObjectLike } from '@dbgate/datalib';
import { quoteFullName, fullNameFromString } from '@dbgate/datalib'; import { quoteFullName, fullNameFromString } from '@dbgate/datalib';
export default async function createImpExpScript(values) { export default async function createImpExpScript(values) {
@@ -41,3 +42,48 @@ export default async function createImpExpScript(values) {
} }
return script.s; 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;
}