UNPKG

enhancer-data-bridge

Version:

A bridge between Enhancer Clould and user business datasource

219 lines (192 loc) 6.64 kB
'use strict'; var BaseServiceClass = require('./service-base'); var mysql = require('mysql'); var async = require('async'); var dbTypeMap = { '1': 'TINYINT', '2': 'SMALLINT', '3': 'INT', '4': 'FLOAT', '5': 'DOUBLE', '7': 'TIMESTAMP', '8': 'BIGINT', '9': 'MEDIUMINT', '10': 'DATE', '11': 'TIME', '12': 'DATETIME', '13': 'YEAR', '16': 'BIT', '252': 'BLOB', '253': 'VARCHAR', '254': 'CHAR', '246': 'DECIMAL' }; var varTypeMap = { '1': 'number', '2': 'number', '3': 'number', '4': 'number', '5': 'number', '7': 'number', '8': 'number', '9': 'string', '10': 'string', '11': 'string', '12': 'string', '13': 'string', '14': 'string', '15': 'string', '16': 'string', '252': 'string', '253': 'string', '254': 'string', '246': 'number' }; class MysqlService extends BaseServiceClass { constructor(dbConfig) { dbConfig.timezone = dbConfig.timezone || '08:00'; dbConfig.charset = dbConfig.charset || 'utf8mb4'; super(dbConfig); this.dbConfig = dbConfig; } // @overridden BaseServiceClass#criteriaQuery criteriaQuery(criteria, callback) { var limitReg = /\sLIMIT\s+\d+\s*(\,\s*\d+\s*)?$/i; var that = this; var limitClause = criteria.query.match(limitReg); criteria.query = criteria.query.replace(limitReg, ''); var statement = this.prepareSQLStatement(criteria, '?'); var sql = statement.sql + (limitClause || [''])[0]; var params = statement.params; var ROWS_LENGTH = 'ROWS_LENGTH'; var countRecords = function(cb) { if (!criteria.paged || !criteria.countRecords || !statement.isSelect) { return cb(null, ROWS_LENGTH); } // var countSql = "SELECT count(*) records FROM (" + sql + ") A"; var countSql = that.getCountSql(sql, params); // Create connection and destroy it after use. This is just for preview mode, // and different from connection using method in bodhi app. var conn = mysql.createConnection(that.dbConfig); conn.query(countSql.sql, countSql.params, function(err, result) { conn && conn.destroy(); if (err) { return cb(err); } if (!result.length) { return cb(null, 0); } cb(null, result[0]['records']); }); }; var fetchData = function(cb) { if ( statement.isSelect && criteria.sortBy ) { sql = sql + " ORDER BY " + criteria.sortBy; } if ( statement.isSelect && criteria.paged === true ) { criteria.rowNum = parseInt(criteria.rowNum) || 1; sql = sql.replace(limitReg, ''); sql = sql + " LIMIT " + ( ( criteria.page - 1 ) * criteria.rowNum ) + ", " + criteria.rowNum; } var conn = mysql.createConnection(that.dbConfig); conn.query(sql, params, function(err, rows, fields) { conn && conn.destroy(); if (err) { return cb(err); } if (!statement.isSelect) { rows = rows[rows.length - 2] || rows[0] || []; fields = fields[fields.length - 2] || fields[0] || []; } var result = { rows: rows, paged: criteria.paged, page: criteria.page, rowNum: criteria.rowNum }; if (criteria.metaData) { result.metaData = fields.map(function(f) { f.dbType = dbTypeMap[f.type]; f.varType = varTypeMap[f.type] || 'string'; return f; }); } cb(null, result); }); }; async.parallel([countRecords, fetchData], function(err, results) { if (err) { return callback(err); } var records = results[0]; var finalResult = results[1]; finalResult.records = records === ROWS_LENGTH ? finalResult.rows.length : records; if (criteria.format === 'array') { finalResult.rows = finalResult.rows.map(function(obj) { var arr = []; for (var i in obj) { arr.push(obj[i]); } return arr; }); } callback(null, finalResult); }); } execute(sql, params, callback) { // Create connection and destroy it after use. This is just for preview mode, // and different from connection using method in bodhi app. var conn = mysql.createConnection(this.dbConfig); conn.query(sql, params, function(err, result, fields) { conn && conn.destroy(); if (err) { return callback(err); } if (result instanceof Array) { return callback(null, { rows: result, metaData: fields }); } callback(null, result); }); } beginTransaction(cb) { var conn = mysql.createConnection(this.dbConfig); // hack var exec = conn.query; conn.execute = function(sql, params, callback) { exec.apply(conn, [sql, params, function(err, result, fields) { if (err) { return callback(err); } if (result instanceof Array) { return callback(null, { rows: result, metaData: fields }); } callback(null, result); }]) } conn.release = conn.destroy; conn.beginTransaction(function(err) { if (err) { return cb(err); } cb(null, conn); }); } getConnection(cb) { var conn = mysql.createConnection(this.dbConfig); // hack conn.execute = conn.query; conn.release = conn.destroy; cb(null, conn); } } module.exports = MysqlService;