Edit: Removed higher-level ideas, included problem-specific and less-transferable code.
I implemented my DAL using DAO's. My application hooks in to various databases (mostly for legacy reasons). In order to facilitate efficient and intelligent usage of connections, I use a ConnectionBroker
singleton to manage the various connections that may (or may not be) open. This ConnectionBroker
is then injected into the DAO's where they can request control of a particular connection object, request new connections, ect.
From an inheritence POV, I'd like something like:
AbstractDbConnection
|-- MongoDbConnection
|-- MsSqlConnection
|-- CouchDbConnection
|-- ...
Where AbstractDbConnection
defines an interface, and implements some shared event-based logic.
var EventEmitter = require('events').EventEmitter;
module.exports = function AbstractDbConnection(host, port, database, login, ...) {
// private
var state = StatesEnum.Closed; // StatesEnum = {Open: 0, Closed: 1, ..}; Object.freeze(StatesEnum);
// api that must be overwritten
this.connect = function connect() {throw new ...}
this.disconnect = function disconnect() {throw new ...}
... <more>
this.getState = function() { return state; }
}
AbstractDbConnection.prototype.__proto__ = EventEmitter.prototype;
And then I implement the interface using driver-specific code:
var mssqldriver = require('mssqldriver'), //fictitious driver
AbstractDbConnection = require(__dirname + '/blah/AbstractDbConnection');
module.exports = function MsSqlConnection(host, port, database, login, ...) {
var me = this;
// implement using driver
this.connect = function connect() {...}
this.disconnect = function disconnect() {...}
... <more>
driverSpecificConnection.on('driverSpecificOpenEvent', function() {
me.emit('open'); // relay driver-specific events into common events
state = StatesEnum.Open; // how ??
}
...
}
MsSqlConnection.prototype.__proto__ = new AbstractDbConnection();
But clearly I want to protect the state
property from changing inadvertently.