export query

This commit is contained in:
Jan Prochazka
2020-10-08 15:34:06 +02:00
parent 360a4ef1bc
commit 3819bf9bd7
6 changed files with 69 additions and 15 deletions

View File

@@ -381,13 +381,13 @@ export abstract class GridDisplay {
}; };
} }
createSelect(): Select { createSelect(options = {}): Select {
return null; return null;
} }
processReferences(select: Select, displayedColumnInfo: DisplayedColumnInfo) {} processReferences(select: Select, displayedColumnInfo: DisplayedColumnInfo, options) {}
createSelectBase(name: NamedObjectInfo, columns: ColumnInfo[]) { createSelectBase(name: NamedObjectInfo, columns: ColumnInfo[], options) {
if (!columns) return null; if (!columns) return null;
const orderColumnName = columns[0].columnName; const orderColumnName = columns[0].columnName;
const select: Select = { const select: Select = {
@@ -411,7 +411,7 @@ export abstract class GridDisplay {
this.columns.map((col) => ({ ...col, sourceAlias: 'basetbl' })), this.columns.map((col) => ({ ...col, sourceAlias: 'basetbl' })),
'uniqueName' 'uniqueName'
); );
this.processReferences(select, displayedColumnInfo); this.processReferences(select, displayedColumnInfo, options);
this.applyFilterOnSelect(select, displayedColumnInfo); this.applyFilterOnSelect(select, displayedColumnInfo);
this.applyGroupOnSelect(select, displayedColumnInfo); this.applyGroupOnSelect(select, displayedColumnInfo);
this.applySortOnSelect(select, displayedColumnInfo); this.applySortOnSelect(select, displayedColumnInfo);
@@ -427,6 +427,13 @@ export abstract class GridDisplay {
return sql; return sql;
} }
getExportQuery() {
const select = this.createSelect({ isExport: true });
if (!select) return null;
const sql = treeToSql(this.driver, select, dumpSqlSelect);
return sql;
}
resizeColumn(uniqueName: string, computedSize: number, diff: number) { resizeColumn(uniqueName: string, computedSize: number, diff: number) {
this.setConfig((cfg) => { this.setConfig((cfg) => {
const columnWidths = { const columnWidths = {

View File

@@ -162,14 +162,16 @@ export class TableGridDisplay extends GridDisplay {
return this.findTable({ schemaName, pureName }); return this.findTable({ schemaName, pureName });
} }
processReferences(select: Select, displayedColumnInfo: DisplayedColumnInfo) { processReferences(select: Select, displayedColumnInfo: DisplayedColumnInfo, options) {
this.addJoinsFromExpandedColumns(select, this.columns, 'basetbl', displayedColumnInfo); this.addJoinsFromExpandedColumns(select, this.columns, 'basetbl', displayedColumnInfo);
this.addHintsToSelect(select); if (!options.isExport) {
this.addHintsToSelect(select);
}
} }
createSelect() { createSelect(options = {}) {
if (!this.table) return null; if (!this.table) return null;
const select = this.createSelectBase(this.table, this.table.columns); const select = this.createSelectBase(this.table, this.table.columns, options);
return select; return select;
} }

View File

@@ -43,8 +43,8 @@ export class ViewGridDisplay extends GridDisplay {
}; };
} }
createSelect() { createSelect(options = {}) {
const select = this.createSelectBase(this.view, this.view.columns); const select = this.createSelectBase(this.view, this.view.columns, options);
return select; return select;
} }
} }

View File

@@ -618,11 +618,17 @@ export default function DataGridCore(props) {
<ImportExportModal <ImportExportModal
modalState={modalState} modalState={modalState}
initialValues={{ initialValues={{
sourceStorageType: jslid ? 'jsldata' : 'database', // sourceStorageType: jslid ? 'jsldata' : 'database',
// sourceJslId: jslid,
// sourceConnectionId: jslid ? undefined : conid,
// sourceDatabaseName: jslid ? undefined : database,
// sourceSchemaName: jslid ? undefined : display.baseTable && display.baseTable.schemaName,
// sourceList: jslid ? ['query-data'] : display.baseTable ? [display.baseTable.pureName] : [],
sourceStorageType: jslid ? 'jsldata' : 'query',
sourceJslId: jslid, sourceJslId: jslid,
sourceConnectionId: jslid ? undefined : conid, sourceConnectionId: jslid ? undefined : conid,
sourceDatabaseName: jslid ? undefined : database, sourceDatabaseName: jslid ? undefined : database,
sourceSchemaName: jslid ? undefined : display.baseTable && display.baseTable.schemaName, sourceSql: display.getExportQuery(),
sourceList: jslid ? ['query-data'] : display.baseTable ? [display.baseTable.pureName] : [], sourceList: jslid ? ['query-data'] : display.baseTable ? [display.baseTable.pureName] : [],
}} }}
/> />

View File

@@ -10,7 +10,7 @@ import {
FormTablesSelect, FormTablesSelect,
FormSchemaSelect, FormSchemaSelect,
} from '../utility/forms'; } from '../utility/forms';
import { useDatabaseInfo } from '../utility/metadataLoaders'; import { useConnectionInfo, 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, isFileStorage } from './createImpExpScript'; import { getActionOptions, getTargetName, isFileStorage } from './createImpExpScript';
@@ -19,6 +19,7 @@ import ErrorInfo from '../widgets/ErrorInfo';
import getAsArray from '../utility/getAsArray'; import getAsArray from '../utility/getAsArray';
import axios from '../utility/axios'; import axios from '../utility/axios';
import LoadingInfo from '../widgets/LoadingInfo'; import LoadingInfo from '../widgets/LoadingInfo';
import SqlEditor from '../sqleditor/SqlEditor';
const Container = styled.div` const Container = styled.div`
max-height: 50vh; max-height: 50vh;
@@ -53,6 +54,12 @@ const TrashWrapper = styled.div`
color: blue; color: blue;
`; `;
const SqlWrapper = styled.div`
position: relative;
height: 100px;
width: 20vw;
`;
function getFileFilters(storageType) { function getFileFilters(storageType) {
const res = []; const res = [];
if (storageType == 'csv') res.push({ name: 'CSV files', extensions: ['csv'] }); if (storageType == 'csv') res.push({ name: 'CSV files', extensions: ['csv'] });
@@ -142,6 +149,7 @@ function SourceTargetConfig({
databaseNameField, databaseNameField,
schemaNameField, schemaNameField,
tablesField = undefined, tablesField = undefined,
engine = undefined,
}) { }) {
const { values, setFieldValue } = useFormikContext(); const { values, setFieldValue } = useFormikContext();
const types = const types =
@@ -152,6 +160,7 @@ function SourceTargetConfig({
{ value: 'csv', label: 'CSV file(s)', directions: ['source', 'target'] }, { value: 'csv', label: 'CSV file(s)', directions: ['source', 'target'] },
{ value: 'jsonl', label: 'JSON lines file(s)', directions: ['source', 'target'] }, { value: 'jsonl', label: 'JSON lines file(s)', directions: ['source', 'target'] },
{ value: 'excel', label: 'MS Excel file(s)', directions: ['source'] }, { value: 'excel', label: 'MS Excel file(s)', directions: ['source'] },
{ value: 'query', label: 'SQL Query', directions: ['source'] },
]; ];
const storageType = values[storageTypeField]; const storageType = values[storageTypeField];
const dbinfo = useDatabaseInfo({ conid: values[connectionIdField], database: values[databaseNameField] }); const dbinfo = useDatabaseInfo({ conid: values[connectionIdField], database: values[databaseNameField] });
@@ -160,12 +169,16 @@ function SourceTargetConfig({
{direction == 'source' && <Label>Source configuration</Label>} {direction == 'source' && <Label>Source configuration</Label>}
{direction == 'target' && <Label>Target configuration</Label>} {direction == 'target' && <Label>Target configuration</Label>}
<FormReactSelect options={types.filter((x) => x.directions.includes(direction))} name={storageTypeField} /> <FormReactSelect options={types.filter((x) => x.directions.includes(direction))} name={storageTypeField} />
{storageType == 'database' && ( {(storageType == 'database' || storageType == 'query') && (
<> <>
<Label>Server</Label> <Label>Server</Label>
<FormConnectionSelect name={connectionIdField} /> <FormConnectionSelect name={connectionIdField} />
<Label>Database</Label> <Label>Database</Label>
<FormDatabaseSelect conidName={connectionIdField} name={databaseNameField} /> <FormDatabaseSelect conidName={connectionIdField} name={databaseNameField} />
</>
)}
{storageType == 'database' && (
<>
<Label>Schema</Label> <Label>Schema</Label>
<FormSchemaSelect conidName={connectionIdField} databaseName={databaseNameField} name={schemaNameField} /> <FormSchemaSelect conidName={connectionIdField} databaseName={databaseNameField} name={schemaNameField} />
{tablesField && ( {tablesField && (
@@ -204,6 +217,20 @@ function SourceTargetConfig({
)} )}
</> </>
)} )}
{storageType == 'query' && (
<>
<Label>Query</Label>
<SqlWrapper>
<SqlEditor
value={values.sourceSql}
onChange={(value) => setFieldValue('sourceSql', value)}
engine={engine}
focusOnCreate
/>
</SqlWrapper>
</>
)}
{isFileStorage(storageType) && direction == 'source' && <FilesInput />} {isFileStorage(storageType) && direction == 'source' && <FilesInput />}
</Column> </Column>
); );
@@ -231,6 +258,8 @@ function SourceName({ name }) {
export default function ImportExportConfigurator() { export default function ImportExportConfigurator() {
const { values, setFieldValue } = useFormikContext(); const { values, setFieldValue } = 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 { engine: sourceEngine } = sourceConnectionInfo || {};
const { sourceList } = values; const { sourceList } = values;
return ( return (
@@ -243,6 +272,7 @@ export default function ImportExportConfigurator() {
databaseNameField="sourceDatabaseName" databaseNameField="sourceDatabaseName"
schemaNameField="sourceSchemaName" schemaNameField="sourceSchemaName"
tablesField="sourceList" tablesField="sourceList"
engine={sourceEngine}
/> />
<SourceTargetConfig <SourceTargetConfig
direction="target" direction="target"

View File

@@ -18,7 +18,7 @@ export function isFileStorage(storageType) {
} }
async function getConnection(storageType, conid, database) { async function getConnection(storageType, conid, database) {
if (storageType == 'database') { if (storageType == 'database' || storageType == 'query') {
const conn = await getConnectionInfo({ conid }); const conn = await getConnectionInfo({ conid });
const driver = engines(conn); const driver = engines(conn);
return [ return [
@@ -44,6 +44,15 @@ function getSourceExpr(sourceName, values, sourceConnection, sourceDriver) {
}, },
]; ];
} }
if (sourceStorageType == 'query') {
return [
'queryReader',
{
connection: sourceConnection,
sql: values.sourceSql,
},
];
}
if (isFileStorage(sourceStorageType)) { if (isFileStorage(sourceStorageType)) {
const sourceFile = values[`sourceFile_${sourceName}`]; const sourceFile = values[`sourceFile_${sourceName}`];
if (sourceStorageType == 'excel') { if (sourceStorageType == 'excel') {