summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/json.cpp69
-rw-r--r--src/mongo/dbtests/jsontests.cpp45
-rw-r--r--src/mongo/dbtests/jstests.cpp27
3 files changed, 81 insertions, 60 deletions
diff --git a/src/mongo/db/json.cpp b/src/mongo/db/json.cpp
index 74fac9f1b3c..afe08f3b0f5 100644
--- a/src/mongo/db/json.cpp
+++ b/src/mongo/db/json.cpp
@@ -465,6 +465,9 @@ namespace mongo {
}
Status JParse::dbRefObject(const StringData& fieldName, BSONObjBuilder& builder) {
+
+ BSONObjBuilder subBuilder(builder.subobjStart(fieldName));
+
if (!accept(COLON)) {
return parseError("Expecting ':'");
}
@@ -474,6 +477,8 @@ namespace mongo {
if (ret != Status::OK()) {
return ret;
}
+ subBuilder.append("$ref", ns);
+
if (!accept(COMMA)) {
return parseError("Expecting ','");
}
@@ -484,42 +489,12 @@ namespace mongo {
if (!accept(COLON)) {
return parseError("Expecting ':'");
}
- if (accept("ObjectId")) {
- BSONObjBuilder subBuilder(builder.subobjStart(fieldName));
- subBuilder.append("$ref", ns);
- objectId("$id", subBuilder);
- subBuilder.done();
- }
- else if (accept(LBRACE)) {
- BSONObjBuilder subBuilder(builder.subobjStart(fieldName));
- subBuilder.append("$ref", ns);
- if (!acceptField("$oid")) {
- return parseError("Expected field name: \"$oid\"");
- }
- objectIdObject("$id", subBuilder);
- subBuilder.done();
- if (!accept(RBRACE)) {
- return parseError("Expecting '}'");
- }
- }
- else {
- std::string id;
- id.reserve(ID_RESERVE_SIZE);
- Status ret = quotedString(&id);
- if (ret != Status::OK()) {
- return ret;
- }
- if (id.size() != 24) {
- return parseError("Expecting 24 hex digits: " + id);
- }
- if (!isHexString(id)) {
- return parseError("Expecting hex digits: " + id);
- }
- BSONObjBuilder subBuilder(builder.subobjStart(fieldName));
- subBuilder.append("$ref", ns);
- subBuilder.append("$id", OID(id));
- subBuilder.done();
+ Status valueRet = value("$id", subBuilder);
+ if (valueRet != Status::OK()) {
+ return valueRet;
}
+
+ subBuilder.done();
return Status::OK();
}
@@ -661,6 +636,8 @@ namespace mongo {
}
Status JParse::dbRef(const StringData& fieldName, BSONObjBuilder& builder) {
+ BSONObjBuilder subBuilder(builder.subobjStart(fieldName));
+
if (!accept(LPAREN)) {
return parseError("Expecting '('");
}
@@ -670,27 +647,21 @@ namespace mongo {
if (refRet != Status::OK()) {
return refRet;
}
+ subBuilder.append("$ref", ns);
+
if (!accept(COMMA)) {
return parseError("Expecting ','");
}
- std::string id;
- id.reserve(ID_RESERVE_SIZE);
- Status idRet = quotedString(&id);
- if (idRet != Status::OK()) {
- return idRet;
- }
- if (id.size() != 24) {
- return parseError("Expecting 24 hex digits: " + id);
- }
- if (!isHexString(id)) {
- return parseError("Expecting hex digits: " + id);
+
+ Status valueRet = value("$id", subBuilder);
+ if (valueRet != Status::OK()) {
+ return valueRet;
}
+
if (!accept(RPAREN)) {
return parseError("Expecting ')'");
}
- BSONObjBuilder subBuilder(builder.subobjStart(fieldName));
- subBuilder.append("$ref", ns);
- subBuilder.append("$id", OID(id));
+
subBuilder.done();
return Status::OK();
}
diff --git a/src/mongo/dbtests/jsontests.cpp b/src/mongo/dbtests/jsontests.cpp
index 0afee14a37b..98a5624dbd4 100644
--- a/src/mongo/dbtests/jsontests.cpp
+++ b/src/mongo/dbtests/jsontests.cpp
@@ -860,11 +860,9 @@ namespace JsonTests {
class DBRefConstructor : public Base {
virtual BSONObj bson() const {
BSONObjBuilder b;
- OID o;
- memset( &o, 0, 12 );
BSONObjBuilder subBuilder(b.subobjStart("a"));
subBuilder.append("$ref", "ns");
- subBuilder.append("$id", o);
+ subBuilder.append("$id", "000000000000000000000000");
subBuilder.done();
return b.obj();
}
@@ -877,11 +875,9 @@ namespace JsonTests {
class DBRefConstructorCapitals : public Base {
virtual BSONObj bson() const {
BSONObjBuilder b;
- OID o;
- memset( &o, 0, 12 );
BSONObjBuilder subBuilder(b.subobjStart("a"));
subBuilder.append("$ref", "ns");
- subBuilder.append("$id", o);
+ subBuilder.append("$id", "000000000000000000000000");
subBuilder.done();
return b.obj();
}
@@ -890,14 +886,40 @@ namespace JsonTests {
}
};
- class DBRefObjectIDString : public Base {
+ class DBRefConstructorNumber : public Base {
virtual BSONObj bson() const {
BSONObjBuilder b;
- OID o;
- memset( &o, 0, 12 );
BSONObjBuilder subBuilder(b.subobjStart("a"));
subBuilder.append("$ref", "ns");
- subBuilder.append("$id", o);
+ subBuilder.append("$id", 1);
+ subBuilder.done();
+ return b.obj();
+ }
+ virtual string json() const {
+ return "{ \"a\" : Dbref( \"ns\", 1 ) }";
+ }
+ };
+
+ class DBRefNumberId : public Base {
+ virtual BSONObj bson() const {
+ BSONObjBuilder b;
+ BSONObjBuilder subBuilder(b.subobjStart("a"));
+ subBuilder.append("$ref", "ns");
+ subBuilder.append("$id", 1);
+ subBuilder.done();
+ return b.obj();
+ }
+ virtual string json() const {
+ return "{ \"a\" : { \"$ref\" : \"ns\", \"$id\" : 1 } }";
+ }
+ };
+
+ class DBRefStringId : public Base {
+ virtual BSONObj bson() const {
+ BSONObjBuilder b;
+ BSONObjBuilder subBuilder(b.subobjStart("a"));
+ subBuilder.append("$ref", "ns");
+ subBuilder.append("$id", "000000000000000000000000");
subBuilder.done();
return b.obj();
}
@@ -1605,7 +1627,8 @@ namespace JsonTests {
add< FromJsonTests::Utf8TooShort >();
add< FromJsonTests::DBRefConstructor >();
add< FromJsonTests::DBRefConstructorCapitals >();
- add< FromJsonTests::DBRefObjectIDString >();
+ add< FromJsonTests::DBRefNumberId >();
+ add< FromJsonTests::DBRefStringId >();
add< FromJsonTests::DBRefObjectIDObject >();
add< FromJsonTests::DBRefObjectIDConstructor >();
add< FromJsonTests::Oid >();
diff --git a/src/mongo/dbtests/jstests.cpp b/src/mongo/dbtests/jstests.cpp
index a95c5db3ded..b17338bc0e5 100644
--- a/src/mongo/dbtests/jstests.cpp
+++ b/src/mongo/dbtests/jstests.cpp
@@ -1061,6 +1061,32 @@ namespace JSTests {
class InformalDBRefTest : public TestRoundTrip {
virtual BSONObj bson() const {
BSONObjBuilder b;
+ BSONObjBuilder subBuilder(b.subobjStart("a"));
+ subBuilder.append("$ref", "ns");
+ subBuilder.append("$id", "000000000000000000000000");
+ subBuilder.done();
+ return b.obj();
+ }
+
+ // Don't need to return anything because we are overriding both jsonOut and jsonIn
+ virtual string json() const { return ""; }
+
+ // Need to override these because the JSON doesn't actually round trip.
+ // An object with "$ref" and "$id" fields is handled specially and different on the way out.
+ virtual string jsonOut() const {
+ return "{ \"a\" : DBRef( \"ns\", \"000000000000000000000000\" ) }";
+ }
+ virtual string jsonIn() const {
+ stringstream ss;
+ ss << "{ \"a\" : { \"$ref\" : \"ns\" , " <<
+ "\"$id\" : \"000000000000000000000000\" } }";
+ return ss.str();
+ }
+ };
+
+ class InformalDBRefOIDTest : public TestRoundTrip {
+ virtual BSONObj bson() const {
+ BSONObjBuilder b;
OID o;
memset( &o, 0, 12 );
BSONObjBuilder subBuilder(b.subobjStart("a"));
@@ -1387,6 +1413,7 @@ namespace JSTests {
add< RoundTripTests::DBRefTest >();
add< RoundTripTests::DBPointerTest >();
add< RoundTripTests::InformalDBRefTest >();
+ add< RoundTripTests::InformalDBRefOIDTest >();
add< RoundTripTests::InformalDBRefExtraFieldTest >();
add< NoReturnSpecified >();
}