ts-api-core
Version:
Nodejs api framework core
386 lines • 15.3 kB
JavaScript
"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