diff options
author | Eliot Horowitz <ehorowitz@shopwiki.com> | 2008-09-14 12:39:49 -0400 |
---|---|---|
committer | Eliot Horowitz <ehorowitz@shopwiki.com> | 2008-09-14 12:39:49 -0400 |
commit | 54668a9afecd39d21d77003bcc20991bddee2090 (patch) | |
tree | 2bb812569929148dc128467472a2695ee39317a4 | |
parent | 5fa38bdeadc90f7733497be9ade32d85b16e69c8 (diff) | |
download | mongo-54668a9afecd39d21d77003bcc20991bddee2090.tar.gz |
can pass functions with scopes
-rw-r--r-- | db/javajs.cpp | 14 | ||||
-rw-r--r-- | db/javajs.h | 2 | ||||
-rw-r--r-- | db/jsobj.cpp | 4 | ||||
-rw-r--r-- | db/jsobj.h | 3 | ||||
-rw-r--r-- | db/matcher.cpp | 38 |
5 files changed, 49 insertions, 12 deletions
diff --git a/db/javajs.cpp b/db/javajs.cpp index 6cb7dd2e5e3..e0bfc4ce0ce 100644 --- a/db/javajs.cpp +++ b/db/javajs.cpp @@ -180,6 +180,7 @@ JavaJSImpl::JavaJSImpl(const char *appserverPath){ jassert( _dbjni ); _scopeCreate = _mainEnv->GetStaticMethodID( _dbhook , "scopeCreate" , "()J" ); + _scopeInit = _mainEnv->GetStaticMethodID( _dbhook , "scopeInit" , "(JLjava/nio/ByteBuffer;)Z" ); _scopeReset = _mainEnv->GetStaticMethodID( _dbhook , "scopeReset" , "(J)Z" ); _scopeFree = _mainEnv->GetStaticMethodID( _dbhook , "scopeFree" , "(J)V" ); @@ -199,6 +200,7 @@ JavaJSImpl::JavaJSImpl(const char *appserverPath){ _invoke = _mainEnv->GetStaticMethodID( _dbhook , "invoke" , "(JJ)I" ); jassert( _scopeCreate ); + jassert( _scopeInit ); jassert( _scopeReset ); jassert( _scopeFree ); @@ -278,6 +280,16 @@ int JavaJSImpl::scopeSetObject( jlong id , const char * field , JSObj * obj ){ return _getEnv()->CallStaticBooleanMethod( _dbhook , _scopeSetObject , id , _getEnv()->NewStringUTF( field ) , bb ); } +int JavaJSImpl::scopeInit( jlong id , JSObj * obj ){ + if ( ! obj ) + return 0; + + jobject bb = _getEnv()->NewDirectByteBuffer( (void*)(obj->objdata()) , (jlong)(obj->objsize()) ); + jassert( bb ); + + return _getEnv()->CallStaticBooleanMethod( _dbhook , _scopeInit , id , bb ); +} + // scope getters char JavaJSImpl::scopeGetType( jlong id , const char * field ){ @@ -540,7 +552,7 @@ int javajstest() { if ( debug ) cout << "func5 start" << endl; jassert( JavaJS.scopeSetObject( scope , "c" , &obj ) ); - jlong func5 = JavaJS.functionCreate( "assert( 517 == c.foo );" ); + jlong func5 = JavaJS.functionCreate( "assert.eq( 517 , c.foo );" ); jassert( func5 ); jassert( ! JavaJS.invoke( scope , func5 ) ); if ( debug ) cout << "func5 done" << endl; diff --git a/db/javajs.h b/db/javajs.h index af904fa7c90..95f7625f485 100644 --- a/db/javajs.h +++ b/db/javajs.h @@ -52,6 +52,7 @@ class JavaJSImpl { ~JavaJSImpl(); jlong scopeCreate(); + int scopeInit( jlong id , JSObj * obj ); jboolean scopeReset( jlong id ); void scopeFree( jlong id ); @@ -117,6 +118,7 @@ class JavaJSImpl { jclass _dbjni; jmethodID _scopeCreate; + jmethodID _scopeInit; jmethodID _scopeReset; jmethodID _scopeFree; diff --git a/db/jsobj.cpp b/db/jsobj.cpp index 8687321f3e4..6894cd79741 100644 --- a/db/jsobj.cpp +++ b/db/jsobj.cpp @@ -104,6 +104,10 @@ int Element::size() const { case String: x = valuestrsize() + 4 + 1; break; + case CodeWScope: + x = objsize() + 1; + break; + case DBRef: x = valuestrsize() + 4 + 12 + 1; break; diff --git a/db/jsobj.h b/db/jsobj.h index 810442def45..b7489412a85 100644 --- a/db/jsobj.h +++ b/db/jsobj.h @@ -36,7 +36,7 @@ class JSObjBuilder; */ enum JSType { EOO = 0, Number=1, String=2, Object=3, Array=4, BinData=5, Undefined=6, jstOID=7, Bool=8, Date=9 , jstNULL=10, RegEx=11 , - DBRef=12, Code=13, Symbol=14, JSTypeMax=14, MaxKey=127 }; + DBRef=12, Code=13, Symbol=14, CodeWScope=15 , JSTypeMax=15, MaxKey=127 }; /* subtypes of BinData. bdtCustom and above are ones that the JS compiler understands, but are @@ -75,6 +75,7 @@ struct OID { BinData: <int len> <byte subtype> <byte[len] data> Code: a function (not a closure): same format as String. Symbol: a language symbol (say a python symbol). same format as String. + Code With Scope: <total size><String><Object> */ #pragma pack(pop) diff --git a/db/matcher.cpp b/db/matcher.cpp index 24c5fdf8ab8..fe8f259871e 100644 --- a/db/matcher.cpp +++ b/db/matcher.cpp @@ -66,10 +66,12 @@ MiniLex minilex; class Where { public: - Where() { codeCopy = 0; } + Where() { codeCopy = 0; jsScope = 0; } ~Where() { JavaJS->scopeFree(scope); delete codeCopy; + if ( jsScope ) + delete jsScope; scope = 0; func = 0; codeCopy = 0; } jlong scope, func; @@ -78,7 +80,8 @@ public: bool fullObject; int nFields; char *codeCopy; - + JSObj *jsScope; + void setFunc(const char *code) { codeCopy = new char[strlen(code)+1]; strcpy(codeCopy,code); @@ -124,23 +127,32 @@ JSMatcher::JSMatcher(JSObj &_jsobj) : in(0), where(0), jsobj(_jsobj), nRegex(0) { nBuilders = 0; - + JSElemIter i(jsobj); n = 0; while( i.more() ) { Element e = i.next(); if( e.eoo() ) break; - - if( e.type() == Code && strcmp(e.fieldName(), "$where")==0 ) { + + if( ( e.type() == CodeWScope || e.type() == Code ) && strcmp(e.fieldName(), "$where")==0 ) { // $where: function()... assert( where == 0 ); where = new Where(); - const char *code = e.valuestr(); massert( "$where query, but jni is disabled", JavaJS ); where->scope = JavaJS->scopeCreate(); JavaJS->scopeSetString(where->scope, "$client", client->name.c_str()); - where->setFunc(code); + + if ( e.type() == CodeWScope ){ + const char *code = (e.value() + 8); + where->setFunc(code); + where->jsScope = new JSObj( code + strlen( code ) + 1 , 0 ); + } + else { + const char *code = e.valuestr(); + where->setFunc(code); + } + continue; } @@ -401,9 +413,15 @@ bool JSMatcher::matches(JSObj& jsobj, bool *deep) { if( where ) { if( where->func == 0 ) return false; // didn't compile - if( jsobj.objsize() < 200 || where->fullObject ) { - JavaJS->scopeSetObject(where->scope, "obj", &jsobj); - } else { + + if( 1 || jsobj.objsize() < 200 || where->fullObject ) { + if ( where->jsScope ){ + cout << "jsScope->objsize " << where->jsScope->objsize() << endl; + JavaJS->scopeInit( where->scope , where->jsScope ); + } + JavaJS->scopeSetObject(where->scope, "obj", &jsobj); + } + else { JSObjBuilder b; where->buildSubset(jsobj, b); JSObj temp = b.done(); |