action.js 7.29 KB
import { MongoClient, FilterQuery, UpdateQuery, FindAndModifyWriteOpResultObject, OptionalId, ClientSession ,DeleteWriteOpResultObject ,UpdateWriteOpResult} from 'mongodb';
import config from "./config_db";
import logger from "../../logger/logger";
import appConfig from "../../../config/app_config";

/**
 * @type {MongoClient}
 */
var mongo = null;

const TAG = "[ConnectMongo] "

async function openConnection() {
  try {
    mongo = await MongoClient.connect(config.DB_CONNECT_STR, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      poolSize: appConfig.config.db_connection_pool_size
    });
    logger.info(`${TAG}::::::::::::::: Mongo DB is connected ::::::::::::::::`);
  } catch (error) {
    logger.error(`${TAG}::::::::::::::: Cannot connect to Mongo DB ::::::::::::::::\n${error}`);
  }
}
/**
 * Select * From
 * @param {String} collectionName 
 * @param {*} queryCondition 
 * @param {Object} filter
 * @returns {Promise<Array>}
 */
async function find(collectionName, queryCondition = {}, filter = {}) {
  try {
    if (mongo === null || !mongo.isConnected()) await openConnection();

    const dbo = mongo.db(config.DB_NAME);
    const resultObject = await dbo.collection(collectionName)
      .find(queryCondition, { projection: { ...filter } })
      .toArray();

    logger.db("Find data from " + collectionName + " Success.");

    return resultObject;

  } catch (error) {
    // logger.error("Find data from " + collectionName + " Failed.");
    // logger.error("Error : ", error);
    throw error;
  }
}
/**
 * Select * From Where Only One Data
 * @param {String} collectionName 
 * @param {*} queryCondition 
 */
async function findOne(collectionName, queryCondition = {}) {
  try {
    if (mongo === null || !mongo.isConnected()) await openConnection();

    const dbo = mongo.db(config.DB_NAME);
    const resultObject = await dbo.collection(collectionName)
      .findOne(queryCondition, { projection: { _id: 0 } })

    logger.db("Find data from " + collectionName + " Success.");

    return resultObject;

  } catch (error) {
    // logger.error("Find data from " + collectionName + " Failed.");
    // logger.error("Error : ", error);
    throw error;
  }
}
/**
 * Insert One Data
 * @param {String} collectionName 
 * @param {OptionalId<Object>} data 
 * @param {ClientSession} session
 */
async function insertOne(collectionName, data = {}, session = undefined) {
  try {
    if (mongo === null || !mongo.isConnected()) await openConnection();

    const dbo = mongo.db(config.DB_NAME);
    const resultObject = await dbo.collection(collectionName).insertOne(data, {session});

    logger.db("Insert data to " + collectionName + " Success.");

    return resultObject;

  } catch (error) {
    // logger.error("Insert data to " + collectionName + " Failed.");
    // logger.error("Error : ", error);
    throw error;
  }
}
/**
 * Update Data
 * @param {String} collectionName 
 * @param {FilterQuery<Object>} queryCondition 
 * @param {*} updateValue 
 * @param {ClientSession} session
 * @return {UpdateWriteOpResult}
 */
async function updateOne(collectionName, queryCondition = {}, updateValue = {}, session = undefined) {
  try {
    if (mongo === null || !mongo.isConnected()) await openConnection();

    const dbo = mongo.db(config.DB_NAME);
    const resultObject = await dbo.collection(collectionName).updateOne(queryCondition, updateValue, {session});

    logger.db("Update data to " + collectionName + " Success.");

    return resultObject;

  } catch (error) {
    // logger.error("Update data to " + collectionName + " Failed.");
    // logger.error("Error : ", error);
    throw error;
  }
}

/**
 * Update Many Data
 * @param {String} collectionName 
 * @param {*} queryCondition 
 * @param {*} updateValue 
 * @param {ClientSession} session
 */
async function updateMany(collectionName, queryCondition = {}, updateValue = {}, session = undefined) {
  try {
    if (mongo === null || !mongo.isConnected()) await openConnection();

    const dbo = mongo.db(config.DB_NAME);
    const resultObject = await dbo.collection(collectionName).updateMany(queryCondition, updateValue, {session});

    logger.db("Update data to " + collectionName + " Success.");

    return resultObject;

  } catch (error) {
    // logger.error("Update data to " + collectionName + " Failed.");
    // logger.error("Error : ", error);
    throw error;
  }
}
/**
 * Delete From
 * @param {String} collectionName 
 * @param {*} queryCondition 
 * @param {ClientSession} session
 * @return {DeleteWriteOpResultObject}
 */
async function deleteMany(collectionName, queryCondition, session = undefined) {
  try {
    if (mongo === null || !mongo.isConnected()) await openConnection();

    const dbo = mongo.db(config.DB_NAME);
    const resultObject = await dbo.collection(collectionName).deleteMany(queryCondition, {session});

    logger.db("Delete data from " + collectionName + " Success.");

    return resultObject;

  } catch (error) {
    // logger.error("Delete data from " + collectionName + " Failed.");
    // logger.error("Error : ", error);
    throw error;
  }
}

/**
* @description Find a document and update it in one atomic operation. Requires a write lock for the duration of the operation.
* http://mongodb.github.io/node-mongodb-native/3.3/api/Collection.html#findOneAndUpdate
* @param {String} collectionName 
* @param {FilterQuery<Object>} queryCondition 
* @param {UpdateQuery<Object>} updateValue 
* @param {ClientSession} session
* 
* @returns {FindAndModifyWriteOpResultObject<Object>}
*/
async function findOneAndUpdate(collectionName, queryCondition = {}, updateValue = {}, session = undefined) {
  try {
    if (mongo === null || !mongo.isConnected()) await openConnection();

    const dbo = mongo.db(config.DB_NAME);
    const resultObject = await dbo.collection(collectionName).findOneAndUpdate(queryCondition, updateValue, {session})

    logger.db("Update data to " + collectionName + " Success.");

    return resultObject;

  } catch (error) {
    // logger.error("Update data to " + collectionName + " Failed.");
    // logger.error("Error : ", error);
    throw error;
  }
}



/**
 * Select * From
 * @param {String} collectionName 
 * @param {Object[]} pipeline 
 */
async function aggregate(collectionName, pipeline = {}) {
  try {
    if (mongo === null || !mongo.isConnected()) await openConnection();

    const dbo = mongo.db(config.DB_NAME);
    const resultObject = await dbo.collection(collectionName)
      .aggregate(pipeline)
      .toArray();

    logger.db("Find data from " + collectionName + " Success.");

    return resultObject;

  } catch (error) {
    // logger.error("Find data from " + collectionName + " Failed.");
    // logger.error("Error : ", error);
    throw error;
  }
}


/**
 * @returns {ClientSession}
 */
async function CreateSession() {
  try {
    if (mongo === null || !mongo.isConnected()) await openConnection();

    const sessions = mongo.startSession({
      defaultTransactionOptions: {
        readConcern: { level: 'local' },
        writeConcern: { w: 'majority' },
        readPreference: 'primary'
      }
    });

    return sessions

  } catch (error) {
    // logger.error("Find data from " + collectionName + " Failed.");
    // logger.error("Error : ", error);
    throw error;
  }
}

export {
  openConnection,
  find,
  findOne,
  insertOne,
  updateOne,
  updateMany,
  deleteMany,
  findOneAndUpdate,
  aggregate,
  CreateSession
}