mirror of
https://github.com/Fabio286/antares.git
synced 2025-04-06 06:21:06 +02:00
perf(MySQL): improved connections pool handling
This commit is contained in:
parent
854472c7a3
commit
434711a360
@ -83,8 +83,8 @@ This is a roadmap with major features will come in near future.
|
|||||||
#### • ARM
|
#### • ARM
|
||||||
|
|
||||||
- [ ] Windows
|
- [ ] Windows
|
||||||
- [ ] Linux
|
- [x] Linux
|
||||||
- [ ] MacOS
|
- [x] MacOS
|
||||||
|
|
||||||
## Translations
|
## Translations
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import mysql from 'mysql2';
|
import mysql from 'mysql2/promise';
|
||||||
import { AntaresCore } from '../AntaresCore';
|
import { AntaresCore } from '../AntaresCore';
|
||||||
import dataTypes from 'common/data-types/mysql';
|
import dataTypes from 'common/data-types/mysql';
|
||||||
|
|
||||||
@ -102,8 +102,10 @@ export class MySQLClient extends AntaresCore {
|
|||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
async connect () {
|
async connect () {
|
||||||
|
delete this._params.application_name;
|
||||||
|
|
||||||
if (!this._poolSize)
|
if (!this._poolSize)
|
||||||
this._connection = mysql.createConnection(this._params);
|
this._connection = await mysql.createConnection(this._params);
|
||||||
else {
|
else {
|
||||||
this._connection = mysql.createPool({
|
this._connection = mysql.createPool({
|
||||||
...this._params,
|
...this._params,
|
||||||
@ -1273,6 +1275,8 @@ export class MySQLClient extends AntaresCore {
|
|||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
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,
|
||||||
@ -1280,15 +1284,15 @@ export class MySQLClient extends AntaresCore {
|
|||||||
...args
|
...args
|
||||||
};
|
};
|
||||||
|
|
||||||
if (args.schema && args.schema !== 'public')
|
|
||||||
await this.use(args.schema);
|
|
||||||
|
|
||||||
const nestTables = args.nest ? '.' : false;
|
const nestTables = args.nest ? '.' : false;
|
||||||
const resultsArr = [];
|
const resultsArr = [];
|
||||||
let paramsArr = [];
|
let paramsArr = [];
|
||||||
const queries = args.split ? sql.split(/((?:[^;'"]*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')[^;'"]*)+)|;/gm) : [sql];
|
const queries = args.split ? sql.split(/((?:[^;'"]*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')[^;'"]*)+)|;/gm) : [sql];
|
||||||
|
const isPool = typeof this._connection.getConnection === 'function';
|
||||||
|
const connection = isPool ? await this._connection.getConnection() : this._connection;
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development') this._logger(sql);// TODO: replace BLOB content with a placeholder
|
if (args.schema)
|
||||||
|
await connection.query(`USE \`${args.schema}\``);
|
||||||
|
|
||||||
for (const query of queries) {
|
for (const query of queries) {
|
||||||
if (!query) continue;
|
if (!query) continue;
|
||||||
@ -1297,87 +1301,85 @@ export class MySQLClient 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({ sql: query, nestTables }, async (err, response, fields) => {
|
connection.query({ sql: query, nestTables }).then(async ([response, fields]) => {
|
||||||
timeStop = new Date();
|
timeStop = new Date();
|
||||||
const queryResult = response;
|
const queryResult = response;
|
||||||
|
|
||||||
if (err)
|
let remappedFields = fields
|
||||||
reject(err);
|
? fields.map(field => {
|
||||||
else {
|
if (!field || Array.isArray(field))
|
||||||
let remappedFields = fields
|
return false;
|
||||||
? fields.map(field => {
|
|
||||||
if (!field || Array.isArray(field))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const type = this._getType(field);
|
const type = this._getType(field);
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: field.orgName,
|
||||||
|
alias: field.name,
|
||||||
|
orgName: field.orgName,
|
||||||
|
schema: field.schema,
|
||||||
|
table: field.table,
|
||||||
|
tableAlias: field.table,
|
||||||
|
orgTable: field.orgTable,
|
||||||
|
type: type.name,
|
||||||
|
length: type.length
|
||||||
|
};
|
||||||
|
}).filter(Boolean)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
if (args.details) {
|
||||||
|
let cachedTable;
|
||||||
|
|
||||||
|
if (remappedFields.length) {
|
||||||
|
paramsArr = remappedFields.map(field => {
|
||||||
|
if (field.orgTable) cachedTable = field.orgTable;// Needed for some queries on information_schema
|
||||||
return {
|
return {
|
||||||
name: field.orgName,
|
table: field.orgTable || cachedTable,
|
||||||
alias: field.name,
|
schema: field.schema || 'INFORMATION_SCHEMA'
|
||||||
orgName: field.orgName,
|
|
||||||
schema: field.schema,
|
|
||||||
table: field.table,
|
|
||||||
tableAlias: field.table,
|
|
||||||
orgTable: field.orgTable,
|
|
||||||
type: type.name,
|
|
||||||
length: type.length
|
|
||||||
};
|
};
|
||||||
}).filter(Boolean)
|
}).filter((val, i, arr) => arr.findIndex(el => el.schema === val.schema && el.table === val.table) === i);
|
||||||
: [];
|
|
||||||
|
|
||||||
if (args.details) {
|
for (const paramObj of paramsArr) {
|
||||||
let cachedTable;
|
if (!paramObj.table || !paramObj.schema) continue;
|
||||||
|
|
||||||
if (remappedFields.length) {
|
try { // Column details
|
||||||
paramsArr = remappedFields.map(field => {
|
const response = await this.getTableColumns(paramObj);
|
||||||
if (field.orgTable) cachedTable = field.orgTable;// Needed for some queries on information_schema
|
remappedFields = remappedFields.map(field => {
|
||||||
return {
|
const detailedField = response.find(f => f.name === field.name);
|
||||||
table: field.orgTable || cachedTable,
|
if (detailedField && field.orgTable === paramObj.table && field.schema === paramObj.schema)
|
||||||
schema: field.schema || 'INFORMATION_SCHEMA'
|
field = { ...field, ...detailedField };
|
||||||
};
|
return field;
|
||||||
}).filter((val, i, arr) => arr.findIndex(el => el.schema === val.schema && el.table === val.table) === i);
|
});
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
for (const paramObj of paramsArr) {
|
try { // Key usage (foreign keys)
|
||||||
if (!paramObj.table || !paramObj.schema) continue;
|
const response = await this.getKeyUsage(paramObj);
|
||||||
|
keysArr = keysArr ? [...keysArr, ...response] : response;
|
||||||
try { // Column details
|
}
|
||||||
const response = await this.getTableColumns(paramObj);
|
catch (err) {
|
||||||
remappedFields = remappedFields.map(field => {
|
reject(err);
|
||||||
const detailedField = response.find(f => f.name === field.name);
|
|
||||||
if (detailedField && field.orgTable === paramObj.table && field.schema === paramObj.schema)
|
|
||||||
field = { ...field, ...detailedField };
|
|
||||||
return field;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
reject(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
try { // Key usage (foreign keys)
|
|
||||||
const response = await this.getKeyUsage(paramObj);
|
|
||||||
keysArr = keysArr ? [...keysArr, ...response] : response;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
reject(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve({
|
|
||||||
duration: timeStop - timeStart,
|
|
||||||
rows: Array.isArray(queryResult) ? queryResult.some(el => Array.isArray(el)) ? [] : queryResult : false,
|
|
||||||
report: !Array.isArray(queryResult) ? queryResult : false,
|
|
||||||
fields: remappedFields,
|
|
||||||
keys: keysArr
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
resolve({
|
||||||
|
duration: timeStop - timeStart,
|
||||||
|
rows: Array.isArray(queryResult) ? queryResult.some(el => Array.isArray(el)) ? [] : queryResult : false,
|
||||||
|
report: !Array.isArray(queryResult) ? queryResult : false,
|
||||||
|
fields: remappedFields,
|
||||||
|
keys: keysArr
|
||||||
|
});
|
||||||
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
|
|
||||||
resultsArr.push({ rows, report, fields, keys, duration });
|
resultsArr.push({ rows, report, fields, keys, duration });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPool) connection.release();
|
||||||
|
|
||||||
return resultsArr.length === 1 ? resultsArr[0] : resultsArr;
|
return resultsArr.length === 1 ? resultsArr[0] : resultsArr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,6 @@ export default {
|
|||||||
},
|
},
|
||||||
setNull () {
|
setNull () {
|
||||||
const row = this.localResults.find(row => this.selectedRows.includes(row._id));
|
const row = this.localResults.find(row => this.selectedRows.includes(row._id));
|
||||||
delete row._id;
|
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
primary: this.primaryField.name,
|
primary: this.primaryField.name,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user