diff --git a/src/main/ipc-handlers/tables.js b/src/main/ipc-handlers/tables.js index 6e46b68c..3a260026 100644 --- a/src/main/ipc-handlers/tables.js +++ b/src/main/ipc-handlers/tables.js @@ -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 { + const offset = (page - 1) * limit; const query = connections[uid] .select('*') .schema(schema) .from(table) - .limit(1000); + .limit(limit) + .offset(offset); if (sortParams && sortParams.field && sortParams.dir) query.orderBy({ [sortParams.field]: sortParams.dir.toUpperCase() }); diff --git a/src/main/libs/AntaresCore.js b/src/main/libs/AntaresCore.js index 4b50c30e..befc1492 100644 --- a/src/main/libs/AntaresCore.js +++ b/src/main/libs/AntaresCore.js @@ -26,6 +26,7 @@ export class AntaresCore { groupBy: [], orderBy: [], limit: [], + offset: [], join: [], update: [], insert: [], @@ -109,6 +110,11 @@ export class AntaresCore { return this; } + offset (...args) { + this._query.offset = args; + return this; + } + /** * @param {String | Array} args field = value * @returns diff --git a/src/main/libs/clients/MySQLClient.js b/src/main/libs/clients/MySQLClient.js index f158cc08..196276b8 100644 --- a/src/main/libs/clients/MySQLClient.js +++ b/src/main/libs/clients/MySQLClient.js @@ -305,11 +305,11 @@ export class MySQLClient extends AntaresCore { .select('*') .schema('information_schema') .from('COLUMNS') - .where({ TABLE_SCHEMA: `= '${this._schema}'`, TABLE_NAME: `= '${table}'` }) + .where({ TABLE_SCHEMA: `= '${this._schema || schema}'`, TABLE_NAME: `= '${table}'` }) .orderBy({ ORDINAL_POSITION: 'ASC' }) .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 => { let n = 0; @@ -1307,7 +1307,10 @@ export class MySQLClient extends AntaresCore { // LIMIT 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) { + if (isPool) connection.release(); reject(err); } @@ -1404,6 +1408,7 @@ export class MySQLClient extends AntaresCore { keysArr = keysArr ? [...keysArr, ...response] : response; } catch (err) { + if (isPool) connection.release(); reject(err); } } diff --git a/src/main/libs/clients/PostgreSQLClient.js b/src/main/libs/clients/PostgreSQLClient.js index 9a2badb3..8bdec925 100644 --- a/src/main/libs/clients/PostgreSQLClient.js +++ b/src/main/libs/clients/PostgreSQLClient.js @@ -1139,7 +1139,10 @@ export class PostgreSQLClient extends AntaresCore { // LIMIT 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}`; } /** diff --git a/src/renderer/components/WorkspaceTableTab.vue b/src/renderer/components/WorkspaceTableTab.vue index 264b7863..532a93e1 100644 --- a/src/renderer/components/WorkspaceTableTab.vue +++ b/src/renderer/components/WorkspaceTableTab.vue @@ -32,6 +32,27 @@ +
+ +
+ {{ page }} +
+ +
+ +
-
+
{{ $t('word.total') }}: {{ tableInfo.rows.toLocaleString() }} ({{ $t('word.approximately') }})
@@ -149,13 +170,15 @@ export default { isFakerModal: false, autorefreshTimer: 0, refreshInterval: null, - sortParams: {} + sortParams: {}, + page: 1 }; }, computed: { ...mapGetters({ getWorkspace: 'workspaces/getWorkspace', - selectedWorkspace: 'workspaces/getSelected' + selectedWorkspace: 'workspaces/getSelected', + limit: 'settings/getDataTabLimit' }), workspace () { return this.getWorkspace(this.connection.uid); @@ -184,7 +207,7 @@ export default { return this.results.length && this.results[0].rows && this.tableInfo && - this.results[0].rows.length === 1000 && + this.results[0].rows.length === this.limit && this.results[0].rows.length < this.tableInfo.rows; } }, @@ -197,6 +220,9 @@ export default { this.$refs.queryTable.resetSort(); } }, + page () { + this.getTableData(); + }, isSelected (val) { if (val && this.lastTable !== this.table) { this.getTableData(); @@ -228,6 +254,8 @@ export default { uid: this.connection.uid, schema: this.schema, table: this.workspace.breadcrumbs.table || this.workspace.breadcrumbs.view, + limit: this.limit, + page: this.page, sortParams }; @@ -255,6 +283,12 @@ export default { this.sortParams = sortParams; this.getTableData(sortParams); }, + pageChange (direction) { + if (direction === 'next') + this.page++; + else if (this.page > 1) + this.page--; + }, showAddModal () { this.isAddModal = true; }, diff --git a/src/renderer/store/modules/settings.store.js b/src/renderer/store/modules/settings.store.js index 1486dd02..487efeb2 100644 --- a/src/renderer/store/modules/settings.store.js +++ b/src/renderer/store/modules/settings.store.js @@ -11,6 +11,7 @@ export default { allow_prerelease: persistentStore.get('allow_prerelease', true), explorebar_size: persistentStore.get('explorebar_size', null), notifications_timeout: persistentStore.get('notifications_timeout', 5), + data_tab_limit: persistentStore.get('data_tab_limit', 1000), auto_complete: persistentStore.get('auto_complete', true), line_wrap: persistentStore.get('line_wrap', true), application_theme: persistentStore.get('application_theme', 'dark'), @@ -21,6 +22,7 @@ export default { getAllowPrerelease: state => state.allow_prerelease, getExplorebarSize: state => state.explorebar_size, getNotificationsTimeout: state => state.notifications_timeout, + getDataTabLimit: state => state.data_tab_limit, getAutoComplete: state => state.auto_complete, getLineWrap: state => state.line_wrap, getApplicationTheme: state => state.application_theme,