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.

189 lines 6.23 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const StringUtils_1 = __importDefault(require("../StringUtils")); const log4js_1 = __importDefault(require("log4js")); const DEFAULT_ROWS_PAGE = 25; const FIRST_PAGE = 1; class CommonSearchCriteria { constructor(criteria) { this.orderBy = ''; this.params = []; this.logger = log4js_1.default.getLogger(this.constructor.name); this.page = StringUtils_1.default.parseNumber(criteria === null || criteria === void 0 ? void 0 : criteria.page, FIRST_PAGE); this.rows = StringUtils_1.default.parseNumber(criteria === null || criteria === void 0 ? void 0 : criteria.rows, DEFAULT_ROWS_PAGE); this.criteria = criteria; } /** * 构建动态查询条件,子类应重写此方法 * @protected * @abstract */ buildDynamicQuery() { } /** * 查询符合条件的记录数量 * @param conn - 数据库连接对象 * @param sql - SQL查询语句 * @param params - SQL参数数组 * @private * @returns Promise返回记录总数 */ async queryCount(conn, sql, params) { let countSQL = `select count(*) as cc from (${sql}) a`; let result = await conn.find(countSQL, params); return result == null ? 0 : parseInt(result['cc']); } /** * 在将行记录转换成对象后的后处理回调函数 * @protected * @returns 后处理函数或null */ getPostConstructor() { return null; } /** * 判断值是否不为空 * @param s - 要检查的值 * @protected * @returns 如果不为空则返回true */ isNotEmpty(s) { return StringUtils_1.default.isString(s) ? !StringUtils_1.default.isEmpty(s) : s != null; } /** * 转义字符串中的%字符 * @param s - 要转义的字符串 * @protected * @returns 转义后的字符串 */ escapePercentage(s) { return s.replace(/%/g, '\\%'); } /** * 判断字符串是否包含通配符* * @param s - 要检查的字符串 * @protected * @returns 如果包含*则返回true */ includeStar(s) { return s.includes('*'); } /** * 将字符串中的*通配符替换成SQL的%通配符 * @param s - 要转换的字符串 * @protected * @returns 转换后的字符串 */ toWildSQL(s) { return s.replace(/\*/g, '%'); } /** * 替换所有的*为%通配符,先转义原有的%字符 * @param s - 要处理的字符串 * @protected * @returns 处理后的字符串 */ replaceWildStar(s) { return s.replace(/%/g, '\\%').replace(/\*/g, '%'); } /** * 构建范围查询条件(from/to范围) * @param fromValue - 起始值 * @param toValue - 结束值 * @param field - 字段名 * @protected * @returns 下一个参数的索引 */ buildRangeCriteria(fromValue, toValue, field) { let idx = this.params.length + 1; if (this.isNotEmpty(fromValue)) { this.sql += ` and ${field} >= $${idx++}`; this.params.push(fromValue); } if (this.isNotEmpty(toValue)) { this.sql += ` and ${field} < $${idx++}`; this.params.push(toValue); } return idx; } /** * 构建带通配符的查询条件(有*用LIKE,无*用等于) * @param text - 搜索文本 * @param field - 字段名 * @protected * @returns 下一个参数的索引 */ buildStarCriteria(text, field) { let idx = this.params.length + 1; if (this.isNotEmpty(text)) { if (this.includeStar(text)) { this.sql += ` and ${field} like $${idx++}`; this.params.push(this.replaceWildStar(text)); } else { this.sql += ` and ${field} = $${idx++}`; this.params.push(text); } } return idx; } /** * 构建等于条件查询 * @param value - 查询值 * @param field - 字段名 * @protected * @returns 下一个参数的索引 */ buildCriteria(value, field) { let idx = this.params.length + 1; if (this.isNotEmpty(value)) { this.sql += ` and ${field} = $${idx++}`; this.params.push(value); } return idx; } /** * 封装LIKE查询值,在字符串两端添加%通配符 * @param s - 要封装的字符串 * @protected * @returns 封装后的字符串 (%字符串%) */ wrapLikeMatch(s) { return `%${s}%`; } /** * 执行分页查询,返回分页结果 * @param conn - 数据库连接对象 */ async paginationQuery(conn) { this.buildDynamicQuery(); let count = await this.queryCount(conn, this.sql, this.params); if (count > 0) { const rows = this.rows; let pageNo = this.page; const offset = (pageNo - 1) * rows; let listSQL = `${this.sql} ${this.orderBy} ${conn.getRowSetLimitClause(rows, offset)} `; this.logger.debug(`Total matching records: ${count}, need to read ${rows} records starting from ${offset}`); let list = count > offset ? await conn.listQuery(listSQL, this.params, this.getPostConstructor()) : []; const hasMore = offset + rows < count; const pages = (Math.floor((count - 1) / rows)) + 1; return { count, hasMore, list, pages }; } else { return { count, hasMore: false, list: [], pages: 0 }; } } /** * 不分页查询,返回所有符合条件的记录 * @param conn - 数据库连接对象 * @returns Promise返回数据对象数组 */ async query(conn) { return await conn.listQuery(`${this.sql} ${this.orderBy}`, this.params); } } exports.default = CommonSearchCriteria; //# sourceMappingURL=CommonSearchCriteria.js.map