UNPKG

@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
"use strict"; 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