meanio-custom
Version:
Extracted functionality for MEAN.io
167 lines (143 loc) • 5.45 kB
JavaScript
;
var mongoose = require ('mongoose'),
Q = require('q'),
Schema = mongoose.Schema,
_ = require('lodash');
mongoose.Promise = Q.Promise;
function filterDBAliases (v) {
return mongoose.alias_MEANIODB_exists(v);
}
function applyModels (schema, model, collection, dbalias) {
mongoose.get_MEANIODB_connection(dbalias).model(model, schema, collection);
return mongoose.get_MEANIODB_connection(dbalias).model(model);
}
function connectDb (alias, path) {
var defer = Q.defer();
var connection = mongoose.createConnection (path);
connection.once ('connected', connectDbOk.bind(null, defer, {path:path, alias: alias, connection: connection}));
connection.once('error', connectDbFailed.bind(null, defer, {}));
return defer.promise;
}
function connectDbOk (defer, s) {
defer.resolve(s);
}
function connectDbFailed(defer, s) {
defer.reject(s);
}
function dataBasesReady (done, database, connection_pool) {
var alias_map = {};
for (var i in connection_pool) {
if (connection_pool[i].state !== 'fulfilled') continue;
alias_map[connection_pool[i].value.alias] = connection_pool[i].value.connection;
}
mongoose.get_MEANIODB_connection = function (alias) {
if ('default' === alias || !alias_map[alias]) {
return database;
}
return alias_map[alias];
};
mongoose.alias_MEANIODB_exists = function (alias) {
return (alias === 'default') || !alias || alias in alias_map;
};
done.resolve();
}
var lazyModelsMap = {};
function createModelStructure (schema, model, collection, db) {
db = db || 'default';
if (!lazyModelsMap[db]) lazyModelsMap[db] = {};
if (!lazyModelsMap[db][model]) lazyModelsMap[db][model] = {pre:[], post:[], virtual: [], indices: []};
var mc = lazyModelsMap[db][model];
mc.collection = collection;
mc.fields = _.merge (mc.fields || {}, schema.fields);
mc.methods = _.assign (mc.methods || {}, schema.methods);
mc.statics = _.assign (mc.statics || {}, schema.statics);
if (schema.options) mc.options = _.assign (mc.options || {}, schema.options);
if (schema.indices) Array.prototype.push (mc.indices, schema.indices);
if (schema.pre) mc.pre.push (schema.pre);
if (schema.virtual) mc.virtual.push (schema.virtual);
}
function bindIndices (s, i) {
s.index(i);
}
function bindVirtuals (s, vr) {
for (var name in vr) {
var v = s.virtual(name);
console.log('create virtual ', name);
if (vr[name].get) v.get(vr[name].get);
if (vr[name].set) v.set(vr[name].set);
}
}
function bindHook (s, type, rec) {
for (var name in rec) {
console.log('create hook', name);
s[type](name, rec[name]);
}
}
function onInstanceAndConfig(defer, meanioinstance, config, done) {
var defaultConfig = config.clean;
mongoose.set('debug', defaultConfig.mongoose && defaultConfig.mongoose.debug);
mongoose.connect(defaultConfig.db || '', defaultConfig.dbOptions || {});
var database = mongoose.connection;
database.on('error', function(err) {
console.error('Error:', err.message);
return console.error('**Could not connect to MongoDB. Please ensure mongod is running and restart MEAN app.**');
});
database.once('open', function() {
// we're connected!
// Register database dependency
meanioinstance.register('database', {
connection:database.base
});
var db_promises = [];
for (var i in defaultConfig.dbs) {
db_promises.push (connectDb(i, defaultConfig.dbs[i]));
}
Q.allSettled (db_promises).then(dataBasesReady.bind(null, defer, database));
});
};
function onInstance(meanioinstance,defer){
meanioinstance.resolve('defaultconfig',onInstanceAndConfig.bind(null,defer,meanioinstance));
}
function supportDB(Meanio) {
Meanio.onInstance(onInstance);
Meanio.createModels = function () {
for (var db in lazyModelsMap) {
for (var model in lazyModelsMap[db]) {
var rec = lazyModelsMap[db][model];
//console.log('for db', db,' model ',model, 'is about to be created:',rec);
var s = new Schema(rec.fields, rec.options);
s.methods = rec.methods;
s.statics = rec.statics;
rec.virtual.forEach(bindVirtuals.bind(null, s));
rec.pre.forEach(bindHook.bind(null, s, 'pre'));
rec.post.forEach(bindHook.bind(null, s, 'post'));
rec.indices.forEach(bindIndices.bind(null, s));
var m = applyModels(s, model, rec.collection, db);
Meanio.Singleton.events.emit ('lazy_model_ready', {model: m, db: db});
}
}
Meanio.Singleton.events.emit('lazy_models_ready');
};
Meanio.applyModels = function (model_register) {
for (var i in model_register) {
var itm = model_register[i];
if (!itm.schema) {
throw 'No schema in reqister model request, can not move on ...';
}
if (!itm.model) {
throw 'No model in register model request, can not move on ...';
}
if (!itm.dbs || itm.dbs.length === 0) {
itm.dbs = ['default'];
}
if (itm.schema instanceof mongoose.Schema) {
///filter out eventual duplicates in dbs array and nonexisting aliases as well
_.uniq(itm.dbs.filter(filterDBAliases)).forEach(applyModels.bind(null, itm.schema, itm.model, itm.collection));
continue;
}
//ok, now form structures for lazy model creation
itm.dbs.forEach( createModelStructure.bind(null, itm.schema, itm.model, itm.collection) );
}
};
}
module.exports = supportDB;