import mysql from "mysql";
import config from "./config";

let pool = undefined;

function initPool() {
  pool = mysql.createPool({
    host: config.db.host,
    port: config.db.port,
    user: config.db.user,
    password: config.db.password,
    database: config.db.database || "",
    charset: "utf8",
    connectionLimit: 10,
  });
}

function getTransactionConnection() {
  return new Promise((resolve, reject) => {
    if (pool == undefined) {
      reject("db not init");
    }
    pool.getConnection((err, connection) => {
      if (err) {
        reject(err);
      } else {
        connection.beginTransaction((err) => {
          if (err) {
            reject(err);
          } else {
            resolve(connection);
          }
        });
      }
    });
  });
}

function _query(connection, sql, datas) {
  return new Promise((resolve, reject) => {
    connection.query(sql, datas, (err, results, fields) => {
      if (err) {
        reject(err);
      } else {
        resolve(results, fields);
      }
    });
  });
}

export function init() {
  if (pool != undefined) {
    pool.end();
    pool = undefined;
  }
  initPool();
}

export function close() {
  if (pool != undefined) {
    pool.end();
    pool = undefined;
  }
}

export function query(sql, datas) {
  return new Promise((resolve, reject) => {
    pool.query(sql, datas, (err, results, fields) => {
      if (err) {
        reject(err);
      } else {
        resolve(results, fields);
      }
    });
  });
}

export function batchQuery(sql, datas) {
  return new Promise((resolve, reject) => {
    getTransactionConnection()
      .then((connection) => {
        const results = [];
        for (let i = 0; i < datas.length; i++) {
          results.push(_query(connection, sql, datas[i]));
        }

        Promise.all(results)
          .then(() => {
            connection.commit((err) => {
              if (err) {
                connection.rollback(() => {
                  reject(err);
                });
              } else {
                connection.release();
                resolve(datas.length);
              }
            });
          })
          .catch((err) => {
            connection.rollback(() => {
              reject(err);
            });
          });
      })
      .catch((err) => {
        reject(err);
      });
  });
}

export default {
  init,
  close,
  query,
  batchQuery,
};
