Skip to content

Commit

Permalink
Fixed eval to work with system.js collection functions, Issue #709
Browse files Browse the repository at this point in the history
  • Loading branch information
christkv committed Sep 19, 2012
1 parent 3b4acf3 commit 4ba1ddb
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 27 deletions.
1 change: 1 addition & 0 deletions lib/mongodb/commands/db_command.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ DbCommand.SYSTEM_INDEX_COLLECTION = "system.indexes";
DbCommand.SYSTEM_PROFILE_COLLECTION = "system.profile";
DbCommand.SYSTEM_USER_COLLECTION = "system.users";
DbCommand.SYSTEM_COMMAND_COLLECTION = "$cmd";
DbCommand.SYSTEM_JS_COLLECTION = "system.js";

// New commands
DbCommand.NcreateIsMasterCommand = function(db, databaseName) {
Expand Down
16 changes: 2 additions & 14 deletions lib/mongodb/cursor.js
Original file line number Diff line number Diff line change
Expand Up @@ -658,22 +658,10 @@ Cursor.prototype.explain = function(callback) {
};

/**
* Returns a stream object that can be used to listen to and stream records
* (**Use the CursorStream object instead as this is deprected**)
*
* Options
* - **fetchSize** {Number} the number of records to fetch in each batch (steam specific batchSize).
*
* Events
* - **data** {function(item) {}} the data event triggers when a document is ready.
* - **error** {function(err) {}} the error event triggers if an error happens.
* - **end** {function() {}} the end event triggers when there is no more documents available.
*
* @param {Object} [options] additional options for streamRecords.
* @return {EventEmitter} returns a stream object.
* @api public
* @ignore
*/
Cursor.prototype.streamRecords = function(options) {
console.log("[WARNING] streamRecords method is deprecated, please use stream method which is much faster");
var args = Array.prototype.slice.call(arguments, 0);
options = args.length ? args.shift() : {};

Expand Down
24 changes: 14 additions & 10 deletions lib/mongodb/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -533,24 +533,28 @@ Db.prototype.eval = function(code, parameters, options, callback) {
} else if(parameters != null && parameters.constructor == Array && typeof parameters !== 'function') {
finalParameters = parameters;
}

// 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, options, 0, -1)
.setReadPreference(ReadPreference.PRIMARY)
.nextObject(function(err, result) {
if(err != null) return callback(err, null);
// Set primary read preference
options.readPreference = ReadPreference.PRIMARY;

if(result.ok == 1) {
callback(null, result.retval);
} else {
callback(new Error("eval failed: " + result.errmsg), null); return;
}
// Execute the eval
this.collection(DbCommand.SYSTEM_COMMAND_COLLECTION).findOne(selector, options, function(err, result) {
if(err) return callback(err);

if(result && result.ok == 1) {
callback(null, result.retval);
} else if(result) {
callback(new Error("eval failed: " + result.errmsg), null); return;
} else {
callback(err, result);
}
});
};

Expand Down
38 changes: 35 additions & 3 deletions test/db_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ exports.shouldCorrectlyExecuteEvalFunctions = function(test) {

// Establish connection to db
db.open(function(err, db) {
var numberOfTests =

// Evaluate a function on the server with the parameter 3 passed in
db.eval('function (x) {return x;}', [3], function(err, result) {
Expand Down Expand Up @@ -234,19 +235,50 @@ exports.shouldCorrectlyExecuteEvalFunctions = function(test) {
// Evaluate a statement using the code object including a scope
db.eval(new Code("i + 3;", {'i':2}), function(err, result) {
test.equal(5, result);
test.done();
});

// Evaluate an illegal statement
db.eval("5 ++ 5;", function(err, result) {
test.ok(err instanceof Error);
test.ok(err.message != null);
// Let's close the db
db.close();
test.done();
});
});
}

db.close();
test.done();
/**
* Defining and calling a system level javascript function (NOT recommended, http://www.mongodb.org/display/DOCS/Server-side+Code+Execution)
*
* @_class db
* @_function eval
* @ignore
*/
exports.shouldCorrectlyDefineSystemLevelFunctionAndExecuteFunction = function(test) {
var db = new Db('integration_tests', new Server("127.0.0.1", 27017,
{auto_reconnect: false, poolSize: 1, ssl:useSSL}), {native_parser: native_parser});

// Establish connection to db
db.open(function(err, db) {

// Clean out the collection
db.collection("system.js").remove({}, {safe:true}, function(err, result) {
test.equal(null, err);

// Define a system level function
db.collection("system.js").insert({_id: "echo", value: new Code("function(x) { return x; }")}, {safe:true}, function(err, result) {
test.equal(null, err);

db.eval("echo(5)", function(err, result) {
test.equal(null, err);
test.equal(5, result);

db.close();
test.done();
});
});
});
});
}

Expand Down

0 comments on commit 4ba1ddb

Please sign in to comment.