mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
refactor: improved structure of connection core
This commit is contained in:
@ -37,6 +37,7 @@ This is a roadmap with major features will come in near future.
|
|||||||
- Query logs console.
|
- Query logs console.
|
||||||
- Fake data filler.
|
- Fake data filler.
|
||||||
- Import/export and migration.
|
- Import/export and migration.
|
||||||
|
- SSH tunnel.
|
||||||
- Themes.
|
- Themes.
|
||||||
|
|
||||||
## Currently supported
|
## Currently supported
|
||||||
|
10
package.json
10
package.json
@ -11,7 +11,9 @@
|
|||||||
"build": "cross-env NODE_ENV=production npm run compile && electron-builder",
|
"build": "cross-env NODE_ENV=production npm run compile && electron-builder",
|
||||||
"release": "standard-version",
|
"release": "standard-version",
|
||||||
"release:pre": "npm run release -- --prerelease alpha",
|
"release:pre": "npm run release -- --prerelease alpha",
|
||||||
"lint": "eslint ."
|
"test": "npm run lint",
|
||||||
|
"lint": "eslint . --ext .js,.vue && stylelint \"./src/**/*.{css,scss,sass,vue}\"",
|
||||||
|
"lint:fix": "eslint . --ext .js,.vue --fix && stylelint \"./src/**/*.{css,scss,sass,vue}\" --fix"
|
||||||
},
|
},
|
||||||
"author": "Fabio Di Stasio <fabio286@gmail.com>",
|
"author": "Fabio Di Stasio <fabio286@gmail.com>",
|
||||||
"build": {
|
"build": {
|
||||||
@ -45,9 +47,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mdi/font": "^5.5.55",
|
"@mdi/font": "^5.6.55",
|
||||||
"electron-log": "^4.2.4",
|
"electron-log": "^4.2.4",
|
||||||
"electron-updater": "^4.3.4",
|
"electron-updater": "^4.3.5",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"moment": "^2.27.0",
|
"moment": "^2.27.0",
|
||||||
"monaco-editor": "^0.20.0",
|
"monaco-editor": "^0.20.0",
|
||||||
@ -67,7 +69,7 @@
|
|||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"cross-env": "^7.0.2",
|
"cross-env": "^7.0.2",
|
||||||
"electron": "^10.1.0",
|
"electron": "^10.1.0",
|
||||||
"electron-builder": "^22.8.0",
|
"electron-builder": "^22.8.1",
|
||||||
"electron-devtools-installer": "^3.1.1",
|
"electron-devtools-installer": "^3.1.1",
|
||||||
"electron-webpack": "^2.8.2",
|
"electron-webpack": "^2.8.2",
|
||||||
"electron-webpack-vue": "^2.4.0",
|
"electron-webpack-vue": "^2.4.0",
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
import { ipcMain } from 'electron';
|
import { ipcMain } from 'electron';
|
||||||
import { AntaresConnector } from '../libs/AntaresConnector';
|
import { ClientsFactory } from '../libs/ClientsFactory';
|
||||||
import InformationSchema from '../models/InformationSchema';
|
import InformationSchema from '../models/InformationSchema';
|
||||||
import Generic from '../models/Generic';
|
import Generic from '../models/Generic';
|
||||||
|
|
||||||
export default connections => {
|
export default connections => {
|
||||||
ipcMain.handle('test-connection', async (event, conn) => {
|
ipcMain.handle('test-connection', async (event, conn) => {
|
||||||
const Connection = new AntaresConnector({
|
const Connection = ClientsFactory.getConnection({
|
||||||
client: conn.client,
|
client: conn.client,
|
||||||
params: {
|
params: {
|
||||||
host: conn.host,
|
host: conn.host,
|
||||||
@ -33,7 +33,7 @@ export default connections => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('connect', async (event, conn) => {
|
ipcMain.handle('connect', async (event, conn) => {
|
||||||
const Connection = new AntaresConnector({
|
const Connection = ClientsFactory.getConnection({
|
||||||
client: conn.client,
|
client: conn.client,
|
||||||
params: {
|
params: {
|
||||||
host: conn.host,
|
host: conn.host,
|
||||||
|
@ -1,341 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
import mysql from 'mysql';
|
|
||||||
import mssql from 'mssql';
|
|
||||||
// import pg from 'pg'; TODO: PostgreSQL
|
|
||||||
|
|
||||||
/**
|
|
||||||
* As Simple As Possible Query Builder
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @class AntaresConnector
|
|
||||||
*/
|
|
||||||
export class AntaresConnector {
|
|
||||||
/**
|
|
||||||
*Creates an instance of AntaresConnector.
|
|
||||||
* @param {Object} args connection params
|
|
||||||
* @memberof AntaresConnector
|
|
||||||
*/
|
|
||||||
constructor (args) {
|
|
||||||
this._client = args.client;
|
|
||||||
this._params = args.params;
|
|
||||||
this._poolSize = args.poolSize || false;
|
|
||||||
this._connection = null;
|
|
||||||
this._logger = args.logger || console.log;
|
|
||||||
|
|
||||||
this._queryDefaults = {
|
|
||||||
schema: '',
|
|
||||||
select: [],
|
|
||||||
from: '',
|
|
||||||
where: [],
|
|
||||||
groupBy: [],
|
|
||||||
orderBy: [],
|
|
||||||
limit: [],
|
|
||||||
join: [],
|
|
||||||
update: [],
|
|
||||||
insert: {},
|
|
||||||
delete: false
|
|
||||||
};
|
|
||||||
this._query = Object.assign({}, this._queryDefaults);
|
|
||||||
}
|
|
||||||
|
|
||||||
_reducer (acc, curr) {
|
|
||||||
const type = typeof curr;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case 'number':
|
|
||||||
case 'string':
|
|
||||||
return [...acc, curr];
|
|
||||||
case 'object':
|
|
||||||
if (Array.isArray(curr))
|
|
||||||
return [...acc, ...curr];
|
|
||||||
else {
|
|
||||||
const clausoles = [];
|
|
||||||
for (const key in curr)
|
|
||||||
clausoles.push(`${key} ${curr[key]}`);
|
|
||||||
|
|
||||||
return clausoles;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the query object after a query
|
|
||||||
*
|
|
||||||
* @memberof AntaresConnector
|
|
||||||
*/
|
|
||||||
_resetQuery () {
|
|
||||||
this._query = Object.assign({}, this._queryDefaults);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @memberof AntaresConnector
|
|
||||||
*/
|
|
||||||
async connect () {
|
|
||||||
switch (this._client) {
|
|
||||||
case 'maria':
|
|
||||||
case 'mysql':
|
|
||||||
if (!this._poolSize)
|
|
||||||
this._connection = mysql.createConnection(this._params);
|
|
||||||
else
|
|
||||||
this._connection = mysql.createPool({ ...this._params, connectionLimit: this._poolSize });
|
|
||||||
break;
|
|
||||||
case 'mssql': {
|
|
||||||
const mssqlParams = {
|
|
||||||
user: this._params.user,
|
|
||||||
password: this._params.password,
|
|
||||||
server: this._params.host
|
|
||||||
};
|
|
||||||
this._connection = await mssql.connect(mssqlParams);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
schema (schema) {
|
|
||||||
this._query.schema = schema;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
select (...args) {
|
|
||||||
this._query.select = [...this._query.select, ...args];
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
from (table) {
|
|
||||||
this._query.from = table;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
into (table) {
|
|
||||||
this._query.from = table;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete (table) {
|
|
||||||
this._query.delete = true;
|
|
||||||
this.from(table);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
where (...args) {
|
|
||||||
this._query.where = [...this._query.where, ...args];
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
groupBy (...args) {
|
|
||||||
this._query.groupBy = [...this._query.groupBy, ...args];
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
orderBy (...args) {
|
|
||||||
this._query.orderBy = [...this._query.orderBy, ...args];
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
limit (...args) {
|
|
||||||
this._query.limit = args;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
use (schema) {
|
|
||||||
let sql;
|
|
||||||
|
|
||||||
switch (this._client) {
|
|
||||||
case 'maria':
|
|
||||||
case 'mysql':
|
|
||||||
sql = `USE \`${schema}\``;
|
|
||||||
break;
|
|
||||||
case 'mssql':
|
|
||||||
sql = `USE "${schema}"`;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.raw(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {String | Array} args field = value
|
|
||||||
* @returns
|
|
||||||
* @memberof AntaresConnector
|
|
||||||
*/
|
|
||||||
update (...args) {
|
|
||||||
this._query.update = [...this._query.update, ...args];
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Object} obj field: value
|
|
||||||
* @returns
|
|
||||||
* @memberof AntaresConnector
|
|
||||||
*/
|
|
||||||
insert (obj) {
|
|
||||||
this._query.insert = { ...this._query.insert, ...obj };
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {string} SQL string
|
|
||||||
* @memberof AntaresConnector
|
|
||||||
*/
|
|
||||||
getSQL () {
|
|
||||||
// SELECT
|
|
||||||
const selectArray = this._query.select.reduce(this._reducer, []);
|
|
||||||
let selectRaw = '';
|
|
||||||
if (selectArray.length) {
|
|
||||||
switch (this._client) {
|
|
||||||
case 'maria':
|
|
||||||
case 'mysql':
|
|
||||||
selectRaw = selectArray.length ? `SELECT ${selectArray.join(', ')} ` : 'SELECT * ';
|
|
||||||
break;
|
|
||||||
case 'mssql': {
|
|
||||||
const topRaw = this._query.limit.length ? ` TOP (${this._query.limit[0]}) ` : '';
|
|
||||||
selectRaw = selectArray.length ? `SELECT${topRaw} ${selectArray.join(', ')} ` : 'SELECT * ';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FROM
|
|
||||||
let fromRaw = '';
|
|
||||||
if (!this._query.update.length && !Object.keys(this._query.insert).length && !!this._query.from)
|
|
||||||
fromRaw = 'FROM';
|
|
||||||
else if (Object.keys(this._query.insert).length)
|
|
||||||
fromRaw = 'INTO';
|
|
||||||
|
|
||||||
switch (this._client) {
|
|
||||||
case 'maria':
|
|
||||||
case 'mysql':
|
|
||||||
fromRaw += this._query.from ? ` ${this._query.schema ? `\`${this._query.schema}\`.` : ''}\`${this._query.from}\` ` : '';
|
|
||||||
break;
|
|
||||||
case 'mssql':
|
|
||||||
fromRaw += this._query.from ? ` ${this._query.schema ? `${this._query.schema}.` : ''}${this._query.from} ` : '';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const whereArray = this._query.where.reduce(this._reducer, []);
|
|
||||||
const whereRaw = whereArray.length ? `WHERE ${whereArray.join(' AND ')} ` : '';
|
|
||||||
|
|
||||||
const updateArray = this._query.update.reduce(this._reducer, []);
|
|
||||||
const updateRaw = updateArray.length ? `SET ${updateArray.join(', ')} ` : '';
|
|
||||||
|
|
||||||
let insertRaw = '';
|
|
||||||
if (Object.keys(this._query.insert).length) {
|
|
||||||
const fieldsList = [];
|
|
||||||
const valueList = [];
|
|
||||||
const fields = this._query.insert;
|
|
||||||
|
|
||||||
for (const key in fields) {
|
|
||||||
if (fields[key] === null) continue;
|
|
||||||
fieldsList.push(key);
|
|
||||||
valueList.push(fields[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
insertRaw = `(${fieldsList.join(', ')}) VALUES (${valueList.join(', ')}) `;
|
|
||||||
}
|
|
||||||
|
|
||||||
const groupByArray = this._query.groupBy.reduce(this._reducer, []);
|
|
||||||
const groupByRaw = groupByArray.length ? `GROUP BY ${groupByArray.join(', ')} ` : '';
|
|
||||||
|
|
||||||
const orderByArray = this._query.orderBy.reduce(this._reducer, []);
|
|
||||||
const orderByRaw = orderByArray.length ? `ORDER BY ${orderByArray.join(', ')} ` : '';
|
|
||||||
|
|
||||||
// LIMIT
|
|
||||||
let limitRaw;
|
|
||||||
switch (this._client) {
|
|
||||||
case 'maria':
|
|
||||||
case 'mysql':
|
|
||||||
limitRaw = this._query.limit.length ? `LIMIT ${this._query.limit.join(', ')} ` : '';
|
|
||||||
break;
|
|
||||||
case 'mssql':
|
|
||||||
limitRaw = '';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${selectRaw}${updateRaw ? 'UPDATE' : ''}${insertRaw ? 'INSERT ' : ''}${this._query.delete ? 'DELETE ' : ''}${fromRaw}${updateRaw}${whereRaw}${groupByRaw}${orderByRaw}${limitRaw}${insertRaw}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise}
|
|
||||||
* @memberof AntaresConnector
|
|
||||||
*/
|
|
||||||
async run () {
|
|
||||||
const rawQuery = this.getSQL();
|
|
||||||
this._resetQuery();
|
|
||||||
return this.raw(rawQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} sql raw SQL query
|
|
||||||
* @param {boolean} [nest]
|
|
||||||
* @returns {Promise}
|
|
||||||
* @memberof AntaresConnector
|
|
||||||
*/
|
|
||||||
async raw (sql, nest) {
|
|
||||||
const nestTables = nest ? '.' : false;
|
|
||||||
const resultsArr = [];
|
|
||||||
const queries = sql.split(';');
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development') this._logger(sql);// TODO: replace BLOB content with a placeholder
|
|
||||||
|
|
||||||
for (const query of queries) {
|
|
||||||
if (!query) continue;
|
|
||||||
|
|
||||||
switch (this._client) { // TODO: uniform fields with every client type, needed table name and fields array
|
|
||||||
case 'maria':
|
|
||||||
case 'mysql': {
|
|
||||||
const { rows, report, fields } = await new Promise((resolve, reject) => {
|
|
||||||
this._connection.query({ sql: query, nestTables }, (err, response, fields) => {
|
|
||||||
if (err)
|
|
||||||
reject(err);
|
|
||||||
else {
|
|
||||||
resolve({
|
|
||||||
rows: Array.isArray(response) ? response : false,
|
|
||||||
report: !Array.isArray(response) ? response : false,
|
|
||||||
fields
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
resultsArr.push({ rows, report, fields });
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'mssql': {
|
|
||||||
const results = await this._connection.request().query(query);
|
|
||||||
resultsArr.push({ rows: results.recordsets[0] });// TODO: fields
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resultsArr.length === 1 ? resultsArr[0] : resultsArr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @memberof AntaresConnector
|
|
||||||
*/
|
|
||||||
destroy () {
|
|
||||||
switch (this._client) {
|
|
||||||
case 'maria':
|
|
||||||
case 'mysql':
|
|
||||||
this._connection.end();
|
|
||||||
break;
|
|
||||||
case 'mssql':
|
|
||||||
this._connection.close();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
141
src/main/libs/AntaresCore.js
Normal file
141
src/main/libs/AntaresCore.js
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
'use strict';
|
||||||
|
/**
|
||||||
|
* As Simple As Possible Query Builder Core
|
||||||
|
*
|
||||||
|
* @class AntaresCore
|
||||||
|
*/
|
||||||
|
export class AntaresCore {
|
||||||
|
/**
|
||||||
|
* Creates an instance of AntaresCore.
|
||||||
|
*
|
||||||
|
* @param {Object} args connection params
|
||||||
|
* @memberof AntaresCore
|
||||||
|
*/
|
||||||
|
constructor (args) {
|
||||||
|
this._client = args.client;
|
||||||
|
this._params = args.params;
|
||||||
|
this._poolSize = args.poolSize || false;
|
||||||
|
this._connection = null;
|
||||||
|
this._logger = args.logger || console.log;
|
||||||
|
|
||||||
|
this._queryDefaults = {
|
||||||
|
schema: '',
|
||||||
|
select: [],
|
||||||
|
from: '',
|
||||||
|
where: [],
|
||||||
|
groupBy: [],
|
||||||
|
orderBy: [],
|
||||||
|
limit: [],
|
||||||
|
join: [],
|
||||||
|
update: [],
|
||||||
|
insert: {},
|
||||||
|
delete: false
|
||||||
|
};
|
||||||
|
this._query = Object.assign({}, this._queryDefaults);
|
||||||
|
}
|
||||||
|
|
||||||
|
_reducer (acc, curr) {
|
||||||
|
const type = typeof curr;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'number':
|
||||||
|
case 'string':
|
||||||
|
return [...acc, curr];
|
||||||
|
case 'object':
|
||||||
|
if (Array.isArray(curr))
|
||||||
|
return [...acc, ...curr];
|
||||||
|
else {
|
||||||
|
const clausoles = [];
|
||||||
|
for (const key in curr)
|
||||||
|
clausoles.push(`${key} ${curr[key]}`);
|
||||||
|
|
||||||
|
return clausoles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the query object after a query
|
||||||
|
*
|
||||||
|
* @memberof AntaresCore
|
||||||
|
*/
|
||||||
|
_resetQuery () {
|
||||||
|
this._query = Object.assign({}, this._queryDefaults);
|
||||||
|
}
|
||||||
|
|
||||||
|
schema (schema) {
|
||||||
|
this._query.schema = schema;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
select (...args) {
|
||||||
|
this._query.select = [...this._query.select, ...args];
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
from (table) {
|
||||||
|
this._query.from = table;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
into (table) {
|
||||||
|
this._query.from = table;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete (table) {
|
||||||
|
this._query.delete = true;
|
||||||
|
this.from(table);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
where (...args) {
|
||||||
|
this._query.where = [...this._query.where, ...args];
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
groupBy (...args) {
|
||||||
|
this._query.groupBy = [...this._query.groupBy, ...args];
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
orderBy (...args) {
|
||||||
|
this._query.orderBy = [...this._query.orderBy, ...args];
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
limit (...args) {
|
||||||
|
this._query.limit = args;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String | Array} args field = value
|
||||||
|
* @returns
|
||||||
|
* @memberof AntaresCore
|
||||||
|
*/
|
||||||
|
update (...args) {
|
||||||
|
this._query.update = [...this._query.update, ...args];
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} obj field: value
|
||||||
|
* @returns
|
||||||
|
* @memberof AntaresCore
|
||||||
|
*/
|
||||||
|
insert (obj) {
|
||||||
|
this._query.insert = { ...this._query.insert, ...obj };
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Promise}
|
||||||
|
* @memberof AntaresCore
|
||||||
|
*/
|
||||||
|
async run () {
|
||||||
|
const rawQuery = this.getSQL();
|
||||||
|
this._resetQuery();
|
||||||
|
return this.raw(rawQuery);
|
||||||
|
}
|
||||||
|
}
|
27
src/main/libs/ClientsFactory.js
Normal file
27
src/main/libs/ClientsFactory.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
'use strict';
|
||||||
|
import { MySQLClient } from './clients/MySQLClient';
|
||||||
|
|
||||||
|
export class ClientsFactory {
|
||||||
|
/**
|
||||||
|
* Returns a database connection based on received args.
|
||||||
|
*
|
||||||
|
* @param {Object} args
|
||||||
|
* @param {String} args.client
|
||||||
|
* @param {Object} args.params
|
||||||
|
* @param {String} args.params.host
|
||||||
|
* @param {Number} args.params.port
|
||||||
|
* @param {String} args.params.password
|
||||||
|
* @param {Number=} args.poolSize
|
||||||
|
* @returns Database Connection
|
||||||
|
* @memberof ClientsFactory
|
||||||
|
*/
|
||||||
|
static getConnection (args) {
|
||||||
|
switch (args.client) {
|
||||||
|
case 'mysql':
|
||||||
|
case 'maria':
|
||||||
|
return new MySQLClient(args);
|
||||||
|
default:
|
||||||
|
return new Error(`Unknown database client: ${args.client}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
129
src/main/libs/clients/MySQLClient.js
Normal file
129
src/main/libs/clients/MySQLClient.js
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
'use strict';
|
||||||
|
import mysql from 'mysql';
|
||||||
|
import { AntaresCore } from '../AntaresCore';
|
||||||
|
|
||||||
|
export class MySQLClient extends AntaresCore {
|
||||||
|
/**
|
||||||
|
* @memberof MySQLClient
|
||||||
|
*/
|
||||||
|
async connect () {
|
||||||
|
if (!this._poolSize)
|
||||||
|
this._connection = mysql.createConnection(this._params);
|
||||||
|
else
|
||||||
|
this._connection = mysql.createPool({ ...this._params, connectionLimit: this._poolSize });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @memberof MySQLClient
|
||||||
|
*/
|
||||||
|
destroy () {
|
||||||
|
this._connection.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes an USE query
|
||||||
|
*
|
||||||
|
* @param {*} schema
|
||||||
|
* @memberof MySQLClient
|
||||||
|
*/
|
||||||
|
use (schema) {
|
||||||
|
const sql = `USE \`${schema}\``;
|
||||||
|
return this.raw(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string} SQL string
|
||||||
|
* @memberof MySQLClient
|
||||||
|
*/
|
||||||
|
getSQL () {
|
||||||
|
// SELECT
|
||||||
|
const selectArray = this._query.select.reduce(this._reducer, []);
|
||||||
|
let selectRaw = '';
|
||||||
|
|
||||||
|
if (selectArray.length)
|
||||||
|
selectRaw = selectArray.length ? `SELECT ${selectArray.join(', ')} ` : 'SELECT * ';
|
||||||
|
|
||||||
|
// FROM
|
||||||
|
let fromRaw = '';
|
||||||
|
|
||||||
|
if (!this._query.update.length && !Object.keys(this._query.insert).length && !!this._query.from)
|
||||||
|
fromRaw = 'FROM';
|
||||||
|
else if (Object.keys(this._query.insert).length)
|
||||||
|
fromRaw = 'INTO';
|
||||||
|
|
||||||
|
fromRaw += this._query.from ? ` ${this._query.schema ? `\`${this._query.schema}\`.` : ''}\`${this._query.from}\` ` : '';
|
||||||
|
|
||||||
|
// WHERE
|
||||||
|
const whereArray = this._query.where.reduce(this._reducer, []);
|
||||||
|
const whereRaw = whereArray.length ? `WHERE ${whereArray.join(' AND ')} ` : '';
|
||||||
|
|
||||||
|
// UPDATE
|
||||||
|
const updateArray = this._query.update.reduce(this._reducer, []);
|
||||||
|
const updateRaw = updateArray.length ? `SET ${updateArray.join(', ')} ` : '';
|
||||||
|
|
||||||
|
// INSERT
|
||||||
|
let insertRaw = '';
|
||||||
|
|
||||||
|
if (Object.keys(this._query.insert).length) {
|
||||||
|
const fieldsList = [];
|
||||||
|
const valueList = [];
|
||||||
|
const fields = this._query.insert;
|
||||||
|
|
||||||
|
for (const key in fields) {
|
||||||
|
if (fields[key] === null) continue;
|
||||||
|
fieldsList.push(key);
|
||||||
|
valueList.push(fields[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
insertRaw = `(${fieldsList.join(', ')}) VALUES (${valueList.join(', ')}) `;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GROUP BY
|
||||||
|
const groupByArray = this._query.groupBy.reduce(this._reducer, []);
|
||||||
|
const groupByRaw = groupByArray.length ? `GROUP BY ${groupByArray.join(', ')} ` : '';
|
||||||
|
|
||||||
|
// ORDER BY
|
||||||
|
const orderByArray = this._query.orderBy.reduce(this._reducer, []);
|
||||||
|
const orderByRaw = orderByArray.length ? `ORDER BY ${orderByArray.join(', ')} ` : '';
|
||||||
|
|
||||||
|
// 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}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} sql raw SQL query
|
||||||
|
* @param {boolean} [nest]
|
||||||
|
* @returns {Promise}
|
||||||
|
* @memberof MySQLClient
|
||||||
|
*/
|
||||||
|
async raw (sql, nest) {
|
||||||
|
const nestTables = nest ? '.' : false;
|
||||||
|
const resultsArr = [];
|
||||||
|
const queries = sql.split(';');
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === 'development') this._logger(sql);// TODO: replace BLOB content with a placeholder
|
||||||
|
|
||||||
|
for (const query of queries) {
|
||||||
|
if (!query) continue;
|
||||||
|
|
||||||
|
const { rows, report, fields } = await new Promise((resolve, reject) => {
|
||||||
|
this._connection.query({ sql: query, nestTables }, (err, response, fields) => {
|
||||||
|
if (err)
|
||||||
|
reject(err);
|
||||||
|
else {
|
||||||
|
resolve({
|
||||||
|
rows: Array.isArray(response) ? response : false,
|
||||||
|
report: !Array.isArray(response) ? response : false,
|
||||||
|
fields
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
resultsArr.push({ rows, report, fields });
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultsArr.length === 1 ? resultsArr[0] : resultsArr;
|
||||||
|
}
|
||||||
|
}
|
@ -29,6 +29,7 @@
|
|||||||
v-for="(field, index) in fields"
|
v-for="(field, index) in fields"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="th c-hand"
|
class="th c-hand"
|
||||||
|
:title="field.comment ? field.comment : false"
|
||||||
>
|
>
|
||||||
<div ref="columnResize" class="column-resizable">
|
<div ref="columnResize" class="column-resizable">
|
||||||
<div class="table-column-title" @click="sort(field.name)">
|
<div class="table-column-title" @click="sort(field.name)">
|
||||||
@ -38,7 +39,7 @@
|
|||||||
:class="`key-${field.key}`"
|
:class="`key-${field.key}`"
|
||||||
:title="keyName(field.key)"
|
:title="keyName(field.key)"
|
||||||
/>
|
/>
|
||||||
<span :title="field.comment ? field.comment : false">{{ field.alias || field.name }}</span>
|
<span>{{ field.alias || field.name }}</span>
|
||||||
<i
|
<i
|
||||||
v-if="currentSort === field.name"
|
v-if="currentSort === field.name"
|
||||||
class="mdi sort-icon"
|
class="mdi sort-icon"
|
||||||
|
Reference in New Issue
Block a user