diff --git a/packages/api/src/shell/queryReader.js b/packages/api/src/shell/queryReader.js index a92092eb..8132d60e 100644 --- a/packages/api/src/shell/queryReader.js +++ b/packages/api/src/shell/queryReader.js @@ -1,14 +1,26 @@ const requireEngineDriver = require('../utility/requireEngineDriver'); -const { decryptConnection } = require('../utility/crypting'); const connectUtility = require('../utility/connectUtility'); -async function queryReader({ connection, sql }) { - console.log(`Reading query ${sql}`); +async function queryReader({ + connection, + query, + queryType, + // obsolete; use query instead + sql, +}) { + // if (sql && json) { + // throw new Error('Only one of sql or json could be set'); + // } + // if (!sql && !json) { + // throw new Error('One of sql or json must be set'); + // } + console.log(`Reading query ${query || sql}`); + // else console.log(`Reading query ${JSON.stringify(json)}`); const driver = requireEngineDriver(connection); - const pool = await connectUtility(driver, connection, 'script'); + const pool = await connectUtility(driver, connection, queryType == 'json' ? 'read' : 'script'); console.log(`Connected.`); - return await driver.readQuery(pool, sql); + return queryType == 'json' ? await driver.readJsonQuery(pool, query) : await driver.readQuery(pool, query || sql); } module.exports = queryReader; diff --git a/packages/datalib/src/GridDisplay.ts b/packages/datalib/src/GridDisplay.ts index 439ac65e..ecec9051 100644 --- a/packages/datalib/src/GridDisplay.ts +++ b/packages/datalib/src/GridDisplay.ts @@ -574,6 +574,13 @@ export abstract class GridDisplay { return sql; } + getExportQueryJson(postprocessSelect = null) { + const select = this.createSelect({ isExport: true }); + if (!select) return null; + if (postprocessSelect) postprocessSelect(select); + return select; + } + getExportColumnMap() { const changesDefined = this.config.hiddenColumns?.length > 0 || this.config.addedColumns?.length > 0; if (this.isDynamicStructure && !changesDefined) { diff --git a/packages/tools/src/driverBase.ts b/packages/tools/src/driverBase.ts index 2b67ccdd..05058955 100644 --- a/packages/tools/src/driverBase.ts +++ b/packages/tools/src/driverBase.ts @@ -1,4 +1,4 @@ -import _compact from 'lodash/compact' +import _compact from 'lodash/compact'; import { SqlDumper } from './SqlDumper'; import { splitQuery } from 'dbgate-query-splitter'; import { dumpSqlSelect } from 'dbgate-sqltree'; @@ -105,4 +105,9 @@ export const driverBase = { const resp = await this.query(pool, dmp.s); return resp.rows; }, + readJsonQuery(pool, select, structure) { + const dmp = this.createDumper(); + dumpSqlSelect(dmp, select); + return this.readQuery(pool, dmp.s, structure); + }, }; diff --git a/packages/types/engines.d.ts b/packages/types/engines.d.ts index 22de715f..e4282af0 100644 --- a/packages/types/engines.d.ts +++ b/packages/types/engines.d.ts @@ -47,7 +47,7 @@ export interface EngineDriver { title: string; defaultPort?: number; databaseEngineTypes: string[]; - readOnlySessions: boolean, + readOnlySessions: boolean; supportedKeyTypes: { name: string; label: string }[]; supportsDatabaseUrl?: boolean; isElectronOnly?: boolean; @@ -62,6 +62,7 @@ export interface EngineDriver { query(pool: any, sql: string, options?: QueryOptions): Promise; stream(pool: any, sql: string, options: StreamOptions); readQuery(pool: any, sql: string, structure?: TableInfo): Promise; + readJsonQuery(pool: any, query: any, structure?: TableInfo): Promise; writeTable(pool: any, name: NamedObjectInfo, options: WriteTableOptions): Promise; analyseSingleObject( pool: any, diff --git a/packages/web/src/datagrid/CollectionDataGridCore.svelte b/packages/web/src/datagrid/CollectionDataGridCore.svelte index 8709bc5d..18575af6 100644 --- a/packages/web/src/datagrid/CollectionDataGridCore.svelte +++ b/packages/web/src/datagrid/CollectionDataGridCore.svelte @@ -168,12 +168,24 @@ .sort(${JSON.stringify(buildMongoSort($$props) || {})})`; } - export function exportGrid() { + function getExportQueryJson() { + return { + collection: pureName, + condition: buildGridMongoCondition($$props) || {}, + sort: buildMongoSort($$props) || {}, + }; + } + + export async function exportGrid() { + const coninfo = await getConnectionInfo({ conid }); const initialValues: any = {}; initialValues.sourceStorageType = 'query'; initialValues.sourceConnectionId = conid; initialValues.sourceDatabaseName = database; - initialValues.sourceSql = getExportQuery(); + initialValues.sourceQuery = coninfo.isReadOnly + ? JSON.stringify(getExportQueryJson(), undefined, 2) + : getExportQuery(); + initialValues.sourceQueryType = coninfo.isReadOnly ? 'json' : 'native'; initialValues.sourceList = [pureName]; initialValues[`columns_${pureName}`] = display.getExportColumnMap(); showModal(ImportExportModal, { initialValues }); @@ -204,7 +216,8 @@ functionName: 'queryReader', props: { connection: extractShellConnection(coninfo, database), - sql: getExportQuery(), + queryType: coninfo.isReadOnly ? 'json' : 'native', + query: coninfo.isReadOnly ? getExportQueryJson() : getExportQuery(), }, }, fmt, diff --git a/packages/web/src/datagrid/SqlDataGridCore.svelte b/packages/web/src/datagrid/SqlDataGridCore.svelte index b7ec864b..c8eab659 100644 --- a/packages/web/src/datagrid/SqlDataGridCore.svelte +++ b/packages/web/src/datagrid/SqlDataGridCore.svelte @@ -129,12 +129,17 @@ // $: console.log('GRIDER', grider); // $: if (onChangeGrider) onChangeGrider(grider); - export function exportGrid() { + export async function exportGrid() { + const coninfo = await getConnectionInfo({ conid }); + const initialValues: any = {}; initialValues.sourceStorageType = 'query'; initialValues.sourceConnectionId = conid; initialValues.sourceDatabaseName = database; - initialValues.sourceSql = display.getExportQuery(); + initialValues.sourceQuery = coninfo.isReadOnly + ? JSON.stringify(display.getExportQueryJson(), undefined, 2) + : display.getExportQuery(); + initialValues.sourceQueryType = coninfo.isReadOnly ? 'json' : 'native'; initialValues.sourceList = display.baseTableOrSimilar ? [display.baseTableOrSimilar.pureName] : []; initialValues[`columns_${pureName}`] = display.getExportColumnMap(); showModal(ImportExportModal, { initialValues }); @@ -189,7 +194,8 @@ functionName: 'queryReader', props: { connection: extractShellConnection(coninfo, database), - sql: display.getExportQuery(), + queryType: coninfo.isReadOnly ? 'json' : 'native', + query: coninfo.isReadOnly ? display.getExportQueryJson() : display.getExportQuery(), }, }, fmt, diff --git a/packages/web/src/impexp/SourceTargetConfig.svelte b/packages/web/src/impexp/SourceTargetConfig.svelte index 43755fe2..900faa1e 100644 --- a/packages/web/src/impexp/SourceTargetConfig.svelte +++ b/packages/web/src/impexp/SourceTargetConfig.svelte @@ -21,6 +21,7 @@ import FormSchemaSelect from './FormSchemaSelect.svelte'; import FormTablesSelect from './FormTablesSelect.svelte'; import { findEngineDriver } from 'dbgate-tools'; +import AceEditor from '../query/AceEditor.svelte'; export let direction; export let storageTypeField; @@ -137,12 +138,19 @@ {#if storageType == 'query'}
Query
- setFieldValue('sourceSql', e.detail)} - {engine} - focusOnCreate - /> + {#if $values.sourceQueryType == 'json'} + setFieldValue('sourceQuery', e.detail)} + mode="json" + /> + {:else} + setFieldValue('sourceQuery', e.detail)} + {engine} + /> + {/if}
{/if} diff --git a/packages/web/src/impexp/createImpExpScript.ts b/packages/web/src/impexp/createImpExpScript.ts index 51fd04f4..8677b235 100644 --- a/packages/web/src/impexp/createImpExpScript.ts +++ b/packages/web/src/impexp/createImpExpScript.ts @@ -78,7 +78,8 @@ function getSourceExpr(extensions, sourceName, values, sourceConnection, sourceD { connection: sourceConnection, ...extractDriverApiParameters(values, 'source', sourceDriver), - sql: values.sourceSql, + queryType: values.sourceQueryType, + query: values.sourceQueryType == 'json' ? JSON.parse(values.sourceQuery) : values.sourceQuery, }, ]; } diff --git a/plugins/dbgate-plugin-mongo/src/backend/driver.js b/plugins/dbgate-plugin-mongo/src/backend/driver.js index 2f9c4d29..2977ff3a 100644 --- a/plugins/dbgate-plugin-mongo/src/backend/driver.js +++ b/plugins/dbgate-plugin-mongo/src/backend/driver.js @@ -325,6 +325,18 @@ const driver = { return { errorMessage: err.message }; } }, + + readJsonQuery(pool, select, structure) { + const { collection, condition, sort } = select; + + const db = pool.__getDatabase(); + const res = db + .collection(collection) + .find(condition || {}) + .sort(sort || {}); + + return res; + }, }; module.exports = driver;