Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6ed9a8b
modified to dispatch queued queries
Aug 10, 2010
fab6b43
firing 'close' event by calling reallyClose() on connection error
Aug 11, 2010
f23aab7
turning off debug :>
Aug 11, 2010
5a81924
resetting close state so the next event doesn't do anything silly
Aug 11, 2010
8819bd6
adding upsert capability
Aug 15, 2010
f1d1387
beefing up find() as it would fail to return large data sets, now als…
Aug 16, 2010
723e896
janky sort support
Aug 16, 2010
9868e82
using bentruyman's fix for dispatching queries that miss the ready ev…
Aug 16, 2010
42a0b37
adding getLastError(function(error)
Aug 18, 2010
d4735bb
preparing new commit
Sep 24, 2010
3ae3265
rewrite of the binding backend
Sep 24, 2010
f85fba3
update build script
Sep 24, 2010
11b0065
updating readme some
Sep 24, 2010
197db0d
tidying up a little
Sep 24, 2010
f5d04e8
woops, hard coded port, fixed
Sep 24, 2010
f2fbf32
removed some TODOs by tearing down the connection on some errors
Sep 27, 2010
fc1c462
adding authentication support....and fixing a bug in the process.
Sep 27, 2010
32b5627
no real changes
Sep 27, 2010
2895b9f
needed to potentially dispatch after results to handle weird query ne…
Sep 27, 2010
f4c76eb
adding note
Sep 27, 2010
085d523
silly bug, was only writing limits > 0, so once a limit was set it wa…
Sep 27, 2010
34a04ed
some performance tuning, need to ask how to handle the problem of too…
Sep 27, 2010
2775be1
adding a drained event to writes to allow a loop of inserts to know when
Sep 28, 2010
6de8b18
drained event may need some more thought, but it works for the limite…
Sep 28, 2010
9fed897
off by one, woops
Aug 12, 2011
3627415
dispatching in edge cases as well as just cleaning up some (potential…
Aug 12, 2011
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,15 @@ Installation
- Make sure you have git installed.
- ./update-mongo-c-driver.sh
- node-waf configure build
- ./run-tests.sh
- ./run-tests.sh <-- the tests may or may not work, i'll update them as i get time

BUGS
----

The entire binding backend has been rewritten with the exception of the bson parsing. Please report any bugs to me instead of bugging orlandov about them as they're likely my fault.


---
This package is EXPERIMENTAL, with emphasis on MENTAL. I am working on this in
my spare time to learn the Node, v8 and MongoDB API's.

Expand All @@ -127,4 +131,5 @@ SEE ALSO
AUTHOR
------

Orlando Vazquez (ovazquez@gmail.com)
Lee Smith (notwink@gmail.com)
Orlando Vazquez (ovazquez@gmail.com) <- Thanks for the bson parsing :)
130 changes: 103 additions & 27 deletions lib/mongodb.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var sys = require("sys"),
mongo = require("../lib/mongo");
var sys = require("sys");
var mongo = require("../lib/mongo");
var crypto = require("crypto");

function Collection(mongo, db, name) {
this.mongo = mongo;
Expand All @@ -8,42 +9,64 @@ function Collection(mongo, db, name) {
this.name = name;
}

Collection.prototype.find = function(query, fields, callback) {
this.mongo.addQuery(callback, this.ns, query, fields);
}
Collection.prototype.getLastError = function(callback)
{
ns = this.db + ".$cmd";
var cmd = {
"query": {getlasterror: 1}
};

this.find_one(cmd, {}, ns, function (result) {
callback(result);
});

jjj = JSON.stringify
};

Collection.prototype.find = function(query, fields, callback, limit, skip, sort) {
var cmd = {
"$query" : query ? query : {}
};

if(sort)
cmd.$orderby = sort;
this.mongo.addQuery(callback, this.ns, cmd, fields, limit, skip);
};

Collection.prototype.insert = function(obj) {
this.mongo.connection.insert(this.ns, obj);
}
};

Collection.prototype.update = function(cond, obj) {
this.mongo.connection.update(this.ns, cond, obj);
}
Collection.prototype.update = function(cond, obj, options) {
var db_upsert = 0;
var db_multi_update = 0;
db_upsert = options != null && options['upsert'] != null ? (options['upsert'] == true ? 1 : 0) : db_upsert;
db_multi_update = options != null && options['multi'] != null ? (options['multi'] == true ? 1 : 0) : db_multi_update;
flags = parseInt(db_multi_update.toString() + db_upsert.toString(), 2);
this.mongo.connection.update(this.ns, cond, obj, flags);
};

Collection.prototype.remove = function(query) {
this.mongo.connection.remove(this.ns, query);
}
};

