mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
feat: views creation
This commit is contained in:
@ -30,4 +30,14 @@ export default (connections) => {
|
|||||||
return { status: 'error', response: err.toString() };
|
return { status: 'error', response: err.toString() };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('create-view', async (event, params) => {
|
||||||
|
try {
|
||||||
|
await connections[params.uid].createView(params);
|
||||||
|
return { status: 'success' };
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
return { status: 'error', response: err.toString() };
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
@ -311,6 +311,17 @@ export class MySQLClient extends AntaresCore {
|
|||||||
return await this.raw(sql);
|
return await this.raw(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CREATE VIEW
|
||||||
|
*
|
||||||
|
* @returns {Array.<Object>} parameters
|
||||||
|
* @memberof MySQLClient
|
||||||
|
*/
|
||||||
|
async createView (view) {
|
||||||
|
const sql = `CREATE ALGORITHM = ${view.algorithm} ${view.definer ? `DEFINER=${view.definer} ` : ''}SQL SECURITY ${view.security} VIEW \`${view.name}\` AS ${view.sql} ${view.updateOption ? `WITH ${view.updateOption} CHECK OPTION` : ''}`;
|
||||||
|
return await this.raw(sql);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SHOW COLLATION
|
* SHOW COLLATION
|
||||||
*
|
*
|
||||||
|
188
src/renderer/components/ModalNewView.vue
Normal file
188
src/renderer/components/ModalNewView.vue
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
<template>
|
||||||
|
<ConfirmModal
|
||||||
|
:confirm-text="$t('word.confirm')"
|
||||||
|
size="medium"
|
||||||
|
@confirm="confirmOptionsChange"
|
||||||
|
@hide="$emit('close')"
|
||||||
|
>
|
||||||
|
<template :slot="'header'">
|
||||||
|
<div class="d-flex">
|
||||||
|
<i class="mdi mdi-24px mdi-eye-plus mr-1" /> {{ $t('message.createNewView') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div :slot="'body'">
|
||||||
|
<div class="container">
|
||||||
|
<div class="columns mb-4">
|
||||||
|
<div class="column col-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">{{ $t('word.name') }}</label>
|
||||||
|
<input
|
||||||
|
ref="firstInput"
|
||||||
|
v-model="localView.name"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column col-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">{{ $t('word.definer') }}</label>
|
||||||
|
<input
|
||||||
|
v-model="localView.definer"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
:placeholder="$t('message.currentUser')"
|
||||||
|
readonly
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column col-4">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">{{ $t('message.sqlSecurity') }}</label>
|
||||||
|
<label class="form-radio">
|
||||||
|
<input
|
||||||
|
v-model="localView.security"
|
||||||
|
type="radio"
|
||||||
|
name="security"
|
||||||
|
value="DEFINER"
|
||||||
|
>
|
||||||
|
<i class="form-icon" /> DEFINER
|
||||||
|
</label>
|
||||||
|
<label class="form-radio">
|
||||||
|
<input
|
||||||
|
v-model="localView.security"
|
||||||
|
type="radio"
|
||||||
|
name="security"
|
||||||
|
value="INVOKER"
|
||||||
|
>
|
||||||
|
<i class="form-icon" /> INVOKER
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column col-4">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">{{ $t('word.algorithm') }}</label>
|
||||||
|
<label class="form-radio">
|
||||||
|
<input
|
||||||
|
v-model="localView.algorithm"
|
||||||
|
type="radio"
|
||||||
|
name="algorithm"
|
||||||
|
value="UNDEFINED"
|
||||||
|
>
|
||||||
|
<i class="form-icon" /> UNDEFINED
|
||||||
|
</label>
|
||||||
|
<label class="form-radio">
|
||||||
|
<input
|
||||||
|
v-model="localView.algorithm"
|
||||||
|
type="radio"
|
||||||
|
value="MERGE"
|
||||||
|
name="algorithm"
|
||||||
|
>
|
||||||
|
<i class="form-icon" /> MERGE
|
||||||
|
</label>
|
||||||
|
<label class="form-radio">
|
||||||
|
<input
|
||||||
|
v-model="localView.algorithm"
|
||||||
|
type="radio"
|
||||||
|
value="TEMPTABLE"
|
||||||
|
name="algorithm"
|
||||||
|
>
|
||||||
|
<i class="form-icon" /> TEMPTABLE
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column col-4">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">{{ $t('message.updateOption') }}</label>
|
||||||
|
<label class="form-radio">
|
||||||
|
<input
|
||||||
|
v-model="localView.updateOption"
|
||||||
|
type="radio"
|
||||||
|
name="update"
|
||||||
|
value=""
|
||||||
|
>
|
||||||
|
<i class="form-icon" /> None
|
||||||
|
</label>
|
||||||
|
<label class="form-radio">
|
||||||
|
<input
|
||||||
|
v-model="localView.updateOption"
|
||||||
|
type="radio"
|
||||||
|
name="update"
|
||||||
|
value="CASCADED"
|
||||||
|
>
|
||||||
|
<i class="form-icon" /> CASCADED
|
||||||
|
</label>
|
||||||
|
<label class="form-radio">
|
||||||
|
<input
|
||||||
|
v-model="localView.updateOption"
|
||||||
|
type="radio"
|
||||||
|
name="update"
|
||||||
|
value="LOCAL"
|
||||||
|
>
|
||||||
|
<i class="form-icon" /> LOCAL
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="workspace-query-results column col-12 mt-2">
|
||||||
|
<label class="form-label ml-2">{{ $t('message.selectStatement') }}</label>
|
||||||
|
<QueryEditor
|
||||||
|
ref="queryEditor"
|
||||||
|
:value.sync="localView.sql"
|
||||||
|
:workspace="workspace"
|
||||||
|
:schema="schema"
|
||||||
|
:height="editorHeight"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ConfirmModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ConfirmModal from '@/components/BaseConfirmModal';
|
||||||
|
import QueryEditor from '@/components/QueryEditor';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ModalNewView',
|
||||||
|
components: {
|
||||||
|
ConfirmModal,
|
||||||
|
QueryEditor
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
table: String,
|
||||||
|
workspace: Object
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
localView: {
|
||||||
|
algorithm: 'UNDEFINED',
|
||||||
|
definer: '',
|
||||||
|
security: 'DEFINER',
|
||||||
|
updateOption: '',
|
||||||
|
sql: '',
|
||||||
|
name: ''
|
||||||
|
},
|
||||||
|
isOptionsChanging: false,
|
||||||
|
editorHeight: 300
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
schema () {
|
||||||
|
return this.workspace.breadcrumbs.schema;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$refs.firstInput.focus();
|
||||||
|
}, 20);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
confirmOptionsChange () {
|
||||||
|
this.$emit('open-create-view-editor', this.localView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@ -54,12 +54,19 @@
|
|||||||
@close="hideCreateTableModal"
|
@close="hideCreateTableModal"
|
||||||
@open-create-table-editor="openCreateTableEditor"
|
@open-create-table-editor="openCreateTableEditor"
|
||||||
/>
|
/>
|
||||||
|
<ModalNewView
|
||||||
|
v-if="isNewViewModal"
|
||||||
|
:workspace="workspace"
|
||||||
|
@close="hideCreateViewModal"
|
||||||
|
@open-create-view-editor="openCreateViewEditor"
|
||||||
|
/>
|
||||||
<DatabaseContext
|
<DatabaseContext
|
||||||
v-if="isDatabaseContext"
|
v-if="isDatabaseContext"
|
||||||
:selected-database="selectedDatabase"
|
:selected-database="selectedDatabase"
|
||||||
:context-event="databaseContextEvent"
|
:context-event="databaseContextEvent"
|
||||||
@close-context="closeDatabaseContext"
|
@close-context="closeDatabaseContext"
|
||||||
@show-create-table-modal="showCreateTableModal"
|
@show-create-table-modal="showCreateTableModal"
|
||||||
|
@show-create-view-modal="showCreateViewModal"
|
||||||
@reload="refresh"
|
@reload="refresh"
|
||||||
/>
|
/>
|
||||||
<TableContext
|
<TableContext
|
||||||
@ -76,12 +83,14 @@
|
|||||||
import { mapGetters, mapActions } from 'vuex';
|
import { mapGetters, mapActions } from 'vuex';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import Tables from '@/ipc-api/Tables';
|
import Tables from '@/ipc-api/Tables';
|
||||||
|
import Views from '@/ipc-api/Views';
|
||||||
import WorkspaceConnectPanel from '@/components/WorkspaceConnectPanel';
|
import WorkspaceConnectPanel from '@/components/WorkspaceConnectPanel';
|
||||||
import WorkspaceExploreBarDatabase from '@/components/WorkspaceExploreBarDatabase';
|
import WorkspaceExploreBarDatabase from '@/components/WorkspaceExploreBarDatabase';
|
||||||
import DatabaseContext from '@/components/WorkspaceExploreBarDatabaseContext';
|
import DatabaseContext from '@/components/WorkspaceExploreBarDatabaseContext';
|
||||||
import TableContext from '@/components/WorkspaceExploreBarTableContext';
|
import TableContext from '@/components/WorkspaceExploreBarTableContext';
|
||||||
import ModalNewDatabase from '@/components/ModalNewDatabase';
|
import ModalNewDatabase from '@/components/ModalNewDatabase';
|
||||||
import ModalNewTable from '@/components/ModalNewTable';
|
import ModalNewTable from '@/components/ModalNewTable';
|
||||||
|
import ModalNewView from '@/components/ModalNewView';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'WorkspaceExploreBar',
|
name: 'WorkspaceExploreBar',
|
||||||
@ -91,7 +100,8 @@ export default {
|
|||||||
DatabaseContext,
|
DatabaseContext,
|
||||||
TableContext,
|
TableContext,
|
||||||
ModalNewDatabase,
|
ModalNewDatabase,
|
||||||
ModalNewTable
|
ModalNewTable,
|
||||||
|
ModalNewView
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
connection: Object,
|
connection: Object,
|
||||||
@ -102,6 +112,7 @@ export default {
|
|||||||
isRefreshing: false,
|
isRefreshing: false,
|
||||||
isNewDBModal: false,
|
isNewDBModal: false,
|
||||||
isNewTableModal: false,
|
isNewTableModal: false,
|
||||||
|
isNewViewModal: false,
|
||||||
localWidth: null,
|
localWidth: null,
|
||||||
isDatabaseContext: false,
|
isDatabaseContext: false,
|
||||||
isTableContext: false,
|
isTableContext: false,
|
||||||
@ -215,6 +226,29 @@ export default {
|
|||||||
},
|
},
|
||||||
closeTableContext () {
|
closeTableContext () {
|
||||||
this.isTableContext = false;
|
this.isTableContext = false;
|
||||||
|
},
|
||||||
|
showCreateViewModal () {
|
||||||
|
this.closeDatabaseContext();
|
||||||
|
this.isNewViewModal = true;
|
||||||
|
},
|
||||||
|
hideCreateViewModal () {
|
||||||
|
this.isNewViewModal = false;
|
||||||
|
},
|
||||||
|
async openCreateViewEditor (payload) {
|
||||||
|
const params = {
|
||||||
|
uid: this.connection.uid,
|
||||||
|
...payload
|
||||||
|
};
|
||||||
|
|
||||||
|
const { status, response } = await Views.createView(params);
|
||||||
|
|
||||||
|
if (status === 'success') {
|
||||||
|
await this.refresh();
|
||||||
|
this.changeBreadcrumbs({ schema: this.selectedDatabase, view: payload.name });
|
||||||
|
this.selectTab({ uid: this.workspace.uid, tab: 'prop' });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.addNotification({ status: 'error', message: response });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -25,7 +25,11 @@
|
|||||||
<i class="table-icon mdi mdi-18px mr-1" :class="table.type === 'view' ? 'mdi-table-eye' : 'mdi-table'" />
|
<i class="table-icon mdi mdi-18px mr-1" :class="table.type === 'view' ? 'mdi-table-eye' : 'mdi-table'" />
|
||||||
<span>{{ table.name }}</span>
|
<span>{{ table.name }}</span>
|
||||||
</a>
|
</a>
|
||||||
<div class="table-size tooltip tooltip-left mr-1" :data-tooltip="formatBytes(table.size)">
|
<div
|
||||||
|
v-if="table.type === 'table'"
|
||||||
|
class="table-size tooltip tooltip-left mr-1"
|
||||||
|
:data-tooltip="formatBytes(table.size)"
|
||||||
|
>
|
||||||
<div class="pie" :style="piePercentage(table.size)" />
|
<div class="pie" :style="piePercentage(table.size)" />
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<div class="context-element" @click="showCreateTableModal">
|
<div class="context-element" @click="showCreateTableModal">
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table text-light pr-1" /> {{ $t('word.table') }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-table text-light pr-1" /> {{ $t('word.table') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element" @click="showCreateTableModal">
|
<div class="context-element" @click="showCreateViewModal">
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-eye text-light pr-1" /> {{ $t('word.view') }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-table-eye text-light pr-1" /> {{ $t('word.view') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element d-none" @click="false">
|
<div class="context-element d-none" @click="false">
|
||||||
@ -96,6 +96,9 @@ export default {
|
|||||||
showCreateTableModal () {
|
showCreateTableModal () {
|
||||||
this.$emit('show-create-table-modal');
|
this.$emit('show-create-table-modal');
|
||||||
},
|
},
|
||||||
|
showCreateViewModal () {
|
||||||
|
this.$emit('show-create-view-modal');
|
||||||
|
},
|
||||||
showDeleteModal () {
|
showDeleteModal () {
|
||||||
this.isDeleteModal = true;
|
this.isDeleteModal = true;
|
||||||
},
|
},
|
||||||
|
@ -145,8 +145,8 @@ export default {
|
|||||||
const { status, response } = res;
|
const { status, response } = res;
|
||||||
|
|
||||||
if (status === 'success') {
|
if (status === 'success') {
|
||||||
if (this.selectedTable.name === this.workspace.breadcrumbs.table)
|
if (this.selectedTable.name === this.workspace.breadcrumbs.table || this.selectedTable.name === this.workspace.breadcrumbs.view)
|
||||||
this.changeBreadcrumbs({ table: null });
|
this.changeBreadcrumbs({ table: null, view: null });
|
||||||
|
|
||||||
this.closeContext();
|
this.closeContext();
|
||||||
this.$emit('reload');
|
this.$emit('reload');
|
||||||
|
@ -142,7 +142,9 @@ module.exports = {
|
|||||||
selectStatement: 'Select statement',
|
selectStatement: 'Select statement',
|
||||||
sqlSecurity: 'SQL security',
|
sqlSecurity: 'SQL security',
|
||||||
updateOption: 'Update option',
|
updateOption: 'Update option',
|
||||||
deleteView: 'Delete view'
|
deleteView: 'Delete view',
|
||||||
|
createNewView: 'Create new view',
|
||||||
|
currentUser: 'Current user'
|
||||||
},
|
},
|
||||||
// Date and Time
|
// Date and Time
|
||||||
short: {
|
short: {
|
||||||
|
@ -13,4 +13,8 @@ export default class {
|
|||||||
static alterView (params) {
|
static alterView (params) {
|
||||||
return ipcRenderer.invoke('alter-view', params);
|
return ipcRenderer.invoke('alter-view', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static createView (params) {
|
||||||
|
return ipcRenderer.invoke('create-view', params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user