import { createPool, Pool, RowDataPacket } from "mysql2"; export type DBInDataType = string | number | null | undefined; export default class Database { private connectionPool:Pool; private static readonly CONNECTION_LIMIT = 128; public connected:boolean = false; public static Instance:Database; public constructor(databaseAddress:string, databasePort:number = 3306, databaseUsername:string, databasePassword:string, databaseName:string) { this.connectionPool = createPool({ connectionLimit: Database.CONNECTION_LIMIT, host: databaseAddress, port: databasePort, user: databaseUsername, password: databasePassword, database: databaseName }); console.log(`DB connection pool created. MAX_CONNECTIONS = ${Database.CONNECTION_LIMIT}`); Database.Instance = this; } public execute(query:string, data?:Array) { return new Promise((resolve, reject) => { this.connectionPool.getConnection((err, connection) => { if (err) { return reject(err); } if (data == null) { connection.execute(query, (err, result) => { if (err) { connection.release(); return reject(err); } resolve(result !== undefined); }); } else { connection.execute(query, data, (err, result) => { if (err) { connection.release(); return reject(err); } resolve(result !== undefined); }); } }); }); } public query(query:string, data?:Array) { return new Promise((resolve, reject) => { this.connectionPool.getConnection((err, connection) => { if (err) { return reject(err); } else { // Use old query if (data == null) { connection.query(query, (err, rows) => { connection.release(); if (err) { return reject(err); } resolve(rows); connection.release(); }); } // Use new prepared statements w/ placeholders else { connection.execute(query, data, (err, rows) => { connection.release(); if (err) { return reject(err); } resolve(rows); connection.release(); }); } } }); }); } public async querySingle(query:string, data?:Array) { const dbData = await this.query(query, data); if (dbData != null && dbData.length > 0) { return dbData[0]; } return null; } }