Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jdarling committed Jul 13, 2012
0 parents commit 9b36868
Show file tree
Hide file tree
Showing 7 changed files with 426 additions and 0 deletions.
22 changes: 22 additions & 0 deletions .gitattributes
@@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto

# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union

# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
15 changes: 15 additions & 0 deletions .gitignore
@@ -0,0 +1,15 @@
#################
## npm/Node.js
#################

node_modules

############
## Windows
############

# Windows image file caches
Thumbs.db

# Folder config file
Desktop.ini
34 changes: 34 additions & 0 deletions bin/test.js
@@ -0,0 +1,34 @@
var MongoMQ = require('../lib/MongoMQ').MongoMQ;
var repl = require('repl');

var queue = new MongoMQ();

var r = repl.start({
prompt: ">"
});

r.on('exit', function(){
queue.close();
});

r.context.listen = function(){
queue.on('test', function(err, data, next){
console.log('got: ', data);
next();
});
};

var msgidx = 0;
r.context.send = function(){
queue.emit('test', msgidx);
msgidx++;
};

r.context.load = function(){
for(var i = 0; i<100; i++){
queue.emit('test', msgidx);
msgidx++;
}
};

r.context.queue = queue;
95 changes: 95 additions & 0 deletions lib/MongoConnection.js
@@ -0,0 +1,95 @@
var mongodb = require('mongodb');
var key;

for(key in mongodb){
if(hasOwnProperty.call(mongodb, key)){
//console.log('Importing: ', key);
global[key] = exports[key] = mongodb[key];
}
}

exports.ObjectId = exports.ObjectID;

var MongoConnection = exports.MongoConnection = function(options, callback){
options = options||{};
var self = this;
if(options.servers instanceof Array){
var servers = [], host, port, serverOptions, l = options.servers.length;
for(var i = 0; i<l; i++){
if(typeof(options.servers[i])=='string'){
host = options.servers[i];
port = Connection.DEFAULT_PORT;
serverOptions = options.serverOptions||{auto_reconnect: true};
}else{
host = options.servers[i].host||options.host||'localhost';
port = options.servers[i].port||options.port||Connection.DEFAULT_PORT;
serverOptions = options.servers[i].serverOptions||options.serverOptions||{auto_reconnect: true};
}
servers.push(new Server(host, port, options));
}
self.server = new ReplSetServers(servers);
}else self.server = new Server(options.host||'localhost', options.port||Connection.DEFAULT_PORT, options.serverOptions||{auto_reconnect: true});

var server = self.server;
var db = self.dbConnection = new Db(options.db, server, {native_parser:(options.nativeParser==null?false:options.nativeParser)});
db.open(function(err, _db){
self._db = _db;
if(options.username&&options.password){
db.admin(function(err, adminDb){
adminDb.authenticate(options.username, options.password, function(err, result){
if(typeof(callback)=='function') callback(null, self);
});
});
}else{
if(typeof(callback)=='function') callback(null, self);
}
});
};

MongoConnection.prototype.Close = function(){
var self = this;
self._db.close();
};

MongoConnection.prototype.Collection = function(collectionName, pkFactory, options){
var self = this;
return self.dbConnection.collection(collectionName, pkFactory, options);
};

MongoConnection.prototype.find = function(inCollection, selector, fields, skip, limit, timeout, callback){
var self = this;
var args = Array.prototype.slice.apply(arguments);
var collection = self.Collection(args.shift());
var cb = args.pop();
if(typeof(cb)!=='function'){
args.push(cb);
cb = function(){};
}
collection.find.apply(collection, args).toArray(cb);
};

MongoConnection.prototype.insert = function(inCollection, selector, fields, skip, limit, timeout, callback){
var self = this;
var args = Array.prototype.slice.apply(arguments);
var collection = self.Collection(args.shift());
var cb = args.pop();
if(typeof(cb)!=='function'){
args.push(cb);
cb = function(){};
}
args.push(cb);
collection.insert.apply(collection, args);
};

MongoConnection.prototype.update = function(inCollection, selector, fields, skip, limit, timeout, callback){
var self = this;
var args = Array.prototype.slice.apply(arguments);
var collection = self.Collection(args.shift());
var cb = args.pop();
if(typeof(cb)!=='function'){
args.push(cb);
cb = function(){};
}
args.push(cb);
collection.update.apply(collection, args);
};
127 changes: 127 additions & 0 deletions lib/MongoMQ.js
@@ -0,0 +1,127 @@
var MC = require("./MongoConnection").MongoConnection;

