summaryrefslogtreecommitdiff
path: root/src/mongo/s/write_ops/batched_insert_request.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/s/write_ops/batched_insert_request.cpp')
-rw-r--r--src/mongo/s/write_ops/batched_insert_request.cpp304
1 files changed, 304 insertions, 0 deletions
diff --git a/src/mongo/s/write_ops/batched_insert_request.cpp b/src/mongo/s/write_ops/batched_insert_request.cpp
new file mode 100644
index 00000000000..f2e47ca0c2b
--- /dev/null
+++ b/src/mongo/s/write_ops/batched_insert_request.cpp
@@ -0,0 +1,304 @@
+/**
+ * Copyright (C) 2013 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/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects
+ * for all of the code used other than as permitted herein. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you do not
+ * wish to do so, delete this exception statement from your version. If you
+ * delete this exception statement from all source files in the program,
+ * then also delete it in the license file.
+ */
+
+#include "mongo/s/write_ops/batched_insert_request.h"
+
+#include "mongo/db/field_parser.h"
+#include "mongo/util/mongoutils/str.h"
+
+namespace mongo {
+
+ using mongoutils::str::stream;
+
+ const std::string BatchedInsertRequest::BATCHED_INSERT_REQUEST = "insert";
+ const BSONField<std::string> BatchedInsertRequest::collName("insert");
+ const BSONField<std::vector<BSONObj> > BatchedInsertRequest::documents("documents");
+ const BSONField<BSONObj> BatchedInsertRequest::writeConcern("writeConcern");
+ const BSONField<bool> BatchedInsertRequest::ordered("ordered", true);
+ const BSONField<BSONObj> BatchedInsertRequest::metadata("metadata");
+
+ BatchedInsertRequest::BatchedInsertRequest() {
+ clear();
+ }
+
+ BatchedInsertRequest::~BatchedInsertRequest() {
+ }
+
+ bool BatchedInsertRequest::isValid(std::string* errMsg) const {
+ std::string dummy;
+ if (errMsg == NULL) {
+ errMsg = &dummy;
+ }
+
+ // All the mandatory fields must be present.
+ if (!_isCollNameSet) {
+ *errMsg = stream() << "missing " << collName.name() << " field";
+ return false;
+ }
+
+ if (!_isDocumentsSet) {
+ *errMsg = stream() << "missing " << documents.name() << " field";
+ return false;
+ }
+
+ return true;
+ }
+
+ BSONObj BatchedInsertRequest::toBSON() const {
+ BSONObjBuilder builder;
+
+ if (_isCollNameSet) builder.append(collName(), _collName);
+
+ if (_isDocumentsSet) {
+ BSONArrayBuilder documentsBuilder(builder.subarrayStart(documents()));
+ for (std::vector<BSONObj>::const_iterator it = _documents.begin();
+ it != _documents.end();
+ ++it) {
+ documentsBuilder.append(*it);
+ }
+ documentsBuilder.done();
+ }
+
+ if (_isWriteConcernSet) builder.append(writeConcern(), _writeConcern);
+
+ if (_isOrderedSet) builder.append(ordered(), _ordered);
+
+ if (_metadata) builder.append(metadata(), _metadata->toBSON());
+
+ return builder.obj();
+ }
+
+ bool BatchedInsertRequest::parseBSON(const BSONObj& source, string* errMsg) {
+ clear();
+
+ std::string dummy;
+ if (!errMsg) errMsg = &dummy;
+
+ BSONObjIterator sourceIt(source);
+
+ while ( sourceIt.more() ) {
+
+ BSONElement sourceEl = sourceIt.next();
+
+ if ( collName() == sourceEl.fieldName() ) {
+ FieldParser::FieldState fieldState =
+ FieldParser::extract( sourceEl, collName, &_collName, errMsg );
+ if (fieldState == FieldParser::FIELD_INVALID) return false;
+ _isCollNameSet = fieldState == FieldParser::FIELD_SET;
+ }
+ else if ( documents() == sourceEl.fieldName() ) {
+ FieldParser::FieldState fieldState =
+ FieldParser::extract( sourceEl, documents, &_documents, errMsg );
+ if ( fieldState == FieldParser::FIELD_INVALID ) return false;
+ _isDocumentsSet = fieldState == FieldParser::FIELD_SET;
+ }
+ else if ( writeConcern() == sourceEl.fieldName() ) {
+ FieldParser::FieldState fieldState =
+ FieldParser::extract(sourceEl, writeConcern, &_writeConcern, errMsg);
+ if (fieldState == FieldParser::FIELD_INVALID) return false;
+ _isWriteConcernSet = fieldState == FieldParser::FIELD_SET;
+ }
+ else if ( ordered() == sourceEl.fieldName() ) {
+ FieldParser::FieldState fieldState =
+ FieldParser::extract(sourceEl, ordered, &_ordered, errMsg);
+ if (fieldState == FieldParser::FIELD_INVALID) return false;
+ _isOrderedSet = fieldState == FieldParser::FIELD_SET;
+ }
+ else if ( metadata() == sourceEl.fieldName() ) {
+ BSONObj metadataObj;
+ FieldParser::FieldState fieldState =
+ FieldParser::extract(sourceEl, metadata, &metadataObj, errMsg);
+ if (fieldState == FieldParser::FIELD_INVALID) return false;
+
+ if (!metadataObj.isEmpty()) {
+ _metadata.reset(new BatchedRequestMetadata());
+ if (!_metadata->parseBSON(metadataObj, errMsg)) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ void BatchedInsertRequest::clear() {
+ _collName.clear();
+ _isCollNameSet = false;
+
+ _documents.clear();
+ _isDocumentsSet =false;
+
+ _writeConcern = BSONObj();
+ _isWriteConcernSet = false;
+
+ _ordered = false;
+ _isOrderedSet = false;
+
+ _metadata.reset();
+ }
+
+ void BatchedInsertRequest::cloneTo(BatchedInsertRequest* other) const {
+ other->clear();
+
+ other->_collName = _collName;
+ other->_isCollNameSet = _isCollNameSet;
+
+ for(std::vector<BSONObj>::const_iterator it = _documents.begin();
+ it != _documents.end();
+ ++it) {
+ other->addToDocuments(*it);
+ }
+ other->_isDocumentsSet = _isDocumentsSet;
+
+ other->_writeConcern = _writeConcern;
+ other->_isWriteConcernSet = _isWriteConcernSet;
+
+ other->_ordered = _ordered;
+ other->_isOrderedSet = _isOrderedSet;
+
+ if (_metadata) {
+ other->_metadata.reset(new BatchedRequestMetadata());
+ _metadata->cloneTo(other->_metadata.get());
+ }
+ }
+
+ std::string BatchedInsertRequest::toString() const {
+ return toBSON().toString();
+ }
+
+ void BatchedInsertRequest::setCollName(const StringData& collName) {
+ _collName = collName.toString();
+ _isCollNameSet = true;
+ }
+
+ void BatchedInsertRequest::unsetCollName() {
+ _isCollNameSet = false;
+ }
+
+ bool BatchedInsertRequest::isCollNameSet() const {
+ return _isCollNameSet;
+ }
+
+ const std::string& BatchedInsertRequest::getCollName() const {
+ dassert(_isCollNameSet);
+ return _collName;
+ }
+
+ void BatchedInsertRequest::addToDocuments(const BSONObj& documents) {
+ _documents.push_back(documents);
+ _isDocumentsSet = true;
+ }
+
+ void BatchedInsertRequest::unsetDocuments() {
+ _documents.clear();
+ _isDocumentsSet = false;
+ }
+
+ bool BatchedInsertRequest::isDocumentsSet() const {
+ return _isDocumentsSet;
+ }
+
+ size_t BatchedInsertRequest::sizeDocuments() const {
+ return _documents.size();
+ }
+
+ const std::vector<BSONObj>& BatchedInsertRequest::getDocuments() const {
+ dassert(_isDocumentsSet);
+ return _documents;
+ }
+
+ const BSONObj& BatchedInsertRequest::getDocumentsAt(size_t pos) const {
+ dassert(_isDocumentsSet);
+ dassert(_documents.size() > pos);
+ return _documents.at(pos);
+ }
+
+ void BatchedInsertRequest::setDocumentAt(size_t pos, const BSONObj& doc) {
+ dassert(_isDocumentsSet);
+ dassert(_documents.size() > pos);
+ _documents[pos] = doc;
+ }
+
+ void BatchedInsertRequest::setWriteConcern(const BSONObj& writeConcern) {
+ _writeConcern = writeConcern.getOwned();
+ _isWriteConcernSet = true;
+ }
+
+ void BatchedInsertRequest::unsetWriteConcern() {
+ _isWriteConcernSet = false;
+ }
+
+ bool BatchedInsertRequest::isWriteConcernSet() const {
+ return _isWriteConcernSet;
+ }
+
+ const BSONObj& BatchedInsertRequest::getWriteConcern() const {
+ dassert(_isWriteConcernSet);
+ return _writeConcern;
+ }
+
+ void BatchedInsertRequest::setOrdered(bool ordered) {
+ _ordered = ordered;
+ _isOrderedSet = true;
+ }
+
+ void BatchedInsertRequest::unsetOrdered() {
+ _isOrderedSet = false;
+ }
+
+ bool BatchedInsertRequest::isOrderedSet() const {
+ return _isOrderedSet;
+ }
+
+ bool BatchedInsertRequest::getOrdered() const {
+ if (_isOrderedSet) {
+ return _ordered;
+ }
+ else {
+ return ordered.getDefault();
+ }
+ }
+
+ void BatchedInsertRequest::setMetadata(BatchedRequestMetadata* metadata) {
+ _metadata.reset(metadata);
+ }
+
+ void BatchedInsertRequest::unsetMetadata() {
+ _metadata.reset();
+ }
+
+ bool BatchedInsertRequest::isMetadataSet() const {
+ return _metadata.get();
+ }
+
+ BatchedRequestMetadata* BatchedInsertRequest::getMetadata() const {
+ return _metadata.get();
+ }
+
+} // namespace mongo