From 0c002918eb0226f6b3f21ed62117495f86396fb1 Mon Sep 17 00:00:00 2001 From: Fabio Di Stasio Date: Sun, 26 Dec 2021 21:13:02 +0100 Subject: [PATCH] feat(PostgreSQL): ability to cancel queries --- .stylelintrc | 3 +- src/common/customizations/postgresql.js | 1 + src/main/libs/clients/PostgreSQLClient.js | 66 +++++++++++++++---- src/renderer/components/TheSettingBar.vue | 2 +- .../components/WorkspaceExploreBarSchema.vue | 10 +-- src/renderer/scss/_db-icons.scss | 2 +- 6 files changed, 62 insertions(+), 22 deletions(-) diff --git a/.stylelintrc b/.stylelintrc index f4abfb45..079be0a0 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -1,7 +1,6 @@ { "extends": [ - "stylelint-config-standard", - "stylelint-config-standard-scss" + "stylelint-config-standard" ], "fix": true, "formatter": "verbose", diff --git a/src/common/customizations/postgresql.js b/src/common/customizations/postgresql.js index 11d5ce97..4d5cda98 100644 --- a/src/common/customizations/postgresql.js +++ b/src/common/customizations/postgresql.js @@ -10,6 +10,7 @@ module.exports = { database: true, sslConnection: true, sshConnection: true, + cancelQueries: true, // Tools processesList: true, // Structure diff --git a/src/main/libs/clients/PostgreSQLClient.js b/src/main/libs/clients/PostgreSQLClient.js index 7c2e65fc..bd9ea56b 100644 --- a/src/main/libs/clients/PostgreSQLClient.js +++ b/src/main/libs/clients/PostgreSQLClient.js @@ -21,6 +21,7 @@ export class PostgreSQLClient extends AntaresCore { super(args); this._schema = null; + this._runningConnections = new Map(); this.types = {}; for (const key in types.builtins) @@ -1088,10 +1089,26 @@ export class PostgreSQLClient extends AntaresCore { }); } + /** + * + * @param {number} id + * @returns {Promise} + */ async killProcess (id) { return await this.raw(`SELECT pg_terminate_backend(${id})`); } + /** + * + * @param {string} tabUid + * @returns {Promise} + */ + async killTabQuery (tabUid) { + const id = this._runningConnections.get(tabUid); + if (id) + return await this.raw(`SELECT pg_cancel_backend(${id})`); + } + /** * CREATE TABLE * @@ -1396,6 +1413,8 @@ export class PostgreSQLClient extends AntaresCore { * @memberof PostgreSQLClient */ async raw (sql, args) { + if (process.env.NODE_ENV === 'development') this._logger(sql);// TODO: replace BLOB content with a placeholder + args = { nest: false, details: false, @@ -1404,9 +1423,6 @@ export class PostgreSQLClient extends AntaresCore { ...args }; - if (args.schema && args.schema !== 'public') - await this.use(args.schema); - if (!args.comments) sql = sql.replace(/(\/\*(.|[\r\n])*?\*\/)|(--(.*|[\r\n]))/gm, '');// Remove comments @@ -1418,7 +1434,14 @@ export class PostgreSQLClient extends AntaresCore { .map(q => q.trim()) : [sql]; - if (process.env.NODE_ENV === 'development') this._logger(sql);// TODO: replace BLOB content with a placeholder + const isPool = this._connection instanceof Pool; + const connection = isPool ? await this._connection.connect() : this._connection; + + if (args.tabUid && isPool) + this._runningConnections.set(args.tabUid, connection.processID); + + if (args.schema && args.schema !== 'public') + await this.use(args.schema); for (const query of queries) { if (!query) continue; @@ -1428,15 +1451,12 @@ export class PostgreSQLClient extends AntaresCore { let keysArr = []; const { rows, report, fields, keys, duration } = await new Promise((resolve, reject) => { - this._connection.query({ - rowMode: args.nest ? 'array' : null, - text: query - }, async (err, res) => { - timeStop = new Date(); + (async () => { + try { + const res = await connection.query({ rowMode: args.nest ? 'array' : null, text: query }); + + timeStop = new Date(); - if (err) - reject(err); - else { let ast; try { @@ -1525,6 +1545,10 @@ export class PostgreSQLClient extends AntaresCore { }); } catch (err) { + if (isPool) { + connection.release(); + this._runningConnections.delete(args.tabUid); + } reject(err); } @@ -1533,6 +1557,10 @@ export class PostgreSQLClient extends AntaresCore { keysArr = keysArr ? [...keysArr, ...response] : response; } catch (err) { + if (isPool) { + connection.release(); + this._runningConnections.delete(args.tabUid); + } reject(err); } } @@ -1547,12 +1575,24 @@ export class PostgreSQLClient extends AntaresCore { keys: keysArr }); } - }); + catch (err) { + if (isPool) { + connection.release(); + this._runningConnections.delete(args.tabUid); + } + reject(err); + } + })(); }); resultsArr.push({ rows, report, fields, keys, duration }); } + if (isPool) { + connection.release(); + this._runningConnections.delete(args.tabUid); + } + return resultsArr.length === 1 ? resultsArr[0] : resultsArr; } } diff --git a/src/renderer/components/TheSettingBar.vue b/src/renderer/components/TheSettingBar.vue index bc5c91a3..f91fb5f6 100644 --- a/src/renderer/components/TheSettingBar.vue +++ b/src/renderer/components/TheSettingBar.vue @@ -200,7 +200,7 @@ export default { } &::before { - content: ''; + content: ""; height: 0; width: 3px; transition: height 0.2s; diff --git a/src/renderer/components/WorkspaceExploreBarSchema.vue b/src/renderer/components/WorkspaceExploreBarSchema.vue index b744c45b..180b7590 100644 --- a/src/renderer/components/WorkspaceExploreBarSchema.vue +++ b/src/renderer/components/WorkspaceExploreBarSchema.vue @@ -452,9 +452,9 @@ export default { top: 0; z-index: 2; - .schema-size{ - visibility: hidden; - width: 22.5px; + .schema-size { + visibility: hidden; + width: 22.5px; } } @@ -502,8 +502,8 @@ export default { &:hover { border-radius: $border-radius; - .schema-size{ - visibility: visible; + .schema-size { + visibility: visible; } } } diff --git a/src/renderer/scss/_db-icons.scss b/src/renderer/scss/_db-icons.scss index 9124f837..0da0644f 100644 --- a/src/renderer/scss/_db-icons.scss +++ b/src/renderer/scss/_db-icons.scss @@ -20,7 +20,7 @@ background-image: url("../images/svg/pg.svg"); } - &.dbi-sqlite { + &.dbi-sqlite { background-image: url("../images/svg/sqlite.svg"); }