summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dbtests/jstests.cpp20
-rw-r--r--mongo.xcodeproj/project.pbxproj6
-rw-r--r--scripting/engine_spidermonkey.cpp5
-rw-r--r--scripting/sm_db.cpp28
4 files changed, 42 insertions, 17 deletions
diff --git a/dbtests/jstests.cpp b/dbtests/jstests.cpp
index 20b32089c6f..6ab3e0c2b39 100644
--- a/dbtests/jstests.cpp
+++ b/dbtests/jstests.cpp
@@ -704,6 +704,25 @@ namespace JSTests {
const char * _b;
};
+ class InformalDBRef {
+ public:
+ void run() {
+ client.insert( ns(), BSON( "i" << 1 ) );
+ BSONObj obj = client.findOne( ns(), BSONObj() );
+ client.remove( ns(), BSONObj() );
+ client.insert( ns(), BSON( "r" << BSON( "$ref" << "jstests.informaldbref" << "$id" << obj["_id"].__oid() << "foo" << "bar" ) ) );
+ obj = client.findOne( ns(), BSONObj() );
+ ASSERT_EQUALS( "bar", obj[ "r" ].embeddedObject()[ "foo" ].str() );
+
+ ASSERT( client.eval( "unittest", "x = db.jstests.informaldbref.findOne(); y = { r:x.r }; db.jstests.informaldbref.drop(); y.r[ \"a\" ] = \"b\"; db.jstests.informaldbref.save( y );" ) );
+ obj = client.findOne( ns(), BSONObj() );
+ ASSERT_EQUALS( "bar", obj[ "r" ].embeddedObject()[ "foo" ].str() );
+ ASSERT_EQUALS( "b", obj[ "r" ].embeddedObject()[ "a" ].str() );
+ }
+ private:
+ static const char *ns() { return "unittest.jstests.informaldbref"; }
+ };
+
class BinDataType {
public:
@@ -807,6 +826,7 @@ namespace JSTests {
add< LongUtf8String >();
add< CodeTests >();
add< DBRefTest >();
+ add< InformalDBRef >();
add< BinDataType >();
add< VarTests >();
diff --git a/mongo.xcodeproj/project.pbxproj b/mongo.xcodeproj/project.pbxproj
index 48005c6dcd1..731b0da6360 100644
--- a/mongo.xcodeproj/project.pbxproj
+++ b/mongo.xcodeproj/project.pbxproj
@@ -469,6 +469,9 @@
93B9F76A112B6C020066ECD2 /* snapshot1.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = snapshot1.js; sourceTree = "<group>"; };
93B9F76B112B6C1D0066ECD2 /* snapshot2.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = snapshot2.js; sourceTree = "<group>"; };
93B9F7E6112B98710066ECD2 /* snapshot3.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = snapshot3.js; sourceTree = "<group>"; };
+ 93B9F91A112C7F200066ECD2 /* set4.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = set4.js; sourceTree = "<group>"; };
+ 93B9F91B112C7F200066ECD2 /* set5.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = set5.js; sourceTree = "<group>"; };
+ 93B9F91C112C7F200066ECD2 /* set6.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = set6.js; sourceTree = "<group>"; };
93BC2AE10FB87662006BC285 /* cursortests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cursortests.cpp; sourceTree = "<group>"; };
93BC2AE20FB87662006BC285 /* jstests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = jstests.cpp; sourceTree = "<group>"; };
93BCE15610F25DFE00FA139B /* arrayfind1.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = arrayfind1.js; sourceTree = "<group>"; };
@@ -739,6 +742,9 @@
934BEB9A10DFFA9600178102 /* jstests */ = {
isa = PBXGroup;
children = (
+ 93B9F91A112C7F200066ECD2 /* set4.js */,
+ 93B9F91B112C7F200066ECD2 /* set5.js */,
+ 93B9F91C112C7F200066ECD2 /* set6.js */,
93B9F671112B3AD40066ECD2 /* copyauth.js */,
93D5A8921117A1380052C931 /* regex6.js */,
938E639A110FC66900A8760A /* auth */,
diff --git a/scripting/engine_spidermonkey.cpp b/scripting/engine_spidermonkey.cpp
index 7b7527723bf..294431c6e35 100644
--- a/scripting/engine_spidermonkey.cpp
+++ b/scripting/engine_spidermonkey.cpp
@@ -453,8 +453,7 @@ namespace mongo {
if ( ref == obj->firstElement().fieldName() ){
JSObject * o = JS_NewObject( _context , &dbref_class , NULL, NULL);
assert( o );
- setProperty( o , "$ref" , toval( obj->firstElement() ) );
- setProperty( o , "$id" , toval( (*obj)["$id"] ) );
+ assert( JS_SetPrivate( _context , o , (void*)(new BSONHolder( obj->getOwned() ) ) ) );
return o;
}
JSObject * o = JS_NewObject( _context , readOnly ? &bson_ro_class : &bson_class , NULL, NULL);
@@ -768,6 +767,8 @@ namespace mongo {
JSBool mark_modified( JSContext *cx, JSObject *obj, jsval idval, jsval *vp){
Convertor c(cx);
BSONHolder * holder = GETHOLDER( cx , obj );
+ if ( !holder ) // needed when we're messing with DBRef.prototype
+ return JS_TRUE;
if ( holder->_inResolve )
return JS_TRUE;
holder->_modified = true;
diff --git a/scripting/sm_db.cpp b/scripting/sm_db.cpp
index d3db026a635..ca4526a3c40 100644
--- a/scripting/sm_db.cpp
+++ b/scripting/sm_db.cpp
@@ -563,29 +563,24 @@ namespace mongo {
JSBool dbref_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ){
Convertor c( cx );
-
+
if ( argc == 2 ){
- assert( JS_SetProperty( cx , obj , "$ref" , &(argv[0]) ) );
- assert( JS_SetProperty( cx , obj , "$id" , &(argv[1]) ) );
+ JSObject * o = JS_NewObject( cx , NULL , NULL, NULL );
+ assert( o );
+ assert( JS_SetProperty( cx, o , "$ref" , &argv[ 0 ] ) );
+ assert( JS_SetProperty( cx, o , "$id" , &argv[ 1 ] ) );
+ BSONObj bo = c.toObject( o );
+ assert( JS_SetPrivate( cx , obj , (void*)(new BSONHolder( bo.getOwned() ) ) ) );
return JS_TRUE;
}
else {
JS_ReportError( cx , "DBRef needs 2 arguments" );
+ assert( JS_SetPrivate( cx , obj , (void*)(new BSONHolder( BSONObj().getOwned() ) ) ) );
return JS_FALSE;
}
}
- JSClass dbref_class = {
- "DBRef" , JSCLASS_HAS_PRIVATE ,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, JS_FinalizeStub,
- JSCLASS_NO_OPTIONAL_MEMBERS
- };
-
- JSFunctionSpec dbref_functions[] = {
- { 0 }
- };
-
+ JSClass dbref_class = bson_class; // name will be fixed later
// BinData
@@ -817,7 +812,6 @@ namespace mongo {
assert( JS_InitClass( cx , global , 0 , &internal_cursor_class , internal_cursor_constructor , 0 , 0 , internal_cursor_functions , 0 , 0 ) );
assert( JS_InitClass( cx , global , 0 , &dbquery_class , dbquery_constructor , 0 , 0 , 0 , 0 , 0 ) );
assert( JS_InitClass( cx , global , 0 , &dbpointer_class , dbpointer_constructor , 0 , 0 , dbpointer_functions , 0 , 0 ) );
- assert( JS_InitClass( cx , global , 0 , &dbref_class , dbref_constructor , 0 , 0 , dbref_functions , 0 , 0 ) );
assert( JS_InitClass( cx , global , 0 , &bindata_class , bindata_constructor , 0 , 0 , bindata_functions , 0 , 0 ) );
assert( JS_InitClass( cx , global , 0 , &timestamp_class , 0 , 0 , 0 , 0 , 0 , 0 ) );
@@ -830,6 +824,10 @@ namespace mongo {
assert( JS_InitClass( cx , global , 0 , &bson_ro_class , bson_cons , 0 , 0 , bson_functions , 0 , 0 ) );
assert( JS_InitClass( cx , global , 0 , &bson_class , bson_cons , 0 , 0 , bson_functions , 0 , 0 ) );
+ static const char *dbrefName = "DBRef";
+ dbref_class.name = dbrefName;
+ assert( JS_InitClass( cx , global , 0 , &dbref_class , dbref_constructor , 2 , 0 , bson_functions , 0 , 0 ) );
+
scope->exec( jsconcatcode );
}