summaryrefslogtreecommitdiff
path: root/src/mongo/db/dbeval.cpp
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2011-12-24 15:33:26 -0500
committerEliot Horowitz <eliot@10gen.com>2011-12-24 15:33:45 -0500
commitae1ecd9c786911f9f1f0242f0f7d702b3e5dfeba (patch)
tree92f8e1649e6f080b251ff5f1763679a72eb59b34 /src/mongo/db/dbeval.cpp
parentdfa4cd7e2cf109b072440155fabc08a93c8045a0 (diff)
downloadmongo-ae1ecd9c786911f9f1f0242f0f7d702b3e5dfeba.tar.gz
bulk move of code to src/ SERVER-4551
Diffstat (limited to 'src/mongo/db/dbeval.cpp')
-rw-r--r--src/mongo/db/dbeval.cpp136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/mongo/db/dbeval.cpp b/src/mongo/db/dbeval.cpp
new file mode 100644
index 00000000000..9e77d8c8097
--- /dev/null
+++ b/src/mongo/db/dbeval.cpp
@@ -0,0 +1,136 @@
+/* commands.cpp
+ db "commands" (sent via db.$cmd.findOne(...))
+ */
+
+/**
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "pch.h"
+#include "ops/query.h"
+#include "pdfile.h"
+#include "jsobj.h"
+#include "../bson/util/builder.h"
+#include <time.h>
+#include "introspect.h"
+#include "btree.h"
+#include "../util/lruishmap.h"
+#include "json.h"
+#include "repl.h"
+#include "commands.h"
+#include "cmdline.h"
+
+#include "../scripting/engine.h"
+
+namespace mongo {
+
+ const int edebug=0;
+
+ bool dbEval(const string& dbName, BSONObj& cmd, BSONObjBuilder& result, string& errmsg) {
+ BSONElement e = cmd.firstElement();
+ uassert( 10046 , "eval needs Code" , e.type() == Code || e.type() == CodeWScope || e.type() == String );
+
+ const char *code = 0;
+ switch ( e.type() ) {
+ case String:
+ case Code:
+ code = e.valuestr();
+ break;
+ case CodeWScope:
+ code = e.codeWScopeCode();
+ break;
+ default:
+ assert(0);
+ }
+ assert( code );
+
+ if ( ! globalScriptEngine ) {
+ errmsg = "db side execution is disabled";
+ return false;
+ }
+
+ auto_ptr<Scope> s = globalScriptEngine->getPooledScope( dbName );
+ ScriptingFunction f = s->createFunction(code);
+ if ( f == 0 ) {
+ errmsg = (string)"compile failed: " + s->getError();
+ return false;
+ }
+
+ if ( e.type() == CodeWScope )
+ s->init( e.codeWScopeScopeData() );
+ s->localConnect( dbName.c_str() );
+
+ BSONObj args;
+ {
+ BSONElement argsElement = cmd.getField("args");
+ if ( argsElement.type() == Array ) {
+ args = argsElement.embeddedObject();
+ if ( edebug ) {
+ out() << "args:" << args.toString() << endl;
+ out() << "code:\n" << code << endl;
+ }
+ }
+ }
+
+ int res;
+ {
+ Timer t;
+ res = s->invoke(f, &args, 0, cmdLine.quota ? 10 * 60 * 1000 : 0 );
+ int m = t.millis();
+ if ( m > cmdLine.slowMS ) {
+ out() << "dbeval slow, time: " << dec << m << "ms " << dbName << endl;
+ if ( m >= 1000 ) log() << code << endl;
+ else OCCASIONALLY log() << code << endl;
+ }
+ }
+ if ( res ) {
+ result.append("errno", (double) res);
+ errmsg = "invoke failed: ";
+ errmsg += s->getError();
+ return false;
+ }
+
+ s->append( result , "retval" , "return" );
+
+ return true;
+ }
+
+ class CmdEval : public Command {
+ public:
+ virtual bool slaveOk() const {
+ return false;
+ }
+ virtual void help( stringstream &help ) const {
+ help << "Evaluate javascript at the server.\n" "http://www.mongodb.org/display/DOCS/Server-side+Code+Execution";
+ }
+ virtual LockType locktype() const { return NONE; }
+ CmdEval() : Command("eval", false, "$eval") { }
+ bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
+
+ AuthenticationInfo *ai = cc().getAuthenticationInfo();
+ uassert( 12598 , "$eval reads unauthorized", ai->isAuthorizedReads(dbname.c_str()) );
+
+ if ( cmdObj["nolock"].trueValue() ) {
+ return dbEval(dbname, cmdObj, result, errmsg);
+ }
+
+ // write security will be enforced in DBDirectClient
+ mongolock lk( ai->isAuthorized( dbname.c_str() ) );
+ Client::Context ctx( dbname );
+
+ return dbEval(dbname, cmdObj, result, errmsg);
+ }
+ } cmdeval;
+
+} // namespace mongo