mysql.js 3.14 KB
const mysql = require('mysql');
const _ = require('lodash');
const config = require('../config/common');

class MysqlAdapter {
  constructor(connect, database) {
    this.connect = connect;
    this.database = database;
    this.createPool();
  }
  createPool() {
    this.pool = mysql.createPool(Object.assign(this.connect, {
      database: this.database,
      queryFormat: function(query, values) {
        let exeQuery;

        if (!values) {
          exeQuery = query;
        } else {
          exeQuery = query.replace(/:(\w+)/g, function(txt, key) {
            if (values.hasOwnProperty(key)) {
              return this.escape(values[key]);
            }
            return txt;
          }.bind(this));
        }

        return exeQuery;
      },
      connectTimeout: 2000
    }));
  }
  getConnection() {
    return new Promise((resolve, reject) => {
      this.pool.getConnection((connErr, connection) => {
        if (connErr) {
          reject(connErr);
        } else {
          resolve(connection);
        }
      });
    });
  }
  query(sql, params, options) {
    return this.execute(sql, params, options);
  }
  delete(sql, params) {
    return this.execute(sql, params).then(result => {
      return result.affectedRows;
    });
  }
  update(sql, params) {
    return this.execute(sql, params).then(result => {
      return result.affectedRows;
    });
  }
  insert(sql, params) {
    return this.execute(sql, params).then(result => {
      return result.insertId;
    });
  }
  execute(sql, params) {
    return new Promise((resolve, reject) => {
      this.getConnection().then(connection => {
        connection.query(sql, params, (queryErr, result) => {
          connection.release();
          if (queryErr) {
            reject(queryErr);
          } else {
            resolve(result);
          }
        });
      }).catch(e => {
        reject(e);
      });
    });
  }
  transaction(sqls, cb) {
    return new Promise((resolve, reject) => {
      this.getConnection().then(connection => {
        let promises = _.map(sqls, sql => {
          return new Promise((res, rej) => {
            connection.query(sql, (queryErr, result) => {
              if (queryErr) {
                connection.rollback();
                rej(queryErr);
              } else {
                                cb && cb(sql); // eslint-disable-line
                res(result);
              }
            });
          });
        });

        Promise.all(promises).then(results => {
          connection.commit(err => {
            if (err) {
              connection.rollback(() => {
                connection.release();
              });
              reject();
            } else {
              connection.release();
              resolve(results);
            }
          });
        }, () => {
          reject();
        });
      });
    });
  }
  changeDatabase(database) {
    return new Promise(resolve => {
      this.pool.end(() => {
        this.createPool(database);
        resolve();
      });
    });
  }
  close() {
    this.pool.end();
  }
}

module.exports = MysqlAdapter;
module.exports.mysqlPool = new MysqlAdapter(config.database.connect, config.database.database);