Collection.prototype.find_one = function(query, fields, ns, callback) {
this.mongo.addQuery(function (results) {
// XXX what if result.Length < 1
callback(results[0]);
}, ns || this.ns, query, fields, 1);
}
};

Collection.prototype.count = function(query, callback) {
ns = this.db + ".$cmd";
var cmd = {
"count": this.name,
"query": query
}
};

this.find_one(cmd, {}, ns, function (result) {
callback(result.n);
});
}
};

function MongoDB() {
this.myID = Math.random();
Expand All @@ -52,21 +75,71 @@ function MongoDB() {
var self = this;

this.connection.addListener("close", function () {
self.isReady = false;
self.emit("close");
});

this.connection.addListener("drained", function() {
self.emit("drained");
});

this.connection.addListener("ready", function () {
self.isReady = true;
self.dispatch();
});

this.connection.addListener("connection", function () {
if(self.username) // if we see a username, authenticate
{
var ns = self.db + ".$cmd";
var cmd = {
"query": { getnonce: 1}
};

self.addQuery(function (results)
{
var nonce = results[0].nonce;
var authcmd = {};
authcmd.authenticate = 1;
authcmd.user = self.username;
authcmd.nonce = nonce;

var hash = crypto.createHash('md5');
hash.update(self.username + ":mongo:" + self.password);
var pwd = hash.digest('hex');

var hash = crypto.createHash('md5');
hash.update(nonce + self.username + pwd);
authcmd.key = hash.digest('hex');

var ns = self.db + ".$cmd";
var cmd = {
"query": authcmd
};
self.addQuery(function(results)
{
if(results[0].ok == 1)
{
self.isReady = true;
self.emit("connection", self);
}
else
sys.puts("authentication error!");
}, ns, cmd, {}, 1);
self.dispatch();
}, ns, cmd, {}, 1);
self.dispatch();
return;
}
self.dispatch();
self.emit("connection", self);
});

this.connection.addListener("result", function(result) {
var callback = self.currentQuery[0];
callback(result);
self.currentQuery = null;
callback(result);
self.dispatch();
});
}

Expand All @@ -77,32 +150,35 @@ MongoDB.prototype.connect = function(args) {
this.hostname = args.hostname || "127.0.0.1";
this.port = args.port || 27017;
this.db = args.db;

this.username = args.username;
this.password = args.password;
this.connection.connect(this.hostname, this.port);
}
};

MongoDB.prototype.close = function() {
this.connection.close();
}
};

MongoDB.prototype.addQuery = function(callback, ns, query, fields, limit, skip ) {
var q = [ callback, ns ];
if (query) q.push(query);
if (fields) q.push(fields);
if (limit) q.push(limit);
if (skip) q.push(skip);
if (query) q.push(query); else q.push({});
if (fields) q.push(fields); else q.push({});
if (limit) q.push(limit); else q.push(0);
if (skip) q.push(skip); else q.push(0);
this.queries.push(q);
}
if(this.isReady)
this.dispatch();
};

MongoDB.prototype.dispatch = function() {
if (this.currentQuery || !this.queries.length) return;
this.currentQuery = this.queries.shift();
this.connection.find.apply(this.connection, this.currentQuery.slice(1));
}
};

MongoDB.prototype.getCollection = function(name) {
return new Collection(this, this.db, name);
}
};

MongoDB.prototype.getCollections = function(callback) {
this.addQuery(function (results) {
Expand All @@ -115,7 +191,7 @@ MongoDB.prototype.getCollections = function(callback) {
callback(collections);
}, this.db + ".system.namespaces");

}
};

exports.MongoDB = MongoDB;
exports.ObjectID = mongo.ObjectID
exports.ObjectID = mongo.ObjectID;
Loading