/**
* @version 1.2
* @author Boris GBAHOUE
* @file abstraction layer to create DBObject from whichever DB implementation is chosen when building the object
* @module amiwo/db
*/
// =======================================================================
// BASIC SETUP
// =======================================================================
// modules
const u = require('../util');
const assert = require('assert');
const path = require('path');
// public static variables
var __dbImplementation;
var __DBObjectClassHash = {};
var __dbObjectRootPath;
var __db;
// =======================================================================
// CONSTRUCTOR
// =======================================================================
/**
* @class
*/
function DBObjectFactory() {
// empty
}
// =======================================================================
// PUBLIC METHODS
// =======================================================================
/**
* Set DB implementation
*
* @param {String} dbImplementation: DB implementation, "mongo" or something else (e.g., SQL, ...)
*
* @public
*/
DBObjectFactory.setDBImplementation = function(dbImplementation) {
__dbImplementation = dbImplementation;
}
/**
* Set app root path
*
* @param {String} root
*
* @public
*/
DBObjectFactory.setDBRootPath = function(root) {
__dbObjectRootPath = path.normalize(root);
}
/**
* Set underlying database
*
* @param {any} db
*/
DBObjectFactory.setDB = function(db) {
__db = db;
}
/**
* Get underlying database
*
* @retur {any} the database (e.g., Mongo DB object)
*/
DBObjectFactory.getDB = function(db) {
return __db;
}
/**
* Build a DBObject from a name or an array of DBObject if object is an Array
*
* @param {String} name
* @param {Array|Object} [object] parameters to pass to the Object's constructor; if an array returns an Array of DBObject each initialized with its associated element
*
* @returns {DBObject} returns a subclass of DBObject or null if 'name' doesn't match an existing object
*/
DBObjectFactory.createObject = function(name, object) {
assert(u.isNotEmpty(__dbImplementation ), "::AMIWO::DBOBJECTFACTORY::CREATEOBJECT::ERROR Invalid state, dbImplementation can't be nully");
if (u.isEmpty(name)) return null;
// Lookup DBObject class and saves the reference to our hash if it didn't exist
var Class = __DBObjectClassHash[name];
if (Class == null) {
var className = path.normalize(__dbObjectRootPath + '/' + __dbImplementation.toLowerCase() + '/' + name); // Path relative to DBObjectFactory
// Add DB impl suffix if it wasn't already set
var nameWithSuffix = name;
var index = name.indexOf(__dbImplementation);
if (index == -1) {
className += __dbImplementation;
nameWithSuffix = name + __dbImplementation;
} else {
nameWithSuffix = name;
name = name.substr(0, index);
}
className = className.replace('//','/');
Class = require(className);
__DBObjectClassHash[name] = Class;
__DBObjectClassHash[nameWithSuffix] = Class;
}
// Create the returned object or array of objects
if (Array.isArray(object)) {
var objects = object; // for readability
var array = [];
for (var i = 0; i < objects.length; i++) {
array[i] = new Class(objects[i]);
}
return array;
} else {
var object = new Class(object);
return object;
}
}
module.exports = DBObjectFactory;