@bonjourjohn/dbhelper v1.0.1
DB HELPER
Purpose
This present model class is designed to simplify the development of object oriented projects using the native MongoDB Node JS driver.
It provides abstract classes for models and collection. It provides overrides for main insert, find and update functions.
It also allows developer to set up a cache and to define specific pre insert, pre update and post save behaviors.
This module also provides a cache client generator based on ioredis.
Provided to Model constructor, it allows you to use a Redis cache to store responses to Mongo queries in order to improve performances.
Quick start
First you need to create a class extending the Model.
The constructor needs to be overridden. The native constructor takes 3 arguments:
dbInstanceis the instance of a Mongo Dbfoois the collection name this class is related tocacheClientis the ioredis cache client this object is going to use. This param is not mandatory
Foo.class:
const Model = require('@bonjourjohn/dbhelper').Model;
module.exports = class Foo extends Model {
constructor(dbInstance, cacheClient) {
super(dbInstance, 'foo', cacheClient);
}
};In your code, where you need your object instance:
without cache:
const MongoClient = require('mongodb').MongoClient;
const FooClass = require('./path/to/Foo.class');
const Mclient = new MongoClient(SERVER, OPTIONS).connect();
const MDB = Mclient.db(DBNAME);
const Foo = new FooClass(MDB);
Foo.init(); //loads the dedicated MongoCollection into object instancewith cache:
const MongoClient = require('mongodb').MongoClient;
const FooClass = require('./path/to/Foo.class');
const Mclient = new MongoClient(SERVER, OPTIONS).connect();
const cacheClient = require('@bonjourjohn/dbhelper').Cache(CACHEOPTS);
const MDB = Mclient.db(DBNAME);
const Foo = new FooClass(MDB, cacheClient);
Foo.init(); //loads the dedicated MongoCollection into object instanceModel native properties list
Here are the properties you can find in an instaciated Model object once it's been initiated (it's ready to work):
this.dbInstanceinstance of Mongodb Dbthis.collectioninstance of Mongodb Collectionthis.collecionNamestring, equivalent tothis.collection.collectionNamethis.cacheClientinstance of Redis client (if cacheClient set, not mandatory)this.useCachebool, true ifthis.cacheClientis set and ready, false otherwise. It can be set tofalseif you want to skip cache.
Temporary properties:
this.docJSON object, document that is going to be inserted in collection. It will exist only during insert process (from _preInsert to _postSave)this.docsJSON object, documents that are going to be inserted in collection. It will exist only during insert process (from _preInsert to _postSave)this.updateJSON object, update query that will be used by an update method. It will exist only during update process (from _preUpdate to _postSave)
Model methods list
Here are the methods provided by this Model class, and the desciption of their usefulness.
Constructor
constructor(dbInstance, collectionName, cacheClient)
Creates a new Model object.
Params:
dbInstanceMongodb Db objectcollectionNamename of the collection the current instance has to be linked tocacheClientnot mandatory Redis cache client
init
init()
Get the collectionName collection in given Db and set it as an object instance local var this.collection.
setCacheClient
setCacheClient(cacheClient)
Store given cache client into this.cacheClient.
Set this.useCache to true if cache client is ready.
Attach listeners:
on('ready')to setthis.useCachetotrueon('end')to setthis.useCachetofalseon('error')to setthis.useCachetofalse
Params
cacheClientinstance of Redis client
_preInsert()
Called in insertOne and insertMany methods.
Execute all pre insert actions.
It can be overriden. Native behavior consist in adding timestamps fields createdAt and updatedAt to document(s).
_preUpdate()
Called in findOneAndUpdate, updateMany and updateOne methods.
Execute all pre update actions.
It can be overriden. Native behavior consist in added the update of updatedAt field in update query if it's not already present.
_postSave()
Called at then end of all saving process: insertOne, insertMany, findOneAndUpdate, updateMany and updateOne.
Execute all post save actions.
It can be overriden. Native behavior consist in clearing cache if cache is on.
_postDelete()
Called at then end of all deleting process: remove, findOneAndDelete.
Execute all post delete actions.
It can be overriden. Native behavior consist in clearing cache if cache is on.
find(), findOne(), findOneAndDelete(), insertOne(), insertMany(), updateOne(), findOneAndUpdate(), updateMany()
These methods will do the exact same thing as they do when their called on Mongodb Collection objects, except two things:
- they will execute _pre and _post methods before and after process
- they will try to read in cache and/or write result in cache, or flush cache according to the nature of the operation (read, write, delete)
They all take the same arguments their analogue in Mongo Collection object, but you can add this option field:
skipCachebool, tell method to skip reading in cache and to go straigth to database.
Example:
const results = await Foo.findOne({"fieldName": "value"}, {"skipCache": true});setupTimestamps()
Add fields createdAt and updatedAt into document stored in this.doc or into documents stored in this.docs.
updateTimestamps()
Add updatedAt to $set part of the query stored in this.update. Create the $set part if it does not exist.
findInCache(query, options)
Check if given query already has a result in cache with given options and return them if it has. Return false otherwise.
Called by read methods when this.useCache is true.
storeInCache(query, options, value)
Stores value into cache under a key generated from given query and options.
Called by read methods when this.useCache is true.
clearCache()
Clears the cache for the current collection name. IE. flush all keys corresponding to the pattern COLLECTIONNAME*
Testing
Requirements
You need a MongoDB and a Redis server running.
Use these Docker images:
docker run --name database -p 27017:27017 -d mongo
docker run --name cache -p 6379:6379 -d redis:3.0.6-32bitRegarding your needs, you can use your own Redis and Mongo applications/servers/containers.
Once everything is running, just run the tests:
npm test