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