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