Delete rows

This commit is contained in:
Fabio 2020-07-23 19:10:14 +02:00
parent 67f55fbeb9
commit fdf5bef5ad
10 changed files with 126 additions and 49 deletions

View File

@ -34,4 +34,14 @@ export default (connections) => {
return { status: 'error', response: err.toString() };
}
});
ipcMain.handle('deleteTableRows', async (event, params) => {
try {
const result = await Generic.deleteTableRows(connections[params.uid], params);
return { status: 'success', response: result };
}
catch (err) {
return { status: 'error', response: err.toString() };
}
});
};

View File

@ -32,7 +32,7 @@ export class AntaresConnector {
join: [],
update: [],
insert: [],
delete: []
delete: false
};
this._query = Object.assign({}, this._queryDefaults);
}
@ -107,6 +107,12 @@ export class AntaresConnector {
return this;
}
delete (table) {
this._query.delete = true;
this.from(table);
return this;
}
where (...args) {
this._query.where = [...this._query.where, ...args];
return this;
@ -145,6 +151,11 @@ export class AntaresConnector {
return this.raw(sql);
}
/**
* @param {String | Array} args field = value
* @returns
* @memberof AntaresConnector
*/
update (...args) {
this._query.update = [...this._query.update, ...args];
return this;
@ -176,7 +187,7 @@ export class AntaresConnector {
// FROM
let fromRaw = '';
if (!this._query.update.length && this._query.from !== '')
if (!this._query.update.length && !!this._query.from)
fromRaw = 'FROM';
switch (this._client) {
@ -217,7 +228,7 @@ export class AntaresConnector {
break;
}
return `${selectRaw}${updateRaw ? 'UPDATE' : ''}${fromRaw}${updateRaw}${whereRaw}${groupByRaw}${orderByRaw}${limitRaw}`;
return `${selectRaw}${updateRaw ? 'UPDATE' : ''}${this._query.delete ? 'DELETE ' : ''}${fromRaw}${updateRaw}${whereRaw}${groupByRaw}${orderByRaw}${limitRaw}`;
}
/**

View File

@ -29,4 +29,12 @@ export default class {
.where({ [params.primary]: `= ${params.id}` })
.run();
}
static async deleteTableRows (connection, params) {
return connection
.schema(params.schema)
.delete(params.table)
.where({ [params.primary]: `IN (${params.rows.join(',')})` })
.run();
}
}

View File

@ -35,6 +35,7 @@
:results="results"
:fields="resultsFields"
@updateField="updateField"
@deleteSelected="deleteSelected"
/>
</div>
</div>
@ -46,6 +47,7 @@ import Structure from '@/ipc-api/Structure';
import QueryEditor from '@/components/QueryEditor';
import WorkspaceQueryTable from '@/components/WorkspaceQueryTable';
import { mapGetters, mapActions } from 'vuex';
import tableTabs from '@/mixins/tableTabs';
export default {
name: 'WorkspaceQueryTab',
@ -53,6 +55,7 @@ export default {
QueryEditor,
WorkspaceQueryTable
},
mixins: [tableTabs],
props: {
connection: Object
},
@ -140,25 +143,6 @@ export default {
}
this.isQuering = false;
},
async updateField (payload) {
const params = {
uid: this.connection.uid,
schema: this.workspace.breadcrumbs.schema,
table: this.workspace.breadcrumbs.table,
...payload
};
try {
const { status, response } = await Structure.updateTableCell(params);
if (status === 'success')
this.$refs.queryTable.applyUpdate(payload);
else
this.addNotification({ status: 'error', message: response });
}
catch (err) {
this.addNotification({ status: 'error', message: err.stack });
}
}
}
};

View File

@ -4,6 +4,7 @@
v-if="isContext"
:context-event="contextEvent"
:selected-rows="selectedRows"
@deleteSelected="deleteSelected"
@closeContext="isContext = false"
/>
<BaseVirtualScroll
@ -143,7 +144,7 @@ export default {
return 'UNKNOWN ' + key;
}
},
resizeResults (e) {
resizeResults () {
if (this.$refs.resultTable) {
const el = this.$refs.resultTable.$el;
const footer = document.getElementById('footer');
@ -152,8 +153,12 @@ export default {
const size = window.innerHeight - el.getBoundingClientRect().top - footer.offsetHeight;
this.resultsSize = size;
}
this.$refs.resultTable.updateWindow();
}
},
refreshScroller () {
this.resizeResults();
},
updateField (payload, id) {
if (!this.primaryField)
this.addNotification({ status: 'warning', message: this.$t('message.unableEditFieldWithoutPrimary') });
@ -166,6 +171,18 @@ export default {
this.$emit('updateField', params);
}
},
deleteSelected () {
if (!this.primaryField)
this.addNotification({ status: 'warning', message: this.$t('message.unableEditFieldWithoutPrimary') });
else {
const rowIDs = this.localResults.filter(row => this.selectedRows.includes(row._id)).map(row => row[this.primaryField.name]);
const params = {
primary: this.primaryField.name,
rows: rowIDs
};
this.$emit('deleteSelected', params);
}
},
applyUpdate (params) {
const { primary, id, field, content } = params;
this.localResults = this.localResults.map(row => {

View File

@ -1,21 +1,25 @@
<template>
<BaseContextMenu
:context-event="contextEvent"
@closeContext="$emit('closeContext')"
@closeContext="closeContext"
>
<div class="context-element" @click="$emit('editCell')">
<i class="material-icons md-18 text-light pr-1">edit</i> {{ $t('message.editCell') }}
</div>
<div class="context-element" @click="showConfirmModal">
<i class="material-icons md-18 text-light pr-1">delete</i> {{ $tc('message.deleteRows', selectedRows.length) }}
</div>
<ConfirmModal
v-if="isConfirmModal"
@confirm="deleteConnection()"
@confirm="deleteRows()"
@hide="hideConfirmModal"
>
<!-- -->
<template :slot="'header'">
{{ $tc('message.deleteRows', selectedRows.length) }}
</template>
<div :slot="'body'">
<div class="mb-2">
{{ $tc('message.confirmToDeleteRows', selectedRows.length) }}
</div>
</div>
</ConfirmModal>
</BaseContextMenu>
</template>
@ -52,6 +56,13 @@ export default {
},
hideConfirmModal () {
this.isConfirmModal = false;
},
closeContext () {
this.$emit('closeContext');
},
deleteRows () {
this.$emit('deleteSelected');
this.closeContext();
}
}
};

View File

@ -33,6 +33,7 @@
:results="results"
:fields="resultsFields"
@updateField="updateField"
@deleteSelected="deleteSelected"
/>
</div>
</div>
@ -42,12 +43,14 @@
import Structure from '@/ipc-api/Structure';
import WorkspaceQueryTable from '@/components/WorkspaceQueryTable';
import { mapGetters, mapActions } from 'vuex';
import tableTabs from '@/mixins/tableTabs';
export default {
name: 'WorkspaceTableTab',
components: {
WorkspaceQueryTable
},
mixins: [tableTabs],
props: {
connection: Object,
table: String
@ -137,25 +140,6 @@ export default {
}
this.isQuering = false;
},
async updateField (payload) {
const params = {
uid: this.connection.uid,
schema: this.workspace.breadcrumbs.schema,
table: this.workspace.breadcrumbs.table,
...payload
};
try {
const { status, response } = await Structure.updateTableCell(params);
if (status === 'success')
this.$refs.queryTable.applyUpdate(payload);
else
this.addNotification({ status: 'error', message: response });
}
catch (err) {
this.addNotification({ status: 'error', message: err.stack });
}
}
}
};

View File

@ -54,7 +54,8 @@ module.exports = {
restartToInstall: 'Restart Antares to install',
unableEditFieldWithoutPrimary: 'Unable to edit a field without a primary key in resultset',
editCell: 'Edit cell',
deleteRows: 'Delete row | Delete {count} rows'
deleteRows: 'Delete row | Delete {count} rows',
confirmToDeleteRows: 'Do you confirm to delete one row? | Do you confirm to delete {count} rows?'
},
// Date and Time
short: {

View File

@ -13,4 +13,8 @@ export default class {
static updateTableCell (params) {
return ipcRenderer.invoke('updateTableCell', params);
}
static deleteTableRows (params) {
return ipcRenderer.invoke('deleteTableRows', params);
}
}

View File

@ -0,0 +1,47 @@
import Structure from '@/ipc-api/Structure';
export default {
methods: {
async updateField (payload) {
const params = {
uid: this.connection.uid,
schema: this.workspace.breadcrumbs.schema,
table: this.workspace.breadcrumbs.table,
...payload
};
try {
const { status, response } = await Structure.updateTableCell(params);
if (status === 'success')
this.$refs.queryTable.applyUpdate(payload);
else
this.addNotification({ status: 'error', message: response });
}
catch (err) {
this.addNotification({ status: 'error', message: err.stack });
}
},
async deleteSelected (payload) {
const params = {
uid: this.connection.uid,
schema: this.workspace.breadcrumbs.schema,
table: this.workspace.breadcrumbs.table,
...payload
};
try {
const { status, response } = await Structure.deleteTableRows(params);
if (status === 'success') {
const { primary, rows } = params;
this.results = { ...this.results, rows: this.results.rows.filter(row => !rows.includes(row[primary])) };
this.$refs.queryTable.refreshScroller();// Necessary to re-render virtual scroller
}
else
this.addNotification({ status: 'error', message: response });
}
catch (err) {
this.addNotification({ status: 'error', message: err.stack });
}
}
}
};