Skip to content

Commit

Permalink
Fixes for a issue, #438, #432
Browse files Browse the repository at this point in the history
  • Loading branch information
Poincare authored and christkv committed Dec 14, 2011
1 parent 8b2c366 commit 9e7923f
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 15 deletions.
8 changes: 6 additions & 2 deletions HISTORY
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
0.9.7.2
* Added SSL support for future version of mongodb (EXPERIMENTAL)
* Added SSL support for future version of mongodb (VERY VERY EXPERIMENTAL)
* pass in the ssl:true option to the server or replicaset server config to enable
* a bug either in mongodb or node.js does not allow for more than 1 connection pr server.
* a bug either in mongodb or node.js does not allow for more than 1 connection pr db instance (poolSize:1).
* Added getTimestamp() method to objectID that returns a date object
* Added finalize function to collection.group
* function group (keys, condition, initial, reduce, finalize, command, callback)
Expand All @@ -10,6 +10,10 @@
* reaperTimeout, set timeout for calls (default 30000 miliseconds)
* reaper, enable/disable reaper (default false)
* Work around for issues with findAndModify during high concurrency load, insure that the behavior is the same across the 1.8.X branch and 2.X branch of MongoDb
* Reworked multiple db's sharing same connection pool to behave correctly on error, timeout and close
* EnsureIndex command can be executed without a callback (Issue #438)
* Eval function no accepts options including nolock (Issue #432)
* eval(code, parameters, options, callback) (where options = {nolock:true})

0.9.7.1-2 2011-11-27
* Set statistical selection strategy as default for secondary choice.
Expand Down
36 changes: 24 additions & 12 deletions lib/mongodb/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,13 @@ Db.prototype.collections = function(callback) {
/**
Evaluate javascript on the server
**/
Db.prototype.eval = function(code, parameters, callback) {
if(typeof parameters === "function") { callback = parameters; parameters = null; }
Db.prototype.eval = function(code, parameters, options, callback) {
// Unpack calls
var args = Array.prototype.slice.call(arguments, 1);
callback = args.pop();
parameters = args.length ? args.shift() : parameters;
options = args.length ? args.shift() : {};

var finalCode = code;
var finalParameters = [];
// If not a code object translate to one
Expand All @@ -325,8 +330,12 @@ Db.prototype.eval = function(code, parameters, callback) {
}
// Create execution selector
var selector = {'$eval':finalCode, 'args':finalParameters};
// Check if the nolock parameter is passed in
if(options['nolock']) {
selector['nolock'] = options['nolock'];
}
// Iterate through all the fields of the index
new Cursor(this, new Collection(this, DbCommand.SYSTEM_COMMAND_COLLECTION), selector, {}, 0, -1).nextObject(function(err, result) {
new Cursor(this, new Collection(this, DbCommand.SYSTEM_COMMAND_COLLECTION), selector, options, 0, -1).nextObject(function(err, result) {
if(err != null) return callback(err, null);

if(result.ok == 1) {
Expand Down Expand Up @@ -617,17 +626,20 @@ Db.prototype.ensureIndex = function(collectionName, fieldOrSpec, options, callba

if(!collectionInfo[index_name]) {
self._executeInsertCommand(command, {read:false, safe:true}, function(err, result) {
if(err != null) return callback(err, null);

result = result && result.documents;
if (result[0].err) {
callback(self.wrap(result[0]));
} else {
callback(null, command.documents[0].name);
}
// Only callback if we have one specified
if(typeof callback === 'function') {
if(err != null) return callback(err, null);

result = result && result.documents;
if (result[0].err) {
callback(self.wrap(result[0]));
} else {
callback(null, command.documents[0].name);
}
}
});
} else {
return callback(null, index_name);
if(typeof callback === 'function') return callback(null, index_name);
}
});
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{ "name" : "mongodb"
, "description" : "A node.js driver for MongoDB"
, "keywords" : ["mongodb", "mongo", "driver", "db"]
, "version" : "0.9.7-1.4"
, "version" : "0.9.7-2"
, "author" : "Christian Amor Kvalheim <christkv@gmail.com>"
, "contributors" : [ "Aaron Heckmann",
"Christoph Pojer",
Expand Down
26 changes: 26 additions & 0 deletions test/cursor_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,32 @@ var tests = testCase({
});
});
},

shouldCorrectlyExecuteEnsureIndexWithNoCallback : function(test) {
var docs = [];

for(var i = 0; i < 1; i++) {
var d = new Date().getTime() + i*1000;
docs[i] = {createdAt:new Date(d)};
}

// Create collection
client.createCollection('shouldCorrectlyExecuteEnsureIndexWithNoCallback', function(err, collection) {
// ensure index of createdAt index
collection.ensureIndex({createdAt:1})
// insert all docs
collection.insert(docs, {safe:true}, function(err, result) {
test.equal(null, err);

// Find with sort
collection.find().sort(['createdAt', 'asc']).toArray(function(err, items) {
if (err) logger.error("error in collection_info.find: " + err);
test.equal(1, items.length);
test.done();
})
})
});
},

shouldCorrectlyInsert5000RecordsWithDateAndSortCorrectlyWithIndex : function(test) {
var docs = [];
Expand Down
4 changes: 4 additions & 0 deletions test/db_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ var tests = testCase({
client.eval('function (x) {return x;}', [3], function(err, result) {
test.equal(3, result);
});

client.eval('function (x) {return x;}', [3], {nolock:true}, function(err, result) {
test.equal(3, result);
});

client.eval('function (x) {db.test_eval.save({y:x});}', [5], function(err, result) {
// Locate the entry
Expand Down
151 changes: 151 additions & 0 deletions test/manual_tests/server_load.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#!/usr/bin/env node
var mongo = require("../../lib/mongodb");
var express = require("express");
var ObjectID = mongo.ObjectID;
var DBRef = mongo.DBRef;
var util = require("util");

var app = express.createServer();

app.configure(function() {
app.set('dbconnection', {
"port": 27017,
"host": "localhost"
});
});

app.renderResponse = function(res, err, data, allCount) {
res.header('Content-Type', 'application/json');
if(err == null) {
if(typeof allCount == "undefined")
res.send({data: data, success: true});
else
res.send({allCount: allCount, data: data, success: true});
} else {
util.log(util.inspect(err));
console.log(err.stack);
res.send({success: false, error:err.message});
}
};

app.use(express.bodyParser());
app.use(app.router);
app.use(express.logger());
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));

var isISO8601 = function(dString) {
var regexp = /(\d\d\d\d)(-)?(\d\d)(-)?(\d\d)(T)?(\d\d)(:)?(\d\d)(:)?(\d\d)(\.\d+)?(Z|([+-])(\d\d)(:)?(\d\d))?/;
if (dString.toString().match(new RegExp(regexp))) {
return true;
}
else
{
return false;
}
};


var decodeField = function(value) {
if(value == null)
return null;

if(typeof value == "object" && value['namespace'] && value['oid']) {
if(/^[0-9a-fA-F]{24}$/.test(value['oid']))
return new DBRef(value['namespace'], new ObjectID(value['oid']));
else
return new DBRef(value['namespace'], value['oid']);
}

if(isISO8601(value))
return new Date(value);

return value;
};

var deepDecode = function(obj) {
for(var i in obj)
{
if(obj[i] == null) {
// do nothing
}
else if(i == "_id" && /^[0-9a-fA-F]{24}$/.test(obj[i])) {
obj[i] = new ObjectID(obj[i]);
}
else if(typeof obj[i] == "object" && typeof obj[i]['namespace'] == "undefined" && typeof obj[i]['oid'] == "undefined") {
deepDecode(obj[i]);
}
else {
obj[i] = decodeField(obj[i]);
}
}
};

db = null;
var openConnection = function(dbname, config, callback) {
if(db) {
callback(null, db);
}
else {
var target;
target = new mongo.Server(config.host, config.port, {'auto_reconnect':true, 'poolSize':4});
db = new mongo.Db(dbname, target);
db.open(callback);
}
}

var listCommand = function (target, spec, options, next){
deepDecode(spec);
openConnection(target.db, target.connection, function(err,db) {
if(err) { next(err); return; }
// open collection
db.collection(target.collection, function(err, collection) {

if(spec._id) {
collection.findOne(spec, options, function(err, doc){
next(err, doc);
});
}
else
{
// console.dir(options)
options['limit'] = 10;

collection.find(spec, options, function(err, cursor)
{

cursor.toArray(function(err, docs)
{
next(err, docs);
//db.close();
});
});
}
});
});
}

app.get('/:db/:collection/:id?', function(req, res, next)
{
var spec = req.query.query? JSON.parse(req.query.query) : {};
spec = req.query.spec? JSON.parse(req.query.spec) : spec;

if(req.params.id)
spec._id = req.params.id;

// JSON decode options
var options = req.query.options?JSON.parse(req.query.options) : {};

listCommand({
connection: app.set("dbconnection"),
db: req.params.db,
collection: req.params.collection
},
spec,
options,
function(err, docs, allCount)
{
app.renderResponse(res, err, docs, allCount);
});
});

app.listen(9999);

0 comments on commit 9e7923f

Please sign in to comment.