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 <string>
34 
35 #include "mongo/base/disallow_copying.h"
36 #include "mongo/bson/mutable/element.h"
37 #include "mongo/db/field_ref.h"
38 #include "mongo/db/jsobj.h"
39 #include "mongo/db/ops/modifier_interface.h"
40 
41 namespace mongo {
42 
43 class CollatorInterface;
44 class LogBuilder;
45 
46 class ModifierCompare : public ModifierInterface {
47     MONGO_DISALLOW_COPYING(ModifierCompare);
48 
49 public:
50     enum ModifierCompareMode { MAX, MIN };
51     explicit ModifierCompare(ModifierCompareMode mode = MAX);
52 
53     virtual ~ModifierCompare();
54 
55     //
56     // Modifier interface implementation
57     //
58 
59     /**
60      * A 'modExpr' is a BSONElement {<fieldname>: <value>} coming from a $set mod such as
61      * {$set: {<fieldname: <value>}}. init() extracts the field name and the value to be
62      * assigned to it from 'modExpr'. It returns OK if successful or a status describing
63      * the error.
64      */
65     virtual Status init(const BSONElement& modExpr, const Options& opts, bool* positional = NULL);
66 
67     /**
68      * Looks up the field name in the sub-tree rooted at 'root', and binds, if necessary,
69      * the '$' field part using the 'matchedfield' number. prepare() returns OK and
70      * fills in 'execInfo' with information of whether this mod is a no-op on 'root' and
71      * whether it is an in-place candidate. Otherwise, returns a status describing the
72      * error.
73      */
74     virtual Status prepare(mutablebson::Element root, StringData matchedField, ExecInfo* execInfo);
75 
76     /**
77      * Applies the prepared mod over the element 'root' specified in the prepare()
78      * call. Returns OK if successful or a status describing the error.
79      */
80     virtual Status apply() const;
81 
82     /**
83      * Adds a log entry to logRoot corresponding to the operation applied here. Returns OK
84      * if successful or a status describing the error.
85      */
86     virtual Status log(LogBuilder* logBuilder) const;
87 
setCollator(const CollatorInterface * collator)88     virtual void setCollator(const CollatorInterface* collator) {
89         invariant(!_collator);
90         _collator = collator;
91     }
92 
93 private:
94     // Compare mode: min/max
95     const ModifierCompareMode _mode;
96 
97     // Access to each component of fieldName that's the target of this mod.
98     FieldRef _updatePath;
99 
100     // 0 or index for $-positional in _updatePath.
101     size_t _pathReplacementPosition;
102 
103     // Element of the mod expression.
104     BSONElement _val;
105 
106     // The instance of the field in the provided doc. This state is valid after a
107     // prepare() was issued and until a log() is issued. The document this mod is
108     // being prepared against must be live throughout all the calls.
109     struct PreparedState;
110     std::unique_ptr<PreparedState> _preparedState;
111 
112     const CollatorInterface* _collator = nullptr;
113 };
114 
115 }  // namespace mongo
116