UNPKG

febs-db

Version:
306 lines (278 loc) 9.01 kB
'use strict'; /** * Copyright (c) 2015 Copyright citongs All Rights Reserved. * Author: lipengxiang * Desc: */ const febs = require('febs'); const assert = require('assert'); const exception = require('./exception'); const TYPES = require('./dataType'); const condition = require('./condition'); const join = require('./utils/join'); module.exports = tablebase; /** * @param idKeyName: 主键. 单主键时为主键名, 多主键时为主键名数组. * @param tablename: 本表名. * @param model: 本表模型. */ function init(tablename, idKeyName, model) { this._tablename = tablename; this._model = model; this._modelMap = {}; for (var key in this._model) { if (!this._model[key].hasOwnProperty('map')) { this._model[key].map = key; } this._modelMap[this._model[key].map] = key; } if (__debug) { let map = {}; for (var key in this._model) { if (map.hasOwnProperty(this._model[key].map)) throw new exception('the map is duplication, ' + this._model[key].map + ' in table ' + tablename, exception.DB_CommonException, __filename, __line); map[key] = true; } } this._idKeyName = idKeyName; this._idKeyIsCombined = (idKeyName instanceof Array); if (this._idKeyIsCombined) { this._idKeyNameMap = []; for (let i = 0; i < this._idKeyName.length; i++) { let kk = this._model[this._idKeyName[i]]; kk.isPrimary = true; this._idKeyNameMap.push(kk.map); if (kk.key === true && TYPES.isIntegerType(kk.type)) { this._idKeyNameAutoInc = this._idKeyName[i]; } } } else { let kk = this._model[this._idKeyName]; this._idKeyNameMap = kk.map; kk.isPrimary = true; if (kk.key === true && TYPES.isIntegerType(kk.type)) { this._idKeyNameAutoInc = this._idKeyName; } } } function tablebase(tablename, idKeyName, model) { if (tablename) { init.bind(this)(tablename, idKeyName, model); } } /** * @param idKeyName: 主键. 单主键时为主键名, 多主键时为主键名数组. * @param tablename: 本表名. * @param model: 本表模型. */ tablebase.prototype.init = function (tablename, idKeyName, model) { init.bind(this)(tablename, idKeyName, model); } /** * @desc: add * (insertId will set to item.id) * @return: Promise. * @resolve: * ret - boolean. */ tablebase.prototype.add = function (item) { return this.adapter.add(this, item); } /** * @desc: 返回sql add. * @return: string */ tablebase.prototype.sql_add = function (item) { return this.adapter.sql_add(this, item); } /** * @desc: remove * @return: Promise. * @resolve: * ret - boolean. */ tablebase.prototype.remove = function (where) { if (typeof where === 'object') { let keys = Object.keys(where); let whereStr = ''; for (let key of keys) { if (whereStr.length > 0) { whereStr += 'AND'; } whereStr += this._condition.equal(key, where[key]); } where = whereStr; } return this.adapter.remove(this, where); } /** * @desc: 返回sql remove. * @return: string */ tablebase.prototype.sql_remove = function (where) { return this.adapter.sql_add(this, where); } /** * @desc: update data. * if item.id is existed, sql condition is: 'id=value' AND (where) * otherwise sql condition is: where * @param item, where. * @return: Promise. * @resolve: * ret - boolean. */ tablebase.prototype.update = function (item, where = null) { if (where && typeof where === 'object') { let keys = Object.keys(where); let whereStr = ''; for (let key of keys) { if (whereStr.length > 0) { whereStr += 'AND'; } whereStr += this._condition.equal(key, where[key]); } where = whereStr; } return this.adapter.update(this, item, where); } /** * @desc: 返回sql remove. * @return: string */ tablebase.prototype.sql_update = function (item, where = null) { return this.adapter.sql_update(this, item, where); } /** * @desc: select by id and lock row for update (use in transaction). * id is Object if table is combined primary. * @param id: 主鍵值. * @param cols: * 需要查询出的字段名称数组, 例如:[col1, col2, ...]. * @return: Promise. * @resolve: * ret - mod. */ tablebase.prototype.selectLockRow = function(id, cols = null) { return this.adapter.selectLockRow(this, id, cols); } /** * @desc: 返回sql selectLockRow. * @return: string */ tablebase.prototype.sql_selectLockRow = function (id, cols = null, alias=null) { return this.adapter.sql_selectLockRow(this, id, cols, alias); } /** * @desc: select. * sql的连接顺序为: SELECT cols FROM table where groupSql orderby pageInfo. * * @param where: * 查询条件,不会对此字符串验证. 使用 condition 对象进行构建. * @param opt: 查询选项. 可以包含以下键值. * - cols: 需要查询出的字段名称数组; 例如: [col1, col2, ...]; 不指定则为查询全部. * - groupSql: group by子句, 不会对内容进行验证; 应包含group by关键字. * - orderby: orderby by子句, 例如: {key:true/false} true-means asc, false-means desc.. * - offset: 分页查询起始位置. * - limit: 分页查询查询行数. * @return: Promise. * @resolve: * ret - mod array. */ tablebase.prototype.select = function (where, opt = null) { if (where && typeof where === 'object') { let keys = Object.keys(where); let whereStr = ''; for (let key of keys) { if (whereStr.length > 0) { whereStr += 'AND'; } whereStr += this._condition.equal(key, where[key]); } where = whereStr; } return this.adapter.select(this, where, opt); } /** * @desc: 返回sql select. * @return: string */ tablebase.prototype.sql_select = function (where, opt = null, alias=null) { opt = opt || {}; let query_cols = opt.cols; let groupSql = opt.groupSql; let orderby = opt.orderby; let pageinfo = {offset:opt.offset, limit:opt.limit}; return this.adapter.sql_select(this, where, query_cols, groupSql, orderby, pageinfo, alias); } /** * @desc: count * @param: where * @return: Promise. * @resolve: * ret - number. */ tablebase.prototype.count = function (where = null) { if (where && typeof where === 'object') { let keys = Object.keys(where); let whereStr = ''; for (let key of keys) { if (whereStr.length > 0) { whereStr += 'AND'; } whereStr += this._condition.equal(key, where[key]); } where = whereStr; } return this.adapter.count(this, where); } /** * @desc: 返回sql count. * @return: string */ tablebase.prototype.sql_count = function (where, alias=null) { return this.adapter.sql_count(this, where, alias); } /** * @desc: exist * id is Object if table is combined primary. * @return: Promise. * @resolve: * ret - boolean. */ tablebase.prototype.exist = function(id) { return this.adapter.exist(this, id); } /** * @desc: 返回join对象. */ tablebase.prototype.join_inner = function(tableB) { return new join('INNER JOIN', this.adapter, this, tableB); } tablebase.prototype.join_cross = function(tableB) { return new join('CROSS JOIN', this.adapter, this, tableB); } tablebase.prototype.join_left = function(tableB) { return new join('LEFT OUTER JOIN', this.adapter, this, tableB); } tablebase.prototype.join_right = function(tableB) { return new join('RIGHT OUTER JOIN', this.adapter, this, tableB); } tablebase.prototype.join_full = function(tableB) { return new join('FULL OUTER JOIN', this.adapter, this, tableB); } /** * @desc: 使用字段的映射名称获得字段的逻辑名称. * @return: string; 找不到返回undefined. */ tablebase.prototype.getLogicColName = function(mapName) { return this._modelMap[mapName]; } /** * @desc: 使用字段的model名称获得字段的映射名称(真实名称). * @return: string; 找不到返回undefined. */ tablebase.prototype.getRealColName = function(colName) { return this._model[colName].map; } /** * @desc: 条件构造对象,使用此对象可以在类型安全的情况下构造查询条件. * @return: */ tablebase.prototype.__defineGetter__("condition", function () { return this._condition; }); /** * @desc: 真實的表名称. * @return: string. */ tablebase.prototype.__defineGetter__("tablename", function () { let nm = this._mapName || this._tablename; return this._db.opt.table_prefix ? this._db.opt.table_prefix + nm : nm; }); tablebase.prototype.__defineGetter__("model", function () { return this._model; }); tablebase.prototype.__defineGetter__("idKeyName", function () { return this._idKeyName; }); tablebase.prototype.__defineGetter__("adapter", function () { return this._adapter; }); tablebase.prototype.__defineGetter__("idKeyIsCombined", function () { return this._idKeyIsCombined; }); tablebase.prototype.__defineGetter__("idKeyNameAutoInc", function () { return this._idKeyNameAutoInc; }); tablebase.prototype.__defineGetter__("db", function () { return this._db; });