var MongoMQ = exports.MongoMQ = function(options){
var self = this;
options = options || {};
self.mqCollectionName = options.mqCollectionName||'queue';
self.mqDB = options.mqDB||options.db||'MongoMQ';
options.db = self.mqDB;
self.handlers = [];
var server = self.server = new MC(options, function(err, conn){
if(err){
console.log(err);
}else{
self.db = conn._db;
self.start();
}
});
};

MongoMQ.prototype.start = function(){
var self = this;
self.db.collection(self.mqCollectionName, {safe: true}, function(err, collection){
var okToStart = true;
if(err){
if(collection){
okToStart = false;
}else{
self.createCollection();
}
}else{
self.startListening(collection);
}
});
};

MongoMQ.prototype.close = function(){
var self = this;
self.db.close();
};

MongoMQ.prototype.createCollection = function(){
var self = this;
self.db.dropCollection(self.mqCollectionName, function(){
self.db.createCollection(self.mqCollectionName, {
capped: true,
size: 100000000
}, function(err, collection){
self.startListening(collection);
});
});
};

MongoMQ.prototype.startListening = function(collection){
var self = this;
collection = collection||self.db.collection(self.mqCollectionName, {safe: true});
if(!collection) self.createCollection();
else{
collection.isCapped(function(err, isCapped){
if(!isCapped) self.createCollection();
else{
self.collection = collection;
if(self.handlers.length>0){
var l = self.handlers.length;
for(var i = 0; i<l; i++){
self.nextMessage(self.handlers[i].msgType, self.handlers[i].passive, self.handlers[i].callback);
}
}
self.listening = true;
}
});
}
};

MongoMQ.prototype.getCursor = function(forMsg, passive, callback){
var self = this;
var doCallback = function(err, msg){
var next = function(){
self.getCursor(forMsg, passive, callback);
};
if(typeof(callback)=='function') callback(err, msg?msg.pkt:false, next);
};
if(typeof(passive)=='function'){
callback = passive;
passive = false;
}
self.collection = self.collection||self.db.collection(self.mqCollectionName, {safe: true});
if(passive){
self.collection.find({$and: [{msg: forMsg}, {$or: [{handled: false}, {handled: {$exists: false}}]}]}, {tailable: true}, function(err, msg){
if(typeof(callback)=='function') doCallback(err, (msg&&msg.length)>0?msg[0]:msg);
});
}else{
self.collection.find({$and: [{msg: forMsg}, {$or: [{handled: false}, {handled: {$exists: false}}]}]}, {tailable: true}).nextObject(function(err, msg){
self.collection.findAndModify((msg&&msg.length)>0?msg[0]:msg, {emitted: -1}, {$set: {handled: true}}, {tailable: true},
function(err, data){
if(err||(!data)) self.getCursor(forMsg, passive, callback); // someone else picked it up
else doCallback(err, data);
});
});
}
};

MongoMQ.prototype.nextMessage = function(msgType, passive, callback){
var self = this;
self.getCursor(msgType, passive, callback);
};

MongoMQ.prototype.emit = function(msg, pkt){
var self = this;
self.collection = self.collection||self.db.collection(self.mqCollectionName, {safe: true});
msg = {
msg: msg,
pkt: pkt,
handled: false,
emitted: new Date()
};
self.collection.insert(msg, function(){});
};

MongoMQ.prototype.on = function(msg, passive, callback){
var self = this;
if(typeof(passive)=='function'){
callback = passive;
passive = false;
}
self.handlers.push({msgType: msg, passive: !!passive, handler: callback});
if(self.listening) self.nextMessage(msg, passive, callback);
};
24 changes: 24 additions & 0 deletions package.json
@@ -0,0 +1,24 @@
{
"author": {
"name": "Jeremy Darling",
"email": "jeremy.darling@gmail.com"
},
"name": "MongoMQ",
"version": "0.1.0",
"repository": {
"type": "git",
"url": "git://github.com/jdarling/MongoMQ.git"
},
"contributors": [
],
"main": "./lib/MongoMQ",
"bin": {
"MongoMQ": "./bin/test.js"
},
"engines": {
"node": ">= v0.6.0"
},
"dependencies": {
"mongodb": ">= 1.0.2"
},
}

0 comments on commit 9b36868

Please sign in to comment.