1 2 /** 3 * Copyright (C) 2018-present MongoDB, Inc. 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the Server Side Public License, version 1, 7 * as published by MongoDB, Inc. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * Server Side Public License for more details. 13 * 14 * You should have received a copy of the Server Side Public License 15 * along with this program. If not, see 16 * <http://www.mongodb.com/licensing/server-side-public-license>. 17 * 18 * As a special exception, the copyright holders give permission to link the 19 * code of portions of this program with the OpenSSL library under certain 20 * conditions as described in each individual source file and distribute 21 * linked combinations including the program with the OpenSSL library. You 22 * must comply with the Server Side Public License in all respects for 23 * all of the code used other than as permitted herein. If you modify file(s) 24 * with this exception, you may extend this exception to your version of the 25 * file(s), but you are not obligated to do so. If you do not wish to do so, 26 * delete this exception statement from your version. If you delete this 27 * exception statement from all source files in the program, then also delete 28 * it in the license file. 29 */ 30 31 #pragma once 32 33 #include <boost/optional.hpp> 34 35 #include "mongo/base/string_data.h" 36 #include "mongo/bson/bsonobj.h" 37 #include "mongo/bson/timestamp.h" 38 #include "mongo/db/pipeline/document.h" 39 #include "mongo/db/pipeline/value.h" 40 #include "mongo/util/uuid.h" 41 42 namespace mongo { 43 44 struct ResumeTokenData { ResumeTokenDataResumeTokenData45 ResumeTokenData(){}; ResumeTokenDataResumeTokenData46 ResumeTokenData(Timestamp clusterTimeIn, 47 Value documentKeyIn, 48 const boost::optional<UUID>& uuidIn) 49 : clusterTime(clusterTimeIn), documentKey(std::move(documentKeyIn)), uuid(uuidIn){}; 50 51 bool operator==(const ResumeTokenData& other) const; 52 bool operator!=(const ResumeTokenData& other) const { 53 return !(*this == other); 54 }; 55 56 Timestamp clusterTime; 57 Value documentKey; 58 boost::optional<UUID> uuid; 59 }; 60 61 std::ostream& operator<<(std::ostream& out, const ResumeTokenData& tokenData); 62 63 /** 64 * A token passed in by the user to indicate where in the oplog we should start for 65 * $changeStream. This token has the following format: 66 * { 67 * _data: <binary data>, 68 * _typeBits: <binary data> 69 * } 70 * The _data field data is encoded such that byte by byte comparisons provide the correct 71 * ordering of tokens. The _typeBits field may be missing and should not affect token 72 * comparison. 73 */ 74 75 class ResumeToken { 76 public: 77 /** 78 * The default no-argument constructor is required by the IDL for types used as non-optional 79 * fields. 80 */ 81 ResumeToken() = default; 82 83 explicit ResumeToken(const ResumeTokenData& resumeValue); 84 85 bool operator==(const ResumeToken&) const; 86 bool operator!=(const ResumeToken&) const; 87 bool operator<(const ResumeToken&) const; 88 bool operator<=(const ResumeToken&) const; 89 bool operator>(const ResumeToken&) const; 90 bool operator>=(const ResumeToken&) const; 91 92 /** Three way comparison, returns 0 if *this is equal to other, < 0 if *this is less than 93 * other, and > 0 if *this is greater than other. 94 */ 95 int compare(const ResumeToken& other) const; 96 97 Document toDocument() const; 98 toBSON()99 BSONObj toBSON() const { 100 return toDocument().toBson(); 101 } 102 103 ResumeTokenData getData() const; 104 105 /** 106 * Parse a resume token from a BSON object; used as an interface to the IDL parser. 107 */ parse(const BSONObj & resumeBson)108 static ResumeToken parse(const BSONObj& resumeBson) { 109 return ResumeToken::parse(Document(resumeBson)); 110 } 111 112 static ResumeToken parse(const Document& document); 113 114 friend std::ostream& operator<<(std::ostream& out, const ResumeToken& token) { 115 return out << token.getData(); 116 } 117 118 constexpr static StringData kDataFieldName = "_data"_sd; 119 constexpr static StringData kTypeBitsFieldName = "_typeBits"_sd; 120 121 private: 122 explicit ResumeToken(const Document& resumeData); 123 124 Value _keyStringData; 125 Value _typeBits; 126 }; 127 } // namespace mongo 128