(function(module) { 'use strict'; var mongoClient = require('mongodb').MongoClient, winston = require('winston'), async = require('async'), nconf = require('nconf'), express = require('express'), mongoStore = require('connect-mongo')(express), mongoHost = nconf.get('mongo:host'), db; module.init = function(callback) { mongoClient.connect('mongodb://'+ mongoHost + ':' + nconf.get('mongo:port') + '/' + nconf.get('mongo:database'), function(err, _db) { db = _db; if(err) { winston.error("NodeBB could not connect to your Mongo database. Mongo returned the following error: " + err.message); process.exit(); } module.sessionStore = new mongoStore({ db: db }); // TODO : what is the db user name?? /*if(nconf.get('mongo:password')) { db.authenticate(dbUser, nconf.get('mongo:password'), function (err) { }); }*/ db.createCollection('objects', function(err, collection) { if(err) { winston.error("Error creating collection " + err.message); return; } if(collection) { collection.ensureIndex({_key :1, setName:1}, {background:true}, function(err, name){ if(err) { winston.error("Error creating index " + err.message); } }); } }); db.createCollection('search', function(err, collection) { if(err) { winston.error("Error creating collection " + err.message); return; } if(collection) { collection.ensureIndex({content:'text'}, {background:true}, function(err, name){ if(err) { winston.error("Error creating index " + err.message); } }); } }) callback(err); }); } // // Exported functions // module.searchIndex = function(key, content, id) { var data = { id:id, key:key, content:content }; db.collection('search').update({id:id, key:key}, {$set:data}, {upsert:true, w: 1}, function(err, result) { if(err) { winston.error('Error indexing ' + err.message); } }); } module.search = function(key, term, callback) { db.command({text:"search" , search: term, filter: {key:key} }, function(err, result) { if(err) { return callback(err); } if(!result) { return callback(null, []); } if(result.results && result.results.length) { var data = result.results.map(function(item) { return item.obj.id; }); callback(null, data); } else { callback(null, []); } }); } module.searchRemove = function(key, id) { db.collection('search').remove({id:id, key:key}, function(err, result) { callback(err, result); }); } module.flushdb = function(callback) { db.dropDatabase(function(err, result) { if(err){ winston.error(error); return callback(err); } callback(null); }); } module.getFileName = function(callback) { throw new Error('not-implemented'); } module.info = function(callback) { db.stats({scale:1024}, function(err, stats) { stats.avgObjSize = (stats.avgObjSize / 1024).toFixed(2); stats.raw = JSON.stringify(stats, null, 4); stats.mongo = true; //remove this when andrew adds in undefined checking to templates stats.redis = false; callback(err, stats); }); } // key module.exists = function(key, callback) { db.collection('objects').findOne({$or:[{_key:key}, {setName:key}]}, function(err, item) { callback(err, item !== undefined && item !== null); }); } module.delete = function(key, callback) { db.collection('objects').remove({_key:key}, function(err, result) { if(err) { if(callback) { return callback(err); } else { return winston.error(err.message); } } if(result === 0) { db.collection('objects').remove({setName:key}, function(err, result) { if(callback) { callback(err, result); } }); } else { if(callback) { callback(null, result); } } }); } module.get = function(key, callback) { module.getObjectField(key, 'value', callback); } module.set = function(key, value, callback) { var data = {value:value}; module.setObject(key, data, callback); } module.keys = function(key, callback) { db.collection('objects').find( { _key: { $regex: key /*, $options: 'i'*/ } }, function(err, result) { callback(err, result); }); } //hashes function removeHiddenFields(item) { if(item) { if(item._id) { delete item._id; } if(item._key) { delete item._key; } if(item.setName) { delete item.setName; } } return item; } module.setObject = function(key, data, callback) { data['_key'] = key; db.collection('objects').update({_key:key}, {$set:data}, {upsert:true, w: 1}, function(err, result) { if(callback) { callback(err, result); } }); } module.setObjectField = function(key, field, value, callback) { var data = {}; // if there is a '.' in the field name it inserts subdocument in mongo, replace '.'s with \uff0E field = field.replace(/\./g, '\uff0E'); data[field] = value; db.collection('objects').update({_key:key}, {$set:data}, {upsert:true, w: 1}, function(err, result) { if(callback) { callback(err, result); } }); } module.getObject = function(key, callback) { db.collection('objects').findOne({_key:key}, function(err, item) { removeHiddenFields(item); callback(err, item); }); } module.getObjects = function(keys, callback) { db.collection('objects').find({_key:{$in:keys}}, {_id:0}).toArray(function(err, data) { if(err) { return callback(err); } var returnData = [], resultIndex = 0; function findData(key) { if(!data) { return null; } for(var i=0; i