diff --git a/src/main/ipc-handlers/database.js b/src/main/ipc-handlers/database.js index d273b992..412fa18d 100644 --- a/src/main/ipc-handlers/database.js +++ b/src/main/ipc-handlers/database.js @@ -14,6 +14,18 @@ export default connections => { } }); + ipcMain.handle('update-database', async (event, params) => { + try { + const query = `ALTER DATABASE \`${params.name}\` COLLATE ${params.collation}`; + await connections[params.uid].raw(query); + + return { status: 'success' }; + } + catch (err) { + return { status: 'error', response: err.toString() }; + } + }); + ipcMain.handle('delete-database', async (event, params) => { try { const query = `DROP DATABASE \`${params.database}\``; @@ -26,6 +38,18 @@ export default connections => { } }); + ipcMain.handle('get-database-collation', async (event, params) => { + try { + const query = `SELECT \`DEFAULT_COLLATION_NAME\` FROM \`information_schema\`.\`SCHEMATA\` WHERE \`SCHEMA_NAME\`='${params.database}'`; + const collation = await connections[params.uid].raw(query); + + return { status: 'success', response: collation.rows.length ? collation.rows[0].DEFAULT_COLLATION_NAME : '' }; + } + catch (err) { + return { status: 'error', response: err.toString() }; + } + }); + ipcMain.handle('get-structure', async (event, uid) => { try { const structure = await connections[uid].getStructure(); diff --git a/src/main/libs/clients/MySQLClient.js b/src/main/libs/clients/MySQLClient.js index 732443a6..1bee3e22 100644 --- a/src/main/libs/clients/MySQLClient.js +++ b/src/main/libs/clients/MySQLClient.js @@ -36,6 +36,7 @@ export class MySQLClient extends AntaresCore { */ async getStructure () { const { rows: databases } = await this.raw('SHOW DATABASES'); + // TODO: SHOW TABLE STATUS FROM `{DATABASE_NAME}`; const { rows: tables } = await this .select('*') @@ -44,10 +45,30 @@ export class MySQLClient extends AntaresCore { .orderBy({ TABLE_SCHEMA: 'ASC', TABLE_NAME: 'ASC' }) .run(); - return databases.map(db => { + const { rows: functions } = await this.raw('SHOW FUNCTION STATUS'); + const { rows: procedures } = await this.raw('SHOW PROCEDURE STATUS'); + const { rows: schedulers } = await this.raw('SELECT *, EVENT_SCHEMA AS `Db`, EVENT_NAME AS `Name` FROM information_schema.`EVENTS`'); + + const triggersArr = []; + for (const db of databases) { + let { rows: triggers } = await this.raw(`SHOW TRIGGERS FROM \`${db.Database}\``); + if (triggers.length) { + triggers = triggers.map(trigger => { + trigger.Db = db.Database; + return trigger; + }); + triggersArr.push(...triggers); + } + } + + return databases.map(db => { // TODO: remap all objects, return { name: db.Database, - tables: tables.filter(table => table.TABLE_SCHEMA === db.Database)// TODO: remap tables objects + tables: tables.filter(table => table.TABLE_SCHEMA === db.Database), + functions: functions.filter(func => func.Db === db.Database), + procedures: procedures.filter(procedure => procedure.Db === db.Database), + triggers: triggersArr.filter(trigger => trigger.Db === db.Database), + schedulers: schedulers.filter(scheduler => scheduler.Db === db.Database) }; }); } diff --git a/src/renderer/components/ModalEditDatabase.vue b/src/renderer/components/ModalEditDatabase.vue new file mode 100644 index 00000000..13f620bb --- /dev/null +++ b/src/renderer/components/ModalEditDatabase.vue @@ -0,0 +1,151 @@ + + + + + diff --git a/src/renderer/components/ModalNewDB.vue b/src/renderer/components/ModalNewDatabase.vue similarity index 99% rename from src/renderer/components/ModalNewDB.vue rename to src/renderer/components/ModalNewDatabase.vue index 348ab808..e26f2741 100644 --- a/src/renderer/components/ModalNewDB.vue +++ b/src/renderer/components/ModalNewDatabase.vue @@ -64,7 +64,7 @@ import { mapGetters, mapActions } from 'vuex'; import Database from '@/ipc-api/Database'; export default { - name: 'ModalNewDB', + name: 'ModalNewDatabase', data () { return { database: { diff --git a/src/renderer/components/WorkspaceExploreBar.vue b/src/renderer/components/WorkspaceExploreBar.vue index 29112ba3..fb3c9502 100644 --- a/src/renderer/components/WorkspaceExploreBar.vue +++ b/src/renderer/components/WorkspaceExploreBar.vue @@ -42,7 +42,7 @@ /> - {{ $t('word.add') }} --> -
+
{{ $t('word.edit') }}
-
+
{{ $t('word.delete') }}
@@ -37,13 +42,15 @@ import { mapGetters, mapActions } from 'vuex'; import BaseContextMenu from '@/components/BaseContextMenu'; import ConfirmModal from '@/components/BaseConfirmModal'; +import ModalEditDatabase from '@/components/ModalEditDatabase'; import Database from '@/ipc-api/Database'; export default { name: 'WorkspaceExploreBarDatabaseContext', components: { BaseContextMenu, - ConfirmModal + ConfirmModal, + ModalEditDatabase }, props: { contextEvent: MouseEvent, @@ -51,7 +58,8 @@ export default { }, data () { return { - isConfirmModal: false + isDeleteModal: false, + isEditModal: false }; }, computed: { @@ -65,11 +73,18 @@ export default { showEditModal: 'application/showEditConnModal', addNotification: 'notifications/addNotification' }), - showConfirmModal () { - this.isConfirmModal = true; + showDeleteModal () { + this.isDeleteModal = true; }, - hideConfirmModal () { - this.isConfirmModal = false; + hideDeleteModal () { + this.isDeleteModal = false; + }, + showEditModal () { + this.isEditModal = true; + }, + hideEditModal () { + this.isEditModal = false; + this.closeContext(); }, closeContext () { this.$emit('close-context'); diff --git a/src/renderer/ipc-api/Database.js b/src/renderer/ipc-api/Database.js index 2464137b..6e1ac288 100644 --- a/src/renderer/ipc-api/Database.js +++ b/src/renderer/ipc-api/Database.js @@ -6,6 +6,14 @@ export default class { return ipcRenderer.invoke('create-database', params); } + static updateDatabase (params) { + return ipcRenderer.invoke('update-database', params); + } + + static getDatabaseCollation (params) { + return ipcRenderer.invoke('get-database-collation', params); + } + static deleteDatabase (params) { return ipcRenderer.invoke('delete-database', params); }