febs-db
Version:
febs-db is a ORM
207 lines (181 loc) • 5.71 kB
JavaScript
'use strict';
/**
* Copyright (c) 2015 Copyright citongs All Rights Reserved.
* Author: lipengxiang
* Desc:
*/
const assert = require('assert');
const febs = require('febs');
const copy = require('copy-to');
const exception = require('./exception');
const mysqlAdapter = require('./mysql/adapter');
const mssqlAdapter = require('./mssql/adapter');
const condition = require('./condition');
const tablebase = require('./tablebase');
module.exports = database;
function connect(dbtype, opt, customGenerateKeyCB = null) {
this._dbtype = dbtype;
// dbtype.
if (dbtype.toLowerCase() == 'mysql') {
this.adapter = mysqlAdapter;
}
else if (dbtype.toLowerCase() == 'mssql') {
this.adapter = mssqlAdapter;
}
else {
throw new exception('not support this db', febs.exception.PARAM, __filename, __line);
}
// create.
opt = this.adapter.opt_cvt(opt);
this.opt = opt;
this.pool = this.adapter.createPool(opt);
this.queryTimeout = opt.queryTimeout;
this.customGenerateKeyCB = customGenerateKeyCB;
// peek connect.
if (dbtype.toLowerCase() == 'mssql') {
this.exec('select getdate()')
.then(res=>{
console.log(`DB: Success connect to mssql ${opt.host}:${opt.port}`);
})
.catch(err=>{
console.error(`DB: Fail connect to mssql ${opt.host}:${opt.port}`);
console.error(err);
})
}
else if (dbtype.toLowerCase() == 'mysql') {
this.exec(`show status like 'uptime'`)
.then(res => {
console.log(`DB: Success connect to mysql ${opt.host}:${opt.port}`);
})
.catch(err => {
console.error(`DB: Fail connect to mysql ${opt.host}:${opt.port}`);
console.error(err);
})
}
this.adapter.errHandle(this, this.pool);
}
function database(dbtype, opt, customGenerateKeyCB = null) {
if ((dbtype == 'mysql' || dbtype == 'mssql') && opt) {
connect.bind(this)(dbtype, opt, customGenerateKeyCB);
}
}
database.prototype.recreate = function (dbtype, opt, customGenerateKeyCB = null) {
connect.bind(this)(dbtype, opt, customGenerateKeyCB);
}
/**
* @desc: 数据库类型.
* @return: 'mysql' / 'mssql'.
*/
database.prototype.__defineGetter__("dbtype", function () {
return this._dbtype;
});
/**
* @desc: 设置执行sql的log回调. 每次执行数据库查询都将调用此方法.
* @param cb: function(err, sql) {}
*/
database.prototype.__defineSetter__("sqlLogCallback", function (cb) {
if (typeof cb !== 'function') {
throw new exception('param is not a funciton', febs.exception.PARAM, __filename, __line);
}
this.logCallback = cb;
});
database.prototype.__defineGetter__("sqlLogCallback", function () {
return this.logCallback;
});
/**
* @desc: 对likeSql进行转义操作.
* @return: string.
*/
database.prototype.escapeLike = function (likeSql) { return this.adapter.escape_like(likeSql); }
/**
* @desc: type cast, 为指定类型和值返回正确的sql值.
* @return: 传入不配对的value与type,可引发异常.
*/
database.prototype.type_cast = function (type, value) { return this.adapter.type_cast(value, type); }
/**
* @desc: 注册表格.
* @param mapName: 在数据库中真实的表名.
*/
database.prototype.registerTable = function (table, mapName = null) {
assert(table);
var tableDest = {};
copy(table).to(tableDest);
tableDest.__proto__ = table.__proto__;
tableDest._condition = new condition(this.adapter, tableDest.model);
tableDest._adapter = this.adapter;
tableDest._db = this;
this[tableDest._tablename] = tableDest;
tableDest._mapName = mapName;
return tableDest;
}
/**
* @desc: 转换查询结果中的数据,按类型转换.
* 一次查询结果只能进行一次数据转换, 转换多次会出现结果错误.
* @return:
*/
database.prototype.ret_data_cvt = function(rows, ...table) {
let ret;
let mapObj = [];
for (let i = 0; i < table.length; i++) {
ret = this.adapter.ret_data_cvt(rows, table[i], mapObj);
}
return ret;
}
/**
* @desc: 执行sql语句.
* @return: Promise.
* @resolve:
* ret - 查询结果.
*/
database.prototype.exec = function (sql) {
return this.adapter.exec(this, this.pool, sql, this._transactionConn);
}
/**
* @desc: 执行存储过程.
* @param name: procedure name.
* @param procedureParams: in,out参数; 使用 procedureParams对象.
* @return: Promise.
* @resolve:
* ret - 查询结果,out参数存储至其中.
*/
database.prototype.execProcedure = function (name, procedureParams) {
return this.adapter.execProcedure(this, this.pool, name, procedureParams, this._transactionConn);
}
/**
* @desc: transaction.
* @param isolationLevel: 事务级别.
* @param taskCB: async function(db):boolean {}; 返回false则rollback, 返回true则commit.
* @param preCB: task执行前的第一个的回调.
* @param commitCB: 提交前的回调.
* @param rollbackCB: rollback前的回调.
* @return: Promise.
* @resolve:
* ret - 是否成功提交.
*/
database.prototype.transaction = function (isolationLevel, taskCB, preCB, commitCB, rollbackCB) {
return this.adapter.transaction(this, isolationLevel, taskCB, preCB, commitCB, rollbackCB);
}
database.prototype._cloneWithConn = function (conn) {
assert(conn);
var dest = {};
copy(this).to(dest);
dest.__proto__ = this.__proto__;
dest._transactionConn = conn;
dest.customGenerateKeyCB = this.customGenerateKeyCB;
dest.pool = null;
for (let ta in dest) {
if (dest[ta] instanceof tablebase) {
dest.registerTable(dest[ta], dest[ta]._mapName);
}
}
return dest;
}
database.prototype._destroy = function () {
for (let ta in this) {
if (this[ta] instanceof tablebase) {
this[ta]._db = null;
}
delete this[ta];
}
this._transactionConn = null;
}