summaryrefslogtreecommitdiff
path: root/src/mongo/db/field_parser-inl.h
diff options
context:
space:
mode:
authorJason Rassi <rassi@10gen.com>2013-06-03 14:23:51 -0400
committerJason Rassi <rassi@10gen.com>2013-06-03 14:23:51 -0400
commitc4b60b8ff775f494873535343cf50794f995cb5f (patch)
tree6dfa8e06ce78e706f0fba792120f50ac4c604e99 /src/mongo/db/field_parser-inl.h
parent59a12930f6be0d422b0a3be342181646b3010bca (diff)
downloadmongo-c4b60b8ff775f494873535343cf50794f995cb5f.tar.gz
SERVER-9468 Move s/field-parser* to db/
Diffstat (limited to 'src/mongo/db/field_parser-inl.h')
-rw-r--r--src/mongo/db/field_parser-inl.h127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/mongo/db/field_parser-inl.h b/src/mongo/db/field_parser-inl.h
new file mode 100644
index 00000000000..905cb17b1d4
--- /dev/null
+++ b/src/mongo/db/field_parser-inl.h
@@ -0,0 +1,127 @@
+/**
+ * Copyright (C) 2012 10gen Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mongo/db/field_parser.h"
+#include "mongo/util/mongoutils/str.h"
+
+namespace mongo {
+
+ using mongoutils::str::stream;
+
+ // Extracts an array into a vector
+ template<typename T>
+ FieldParser::FieldState FieldParser::extract(BSONObj doc,
+ const BSONField<vector<T> >& field,
+ vector<T>* out,
+ string* errMsg)
+ {
+ BSONElement elem = doc[field.name()];
+ 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());
+ 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(arr,
+ 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;
+ }
+
+ if (errMsg) {
+ *errMsg = stream() << "wrong type for '" << field() << "' field, expected "
+ << "vector array" << ", found " << doc[field.name()].toString();
+ }
+ return FIELD_INVALID;
+ }
+
+ // Extracts an object into a map
+ template<typename K, typename T>
+ FieldParser::FieldState FieldParser::extract(BSONObj doc,
+ const BSONField<map<K, T> >& field,
+ map<K, T>* out,
+ string* errMsg)
+ {
+ BSONElement elem = doc[field.name()];
+ if (elem.eoo()) {
+ if (field.hasDefault()) {
+ *out = field.getDefault();
+ return FIELD_DEFAULT;
+ }
+ else {
+ return FIELD_NONE;
+ }
+ }
+
+ if (elem.type() == Object) {
+ BSONObj obj = elem.embeddedObject();
+ 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(obj, 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 " << doc[field.name()].toString();
+ }
+ return FIELD_INVALID;
+ }
+
+} // namespace mongo