UNPKG

imsdk-server-core

Version:

轻量级Web服务器框架、WebSocket服务器框架。采用Typescript编写,简单易用。

420 lines (419 loc) 16.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MongoMan = void 0; /** * 对node-mongodb-native封装的类 * node-mongodb-native相关信息:http://mongodb.github.io/node-mongodb-native/ */ const mongodb_1 = require("mongodb"); class MongoMan { /** * @param context 上下文包装类实例 * @param category 日志分类 * @param config 配置信息 */ constructor(context, category, config = {}) { this._context = context; this._config = config; //绑定log4js实例 this._logger = context.getLogger(category); //mongo相关引用 this._client = null; //客户端实例 this._db = null; //数据库实例 } /** * 建立数据库连接 */ async connect() { try { this._client = new mongodb_1.MongoClient(this._config.url, this._config.urlOptions); await this._client.connect(); this._db = this._client.db(this._config.db, this._config.dbOptions); this._logger.info(this._config.url, this._config.db, 'was connected.'); } catch (e) { this._logger.error(this._config.url, this._config.db, 'connect error,', e); } } /** * 关闭数据库连接 * @param force */ async close(force = false) { try { if (this._client) { await this._client.close(force); this._client = null; this._db = null; } this._logger.info(this._config.url, this._config.db, 'was closed.'); } catch (e) { this._logger.error(this._config.url, this._config.db, 'close error,', e); } } /** * 插入单条记录 * @param table * @param doc * @param insertOptions * @param tableOptions * @returns 当返回值<0:操作失败。当返回值>=0:操作成功的数量 */ async insertOne(table, doc, insertOptions, tableOptions) { try { const result = await this._db.collection(table, tableOptions).insertOne(doc, insertOptions); this._logger.debug(this._config.url, this._config.db, 'insertOne', ...arguments, result.insertedCount); return result.insertedCount; } catch (e) { this._logger.error(this._config.url, this._config.db, 'insertOne', ...arguments, e); return -1; } } /** * 插入多条记录 * @param table * @param docs * @param insertOptions * @param tableOptions * @returns 当返回值<0:操作失败。当返回值>=0:操作成功的数量 */ async insertMany(table, docs, insertOptions, tableOptions) { try { const result = await this._db.collection(table, tableOptions).insertMany(docs, insertOptions); this._logger.debug(this._config.url, this._config.db, 'insertMany', ...arguments, result.insertedCount); return result.insertedCount; } catch (e) { this._logger.error(this._config.url, this._config.db, 'insertMany', ...arguments, e); return -1; } } /** * 查找单条记录 * @param table * @param query * @param findOptions * @param tableOptions * @returns 当返回值为null:操作失败。 */ async findOne(table, query, findOptions, tableOptions) { try { const result = await this._db.collection(table, tableOptions).findOne(query, findOptions); this._logger.debug(this._config.url, this._config.db, 'findOne', ...arguments, result); return result; } catch (e) { this._logger.error(this._config.url, this._config.db, 'findOne', ...arguments, e); return null; } } /** * 查找多条记录 * @param table * @param query * @param join * @param findOptions * @param tableOptions * @returns 当返回值为null:操作失败。 */ async findMany(table, query, join, findOptions, tableOptions) { try { const result = await this._db.collection(table, tableOptions).find(query, findOptions).toArray(); if (result.length > 0 && join) { //模拟单表左外连接 let equalsId = false; join.query = join.query || {}; if (join.orExp) { //使用$or查询 join.query.$or = []; for (let i = 0; i < result.length; i++) { const param = {}; param[join.toField] = result[i][join.fromField]; equalsId = typeof param[join.toField] === 'object'; join.query.$or.push(param); } } else { //使用$in查询 const toInValues = { $in: [] }; for (let i = 0; i < result.length; i++) { const fromValue = result[i][join.fromField]; equalsId = typeof fromValue === 'object'; toInValues.$in.push(fromValue); } join.query[join.toField] = toInValues; } const joinResult = await this._db.collection(join.table, join.tableOptions).find(join.query, join.findOptions).toArray(); for (let i = 0; i < result.length; i++) { const doc = result[i]; const fromValue = doc[join.fromField]; doc[join.resField] = join.onlyOne ? {} : []; for (let k = 0; k < joinResult.length; k++) { const item = joinResult[k]; if ((equalsId && fromValue && fromValue.equals(item[join.toField])) || (!equalsId && fromValue === item[join.toField])) { if (join.onlyOne) { doc[join.resField] = item; break; } else { doc[join.resField].push(item); } } } } } this._logger.debug(this._config.url, this._config.db, 'findMany', ...arguments, result); return result; } catch (e) { this._logger.error(this._config.url, this._config.db, 'findMany', ...arguments, e); return null; } } /** * 更新单条记录 * @param table * @param filter * @param update * @param updateOptions * @param tableOptions * @returns 当返回值<0:操作失败。当返回值>=0:操作成功的数量 */ async updateOne(table, filter, update, updateOptions, tableOptions) { try { const result = await this._db.collection(table, tableOptions).updateOne(filter, update, updateOptions); this._logger.debug(this._config.url, this._config.db, 'updateOne', ...arguments, result.modifiedCount, result.matchedCount, result.upsertedCount); return result.modifiedCount || result.matchedCount || result.upsertedCount; } catch (e) { this._logger.error(this._config.url, this._config.db, 'updateOne', ...arguments, e); return -1; } } /** * 更新多条记录 * @param table * @param filter * @param update * @param updateOptions * @param tableOptions * @returns 当返回值<0:操作失败。当返回值>=0:操作成功的数量 */ async updateMany(table, filter, update, updateOptions, tableOptions) { try { const result = await this._db.collection(table, tableOptions).updateMany(filter, update, updateOptions); this._logger.debug(this._config.url, this._config.db, 'updateMany', ...arguments, result.modifiedCount, result.matchedCount, result.upsertedCount); return result.modifiedCount || result.matchedCount || result.upsertedCount; } catch (e) { this._logger.error(this._config.url, this._config.db, 'updateMany', ...arguments, e); return -1; } } /** * 删除单条记录 * @param table * @param filter * @param deleteOptions * @param tableOptions * @returns 当返回值<0:操作失败。当返回值>=0:操作成功的数量 */ async deleteOne(table, filter, deleteOptions, tableOptions) { try { const result = await this._db.collection(table, tableOptions).deleteOne(filter, deleteOptions); this._logger.debug(this._config.url, this._config.db, 'deleteOne', ...arguments, result.deletedCount); return result.deletedCount; } catch (e) { this._logger.error(this._config.url, this._config.db, 'deleteOne', ...arguments, e); return -1; } } /** * 删除多条记录 * @param table * @param filter * @param deleteOptions * @param tableOptions * @returns 当返回值<0:操作失败。当返回值>=0:操作成功的数量 */ async deleteMany(table, filter, deleteOptions, tableOptions) { try { const result = await this._db.collection(table, tableOptions).deleteMany(filter, deleteOptions); this._logger.debug(this._config.url, this._config.db, 'deleteMany', ...arguments, result.deletedCount); return result.deletedCount; } catch (e) { this._logger.error(this._config.url, this._config.db, 'deleteMany', ...arguments, e); return -1; } } /** * 查询记录数量 * @param table * @param query * @param countOptions * @param tableOptions * @returns 当返回值<0:操作失败。当返回值>=0:操作成功的数量 */ async countDocuments(table, query, countOptions, tableOptions) { try { const result = await this._db.collection(table, tableOptions).countDocuments(query, countOptions); this._logger.debug(this._config.url, this._config.db, 'countDocuments', ...arguments, result); return result; } catch (e) { this._logger.error(this._config.url, this._config.db, 'countDocuments', ...arguments, e); return -1; } } /** * 这个是原子操作 * @param table * @param filter * @param update * @param findUpdateOptions * @param tableOptions * @returns 当返回值为null:操作失败。 */ async findOneAndUpdate(table, filter, update, findUpdateOptions, tableOptions) { try { const result = await this._db.collection(table, tableOptions).findOneAndUpdate(filter, update, findUpdateOptions); this._logger.debug(this._config.url, this._config.db, 'findOneAndUpdate', ...arguments, result.value); return result.value; } catch (e) { this._logger.error(this._config.url, this._config.db, 'findOneAndUpdate', ...arguments, e); return null; } } /** * 这个是原子操作 * @param table * @param filter * @param findDeleteOptions * @param tableOptions * @returns 当返回值为null:操作失败。 */ async findOneAndDelete(table, filter, findDeleteOptions, tableOptions) { try { const result = await this._db.collection(table, tableOptions).findOneAndDelete(filter, findDeleteOptions); this._logger.debug(this._config.url, this._config.db, 'findOneAndDelete', ...arguments, result.value); return result.value; } catch (e) { this._logger.error(this._config.url, this._config.db, 'findOneAndDelete', ...arguments, e); return null; } } /** * 聚合操作 * @param table * @param aggregatePipeline * @param aggregateOptions * @param tableOptions * @returns 当返回值为null:操作失败。 */ async aggregate(table, aggregatePipeline, aggregateOptions, tableOptions) { try { const result = await this._db.collection(table, tableOptions).aggregate(aggregatePipeline, aggregateOptions).toArray(); this._logger.debug(this._config.url, this._config.db, 'aggregate', ...arguments, result); return result; } catch (e) { this._logger.error(this._config.url, this._config.db, 'aggregate', ...arguments, e); return null; } } /** * 使用withTransaction函数来进行事务操作 * 官方解释:Use withTransaction to start a transaction, execute the callback, and commit (or abort on error) * Note: The callback for withTransaction MUST be async and/or return a Promise. * Important: You must pass the session to the operations * @param callback 未抛出异常则提交事务,抛出异常则回滚事务,务必将回调参数session传入数据库操作中 * @param sessionOptions * @param transactionOptions * @returns 当返回值为null:操作成功。当返回值为string:操作失败的描述。 */ async withTransaction(callback, sessionOptions, transactionOptions) { const session = this._client.startSession(sessionOptions); this._logger.debug(this._config.url, this._config.db, 'withTransaction -> startSession', ...arguments); let errmsg = null; try { this._logger.debug(this._config.url, this._config.db, 'withTransaction -> withTransaction', ...arguments); await session.withTransaction(callback, transactionOptions); } catch (e) { errmsg = e.message; this._logger.error(this._config.url, this._config.db, 'withTransaction -> catchError', ...arguments, e); } finally { session.endSession(); this._logger.debug(this._config.url, this._config.db, 'withTransaction -> endSession', ...arguments); } return errmsg; } /** * 使用startTransaction、commitTransaction、abortTransaction函数来进行事务操作 * @param callback 未抛出异常则提交事务,抛出异常则回滚事务,务必将回调参数session传入数据库操作中 * @param sessionOptions * @param transactionOptions * @returns 当返回值为null:操作成功。当返回值为string:操作失败的描述。 */ async handTransaction(callback, sessionOptions, transactionOptions) { const session = this._client.startSession(sessionOptions); this._logger.debug(this._config.url, this._config.db, 'handTransaction -> startSession', ...arguments); let errmsg = null; try { session.startTransaction(transactionOptions); this._logger.debug(this._config.url, this._config.db, 'handTransaction -> startTransaction', ...arguments); await callback(session); await session.commitTransaction(); this._logger.debug(this._config.url, this._config.db, 'handTransaction -> commitTransaction', ...arguments); } catch (e) { errmsg = e.message; await session.abortTransaction(); this._logger.error(this._config.url, this._config.db, 'handTransaction -> abortTransaction', ...arguments, e); } finally { session.endSession(); this._logger.debug(this._config.url, this._config.db, 'handTransaction -> endSession', ...arguments); } return errmsg; } /** * 获取可操作的集合 * @param table * @param tableOptions */ collection(table, tableOptions) { return this._db.collection(table, tableOptions); } /** * 创建ObjectId */ createObjectId() { return new mongodb_1.ObjectId(); } /** * 16进制转ObjectId * @param hexstr */ hexstr2ObjectId(hexstr) { try { return mongodb_1.ObjectId.createFromHexString(hexstr); } catch (e) { return mongodb_1.ObjectId.createFromHexString('000000000000000000000000'); } } get context() { return this._context; } get client() { return this._client; } ; get db() { return this._db; } ; } exports.MongoMan = MongoMan;