mysql.js 3.7 KB
const mysql = require('mysql');
const _ = require('lodash');

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) {
                if (!values) {
                    return query;
                }
                return query.replace(/\:(\w+)/g, function(txt, key) {
                    if (values.hasOwnProperty(key)) {
                        return this.escape(values[key]);
                    }
                    return txt;
                }.bind(this));
            },
            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.changedRows;
        });
    }
    insert(sql, params) {
        return this.execute(sql, params).then(result => {
            return result.insertId;
        });
    }
    async execute(sql, params, options = {}) {
        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;