import { QueryOptions, PoolConnection, Pool } from 'mysql'; import { Logger } from '../../../common/util/logger.class'; const MAX_CONNECTION_RETRIES = 60; export class MariaDBConnector { private _conn?: PoolConnection; constructor(private pool: Pool) {} public query(options: string | QueryOptions, values: any): Promise> { return new Promise(async (resolve, reject) => { try { if (!this._conn) return reject('Database not opened.'); this._conn.query(options, values, (err, results) => (err ? reject(err) : resolve(results))); } catch (e) { reject(e); } }); } public beginTransaction() { return new Promise((resolve, reject) => { try { if (!this._conn) return reject('Database not opened.'); this._conn.beginTransaction(err => (err ? reject(err) : resolve())); } catch (e) { reject(e); } }); } public commit() { return new Promise((resolve, reject) => { try { if (!this._conn) return reject('Database not opened.'); this._conn.commit(err => (err ? reject(err) : resolve())); } catch (e) { reject(e); } }); } public async rollback() { return new Promise((resolve, reject) => { try { if (!this._conn) return reject('Database not opened.'); this._conn.rollback(err => (err ? reject(err) : resolve())); } catch (e) { reject(e); } }); } public async connect(): Promise { let retries = 1; let lasterror: any | null = null; while (retries <= MAX_CONNECTION_RETRIES) { try { Logger.debug(`[DEBUG] Connecting mariadb connection pool (${retries}/${MAX_CONNECTION_RETRIES}) ...`); await this._connect(); lasterror = null; break; } catch (e) { lasterror = e; await new Promise(res => setTimeout(res, 1000)); } finally { retries++; } } if (lasterror) throw lasterror; } private async _connect(): Promise { return new Promise((resolve, reject) => { try { if (!this._conn || !['connected', 'authenticated'].includes(this._conn?.state)) { return this.pool.getConnection((err, conn) => { if (err) return reject(err); this._conn = conn; resolve(); }); } resolve(); } catch (e) { reject(e); } }); } public close(): Promise { return new Promise(async (resolve, reject) => { try { if (this._conn && ['connected', 'authenticated'].includes(this._conn?.state)) { Logger.debug(`[DEBUG] Closing mariadb connection.`); this._conn.release(); } resolve(); } catch (e) { reject(e); } }); } }