summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Horowitz <ehorowitz@shopwiki.com>2008-09-14 12:39:49 -0400
committerEliot Horowitz <ehorowitz@shopwiki.com>2008-09-14 12:39:49 -0400
commit54668a9afecd39d21d77003bcc20991bddee2090 (patch)
tree2bb812569929148dc128467472a2695ee39317a4
parent5fa38bdeadc90f7733497be9ade32d85b16e69c8 (diff)
downloadmongo-54668a9afecd39d21d77003bcc20991bddee2090.tar.gz
can pass functions with scopes
-rw-r--r--db/javajs.cpp14
-rw-r--r--db/javajs.h2
-rw-r--r--db/jsobj.cpp4
-rw-r--r--db/jsobj.h3
-rw-r--r--db/matcher.cpp38
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();