Ok... so, this is could be using a bit of outdated use of Mongo, but this is how I managed to solve the singleton piece of the DB. Disclaimer: it was a personal learning project for Mongo and Ecmascript 6.0 so not sure it follows the Best practices, but it works.
Fist, Db Connection: personnaDB.js
/************ Copyright ************/
/* Year: 2016
* Author: David Espino
*/
"use strict"
// Imports
const url = require('url'),
connectionUrl = process.env.CONNECTION_STRING || 'mongodb://localhost:27017/personna',
parsedUrl = url.parse(connectionUrl),
Db = require('mongodb').Db,
Server = require('mongodb').Server,
Connection = require('mongodb').Connection,
Q = require("q"),
mongoose = require("mongoose"),
dao = require('./personnaDao'),
autoIncrement = require( 'mongoose-auto-increment' );
// Symbol Keys
const _connKey = Symbol();
const _connInfoKey = Symbol();
const _monConnKey = Symbol();
const _dataModelsKey = Symbol();
const _autoIncrementKey = Symbol();
/**
* This class represents the DB Connection
*/
class PersonnaDb {
/**
* Class Constructor
* @return {[type]} [description]
*/
constructor() {
let mongoObject = null;
this[_connInfoKey] = {
host: parsedUrl.hostname,
port: parseInt(parsedUrl.port, 10),
name: parsedUrl.pathname.substr(1),
user: parsedUrl.auth ? parsedUrl.auth.split(':')[0] : null,
password: parsedUrl.auth ? parsedUrl.auth.split(':')[1] : null
};
this._connInstance = null;
}
/**
* Opens the DB connection using regular mongo db access
* @return {[type]} [description]
*/
openConnection() {
let deferred = Q.defer();
if (this[_connKey]) {
console.log('---> not need to create instance');
deferred.resolve(this[_connInfoKey]);
} else {
let $this = this;
const mongoObject = new Db('your-db', new Server(this[_connInfoKey].host, this[_connInfoKey].port, { auto_reconnect: true }));
mongoObject.open(function(error, databaseConnection) {
if (error) throw new Error(error);
console.log('---> Succesfully CREATED connection');
$this[_connKey] = databaseConnection;
// Initialize auto increment
autoIncrement.initialize(databaseConnection);
$this[_autoIncrementKey] = autoIncrement;
deferred.resolve($this);
});
}
return deferred.promise;
}
/**
* Opens a Mongo db connection
* @return {[type]} [description]
*/
openMongooseConnection() {
mongoose.connect(connectionUrl);
// set the identity plugin
autoIncrement.initialize(mongoose.connection);
this[_autoIncrementKey] = autoIncrement;
// CONNECTION EVENTS
// When successfully connected
mongoose.connection.on('connected', function () {
console.log('Mongoose default connection open to ' + parsedUrl);
});
// If the connection throws an error
mongoose.connection.on('error',function (err) {
console.log('Mongoose default connection error: ' + err);
});
// When the connection is disconnected
mongoose.connection.on('disconnected', function () {
console.log('Mongoose default connection disconnected');
});
// If the Node process ends, close the Mongoose connection
process.on('SIGINT', function() {
mongoose.connection.close(function () {
console.log('Mongoose default connection disconnected through app termination');
process.exit(0);
});
});
this[_dataModelsKey] = dao.PersonaDataModels.GetModels(this[_autoIncrementKey]);
// require('../models/data/bodySectionModel');
}
dataModels() {
return this[_dataModelsKey];
}
}
module.exports.PersonnaDb = PersonnaDb;
Second... services setup (my layer that takes the dbconnection)
services > include.js
const ModifierService = require('./modifierService').ModifierService;
const BodySectionService = require('./bodySectionService').BodySectionService;
module.exports = (dbConnection) => {
return {
Modifier: new ModifierService(dbConnection),
BodySection: new BodySectionService(dbConnection),
}
}
Sample of the service (it basically intitializes the mongo Model. BodySectionService.js
class BodySectionService extends BaseService {
constructor(db) {
super(db.dataModels().BodySection); // this is the mongo model with the schema etc
}
Then DB initialization (and passing the DB Connection as a singleton object)
app.js
var express = require('express');
const PersonnaDb = require('./dao/personnaDb').PersonnaDb;
const dbConnection = new PersonnaDb();
var app = express();
// Open DB Connection
dbConnection.openMongooseConnection();
// get the services
const services = require('./services/include')(dbConnection);
// // This is the piece that I was not totally sure, making this available on the app
app.set('services', services);
app.set('dbAccess', dbConnection);
And this is how I use it:
bodySectionController.js
router.get('/', function(req, res, next) {
const bodySectionProxy = req.app.get("services").BodySection;
const logger = req.app.get("customLogger");
var result = bodySectionProxy.getBodySections({}).then((result) => {
res.json(result);
})
.fail((err) => {
logger.logError(err);
res.json(err.message);
})
.done();
});
module.exports = router;
I've excluded the Path on how I set the models on the service since your question only asks about How to setup the DB. But if you need me to, I could extend the answer with that too.
Hope this gives an idea.