UNPKG

ts-api-core

Version:

Nodejs api framework core

386 lines 15.3 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var BaseObject_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.DataBase = exports.BaseObject = void 0; /* eslint-disable no-await-in-loop */ const _async = require("async"); const app_1 = require("../base/app"); const db_manager_1 = require("../database/db.manager"); const db_script_1 = require("../database/db.script"); const error_1 = require("../base/error"); const utils_1 = require("../utils/utils"); const request_context_1 = require("./request.context"); const ioc_decorator_1 = require("../mvc/ioc.decorator"); const dbConfigMap = new Map(); /** 扩展基础对象,包含请求上下文的数据库基础能力 */ let BaseObject = BaseObject_1 = class BaseObject extends ioc_decorator_1.BaseProvider { constructor( /** 上下文对象 */ _context) { super(); this._context = _context; } get context() { return this._context; } onFree() { } logD(data) { this.context.logD(data); } logE(data) { this.context.logE(data); } logW(data) { this.context.logW(data); } logI(data) { this.context.logI(data); } logSQL(sql, values) { return this.context.logSQL(sql, values); } /** * 初始化数据库连接 * @description 优先使用 Context 指定的数据库配置 * @returns */ initDB() { var _a, _b, _c, _d, _e; const key = this.context.dbConfig ? this.context.dbConfig : ((_a = dbConfigMap.get(this.constructor.name)) !== null && _a !== void 0 ? _a : '$'); let _db = (_b = this._db) === null || _b === void 0 ? void 0 : _b[key]; if (!_db) { const dbConfig = (_d = (_c = this.context.config) === null || _c === void 0 ? void 0 : _c.dbConfig) !== null && _d !== void 0 ? _d : (_e = app_1.App.config) === null || _e === void 0 ? void 0 : _e.dbConfig; const cfg = dbConfig ? (dbConfig instanceof Map ? dbConfig.get(key) : dbConfig) : undefined; if (cfg) { if (!this._db) { this._db = {}; } _db = new db_manager_1.DBManager(cfg); this._db[key] = _db; } else { this.err('无法连接数据库: 未指定数据库配置'); } } return _db; } /** 异步执行SQL */ asyncExecuteSQL(sql, values, execute) { return __awaiter(this, void 0, void 0, function* () { const _db = this.initDB(); const index = this.logSQL(sql, values); const time = new Date().getTime(); try { const result = yield execute(_db); return result; } finally { this.context.notifySqlExecuteFinish(index, new Date().getTime() - time); } }); } /** * 执行SQL查询 * @param sql * @param values */ query(sql, values, onRawResult) { return __awaiter(this, void 0, void 0, function* () { return this.asyncExecuteSQL(sql, values, (db) => { return db.query(sql, values, onRawResult); }); }); } /** * 执行SQL查询,返回第1行数据指定字段或第1个字段的值 * @param sql * @param values * @param fieldName 字段名称, 默认使用返回数据的第一个字段 */ queryValue(sql, values, fieldName = '', defaultValue, onRawResult) { return __awaiter(this, void 0, void 0, function* () { return this.asyncExecuteSQL(sql, values, (db) => { return db.queryValue(sql, values, fieldName, defaultValue, onRawResult); }); }); } /** * 执行SQL查询,返回指定字段的值 * @param sql * @param values * @param fieldName 字段名称,或需要的字段数量(从第1个字段开始算) */ queryValues(sql, values, fieldName, defaultValue, onRawResult) { return __awaiter(this, void 0, void 0, function* () { return this.asyncExecuteSQL(sql, values, (db) => { return db.queryValues(sql, values, fieldName, defaultValue, onRawResult); }); }); } /** * 执行SQL查询 * @param sql * @param values */ queryData(classType, sql, values, onRawResult) { return __awaiter(this, void 0, void 0, function* () { return this.asyncExecuteSQL(sql, values, (db) => { return db.queryData(classType, sql, values, onRawResult); }); }); } /** * 执行查询, 返回 Array * @param sql sql 语句 * @param values 查询参数 */ queryDatas(classType, sql, values, onRawResult) { return __awaiter(this, void 0, void 0, function* () { return this.asyncExecuteSQL(sql, values, (db) => { return db.queryDatas(classType, sql, values, onRawResult); }); }); } /** * 执行查询, 返回 [Array, Count] * @param sql sql 语句 * @param values 查询参数 * @param countSql 获取总行数的 sql (不设置会自动生成,但某些复杂或特殊情况可能会出错,比如字段列表中中带子查询等),总行数字段名 `rowCount` */ queryDatasAndCount(classType, sql, values, countSql, onRawResult) { return __awaiter(this, void 0, void 0, function* () { return this.asyncExecuteSQL(sql, values, (db) => { return db.queryDatasAndCount(classType, sql, values, countSql, onRawResult); }); }); } /** * 执行SQL语句,返回受影响的行数 * @param sql * @param values * @returns 返回值 < 0 说明更新失败, = 0 说明没有更改任何数据 */ executeSql(sql, values, onRawResult) { return __awaiter(this, void 0, void 0, function* () { return this.asyncExecuteSQL(sql, values, (db) => { return db.execute(sql, values, onRawResult); }); }); } /** * 执行SQL插入语句,返回插入成功后的主键ID * @param sql * @param values 插入失败返回 `undefined` */ insert(sql, values, onRawResult) { return __awaiter(this, void 0, void 0, function* () { return this.asyncExecuteSQL(sql, values, (db) => { return db.insert(sql, values, onRawResult); }); }); } /** * 更新数据 * @param target 数据对象类 * @param entity 数据 entity * @param options 选项 * @returns */ updateData(target, entity, options) { return __awaiter(this, void 0, void 0, function* () { const script = db_script_1.DBScript.insertUpdate(target, entity, options); return script ? (yield this.executeSql(script.sql, script.params, options === null || options === void 0 ? void 0 : options.onRawResult)) > 0 : false; }); } /** * 开启事务,在回调中执行 query ,出错自动回滚,正确执行时自动提交事务 * @param callback 事务开始后,在这个回调中执行query * @param onFinish 事务执行完成回调 */ transaction(callback, onFinish) { return __awaiter(this, void 0, void 0, function* () { return this.initDB().transaction(callback, (value, useTime, flag) => { if (flag) this.context.notifySqlTransactionFinish(useTime); if (onFinish) { onFinish(value, useTime, flag); } }); }); } /** * 生成分页需要的 Limit 条件 SQL 语句 * @param pageIndex 页码,从1开始 * @param pageSize 分页大小 */ static limit(pageIndex, pageSize) { return db_script_1.DBScript.limit(pageIndex, pageSize); } /** * 将字符串数组转化为 SQL 语句 IN 的可选值字符串 * @param ids 字符串数组 * @returns ` ('n','n1','n2',...) ` */ static tranArrayToInSql(ids) { return db_script_1.DBScript.tranArrayToInSql(ids); } /** 抛出异常 */ err(msg, action, code) { throw new error_1.SysError(msg, action, code); } /** * Promise包裹器,出错会抛出异常 * @param promise Promise * @param action 动作名称 * @param errLog 是否输出错误日志,默认 `false`。不输是否输出异常日志,出错时都会抛出错误 * @param retryCount 执行失败时重试次数,默认 `0` * @param retryDelay 执行失败时,重试延时时间(ms),默认 `100` ms * @returns 执行成功时返回 Promise 的返回值 */ execute(promise, action = "", errLog = false, retryCount = 0, retryDelay = 100) { return __awaiter(this, void 0, void 0, function* () { let result = yield this.executeSilence(promise, errLog, retryCount, retryDelay); if (result[0] || result[1] === undefined) { this.err(`${action}异常: ${result[0] ? result[0].message : '返回值为空'}`); } return result[1]; }); } /** * 安静的Promise包裹器 * @param promise Promise * @param errLog 是否输出错误日志,默认 `false` * @param retryCount 执行失败时重试次数,默认 `0` * @param retryDelay 执行失败时,重试延时时间(ms),默认 `100` ms * @returns 执行成功时返回 Promise 的返回值 */ executeSilence(promise, errLog = false, retryCount = 0, retryDelay = 100) { return __awaiter(this, void 0, void 0, function* () { let i = 0; let result = [undefined, undefined]; do { result = yield BaseObject_1.executeSilence(promise, errLog ? this.context : undefined); if (result[0] || result[1] === undefined) { i = i + 1; if (retryDelay > 0) { yield utils_1.Utils.sleep(retryDelay); } } else { return result; } } while (i < retryCount); return result; }); } /** * 安静的Promise包裹器 * @param promise Promise * @param context 上下文对象,输出错误日志必须 * @param errLog 是否输出错误日志,默认 `false` * @returns */ static executeSilence(promise, context, errLog = true) { return __awaiter(this, void 0, void 0, function* () { // @ts-expect-error return promise .then((data) => { return [undefined, data]; }) .catch((err) => { if (context && errLog === true) { context.logE(err.message); } return [err, undefined]; }); }); } /** * 并行执行异步任务 * 某步出错不影响其他步骤执行 * 程序执行时间为最长的那个时间 * @param promises Promise 数组 * @param context 上下文对象(需要输出错误日志时必传) * @param errLog 是否输入错误日志,默认 `true` * @returns * @author yangyxd */ static executeParaller(promises, context, errLog = true) { return __awaiter(this, void 0, void 0, function* () { if (promises.length === 0) { return [undefined, undefined]; } const _tasks = new Array(promises.length); // eslint-disable-next-line no-plusplus for (let i = 0; i < promises.length; i++) { const _p = promises[i]; _tasks[i] = (cb) => { if (_p === undefined) { cb(undefined, undefined); } else { _p.then((data) => { cb(undefined, data); }).catch((err) => { if (context && errLog === true) { context.logE(err.message); } cb(err, undefined); }); } }; } let _result; let _err; _async.parallel(_tasks, (err, result) => { _result = result; _err = err; }); try { yield Promise.all(promises); } catch (e) { _err = e; if (context && errLog === true) { context.logE(_err.message); } } return [_err, _result]; }); } }; BaseObject = BaseObject_1 = __decorate([ (0, ioc_decorator_1.BaseClass)(), __metadata("design:paramtypes", [request_context_1.RequestContext]) ], BaseObject); exports.BaseObject = BaseObject; /** 数据库定义, 多个数据库连接配置时,指定当前对象默认数据库配置 Key */ function DataBase(dbConfigKey) { return function (target) { dbConfigMap.set(dbConfigKey, target.name); }; } exports.DataBase = DataBase; //# sourceMappingURL=base.object.js.map