mirror of
https://github.com/Fabio286/antares.git
synced 2025-02-17 04:00:48 +01:00
feat: database creation
This commit is contained in:
parent
c1cdd03938
commit
3d0a83f2cf
@ -66,36 +66,4 @@ export default connections => {
|
||||
connections[uid].destroy();
|
||||
delete connections[uid];
|
||||
});
|
||||
|
||||
ipcMain.handle('get-structure', async (event, uid) => {
|
||||
try {
|
||||
const { rows: structure } = await connections[uid]
|
||||
.select('*')
|
||||
.schema('information_schema')
|
||||
.from('TABLES')
|
||||
.orderBy({ TABLE_SCHEMA: 'ASC', TABLE_NAME: 'ASC' })
|
||||
.run();
|
||||
|
||||
return { status: 'success', response: structure };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('raw-query', async (event, { uid, query, schema }) => {
|
||||
if (!query) return;
|
||||
|
||||
try {
|
||||
if (schema)
|
||||
await connections[uid].use(schema);
|
||||
|
||||
const result = await connections[uid].raw(query, true);
|
||||
|
||||
return { status: 'success', response: result };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
};
|
||||
|
70
src/main/ipc-handlers/database.js
Normal file
70
src/main/ipc-handlers/database.js
Normal file
@ -0,0 +1,70 @@
|
||||
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
export default connections => {
|
||||
ipcMain.handle('create-database', async (event, params) => {
|
||||
try {
|
||||
const query = `CREATE DATABASE \`${params.name}\` COLLATE ${params.collation}`;
|
||||
const result = await connections[params.uid].raw(query, true);
|
||||
|
||||
return { status: 'success', response: result };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('get-structure', async (event, uid) => {
|
||||
try {
|
||||
const { rows: structure } = await connections[uid]
|
||||
.select('*')
|
||||
.schema('information_schema')
|
||||
.from('TABLES')
|
||||
.orderBy({ TABLE_SCHEMA: 'ASC', TABLE_NAME: 'ASC' })
|
||||
.run();
|
||||
|
||||
return { status: 'success', response: structure };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('get-collations', async (event, uid) => {
|
||||
try {
|
||||
const result = await connections[uid].getCollations();
|
||||
|
||||
return { status: 'success', response: result };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('get-variables', async (event, uid) => {
|
||||
try {
|
||||
const result = await connections[uid].getVariables();
|
||||
|
||||
return { status: 'success', response: result };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('raw-query', async (event, { uid, query, schema }) => {
|
||||
if (!query) return;
|
||||
|
||||
try {
|
||||
if (schema)
|
||||
await connections[uid].use(schema);
|
||||
|
||||
const result = await connections[uid].raw(query, true);
|
||||
|
||||
return { status: 'success', response: result };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
};
|
@ -2,14 +2,14 @@ import connection from './connection';
|
||||
import tables from './tables';
|
||||
import updates from './updates';
|
||||
import application from './application';
|
||||
import properties from './properties';
|
||||
import database from './database';
|
||||
|
||||
const connections = {};
|
||||
|
||||
export default () => {
|
||||
connection(connections);
|
||||
tables(connections);
|
||||
properties(connections);
|
||||
database(connections);
|
||||
updates();
|
||||
application();
|
||||
};
|
||||
|
@ -1,14 +0,0 @@
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
export default (connections) => {
|
||||
ipcMain.handle('get-collations', async (event, uid) => {
|
||||
try {
|
||||
const result = await connections[uid].getCollations();
|
||||
|
||||
return { status: 'success', response: result };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
};
|
@ -31,9 +31,44 @@ export class MySQLClient extends AntaresCore {
|
||||
return this.raw(sql);
|
||||
}
|
||||
|
||||
getCollations () {
|
||||
/**
|
||||
* SHOW COLLATION
|
||||
*
|
||||
* @returns
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async getCollations () {
|
||||
const sql = 'SHOW COLLATION';
|
||||
return this.raw(sql);
|
||||
const results = await this.raw(sql);
|
||||
|
||||
return results.rows.map(row => {
|
||||
return {
|
||||
charset: row.Charset,
|
||||
collation: row.Collation,
|
||||
compiled: row.Compiled.includes('Yes'),
|
||||
default: row.Default.includes('Yes'),
|
||||
id: row.Id,
|
||||
sortLen: row.Sortlen
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* SHOW VARIABLES
|
||||
*
|
||||
* @returns
|
||||
* @memberof MySQLClient
|
||||
*/
|
||||
async getVariables () {
|
||||
const sql = 'SHOW VARIABLES';
|
||||
const results = await this.raw(sql);
|
||||
|
||||
return results.rows.map(row => {
|
||||
return {
|
||||
name: row.Variable_name,
|
||||
value: row.Value
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
125
src/renderer/components/ModalNewDB.vue
Normal file
125
src/renderer/components/ModalNewDB.vue
Normal file
@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<div class="modal active">
|
||||
<a class="modal-overlay" @click.stop="closeModal" />
|
||||
<div class="modal-container p-0">
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-database-plus mr-1" /> {{ $t('message.createNewDatabase') }}
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
</div>
|
||||
<div class="modal-body pb-0">
|
||||
<div class="content">
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ $t('word.name') }}:</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<input
|
||||
v-model="database.name"
|
||||
class="form-input"
|
||||
type="text"
|
||||
required
|
||||
:placeholder="$t('message.databaseName')"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ $t('word.collation') }}:</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<select v-model="database.collation" class="form-select">
|
||||
<option
|
||||
v-for="collation in collations"
|
||||
:key="collation.id"
|
||||
:value="collation.collation"
|
||||
>
|
||||
{{ collation.collation }}
|
||||
</option>
|
||||
</select>
|
||||
<small>{{ $t('message.serverDefault') }}: {{ defaultCollation }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer text-light">
|
||||
<button class="btn btn-primary mr-2" @click.stop="createDatabase">
|
||||
{{ $t('word.add') }}
|
||||
</button>
|
||||
<button class="btn btn-link" @click.stop="closeModal">
|
||||
{{ $t('word.close') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapActions } from 'vuex';
|
||||
import Database from '@/ipc-api/Database';
|
||||
|
||||
export default {
|
||||
name: 'ModalNewDB',
|
||||
data () {
|
||||
return {
|
||||
database: {
|
||||
name: '',
|
||||
collation: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
selectedWorkspace: 'workspaces/getSelected',
|
||||
getWorkspace: 'workspaces/getWorkspace',
|
||||
getDatabaseVariable: 'workspaces/getDatabaseVariable'
|
||||
}),
|
||||
collations () {
|
||||
return this.getWorkspace(this.selectedWorkspace).collations;
|
||||
},
|
||||
defaultCollation () {
|
||||
return this.getDatabaseVariable(this.selectedWorkspace, 'collation_server').value || '';
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.database = { ...this.database, collation: this.defaultCollation };
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
addNotification: 'notifications/addNotification'
|
||||
}),
|
||||
async createDatabase () {
|
||||
try {
|
||||
const { status, response } = await Database.createDatabase({
|
||||
uid: this.selectedWorkspace,
|
||||
...this.database
|
||||
});
|
||||
|
||||
if (status === 'success') {
|
||||
this.closeModal();
|
||||
this.$emit('reload');
|
||||
}
|
||||
else
|
||||
this.addNotification({ status: 'error', message: response });
|
||||
}
|
||||
catch (err) {
|
||||
this.addNotification({ status: 'error', message: err.stack });
|
||||
}
|
||||
},
|
||||
closeModal () {
|
||||
this.$emit('close');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.modal-container {
|
||||
max-width: 360px;
|
||||
}
|
||||
</style>
|
@ -10,13 +10,18 @@
|
||||
<span class="workspace-explorebar-title">{{ connectionName }}</span>
|
||||
<span v-if="workspace.connected" class="workspace-explorebar-tools">
|
||||
<i
|
||||
class="mdi mdi-18px mdi-refresh c-hand"
|
||||
class="mdi mdi-18px mdi-database-plus c-hand mr-2"
|
||||
:title="$t('message.createNewDatabase')"
|
||||
@click="showNewDBModal"
|
||||
/>
|
||||
<i
|
||||
class="mdi mdi-18px mdi-refresh c-hand mr-2"
|
||||
:class="{'rotate':isRefreshing}"
|
||||
:title="$t('word.refresh')"
|
||||
@click="refresh"
|
||||
/>
|
||||
<i
|
||||
class="mdi mdi-18px mdi-power-plug-off c-hand mr-1 ml-2"
|
||||
class="mdi mdi-18px mdi-power-plug-off c-hand"
|
||||
:title="$t('word.disconnect')"
|
||||
@click="disconnectWorkspace(connection.uid)"
|
||||
/>
|
||||
@ -36,6 +41,11 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<ModalNewDB
|
||||
v-if="isNewDBModal"
|
||||
@close="hideNewDBModal"
|
||||
@reload="refresh"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -44,12 +54,14 @@ import { mapGetters, mapActions } from 'vuex';
|
||||
import _ from 'lodash';
|
||||
import WorkspaceConnectPanel from '@/components/WorkspaceConnectPanel';
|
||||
import WorkspaceExploreBarDatabase from '@/components/WorkspaceExploreBarDatabase';
|
||||
import ModalNewDB from '@/components/ModalNewDB';
|
||||
|
||||
export default {
|
||||
name: 'WorkspaceExploreBar',
|
||||
components: {
|
||||
WorkspaceConnectPanel,
|
||||
WorkspaceExploreBarDatabase
|
||||
WorkspaceExploreBarDatabase,
|
||||
ModalNewDB
|
||||
},
|
||||
props: {
|
||||
connection: Object,
|
||||
@ -58,6 +70,7 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
isRefreshing: false,
|
||||
isNewDBModal: false,
|
||||
localWidth: null
|
||||
};
|
||||
},
|
||||
@ -117,6 +130,12 @@ export default {
|
||||
},
|
||||
stopResize () {
|
||||
window.removeEventListener('mousemove', this.resize);
|
||||
},
|
||||
showNewDBModal () {
|
||||
this.isNewDBModal = true;
|
||||
},
|
||||
hideNewDBModal () {
|
||||
this.isNewDBModal = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -44,7 +44,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Connection from '@/ipc-api/Connection';
|
||||
import Database from '@/ipc-api/Database';
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
import QueryEditor from '@/components/QueryEditor';
|
||||
import WorkspaceQueryTable from '@/components/WorkspaceQueryTable';
|
||||
@ -114,7 +114,7 @@ export default {
|
||||
query
|
||||
};
|
||||
|
||||
const { status, response } = await Connection.rawQuery(params);
|
||||
const { status, response } = await Database.rawQuery(params);
|
||||
|
||||
if (status === 'success') {
|
||||
this.results = Array.isArray(response) ? response : [response];
|
||||
|
@ -75,7 +75,8 @@ module.exports = {
|
||||
openNewTab: 'Open a new tab',
|
||||
affectedRows: 'Affected rows',
|
||||
createNewDatabase: 'Create new Database',
|
||||
databaseName: 'Database name'
|
||||
databaseName: 'Database name',
|
||||
serverDefault: 'Server default'
|
||||
},
|
||||
// Date and Time
|
||||
short: {
|
||||
|
@ -17,16 +17,4 @@ export default class {
|
||||
static disconnect (uid) {
|
||||
return ipcRenderer.invoke('disconnect', uid);
|
||||
}
|
||||
|
||||
static getStructure (uid) {
|
||||
return ipcRenderer.invoke('get-structure', uid);
|
||||
}
|
||||
|
||||
static getCollations (uid) {
|
||||
return ipcRenderer.invoke('get-collations', uid);
|
||||
}
|
||||
|
||||
static rawQuery (params) {
|
||||
return ipcRenderer.invoke('raw-query', params);
|
||||
}
|
||||
}
|
||||
|
24
src/renderer/ipc-api/Database.js
Normal file
24
src/renderer/ipc-api/Database.js
Normal file
@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
import { ipcRenderer } from 'electron';
|
||||
|
||||
export default class {
|
||||
static createDatabase (params) {
|
||||
return ipcRenderer.invoke('create-database', params);
|
||||
}
|
||||
|
||||
static getStructure (uid) {
|
||||
return ipcRenderer.invoke('get-structure', uid);
|
||||
}
|
||||
|
||||
static getCollations (uid) {
|
||||
return ipcRenderer.invoke('get-collations', uid);
|
||||
}
|
||||
|
||||
static getVariables (uid) {
|
||||
return ipcRenderer.invoke('get-variables', uid);
|
||||
}
|
||||
|
||||
static rawQuery (params) {
|
||||
return ipcRenderer.invoke('raw-query', params);
|
||||
}
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
'use strict';
|
||||
import Connection from '@/ipc-api/Connection';
|
||||
import Database from '@/ipc-api/Database';
|
||||
import { uidGen } from 'common/libs/uidGen';
|
||||
const tabIndex = [];
|
||||
|
||||
function remapStructure (structure) { // TODO: move to main process and add fields (for autocomplete purpose)
|
||||
function remapStructure (structure) { // TODO: move to main process and add fields (for autocomplete purpose), also add empty database
|
||||
const databases = structure.map(table => table.TABLE_SCHEMA)
|
||||
.filter((value, index, self) => self.indexOf(value) === index);
|
||||
|
||||
@ -31,6 +32,9 @@ export default {
|
||||
getWorkspace: state => uid => {
|
||||
return state.workspaces.find(workspace => workspace.uid === uid);
|
||||
},
|
||||
getDatabaseVariable: state => (uid, name) => {
|
||||
return state.workspaces.find(workspace => workspace.uid === uid).variables.find(variable => variable.name === name);
|
||||
},
|
||||
getWorkspaceTab: (state, getters) => tUid => {
|
||||
if (!getters.getSelected) return;
|
||||
const workspace = state.workspaces.find(workspace => workspace.uid === getters.getSelected);
|
||||
@ -57,8 +61,11 @@ export default {
|
||||
REFRESH_STRUCTURE (state, { uid, structure }) {
|
||||
state.workspaces = state.workspaces.map(workspace => workspace.uid === uid ? { ...workspace, structure } : workspace);
|
||||
},
|
||||
REFRESH_COLLATIONS (state, { uid, collations }) { // TODO: Save collations
|
||||
// state.workspaces = state.workspaces.map(workspace => workspace.uid === uid ? { ...workspace, structure } : workspace);
|
||||
REFRESH_COLLATIONS (state, { uid, collations }) {
|
||||
state.workspaces = state.workspaces.map(workspace => workspace.uid === uid ? { ...workspace, collations } : workspace);
|
||||
},
|
||||
REFRESH_VARIABLES (state, { uid, variables }) {
|
||||
state.workspaces = state.workspaces.map(workspace => workspace.uid === uid ? { ...workspace, variables } : workspace);
|
||||
},
|
||||
ADD_WORKSPACE (state, workspace) {
|
||||
state.workspaces.push(workspace);
|
||||
@ -150,6 +157,7 @@ export default {
|
||||
else {
|
||||
commit('ADD_CONNECTED', { uid: connection.uid, structure: remapStructure(response) });
|
||||
dispatch('refreshCollations', connection.uid);
|
||||
dispatch('refreshVariables', connection.uid);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@ -158,7 +166,7 @@ export default {
|
||||
},
|
||||
async refreshStructure ({ dispatch, commit }, uid) {
|
||||
try {
|
||||
const { status, response } = await Connection.getStructure(uid);
|
||||
const { status, response } = await Database.getStructure(uid);
|
||||
if (status === 'error')
|
||||
dispatch('notifications/addNotification', { status, message: response }, { root: true });
|
||||
else
|
||||
@ -170,7 +178,7 @@ export default {
|
||||
},
|
||||
async refreshCollations ({ dispatch, commit }, uid) {
|
||||
try {
|
||||
const { status, response } = await Connection.getCollations(uid);
|
||||
const { status, response } = await Database.getCollations(uid);
|
||||
if (status === 'error')
|
||||
dispatch('notifications/addNotification', { status, message: response }, { root: true });
|
||||
else
|
||||
@ -180,6 +188,18 @@ export default {
|
||||
dispatch('notifications/addNotification', { status: 'error', message: err.stack }, { root: true });
|
||||
}
|
||||
},
|
||||
async refreshVariables ({ dispatch, commit }, uid) {
|
||||
try {
|
||||
const { status, response } = await Database.getVariables(uid);
|
||||
if (status === 'error')
|
||||
dispatch('notifications/addNotification', { status, message: response }, { root: true });
|
||||
else
|
||||
commit('REFRESH_VARIABLES', { uid, variables: response });
|
||||
}
|
||||
catch (err) {
|
||||
dispatch('notifications/addNotification', { status: 'error', message: err.stack }, { root: true });
|
||||
}
|
||||
},
|
||||
removeConnected ({ commit }, uid) {
|
||||
Connection.disconnect(uid);
|
||||
commit('REMOVE_CONNECTED', uid);
|
||||
@ -203,6 +223,8 @@ export default {
|
||||
keyUsage: []
|
||||
}],
|
||||
structure: {},
|
||||
variables: [],
|
||||
collations: [],
|
||||
breadcrumbs: {}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user