diff --git a/packages/tools/src/driverBase.ts b/packages/tools/src/driverBase.ts index 3a304525e..9f9ca0691 100644 --- a/packages/tools/src/driverBase.ts +++ b/packages/tools/src/driverBase.ts @@ -161,6 +161,12 @@ export const driverBase = { getCollectionExportQueryJson(collection: string, condition: any, sort: any) { return null; }, + getScriptTemplates(objectTypeField) { + return []; + }, + getScriptTemplateContent(scriptTemplate, props) { + return null; + }, dataEditorTypesBehaviour: { parseSqlNull: true, diff --git a/packages/types/engines.d.ts b/packages/types/engines.d.ts index dea2c0409..51cfac77d 100644 --- a/packages/types/engines.d.ts +++ b/packages/types/engines.d.ts @@ -2,7 +2,16 @@ import stream from 'stream'; import { QueryResult } from './query'; import { SqlDialect } from './dialect'; import { SqlDumper } from './dumper'; -import { DatabaseInfo, NamedObjectInfo, TableInfo, ViewInfo, ProcedureInfo, FunctionInfo, TriggerInfo, CollectionInfo } from './dbinfo'; +import { + DatabaseInfo, + NamedObjectInfo, + TableInfo, + ViewInfo, + ProcedureInfo, + FunctionInfo, + TriggerInfo, + CollectionInfo, +} from './dbinfo'; import { FilterBehaviour } from './filter-type'; export interface StreamOptions { @@ -211,6 +220,8 @@ export interface EngineDriver extends FilterBehaviourProvider { getAccessTokenFromAuth(connection, req): Promise; getCollectionExportQueryScript(collection: string, condition: any, sort?: CollectionSortDefinition): string; getCollectionExportQueryJson(collection: string, condition: any, sort?: CollectionSortDefinition): {}; + getScriptTemplates(objectTypeField: keyof DatabaseInfo): { label: string; scriptTemplate: string }[]; + getScriptTemplateContent(scriptTemplate: string, props: any): Promise; analyserClass?: any; dumperClass?: any; diff --git a/packages/web/src/appobj/DatabaseObjectAppObject.svelte b/packages/web/src/appobj/DatabaseObjectAppObject.svelte index 4851e677e..e12c54069 100644 --- a/packages/web/src/appobj/DatabaseObjectAppObject.svelte +++ b/packages/web/src/appobj/DatabaseObjectAppObject.svelte @@ -31,7 +31,10 @@ queries: 'QueryDataTab', }; - function createMenusCore(objectTypeField): { + function createMenusCore( + objectTypeField, + driver + ): { label?: string; tab?: string; forceNewTab?: boolean; @@ -400,31 +403,24 @@ functionName: 'tableReader', }, hasPermission('dbops/model/edit') && { - label: 'Drop collection', + label: `Drop ${driver?.collectionSingularLabel ?? 'collection/container'}`, isDropCollection: true, requiresWriteAccess: true, }, hasPermission('dbops/table/rename') && { - label: 'Rename collection', + label: `Rename ${driver?.collectionSingularLabel ?? 'collection/container'}`, isRenameCollection: true, requiresWriteAccess: true, }, hasPermission('dbops/table/backup') && { - label: 'Create collection backup', + label: `Create ${driver?.collectionSingularLabel ?? 'collection/container'} backup`, isDuplicateCollection: true, requiresWriteAccess: true, }, { divider: true, }, - { - label: 'JS: dropCollection()', - scriptTemplate: 'dropCollection', - }, - { - label: 'JS: find()', - scriptTemplate: 'findCollection', - }, + ...(driver?.getScriptTemplates?.('collections') || []), ]; } } @@ -557,9 +553,10 @@ } else if (menu.isCopyTableName) { copyTextToClipboard(data.pureName); } else if (menu.isRenameCollection) { + const driver = await getDriver(); showModal(InputTextModal, { - label: `New collection/container name`, - header: `Rename collection/container`, + label: `New ${driver?.collectionSingularLabel ?? 'collection/container'} name`, + header: `Rename ${driver?.collectionSingularLabel ?? 'collection/container'}`, value: data.pureName, onConfirm: async newName => { const dbid = _.pick(data, ['conid', 'database']); @@ -572,9 +569,10 @@ }); } else if (menu.isDuplicateCollection) { const newName = `_${data.pureName}_${dateFormat(new Date(), 'yyyy-MM-dd-hh-mm-ss')}`; + const driver = await getDriver(); showModal(ConfirmModal, { - message: `Really create collection copy named ${newName}?`, + message: `Really create ${driver?.collectionSingularLabel ?? 'collection/container'} copy named ${newName}?`, onConfirm: async () => { const dbid = _.pick(data, ['conid', 'database']); runOperationOnDatabase(dbid, { @@ -642,8 +640,8 @@ } } - function createMenus(objectTypeField): ReturnType { - return createMenusCore(objectTypeField).filter(x => { + function createMenus(objectTypeField, driver): ReturnType { + return createMenusCore(objectTypeField, driver).filter(x => { if (x.scriptTemplate) { return hasPermission(`dbops/sql-template/${x.scriptTemplate}`); } @@ -703,9 +701,10 @@ export function handleDatabaseObjectClick(data, forceNewTab = false) { const { schemaName, pureName, conid, database, objectTypeField } = data; + const driver = findEngineDriver(data, getExtensions()); const configuredAction = getCurrentSettings()[`defaultAction.dbObjectClick.${objectTypeField}`]; - const overrideMenu = createMenus(objectTypeField).find(x => x.label && x.label == configuredAction); + const overrideMenu = createMenus(objectTypeField, driver).find(x => x.label && x.label == configuredAction); if (overrideMenu) { databaseObjectMenuClickHandler(data, overrideMenu); return; @@ -739,8 +738,10 @@ } export function createDatabaseObjectMenu(data, connection = null) { + const driver = findEngineDriver(data, getExtensions()); + const { objectTypeField } = data; - return createMenus(objectTypeField) + return createMenus(objectTypeField, driver) .filter(x => x) .map(menu => { if (menu.divider) return menu; diff --git a/packages/web/src/utility/applyScriptTemplate.ts b/packages/web/src/utility/applyScriptTemplate.ts index 7f0d3ab30..5541313c0 100644 --- a/packages/web/src/utility/applyScriptTemplate.ts +++ b/packages/web/src/utility/applyScriptTemplate.ts @@ -56,12 +56,10 @@ export default async function applyScriptTemplate(scriptTemplate, extensions, pr if (procedureInfo) dmp.put('^execute %f', procedureInfo); return dmp.s; } - if (scriptTemplate == 'dropCollection') { - return `db.collection('${props.pureName}').drop()`; - } - if (scriptTemplate == 'findCollection') { - return `db.collection('${props.pureName}').find()`; - } - return null; + const connection = await getConnectionInfo(props); + const driver = findEngineDriver(connection, extensions) || driverBase; + const res = await driver.getScriptTemplateContent(scriptTemplate, props); + + return res; } diff --git a/plugins/dbgate-plugin-mongo/src/frontend/driver.js b/plugins/dbgate-plugin-mongo/src/frontend/driver.js index 4f3f1bfea..58e34cc22 100644 --- a/plugins/dbgate-plugin-mongo/src/frontend/driver.js +++ b/plugins/dbgate-plugin-mongo/src/frontend/driver.js @@ -150,6 +150,33 @@ const driver = { supportFieldRemoval: true, }, + + getScriptTemplates(objectTypeField) { + switch (objectTypeField) { + case 'collections': + return [ + { + label: 'JS: dropCollection()', + scriptTemplate: 'dropCollection', + }, + { + label: 'JS: find()', + scriptTemplate: 'findCollection', + }, + ]; + } + + return []; + }, + + async getScriptTemplateContent(scriptTemplate, props) { + switch (scriptTemplate) { + case 'dropCollection': + return `db.${props.pureName}.drop();`; + case 'findCollection': + return `db.${props.pureName}.find();`; + } + }, }; module.exports = driver;