From 219da0aba46839295807a01056199d42584e0af9 Mon Sep 17 00:00:00 2001 From: Fabio Di Stasio Date: Thu, 25 Feb 2021 17:43:23 +0100 Subject: [PATCH] feat(UI): run procedures/functions from sidebar context menu --- src/main/libs/clients/MySQLClient.js | 18 +-- .../WorkspaceExploreBarMiscContext.vue | 129 ++++++++++++++++-- 2 files changed, 130 insertions(+), 17 deletions(-) diff --git a/src/main/libs/clients/MySQLClient.js b/src/main/libs/clients/MySQLClient.js index 2a0a3b6d..2ef8ce6f 100644 --- a/src/main/libs/clients/MySQLClient.js +++ b/src/main/libs/clients/MySQLClient.js @@ -562,7 +562,7 @@ export class MySQLClient extends AntaresCore { return { name: param[1] ? param[1].replaceAll('`', '') : '', type: type[0].replaceAll('\n', ''), - length: +type[1].replace(/\D/g, ''), + length: +type[1] ? +type[1].replace(/\D/g, '') : '', context: param[0] ? param[0].replace('\n', '') : '' }; }).filter(el => el.name); @@ -578,7 +578,7 @@ export class MySQLClient extends AntaresCore { return { definer: row['Create Procedure'].match(/(?<=DEFINER=).*?(?=\s)/gs)[0], sql: row['Create Procedure'].match(/(BEGIN|begin)(.*)(END|end)/gs)[0], - parameters, + parameters: parameters || [], name: row.Procedure, comment: row['Create Procedure'].match(/(?<=COMMENT ').*?(?=')/gs) ? row['Create Procedure'].match(/(?<=COMMENT ').*?(?=')/gs)[0] : '', security: row['Create Procedure'].includes('SQL SECURITY INVOKER') ? 'INVOKER' : 'DEFINER', @@ -628,10 +628,12 @@ export class MySQLClient extends AntaresCore { * @memberof MySQLClient */ async createRoutine (routine) { - const parameters = routine.parameters.reduce((acc, curr) => { - acc.push(`${curr.context} \`${curr.name}\` ${curr.type}${curr.length ? `(${curr.length})` : ''}`); - return acc; - }, []).join(','); + const parameters = 'parameters' in routine + ? routine.parameters.reduce((acc, curr) => { + acc.push(`${curr.context} \`${curr.name}\` ${curr.type}${curr.length ? `(${curr.length})` : ''}`); + return acc; + }, []).join(',') + : ''; const sql = `CREATE ${routine.definer ? `DEFINER=${routine.definer} ` : ''}PROCEDURE \`${routine.name}\`(${parameters}) LANGUAGE SQL @@ -683,7 +685,7 @@ export class MySQLClient extends AntaresCore { return { name: param[0] ? param[0].replaceAll('`', '') : '', type: type[0], - length: +type[1].replace(/\D/g, '') + length: +type[1] ? +type[1].replace(/\D/g, '') : '' }; }).filter(el => el.name); @@ -700,7 +702,7 @@ export class MySQLClient extends AntaresCore { return { definer: row['Create Function'].match(/(?<=DEFINER=).*?(?=\s)/gs)[0], sql: row['Create Function'].match(/(BEGIN|begin)(.*)(END|end)/gs)[0], - parameters, + parameters: parameters || [], name: row.Function, comment: row['Create Function'].match(/(?<=COMMENT ').*?(?=')/gs) ? row['Create Function'].match(/(?<=COMMENT ').*?(?=')/gs)[0] : '', security: row['Create Function'].includes('SQL SECURITY INVOKER') ? 'INVOKER' : 'DEFINER', diff --git a/src/renderer/components/WorkspaceExploreBarMiscContext.vue b/src/renderer/components/WorkspaceExploreBarMiscContext.vue index 4baff39d..204c9ebb 100644 --- a/src/renderer/components/WorkspaceExploreBarMiscContext.vue +++ b/src/renderer/components/WorkspaceExploreBarMiscContext.vue @@ -5,8 +5,8 @@ >
{{ $t('word.run') }}
@@ -29,6 +29,12 @@ + @@ -36,6 +42,7 @@ import { mapGetters, mapActions } from 'vuex'; import BaseContextMenu from '@/components/BaseContextMenu'; import ConfirmModal from '@/components/BaseConfirmModal'; +import ModalAskParameters from '@/components/ModalAskParameters'; import Triggers from '@/ipc-api/Triggers'; import Routines from '@/ipc-api/Routines'; import Functions from '@/ipc-api/Functions'; @@ -45,7 +52,8 @@ export default { name: 'WorkspaceExploreBarMiscContext', components: { BaseContextMenu, - ConfirmModal + ConfirmModal, + ModalAskParameters }, props: { contextEvent: MouseEvent, @@ -54,7 +62,9 @@ export default { data () { return { isDeleteModal: false, - isRunModal: false + isRunModal: false, + isAskingParameters: false, + localElement: {} }; }, computed: { @@ -83,7 +93,8 @@ export default { methods: { ...mapActions({ addNotification: 'notifications/addNotification', - changeBreadcrumbs: 'workspaces/changeBreadcrumbs' + changeBreadcrumbs: 'workspaces/changeBreadcrumbs', + newTab: 'workspaces/newTab' }), showCreateTableModal () { this.$emit('show-create-table-modal'); @@ -94,11 +105,12 @@ export default { hideDeleteModal () { this.isDeleteModal = false; }, - showRunModal () { - this.isRunModal = true; + showAskParamsModal () { + this.isAskingParameters = true; }, - hideRunModal () { - this.isRunModal = false; + hideAskParamsModal () { + this.isAskingParameters = false; + this.closeContext(); }, closeContext () { this.$emit('close-context'); @@ -148,6 +160,105 @@ export default { catch (err) { this.addNotification({ status: 'error', message: err.stack }); } + }, + runElementCheck () { + if (this.selectedMisc.type === 'procedure') + this.runRoutineCheck(); + else if (this.selectedMisc.type === 'function') + this.runFunctionCheck(); + }, + runElement (params) { + if (this.selectedMisc.type === 'procedure') + this.runRoutine(params); + else if (this.selectedMisc.type === 'function') + this.runFunction(params); + }, + async runRoutineCheck () { + const params = { + uid: this.selectedWorkspace, + schema: this.workspace.breadcrumbs.schema, + routine: this.workspace.breadcrumbs.procedure + }; + + try { + const { status, response } = await Routines.getRoutineInformations(params); + if (status === 'success') + this.localElement = response; + + else + this.addNotification({ status: 'error', message: response }); + } + catch (err) { + this.addNotification({ status: 'error', message: err.stack }); + } + + if (this.localElement.parameters.length) + this.showAskParamsModal(); + else + this.runRoutine(); + }, + runRoutine (params) { + if (!params) params = []; + + let sql; + switch (this.workspace.client) { // TODO: move in a better place + case 'maria': + case 'mysql': + case 'pg': + sql = `CALL \`${this.localElement.name}\` (${params.join(',')})`; + break; + case 'mssql': + sql = `EXEC ${this.localElement.name} ${params.join(',')}`; + break; + default: + sql = `CALL \`${this.localElement.name}\` (${params.join(',')})`; + } + + this.newTab({ uid: this.workspace.uid, content: sql, autorun: true }); + this.closeContext(); + }, + async runFunctionCheck () { + const params = { + uid: this.selectedWorkspace, + schema: this.workspace.breadcrumbs.schema, + func: this.workspace.breadcrumbs.function + }; + + try { + const { status, response } = await Functions.getFunctionInformations(params); + if (status === 'success') + this.localElement = response; + else + this.addNotification({ status: 'error', message: response }); + } + catch (err) { + this.addNotification({ status: 'error', message: err.stack }); + } + + if (this.localElement.parameters.length) + this.showAskParamsModal(); + else + this.runFunction(); + }, + runFunction (params) { + if (!params) params = []; + + let sql; + switch (this.workspace.client) { // TODO: move in a better place + case 'maria': + case 'mysql': + case 'pg': + sql = `SELECT \`${this.localElement.name}\` (${params.join(',')})`; + break; + case 'mssql': + sql = `SELECT ${this.localElement.name} ${params.join(',')}`; + break; + default: + sql = `SELECT \`${this.localElement.name}\` (${params.join(',')})`; + } + + this.newTab({ uid: this.workspace.uid, content: sql, autorun: true }); + this.closeContext(); } } };