diff options
Diffstat (limited to 'src/lib/cc/stamped_value.h')
-rw-r--r-- | src/lib/cc/stamped_value.h | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/src/lib/cc/stamped_value.h b/src/lib/cc/stamped_value.h new file mode 100644 index 0000000..2120593 --- /dev/null +++ b/src/lib/cc/stamped_value.h @@ -0,0 +1,237 @@ +// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC") +// +// 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 + +#include <cc/data.h> +#include <cc/stamped_element.h> +#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> +#include <boost/shared_ptr.hpp> +#include <cstdint> +#include <string> + +namespace isc { +namespace data { + +class StampedValue; + +/// @brief Pointer to the stamped value. +typedef boost::shared_ptr<StampedValue> StampedValuePtr; + +/// @brief This class represents a named configuration parameter, +/// e.g. global parameter of the DHCP server. +/// +/// 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. +/// 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. +class StampedValue : public StampedElement { +public: + + /// @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. + /// + /// Creates stamped value from a string. + /// + /// @param name Name of the value. + /// @param value Value to be set. + StampedValue(const std::string& name, const std::string& value); + + /// @brief Factory function creating a null value. + /// + /// @param name Name of the value. + static StampedValuePtr create(const std::string& name); + + /// @brief Factory function 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. + static StampedValuePtr create(const std::string& name, + const ElementPtr& value); + + /// @brief Factory function creating a string value. + /// + /// Creates stamped value from a string. + /// + /// @param name Name of the value. + /// @param value Value to be set. + static StampedValuePtr create(const std::string& name, + const std::string& value); + + /// @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); + + /// @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; + + /// @brief Returns value name. + /// + /// @return Value name. + std::string getName() const { + return (name_); + } + + /// @brief Returns value as string. + /// + /// 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_); + } + + /// @brief Returns value as signed integer. + /// + /// @return Stored value as a signed integer. + /// @throw TypeError if the value is not of @c Element::integer + /// type. + int64_t getIntegerValue() const; + + /// @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; + + /// @brief Returns the value as @c Element. + ConstElementPtr getElementValue() const { + return (value_); + } + +private: + + /// @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; + + /// @brief Name of the value. + std::string name_; + + /// @brief Stored value. + ElementPtr value_; +}; + +/// @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< + BaseStampedElement, + boost::posix_time::ptime, + &BaseStampedElement::getModificationTime + > + > + > +> StampedValueCollection; + +//@} + +} // end of namespace isc::data +} // end of namespace isc + +#endif |