summaryrefslogtreecommitdiff
path: root/src/mongo/db/field_parser-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/field_parser-inl.h')
-rw-r--r--src/mongo/db/field_parser-inl.h534
1 files changed, 260 insertions, 274 deletions
diff --git a/src/mongo/db/field_parser-inl.h b/src/mongo/db/field_parser-inl.h
index 04dbccf9e2a..b121659f59f 100644
--- a/src/mongo/db/field_parser-inl.h
+++ b/src/mongo/db/field_parser-inl.h
@@ -31,346 +31,332 @@
namespace mongo {
- using mongoutils::str::stream;
-
- template<class T>
- void _genFieldErrMsg(const BSONElement& elem,
- const BSONField<T>& field,
- const std::string expected,
- std::string* errMsg)
- {
- if (!errMsg) return;
- *errMsg = stream() << "wrong type for '" << field() << "' field, expected " << expected
- << ", found " << elem.toString();
+using mongoutils::str::stream;
+
+template <class T>
+void _genFieldErrMsg(const BSONElement& elem,
+ const BSONField<T>& field,
+ const std::string expected,
+ std::string* errMsg) {
+ if (!errMsg)
+ return;
+ *errMsg = stream() << "wrong type for '" << field() << "' field, expected " << expected
+ << ", found " << elem.toString();
+}
+
+template <typename T>
+FieldParser::FieldState FieldParser::extract(BSONObj doc,
+ const BSONField<T>& field,
+ T* out,
+ std::string* errMsg) {
+ BSONElement elem = doc[field.name()];
+ if (elem.eoo()) {
+ if (field.hasDefault()) {
+ field.getDefault().cloneTo(out);
+ return FIELD_DEFAULT;
+ } else {
+ return FIELD_NONE;
+ }
}
- template<typename T>
- FieldParser::FieldState FieldParser::extract(BSONObj doc,
- const BSONField<T>& field,
- T* out,
- std::string* errMsg)
- {
- BSONElement elem = doc[field.name()];
- if (elem.eoo()) {
- if (field.hasDefault()) {
- field.getDefault().cloneTo(out);
- return FIELD_DEFAULT;
- }
- else {
- return FIELD_NONE;
- }
- }
+ if (elem.type() != Object && elem.type() != Array) {
+ _genFieldErrMsg(elem, field, "Object/Array", errMsg);
+ return FIELD_INVALID;
+ }
- if (elem.type() != Object && elem.type() != Array) {
- _genFieldErrMsg(elem, field, "Object/Array", errMsg);
- return FIELD_INVALID;
- }
+ if (!out->parseBSON(elem.embeddedObject(), errMsg)) {
+ return FIELD_INVALID;
+ }
- if (!out->parseBSON(elem.embeddedObject(), errMsg)) {
- return FIELD_INVALID;
+ return FIELD_SET;
+}
+
+template <typename T>
+FieldParser::FieldState FieldParser::extract(BSONObj doc,
+ const BSONField<T*>& field,
+ T** out,
+ std::string* errMsg) {
+ BSONElement elem = doc[field.name()];
+ if (elem.eoo()) {
+ if (field.hasDefault()) {
+ std::unique_ptr<T> temp(new T);
+ field.getDefault()->cloneTo(temp.get());
+
+ *out = temp.release();
+ return FIELD_DEFAULT;
+ } else {
+ return FIELD_NONE;
}
+ }
- return FIELD_SET;
+ if (elem.type() != Object && elem.type() != Array) {
+ _genFieldErrMsg(elem, field, "Object/Array", errMsg);
+ return FIELD_INVALID;
}
- template<typename T>
- FieldParser::FieldState FieldParser::extract(BSONObj doc,
- const BSONField<T*>& field,
- T** out,
- std::string* errMsg)
- {
- BSONElement elem = doc[field.name()];
- if (elem.eoo()) {
- if (field.hasDefault()) {
- std::unique_ptr<T> temp(new T);
- field.getDefault()->cloneTo(temp.get());
-
- *out = temp.release();
- return FIELD_DEFAULT;
- }
- else {
- return FIELD_NONE;
- }
- }
+ std::unique_ptr<T> temp(new T);
+ if (!temp->parseBSON(elem.embeddedObject(), errMsg)) {
+ return FIELD_INVALID;
+ }
- if (elem.type() != Object && elem.type() != Array) {
- _genFieldErrMsg(elem, field, "Object/Array", errMsg);
- return FIELD_INVALID;
+ *out = temp.release();
+ return FIELD_SET;
+}
+
+template <typename T>
+FieldParser::FieldState FieldParser::extract(BSONObj doc,
+ const BSONField<T>& field,
+ T** out,
+ std::string* errMsg) {
+ BSONElement elem = doc[field.name()];
+ if (elem.eoo()) {
+ if (field.hasDefault()) {
+ *out = new T;
+ field.getDefault().cloneTo(*out);
+ return FIELD_DEFAULT;
+ } else {
+ return FIELD_NONE;
}
+ }
- std::unique_ptr<T> temp(new T);
- if (!temp->parseBSON(elem.embeddedObject(), errMsg)) {
- return FIELD_INVALID;
+ if (elem.type() != Object && elem.type() != Array) {
+ if (errMsg) {
+ *errMsg = stream() << "wrong type for '" << field() << "' field, expected "
+ << "vector or array"
+ << ", found " << doc[field.name()].toString();
}
+ return FIELD_INVALID;
+ }
- *out = temp.release();
- return FIELD_SET;
+ std::unique_ptr<T> temp(new T);
+ if (!temp->parseBSON(elem.embeddedObject(), errMsg)) {
+ return FIELD_INVALID;
}
- template<typename T>
- FieldParser::FieldState FieldParser::extract(BSONObj doc,
- const BSONField<T>& field,
- T** out,
- std::string* errMsg)
- {
- BSONElement elem = doc[field.name()];
- if (elem.eoo()) {
- if (field.hasDefault()) {
- *out = new T;
- field.getDefault().cloneTo(*out);
- return FIELD_DEFAULT;
- }
- else {
- return FIELD_NONE;
- }
+ *out = temp.release();
+ return FIELD_SET;
+}
+
+// Extracts an array into a vector
+template <typename T>
+FieldParser::FieldState FieldParser::extract(BSONObj doc,
+ const BSONField<std::vector<T>>& field,
+ std::vector<T>* out,
+ std::string* errMsg) {
+ return extract(doc[field.name()], field, out, errMsg);
+}
+
+template <typename T>
+FieldParser::FieldState FieldParser::extract(BSONElement elem,
+ const BSONField<std::vector<T>>& field,
+ std::vector<T>* out,
+ std::string* errMsg) {
+ if (elem.eoo()) {
+ if (field.hasDefault()) {
+ *out = field.getDefault();
+ return FIELD_DEFAULT;
+ } else {
+ return FIELD_NONE;
}
+ }
- if (elem.type() != Object && elem.type() != Array) {
- if (errMsg) {
- *errMsg = stream() << "wrong type for '" << field() << "' field, expected "
- << "vector or array" << ", found "
- << doc[field.name()].toString();
- }
- return FIELD_INVALID;
- }
+ if (elem.type() == Array) {
+ BSONArray arr = BSONArray(elem.embeddedObject());
+ std::string elErrMsg;
- std::unique_ptr<T> temp(new T);
- if (!temp->parseBSON(elem.embeddedObject(), errMsg)) {
- return FIELD_INVALID;
+ // Append all the new elements to the end of the vector
+ size_t initialSize = out->size();
+ out->resize(initialSize + arr.nFields());
+
+ int i = 0;
+ BSONObjIterator objIt(arr);
+ while (objIt.more()) {
+ BSONElement next = objIt.next();
+ BSONField<T> fieldFor(next.fieldName(), out->at(initialSize + i));
+
+ if (!FieldParser::extract(next, fieldFor, &out->at(initialSize + i), &elErrMsg)) {
+ if (errMsg) {
+ *errMsg = stream() << "error parsing element " << i << " of field " << field()
+ << causedBy(elErrMsg);
+ }
+ return FIELD_INVALID;
+ }
+ i++;
}
- *out = temp.release();
return FIELD_SET;
}
- // Extracts an array into a vector
- template<typename T>
- FieldParser::FieldState FieldParser::extract( BSONObj doc,
- const BSONField<std::vector<T> >& field,
- std::vector<T>* out,
- std::string* errMsg ) {
- return extract( doc[field.name()], field, out, errMsg );
+ if (errMsg) {
+ *errMsg = stream() << "wrong type for '" << field() << "' field, expected "
+ << "vector array"
+ << ", found " << elem.toString();
+ }
+ return FIELD_INVALID;
+}
+
+template <typename T>
+FieldParser::FieldState FieldParser::extract(BSONObj doc,
+ const BSONField<std::vector<T*>>& field,
+ std::vector<T*>* out,
+ std::string* errMsg) {
+ dassert(!field.hasDefault());
+
+ BSONElement elem = doc[field.name()];
+ if (elem.eoo()) {
+ return FIELD_NONE;
}
- template<typename T>
- FieldParser::FieldState FieldParser::extract( BSONElement elem,
- const BSONField<std::vector<T> >& field,
- std::vector<T>* out,
- std::string* errMsg )
- {
- if (elem.eoo()) {
- if (field.hasDefault()) {
- *out = field.getDefault();
- return FIELD_DEFAULT;
- }
- else {
- return FIELD_NONE;
- }
- }
-
- if (elem.type() == Array) {
- BSONArray arr = BSONArray(elem.embeddedObject());
- std::string elErrMsg;
-
- // Append all the new elements to the end of the vector
- size_t initialSize = out->size();
- out->resize(initialSize + arr.nFields());
-
- int i = 0;
- BSONObjIterator objIt(arr);
- while (objIt.more()) {
- BSONElement next = objIt.next();
- BSONField<T> fieldFor(next.fieldName(), out->at(initialSize + i));
-
- if (!FieldParser::extract(next,
- fieldFor,
- &out->at(initialSize + i),
- &elErrMsg))
- {
- if (errMsg) {
- *errMsg = stream() << "error parsing element " << i << " of field "
- << field() << causedBy(elErrMsg);
- }
- return FIELD_INVALID;
- }
- i++;
- }
-
- return FIELD_SET;
- }
+ return extract(elem, field, out, errMsg);
+}
+template <typename T>
+FieldParser::FieldState FieldParser::extract(BSONElement elem,
+ const BSONField<std::vector<T*>>& field,
+ std::vector<T*>* out,
+ std::string* errMsg) {
+ if (elem.type() != Array) {
if (errMsg) {
*errMsg = stream() << "wrong type for '" << field() << "' field, expected "
- << "vector array" << ", found " << elem.toString();
+ << "vector array"
+ << ", found " << elem.toString();
}
return FIELD_INVALID;
}
- template<typename T>
- FieldParser::FieldState FieldParser::extract(BSONObj doc,
- const BSONField<std::vector<T*> >& field,
- std::vector<T*>* out,
- std::string* errMsg) {
- dassert(!field.hasDefault());
+ BSONArray arr = BSONArray(elem.embeddedObject());
+ BSONObjIterator objIt(arr);
+ while (objIt.more()) {
+ BSONElement next = objIt.next();
- BSONElement elem = doc[field.name()];
- if (elem.eoo()) {
- return FIELD_NONE;
- }
-
- return extract(elem, field, out, errMsg);
- }
-
- template<typename T>
- FieldParser::FieldState FieldParser::extract(BSONElement elem,
- const BSONField<std::vector<T*> >& field,
- std::vector<T*>* out,
- std::string* errMsg) {
-
- if (elem.type() != Array) {
+ if (next.type() != Object) {
if (errMsg) {
- *errMsg = stream() << "wrong type for '" << field() << "' field, expected "
- << "vector array" << ", found " << elem.toString();
+ *errMsg = stream() << "wrong type for '" << field() << "' field contents, "
+ << "expected object, found " << elem.type();
}
return FIELD_INVALID;
}
- BSONArray arr = BSONArray(elem.embeddedObject());
- BSONObjIterator objIt(arr);
- while (objIt.more()) {
+ std::unique_ptr<T> toInsert(new T);
- BSONElement next = objIt.next();
-
- if (next.type() != Object) {
- if (errMsg) {
- *errMsg = stream() << "wrong type for '" << field() << "' field contents, "
- << "expected object, found " << elem.type();
- }
- return FIELD_INVALID;
- }
-
- std::unique_ptr<T> toInsert(new T);
+ if (!toInsert->parseBSON(next.embeddedObject(), errMsg) || !toInsert->isValid(errMsg)) {
+ return FIELD_INVALID;
+ }
- if ( !toInsert->parseBSON( next.embeddedObject(), errMsg )
- || !toInsert->isValid( errMsg ) ) {
- return FIELD_INVALID;
- }
+ out->push_back(toInsert.release());
+ }
- out->push_back(toInsert.release());
- }
+ return FIELD_SET;
+}
- return FIELD_SET;
+template <typename T>
+void FieldParser::clearOwnedVector(std::vector<T*>* vec) {
+ for (typename std::vector<T*>::iterator it = vec->begin(); it != vec->end(); ++it) {
+ delete (*it);
+ }
+}
+
+template <typename T>
+FieldParser::FieldState FieldParser::extract(BSONObj doc,
+ const BSONField<std::vector<T*>>& field,
+ std::vector<T*>** out,
+ std::string* errMsg) {
+ dassert(!field.hasDefault());
+
+ BSONElement elem = doc[field.name()];
+ if (elem.eoo()) {
+ return FIELD_NONE;
}
- template<typename T>
- void FieldParser::clearOwnedVector(std::vector<T*>* vec) {
- for (typename std::vector<T*>::iterator it = vec->begin(); it != vec->end(); ++it) {
- delete (*it);
+ if (elem.type() != Array) {
+ if (errMsg) {
+ *errMsg = stream() << "wrong type for '" << field() << "' field, expected "
+ << "vector array"
+ << ", found " << doc[field.name()].toString();
}
+ return FIELD_INVALID;
}
- template<typename T>
- FieldParser::FieldState FieldParser::extract(BSONObj doc,
- const BSONField<std::vector<T*> >& field,
- std::vector<T*>** out,
- std::string* errMsg) {
- dassert(!field.hasDefault());
+ std::unique_ptr<std::vector<T*>> tempVector(new std::vector<T*>);
- BSONElement elem = doc[field.name()];
- if (elem.eoo()) {
- return FIELD_NONE;
- }
+ BSONArray arr = BSONArray(elem.embeddedObject());
+ BSONObjIterator objIt(arr);
+ while (objIt.more()) {
+ BSONElement next = objIt.next();
- if (elem.type() != Array) {
+ if (next.type() != Object) {
if (errMsg) {
- *errMsg = stream() << "wrong type for '" << field() << "' field, expected "
- << "vector array" << ", found " << doc[field.name()].toString();
+ *errMsg = stream() << "wrong type for '" << field() << "' field contents, "
+ << "expected object, found " << elem.type();
}
+ clearOwnedVector(tempVector.get());
return FIELD_INVALID;
}
- std::unique_ptr<std::vector<T*> > tempVector(new std::vector<T*>);
+ std::unique_ptr<T> toInsert(new T);
+ if (!toInsert->parseBSON(next.embeddedObject(), errMsg)) {
+ clearOwnedVector(tempVector.get());
+ return FIELD_INVALID;
+ }
- BSONArray arr = BSONArray(elem.embeddedObject());
- BSONObjIterator objIt(arr);
- while (objIt.more()) {
+ tempVector->push_back(toInsert.release());
+ }
+
+ *out = tempVector.release();
+ return FIELD_SET;
+}
+
+// Extracts an object into a map
+template <typename K, typename T>
+FieldParser::FieldState FieldParser::extract(BSONObj doc,
+ const BSONField<std::map<K, T>>& field,
+ std::map<K, T>* out,
+ std::string* errMsg) {
+ return extract(doc[field.name()], field, out, errMsg);
+}
+
+template <typename K, typename T>
+FieldParser::FieldState FieldParser::extract(BSONElement elem,
+ const BSONField<std::map<K, T>>& field,
+ std::map<K, T>* out,
+ std::string* errMsg) {
+ if (elem.eoo()) {
+ if (field.hasDefault()) {
+ *out = field.getDefault();
+ return FIELD_DEFAULT;
+ } else {
+ return FIELD_NONE;
+ }
+ }
+
+ if (elem.type() == Object) {
+ BSONObj obj = elem.embeddedObject();
+ std::string elErrMsg;
+ BSONObjIterator objIt(obj);
+ while (objIt.more()) {
BSONElement next = objIt.next();
+ T& value = (*out)[next.fieldName()];
- if (next.type() != Object) {
+ BSONField<T> fieldFor(next.fieldName(), value);
+ if (!FieldParser::extract(next, fieldFor, &value, &elErrMsg)) {
if (errMsg) {
- *errMsg = stream() << "wrong type for '" << field() << "' field contents, "
- << "expected object, found " << elem.type();
+ *errMsg = stream() << "error parsing map element " << next.fieldName()
+ << " of field " << field() << causedBy(elErrMsg);
}
- clearOwnedVector(tempVector.get());
- return FIELD_INVALID;
- }
-
- std::unique_ptr<T> toInsert(new T);
- if (!toInsert->parseBSON(next.embeddedObject(), errMsg)) {
- clearOwnedVector(tempVector.get());
return FIELD_INVALID;
}
-
- tempVector->push_back(toInsert.release());
}
- *out = tempVector.release();
return FIELD_SET;
}
- // Extracts an object into a map
- template<typename K, typename T>
- FieldParser::FieldState FieldParser::extract( BSONObj doc,
- const BSONField<std::map<K, T> >& field,
- std::map<K, T>* out,
- std::string* errMsg ) {
- return extract( doc[field.name()], field, out, errMsg );
- }
-
- template<typename K, typename T>
- FieldParser::FieldState FieldParser::extract( BSONElement elem,
- const BSONField<std::map<K, T> >& field,
- std::map<K, T>* out,
- std::string* errMsg )
- {
- if (elem.eoo()) {
- if (field.hasDefault()) {
- *out = field.getDefault();
- return FIELD_DEFAULT;
- }
- else {
- return FIELD_NONE;
- }
- }
-
- if (elem.type() == Object) {
- BSONObj obj = elem.embeddedObject();
- std::string elErrMsg;
-
- BSONObjIterator objIt(obj);
- while (objIt.more()) {
- BSONElement next = objIt.next();
- T& value = (*out)[next.fieldName()];
-
- BSONField<T> fieldFor(next.fieldName(), value);
- if (!FieldParser::extract(next, fieldFor, &value, &elErrMsg)) {
- if (errMsg) {
- *errMsg = stream() << "error parsing map element " << next.fieldName()
- << " of field " << field() << causedBy(elErrMsg);
- }
- return FIELD_INVALID;
- }
- }
-
- return FIELD_SET;
- }
-
- if (errMsg) {
- *errMsg = stream() << "wrong type for '" << field() << "' field, expected "
- << "vector array" << ", found " << elem.toString();
- }
- return FIELD_INVALID;
+ if (errMsg) {
+ *errMsg = stream() << "wrong type for '" << field() << "' field, expected "
+ << "vector array"
+ << ", found " << elem.toString();
}
+ return FIELD_INVALID;
+}
-} // namespace mongo
+} // namespace mongo