@ticatec/node-common-library
Version:
A comprehensive Node.js database access framework providing robust abstractions for database connection management, SQL execution, transaction handling, pagination, and dynamic query building.
211 lines • 6.73 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const log4js_1 = __importDefault(require("log4js"));
class DBConnection {
constructor() {
this.logger = log4js_1.default.getLogger("SQL");
}
/**
* 获取count数,默认属性是cc
* @param data
* @param key
* @protected
*/
getCount(data, key = 'cc') {
let s = data == null ? null : data[key];
return s == null ? 0 : parseInt(s);
}
/**
* 执行count语句,返回count值
* @param sql - 要执行的count SQL语句
* @param params - SQL参数数组
* @param key - 计数字段的键名,默认为'cc'
* @protected
* @returns Promise返回计数值
*/
async executeCountSQL(sql, params, key = 'cc') {
return this.getCount(await this.find(sql, params), key);
}
/**
*
* @param sql
* @param params
* @param pageNo
* @param rowCount
* @protected
*/
async quickSearch(sql, params = [], pageNo = 1, rowCount = 25) {
pageNo = pageNo < 1 ? 1 : pageNo;
let offset = (pageNo - 1) * rowCount;
let count = await this.executeCountSQL(`select count(*) as cc from (${sql}) a`, params);
if (count > 0 && offset < count) {
let list = await this.listQuery(`${sql} ${this.getRowSetLimitClause(rowCount, offset)}`, params);
return {
list,
hasMore: list.length < count
};
}
else {
return {
list: [],
hasMore: false
};
}
}
/**
* 执行select查询语句,返回数据列表
* @param sql
* @param params
* @param postConstruction
*/
async listQuery(sql, params = null, postConstruction = null) {
let result = await this.fetchData(sql, params);
let list = this.resultToList(result);
if (postConstruction) {
list.forEach(data => postConstruction(data));
}
return list;
}
/**
* 查询单条记录,如果有多条,返回第一条
* @param sql
* @param params
* @param postConstruction
*/
async find(sql, params = null, postConstruction = null) {
let result = await this.fetchData(sql, params);
let row = this.getFirstRow(result);
if (row && postConstruction) {
postConstruction(row);
}
return row;
}
/**
* 处理SQL文件,去除注释行,分割sql语句
* @param file
* @private
*/
loadAndSplitSQL(file) {
let sql = fs_1.default.readFileSync(file, 'utf8');
// 去除多行注释 /* ... */
sql = sql.replace(/\/\*[\s\S]*?\*\//g, '');
// 去除单行注释 -- ... 和 // ...
sql = sql.replace(/--.*$/gm, '');
sql = sql.replace(/\/\/.*$/gm, '');
// 按 ; 分割(适用于简单语句,不解析字符串中的 ;)
return sql
.split(/;\s*[\r\n]+|;\s*$/) // 按换行或文件结尾的分号切分
.map(stmt => stmt.trim())
.filter(stmt => stmt.length > 0);
}
/**
* 执行一个SQL文件,去除注释并分割SQL语句执行
* @param file - SQL文件路径
* @returns Promise返回是否有错误发生
*/
async executeSQLFile(file) {
let hasError = false;
const sqlStatements = this.loadAndSplitSQL(file);
for (const statement of sqlStatements) {
try {
this.logger.debug('execute sql statement: ', statement);
await this.executeSQL(statement);
}
catch (error) {
hasError = true;
this.logger.error('execute sql statement with error.', error);
}
}
return hasError;
}
/**
* 执行分页查询,按照分页条件返回分页结果
* @param criteria - 分页查询条件对象
* @returns Promise返回分页结果列表
*/
async executePaginationSQL(criteria) {
return criteria.paginationQuery(this);
}
/**
* 根据条件查询返回所有符合条件的结果,忽略分页
* @param criteria - 查询条件对象
* @returns Promise返回所有符合条件的数据数组
*/
async queryByCriteria(criteria) {
return criteria.query(this);
}
/**
* 下划线命名转换为驼峰命名
* @param name - 要转换的字段名
* @protected
* @returns 转换后的驼峰命名字符串
*/
toCamel(name) {
return name.replace(/\_(\w)/g, (all, letter) => {
return letter.toUpperCase();
});
}
/**
* 构建字段对应列表
* @param fields - 字段信息数组
* @protected
* @returns 字段映射Map对象
*/
buildFieldsMap(fields) {
return null;
}
/**
* 设置嵌套对象的属性值
* @param obj - 目标对象
* @param field - 字段名(支持点分隔的嵌套字段)
* @param value - 要设置的值
* @protected
*/
setNestObj(obj, field, value) {
var _a;
if (value != null) {
let attrs = field.split('.');
let attr = this.toCamel(attrs[0]);
let nestObj = obj;
for (let i = 0; i < attrs.length - 1; i++) {
nestObj[attr] = (_a = nestObj[attr]) !== null && _a !== void 0 ? _a : {};
nestObj = nestObj[attr];
attr = this.toCamel(attrs[i + 1]);
}
nestObj[attr] = value;
}
}
/**
* 将返回的多行数据转换成数组对象
* @param result - 查询结果对象
* @protected
* @returns 转换后的数据对象数组
*/
resultToList(result) {
let list = [];
let fields = this.buildFieldsMap(result.fields);
result.rows.forEach(row => {
let obj = {};
fields.forEach((value, key) => {
this.setNestObj(obj, value, row[key]);
});
list.push(obj);
});
return list;
}
/**
* 返回设定结果集大小的限制语句
* @param rowCount - 行数限制
* @param offset - 偏移量
* @returns LIMIT和OFFSET语句字符串
*/
getRowSetLimitClause(rowCount, offset) {
return ` limit ${rowCount} offset ${offset}`;
}
}
exports.default = DBConnection;
//# sourceMappingURL=DBConnection.js.map
;