feat: prev/next buttons to browse the results pages of data tab

This commit is contained in:
Fabio Di Stasio 2021-05-27 22:13:59 +02:00
parent 310cfaa3c2
commit 79f033e524
6 changed files with 62 additions and 10 deletions

View File

@ -16,13 +16,15 @@ export default (connections) => {
} }
}); });
ipcMain.handle('get-table-data', async (event, { uid, schema, table, sortParams }) => { ipcMain.handle('get-table-data', async (event, { uid, schema, table, limit, page, sortParams }) => {
try { try {
const offset = (page - 1) * limit;
const query = connections[uid] const query = connections[uid]
.select('*') .select('*')
.schema(schema) .schema(schema)
.from(table) .from(table)
.limit(1000); .limit(limit)
.offset(offset);
if (sortParams && sortParams.field && sortParams.dir) if (sortParams && sortParams.field && sortParams.dir)
query.orderBy({ [sortParams.field]: sortParams.dir.toUpperCase() }); query.orderBy({ [sortParams.field]: sortParams.dir.toUpperCase() });

View File

@ -26,6 +26,7 @@ export class AntaresCore {
groupBy: [], groupBy: [],
orderBy: [], orderBy: [],
limit: [], limit: [],
offset: [],
join: [], join: [],
update: [], update: [],
insert: [], insert: [],
@ -109,6 +110,11 @@ export class AntaresCore {
return this; return this;
} }
offset (...args) {
this._query.offset = args;
return this;
}
/** /**
* @param {String | Array} args field = value * @param {String | Array} args field = value
* @returns * @returns

View File

@ -305,11 +305,11 @@ export class MySQLClient extends AntaresCore {
.select('*') .select('*')
.schema('information_schema') .schema('information_schema')
.from('COLUMNS') .from('COLUMNS')
.where({ TABLE_SCHEMA: `= '${this._schema}'`, TABLE_NAME: `= '${table}'` }) .where({ TABLE_SCHEMA: `= '${this._schema || schema}'`, TABLE_NAME: `= '${table}'` })
.orderBy({ ORDINAL_POSITION: 'ASC' }) .orderBy({ ORDINAL_POSITION: 'ASC' })
.run(); .run();
const { rows: fields } = await this.raw(`SHOW CREATE TABLE ${this._schema}.${table}`); const { rows: fields } = await this.raw(`SHOW CREATE TABLE \`${this._schema || schema}\`.\`${table}\``);
const remappedFields = fields.map(row => { const remappedFields = fields.map(row => {
let n = 0; let n = 0;
@ -1307,7 +1307,10 @@ export class MySQLClient extends AntaresCore {
// LIMIT // LIMIT
const limitRaw = this._query.limit.length ? `LIMIT ${this._query.limit.join(', ')} ` : ''; const limitRaw = this._query.limit.length ? `LIMIT ${this._query.limit.join(', ')} ` : '';
return `${selectRaw}${updateRaw ? 'UPDATE' : ''}${insertRaw ? 'INSERT ' : ''}${this._query.delete ? 'DELETE ' : ''}${fromRaw}${updateRaw}${whereRaw}${groupByRaw}${orderByRaw}${limitRaw}${insertRaw}`; // OFFSET
const offsetRaw = this._query.limit.length ? `OFFSET ${this._query.offset.join(', ')} ` : '';
return `${selectRaw}${updateRaw ? 'UPDATE' : ''}${insertRaw ? 'INSERT ' : ''}${this._query.delete ? 'DELETE ' : ''}${fromRaw}${updateRaw}${whereRaw}${groupByRaw}${orderByRaw}${limitRaw}${offsetRaw}${insertRaw}`;
} }
/** /**
@ -1396,6 +1399,7 @@ export class MySQLClient extends AntaresCore {
}); });
} }
catch (err) { catch (err) {
if (isPool) connection.release();
reject(err); reject(err);
} }
@ -1404,6 +1408,7 @@ export class MySQLClient extends AntaresCore {
keysArr = keysArr ? [...keysArr, ...response] : response; keysArr = keysArr ? [...keysArr, ...response] : response;
} }
catch (err) { catch (err) {
if (isPool) connection.release();
reject(err); reject(err);
} }
} }

View File

@ -1139,7 +1139,10 @@ export class PostgreSQLClient extends AntaresCore {
// LIMIT // LIMIT
const limitRaw = selectArray.length && this._query.limit.length ? `LIMIT ${this._query.limit.join(', ')} ` : ''; const limitRaw = selectArray.length && this._query.limit.length ? `LIMIT ${this._query.limit.join(', ')} ` : '';
return `${selectRaw}${updateRaw ? 'UPDATE' : ''}${insertRaw ? 'INSERT ' : ''}${this._query.delete ? 'DELETE ' : ''}${fromRaw}${updateRaw}${whereRaw}${groupByRaw}${orderByRaw}${limitRaw}${insertRaw}`; // OFFSET
const offsetRaw = selectArray.length && this._query.limit.length ? `OFFSET ${this._query.offset.join(', ')} ` : '';
return `${selectRaw}${updateRaw ? 'UPDATE' : ''}${insertRaw ? 'INSERT ' : ''}${this._query.delete ? 'DELETE ' : ''}${fromRaw}${updateRaw}${whereRaw}${groupByRaw}${orderByRaw}${limitRaw}${offsetRaw}${insertRaw}`;
} }
/** /**

View File

@ -32,6 +32,27 @@
</div> </div>
</div> </div>
</div> </div>
<div class="btn-group">
<button
class="btn btn-dark btn-sm mr-0"
:disabled="isQuering || page === 1"
@click="pageChange('prev')"
>
<i class="mdi mdi-24px mdi-skip-previous" />
</button>
<div class="btn btn-dark btn-sm mr-0 text-bold c-auto px-2">
{{ page }}
</div>
<button
class="btn btn-dark btn-sm mr-0"
:disabled="isQuering || (results.length && results[0].rows.length < limit)"
@click="pageChange('next')"
>
<i class="mdi mdi-24px mdi-skip-next" />
</button>
</div>
<div class="divider-vert py-3" />
<button <button
v-if="isTable" v-if="isTable"
@ -74,7 +95,7 @@
<div v-if="results.length && results[0].rows"> <div v-if="results.length && results[0].rows">
{{ $t('word.results') }}: <b>{{ results[0].rows.length.toLocaleString() }}</b> {{ $t('word.results') }}: <b>{{ results[0].rows.length.toLocaleString() }}</b>
</div> </div>
<div v-if="hasApproximately"> <div v-if="hasApproximately || page > 1">
{{ $t('word.total') }}: <b>{{ tableInfo.rows.toLocaleString() }}</b> <small>({{ $t('word.approximately') }})</small> {{ $t('word.total') }}: <b>{{ tableInfo.rows.toLocaleString() }}</b> <small>({{ $t('word.approximately') }})</small>
</div> </div>
<div v-if="workspace.breadcrumbs.database"> <div v-if="workspace.breadcrumbs.database">
@ -149,13 +170,15 @@ export default {
isFakerModal: false, isFakerModal: false,
autorefreshTimer: 0, autorefreshTimer: 0,
refreshInterval: null, refreshInterval: null,
sortParams: {} sortParams: {},
page: 1
}; };
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
getWorkspace: 'workspaces/getWorkspace', getWorkspace: 'workspaces/getWorkspace',
selectedWorkspace: 'workspaces/getSelected' selectedWorkspace: 'workspaces/getSelected',
limit: 'settings/getDataTabLimit'
}), }),
workspace () { workspace () {
return this.getWorkspace(this.connection.uid); return this.getWorkspace(this.connection.uid);
@ -184,7 +207,7 @@ export default {
return this.results.length && return this.results.length &&
this.results[0].rows && this.results[0].rows &&
this.tableInfo && this.tableInfo &&
this.results[0].rows.length === 1000 && this.results[0].rows.length === this.limit &&
this.results[0].rows.length < this.tableInfo.rows; this.results[0].rows.length < this.tableInfo.rows;
} }
}, },
@ -197,6 +220,9 @@ export default {
this.$refs.queryTable.resetSort(); this.$refs.queryTable.resetSort();
} }
}, },
page () {
this.getTableData();
},
isSelected (val) { isSelected (val) {
if (val && this.lastTable !== this.table) { if (val && this.lastTable !== this.table) {
this.getTableData(); this.getTableData();
@ -228,6 +254,8 @@ export default {
uid: this.connection.uid, uid: this.connection.uid,
schema: this.schema, schema: this.schema,
table: this.workspace.breadcrumbs.table || this.workspace.breadcrumbs.view, table: this.workspace.breadcrumbs.table || this.workspace.breadcrumbs.view,
limit: this.limit,
page: this.page,
sortParams sortParams
}; };
@ -255,6 +283,12 @@ export default {
this.sortParams = sortParams; this.sortParams = sortParams;
this.getTableData(sortParams); this.getTableData(sortParams);
}, },
pageChange (direction) {
if (direction === 'next')
this.page++;
else if (this.page > 1)
this.page--;
},
showAddModal () { showAddModal () {
this.isAddModal = true; this.isAddModal = true;
}, },

View File

@ -11,6 +11,7 @@ export default {
allow_prerelease: persistentStore.get('allow_prerelease', true), allow_prerelease: persistentStore.get('allow_prerelease', true),
explorebar_size: persistentStore.get('explorebar_size', null), explorebar_size: persistentStore.get('explorebar_size', null),
notifications_timeout: persistentStore.get('notifications_timeout', 5), notifications_timeout: persistentStore.get('notifications_timeout', 5),
data_tab_limit: persistentStore.get('data_tab_limit', 1000),
auto_complete: persistentStore.get('auto_complete', true), auto_complete: persistentStore.get('auto_complete', true),
line_wrap: persistentStore.get('line_wrap', true), line_wrap: persistentStore.get('line_wrap', true),
application_theme: persistentStore.get('application_theme', 'dark'), application_theme: persistentStore.get('application_theme', 'dark'),
@ -21,6 +22,7 @@ export default {
getAllowPrerelease: state => state.allow_prerelease, getAllowPrerelease: state => state.allow_prerelease,
getExplorebarSize: state => state.explorebar_size, getExplorebarSize: state => state.explorebar_size,
getNotificationsTimeout: state => state.notifications_timeout, getNotificationsTimeout: state => state.notifications_timeout,
getDataTabLimit: state => state.data_tab_limit,
getAutoComplete: state => state.auto_complete, getAutoComplete: state => state.auto_complete,
getLineWrap: state => state.line_wrap, getLineWrap: state => state.line_wrap,
getApplicationTheme: state => state.application_theme, getApplicationTheme: state => state.application_theme,