feat(PostgreSQL): ability to cancel queries

This commit is contained in:
Fabio Di Stasio 2021-12-26 21:13:02 +01:00
parent 3d56ec7b49
commit 0c002918eb
6 changed files with 62 additions and 22 deletions

View File

@ -1,7 +1,6 @@
{ {
"extends": [ "extends": [
"stylelint-config-standard", "stylelint-config-standard"
"stylelint-config-standard-scss"
], ],
"fix": true, "fix": true,
"formatter": "verbose", "formatter": "verbose",

View File

@ -10,6 +10,7 @@ module.exports = {
database: true, database: true,
sslConnection: true, sslConnection: true,
sshConnection: true, sshConnection: true,
cancelQueries: true,
// Tools // Tools
processesList: true, processesList: true,
// Structure // Structure

View File

@ -21,6 +21,7 @@ export class PostgreSQLClient extends AntaresCore {
super(args); super(args);
this._schema = null; this._schema = null;
this._runningConnections = new Map();
this.types = {}; this.types = {};
for (const key in types.builtins) for (const key in types.builtins)
@ -1088,10 +1089,26 @@ export class PostgreSQLClient extends AntaresCore {
}); });
} }
/**
*
* @param {number} id
* @returns {Promise<null>}
*/
async killProcess (id) { async killProcess (id) {
return await this.raw(`SELECT pg_terminate_backend(${id})`); return await this.raw(`SELECT pg_terminate_backend(${id})`);
} }
/**
*
* @param {string} tabUid
* @returns {Promise<null>}
*/
async killTabQuery (tabUid) {
const id = this._runningConnections.get(tabUid);
if (id)
return await this.raw(`SELECT pg_cancel_backend(${id})`);
}
/** /**
* CREATE TABLE * CREATE TABLE
* *
@ -1396,6 +1413,8 @@ export class PostgreSQLClient extends AntaresCore {
* @memberof PostgreSQLClient * @memberof PostgreSQLClient
*/ */
async raw (sql, args) { async raw (sql, args) {
if (process.env.NODE_ENV === 'development') this._logger(sql);// TODO: replace BLOB content with a placeholder
args = { args = {
nest: false, nest: false,
details: false, details: false,
@ -1404,9 +1423,6 @@ export class PostgreSQLClient extends AntaresCore {
...args ...args
}; };
if (args.schema && args.schema !== 'public')
await this.use(args.schema);
if (!args.comments) if (!args.comments)
sql = sql.replace(/(\/\*(.|[\r\n])*?\*\/)|(--(.*|[\r\n]))/gm, '');// Remove comments sql = sql.replace(/(\/\*(.|[\r\n])*?\*\/)|(--(.*|[\r\n]))/gm, '');// Remove comments
@ -1418,7 +1434,14 @@ export class PostgreSQLClient extends AntaresCore {
.map(q => q.trim()) .map(q => q.trim())
: [sql]; : [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) { for (const query of queries) {
if (!query) continue; if (!query) continue;
@ -1428,15 +1451,12 @@ export class PostgreSQLClient extends AntaresCore {
let keysArr = []; let keysArr = [];
const { rows, report, fields, keys, duration } = await new Promise((resolve, reject) => { const { rows, report, fields, keys, duration } = await new Promise((resolve, reject) => {
this._connection.query({ (async () => {
rowMode: args.nest ? 'array' : null, try {
text: query const res = await connection.query({ rowMode: args.nest ? 'array' : null, text: query });
}, async (err, res) => {
timeStop = new Date(); timeStop = new Date();
if (err)
reject(err);
else {
let ast; let ast;
try { try {
@ -1525,6 +1545,10 @@ export class PostgreSQLClient extends AntaresCore {
}); });
} }
catch (err) { catch (err) {
if (isPool) {
connection.release();
this._runningConnections.delete(args.tabUid);
}
reject(err); reject(err);
} }
@ -1533,6 +1557,10 @@ export class PostgreSQLClient extends AntaresCore {
keysArr = keysArr ? [...keysArr, ...response] : response; keysArr = keysArr ? [...keysArr, ...response] : response;
} }
catch (err) { catch (err) {
if (isPool) {
connection.release();
this._runningConnections.delete(args.tabUid);
}
reject(err); reject(err);
} }
} }
@ -1547,12 +1575,24 @@ export class PostgreSQLClient extends AntaresCore {
keys: keysArr keys: keysArr
}); });
} }
}); catch (err) {
if (isPool) {
connection.release();
this._runningConnections.delete(args.tabUid);
}
reject(err);
}
})();
}); });
resultsArr.push({ rows, report, fields, keys, duration }); resultsArr.push({ rows, report, fields, keys, duration });
} }
if (isPool) {
connection.release();
this._runningConnections.delete(args.tabUid);
}
return resultsArr.length === 1 ? resultsArr[0] : resultsArr; return resultsArr.length === 1 ? resultsArr[0] : resultsArr;
} }
} }

View File

@ -200,7 +200,7 @@ export default {
} }
&::before { &::before {
content: ''; content: "";
height: 0; height: 0;
width: 3px; width: 3px;
transition: height 0.2s; transition: height 0.2s;