Source: db/DBObjectFactory.js

/**
 * @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;