stamped_value.h 7.64 KB
Newer Older
1
// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
2 3 4 5 6 7 8 9
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef STAMPED_VALUE_H
#define STAMPED_VALUE_H

10
#include <cc/data.h>
11
#include <cc/stamped_element.h>
12 13 14 15
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index_container.hpp>
16 17 18 19 20 21 22
#include <boost/shared_ptr.hpp>
#include <cstdint>
#include <string>

namespace isc {
namespace data {

23 24 25 26 27
class StampedValue;

/// @brief Pointer to the stamped value.
typedef boost::shared_ptr<StampedValue> StampedValuePtr;

28 29
/// @brief This class represents a named configuration parameter,
/// e.g. global parameter of the DHCP server.
30 31 32 33
///
/// Global configuration elements having simple types, e.g. DHCP
/// timers, need to be associatied with modification timestamps.
/// This association is made by deriving from @c StampedElement.
34 35 36 37 38 39 40
/// The values can be strings, integers, booleans or real numbers.
///
/// Because the strings are more flexible, configuration elements
/// are always held as strings in the configuration backends. This
/// class reflects a single value held in the database. The value
/// can be return in its orginal type or can be returned as a
/// string. Also the null values are allowed.
41 42 43
class StampedValue : public StampedElement {
public:

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
    /// @brief Constructor creating a null value.
    ///
    /// @param name Name of the value.
    StampedValue(const std::string& name);

    /// @brief Constructor creating a value from the @c Element.
    ///
    /// @param name Name of the value.
    /// @param value Value encapsulated in the @c Element object.
    ///
    /// @throw BadValue if the value is null.
    /// @throw TypeError if the value is neither a string, integer,
    /// bool nor real.
    StampedValue(const std::string& name, const ElementPtr& value);

    /// @brief Constructor creating a string value.
60 61 62
    ///
    /// Creates stamped value from a string.
    ///
63
    /// @param name Name of the value.
64
    /// @param value Value to be set.
65
    StampedValue(const std::string& name, const std::string& value);
66

67
    /// @brief Factory function creating a null value.
68
    ///
69
    /// @param name Name of the value.
70
    static StampedValuePtr create(const std::string& name);
71

72
    /// @brief Factory function creating a value from the @c Element.
73 74
    ///
    /// @param name Name of the value.
75 76 77 78 79
    /// @param value Value encapsulated in the @c Element object.
    ///
    /// @throw BadValue if the value is null.
    /// @throw TypeError if the value is neither a string, integer,
    /// bool nor real.
80
    static StampedValuePtr create(const std::string& name,
81
                                  const ElementPtr& value);
82

83 84 85
    /// @brief Factory function creating a string value.
    ///
    /// Creates stamped value from a string.
86 87
    ///
    /// @param name Name of the value.
88
    /// @param value Value to be set.
89
    static StampedValuePtr create(const std::string& name,
90 91
                                  const std::string& value);

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
    /// @brief Factory function which attempts to convert provided
    /// string value to a given type.
    ///
    /// This factory function is useful in cases when the value is
    /// read as a string from a database. The string value has to
    /// be converted to the appropriate data type. The type is also
    /// known from the database.
    ///
    /// @param name Name of the value.
    /// @param value Value given as string to be converted.
    /// @param type Type of the value to convert to.
    static StampedValuePtr create(const std::string& name,
                                  const std::string& value,
                                  Element::types type);

107 108 109 110 111 112
    /// @brief Returns a type of the value.
    ///
    /// @return Type of the value as integer. It can be compared
    /// with the @c Element::getType() output.
    /// @throw InvalidOperation if the value is null.
    int getType() const;
113

114
    /// @brief Returns value name.
115 116
    ///
    /// @return Value name.
117 118 119 120
    std::string getName() const {
        return (name_);
    }

121
    /// @brief Returns value as string.
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
    ///
    /// It is allowed to call this function for all supported data
    /// types. They are converted to a string. For example, a real
    /// number of 1.4 will be returned as "1.4". The boolean true
    /// value will be returned as "1" etc.
    ///
    /// @return Stored value as string.
    /// @throw InvalidOperation if the value is null.
    std::string getValue() const;

    /// @brief Checks if the value is null.
    ///
    /// @return true if the value is null, false otherwise.
    bool amNull() const {
        return (!value_);
137 138 139 140
    }

    /// @brief Returns value as signed integer.
    ///
141 142 143
    /// @return Stored value as a signed integer.
    /// @throw TypeError if the value is not of @c Element::integer
    /// type.
144
    int64_t getIntegerValue() const;
145

146 147 148 149 150 151 152 153 154 155 156 157 158 159
    /// @brief Returns value as a boolean.
    ///
    /// @return Stored value as a boolean.
    /// @throw TypeError if the value is not of @c Element::boolean
    /// type.
    bool getBoolValue() const;

    /// @brief Returns value as a real number.
    ///
    /// @return Stored value as a real number.
    /// @throw TypeError if the value is not of @c Element::real
    /// type.
    double getDoubleValue() const;

160 161 162 163 164
    /// @brief Returns the value as @c Element.
    ConstElementPtr getElementValue() const {
        return (value_);
    }

165 166
private:

167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
    /// @brief Checks if the values passed to the constructors
    /// were correct.
    ///
    /// This is called from the constructors.
    ///
    /// @throw BadValue if the value is null.
    /// @throw TypeError if the value type is neither a string,
    /// integer, boolean nor real.
    void validateConstruct() const;

    /// @brief Checks if the value is accessed correctly.
    ///
    /// This is called from the accessors of this class.
    ///
    /// @param type Type of the value expected by the accessor
    /// function.
    ///
    /// @throw InvalidOperation if the accessed value is null.
    /// @throw TypeError if the expected type is not a string
    /// and it doesn't match the value type.
    void validateAccess(Element::types type) const;

189 190 191
    /// @brief Name of the value.
    std::string name_;

192 193
    /// @brief Stored value.
    ElementPtr value_;
194 195
};

196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
/// @name Definition of the multi index container for @c StampedValue.
///
//@{

/// @brief Tag for the index for access by value name.
struct StampedValueNameIndexTag { };

/// @brief Tag for the index for access by modification time.
struct StampedValueModificationTimeIndexTag { };

/// @brief Multi index container for @c StampedValue.
typedef boost::multi_index_container<
    StampedValuePtr,
    boost::multi_index::indexed_by<
        // Index used to access value by name.
        boost::multi_index::hashed_non_unique<
            boost::multi_index::tag<StampedValueNameIndexTag>,
            boost::multi_index::const_mem_fun<
                StampedValue,
                std::string,
                &StampedValue::getName
            >
        >,

        // Index used to access value by modification time.
        boost::multi_index::ordered_non_unique<
            boost::multi_index::tag<StampedValueModificationTimeIndexTag>,
            boost::multi_index::const_mem_fun<
                StampedElement,
                boost::posix_time::ptime,
                &StampedElement::getModificationTime
            >
        >
    >
> StampedValueCollection;

//@}
233 234 235 236 237

} // end of namespace isc::data
} // end of namespace isc

#endif