File: /var/dev/farhangmoaser/web/connectors/mysql.js
"use strict";
/**
 * MySQL Connector
 * Version: 0.1
 * Author: Babak Vandad
 *
 * Manages a singleton connection to MySQL
 */
var mysql = require('mysql');
var config = require('../config.js');
/**
 * Custom SQL formatter for !! token
 * Object values converted to key=value and ... format.
 * @param {string} query  the query string containing tokens
 * @param {object} values the key/value pairs to be substituted
 * @return {string} converted query string
 **/ 
var queryFormatter = function (query, values) {
	if (!values) return mysql.format(query);
	return mysql.format(query.replace("!!", function () {
		var localValues;
		if(typeof values[0] == 'object')
			localValues = values.shift();
		else
			localValues = values;
		var whereClause = "";
		for(var index in localValues) {
			/* query: {column: [value1, value2, value3]} => `column` IN ('value1', 'value2', 'value3') */
			if(Array.isArray(localValues[index])) {
				let value = localValues[index].map(v => mysql.escape(v)).join(', ');
				whereClause+= mysql.escapeId(index) + ' IN (' + value + ') AND ';
			}else{
				/* query: {__f(col): value} => f(col) = value */
				if (index.substring(0, 2) == '__')
					whereClause += index.substring(2) + " = " + localValues[index] + " AND ";
				/* query: {%%col: value} => `col` like `value` */
				else if (/^%%.*[^%]$/.exec(index))
					whereClause += mysql.escapeId(index.substring(2)) + " LIKE " + mysql.escape(localValues[index]) + " AND ";
				/* query: {>=col: value} => `col` >= `value` */
				else if (index.substring(0, 2) == '>=')
					whereClause += mysql.escapeId(index.substring(2)) + " >= " + mysql.escape(localValues[index]) + " AND ";
				/* query: {<=col: value} => `col` <= `value` */
				else if (index.substring(0, 2) == '<=')
					whereClause += mysql.escapeId(index.substring(2)) + " <= " + mysql.escape(localValues[index]) + " AND ";
				/* query: {col: value} => `col` = `value` */
				else
					whereClause += mysql.escapeId(index) + " = " + mysql.escape(localValues[index]) + " AND ";
			}
		}
		return whereClause.substring(0, whereClause.length - 5);
	}.bind(this)), values);
};
/**
 * Connection configurations
 * @type {Object}
 */
var pool = mysql.createPool({
	connectionLimit : 100,
	user: config.read('mysql.username'),
	password: config.read('mysql.password'),
	database: config.read('mysql.database'),
	host: config.read('mysql.host') || 'localhost',
	port: config.read('mysql.port') || 3306
})
.on('connection', function(conn){
	conn.query("SET SESSION query_cache_type = ON");
	//TODO: set mode properly!
	//just removing full_group_mode
	conn.query("SET SESSION sql_mode = ''");
	conn.config.queryFormat = queryFormatter;
});
/**
 * Determines if any attempt to connection request has been issued or not.
 * IMPORTANT: It does not if the connection stablished or not. Only the attempt.
 * @type {Boolean}
 */
var connectionFlag = false;
exports.getConnection = function(callback){
	pool.getConnection(callback);
};
exports.getConnectionPromise = () =>
	new Promise((resolve, reject) => {
		pool.getConnection((err, conn) => {
			if(err) return reject(err);
			resolve (conn);
		});
	});