From 4bf96beb17cdcb698a5711b87fde339a4a6efbe3 Mon Sep 17 00:00:00 2001 From: Eliot Horowitz Date: Wed, 13 May 2009 17:27:45 -0400 Subject: [PATCH] Spider Monkey Shell: another checkpoint --- scripting/engine.h | 1 + scripting/engine_spidermonkey.cpp | 10 ++++++++-- scripting/sm_db.cpp | 33 ++++++++++++++++++++++--------- shell/collection.js | 1 + shell/dbshell.cpp | 13 +++++------- 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/scripting/engine.h b/scripting/engine.h index ce3c739b72b..748478e3d40 100644 --- a/scripting/engine.h +++ b/scripting/engine.h @@ -25,6 +25,7 @@ namespace mongo { } virtual void localConnect( const char * dbName ) = 0; + virtual void externalSetup() = 0; virtual double getNumber( const char *field ) = 0; virtual string getString( const char *field ) = 0; diff --git a/scripting/engine_spidermonkey.cpp b/scripting/engine_spidermonkey.cpp index d7a4ede1352..d0fb1018234 100644 --- a/scripting/engine_spidermonkey.cpp +++ b/scripting/engine_spidermonkey.cpp @@ -586,6 +586,10 @@ namespace mongo { } + void externalSetup(){ + initMongoJS( this , _context , _global , false ); + } + void localConnect( const char * dbName ){ initMongoJS( this , _context , _global , true ); @@ -684,8 +688,10 @@ namespace mongo { if ( assertOnError ) uassert( name + " exec failed" , worked ); - if ( reportError && ! _error.empty() ) - cout << "exec error: " << _error << endl; + if ( reportError && ! _error.empty() ){ + // cout << "exec error: " << _error << endl; + // already printed in reportError, so... TODO + } if ( worked && printResult && ! JSVAL_IS_VOID( ret ) ) cout << _convertor->toString( ret ) << endl; diff --git a/scripting/sm_db.cpp b/scripting/sm_db.cpp index ab8e5ac08a2..ba191f01446 100644 --- a/scripting/sm_db.cpp +++ b/scripting/sm_db.cpp @@ -93,6 +93,28 @@ namespace mongo { return JS_TRUE; } + JSBool mongo_external_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ){ + Convertor c( cx ); + + uassert( "0 or 1 args to Mongo" , argc <= 1 ); + + DBClientConnection * conn = new DBClientConnection( true ); + + string host = "127.0.0.1"; + if ( argc > 0 ) + host = c.toString( argv[0] ); + + string errmsg; + if ( ! conn->connect( host , errmsg ) ){ + JS_ReportError( cx , ((string)"couldn't connect: " + errmsg).c_str() ); + return JS_FALSE; + } + + JS_SetPrivate( cx , obj , (void*)conn ); + return JS_TRUE; + + } + void mongo_finalize( JSContext * cx , JSObject * obj ){ DBClientBase * client = (DBClientBase*)JS_GetPrivate( cx , obj ); if ( client ){ @@ -106,13 +128,6 @@ namespace mongo { JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, mongo_finalize, JSCLASS_NO_OPTIONAL_MEMBERS - }; - - JSClass mongo_local_class = { - "Mongo" , JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE , - JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, - JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, mongo_finalize, - JSCLASS_NO_OPTIONAL_MEMBERS }; JSBool mongo_find(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ @@ -380,9 +395,9 @@ namespace mongo { // ---- other stuff ---- void initMongoJS( SMScope * scope , JSContext * cx , JSObject * global , bool local ){ - uassert( "non-local not supported yet" , local ); - assert( JS_InitClass( cx , global , 0 , &mongo_local_class , mongo_local_constructor , 0 , 0 , mongo_functions , 0 , 0 ) ); + assert( JS_InitClass( cx , global , 0 , &mongo_class , local ? mongo_local_constructor : mongo_external_constructor , 0 , 0 , mongo_functions , 0 , 0 ) ); + assert( JS_InitClass( cx , global , 0 , &object_id_class , object_id_constructor , 0 , 0 , object_id_functions , 0 , 0 ) ); assert( JS_InitClass( cx , global , 0 , &db_class , db_constructor , 2 , 0 , 0 , 0 , 0 ) ); assert( JS_InitClass( cx , global , 0 , &db_collection_class , db_collection_constructor , 4 , 0 , 0 , 0 , 0 ) ); diff --git a/shell/collection.js b/shell/collection.js index 71e4ef42980..c1483675229 100644 --- a/shell/collection.js +++ b/shell/collection.js @@ -125,6 +125,7 @@ DBCollection.prototype.update = function( query , obj , upsert ){ DBCollection.prototype.save = function( obj ){ if ( ! obj._id ){ + obj._id = new ObjectId(); return this.insert( obj ); } else { diff --git a/shell/dbshell.cpp b/shell/dbshell.cpp index edc083733b6..8e91911b106 100644 --- a/shell/dbshell.cpp +++ b/shell/dbshell.cpp @@ -238,30 +238,27 @@ int main(int argc, char* argv[]) { break; } + + scope->externalSetup(); - /* if ( !nodb ) { // connect to db - v8::HandleScope handle_scope; cout << "url: " << url << endl; string setup = (string)"db = connect( \"" + fixHost( url , dbhost , port ) + "\")"; - if ( ! ExecuteString( v8::String::New( setup.c_str() ) , v8::String::New( "(connect)" ) , false , true ) ){ + if ( ! scope->exec( setup , "(connect)" , false , true , false ) ) return -1; - } - + if ( username.size() && password.size() ){ stringstream ss; ss << "if ( ! db.auth( \"" << username << "\" , \"" << password << "\" ) ){ throw 'login failed'; }"; - if ( ! ExecuteString( v8::String::New( ss.str().c_str() ) , v8::String::New( "(auth)" ) , true , true ) ){ + if ( ! scope->exec( ss.str() , "(auth)" , true , true , false ) ){ cout << "login failed" << endl; return -1; } - } } - */ int numFiles = 0;