]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
boost::any for CHDS
authorAndrei Pavel <andrei.pavel@qualitance.com>
Fri, 18 Aug 2017 14:41:22 +0000 (17:41 +0300)
committerAndrei Pavel <andrei.pavel@qualitance.com>
Fri, 18 Aug 2017 14:42:15 +0000 (17:42 +0300)
src/lib/dhcpsrv/cql_connection.h
src/lib/dhcpsrv/cql_host_data_source.cc
src/lib/dhcpsrv/cql_host_data_source.h
src/lib/dhcpsrv/dhcpsrv_messages.mes
src/lib/dhcpsrv/host_data_source_factory.cc
src/lib/dhcpsrv/tests/cql_host_data_source_unittest.cc
src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc
src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h

index 70db2f2be0dca2f40f1e8fb4dfa166411535fbcc..a3b88d8c1525bd09fc51b5d566a7a63b7bf2aa49 100644 (file)
@@ -89,10 +89,6 @@ struct StatementTagHash {
     }
 };
 
-/// Define CQL schema version: 2.0
-const uint32_t CQL_SCHEMA_VERSION_MAJOR = 2;
-const uint32_t CQL_SCHEMA_VERSION_MINOR = 0;
-
 /// @brief Equality function for StatementMap keys
 struct StatementTagEqual {
     bool operator()(StatementTag const& lhs, StatementTag const& rhs) const {
index 43bebf04590f29c81781ca8467080d6d4d3f496d..87ab9a2a2cccff783dcda154c6decf8f28a0837c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2016 Deutsche Telekom AG.
+// Copyright (C) 2016-2017 Deutsche Telekom AG.
 //
 // Author: Andrei Pavel <andrei.pavel@qualitance.com>
 //
 
 #include <config.h>
 
+#include <dhcpsrv/cql_host_data_source.h>
+
 #include <dhcp/libdhcp++.h>
 #include <dhcp/option.h>
 #include <dhcp/option_definition.h>
 #include <dhcpsrv/cfg_option.h>
 #include <dhcpsrv/cfgmgr.h>
-#include <dhcpsrv/cql_host_data_source.h>
-#include <dhcpsrv/cql_lease_mgr.h>
+#include <dhcpsrv/cql_exchange.h>
 #include <dhcpsrv/db_exceptions.h>
 #include <dhcpsrv/dhcpsrv_log.h>
 #include <util/buffer.h>
 #include <util/optional_value.h>
 
-#include <boost/algorithm/string/classification.hpp>
-#include <boost/algorithm/string/split.hpp>
-#include <boost/tuple/tuple.hpp>
-#include <boost/unordered_map.hpp>
+#include <openssl/md5.h>  // for MD5_DIGEST_LENGTH
+#include <stdint.h>       // for uint64_t
 
-#include <openssl/md5.h>
+#include <boost/algorithm/string/classification.hpp>  // for boost::is_any_of
+#include <boost/algorithm/string/split.hpp>           // for split
+#include <boost/assert.hpp>                           // for BOOST_ASSERT
+#include <boost/unordered_map.hpp>                    // for std::unordered_map
 
-#include <list>
-#include <vector>
+#include <iosfwd>  // for size_t, std::stringstream
+#include <memory>  // for std::unique_ptr
+#include <string>  // for std::string
 
-using namespace isc;
 using namespace isc::asiolink;
 using namespace isc::dhcp;
 using namespace isc::util;
@@ -48,72 +50,85 @@ namespace {
 /// @brief Host identifier consisting of DUID or hardware address
 typedef std::vector<uint8_t> HostIdentifier;
 
-/// @brief Host identifier converted to Cassandra data type
-typedef std::vector<cass_byte_t> CassHostIdentifier;
-
-/// @brief Host identifier converted to Cassandra data type
-typedef std::vector<cass_byte_t> CassOptionBuffer;
-
 /// @brief key for HostMap containing objects which uniquely identify a
 ///     host: host identifier, host identifier type, subnets for IPv4 and IPv6
-typedef boost::tuple<HostIdentifier,
-                     Host::IdentifierType,
-                     SubnetID,
-                     SubnetID,
-                     asiolink::IOAddress>
-    HostKey;
+///     and the IPv4 reservation
+typedef std::
+    tuple<HostIdentifier, Host::IdentifierType, SubnetID, SubnetID, IOAddress>
+        HostKey;
+
+enum HostKeyComponent {
+    HOST_IDENTIFIER,
+    HOST_IDENTIFIER_TYPE,
+    IPv4_SUBNET_ID,
+    IPv6_SUBNET_ID,
+    IPv4_RESERVATION
+};
 
 /// @brief Map used to merge reservations and options into a single host on
 ///     retrieve from database
-typedef boost::unordered_map<HostKey, HostPtr, boost::hash<HostKey> > HostMap;
+typedef std::unordered_map<HostKey, HostPtr, boost::hash<HostKey>> HostMap;
+
+typedef std::pair<HostKey, HostPtr> HostPair;
+
+/// @brief Wrapper used to specify option space alongside option descriptor
+struct OptionWrapper {
+    OptionWrapper(OptionDescriptorPtr option_descriptor,
+                  std::string option_space)
+        : option_descriptor_(option_descriptor), option_space_(option_space) {
+    }
+    OptionDescriptorPtr option_descriptor_;
+    std::string option_space_;
+};
 
 /// @brief Maximum size of an IPv4 address represented as a text string. 12
 ///     digits plus 3 full stops (dots).
-static const size_t ADDRESS4_TEXT_MAX_LENGTH = 15U;
+static constexpr size_t ADDRESS4_TEXT_MAX_LENGTH = 15u;
 
 /// @brief Maximum size of an IPv6 address represented as a text string. 32
 ///     hexadecimal characters written in 8 groups of four, plus 7 colon
 ///     separators.
-static const size_t ADDRESS6_TEXT_MAX_LENGTH = 39U;
+static constexpr size_t ADDRESS6_TEXT_MAX_LENGTH = 39u;
 
 /// @brief Maximum length of classes stored in a host_ipv4/6_client_classes
 ///     column.
-static const size_t CLIENT_CLASSES_MAX_LENGTH = 255U;
+static constexpr size_t CLIENT_CLASSES_MAX_LENGTH = 255u;
 
 /// @brief Maximum length of the hostname stored in DNS. This length is
 ///     restricted by the length of the domain-name carried in the Client FQDN
 ///     Option (see RFC4702 and RFC4704).
-static const size_t HOSTNAME_MAX_LENGTH = 255U;
+static constexpr size_t HOSTNAME_MAX_LENGTH = 255u;
 
 /// @brief Maximum length of option value
-static const size_t OPTION_VALUE_MAX_LENGTH = 4096U;
+static constexpr size_t OPTION_VALUE_MAX_LENGTH = 4096u;
 
 /// @brief Maximum length of option value specified in textual format
-static const size_t OPTION_FORMATTED_VALUE_MAX_LENGTH = 8192U;
+static constexpr size_t OPTION_FORMATTED_VALUE_MAX_LENGTH = 8192u;
 
 /// @brief Maximum length of option space name
-static const size_t OPTION_SPACE_MAX_LENGTH = 128U;
+static constexpr size_t OPTION_SPACE_MAX_LENGTH = 128u;
 
 /// @brief Numeric value representing the last supported identifier. This value
 ///     is used to validate whether the identifier type stored in a database is
 ///     within bounds of supported identifiers.
-static const cass_int8_t MAX_IDENTIFIER_TYPE =
-    static_cast<cass_int8_t>(Host::IDENT_CIRCUIT_ID);
+static constexpr cass_int32_t MAX_IDENTIFIER_TYPE =
+    static_cast<cass_int32_t>(Host::IDENT_CIRCUIT_ID);
 
 /// @{
 /// @brief Invalid values in the Cassandra database
-static const char NULL_RESERVED_IPV6_PREFIX_ADDRESS[] = "";
-static const cass_int32_t NULL_RESERVED_IPV6_PREFIX_LENGTH = 0;
-static const cass_int32_t NULL_RESERVED_IPV6_PREFIX_ADDRESS_TYPE = -1;
-static const cass_int32_t NULL_IAID = -1;
-static const cass_int32_t NULL_OPTION_UNIVERSE = -1;
-static const cass_int32_t NULL_OPTION_CODE = -1;
-static const CassOptionBuffer NULL_OPTION_VALUE = CassOptionBuffer();
-static const char NULL_OPTION_FORMATTED_VALUE[] = "";
-static const char NULL_OPTION_SPACE[] = "";
-static const cass_bool_t NULL_OPTION_IS_PERSISTENT = cass_false;
-static const char NULL_OPTION_CLIENT_CLASS[] = "";
-static const cass_int32_t NULL_OPTION_SUBNET_ID = -1;
+static constexpr char NULL_RESERVED_IPV6_PREFIX_ADDRESS[] = "::";
+static constexpr cass_int32_t NULL_RESERVED_IPV6_PREFIX_LENGTH = 0;
+static constexpr cass_int32_t NULL_RESERVED_IPV6_PREFIX_ADDRESS_TYPE = -1;
+static constexpr cass_int32_t NULL_IAID = -1;
+static constexpr cass_int32_t NULL_OPTION_UNIVERSE = -1;
+static constexpr cass_int32_t NULL_OPTION_CODE = -1;
+static const CassBlob NULL_OPTION_VALUE = CassBlob();
+static constexpr char NULL_OPTION_FORMATTED_VALUE[] = "";
+static constexpr char NULL_OPTION_SPACE[] = "";
+static constexpr cass_bool_t NULL_OPTION_IS_PERSISTENT = cass_false;
+static constexpr char NULL_OPTION_CLIENT_CLASS[] = "";
+static constexpr cass_int32_t NULL_OPTION_SUBNET_ID = -1;
+// static constexpr CassCollection* NULL_COLLECTION = NULL;
 /// @}
 
 /// @brief Invalid reservation used to check for an invalid IPv6Resrv formed
@@ -121,377 +136,19 @@ static const cass_int32_t NULL_OPTION_SUBNET_ID = -1;
 static const IPv6Resrv NULL_IPV6_RESERVATION =
     IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("::"), 128);
 
-}  // anonymous namespace
+}  // namespace
 
 namespace isc {
 namespace dhcp {
 
-/// @{
-/// @brief Statement parameters
-// INSERT_HOST
-static const char* INSERT_HOST_PARAMS[] = {
-    static_cast<const char*>("id"),
-    static_cast<const char*>("host_identifier"),
-    static_cast<const char*>("host_identifier_type"),
-    static_cast<const char*>("host_ipv4_subnet_id"),
-    static_cast<const char*>("host_ipv6_subnet_id"),
-    static_cast<const char*>("host_ipv4_address"),
-    static_cast<const char*>("hostname"),
-    static_cast<const char*>("host_ipv4_client_classes"),
-    static_cast<const char*>("host_ipv6_client_classes"),
-    static_cast<const char*>("reserved_ipv6_prefix_address"),
-    static_cast<const char*>("reserved_ipv6_prefix_length"),
-    static_cast<const char*>("reserved_ipv6_prefix_address_type"),
-    static_cast<const char*>("iaid"),
-    static_cast<const char*>("option_universe"),
-    static_cast<const char*>("option_code"),
-    static_cast<const char*>("option_value"),
-    static_cast<const char*>("option_formatted_value"),
-    static_cast<const char*>("option_space"),
-    static_cast<const char*>("option_is_persistent"),
-    static_cast<const char*>("option_client_class"),
-    static_cast<const char*>("option_subnet_id"),
-    NULL};
-// GET_HOST_BY_HOST_ID
-static const char* GET_HOST_BY_HOST_ID_PARAMS[] = {
-    static_cast<const char*>("host_identifier"),
-    static_cast<const char*>("host_identifier_type"),
-    NULL};
-// GET_HOST_BY_IPV4_ADDRESS
-static const char* GET_HOST_BY_IPV4_ADDRESS_PARAMS[] = {
-    static_cast<const char*>("host_ipv4_address"),
-    NULL};
-// GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID
-static const char* GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID_PARAMS[] = {
-    static_cast<const char*>("host_ipv4_subnet_id"),
-    static_cast<const char*>("host_identifier"),
-    static_cast<const char*>("host_identifier_type"),
-    NULL};
-// GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID,
-static const char* GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID_PARAMS[] = {
-    static_cast<const char*>("host_ipv6_subnet_id"),
-    static_cast<const char*>("host_identifier"),
-    static_cast<const char*>("host_identifier_type"),
-    NULL};
-// GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS,
-static const char* GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS_PARAMS[] = {
-    static_cast<const char*>("host_ipv4_subnet_id"),
-    static_cast<const char*>("host_ipv4_address"),
-    NULL};
-// GET_HOST_BY_IPV6_PREFIX
-static const char* GET_HOST_BY_IPV6_PREFIX_PARAMS[] = {
-    static_cast<const char*>("reserved_ipv6_prefix_address"),
-    static_cast<const char*>("reserved_ipv6_prefix_length"),
-    NULL};
-// GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS
-static const char* GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS_PARAMS[] = {
-    static_cast<const char*>("host_ipv6_subnet_id"),
-    static_cast<const char*>("reserved_ipv6_prefix_address"),
-    NULL};
-// GET_VERSION
-static const char* GET_VERSION_PARAMS[] = {NULL};
-/// @}
-
-/// @brief Prepared CQL statements used by the backend to insert and retrieve
-///     hosts from the database.
-static CqlTaggedStatement tagged_statements[] = {
-    // INSERT_HOST
-    {INSERT_HOST_PARAMS, "INSERT_HOST",
-     "INSERT INTO host_reservations ( "
-     "id, "
-     "host_identifier, "
-     "host_identifier_type, "
-     "host_ipv4_subnet_id, "
-     "host_ipv6_subnet_id, "
-     "host_ipv4_address, "
-     "hostname, "
-     "host_ipv4_client_classes, "
-     "host_ipv6_client_classes, "
-     "reserved_ipv6_prefix_address, "
-     "reserved_ipv6_prefix_length, "
-     "reserved_ipv6_prefix_address_type, "
-     "iaid, "
-     "option_universe, "
-     "option_code, "
-     "option_value, "
-     "option_formatted_value, "
-     "option_space, "
-     "option_is_persistent, "
-     "option_client_class, "
-     "option_subnet_id "
-     ") "
-     "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "
-     "IF NOT EXISTS "
-    },
-
-    // GET_HOST_BY_HOST_ID
-    {GET_HOST_BY_HOST_ID_PARAMS, "GET_HOST_BY_HOST_ID",
-     "SELECT "
-     "id, "
-     "host_identifier, "
-     "host_identifier_type, "
-     "host_ipv4_subnet_id, "
-     "host_ipv6_subnet_id, "
-     "host_ipv4_address, "
-     "hostname, "
-     "host_ipv4_client_classes, "
-     "host_ipv6_client_classes, "
-     "reserved_ipv6_prefix_address, "
-     "reserved_ipv6_prefix_length, "
-     "reserved_ipv6_prefix_address_type, "
-     "iaid, "
-     "option_universe, "
-     "option_code, "
-     "option_value, "
-     "option_formatted_value, "
-     "option_space, "
-     "option_is_persistent, "
-     "option_client_class, "
-     "option_subnet_id "
-     "FROM host_reservations "
-     "WHERE host_identifier = ? "
-     "AND host_identifier_type = ? "
-     "ALLOW FILTERING "
-    },
-
-    // GET_HOST_BY_IPV4_ADDRESS
-    {GET_HOST_BY_IPV4_ADDRESS_PARAMS, "GET_HOST_BY_IPV4_ADDRESS",
-     "SELECT "
-     "id, "
-     "host_identifier, "
-     "host_identifier_type, "
-     "host_ipv4_subnet_id, "
-     "host_ipv6_subnet_id, "
-     "host_ipv4_address, "
-     "hostname, "
-     "host_ipv4_client_classes, "
-     "host_ipv6_client_classes, "
-     "reserved_ipv6_prefix_address, "
-     "reserved_ipv6_prefix_length, "
-     "reserved_ipv6_prefix_address_type, "
-     "iaid, "
-     "option_universe, "
-     "option_code, "
-     "option_value, "
-     "option_formatted_value, "
-     "option_space, "
-     "option_is_persistent, "
-     "option_client_class, "
-     "option_subnet_id "
-     "FROM host_reservations "
-     "WHERE host_ipv4_address = ? "
-     "ALLOW FILTERING "
-    },
-
-    // GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID
-    {GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID_PARAMS,
-     "GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID",
-     "SELECT "
-     "id, "
-     "host_identifier, "
-     "host_identifier_type, "
-     "host_ipv4_subnet_id, "
-     "host_ipv6_subnet_id, "
-     "host_ipv4_address, "
-     "hostname, "
-     "host_ipv4_client_classes, "
-     "host_ipv6_client_classes, "
-     "reserved_ipv6_prefix_address, "
-     "reserved_ipv6_prefix_length, "
-     "reserved_ipv6_prefix_address_type, "
-     "iaid, "
-     "option_universe, "
-     "option_code, "
-     "option_value, "
-     "option_formatted_value, "
-     "option_space, "
-     "option_is_persistent, "
-     "option_client_class, "
-     "option_subnet_id "
-     "FROM host_reservations "
-     "WHERE host_ipv4_subnet_id = ? "
-     "AND host_identifier = ? "
-     "AND host_identifier_type = ? "
-     "ALLOW FILTERING "
-    },
-
-    // GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID
-    {GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID_PARAMS,
-     "GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID",
-     "SELECT "
-     "id, "
-     "host_identifier, "
-     "host_identifier_type, "
-     "host_ipv4_subnet_id, "
-     "host_ipv6_subnet_id, "
-     "host_ipv4_address, "
-     "hostname, "
-     "host_ipv4_client_classes, "
-     "host_ipv6_client_classes, "
-     "reserved_ipv6_prefix_address, "
-     "reserved_ipv6_prefix_length, "
-     "reserved_ipv6_prefix_address_type, "
-     "iaid, "
-     "option_universe, "
-     "option_code, "
-     "option_value, "
-     "option_formatted_value, "
-     "option_space, "
-     "option_is_persistent, "
-     "option_client_class, "
-     "option_subnet_id "
-     "FROM host_reservations "
-     "WHERE host_ipv6_subnet_id = ? "
-     "AND host_identifier = ? "
-     "AND host_identifier_type = ? "
-     "ALLOW FILTERING "
-    },
-
-    // GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS
-    {GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS_PARAMS,
-     "GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS",
-     "SELECT "
-     "id, "
-     "host_identifier, "
-     "host_identifier_type, "
-     "host_ipv4_subnet_id, "
-     "host_ipv6_subnet_id, "
-     "host_ipv4_address, "
-     "hostname, "
-     "host_ipv4_client_classes, "
-     "host_ipv6_client_classes, "
-     "reserved_ipv6_prefix_address, "
-     "reserved_ipv6_prefix_length, "
-     "reserved_ipv6_prefix_address_type, "
-     "iaid, "
-     "option_universe, "
-     "option_code, "
-     "option_value, "
-     "option_formatted_value, "
-     "option_space, "
-     "option_is_persistent, "
-     "option_client_class, "
-     "option_subnet_id "
-     "FROM host_reservations "
-     "WHERE host_ipv4_subnet_id = ? "
-     "AND host_ipv4_address = ? "
-     "ALLOW FILTERING "
-    },
-
-    // GET_HOST_BY_IPV6_PREFIX
-    {GET_HOST_BY_IPV6_PREFIX_PARAMS, "GET_HOST_BY_IPV6_PREFIX",
-     "SELECT "
-     "id, "
-     "host_identifier, "
-     "host_identifier_type, "
-     "host_ipv4_subnet_id, "
-     "host_ipv6_subnet_id, "
-     "host_ipv4_address, "
-     "hostname, "
-     "host_ipv4_client_classes, "
-     "host_ipv6_client_classes, "
-     "reserved_ipv6_prefix_address, "
-     "reserved_ipv6_prefix_length, "
-     "reserved_ipv6_prefix_address_type, "
-     "iaid, "
-     "option_universe, "
-     "option_code, "
-     "option_value, "
-     "option_formatted_value, "
-     "option_space, "
-     "option_is_persistent, "
-     "option_client_class, "
-     "option_subnet_id "
-     "FROM host_reservations "
-     "WHERE reserved_ipv6_prefix_address = ? "
-     "AND reserved_ipv6_prefix_length = ? "
-     "ALLOW FILTERING "
-    },
-
-    // GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS
-    {GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS_PARAMS,
-     "GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS",
-     "SELECT "
-     "id, "
-     "host_identifier, "
-     "host_identifier_type, "
-     "host_ipv4_subnet_id, "
-     "host_ipv6_subnet_id, "
-     "host_ipv4_address, "
-     "hostname, "
-     "host_ipv4_client_classes, "
-     "host_ipv6_client_classes, "
-     "reserved_ipv6_prefix_address, "
-     "reserved_ipv6_prefix_length, "
-     "reserved_ipv6_prefix_address_type, "
-     "iaid, "
-     "option_universe, "
-     "option_code, "
-     "option_value, "
-     "option_formatted_value, "
-     "option_space, "
-     "option_is_persistent, "
-     "option_client_class, "
-     "option_subnet_id "
-     "FROM host_reservations "
-     "WHERE host_ipv6_subnet_id = ? "
-     "AND reserved_ipv6_prefix_address = ? "
-     "ALLOW FILTERING "
-    },
-
-    // GET_VERSION
-    {GET_VERSION_PARAMS, "GET_VERSION",
-     "SELECT version, minor FROM schema_version"},
-
-    // End of list sentinel
-    {NULL, NULL, NULL}};  // tagged_statements
-
 /// @brief Provides mechanisms for sending and retrieving data from the
 ///     host_reservations table.
 class CqlHostExchange : public virtual CqlExchange {
 public:
-    /// @brief Statement Tags
-    ///
-    /// The contents of the enum are indexes into the list of CQL statements
-    enum StatementIndex {
-        // Inserts all options belonging to any reservation from a single host.
-        INSERT_HOST,
-        // Retrieves host information, IPv6 reservations and both IPv4 and IPv6
-        // options associated with the host.
-        GET_HOST_BY_HOST_ID,
-        // Retrieves host information along with the IPv4 options associated
-        // with it.
-        GET_HOST_BY_IPV4_ADDRESS,
-        // Retrieves host information and IPv4 options using subnet identifier
-        // and client's identifier (i.e. hardware address or DUID).
-        GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID,
-        // Retrieves host information, IPv6 reservations and IPv6 options
-        // associated with a host using subnet identifier and client's
-        // identifier (i.e. hardware address or DUID).
-        GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID,
-        // Retrieves host information and IPv4 options for the host using subnet
-        // identifier and IPv4 reservation.
-        GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS,
-        // Retrieves host information, IPv6 reservations and IPv6 options
-        // associated with a host using prefix and prefix length. This query
-        // returns host information for a single host. However, multiple rows
-        // are returned due to left joining IPv6 reservations and IPv6 options.
-        // The number of rows returned is multiplication of number of existing
-        // IPv6 reservations and IPv6 options.
-        GET_HOST_BY_IPV6_PREFIX,
-        // Retrieves host information and IPv6 options for the host using subnet
-        // identifier and IPv6 reservation.
-        GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS,
-        // Get CQL schema version.
-        GET_VERSION,
-        // Number of statements
-        NUM_STATEMENTS
-    };
-
     /// @brief Constructor
     ///
     /// Specifies table columns.
-    CqlHostExchange();
+    CqlHostExchange(CqlConnection& connection);
 
     /// @brief Virtual destructor.
     virtual ~CqlHostExchange();
@@ -501,13 +158,14 @@ public:
     /// Creates a bind array to receive @ref Host data from the Cassandra
     /// database. After data is successfully received, @ref retrieve() can be
     /// called to retrieve the @ref Host object. Called in @ref
-    /// CqlExchange::executeRead().
+    /// CqlExchange::executeSelect().
     ///
     /// @param data array of objects representing data being retrieved
-    /// @param statement_index prepared statement being executed; defaults to an
+    /// @param statement_tag prepared statement being executed; defaults to an
     ///     invalid statement
-    virtual void createBindForReceive(CqlDataArray& data,
-                                      const int statement_index = -1);
+    virtual void
+    createBindForSelect(AnyArray& data,
+                        StatementTag statement_tag = NULL) override;
 
     /// @brief Binds @ref Host to data array to send data to the Cassandra
     ///     database.
@@ -521,12 +179,14 @@ public:
     /// @param option_space option space
     /// @param option_descriptor structure used to hold option information
     /// @param data array being filled with data from to the Host object
-    void createBindForSend(const HostPtr& host,
-                           const OptionalValue<SubnetID>& subnet_id,
-                           const IPv6Resrv* const reservation,
-                           const std::string& option_space,
-                           const OptionDescriptor& option_descriptor,
-                           CqlDataArray& data);
+    /// @param statement_tag tag of the statement being executed
+    void createBindForMutation(const HostPtr& host,
+                               const OptionalValue<SubnetID>& subnet_id,
+                               const IPv6Resrv* const reservation,
+                               const std::string& option_space,
+                               const OptionDescriptor& option_descriptor,
+                               StatementTag statement_tag,
+                               AnyArray& data);
 
     /// @brief Create unique hash for storage in table id.
     ///
@@ -542,34 +202,85 @@ public:
     /// @brief Copy received data into Host object
     ///
     /// Copies information about the host into a newly created @ref Host object
-    /// Called in @ref executeRead after @ref createBindForReceive().
+    /// Called in @ref executeSelect after @ref createBindForSelect().
     ///
     /// @return Host Pointer to a @ref HostPtr object holding a pointer to the
     /// @ref Host object returned.
-    virtual void* retrieve();
+    virtual boost::any retrieve() override;
 
     /// @brief Creates IPv6 reservation from the data contained in the
-    /// currently processed row.
+    ///     currently processed row.
     ///
-    /// Called after createBindForReceive().
+    /// Called after createBindForSelect().
     ///
     /// @return IPv6Resrv object (containing IPv6 address or prefix reservation)
     const IPv6Resrv retrieveReservation() const;
 
     /// @brief Retrieves option from members.
-    OptionDescriptorPtr retrieveOption() const;
+    ///
+    /// Called after createBindForSelect().
+    ///
+    /// @return OptionDescriptorPtr object (containing the option from the
+    /// database)
+    const OptionWrapper retrieveOption() const;
+
+    /// @brief Statement tags definitions
+    /// @{
+    // Inserts all options belonging to any reservation from a single host.
+    static constexpr StatementTag INSERT_HOST = "INSERT_HOST";
+
+    // Retrieves host information, IPv6 reservations and both IPv4 and IPv6
+    // options associated with the host.
+    static constexpr StatementTag GET_HOST_BY_HOST_ID = "GET_HOST_BY_HOST_ID";
+
+    // Retrieves host information along with the IPv4 options associated
+    // with it.
+    static constexpr StatementTag GET_HOST_BY_IPV4_ADDRESS =
+        "GET_HOST_BY_IPV4_ADDRESS";
+    // Retrieves host information and IPv4 options using subnet identifier
+    // and client's identifier (i.e. hardware address or DUID).
+    static constexpr StatementTag GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID =
+        "GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID";
+    // Retrieves host information; IPv6 reservations and IPv6 options
+    // associated with a host using subnet identifier and client's
+    // identifier (i.e. hardware address or DUID).
+    static constexpr StatementTag GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID =
+        "GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID";
+    // Retrieves host information and IPv4 options for the host using subnet
+    // identifier and IPv4 reservation.
+    static constexpr StatementTag GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS =
+        "GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS";
+    // Retrieves host information, IPv6 reservations and IPv6 options
+    // associated with a host using prefix and prefix length. This query
+    // returns host information for a single host. However, multiple rows
+    // are returned due to left joining IPv6 reservations and IPv6 options.
+    // The number of rows returned is multiplication of number of existing
+    // IPv6 reservations and IPv6 options.
+    static constexpr StatementTag GET_HOST_BY_IPV6_PREFIX =
+        "GET_HOST_BY_IPV6_PREFIX";
+    // Retrieves host information and IPv6 options for the host using subnet
+    // identifier and IPv6 reservation.
+    static constexpr StatementTag GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS =
+        "GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS";
+    /// @}
+
+    /// @brief Cassandra statements
+    static StatementMap tagged_statements_;
 
 private:
     /// Pointer to Host object holding information being inserted into database.
     HostPtr host_;
 
+    /// @brief Connection to the Cassandra database
+    CqlConnection& connection_;
+
     /// @brief Primary key. Aggregates: host_identifier, host_identifier_type,
     /// reserved_ipv6_prefix_address, reserved_ipv6_prefix_length, option_code,
     /// option_space.
     cass_int64_t id_;
 
     /// @brief Client's identifier (e.g. DUID, HW address) in binary format
-    CassHostIdentifier host_identifier_;
+    CassBlob host_identifier_;
 
     /// @brief Type of the identifier in the host_identifier_
     /// This value corresponds to the @ref Host::IdentifierType value.
@@ -578,7 +289,7 @@ private:
     /// @brief IPv4 subnet identifier
     cass_int32_t host_ipv4_subnet_id_;
 
-    /// @brief Ipv6 subnet identifier
+    /// @brief IPv6 subnet identifier
     cass_int32_t host_ipv6_subnet_id_;
 
     /// @brief Reserved IPv4 address
@@ -614,7 +325,7 @@ private:
     cass_int32_t option_code_;
 
     /// @brief Option value
-    CassOptionBuffer option_value_;
+    CassBlob option_value_;
 
     /// @brief The textual value of an option
     std::string option_formatted_value_;
@@ -632,140 +343,346 @@ private:
     cass_int32_t option_subnet_id_;
 };  // CqlHostExchange
 
-CqlHostExchange::CqlHostExchange()
-    : host_identifier_type_(0), host_ipv4_subnet_id_(0),
-      host_ipv6_subnet_id_(0), host_ipv4_address_(0),
-      reserved_ipv6_prefix_length_(0), reserved_ipv6_prefix_address_type_(0),
-      iaid_(0), option_universe_(0), option_code_(0),
-      option_is_persistent_(cass_false), option_subnet_id_(0) {
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "id", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_INT64)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "host_identifier", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_BYTES)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "host_identifier_type", parameters_.size(),
-        EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "host_ipv4_subnet_id", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_INT32)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "host_ipv6_subnet_id", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_INT32)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "host_ipv4_address", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_INT32)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "hostname", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_STRING)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "host_ipv4_client_classes", parameters_.size(),
-        EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "host_ipv6_client_classes", parameters_.size(),
-        EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "reserved_ipv6_prefix_address", parameters_.size(),
-        EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "reserved_ipv6_prefix_length", parameters_.size(),
-        EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "reserved_ipv6_prefix_address_type", parameters_.size(),
-        EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "iaid", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_INT32)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "option_universe", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_INT32)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "option_code", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_INT32)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "option_value", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_BYTES)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "option_formatted_value", parameters_.size(),
-        EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "option_space", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_STRING)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "option_is_persistent", parameters_.size(),
-        EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BOOL)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "option_client_class", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_STRING)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "option_subnet_id", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_INT32)));
-    parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
-        "[applied]", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
-        EXCHANGE_DATA_TYPE_BOOL)));
-    BOOST_ASSERT(parameters_.size() == 22U);
+constexpr StatementTag CqlHostExchange::INSERT_HOST;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_HOST_ID;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV4_ADDRESS;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_PREFIX;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS;
+
+StatementMap CqlHostExchange::tagged_statements_ = {
+    {INSERT_HOST,   //
+     {INSERT_HOST,  //
+      "INSERT INTO host_reservations ( "
+      "id, "
+      "host_identifier, "
+      "host_identifier_type, "
+      "host_ipv4_subnet_id, "
+      "host_ipv6_subnet_id, "
+      "host_ipv4_address, "
+      "hostname, "
+      "host_ipv4_client_classes, "
+      "host_ipv6_client_classes, "
+      "reserved_ipv6_prefix_address, "
+      "reserved_ipv6_prefix_length, "
+      "reserved_ipv6_prefix_address_type, "
+      "iaid, "
+      "option_universe, "
+      "option_code, "
+      "option_value, "
+      "option_formatted_value, "
+      "option_space, "
+      "option_is_persistent, "
+      "option_client_class, "
+      "option_subnet_id "
+      ") VALUES ( "
+      // id
+      "?, "
+      // host
+      "?, ?, ?, ?, ?, ?, ?, ?, "
+      // denormalized reservation, option
+      "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? "
+      ") "
+      "IF NOT EXISTS "
+     }},
+
+    {GET_HOST_BY_HOST_ID,   //
+     {GET_HOST_BY_HOST_ID,  //
+      "SELECT "
+      "id, "
+      "host_identifier, "
+      "host_identifier_type, "
+      "host_ipv4_subnet_id, "
+      "host_ipv6_subnet_id, "
+      "host_ipv4_address, "
+      "hostname, "
+      "host_ipv4_client_classes, "
+      "host_ipv6_client_classes, "
+      "reserved_ipv6_prefix_address, "
+      "reserved_ipv6_prefix_length, "
+      "reserved_ipv6_prefix_address_type, "
+      "iaid, "
+      "option_universe, "
+      "option_code, "
+      "option_value, "
+      "option_formatted_value, "
+      "option_space, "
+      "option_is_persistent, "
+      "option_client_class, "
+      "option_subnet_id "
+      "FROM host_reservations "
+      "WHERE host_identifier = ? "
+      "AND host_identifier_type = ? "
+      "ALLOW FILTERING "
+     }},
+
+    {GET_HOST_BY_IPV4_ADDRESS,   //
+     {GET_HOST_BY_IPV4_ADDRESS,  //
+      "SELECT "
+      "id, "
+      "host_identifier, "
+      "host_identifier_type, "
+      "host_ipv4_subnet_id, "
+      "host_ipv6_subnet_id, "
+      "host_ipv4_address, "
+      "hostname, "
+      "host_ipv4_client_classes, "
+      "host_ipv6_client_classes, "
+      "reserved_ipv6_prefix_address, "
+      "reserved_ipv6_prefix_length, "
+      "reserved_ipv6_prefix_address_type, "
+      "iaid, "
+      "option_universe, "
+      "option_code, "
+      "option_value, "
+      "option_formatted_value, "
+      "option_space, "
+      "option_is_persistent, "
+      "option_client_class, "
+      "option_subnet_id "
+      "FROM host_reservations "
+      "WHERE host_ipv4_address = ? "
+      "ALLOW FILTERING "
+     }},
+
+    {GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID,   //
+     {GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID,  //
+      "SELECT "
+      "id, "
+      "host_identifier, "
+      "host_identifier_type, "
+      "host_ipv4_subnet_id, "
+      "host_ipv6_subnet_id, "
+      "host_ipv4_address, "
+      "hostname, "
+      "host_ipv4_client_classes, "
+      "host_ipv6_client_classes, "
+      "reserved_ipv6_prefix_address, "
+      "reserved_ipv6_prefix_length, "
+      "reserved_ipv6_prefix_address_type, "
+      "iaid, "
+      "option_universe, "
+      "option_code, "
+      "option_value, "
+      "option_formatted_value, "
+      "option_space, "
+      "option_is_persistent, "
+      "option_client_class, "
+      "option_subnet_id "
+      "FROM host_reservations "
+      "WHERE host_ipv4_subnet_id = ? "
+      "AND host_identifier = ? "
+      "AND host_identifier_type = ? "
+      "ALLOW FILTERING "
+     }},
+
+    {GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID,   //
+     {GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID,  //
+      "SELECT "
+      "id, "
+      "host_identifier, "
+      "host_identifier_type, "
+      "host_ipv4_subnet_id, "
+      "host_ipv6_subnet_id, "
+      "host_ipv4_address, "
+      "hostname, "
+      "host_ipv4_client_classes, "
+      "host_ipv6_client_classes, "
+      "reserved_ipv6_prefix_address, "
+      "reserved_ipv6_prefix_length, "
+      "reserved_ipv6_prefix_address_type, "
+      "iaid, "
+      "option_universe, "
+      "option_code, "
+      "option_value, "
+      "option_formatted_value, "
+      "option_space, "
+      "option_is_persistent, "
+      "option_client_class, "
+      "option_subnet_id "
+      "FROM host_reservations "
+      "WHERE host_ipv6_subnet_id = ? "
+      "AND host_identifier = ? "
+      "AND host_identifier_type = ? "
+      "ALLOW FILTERING "
+     }},
+
+    {GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS,   //
+     {GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS,  //
+      "SELECT "
+      "id, "
+      "host_identifier, "
+      "host_identifier_type, "
+      "host_ipv4_subnet_id, "
+      "host_ipv6_subnet_id, "
+      "host_ipv4_address, "
+      "hostname, "
+      "host_ipv4_client_classes, "
+      "host_ipv6_client_classes, "
+      "reserved_ipv6_prefix_address, "
+      "reserved_ipv6_prefix_length, "
+      "reserved_ipv6_prefix_address_type, "
+      "iaid, "
+      "option_universe, "
+      "option_code, "
+      "option_value, "
+      "option_formatted_value, "
+      "option_space, "
+      "option_is_persistent, "
+      "option_client_class, "
+      "option_subnet_id "
+      "FROM host_reservations "
+      "WHERE host_ipv4_subnet_id = ? "
+      "AND host_ipv4_address = ? "
+      "ALLOW FILTERING "
+     }},
+
+    {GET_HOST_BY_IPV6_PREFIX,   //
+     {GET_HOST_BY_IPV6_PREFIX,  //
+      "SELECT "
+      "id, "
+      "host_identifier, "
+      "host_identifier_type, "
+      "host_ipv4_subnet_id, "
+      "host_ipv6_subnet_id, "
+      "host_ipv4_address, "
+      "hostname, "
+      "host_ipv4_client_classes, "
+      "host_ipv6_client_classes, "
+      "reserved_ipv6_prefix_address, "
+      "reserved_ipv6_prefix_length, "
+      "reserved_ipv6_prefix_address_type, "
+      "iaid, "
+      "option_universe, "
+      "option_code, "
+      "option_value, "
+      "option_formatted_value, "
+      "option_space, "
+      "option_is_persistent, "
+      "option_client_class, "
+      "option_subnet_id "
+      "FROM host_reservations "
+      "WHERE reserved_ipv6_prefix_address = ? "
+      "AND reserved_ipv6_prefix_length = ? "
+      "ALLOW FILTERING "
+     }},
+
+    {GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS,   //
+     {GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS,  //
+      "SELECT "
+      "id, "
+      "host_identifier, "
+      "host_identifier_type, "
+      "host_ipv4_subnet_id, "
+      "host_ipv6_subnet_id, "
+      "host_ipv4_address, "
+      "hostname, "
+      "host_ipv4_client_classes, "
+      "host_ipv6_client_classes, "
+      "reserved_ipv6_prefix_address, "
+      "reserved_ipv6_prefix_length, "
+      "reserved_ipv6_prefix_address_type, "
+      "iaid, "
+      "option_universe, "
+      "option_code, "
+      "option_value, "
+      "option_formatted_value, "
+      "option_space, "
+      "option_is_persistent, "
+      "option_client_class, "
+      "option_subnet_id "
+      "FROM host_reservations "
+      "WHERE host_ipv6_subnet_id = ? "
+      "AND reserved_ipv6_prefix_address = ? "
+      "ALLOW FILTERING "
+     }},
+
+};
+
+CqlHostExchange::CqlHostExchange(CqlConnection& connection)
+    : host_(NULL), connection_(connection), id_(0), host_identifier_type_(0),
+      host_ipv4_subnet_id_(0), host_ipv6_subnet_id_(0), host_ipv4_address_(0),
+      reserved_ipv6_prefix_length_(NULL_RESERVED_IPV6_PREFIX_LENGTH),
+      reserved_ipv6_prefix_address_type_(
+          NULL_RESERVED_IPV6_PREFIX_ADDRESS_TYPE),
+      iaid_(NULL_IAID), option_universe_(NULL_OPTION_UNIVERSE),
+      option_code_(NULL_OPTION_CODE),
+      option_is_persistent_(NULL_OPTION_IS_PERSISTENT),
+      option_subnet_id_(NULL_OPTION_SUBNET_ID) {
 }
 
 CqlHostExchange::~CqlHostExchange() {
 }
 
 void
-CqlHostExchange::createBindForReceive(CqlDataArray& data,
-                                      const int /* statement_index = -1 */) {
+CqlHostExchange::createBindForSelect(AnyArray& data,
+                                     StatementTag /* statement_tag = NULL */) {
     // Start with a fresh array.
     data.clear();
+
     // id: blob
-    data.add(reinterpret_cast<void*>(&id_));
+    data.add(&id_);
+
     // host_identifier: blob
-    data.add(reinterpret_cast<void*>(&host_identifier_));
+    data.add(&host_identifier_);
     // host_identifier_type: int
-    data.add(reinterpret_cast<void*>(&host_identifier_type_));
+    data.add(&host_identifier_type_);
     // host_ipv4_subnet_id: int
-    data.add(reinterpret_cast<void*>(&host_ipv4_subnet_id_));
+    data.add(&host_ipv4_subnet_id_);
     // host_ipv6_subnet_id: int
-    data.add(reinterpret_cast<void*>(&host_ipv6_subnet_id_));
+    data.add(&host_ipv6_subnet_id_);
     // host_ipv4_address: int
-    data.add(reinterpret_cast<void*>(&host_ipv4_address_));
+    data.add(&host_ipv4_address_);
     // hostname: text
-    data.add(reinterpret_cast<void*>(&hostname_));
+    data.add(&hostname_);
     // host_ipv4_client_classes: text
-    data.add(reinterpret_cast<void*>(&host_ipv4_client_classes_));
+    data.add(&host_ipv4_client_classes_);
     // host_ipv6_client_classes: text
-    data.add(reinterpret_cast<void*>(&host_ipv6_client_classes_));
+    data.add(&host_ipv6_client_classes_);
+    /// @brief Denormalized reservation columns
+    /// @{
     // reserved_ipv6_prefix_address: text
-    data.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_address_));
-    // reserved_ipv6_prefix_length: int
-    data.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_length_));
+    data.add(&reserved_ipv6_prefix_address_);
     // reserved_ipv6_prefix_length: int
-    data.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_address_type_));
+    data.add(&reserved_ipv6_prefix_length_);
+    // reserved_ipv6_prefix_address_type: int
+    data.add(&reserved_ipv6_prefix_address_type_);
     // iaid: int
-    data.add(reinterpret_cast<void*>(&iaid_));
+    data.add(&iaid_);
+    /// @}
+
+    /// @brief Denormalized option columns
+    /// @{
     // option_universe: int
-    data.add(reinterpret_cast<void*>(&option_universe_));
+    data.add(&option_universe_);
     // option_code: int
-    data.add(reinterpret_cast<void*>(&option_code_));
+    data.add(&option_code_);
     // option_value: blob
-    data.add(reinterpret_cast<void*>(&option_value_));
+    data.add(&option_value_);
     // option_formatted_value: text
-    data.add(reinterpret_cast<void*>(&option_formatted_value_));
+    data.add(&option_formatted_value_);
     // option_space: text
-    data.add(reinterpret_cast<void*>(&option_space_));
+    data.add(&option_space_);
     // option_is_persistent: boolean
-    data.add(reinterpret_cast<void*>(&option_is_persistent_));
+    data.add(&option_is_persistent_);
     // option_client_class: text
-    data.add(reinterpret_cast<void*>(&option_client_class_));
+    data.add(&option_client_class_);
     // option_subnet_id: int
-    data.add(reinterpret_cast<void*>(&option_subnet_id_));
+    data.add(&option_subnet_id_);
+    /// @}
 }
 
 void
-CqlHostExchange::createBindForSend(const HostPtr& host,
-                                   const OptionalValue<SubnetID>& subnet_id,
-                                   const IPv6Resrv* const reservation,
-                                   const std::string& option_space,
-                                   const OptionDescriptor& option_descriptor,
-                                   CqlDataArray& data) {
+CqlHostExchange::createBindForMutation(
+    const HostPtr& host,
+    const OptionalValue<SubnetID>& subnet_id,
+    const IPv6Resrv* const reservation,
+    const std::string& option_space,
+    const OptionDescriptor& option_descriptor,
+    StatementTag statement_tag,
+    AnyArray& data) {
     // Store host object to ensure it remains valid.
     host_ = host;
 
@@ -773,24 +690,28 @@ CqlHostExchange::createBindForSend(const HostPtr& host,
     // structure.
     try {
         // host_identifier: blob
-        // Convert from std::vector<uint8_t> to std::vector<cass_byte_t>.
+        // Convert from std::vector<uint8_t> to
+        // std::vector<cass_byte_t>.
         HostIdentifier host_identifier = host->getIdentifier();
-        host_identifier_ = CassHostIdentifier(host_identifier.begin(),
-                                              host_identifier.end());
+        host_identifier_ =
+            CassBlob(host_identifier.begin(), host_identifier.end());
         if (host_identifier_.size() > DUID::MAX_DUID_LEN) {
-            isc_throw(BadValue, "host identifier "
-                                    << host_identifier_.data() << " of length "
-                                    << host_identifier_.size()
-                                    << " is greater than allowed of "
-                                    << DUID::MAX_DUID_LEN);
+            isc_throw(
+                BadValue,
+                "CqlHostExchange::createBindForMutation(): host identifier "
+                    << host_identifier_.data() << " of length "
+                    << host_identifier_.size() << " is greater than allowed of "
+                    << DUID::MAX_DUID_LEN);
         }
 
-        // host_identifier_type: int
+        // host_identifier_type: tinyint
         host_identifier_type_ =
             static_cast<cass_int32_t>(host->getIdentifierType());
         if (host_identifier_type_ > MAX_IDENTIFIER_TYPE) {
-            isc_throw(BadValue, "invalid host identifier type returned: "
-                                    << host_identifier_type_);
+            isc_throw(BadValue,
+                      "CqlHostExchange::createBindForMutation(): invalid "
+                      "host identifier type returned: "
+                          << host_identifier_type_);
         }
 
         // host_ipv4_subnet_id: int
@@ -808,37 +729,43 @@ CqlHostExchange::createBindForSend(const HostPtr& host,
         // hostname: text
         hostname_ = host->getHostname();
         if (hostname_.size() > HOSTNAME_MAX_LENGTH) {
-            isc_throw(BadValue, "hostname " << hostname_ << " of length "
-                                            << hostname_.size()
-                                            << " is greater than allowed of "
-                                            << HOSTNAME_MAX_LENGTH);
+            isc_throw(BadValue,
+                      "CqlHostExchange::createBindForMutation(): hostname "
+                          << hostname_ << " of length " << hostname_.size()
+                          << " is greater than allowed of "
+                          << HOSTNAME_MAX_LENGTH);
         }
 
         // host_ipv4_client_classes: text
         host_ipv4_client_classes_ = host->getClientClasses4().toText(",");
         if (host_ipv4_client_classes_.size() > CLIENT_CLASSES_MAX_LENGTH) {
-            isc_throw(BadValue, "IPv4 client classes "
-                                    << host_ipv4_client_classes_
-                                    << " of length "
-                                    << host_ipv4_client_classes_.size()
-                                    << " is greater than allowed of "
-                                    << CLIENT_CLASSES_MAX_LENGTH);
+            isc_throw(BadValue,
+                      "CqlHostExchange::createBindForMutation(): "
+                      "IPv4 client classes "
+                          << host_ipv4_client_classes_ << " of length "
+                          << host_ipv4_client_classes_.size()
+                          << " is greater than allowed of "
+                          << CLIENT_CLASSES_MAX_LENGTH);
         }
 
         // host_ipv6_client_classes: text
         host_ipv6_client_classes_ = host->getClientClasses6().toText(",");
         if (host_ipv6_client_classes_.size() > CLIENT_CLASSES_MAX_LENGTH) {
-            isc_throw(BadValue, "IPv6 client classes "
-                                    << host_ipv6_client_classes_
-                                    << " of length "
-                                    << host_ipv6_client_classes_.size()
-                                    << " is greater than allowed of "
-                                    << CLIENT_CLASSES_MAX_LENGTH);
+            isc_throw(BadValue,
+                      "CqlHostExchange::createBindForMutation(): "
+                      "IPv6 client classes "
+                          << host_ipv6_client_classes_ << " of length "
+                          << host_ipv6_client_classes_.size()
+                          << " is greater than allowed of "
+                          << CLIENT_CLASSES_MAX_LENGTH);
         }
 
         if (reservation == NULL) {
+            // reserved_ipv6_prefix_address: text
             reserved_ipv6_prefix_address_ = NULL_RESERVED_IPV6_PREFIX_ADDRESS;
+            // reserved_ipv6_prefix_length: int
             reserved_ipv6_prefix_length_ = NULL_RESERVED_IPV6_PREFIX_LENGTH;
+            // reserved_ipv6_prefix_address_type: int
             reserved_ipv6_prefix_address_type_ =
                 NULL_RESERVED_IPV6_PREFIX_ADDRESS_TYPE;
             iaid_ = NULL_IAID;
@@ -850,7 +777,7 @@ CqlHostExchange::createBindForSend(const HostPtr& host,
             reserved_ipv6_prefix_length_ =
                 static_cast<cass_int32_t>(reservation->getPrefixLen());
 
-            // reserved_ipv6_prefix_address: int
+            // reserved_ipv6_prefix_address_type: int
             reserved_ipv6_prefix_address_type_ =
                 reservation->getType() == IPv6Resrv::TYPE_NA ? 0 : 2;
 
@@ -924,31 +851,39 @@ CqlHostExchange::createBindForSend(const HostPtr& host,
 
         // Add all parameters to bind array.
         data.clear();
-        data.add(reinterpret_cast<void*>(&id_));
-        data.add(reinterpret_cast<void*>(&host_identifier_));
-        data.add(reinterpret_cast<void*>(&host_identifier_type_));
-        data.add(reinterpret_cast<void*>(&host_ipv4_subnet_id_));
-        data.add(reinterpret_cast<void*>(&host_ipv6_subnet_id_));
-        data.add(reinterpret_cast<void*>(&host_ipv4_address_));
-        data.add(reinterpret_cast<void*>(&hostname_));
-        data.add(reinterpret_cast<void*>(&host_ipv4_client_classes_));
-        data.add(reinterpret_cast<void*>(&host_ipv6_client_classes_));
-        data.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_address_));
-        data.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_length_));
-        data.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_address_type_));
-        data.add(reinterpret_cast<void*>(&iaid_));
-        data.add(reinterpret_cast<void*>(&option_universe_));
-        data.add(reinterpret_cast<void*>(&option_code_));
-        data.add(reinterpret_cast<void*>(&option_value_));
-        data.add(reinterpret_cast<void*>(&option_formatted_value_));
-        data.add(reinterpret_cast<void*>(&option_space_));
-        data.add(reinterpret_cast<void*>(&option_is_persistent_));
-        data.add(reinterpret_cast<void*>(&option_client_class_));
-        data.add(reinterpret_cast<void*>(&option_subnet_id_));
-    } catch (const std::exception& ex) {
-        isc_throw(DbOperationError, "could not create bind array from host "
-                                        << host->getHostname()
-                                        << ", reason: " << ex.what());
+
+        if (statement_tag == CqlHostExchange::INSERT_HOST) {
+            data.add(&id_);
+            data.add(&host_identifier_);
+            data.add(&host_identifier_type_);
+            data.add(&host_ipv4_subnet_id_);
+            data.add(&host_ipv6_subnet_id_);
+            data.add(&host_ipv4_address_);
+            data.add(&hostname_);
+            data.add(&host_ipv4_client_classes_);
+            data.add(&host_ipv6_client_classes_);
+        }
+        // Reservation
+        data.add(&reserved_ipv6_prefix_address_);
+        data.add(&reserved_ipv6_prefix_length_);
+        data.add(&reserved_ipv6_prefix_address_type_);
+        data.add(&iaid_);
+
+        // Option
+        data.add(&option_universe_);
+        data.add(&option_code_);
+        data.add(&option_value_);
+        data.add(&option_formatted_value_);
+        data.add(&option_space_);
+        data.add(&option_is_persistent_);
+        data.add(&option_client_class_);
+        data.add(&option_subnet_id_);
+
+    } catch (const Exception& ex) {
+        isc_throw(DbOperationError,
+                  "CqlHostExchange::createBindForMutation(): "
+                  "could not create bind array from host "
+                      << host->getHostname() << ", reason: " << ex.what());
     }
 }
 
@@ -977,30 +912,33 @@ CqlHostExchange::hashIntoId() const {
 
     // Get key.
     std::stringstream key_stream;
-    key_stream << std::setw(10) << std::setfill('0') << host_ipv4_subnet_id_;
-    key_stream << std::setw(10) << std::setfill('0') << host_ipv6_subnet_id_;
-    key_stream << std::setw(ADDRESS4_TEXT_MAX_LENGTH) << host_ipv4_address_;
-    key_stream << std::setw(ADDRESS6_TEXT_MAX_LENGTH)
+    key_stream << std::setw(10) << std::setfill('-') << host_ipv4_subnet_id_;
+    key_stream << std::setw(10) << std::setfill('-') << host_ipv6_subnet_id_;
+    key_stream << std::setw(ADDRESS4_TEXT_MAX_LENGTH) << std::setfill('-')
+               << host_ipv4_address_;
+    key_stream << std::setw(ADDRESS6_TEXT_MAX_LENGTH) << std::setfill('-')
                << reserved_ipv6_prefix_address_;
-    key_stream << std::setw(4) << std::setfill('0')
+    key_stream << std::setw(4) << std::setfill('-')
                << reserved_ipv6_prefix_length_;
-    key_stream << std::setw(4) << std::setfill('0') << option_code_;
-    key_stream << std::setw(OPTION_SPACE_MAX_LENGTH) << option_space_;
+    key_stream << std::setw(4) << std::setfill('-') << option_code_;
+    key_stream << std::setw(OPTION_SPACE_MAX_LENGTH) << std::setfill('-')
+               << option_space_;
     const std::string key = key_stream.str();
 
-    const uint64_t md5 = md5Hash(key);
+    const cass_int64_t md5 = static_cast<cass_int64_t>(md5Hash(key));
 
-    return static_cast<cass_int64_t>(md5);
+    return md5;
 }
 
-void*
+boost::any
 CqlHostExchange::retrieve() {
-    uint64_t id = static_cast<uint64_t>(id_);
+    const uint64_t id = static_cast<uint64_t>(id_);
 
     HostIdentifier host_identifier =
         HostIdentifier(host_identifier_.begin(), host_identifier_.end());
 
-    // Set the host identifier type in a variable of the appropriate data type.
+    // Set the host identifier type in a variable of the appropriate
+    // data type.
     Host::IdentifierType host_identifier_type =
         static_cast<Host::IdentifierType>(host_identifier_type_);
 
@@ -1012,7 +950,7 @@ CqlHostExchange::retrieve() {
 
     // Set IPv4 address reservation.
     asiolink::IOAddress ipv4_reservation =
-        asiolink::IOAddress(host_ipv4_address_);
+        asiolink::IOAddress(static_cast<uint32_t>(host_ipv4_address_));
 
     Host* host = new Host(host_identifier.data(), host_identifier.size(),
                           host_identifier_type, ipv4_subnet_id, ipv6_subnet_id,
@@ -1026,22 +964,25 @@ CqlHostExchange::retrieve() {
         host->addReservation(reservation);
     }
 
-    OptionDescriptorPtr option_descriptor_ptr = retrieveOption();
-    if (option_descriptor_ptr) {
-        if (option_descriptor_ptr->option_->getUniverse() == Option::V4) {
-            host->getCfgOption4()->add(*option_descriptor_ptr, option_space_);
-        } else if (option_descriptor_ptr->option_->getUniverse() ==
+    OptionWrapper option_wrapper = retrieveOption();
+    if (option_wrapper.option_descriptor_) {
+        if (option_wrapper.option_descriptor_->option_->getUniverse() ==
+            Option::V4) {
+            host->getCfgOption4()->add(*option_wrapper.option_descriptor_,
+                                       option_wrapper.option_space_);
+        } else if (option_wrapper.option_descriptor_->option_->getUniverse() ==
                    Option::V6) {
-            host->getCfgOption6()->add(*option_descriptor_ptr, option_space_);
+            host->getCfgOption6()->add(*option_wrapper.option_descriptor_,
+                                       option_wrapper.option_space_);
         }
     }
 
-    return reinterpret_cast<void*>(host);
+    return host;
 }
 
 const IPv6Resrv
 CqlHostExchange::retrieveReservation() const {
-    // Set the IPv6 Reservation type (0 = IA_NA, 2 = IA_PD)
+    // Set the IPv6 Reservation type (0 = IA_NA, 2 = IA_PD).
     IPv6Resrv::Type type;
     switch (reserved_ipv6_prefix_address_type_) {
     case 0:
@@ -1054,7 +995,8 @@ CqlHostExchange::retrieveReservation() const {
         return NULL_IPV6_RESERVATION;
     default:
         isc_throw(BadValue,
-                  "invalid IPv6 reservation type returned: "
+                  "CqlHostExchange::retrieveReservation(): invalid IPv6 "
+                  "reservation type returned: "
                       << reserved_ipv6_prefix_address_type_
                       << ". Only 0 (IA_NA) or 2 (IA_PD) are allowed.");
     }
@@ -1063,7 +1005,7 @@ CqlHostExchange::retrieveReservation() const {
                      reserved_ipv6_prefix_length_);
 }
 
-OptionDescriptorPtr
+const OptionWrapper
 CqlHostExchange::retrieveOption() const {
     // Options are held in a binary or textual format in the database.
     // This is similar to having an option specified in a server
@@ -1075,7 +1017,7 @@ CqlHostExchange::retrieveOption() const {
     // this is most likely a standard option, for which we have a
     // definition created within libdhcp++.
     if (option_space_.empty() || option_universe_ == NULL_OPTION_UNIVERSE) {
-        return OptionDescriptorPtr();
+        return OptionWrapper(OptionDescriptorPtr(), "");
     }
 
     OptionDefinitionPtr option_definition_ptr =
@@ -1108,8 +1050,10 @@ CqlHostExchange::retrieveOption() const {
                                 static_cast<uint16_t>(option_code_),
                                 option_buffer.begin(), option_buffer.end()));
     } else {
-        // The option value may be specified in textual or binary format in the
-        // database. If formatted_value is empty, the binary format is used.
+        // The option value may be specified in textual or binary format
+        // in the
+        // database. If formatted_value is empty, the binary format is
+        // used.
         // Depending on the format we use a different variant of @ref
         // optionFactory().
         if (option_formatted_value_.empty()) {
@@ -1120,7 +1064,8 @@ CqlHostExchange::retrieveOption() const {
                 static_cast<uint16_t>(option_code_), option_buffer.begin(),
                 option_buffer.end());
         } else {
-            // Spit the value specified in comma separated values format.
+            // Spit the value specified in comma separated values
+            // format.
             std::vector<std::string> split_vector;
             boost::split(split_vector, option_formatted_value_,
                          boost::is_any_of(","));
@@ -1130,8 +1075,10 @@ CqlHostExchange::retrieveOption() const {
         }
     }
 
-    return OptionDescriptorPtr(new OptionDescriptor(
-        option, option_is_persistent_, option_formatted_value_));
+    return OptionWrapper(
+        OptionDescriptorPtr(new OptionDescriptor(option, option_is_persistent_,
+                                                 option_formatted_value_)),
+        option_space_);
 }
 
 /// @brief Implementation of the @ref CqlHostDataSource.
@@ -1139,7 +1086,8 @@ class CqlHostDataSourceImpl {
 public:
     /// @brief Constructor.
     ///
-    /// This constructor opens database connection and initializes prepared
+    /// This constructor opens database connection and initializes
+    /// prepared
     /// statements used in the queries.
     explicit CqlHostDataSourceImpl(
         const CqlConnection::ParameterMap& parameters);
@@ -1148,53 +1096,113 @@ public:
     virtual ~CqlHostDataSourceImpl();
 
     /// @brief Implementation of @ref CqlHostDataSource::add()
+    ///
+    /// See @ref CqlHostDataSource::add() for parameter details.
+    ///
+    /// @param host
     virtual void add(const HostPtr& host);
 
     /// @brief Implementation of @ref CqlHostDataSource::get4()
+    ///
+    /// See @ref CqlHostDataSource::get4() for parameter details.
+    ///
+    /// @param subnet_id
+    /// @param address
     virtual ConstHostPtr get4(const SubnetID& subnet_id,
                               const asiolink::IOAddress& address) const;
 
     /// @brief Implementation of @ref CqlHostDataSource::get4()
+    ///
+    /// See @ref CqlHostDataSource::get4() for parameter details.
+    ///
+    /// @param subnet_id
+    /// @param hwaddr
+    /// @param duid
     virtual ConstHostPtr get4(const SubnetID& subnet_id,
                               const HWAddrPtr& hwaddr,
                               const DuidPtr& duid = DuidPtr()) const;
 
     /// @brief Implementation of @ref CqlHostDataSource::get4()
+    ///
+    /// See @ref CqlHostDataSource::get4() for parameter details.
+    ///
+    /// @param subnet_id
+    /// @param identifier_type
+    /// @param identifier_begin
+    /// @param identifier_len
     virtual ConstHostPtr get4(const SubnetID& subnet_id,
                               const Host::IdentifierType& identifier_type,
                               const uint8_t* identifier_begin,
                               const size_t identifier_len) const;
 
     /// @brief Implementation of @ref CqlHostDataSource::get6()
+    ///
+    /// See @ref CqlHostDataSource::get6() for parameter details.
+    ///
+    /// @param prefix
+    /// @param prefix_len
     virtual ConstHostPtr get6(const asiolink::IOAddress& prefix,
                               const uint8_t prefix_len) const;
 
     /// @brief Implementation of @ref CqlHostDataSource::get6()
+    ///
+    /// See @ref CqlHostDataSource::get6() for parameter details.
+    ///
+    /// @param subnet_id
+    /// @param duid
+    /// @param hwaddr
     virtual ConstHostPtr get6(const SubnetID& subnet_id,
                               const DuidPtr& duid,
                               const HWAddrPtr& hwaddr = HWAddrPtr()) const;
 
     /// @brief Implementation of @ref CqlHostDataSource::get6()
+    ///
+    /// See @ref CqlHostDataSource::get6() for parameter details.
+    ///
+    /// @param subnet_id
+    /// @param identifier_type
+    /// @param identifier_begin
+    /// @param identifier_len
     virtual ConstHostPtr get6(const SubnetID& subnet_id,
                               const Host::IdentifierType& identifier_type,
                               const uint8_t* identifier_begin,
                               const size_t identifier_len) const;
 
     /// @brief Implementation of @ref CqlHostDataSource::get6()
+    ///
+    /// See @ref CqlHostDataSource::get6() for parameter details.
+    ///
+    /// @param subnet_id
+    /// @param address
     virtual ConstHostPtr get6(const SubnetID& subnet_id,
                               const asiolink::IOAddress& address) const;
 
-    /// @brief Implementation of @ref CqlHostDataSource::getAll
+    /// @brief Implementation of @ref CqlHostDataSource::getAll()
+    ///
+    /// See @ref CqlHostDataSource::getAll() for parameter details.
+    ///
+    /// @param hwaddr
+    /// @param duid
     virtual ConstHostCollection getAll(const HWAddrPtr& hwaddr,
                                        const DuidPtr& duid = DuidPtr()) const;
 
     /// @brief Implementation of @ref CqlHostDataSource::getAll()
+    ///
+    /// See @ref CqlHostDataSource::getAll() for parameter details.
+    ///
+    /// @param identifier_type
+    /// @param identifier_begin
+    /// @param identifier_len
     virtual ConstHostCollection
     getAll(const Host::IdentifierType& identifier_type,
            const uint8_t* identifier_begin,
            const size_t identifier_len) const;
 
     /// @brief Implementation of @ref CqlHostDataSource::getAll4()
+    ///
+    /// See @ref CqlHostDataSource::getAll4() for parameter details.
+    ///
+    /// @param address
     virtual ConstHostCollection
     getAll4(const asiolink::IOAddress& address) const;
 
@@ -1211,14 +1219,18 @@ public:
     virtual void rollback();
 
 protected:
-    /// @brief Adds any options found in the @ref Host object to a separate
+    /// @brief Adds any options found in the @ref Host object to a
+    /// separate
     ///     table entry.
     ///
-    /// @param host @ref Host object from which options are retrieved and
+    /// @param host @ref Host object from which options are retrieved
+    /// and
     ///     inserted into the Cassandra database
-    /// @param reservation reservation for the current denormalized table entry
+    /// @param reservation reservation for the current denormalized
+    /// table entry
     /// @param option_spaces list of option spaces to search for
-    /// @param cfg_option option configuration used to match option spaces in
+    /// @param cfg_option option configuration used to match option
+    /// spaces in
     ///     order to obtain actual options
     virtual void insertHostWithOptions(
         const HostPtr& host,
@@ -1226,19 +1238,26 @@ protected:
         const std::list<std::string>& option_spaces = std::list<std::string>(),
         const ConstCfgOptionPtr cfg_option = ConstCfgOptionPtr());
 
-    /// @brief Adds any reservations found in the @ref Host object to a separate
+    /// @brief Adds any reservations found in the @ref Host object to a
+    /// separate
     ///     table entry.
     ///
-    /// @param host @ref Host object from which reservations are retrieved and
+    /// @param host @ref Host object from which reservations are
+    /// retrieved and
     ///     inserted into the Cassandra database
-    /// @param reservation reservation for the current denormalized table entry
-    /// @param option_spaces4 list of option spaces for universe Option::V4 to
+    /// @param reservation reservation for the current denormalized
+    /// table entry
+    /// @param option_spaces4 list of option spaces for universe
+    /// Option::V4 to
     ///     search in
-    /// @param cfg_option4 option configuration for universe Option::V4 used to
+    /// @param cfg_option4 option configuration for universe Option::V4
+    /// used to
     ///     match option spaces in order to obtain actual options
-    /// @param option_spaces6 list of option spaces for universe Option::V6 to
+    /// @param option_spaces6 list of option spaces for universe
+    /// Option::V6 to
     ///     search in
-    /// @param cfg_option6 option configuration for universe Option::V6 used to
+    /// @param cfg_option6 option configuration for universe Option::V6
+    /// used to
     ///     match option spaces in order to obtain actual options
     virtual void
     insertHostWithReservations(const HostPtr& host,
@@ -1250,43 +1269,49 @@ protected:
 
     /// @brief Retrieves a single host.
     ///
-    /// Calls @ref getHostCollection() and checks if a single host was returned.
+    /// Calls @ref getHostCollection() and checks if a single host was
+    /// returned.
     ///
-    /// @param where_values array of bound objects used to filter the results
-    /// @param statement_index prepared statement being executed
+    /// @param where_values array of bound objects used to filter the
+    /// results
+    /// @param statement_tag prepared statement being executed
     ///
     /// @return one host or a null pointer to a host
     ///
-    /// @throw MultipleRecords exception if two or more hosts are returned
-    virtual ConstHostPtr
-    getHost(const CqlDataArray& where_values,
-            const CqlHostExchange::StatementIndex statement_index) const;
+    /// @throw MultipleRecords exception if two or more hosts are
+    /// returned
+    virtual ConstHostPtr getHost(StatementTag statement_tag,
+                                 AnyArray& where_values) const;
 
     /// @brief Retrieves a collection of hosts.
     ///
-    /// Calls @ref CqlExchange::executeRead().
+    /// Calls @ref CqlExchange::executeSelect().
     ///
-    /// @param where_values array of bound objects used to filter the results
-    /// @param statement_index prepared statement being executed
+    /// @param where_values array of bound objects used to filter the
+    /// results
+    /// @param statement_tag prepared statement being executed
     ///
     /// @return a collection of hosts containing one or more hosts
-    virtual ConstHostCollection getHostCollection(
-        const CqlDataArray& where_values,
-        const CqlHostExchange::StatementIndex statement_index) const;
+    virtual ConstHostCollection getHostCollection(StatementTag statement_tag,
+                                                  AnyArray& where_values) const;
 
     /// @brief Inserts a single host.
     ///
     /// All information is available here. Calls @ref
-    /// CqlExchange::executeWrite().
+    /// CqlExchange::executeMutation().
     ///
-    /// @param host @ref Host object from which options are retrieved and
+    /// @param host @ref Host object from which options are retrieved
+    /// and
     ///     inserted into the Cassandra database
-    /// @param subnet_id identifier of the subnet to which the host belongs
-    /// @param reservation reservation for the current denormalized table entry
-    /// @param option_space option space for the current denormalized table
+    /// @param subnet_id identifier of the subnet to which the host
+    /// belongs
+    /// @param reservation reservation for the current denormalized
+    /// table entry
+    /// @param option_space option space for the current denormalized
+    /// table
     ///     entry's option
-    /// @param option_descriptor option descriptor containing information for
-    ///     the current denormalized table entry's option
+    /// @param option_descriptor option descriptor containing
+    ///     information for the current denormalized table entry's option
     virtual void insertHost(
         const HostPtr& host,
         const OptionalValue<SubnetID>& subnet_id = OptionalValue<SubnetID>(),
@@ -1294,27 +1319,25 @@ protected:
         const std::string& option_space = NULL_OPTION_SPACE,
         const OptionDescriptor& option_descriptor = OptionDescriptor(false));
 
-    /// @brief Merge denormalized table entries that belong to the same host
+    /// @brief Merge denormalized table entries that belong to the same
+    /// host
     /// into a single host, one by one.
     ///
-    /// @param target_host host which can contain multiple reservations and
-    ///     options to which other distinct reservations and options are added.
-    /// @param source_host host that is being search for new reservations and
+    /// @param target_host host which can contain multiple reservations
+    /// and
+    ///     options to which other distinct reservations and options are
+    ///     added.
+    /// @param source_host host that is being search for new
+    /// reservations and
     ///     options that will be merged into the old host.
-    virtual void mergeHosts(HostPtr& target_host,
-                            const ConstHostPtr& source_host) const;
+    virtual void mergeHosts(const ConstHostPtr& source_host,
+                            HostPtr& target_host) const;
 
 private:
-    /// @brief pointer to the exchange responsible for trading host information
-    boost::shared_ptr<CqlHostExchange> host_exchange_;
-    /// @brief pointer to the exchange responsible for retrieving schema version
-    boost::shared_ptr<CqlVersionExchange> version_exchange_;
-
     /// @brief CQL connection
     mutable CqlConnection dbconn_;
 };  // class CqlHostDataSourceImpl
 
-
 /// @brief hash function for HostMap
 ///
 /// @param key being hashed
@@ -1324,14 +1347,17 @@ std::size_t
 hash_value(const HostKey& key) {
     // Get key.
     std::stringstream key_stream;
-    HostIdentifier host_identifier = key.get<0>();
+    HostIdentifier host_identifier = std::get<HOST_IDENTIFIER>(key);
     key_stream << std::setw(DUID::MAX_DUID_LEN) << std::setfill('0')
                << DUID(host_identifier).toText();
-    key_stream << std::setw(2) << std::setfill('0') << key.get<1>();
-    key_stream << std::setw(10) << std::setfill('0') << key.get<2>();
-    key_stream << std::setw(10) << std::setfill('0') << key.get<3>();
+    key_stream << std::setw(2) << std::setfill('0')
+               << std::get<HOST_IDENTIFIER_TYPE>(key);
+    key_stream << std::setw(10) << std::setfill('0')
+               << std::get<IPv4_SUBNET_ID>(key);
+    key_stream << std::setw(10) << std::setfill('0')
+               << std::get<IPv6_SUBNET_ID>(key);
     key_stream << std::setw(ADDRESS4_TEXT_MAX_LENGTH) << std::setfill('0')
-               << key.get<4>();
+               << std::get<IPv4_RESERVATION>(key);
     const std::string key_string = key_stream.str();
 
     const uint64_t md5 = md5Hash(key_string);
@@ -1347,19 +1373,23 @@ hash_value(const HostKey& key) {
 /// @return true if keys are equal. Deep comparison is made.
 bool
 operator==(const HostKey& key1, const HostKey& key2) {
-    return key1.get<0>() == key2.get<0>() && key1.get<1>() == key2.get<1>() &&
-           key1.get<2>() == key2.get<2>() && key1.get<3>() == key2.get<3>() &&
-           key1.get<4>() == key2.get<4>();
+    return std::get<HOST_IDENTIFIER>(key1) == std::get<HOST_IDENTIFIER>(key2) &&
+           std::get<HOST_IDENTIFIER_TYPE>(key1) ==
+               std::get<HOST_IDENTIFIER_TYPE>(key2) &&
+           std::get<IPv4_SUBNET_ID>(key1) == std::get<IPv4_SUBNET_ID>(key2) &&
+           std::get<IPv6_SUBNET_ID>(key1) == std::get<IPv6_SUBNET_ID>(key2) &&
+           std::get<IPv4_RESERVATION>(key1) == std::get<IPv4_RESERVATION>(key2);
 }
 
 CqlHostDataSourceImpl::CqlHostDataSourceImpl(
     const CqlConnection::ParameterMap& parameters)
-    : host_exchange_(new CqlHostExchange()),
-      version_exchange_(new CqlVersionExchange()), dbconn_(parameters) {
+    : dbconn_(parameters) {
     // Open the database.
     dbconn_.openDatabase();
+
     // Prepare all possible statements.
-    dbconn_.prepareStatements(tagged_statements);
+    dbconn_.prepareStatements(CqlHostExchange::tagged_statements_);
+    dbconn_.prepareStatements(CqlVersionExchange::tagged_statements_);
 }
 
 CqlHostDataSourceImpl::~CqlHostDataSourceImpl() {
@@ -1369,10 +1399,8 @@ CqlHostDataSourceImpl::~CqlHostDataSourceImpl() {
 
 void
 CqlHostDataSourceImpl::add(const HostPtr& host) {
-    // Start transaction.
-    CqlTransaction transaction(dbconn_);
-
-    // Get option space names and vendor space names and combine them within a
+    // Get option space names and vendor space names and combine them
+    // within a
     // single list.
     // For IPv4:
     ConstCfgOptionPtr cfg_option4 = host->getCfgOption4();
@@ -1390,7 +1418,8 @@ CqlHostDataSourceImpl::add(const HostPtr& host) {
     option_spaces6.insert(option_spaces6.end(), vendor_spaces6.begin(),
                           vendor_spaces6.end());
 
-    // For every IPv6 reservation, add each of their options to the database.
+    // For every IPv6 reservation, add each of their options to the
+    // database.
     IPv6ResrvRange reservations = host->getIPv6Reservations();
     if (std::distance(reservations.first, reservations.second) > 0) {
         for (IPv6ResrvIterator it = reservations.first;
@@ -1400,12 +1429,12 @@ CqlHostDataSourceImpl::add(const HostPtr& host) {
                                        cfg_option6);
         }
     } else {
-        // If host has no reservation, add entries with null reservation.
+        // If host has no reservation, add entries with null
+        // reservation.
         // Options could still be present.
         insertHostWithReservations(host, NULL, option_spaces4, cfg_option4,
                                    option_spaces6, cfg_option6);
     }
-    transaction.commit();
 }
 
 ConstHostPtr
@@ -1422,20 +1451,24 @@ CqlHostDataSourceImpl::get4(const SubnetID& subnet_id,
         static_cast<cass_int32_t>(address.toUint32());
 
     // Bind to array.
-    CqlDataArray where_values;
-    where_values.add(reinterpret_cast<void*>(&host_ipv4_subnet_id));
-    where_values.add(reinterpret_cast<void*>(&host_ipv4_address));
+    AnyArray where_values;
+    where_values.add(&host_ipv4_subnet_id);
+    where_values.add(&host_ipv4_address);
+
 
     // Run statement.
-    return getHost(*const_cast<const CqlDataArray*>(&where_values),
-                   CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS);
+    ConstHostPtr result = getHost(
+        CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS, where_values);
+
+    return result;
 }
 
 ConstHostPtr
 CqlHostDataSourceImpl::get4(const SubnetID& subnet_id,
                             const HWAddrPtr& hwaddr,
                             const DuidPtr& duid) const {
-    /// @todo: Rethink the logic in BaseHostDataSource::get4(subnet, hwaddr,
+    /// @todo: Rethink the logic in BaseHostDataSource::get4(subnet,
+    /// hwaddr,
     /// duid)
     if (hwaddr && duid) {
         isc_throw(BadValue, "CqlHostDataSource::get4(3) called with both "
@@ -1444,17 +1477,26 @@ CqlHostDataSourceImpl::get4(const SubnetID& subnet_id,
         isc_throw(BadValue, "CqlHostDataSource::get4(3) called with neither "
                             "hwaddr or duid specified, one of them is "
                             "required");
-    } else if (duid) {
-        HostIdentifier duid_vector = duid->getDuid();
-        // Delegate to get4(4).
-        return get4(subnet_id, Host::IDENT_DUID, duid_vector.data(),
-                    duid_vector.size());
+    }
+
+    const HostIdentifier* host_identifier;
+    Host::IdentifierType host_identifier_type;
+    if (duid) {
+        host_identifier = &duid->getDuid();
+        host_identifier_type = Host::IDENT_DUID;
     } else if (hwaddr) {
-        // Delegate to get4(4).
-        return get4(subnet_id, Host::IDENT_HWADDR, hwaddr->hwaddr_.data(),
-                    hwaddr->hwaddr_.size());
+        host_identifier = &hwaddr->hwaddr_;
+        host_identifier_type = Host::IDENT_HWADDR;
+    } else {
+        return ConstHostPtr();
     }
-    return ConstHostPtr();
+
+    // Delegate to get4(4).
+    ConstHostPtr result =
+        get4(subnet_id, host_identifier_type, host_identifier->data(),
+             host_identifier->size());
+
+    return result;
 }
 
 ConstHostPtr
@@ -1463,21 +1505,24 @@ CqlHostDataSourceImpl::get4(const SubnetID& subnet_id,
                             const uint8_t* identifier_begin,
                             const size_t identifier_len) const {
     // Convert to CQL data types.
-    cass_int32_t host_ipv4_subnet_id = static_cast<cass_int32_t>(subnet_id);
-    CassHostIdentifier host_identifier(identifier_begin,
-                                       identifier_begin + identifier_len);
+    CassBlob host_identifier(identifier_begin,
+                             identifier_begin + identifier_len);
     cass_int32_t host_identifier_type =
         static_cast<cass_int32_t>(identifier_type);
+    cass_int32_t host_ipv4_subnet_id = static_cast<cass_int32_t>(subnet_id);
 
     // Bind to array.
-    CqlDataArray where_values;
-    where_values.add(reinterpret_cast<void*>(&host_ipv4_subnet_id));
-    where_values.add(reinterpret_cast<void*>(&host_identifier));
-    where_values.add(reinterpret_cast<void*>(&host_identifier_type));
+    AnyArray where_values;
+    where_values.add(&host_ipv4_subnet_id);
+    where_values.add(&host_identifier);
+    where_values.add(&host_identifier_type);
+
 
     // Run statement.
-    return getHost(*const_cast<const CqlDataArray*>(&where_values),
-                   CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID);
+    ConstHostPtr result = getHost(
+        CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID, where_values);
+
+    return result;
 }
 
 ConstHostPtr
@@ -1487,14 +1532,15 @@ CqlHostDataSourceImpl::get6(const asiolink::IOAddress& prefix,
     std::string reserved_ipv6_prefix_address = prefix.toText();
     cass_int32_t reserved_ipv6_prefix_length = prefix_len;
 
+    ConstHostPtr host;
     // Bind to array.
-    CqlDataArray where_values;
-    where_values.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_address));
-    where_values.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_length));
+    AnyArray where_values;
+    where_values.add(&reserved_ipv6_prefix_address);
+    where_values.add(&reserved_ipv6_prefix_length);
+
 
     // Get host id.
-    ConstHostPtr host = getHost(*const_cast<const CqlDataArray*>(&where_values),
-                                CqlHostExchange::GET_HOST_BY_IPV6_PREFIX);
+    host = getHost(CqlHostExchange::GET_HOST_BY_IPV6_PREFIX, where_values);
 
     if (host == ConstHostPtr()) {
         return ConstHostPtr();
@@ -1502,6 +1548,7 @@ CqlHostDataSourceImpl::get6(const asiolink::IOAddress& prefix,
 
     // Get host.
     HostIdentifier host_identifier = host->getIdentifier();
+    // Delegate to getAll(3).
     ConstHostCollection collection =
         getAll(host->getIdentifierType(), host_identifier.data(),
                host_identifier.size());
@@ -1510,24 +1557,25 @@ CqlHostDataSourceImpl::get6(const asiolink::IOAddress& prefix,
         return ConstHostPtr();
     }
 
-    if (collection.size() >= 2U) {
-        isc_throw(
-            MultipleRecords,
-            "CqlHostDataSource::get6(2): multiple records were found in the "
-            "database where only one was expected for statement "
-                << dbconn_
-                       .tagged_statements_[CqlHostExchange::GET_HOST_BY_HOST_ID]
-                       .name_);
+    if (collection.size() >= 2u) {
+        isc_throw(MultipleRecords,
+                  "CqlHostDataSource::get6(2): multiple records were "
+                  "found in the "
+                  "database where only one was expected for statement "
+                      << CqlHostExchange::GET_HOST_BY_IPV6_PREFIX);
     }
 
-    return *collection.begin();
+    ConstHostPtr result = *collection.begin();
+
+    return result;
 }
 
 ConstHostPtr
 CqlHostDataSourceImpl::get6(const SubnetID& subnet_id,
                             const DuidPtr& duid,
                             const HWAddrPtr& hwaddr) const {
-    /// @todo: Rethink the logic in BaseHostDataSource::get6(subnet, hwaddr,
+    /// @todo: Rethink the logic in BaseHostDataSource::get6(subnet,
+    /// hwaddr,
     /// duid)
     if (hwaddr && duid) {
         isc_throw(BadValue, "CqlHostDataSource::get6(3): both hardware address "
@@ -1536,17 +1584,26 @@ CqlHostDataSourceImpl::get6(const SubnetID& subnet_id,
     } else if (!hwaddr && !duid) {
         isc_throw(BadValue, "CqlHostDataSource::get6(3): both hardware address "
                             "and DUID are specified, one of them is required");
-    } else if (duid) {
-        HostIdentifier duid_vector = duid->getDuid();
-        // Delegate to get6(4).
-        return get6(subnet_id, Host::IDENT_DUID, duid_vector.data(),
-                    duid_vector.size());
+    }
+
+    const HostIdentifier* host_identifier;
+    Host::IdentifierType host_identifier_type;
+    if (duid) {
+        host_identifier = &duid->getDuid();
+        host_identifier_type = Host::IDENT_DUID;
     } else if (hwaddr) {
-        // Delegate to get6(4).
-        return get6(subnet_id, Host::IDENT_HWADDR, hwaddr->hwaddr_.data(),
-                    hwaddr->hwaddr_.size());
+        host_identifier = &hwaddr->hwaddr_;
+        host_identifier_type = Host::IDENT_HWADDR;
+    } else {
+        return ConstHostPtr();
     }
-    return ConstHostPtr();
+
+    // Delegate to get6(4).
+    ConstHostPtr result =
+        get6(subnet_id, host_identifier_type, host_identifier->data(),
+             host_identifier->size());
+
+    return result;
 }
 
 ConstHostPtr
@@ -1556,20 +1613,23 @@ CqlHostDataSourceImpl::get6(const SubnetID& subnet_id,
                             const size_t identifier_len) const {
     // Convert to CQL data types.
     cass_int32_t host_ipv6_subnet_id = static_cast<cass_int32_t>(subnet_id);
-    CassHostIdentifier host_identifier(identifier_begin,
-                                   identifier_begin + identifier_len);
+    CassBlob host_identifier(identifier_begin,
+                             identifier_begin + identifier_len);
     cass_int32_t host_identifier_type =
         static_cast<cass_int32_t>(identifier_type);
 
     // Bind to array.
-    CqlDataArray where_values;
-    where_values.add(reinterpret_cast<void*>(&host_ipv6_subnet_id));
-    where_values.add(reinterpret_cast<void*>(&host_identifier));
-    where_values.add(reinterpret_cast<void*>(&host_identifier_type));
+    AnyArray where_values;
+    where_values.add(&host_ipv6_subnet_id);
+    where_values.add(&host_identifier);
+    where_values.add(&host_identifier_type);
+
 
     // Run statement.
-    return getHost(*const_cast<const CqlDataArray*>(&where_values),
-                   CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID);
+    ConstHostPtr result = getHost(
+        CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID, where_values);
+
+    return result;
 }
 
 ConstHostPtr
@@ -1580,13 +1640,16 @@ CqlHostDataSourceImpl::get6(const SubnetID& subnet_id,
     std::string reserved_ipv6_prefix_address = address.toText();
 
     // Bind to array.
-    CqlDataArray where_values;
-    where_values.add(reinterpret_cast<void*>(&host_ipv6_subnet_id));
-    where_values.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_address));
+    AnyArray where_values;
+    where_values.add(&host_ipv6_subnet_id);
+    where_values.add(&reserved_ipv6_prefix_address);
+
 
     // Run statement.
-    return getHost(*const_cast<const CqlDataArray*>(&where_values),
-                   CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS);
+    ConstHostPtr result = getHost(
+        CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS, where_values);
+
+    return result;
 }
 
 ConstHostCollection
@@ -1597,27 +1660,29 @@ CqlHostDataSourceImpl::getAll(const HWAddrPtr& hwaddr,
     }
 
     // Convert to CQL data types.
-    CassHostIdentifier host_identifier;
     cass_int32_t host_identifier_type;
+    CassBlob host_identifier;
     if (duid) {
         HostIdentifier duid_vector = duid->getDuid();
-        host_identifier =
-            CassHostIdentifier(duid_vector.begin(), duid_vector.end());
+        host_identifier = CassBlob(duid_vector.begin(), duid_vector.end());
         host_identifier_type = static_cast<cass_int32_t>(Host::IDENT_DUID);
     } else if (hwaddr) {
-        host_identifier = CassHostIdentifier(hwaddr->hwaddr_.begin(),
-                                                   hwaddr->hwaddr_.end());
+        host_identifier =
+            CassBlob(hwaddr->hwaddr_.begin(), hwaddr->hwaddr_.end());
         host_identifier_type = static_cast<cass_int32_t>(Host::IDENT_HWADDR);
     }
 
     // Bind to array.
-    CqlDataArray where_values;
-    where_values.add(reinterpret_cast<void*>(&host_identifier));
-    where_values.add(reinterpret_cast<void*>(&host_identifier_type));
+    AnyArray where_values;
+    where_values.add(&host_identifier);
+    where_values.add(&host_identifier_type);
+
 
     // Run statement.
-    return getHostCollection(*const_cast<const CqlDataArray*>(&where_values),
-                             CqlHostExchange::GET_HOST_BY_HOST_ID);
+    ConstHostCollection result =
+        getHostCollection(CqlHostExchange::GET_HOST_BY_HOST_ID, where_values);
+
+    return result;
 }
 
 ConstHostCollection
@@ -1625,19 +1690,22 @@ CqlHostDataSourceImpl::getAll(const Host::IdentifierType& identifier_type,
                               const uint8_t* identifier_begin,
                               const size_t identifier_len) const {
     // Convert to CQL data types.
-    CassHostIdentifier host_identifier(identifier_begin,
-                                             identifier_begin + identifier_len);
+    CassBlob host_identifier(identifier_begin,
+                             identifier_begin + identifier_len);
     cass_int32_t host_identifier_type =
         static_cast<cass_int32_t>(identifier_type);
 
     // Bind to array.
-    CqlDataArray where_values;
-    where_values.add(reinterpret_cast<void*>(&host_identifier));
-    where_values.add(reinterpret_cast<void*>(&host_identifier_type));
+    AnyArray where_values;
+    where_values.add(&host_identifier);
+    where_values.add(&host_identifier_type);
+
 
     // Run statement.
-    return getHostCollection(*const_cast<const CqlDataArray*>(&where_values),
-                             CqlHostExchange::GET_HOST_BY_HOST_ID);
+    ConstHostCollection result =
+        getHostCollection(CqlHostExchange::GET_HOST_BY_HOST_ID, where_values);
+
+    return result;
 }
 
 ConstHostCollection
@@ -1647,29 +1715,33 @@ CqlHostDataSourceImpl::getAll4(const asiolink::IOAddress& address) const {
         static_cast<cass_int32_t>(address.toUint32());
 
     // Bind to array.
-    CqlDataArray where_values;
-    where_values.add(reinterpret_cast<void*>(&host_ipv4_address));
+    AnyArray where_values;
+    where_values.add(&host_ipv4_address);
+
 
     // Run statement.
-    return getHostCollection(*const_cast<const CqlDataArray*>(&where_values),
-                             CqlHostExchange::GET_HOST_BY_IPV4_ADDRESS);
+    ConstHostCollection result = getHostCollection(
+        CqlHostExchange::GET_HOST_BY_IPV4_ADDRESS, where_values);
+
+    return result;
 }
 
 std::string
 CqlHostDataSourceImpl::getName() const {
-    std::string name = "";
+    std::string name = NULL;
     try {
         name = dbconn_.getParameter("name");
     } catch (...) {
-        // Return an empty name
+        // Return an empty name.
     }
     return name;
 }
 
 VersionPair
 CqlHostDataSourceImpl::getVersion() const {
-    return version_exchange_->retrieveVersion(dbconn_,
-                                              CqlHostExchange::GET_VERSION);
+    std::unique_ptr<CqlVersionExchange> version_exchange(
+        new CqlVersionExchange());
+    return version_exchange->retrieveVersion(dbconn_);
 }
 
 void
@@ -1689,22 +1761,22 @@ CqlHostDataSourceImpl::insertHostWithOptions(
     const std::list<std::string>& option_spaces
     /* = std::list<std::string>() */,
     const ConstCfgOptionPtr cfg_option /* = ConstCfgOptionPtr() */) {
-    // For each option space retrieve all options and insert them into the
-    // database.
+    // For each option space retrieve all options and insert them into
+    // the database.
     bool option_found = false;
-    for (std::list<std::string>::const_iterator space = option_spaces.begin();
-         space != option_spaces.end(); ++space) {
-        OptionContainerPtr options = cfg_option->getAll(*space);
+    for (const std::string& space : option_spaces) {
+        OptionContainerPtr options = cfg_option->getAll(space);
         if (options && !options->empty()) {
-            for (OptionContainer::const_iterator option = options->begin();
-                 option != options->end(); ++option) {
+            for (const OptionDescriptor& option : *options) {
                 option_found = true;
-                insertHost(host, OptionalValue<SubnetID>(), reservation, *space,
-                           *option);
+                // @todo: Assign actual value to subnet id.
+                insertHost(host, OptionalValue<SubnetID>(), reservation, space,
+                           option);
             }
         }
     }
     if (!option_found) {
+        // @todo: Assign actual value to subnet id.
         insertHost(host, OptionalValue<SubnetID>(), reservation);
     }
 }
@@ -1732,61 +1804,61 @@ CqlHostDataSourceImpl::insertHostWithReservations(
 }
 
 ConstHostPtr
-CqlHostDataSourceImpl::getHost(
-    const CqlDataArray& where_values,
-    const CqlHostExchange::StatementIndex statement_index) const {
+CqlHostDataSourceImpl::getHost(StatementTag statement_tag,
+                               AnyArray& where_values) const {
     ConstHostCollection collection =
-        getHostCollection(where_values, statement_index);
+        getHostCollection(statement_tag, where_values);
 
     if (collection.empty()) {
         return ConstHostPtr();
     }
 
-    if (collection.size() >= 2U) {
+    if (collection.size() >= 2u) {
         isc_throw(MultipleRecords,
-                  "multiple records were found in the database where only one "
+                  "CqlHostDataSourceImpl::getHost(): multiple records were "
+                  "found in the database where only one "
                   "was expected for statement "
-                      << dbconn_.tagged_statements_[statement_index].name_);
+                      << statement_tag);
     }
 
     return *collection.begin();
 }
 
 ConstHostCollection
-CqlHostDataSourceImpl::getHostCollection(
-    const CqlDataArray& where_values,
-    const CqlHostExchange::StatementIndex statement_index) const {
+CqlHostDataSourceImpl::getHostCollection(StatementTag statement_tag,
+                                         AnyArray& where_values) const {
 
     // Run statement.
-    CqlDataArray collection = host_exchange_->executeRead(
-        dbconn_, where_values, statement_index, false);
+    std::unique_ptr<CqlHostExchange> host_exchange(
+        new CqlHostExchange(dbconn_));
+    AnyArray collection = host_exchange->executeSelect(dbconn_, where_values,
+                                                       statement_tag, false);
 
     // Form HostPtr objects.
     HostCollection host_collection;
-    for (std::vector<void*>::const_iterator it = collection.begin();
-         it != collection.end(); ++it) {
-        host_collection.push_back(HostPtr(reinterpret_cast<Host*>(*it)));
+    for (boost::any& host : collection) {
+        host_collection.push_back(HostPtr(boost::any_cast<Host*>(host)));
     }
 
-    // Merge the denormalized table entries that belong to the same host into a
+    // Merge the denormalized table entries that belong to the same host
+    // into a
     // single host.
     HostMap map;
-    for (HostCollection::iterator it = host_collection.begin();
-         it != host_collection.end(); ++it) {
-        HostKey key =
-            HostKey((*it)->getIdentifier(), (*it)->getIdentifierType(),
-                    (*it)->getIPv4SubnetID(), (*it)->getIPv6SubnetID(),
-                    (*it)->getIPv4Reservation());
+    for (HostPtr& host : host_collection) {
+
+        HostKey key = HostKey(host->getIdentifier(), host->getIdentifierType(),
+                              host->getIPv4SubnetID(), host->getIPv6SubnetID(),
+                              host->getIPv4Reservation());
         if (map.find(key) == map.end()) {
-            map[key] = *it;
+            map[key] = host;
         } else {
-            mergeHosts(map[key], *it);
+            mergeHosts(host, map[key]);
         }
     }
 
     ConstHostCollection result_collection;
-    for (HostMap::const_iterator it = map.begin(); it != map.end(); ++it) {
-        result_collection.push_back(it->second);
+    for (HostPair pair : map) {
+        result_collection.push_back(pair.second);
     }
     return result_collection;
 }
@@ -1794,24 +1866,31 @@ CqlHostDataSourceImpl::getHostCollection(
 void
 CqlHostDataSourceImpl::insertHost(
     const HostPtr& host,
-    const OptionalValue<SubnetID>& subnet_id
-    /* = OptionalValue<SubnetID>() */,
+    const OptionalValue<SubnetID>& subnet_id /* = OptionalValue<SubnetID>() */,
     const IPv6Resrv* const reservation /* = NULL */,
     const std::string& option_space /* = NULL_OPTION_SPACE */,
-    const OptionDescriptor& option_descriptor
-    /* = OptionDescriptorPtr */) {
-    CqlDataArray assigned_values;
-    // @todo: Assign actual value to subnet id.
-    host_exchange_->createBindForSend(host, subnet_id, reservation,
-                                      option_space, option_descriptor,
-                                      assigned_values);
-    host_exchange_->executeWrite(dbconn_, assigned_values,
-                                 CqlHostExchange::INSERT_HOST);
+    const OptionDescriptor& option_descriptor /* = OptionDescriptorPtr */) {
+    AnyArray assigned_values;
+
+    std::unique_ptr<CqlHostExchange> host_exchange(
+        new CqlHostExchange(dbconn_));
+
+    try {
+        host_exchange->createBindForMutation(
+            host, subnet_id, reservation, option_space, option_descriptor,
+            CqlHostExchange::INSERT_HOST, assigned_values);
+
+
+        host_exchange->executeMutation(dbconn_, assigned_values,
+                                       CqlHostExchange::INSERT_HOST);
+    } catch (const StatementNotApplied& exception) {
+        isc_throw(DuplicateEntry, exception.what());
+    }
 }
 
 void
-CqlHostDataSourceImpl::mergeHosts(HostPtr& target_host,
-                                  const ConstHostPtr& source_host) const {
+CqlHostDataSourceImpl::mergeHosts(const ConstHostPtr& source_host,
+                                  HostPtr& target_host) const {
     // Merge reservations.
     const IPv6ResrvRange reservations_range =
         source_host->getIPv6Reservations();
@@ -1939,6 +2018,38 @@ CqlHostDataSource::get6(const SubnetID& subnet_id,
     return impl_->get6(subnet_id, address);
 }
 
+bool
+CqlHostDataSource::del(const SubnetID& subnet_id,
+                       const asiolink::IOAddress& addr) {
+    (void)subnet_id;
+    (void)addr;
+    isc_throw(NotImplemented, "CqlHostDataSource::del NotImplemented");
+}
+
+bool
+CqlHostDataSource::del4(const SubnetID& subnet_id,
+                        const Host::IdentifierType& identifier_type,
+                        const uint8_t* identifier_begin,
+                        const size_t identifier_len) {
+    (void)subnet_id;
+    (void)identifier_type;
+    (void)identifier_begin;
+    (void)identifier_len;
+    isc_throw(NotImplemented, "CqlHostDataSource::del4 NotImplemented");
+}
+
+bool
+CqlHostDataSource::del6(const SubnetID& subnet_id,
+                        const Host::IdentifierType& identifier_type,
+                        const uint8_t* identifier_begin,
+                        const size_t identifier_len) {
+    (void)subnet_id;
+    (void)identifier_type;
+    (void)identifier_begin;
+    (void)identifier_len;
+    isc_throw(NotImplemented, "CqlHostDataSource::del6 NotImplemented");
+}
+
 std::string
 CqlHostDataSource::getType() const {
     return std::string("cql");
@@ -1951,8 +2062,8 @@ CqlHostDataSource::getName() const {
 
 std::string
 CqlHostDataSource::getDescription() const {
-    return std::string(
-        "Host data source that stores host information in the CQL database");
+    return std::string("Host data source that stores host information "
+                       "in the CQL database");
 }
 
 VersionPair
@@ -1977,5 +2088,5 @@ CqlHostDataSource::rollback() {
     impl_->rollback();
 }
 
-};  // namespace dhcp
-};  // namespace isc
+}  // namespace dhcp
+}  // namespace isc
index e22e1eddb42830eb00b5a7f91718bbcdb904975f..d2dcf67eb44b1410874de474f81774cedfc70d37 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2016 Deutsche Telekom AG.
+// Copyright (C) 2016-2017 Deutsche Telekom AG.
 //
 // Author: Andrei Pavel <andrei.pavel@qualitance.com>
 //
 #include <dhcpsrv/base_host_data_source.h>
 #include <dhcpsrv/cql_connection.h>
 
-#include <stdint.h>
-
 #include <string>
-#include <utility>
+#include <vector>
 
 namespace isc {
 namespace dhcp {
 
-/// Forward declaration to the implementation of @ref CqlHostDataSource.
+/// @brief Forward declaration to the implementation of @ref CqlHostDataSource.
 class CqlHostDataSourceImpl;
 
 /// @brief Cassandra host data source
@@ -53,7 +51,7 @@ public:
     ///
     /// Finally, all the CQL commands are pre-compiled.
     ///
-    /// @param parameters A data structure relating keywords and values
+    /// @param parameters a data structure relating keywords and values
     ///        concerned with the database.
     ///
     /// @throw isc::dhcp::NoDatabaseName Mandatory database name not given
@@ -68,8 +66,7 @@ public:
     /// Releases prepared CQL statements used by the backend.
     virtual ~CqlHostDataSource();
 
-    /// @brief Adds a new @ref Host to the Cassandra database along with it's
-    ///     reservations and options.
+    /// @brief Adds a new host to the collection.
     ///
     /// The implementations of this method should guard against duplicate
     /// reservations for the same @ref Host, where possible. For example, when
@@ -80,7 +77,7 @@ public:
     /// @ref DUID.
     ///
     /// @param host pointer to the new @ref Host being added.
-    virtual void add(const HostPtr& host);
+    virtual void add(const HostPtr& host) override;
 
     /// @brief Retrieves a single @ref Host connected to an IPv4 subnet.
     ///
@@ -100,14 +97,14 @@ public:
     /// @throw BadValue if both or neither of subnet_id and duid are specified
     virtual ConstHostPtr get4(const SubnetID& subnet_id,
                               const HWAddrPtr& hwaddr,
-                              const DuidPtr& duid = DuidPtr()) const;
+                              const DuidPtr& duid = DuidPtr()) const override;
 
     /// @brief Retrieves a @ref Host connected to an IPv4 subnet.
     ///
     /// @param subnet_id subnet identifier to filter by
     /// @param identifier_type identifier type to filter by
-    /// @param identifier_begin pointer to the beginning of a buffer containing a
-    ///     host identifier to filter by
+    /// @param identifier_begin pointer to the beginning of a buffer containing
+    ///     host identifier to filter by
     /// @param identifier_len length of the host identifier buffer
     ///
     /// @return @ref Host object for which a reservation has been made using the
@@ -115,7 +112,7 @@ public:
     virtual ConstHostPtr get4(const SubnetID& subnet_id,
                               const Host::IdentifierType& identifier_type,
                               const uint8_t* identifier_begin,
-                              const size_t identifier_len) const;
+                              const size_t identifier_len) const override;
 
     /// @brief Retrieves a @ref Host connected to an IPv4 subnet.
     ///
@@ -130,8 +127,9 @@ public:
     /// @return Const @ref Host object
     ///
     /// @throw BadValue if address in not a valid IPv4address
-    virtual ConstHostPtr get4(const SubnetID& subnet_id,
-                              const asiolink::IOAddress& address) const;
+    virtual ConstHostPtr
+    get4(const SubnetID& subnet_id,
+         const asiolink::IOAddress& address) const override;
 
     /// @brief Retrieves a @ref Host connected to an IPv6 subnet.
     ///
@@ -148,16 +146,17 @@ public:
     /// @return @ref Host object using a specified @ref HWAddr or @ref DUID
     ///
     /// @throw BadValue if both or neither of subnet_id and duid are specified
-    virtual ConstHostPtr get6(const SubnetID& subnet_id,
-                              const DuidPtr& duid,
-                              const HWAddrPtr& hwaddr = HWAddrPtr()) const;
+    virtual ConstHostPtr
+    get6(const SubnetID& subnet_id,
+         const DuidPtr& duid,
+         const HWAddrPtr& hwaddr = HWAddrPtr()) const override;
 
     /// @brief Returns a @ref Host connected to an IPv6 subnet.
     ///
     /// @param subnet_id subnet identifier to filter by
     /// @param identifier_type identifier type to filter by
-    /// @param identifier_begin pointer to the beginning of a buffer containing a
-    ///     host identifier to filter by
+    /// @param identifier_begin pointer to the beginning of a buffer containing
+    ///     host identifier to filter by
     /// @param identifier_len length of the host identifier buffer
     ///
     /// @return Const @ref Host object for which reservation has been made using
@@ -165,7 +164,7 @@ public:
     virtual ConstHostPtr get6(const SubnetID& subnet_id,
                               const Host::IdentifierType& identifier_type,
                               const uint8_t* identifier_begin,
-                              const size_t identifier_len) const;
+                              const size_t identifier_len) const override;
 
     /// @brief Returns a @ref Host with the specified reservation prefix.
     ///
@@ -177,7 +176,7 @@ public:
     /// @throw MultipleRecords if two or more rows are returned from the
     ///     Cassandra database
     virtual ConstHostPtr get6(const asiolink::IOAddress& prefix,
-                              const uint8_t prefix_len) const;
+                              const uint8_t prefix_len) const override;
 
     /// @brief Returns a host connected to the IPv6 subnet and having
     /// a reservation for a specified IPv6 address or prefix.
@@ -186,8 +185,9 @@ public:
     /// @param address reserved IPv6 address/prefix.
     ///
     /// @return Const @c Host object using a specified IPv6 address/prefix.
-    virtual ConstHostPtr get6(const SubnetID& subnet_id,
-                              const asiolink::IOAddress& address) const;
+    virtual ConstHostPtr
+    get6(const SubnetID& subnet_id,
+         const asiolink::IOAddress& address) const override;
 
     /// @brief Return all @ref Host objects for the specified @ref HWAddr or
     /// @ref DUID.
@@ -211,8 +211,9 @@ public:
     /// @param duid client id or NULL if not available, e.g. DHCPv4 client case.
     ///
     /// @return collection of const @ref Host objects.
-    virtual ConstHostCollection getAll(const HWAddrPtr& hwaddr,
-                                       const DuidPtr& duid = DuidPtr()) const;
+    virtual ConstHostCollection
+    getAll(const HWAddrPtr& hwaddr,
+           const DuidPtr& duid = DuidPtr()) const override;
 
     /// @brief Return all hosts connected to any subnet for which reservations
     /// have been made using a specified identifier.
@@ -223,14 +224,14 @@ public:
     ///
     /// @param identifier_type Identifier type.
     /// @param identifier_begin Pointer to a beginning of a buffer containing
-    /// an identifier.
+    ///     an identifier.
     /// @param identifier_len Identifier length.
     ///
     /// @return Collection of const @ref Host objects.
     virtual ConstHostCollection
     getAll(const Host::IdentifierType& identifier_type,
            const uint8_t* identifier_begin,
-           const size_t identifier_len) const;
+           const size_t identifier_len) const override;
 
     /// @brief Returns a collection of hosts using the specified IPv4 address.
     ///
@@ -241,7 +242,55 @@ public:
     ///
     /// @return Collection of const @ref Host objects.
     virtual ConstHostCollection
-    getAll4(const asiolink::IOAddress& address) const;
+    getAll4(const asiolink::IOAddress& address) const override;
+
+    /// @brief Attempts to delete a host by (subnet-id, address)
+    ///
+    /// This method supports both v4 and v6.
+    ///
+    /// @param subnet_id subnet identfier.
+    /// @param addr specified address.
+    /// @return true if deletion was successful, false if the host was not
+    ///     there.
+    /// @throw various exceptions in case of errors
+    virtual bool del(const SubnetID& subnet_id,
+                     const asiolink::IOAddress& addr);
+
+    /// @brief Attempts to delete a host by (subnet-id4, identifier,
+    /// identifier-type)
+    ///
+    /// This method supports both v4 hosts only.
+    ///
+    /// @param subnet_id IPv4 Subnet identifier.
+    /// @param identifier_type Identifier type.
+    /// @param identifier_begin Pointer to a beginning of a buffer containing
+    ///     an identifier.
+    /// @param identifier_len Identifier length.
+    /// @return true if deletion was successful, false if the host was not
+    ///     there.
+    /// @throw various exceptions in case of errors
+    virtual bool del4(const SubnetID& subnet_id,
+                      const Host::IdentifierType& identifier_type,
+                      const uint8_t* identifier_begin,
+                      const size_t identifier_len);
+
+    /// @brief Attempts to delete a host by (subnet-id6, identifier,
+    /// identifier-type)
+    ///
+    /// This method supports both v6 hosts only.
+    ///
+    /// @param subnet_id IPv6 Subnet identifier.
+    /// @param identifier_type Identifier type.
+    /// @param identifier_begin Pointer to a beginning of a buffer containing
+    ///     an identifier.
+    /// @param identifier_len Identifier length.
+    /// @return true if deletion was successful, false if the host was not
+    ///     there.
+    /// @throw various exceptions in case of errors
+    virtual bool del6(const SubnetID& subnet_id,
+                      const Host::IdentifierType& identifier_type,
+                      const uint8_t* identifier_begin,
+                      const size_t identifier_len);
 
     /// @brief Returns description of the backend.
     ///
@@ -258,7 +307,7 @@ public:
     /// @brief Return backend type
     ///
     /// @return backend type "cql"
-    virtual std::string getType() const;
+    virtual std::string getType() const override;
 
     /// @brief Retrieves schema version.
     ///
@@ -268,24 +317,24 @@ public:
     ///
     /// @throw isc::dhcp::DbOperationError An operation on the open database
     ///        has failed.
-    virtual std::pair<uint32_t, uint32_t> getVersion() const;
+    virtual VersionPair getVersion() const;
 
     /// @brief Commit Transactions
     ///
     /// Commits all pending database operations.
-    virtual void commit();
+    virtual void commit() override;
 
     /// @brief Rollback Transactions
     ///
     /// Rolls back all pending database operations.
-    virtual void rollback();
+    virtual void rollback() override;
 
 private:
     /// @brief Pointer to the implementation of the @ref CqlHostDataSource.
     CqlHostDataSourceImpl* impl_;
 };  // class CqlHostDataSource
 
-};  // namespace dhcp
-};  // namespace isc
+}  // namespace dhcp
+}  // namespace isc
 
 #endif  // CQL_HOST_DATA_SOURCE_H
index 04df354a091d8caf7fc4fb212e016fbf3f8c22ca..c91eff65da1bca33ceac95ddfc1980bf183433fa 100644 (file)
@@ -197,9 +197,6 @@ V6) is about to open a Cassandra lease database.  The parameters of
 the connection including database name and username needed to access it
 (but not the password if any) are logged.
 
-% DHCPSRV_CQL_COMMIT committing to Cassandra database.
-A commit call been issued on the server. For Cassandra, this is a no-op.
-
 % DHCPSRV_CQL_CONNECTION_COMMIT committing to Cassandra database on current connection.
 A commit call been issued on the server. For Cassandra, this is a no-op.
 
@@ -231,9 +228,6 @@ The server has issued a rollback transaction call on an opened transaction.
 % DHCPSRV_CQL_TRANSACTION_MGR_TRANSACTION_NOT_FOUND failed to select a transaction.
 The server failed to select a transaction to operate on.
 
-% DHCPSRV_CQL_BEGIN_TRANSACTION begin transaction.
-The server has issued a begin transaction call.
-
 % DHCPSRV_CQL_CONNECTION_BEGIN_TRANSACTION begin transaction on current connection.
 The server has issued a begin transaction call.
 
@@ -246,12 +240,6 @@ The server has issued a commit transaction call.
 % DHCPSRV_CQL_TRANSACTION_MGR_ROLLBACK_TRANSACTION rollback transaction action has been initiated.
 The server has issued a rollback transaction call.
 
-% DHCPSRV_CQL_DB opening Cassandra lease database: %1
-This informational message is logged when a DHCP server (either V4 or
-V6) is about to open a Cassandra lease database.  The parameters of
-the connection including database name and username needed to access it
-(but not the password if any) are logged.
-
 % DHCPSRV_CQL_DELETE_ADDR deleting lease for address %1
 A debug message issued when the server is attempting to delete a lease from the
 Cassandra database for the specified address.
index e84f7f31d3d1f82671d9641a5450b1f6856cd03e..7a4591fd4803d1885a9352500d041bbbbded9a72 100644 (file)
@@ -4,7 +4,7 @@
 // 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/.
 
-#include "config.h"
+#include <config.h>
 
 #include <dhcpsrv/dhcpsrv_log.h>
 #include <dhcpsrv/host_data_source_factory.h>
@@ -38,7 +38,6 @@ using namespace std;
 namespace isc {
 namespace dhcp {
 
-
 HostDataSourcePtr&
 HostDataSourceFactory::getHostDataSourcePtr() {
     static HostDataSourcePtr hostDataSourcePtr;
@@ -115,5 +114,5 @@ HostDataSourceFactory::instance() {
 }
 #endif
 
-}; // namespace dhcp
-}; // namespace isc
+}  // namespace dhcp
+}  // namespace isc
index 684b76db8caac66c0b4d8edb6c214853d5b65465..754f86b661c35220af624b6798031e17edc17a1a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2017 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
 #include <gtest/gtest.h>
 
 #include <algorithm>
-#include <iostream>
 #include <sstream>
 #include <string>
 #include <utility>
 
+namespace {
+
 using namespace isc;
 using namespace isc::asiolink;
 using namespace isc::dhcp;
 using namespace isc::dhcp::test;
-using namespace std;
-
-namespace {
 
 class CqlHostDataSourceTest : public GenericHostDataSourceTest {
 public:
-    /// @brief Constructor
-    ///
-    /// Deletes everything from the database and opens it.
-    CqlHostDataSourceTest() {
+    /// @brief Clears the database and opens connection to it.
+    void initializeTest() {
         // Ensure schema is the correct one.
         destroyCqlSchema(false, true);
         createCqlSchema(false, true);
@@ -58,15 +54,31 @@ public:
         hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
     }
 
+    /// @brief Destroys the HDS and the schema.
+    void destroyTest() {
+        try {
+            hdsptr_->rollback();
+        } catch (...) {
+            // Rollback may fail if backend is in read only mode. That's ok.
+        }
+        HostDataSourceFactory::destroy();
+        destroyCqlSchema(false, true);
+    }
+
+    /// @brief Constructor
+    ///
+    /// Deletes everything from the database and opens it.
+    CqlHostDataSourceTest() {
+        initializeTest();
+    }
+
     /// @brief Destructor
     ///
     /// Rolls back all pending transactions.  The deletion of myhdsptr_ will
     /// close the database.  Then reopen it and delete everything created by the
     /// test.
     virtual ~CqlHostDataSourceTest() {
-        hdsptr_->rollback();
-        HostDataSourceFactory::destroy();
-        destroyCqlSchema(false, true);
+        destroyTest();
     }
 
     /// @brief Reopen the database
@@ -169,7 +181,7 @@ TEST(CqlHostDataSource, OpenDatabase) {
     destroyCqlSchema(false, true);
 }
 
-/// @brief Check conversion functions
+/// @brief Check conversion methods
 ///
 /// The server works using cltt and valid_filetime.  In the database, the
 /// information is stored as expire_time and valid-lifetime, which are
@@ -475,8 +487,7 @@ TEST_F(CqlHostDataSourceTest, testAddRollback) {
     CqlConnection connection(params);
     ASSERT_NO_THROW(connection.openDatabase());
 
-    // Drop every table so we make sure host_ipv6_reservation_options doesn't
-    // exist anymore
+    // Drop every table so we make sure host_reservations doesn't exist anymore.
     destroyCqlSchema(false, true);
 
     // Create a host with a reservation.
index bc431ed938cc798bcdb3fa3518268fe7598a86ba..3a1301fd97a2cc161a358889bf691a2e4efb255e 100644 (file)
@@ -5,26 +5,29 @@
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 #include <config.h>
+
+#include <asiolink/io_address.h>
+#include <boost/foreach.hpp>
 #include <dhcp/dhcp6.h>
 #include <dhcp/libdhcp++.h>
 #include <dhcp/option4_addrlst.h>
 #include <dhcp/option6_addrlst.h>
-#include <dhcp/option_string.h>
 #include <dhcp/option_int.h>
+#include <dhcp/option_string.h>
 #include <dhcp/option_vendor.h>
+#include <dhcpsrv/database_connection.h>
 #include <dhcpsrv/host_data_source_factory.h>
 #include <dhcpsrv/tests/generic_host_data_source_unittest.h>
 #include <dhcpsrv/tests/test_utils.h>
 #include <dhcpsrv/testutils/schema.h>
-#include <dhcpsrv/database_connection.h>
-#include <asiolink/io_address.h>
-#include <util/buffer.h>
-#include <boost/foreach.hpp>
 #include <gtest/gtest.h>
+#include <util/buffer.h>
+
+#include <chrono>
 #include <cstring>
 #include <list>
-#include <string>
 #include <sstream>
+#include <string>
 #include <typeinfo>
 
 using namespace std;
@@ -35,13 +38,13 @@ namespace isc {
 namespace dhcp {
 namespace test {
 
-GenericHostDataSourceTest::GenericHostDataSourceTest()
-    :hdsptr_() {
+GenericHostDataSourceTest::GenericHostDataSourceTest() : hdsptr_() {
     LibDHCP::clearRuntimeOptionDefs();
 }
 
 GenericHostDataSourceTest::~GenericHostDataSourceTest() {
     LibDHCP::clearRuntimeOptionDefs();
+    hdsptr_.reset();
 }
 
 std::vector<uint8_t>
@@ -70,12 +73,11 @@ GenericHostDataSourceTest::generateIdentifier(const bool new_identifier) {
 
     // Let's use something that is easily printable. That's convenient
     // if you need to enter MySQL queries by hand.
-    static uint8_t ident[] = { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74 };
+    static uint8_t ident[] = {65, 66, 67, 68, 69, 70, 71, 72, 73, 74};
 
-    // Increase the identifier for the next time we use it.
-    // This is primitive, but will work for 65k unique
-    // identifiers.
     if (new_identifier) {
+        // Increase the identifier for the next time we use it.
+        // This is primitive, but will work for 65k unique identifiers.
         ident[sizeof(ident) - 1]++;
         if (ident[sizeof(ident) - 1] == 0) {
             ident[sizeof(ident) - 2]++;
@@ -90,7 +92,6 @@ GenericHostDataSourceTest::initializeHost4(const std::string& address,
     std::vector<uint8_t> ident;
     if (id == Host::IDENT_HWADDR) {
         ident = generateHWAddr();
-
     } else {
         ident = generateIdentifier();
     }
@@ -109,10 +110,11 @@ GenericHostDataSourceTest::initializeHost4(const std::string& address,
     return (host);
 }
 
-HostPtr GenericHostDataSourceTest::initializeHost6(std::string address,
-                                                   Host::IdentifierType identifier,
-                                                   bool prefix,
-                                                   bool new_identifier) {
+HostPtr
+GenericHostDataSourceTest::initializeHost6(std::string address,
+                                           Host::IdentifierType identifier,
+                                           bool prefix,
+                                           bool new_identifier) {
     std::vector<uint8_t> ident;
     switch (identifier) {
     case Host::IDENT_HWADDR:
@@ -134,8 +136,8 @@ HostPtr GenericHostDataSourceTest::initializeHost6(std::string address,
     subnet4++;
     subnet6++;
 
-    HostPtr host(new Host(&ident[0], ident.size(), identifier, subnet4,
-                          subnet6, IOAddress("0.0.0.0")));
+    HostPtr host(new Host(&ident[0], ident.size(), identifier, subnet4, subnet6,
+                          IOAddress("0.0.0.0")));
 
     if (!prefix) {
         // Create IPv6 reservation (for an address)
@@ -149,6 +151,17 @@ HostPtr GenericHostDataSourceTest::initializeHost6(std::string address,
     return (host);
 }
 
+bool
+GenericHostDataSourceTest::reservationExists(const IPv6Resrv& resrv,
+                                             const IPv6ResrvRange& range) {
+    for (IPv6ResrvIterator it = range.first; it != range.second; ++it) {
+        if (resrv == it->second) {
+            return true;
+        }
+    }
+    return false;
+}
+
 void
 GenericHostDataSourceTest::compareHwaddrs(const ConstHostPtr& host1,
                                           const ConstHostPtr& host2,
@@ -159,13 +172,12 @@ GenericHostDataSourceTest::compareHwaddrs(const ConstHostPtr& host1,
     // Compare if both have or have not HWaddress set.
     if ((host1->getHWAddress() && !host2->getHWAddress()) ||
         (!host1->getHWAddress() && host2->getHWAddress())) {
-
         // One host has hardware address set while the other has not.
         // Let's see if it's a problem.
         if (expect_match) {
             ADD_FAILURE() << "Host comparison failed: host1 hwaddress="
-                          << host1->getHWAddress() << ", host2 hwaddress="
-                          << host2->getHWAddress();
+                          << host1->getHWAddress()
+                          << ", host2 hwaddress=" << host2->getHWAddress();
         }
         return;
     }
@@ -173,7 +185,6 @@ GenericHostDataSourceTest::compareHwaddrs(const ConstHostPtr& host1,
     // Now we know that either both or neither have hw address set.
     // If host1 has it, we can proceed to value comparison.
     if (host1->getHWAddress()) {
-
         if (expect_match) {
             // Compare the actual address if they match.
             EXPECT_TRUE(*host1->getHWAddress() == *host2->getHWAddress());
@@ -197,13 +208,12 @@ GenericHostDataSourceTest::compareDuids(const ConstHostPtr& host1,
     // compare if both have or have not DUID set
     if ((host1->getDuid() && !host2->getDuid()) ||
         (!host1->getDuid() && host2->getDuid())) {
-
         // One host has a DUID and the other doesn't.
         // Let's see if it's a problem.
         if (expect_match) {
             ADD_FAILURE() << "DUID comparison failed: host1 duid="
-                          << host1->getDuid() << ", host2 duid="
-                          << host2->getDuid();
+                          << host1->getDuid()
+                          << ", host2 duid=" << host2->getDuid();
         }
         return;
     }
@@ -211,7 +221,6 @@ GenericHostDataSourceTest::compareDuids(const ConstHostPtr& host1,
     // Now we know that either both or neither have DUID set.
     // If host1 has it, we can proceed to value comparison.
     if (host1->getDuid()) {
-
         if (expect_match) {
             EXPECT_TRUE(*host1->getDuid() == *host2->getDuid());
         } else {
@@ -224,9 +233,9 @@ GenericHostDataSourceTest::compareDuids(const ConstHostPtr& host1,
     }
 }
 
-void GenericHostDataSourceTest::compareHosts(const ConstHostPtr& host1,
-                                             const ConstHostPtr& host2) {
-
+void
+GenericHostDataSourceTest::compareHosts(const ConstHostPtr& host1,
+                                        const ConstHostPtr& host2) {
     // Let's compare HW addresses and expect match.
     compareHwaddrs(host1, host2, true);
 
@@ -262,18 +271,18 @@ void GenericHostDataSourceTest::compareHosts(const ConstHostPtr& host1,
     compareOptions(host1->getCfgOption6(), host2->getCfgOption6());
 }
 
-bool GenericHostDataSourceTest::compareHostsForSort4(
-    const ConstHostPtr& host1,
-    const ConstHostPtr& host2) {
+bool
+GenericHostDataSourceTest::compareHostsForSort4(const ConstHostPtr& host1,
+                                                const ConstHostPtr& host2) {
     if (host1->getIPv4SubnetID() < host2->getIPv4SubnetID()) {
         return true;
     }
     return false;
 }
 
-bool GenericHostDataSourceTest::compareHostsForSort6(
-    const ConstHostPtr& host1,
-    const ConstHostPtr& host2) {
+bool
+GenericHostDataSourceTest::compareHostsForSort6(const ConstHostPtr& host1,
+                                                const ConstHostPtr& host2) {
     if (host1->getIPv6SubnetID() < host2->getIPv6SubnetID()) {
         return true;
     }
@@ -298,16 +307,14 @@ GenericHostDataSourceTest::DuidToHWAddr(const DuidPtr& duid) {
     return (HWAddrPtr(new HWAddr(duid->getDuid(), HTYPE_ETHER)));
 }
 
-
 void
 GenericHostDataSourceTest::compareReservations6(IPv6ResrvRange resrv1,
                                                 IPv6ResrvRange resrv2) {
-
     // Compare number of reservations for both hosts
     if (std::distance(resrv1.first, resrv1.second) !=
-            std::distance(resrv2.first, resrv2.second)){
-        ADD_FAILURE()<< "Reservation comparison failed, "
-            "hosts got different number of reservations.";
+        std::distance(resrv2.first, resrv2.second)) {
+        ADD_FAILURE() << "Reservation comparison failed, "
+                         "hosts got different number of reservations.";
         return;
     }
 
@@ -333,16 +340,19 @@ GenericHostDataSourceTest::compareReservations6(IPv6ResrvRange resrv1,
         for (; resrv1.first != resrv1.second; resrv1.first++) {
             IPv6ResrvIterator iter = resrv2.first;
             while (iter != resrv2.second) {
-                if((resrv1.first->second.getType() == iter->second.getType()) &&
-                        (resrv1.first->second.getPrefixLen() == iter->second.getPrefixLen()) &&
-                        (resrv1.first->second.getPrefix() == iter->second.getPrefix())) {
+                if ((resrv1.first->second.getType() ==
+                     iter->second.getType()) &&
+                    (resrv1.first->second.getPrefixLen() ==
+                     iter->second.getPrefixLen()) &&
+                    (resrv1.first->second.getPrefix() ==
+                     iter->second.getPrefix())) {
                     break;
                 }
                 iter++;
                 if (iter == resrv2.second) {
-                    ADD_FAILURE()<< "Reservation comparison failed, "
-                    "no match for reservation: "
-                    << resrv1.first->second.getPrefix().toText();
+                    ADD_FAILURE() << "Reservation comparison failed, "
+                                     "no match for reservation: "
+                                  << resrv1.first->second.getPrefix().toText();
                 }
             }
         }
@@ -373,7 +383,7 @@ GenericHostDataSourceTest::compareOptions(const ConstCfgOptionPtr& cfg1,
     EXPECT_EQ(vendor_spaces.size(), cfg1->getVendorIdsSpaceNames().size());
 
     // Iterate over all option spaces existing in cfg2.
-    BOOST_FOREACH(std::string space, option_spaces) {
+    BOOST_FOREACH (std::string space, option_spaces) {
         // Retrieve options belonging to the current option space.
         OptionContainerPtr options1 = cfg1->getAll(space);
         OptionContainerPtr options2 = cfg2->getAll(space);
@@ -385,14 +395,16 @@ GenericHostDataSourceTest::compareOptions(const ConstCfgOptionPtr& cfg1,
             << "failed for option space " << space;
 
         // Iterate over all options within this option space.
-        BOOST_FOREACH(OptionDescriptor desc1, *options1) {
+        BOOST_FOREACH (OptionDescriptor desc1, *options1) {
             OptionDescriptor desc2 = cfg2->get(space, desc1.option_->getType());
             // Compare persistent flag.
             EXPECT_EQ(desc1.persistent_, desc2.persistent_)
-                << "failed for option " << space << "." << desc1.option_->getType();
+                << "failed for option " << space << "."
+                << desc1.option_->getType();
             // Compare formatted value.
             EXPECT_EQ(desc1.formatted_value_, desc2.formatted_value_)
-                << "failed for option " << space << "." << desc1.option_->getType();
+                << "failed for option " << space << "."
+                << desc1.option_->getType();
 
             // Retrieve options.
             Option* option1 = desc1.option_.get();
@@ -402,11 +414,10 @@ GenericHostDataSourceTest::compareOptions(const ConstCfgOptionPtr& cfg1,
             // the Option class.
             EXPECT_TRUE(typeid(*option1) == typeid(*option2))
                 << "Compared DHCP options, having option code "
-                << desc1.option_->getType() << " and belonging to the "
-                << space << " option space, are represented "
-                "by different C++ classes: "
-                << typeid(*option1).name() << " vs "
-                << typeid(*option2).name();
+                << desc1.option_->getType() << " and belonging to the " << space
+                << " option space, are represented "
+                   "by different C++ classes: "
+                << typeid(*option1).name() << " vs " << typeid(*option2).name();
 
             // Because we use different C++ classes to represent different
             // options, the simplest way to make sure that the options are
@@ -417,9 +428,12 @@ GenericHostDataSourceTest::compareOptions(const ConstCfgOptionPtr& cfg1,
             ASSERT_NO_THROW(option2->pack(buf2));
 
             ASSERT_EQ(buf1.getLength(), buf2.getLength())
-                 << "failed for option " << space << "." << desc1.option_->getType();
-            EXPECT_EQ(0, memcmp(buf1.getData(), buf2.getData(), buf1.getLength()))
-                << "failed for option " << space << "." << desc1.option_->getType();
+                << "failed for option " << space << "."
+                << desc1.option_->getType();
+            EXPECT_EQ(0,
+                      memcmp(buf1.getData(), buf2.getData(), buf1.getLength()))
+                << "failed for option " << space << "."
+                << desc1.option_->getType();
         }
     }
 }
@@ -433,7 +447,6 @@ GenericHostDataSourceTest::createEmptyOption(const Option::Universe& universe,
     return (desc);
 }
 
-
 OptionDescriptor
 GenericHostDataSourceTest::createVendorOption(const Option::Universe& universe,
                                               const bool persist,
@@ -453,10 +466,10 @@ GenericHostDataSourceTest::createVendorOption(const Option::Universe& universe,
 }
 
 void
-GenericHostDataSourceTest::addTestOptions(const HostPtr& host,
-                                          const bool formatted,
-                                          const AddedOptions& added_options) const {
-
+GenericHostDataSourceTest::addTestOptions(
+    const HostPtr& host,
+    const bool formatted,
+    const AddedOptions& added_options) const {
     OptionDefSpaceContainer defs;
 
     if ((added_options == DHCP4_ONLY) || (added_options == DHCP4_AND_DHCP6)) {
@@ -468,36 +481,40 @@ GenericHostDataSourceTest::addTestOptions(const HostPtr& host,
         opts->add(createOption<OptionUint8>(Option::V4, DHO_DEFAULT_IP_TTL,
                                             false, formatted, 64),
                   DHCP4_OPTION_SPACE);
-        opts->add(createOption<OptionUint32>(Option::V4, 1, false, formatted, 312131),
-                  "vendor-encapsulated-options");
-        opts->add(createAddressOption<Option4AddrLst>(254, false, formatted, "192.0.2.3"),
+        opts->add(
+            createOption<OptionUint32>(Option::V4, 1, false, formatted, 312131),
+            "vendor-encapsulated-options");
+        opts->add(createAddressOption<Option4AddrLst>(254, false, formatted,
+                                                      "192.0.2.3"),
                   DHCP4_OPTION_SPACE);
         opts->add(createEmptyOption(Option::V4, 1, true), "isc");
-        opts->add(createAddressOption<Option4AddrLst>(2, false, formatted, "10.0.0.5",
-                                                      "10.0.0.3", "10.0.3.4"),
+        opts->add(createAddressOption<Option4AddrLst>(
+                      2, false, formatted, "10.0.0.5", "10.0.0.3", "10.0.3.4"),
                   "isc");
 
         // Add definitions for DHCPv4 non-standard options.
-        defs.addItem(OptionDefinitionPtr(new OptionDefinition("vendor-encapsulated-1",
-                                                              1, "uint32")),
+        defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+                         "vendor-encapsulated-1", 1, "uint32")),
                      "vendor-encapsulated-options");
-        defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-254", 254,
-                                                              "ipv4-address", true)),
+        defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+                         "option-254", 254, "ipv4-address", true)),
                      DHCP4_OPTION_SPACE);
-        defs.addItem(OptionDefinitionPtr(new OptionDefinition("isc-1", 1, "empty")),
-                     "isc");
-        defs.addItem(OptionDefinitionPtr(new OptionDefinition("isc-2", 2,
-                                                              "ipv4-address", true)),
+        defs.addItem(
+            OptionDefinitionPtr(new OptionDefinition("isc-1", 1, "empty")),
+            "isc");
+        defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+                         "isc-2", 2, "ipv4-address", true)),
                      "isc");
     }
 
     if ((added_options == DHCP6_ONLY) || (added_options == DHCP4_AND_DHCP6)) {
         // Add DHCPv6 options.
         CfgOptionPtr opts = host->getCfgOption6();
-        opts->add(createOption<OptionString>(Option::V6, D6O_BOOTFILE_URL,
-                                             true, formatted, "my-boot-file"),
+        opts->add(createOption<OptionString>(Option::V6, D6O_BOOTFILE_URL, true,
+                                             formatted, "my-boot-file"),
                   DHCP6_OPTION_SPACE);
-        opts->add(createOption<OptionUint32>(Option::V6, D6O_INFORMATION_REFRESH_TIME,
+        opts->add(createOption<OptionUint32>(Option::V6,
+                                             D6O_INFORMATION_REFRESH_TIME,
                                              false, formatted, 3600),
                   DHCP6_OPTION_SPACE);
         opts->add(createVendorOption(Option::V6, false, formatted, 2495),
@@ -506,18 +523,19 @@ GenericHostDataSourceTest::addTestOptions(const HostPtr& host,
                                                       "2001:db8:1::1"),
                   DHCP6_OPTION_SPACE);
         opts->add(createEmptyOption(Option::V6, 1, true), "isc2");
-        opts->add(createAddressOption<Option6AddrLst>(2, false, formatted, "3000::1",
-                                                      "3000::2", "3000::3"),
+        opts->add(createAddressOption<Option6AddrLst>(
+                      2, false, formatted, "3000::1", "3000::2", "3000::3"),
                   "isc2");
 
         // Add definitions for DHCPv6 non-standard options.
-        defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-1024", 1024,
-                                                              "ipv6-address", true)),
+        defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+                         "option-1024", 1024, "ipv6-address", true)),
                      DHCP6_OPTION_SPACE);
-        defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-1", 1, "empty")),
-                     "isc2");
-        defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-2", 2,
-                                                              "ipv6-address", true)),
+        defs.addItem(
+            OptionDefinitionPtr(new OptionDefinition("option-1", 1, "empty")),
+            "isc2");
+        defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+                         "option-2", 2, "ipv6-address", true)),
                      "isc2");
     }
 
@@ -542,21 +560,18 @@ GenericHostDataSourceTest::testReadOnlyDatabase(const char* valid_db_type) {
 
     // Make sure that the host has been inserted and that the data can be
     // retrieved.
-    ConstHostPtr host_by_id = hdsptr_->get6(subnet_id, host->getIdentifierType(),
-                                            &host->getIdentifier()[0],
-                                            host->getIdentifier().size());
+    ConstHostPtr host_by_id =
+        hdsptr_->get6(subnet_id, host->getIdentifierType(),
+                      &host->getIdentifier()[0], host->getIdentifier().size());
     ASSERT_TRUE(host_by_id);
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_id));
 
     // Close the database connection and reopen in "read-only" mode as
     // specified by the "VALID_READONLY_DB" parameter.
     HostDataSourceFactory::destroy();
-    HostDataSourceFactory::create(connectionString(valid_db_type,
-                                                   VALID_NAME,
-                                                   VALID_HOST,
-                                                   VALID_READONLY_USER,
-                                                   VALID_PASSWORD,
-                                                   VALID_READONLY_DB));
+    HostDataSourceFactory::create(connectionString(
+        valid_db_type, VALID_NAME, VALID_HOST, VALID_READONLY_USER,
+        VALID_PASSWORD, VALID_READONLY_DB));
 
     hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
 
@@ -569,20 +584,21 @@ GenericHostDataSourceTest::testReadOnlyDatabase(const char* valid_db_type) {
     ASSERT_THROW(hdsptr_->rollback(), ReadOnlyDb);
 
     // Reading from the database should still be possible, though.
-    host_by_id = hdsptr_->get6(subnet_id, host->getIdentifierType(),
-                               &host->getIdentifier()[0],
-                               host->getIdentifier().size());
+    host_by_id =
+        hdsptr_->get6(subnet_id, host->getIdentifierType(),
+                      &host->getIdentifier()[0], host->getIdentifier().size());
     ASSERT_TRUE(host_by_id);
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_id));
 }
 
-void GenericHostDataSourceTest::testBasic4(const Host::IdentifierType& id) {
+void
+GenericHostDataSourceTest::testBasic4(const Host::IdentifierType& id) {
     // Make sure we have the pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
     // Create a host reservation.
     HostPtr host = initializeHost4("192.0.2.1", id);
-    ASSERT_TRUE(host); // Make sure the host is generate properly.
+    ASSERT_TRUE(host);  // Make sure the host is generate properly.
     SubnetID subnet = host->getIPv4SubnetID();
 
     // Try to add it to the host data source.
@@ -600,8 +616,8 @@ void GenericHostDataSourceTest::testBasic4(const Host::IdentifierType& id) {
     compareHosts(host, from_hds);
 }
 
-
-void GenericHostDataSourceTest::testGetByIPv4(const Host::IdentifierType& id) {
+void
+GenericHostDataSourceTest::testGetByIPv4(const Host::IdentifierType& id) {
     // Make sure we have a pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -646,7 +662,8 @@ void GenericHostDataSourceTest::testGetByIPv4(const Host::IdentifierType& id) {
 }
 
 void
-GenericHostDataSourceTest::testGet4ByIdentifier(const Host::IdentifierType& identifier_type) {
+GenericHostDataSourceTest::testGet4ByIdentifier(
+    const Host::IdentifierType& identifier_type) {
     // Make sure we have a pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -663,15 +680,13 @@ GenericHostDataSourceTest::testGet4ByIdentifier(const Host::IdentifierType& iden
     SubnetID subnet1 = host1->getIPv4SubnetID();
     SubnetID subnet2 = host2->getIPv4SubnetID();
 
-    ConstHostPtr from_hds1 = hdsptr_->get4(subnet1,
-                                           identifier_type,
-                                           &host1->getIdentifier()[0],
-                                           host1->getIdentifier().size());
+    ConstHostPtr from_hds1 =
+        hdsptr_->get4(subnet1, identifier_type, &host1->getIdentifier()[0],
+                      host1->getIdentifier().size());
 
-    ConstHostPtr from_hds2 = hdsptr_->get4(subnet2,
-                                           identifier_type,
-                                           &host2->getIdentifier()[0],
-                                           host2->getIdentifier().size());
+    ConstHostPtr from_hds2 =
+        hdsptr_->get4(subnet2, identifier_type, &host2->getIdentifier()[0],
+                      host2->getIdentifier().size());
 
     // Now let's check if we got what we expected.
     ASSERT_TRUE(from_hds1);
@@ -680,7 +695,8 @@ GenericHostDataSourceTest::testGet4ByIdentifier(const Host::IdentifierType& iden
     compareHosts(host2, from_hds2);
 }
 
-void GenericHostDataSourceTest::testHWAddrNotClientId() {
+void
+GenericHostDataSourceTest::testHWAddrNotClientId() {
     // Make sure we have a pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -697,21 +713,22 @@ void GenericHostDataSourceTest::testHWAddrNotClientId() {
     DuidPtr duid = HWAddrToDuid(host->getHWAddress());
 
     // Get the host by HW address (should succeed)
-    ConstHostPtr by_hwaddr = hdsptr_->get4(subnet, Host::IDENT_HWADDR,
-                                           &host->getIdentifier()[0],
-                                           host->getIdentifier().size());
+    ConstHostPtr by_hwaddr =
+        hdsptr_->get4(subnet, Host::IDENT_HWADDR, &host->getIdentifier()[0],
+                      host->getIdentifier().size());
 
     // Get the host by DUID (should fail)
-    ConstHostPtr by_duid   = hdsptr_->get4(subnet, Host::IDENT_DUID,
-                                           &host->getIdentifier()[0],
-                                           host->getIdentifier().size());
+    ConstHostPtr by_duid =
+        hdsptr_->get4(subnet, Host::IDENT_DUID, &host->getIdentifier()[0],
+                      host->getIdentifier().size());
 
     // Now let's check if we got what we expected.
     EXPECT_TRUE(by_hwaddr);
     EXPECT_FALSE(by_duid);
 }
 
-void GenericHostDataSourceTest::testClientIdNotHWAddr() {
+void
+GenericHostDataSourceTest::testClientIdNotHWAddr() {
     // Make sure we have a pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -728,15 +745,14 @@ void GenericHostDataSourceTest::testClientIdNotHWAddr() {
     HWAddrPtr hwaddr = DuidToHWAddr(host->getDuid());
 
     // Get the host by DUID (should succeed)
-    ConstHostPtr by_duid   = hdsptr_->get4(subnet, Host::IDENT_DUID,
-                                           &host->getIdentifier()[0],
-                                           host->getIdentifier().size());
-
+    ConstHostPtr by_duid =
+        hdsptr_->get4(subnet, Host::IDENT_DUID, &host->getIdentifier()[0],
+                      host->getIdentifier().size());
 
     // Get the host by HW address (should fail)
-    ConstHostPtr by_hwaddr = hdsptr_->get4(subnet, Host::IDENT_HWADDR,
-                                           &host->getIdentifier()[0],
-                                           host->getIdentifier().size());
+    ConstHostPtr by_hwaddr =
+        hdsptr_->get4(subnet, Host::IDENT_HWADDR, &host->getIdentifier()[0],
+                      host->getIdentifier().size());
 
     // Now let's check if we got what we expected.
     EXPECT_TRUE(by_duid);
@@ -745,7 +761,6 @@ void GenericHostDataSourceTest::testClientIdNotHWAddr() {
 
 void
 GenericHostDataSourceTest::testHostname(std::string name, int num) {
-
     // Make sure we have a pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -757,7 +772,6 @@ GenericHostDataSourceTest::testHostname(std::string name, int num) {
 
     // Prepare a vector of hosts with unique hostnames
     for (int i = 0; i < num; ++i) {
-
         addr = IOAddress::increase(addr);
 
         HostPtr host = initializeHost4(addr.toText(), Host::IDENT_DUID);
@@ -774,21 +788,19 @@ GenericHostDataSourceTest::testHostname(std::string name, int num) {
     }
 
     // Now add them all to the host data source.
-    for (vector<HostPtr>::const_iterator it = hosts.begin();
-         it != hosts.end(); ++it) {
+    for (vector<HostPtr>::const_iterator it = hosts.begin(); it != hosts.end();
+         ++it) {
         // Try to add both of the to the host data source.
         ASSERT_NO_THROW(hdsptr_->add(*it));
     }
 
     // And finally retrieve them one by one and check
     // if the hostname was preserved.
-    for (vector<HostPtr>::const_iterator it = hosts.begin();
-         it != hosts.end(); ++it) {
-
+    for (vector<HostPtr>::const_iterator it = hosts.begin(); it != hosts.end();
+         ++it) {
         ConstHostPtr from_hds;
-        ASSERT_NO_THROW(from_hds = hdsptr_->get4(
-                            (*it)->getIPv4SubnetID(),
-                            (*it)->getIPv4Reservation()));
+        ASSERT_NO_THROW(from_hds = hdsptr_->get4((*it)->getIPv4SubnetID(),
+                                                 (*it)->getIPv4Reservation()));
         ASSERT_TRUE(from_hds);
 
         EXPECT_EQ((*it)->getHostname(), from_hds->getHostname());
@@ -798,7 +810,6 @@ GenericHostDataSourceTest::testHostname(std::string name, int num) {
 void
 GenericHostDataSourceTest::testMultipleSubnets(int subnets,
                                                const Host::IdentifierType& id) {
-
     // Make sure we have a pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -815,16 +826,15 @@ GenericHostDataSourceTest::testMultipleSubnets(int subnets,
     // Now check that the reservations can be retrieved by IPv4 address from
     // each subnet separately.
     for (int i = 0; i < subnets; ++i) {
-
         // Try to retrieve the host by IPv4 address.
-        ConstHostPtr from_hds = hdsptr_->get4(i + 1000, host->getIPv4Reservation());
+        ConstHostPtr from_hds =
+            hdsptr_->get4(i + 1000, host->getIPv4Reservation());
 
         ASSERT_TRUE(from_hds);
         EXPECT_EQ(i + 1000, from_hds->getIPv4SubnetID());
 
         // Try to retrieve the host by either HW address of client-id
-        from_hds = hdsptr_->get4(i + 1000,
-                                 id, &host->getIdentifier()[0],
+        from_hds = hdsptr_->get4(i + 1000, id, &host->getIdentifier()[0],
                                  host->getIdentifier().size());
         ASSERT_TRUE(from_hds);
         EXPECT_EQ(i + 1000, from_hds->getIPv4SubnetID());
@@ -849,9 +859,8 @@ GenericHostDataSourceTest::testMultipleSubnets(int subnets,
     }
 
     // Finally, check that the hosts can be retrieved by HW address or DUID
-    ConstHostCollection all_by_id =
-        hdsptr_->getAll(id, &host->getIdentifier()[0],
-                        host->getIdentifier().size());
+    ConstHostCollection all_by_id = hdsptr_->getAll(
+        id, &host->getIdentifier()[0], host->getIdentifier().size());
     ASSERT_EQ(subnets, all_by_id.size());
 
     // Check that the returned values are as expected.
@@ -869,7 +878,8 @@ GenericHostDataSourceTest::testMultipleSubnets(int subnets,
     }
 }
 
-void GenericHostDataSourceTest::testGet6ByHWAddr() {
+void
+GenericHostDataSourceTest::testGet6ByHWAddr() {
     // Make sure we have the pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -890,13 +900,13 @@ void GenericHostDataSourceTest::testGet6ByHWAddr() {
     SubnetID subnet1 = host1->getIPv6SubnetID();
     SubnetID subnet2 = host2->getIPv6SubnetID();
 
-    ConstHostPtr from_hds1 = hdsptr_->get6(subnet1, Host::IDENT_HWADDR,
-                                           &host1->getIdentifier()[0],
-                                           host1->getIdentifier().size());
+    ConstHostPtr from_hds1 =
+        hdsptr_->get6(subnet1, Host::IDENT_HWADDR, &host1->getIdentifier()[0],
+                      host1->getIdentifier().size());
 
-    ConstHostPtr from_hds2 = hdsptr_->get6(subnet2, Host::IDENT_HWADDR,
-                                           &host2->getIdentifier()[0],
-                                           host2->getIdentifier().size());
+    ConstHostPtr from_hds2 =
+        hdsptr_->get6(subnet2, Host::IDENT_HWADDR, &host2->getIdentifier()[0],
+                      host2->getIdentifier().size());
 
     // Now let's check if we got what we expected.
     ASSERT_TRUE(from_hds1);
@@ -905,7 +915,8 @@ void GenericHostDataSourceTest::testGet6ByHWAddr() {
     compareHosts(host2, from_hds2);
 }
 
-void GenericHostDataSourceTest::testGet6ByClientId() {
+void
+GenericHostDataSourceTest::testGet6ByClientId() {
     // Make sure we have the pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -926,13 +937,13 @@ void GenericHostDataSourceTest::testGet6ByClientId() {
     SubnetID subnet1 = host1->getIPv6SubnetID();
     SubnetID subnet2 = host2->getIPv6SubnetID();
 
-    ConstHostPtr from_hds1 = hdsptr_->get6(subnet1, Host::IDENT_DUID,
-                                           &host1->getIdentifier()[0],
-                                           host1->getIdentifier().size());
+    ConstHostPtr from_hds1 =
+        hdsptr_->get6(subnet1, Host::IDENT_DUID, &host1->getIdentifier()[0],
+                      host1->getIdentifier().size());
 
-    ConstHostPtr from_hds2 = hdsptr_->get6(subnet2, Host::IDENT_DUID,
-                                           &host2->getIdentifier()[0],
-                                           host2->getIdentifier().size());
+    ConstHostPtr from_hds2 =
+        hdsptr_->get6(subnet2, Host::IDENT_DUID, &host2->getIdentifier()[0],
+                      host2->getIdentifier().size());
 
     // Now let's check if we got what we expected.
     ASSERT_TRUE(from_hds1);
@@ -943,7 +954,6 @@ void GenericHostDataSourceTest::testGet6ByClientId() {
 
 void
 GenericHostDataSourceTest::testSubnetId6(int subnets, Host::IdentifierType id) {
-
     // Make sure we have a pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -967,18 +977,18 @@ GenericHostDataSourceTest::testSubnetId6(int subnets, Host::IdentifierType id) {
 
     // Check that the reservations can be retrieved from each subnet separately.
     for (int i = 0; i < subnets; ++i) {
-
         // Try to retrieve the host
-        ConstHostPtr from_hds = hdsptr_->get6(i + 1000, id, &host->getIdentifier()[0],
-                                              host->getIdentifier().size());
+        ConstHostPtr from_hds =
+            hdsptr_->get6(i + 1000, id, &host->getIdentifier()[0],
+                          host->getIdentifier().size());
 
         ASSERT_TRUE(from_hds) << "failed for i=" << i;
         EXPECT_EQ(i + 1000, from_hds->getIPv6SubnetID());
     }
 
     // Check that the hosts can all be retrieved by HW address or DUID
-    ConstHostCollection all_by_id = hdsptr_->getAll(id, &host->getIdentifier()[0],
-                                                    host->getIdentifier().size());
+    ConstHostCollection all_by_id = hdsptr_->getAll(
+        id, &host->getIdentifier()[0], host->getIdentifier().size());
     ASSERT_EQ(subnets, all_by_id.size());
 
     // Check that the returned values are as expected.
@@ -995,8 +1005,8 @@ GenericHostDataSourceTest::testSubnetId6(int subnets, Host::IdentifierType id) {
     }
 }
 
-void GenericHostDataSourceTest::testGetByIPv6(Host::IdentifierType id,
-                                              bool prefix) {
+void
+GenericHostDataSourceTest::testGetByIPv6(Host::IdentifierType id, bool prefix) {
     // Make sure we have a pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -1038,7 +1048,8 @@ void GenericHostDataSourceTest::testGetByIPv6(Host::IdentifierType id,
     EXPECT_FALSE(hdsptr_->get6(IOAddress("2001:db8::5"), len));
 }
 
-void GenericHostDataSourceTest::testGetBySubnetIPv6() {
+void
+GenericHostDataSourceTest::testGetBySubnetIPv6() {
     // Make sure we have a pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -1055,14 +1066,14 @@ void GenericHostDataSourceTest::testGetBySubnetIPv6() {
     ASSERT_NO_THROW(hdsptr_->add(host4));
 
     // And then try to retrieve them back.
-    ConstHostPtr from_hds1 = hdsptr_->get6(host1->getIPv6SubnetID(),
-                                           IOAddress("2001:db8:1::"));
-    ConstHostPtr from_hds2 = hdsptr_->get6(host2->getIPv6SubnetID(),
-                                           IOAddress("2001:db8:2::"));
-    ConstHostPtr from_hds3 = hdsptr_->get6(host3->getIPv6SubnetID(),
-                                           IOAddress("2001:db8:3::"));
-    ConstHostPtr from_hds4 = hdsptr_->get6(host4->getIPv6SubnetID(),
-                                           IOAddress("2001:db8:4::"));
+    ConstHostPtr from_hds1 =
+        hdsptr_->get6(host1->getIPv6SubnetID(), IOAddress("2001:db8:1::"));
+    ConstHostPtr from_hds2 =
+        hdsptr_->get6(host2->getIPv6SubnetID(), IOAddress("2001:db8:2::"));
+    ConstHostPtr from_hds3 =
+        hdsptr_->get6(host3->getIPv6SubnetID(), IOAddress("2001:db8:3::"));
+    ConstHostPtr from_hds4 =
+        hdsptr_->get6(host4->getIPv6SubnetID(), IOAddress("2001:db8:4::"));
 
     // Make sure we got something back.
     ASSERT_TRUE(from_hds1);
@@ -1077,8 +1088,8 @@ void GenericHostDataSourceTest::testGetBySubnetIPv6() {
     compareHosts(host4, from_hds4);
 }
 
-
-void GenericHostDataSourceTest::testAddDuplicate6WithSameDUID() {
+void
+GenericHostDataSourceTest::testAddDuplicate6WithSameDUID() {
     // Make sure we have the pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -1092,7 +1103,8 @@ void GenericHostDataSourceTest::testAddDuplicate6WithSameDUID() {
     ASSERT_THROW(hdsptr_->add(host), DuplicateEntry);
 }
 
-void GenericHostDataSourceTest::testAddDuplicate6WithSameHWAddr() {
+void
+GenericHostDataSourceTest::testAddDuplicate6WithSameHWAddr() {
     // Make sure we have the pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -1106,7 +1118,8 @@ void GenericHostDataSourceTest::testAddDuplicate6WithSameHWAddr() {
     ASSERT_THROW(hdsptr_->add(host), DuplicateEntry);
 }
 
-void GenericHostDataSourceTest::testAddDuplicate4() {
+void
+GenericHostDataSourceTest::testAddDuplicate4() {
     // Make sure we have the pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -1131,7 +1144,8 @@ void GenericHostDataSourceTest::testAddDuplicate4() {
     EXPECT_NO_THROW(hdsptr_->add(host));
 }
 
-void GenericHostDataSourceTest::testAddr6AndPrefix(){
+void
+GenericHostDataSourceTest::testAddr6AndPrefix() {
     // Make sure we have the pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
 
@@ -1146,10 +1160,9 @@ void GenericHostDataSourceTest::testAddr6AndPrefix(){
     ASSERT_NO_THROW(hdsptr_->add(host));
 
     // Get this host by DUID
-    ConstHostPtr from_hds = hdsptr_->get6(host->getIPv6SubnetID(),
-                                          Host::IDENT_DUID,
-                                          &host->getIdentifier()[0],
-                                          host->getIdentifier().size());
+    ConstHostPtr from_hds =
+        hdsptr_->get6(host->getIPv6SubnetID(), Host::IDENT_DUID,
+                      &host->getIdentifier()[0], host->getIdentifier().size());
 
     // Make sure we got something back
     ASSERT_TRUE(from_hds);
@@ -1159,7 +1172,8 @@ void GenericHostDataSourceTest::testAddr6AndPrefix(){
                          from_hds->getIPv6Reservations());
 }
 
-void GenericHostDataSourceTest::testMultipleReservations(){
+void
+GenericHostDataSourceTest::testMultipleReservations() {
     // Make sure we have the pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
     uint8_t len = 128;
@@ -1179,7 +1193,6 @@ void GenericHostDataSourceTest::testMultipleReservations(){
 
     ASSERT_NO_THROW(hdsptr_->add(host));
 
-
     ConstHostPtr from_hds = hdsptr_->get6(IOAddress("2001:db8::1"), len);
 
     // Make sure we got something back
@@ -1189,7 +1202,8 @@ void GenericHostDataSourceTest::testMultipleReservations(){
     compareHosts(host, from_hds);
 }
 
-void GenericHostDataSourceTest::testMultipleReservationsDifferentOrder(){
+void
+GenericHostDataSourceTest::testMultipleReservationsDifferentOrder() {
     // Make sure we have the pointer to the host data source.
     ASSERT_TRUE(hdsptr_);
     uint8_t len = 128;
@@ -1214,11 +1228,12 @@ void GenericHostDataSourceTest::testMultipleReservationsDifferentOrder(){
     host2->addReservation(resv1);
 
     // Check if reservations are the same
-    compareReservations6(host1->getIPv6Reservations(), host2->getIPv6Reservations());
-
+    compareReservations6(host1->getIPv6Reservations(),
+                         host2->getIPv6Reservations());
 }
 
-void GenericHostDataSourceTest::testOptionsReservations4(const bool formatted) {
+void
+GenericHostDataSourceTest::testOptionsReservations4(const bool formatted) {
     HostPtr host = initializeHost4("192.0.2.5", Host::IDENT_HWADDR);
     // Add a bunch of DHCPv4 and DHCPv6 options for the host.
     ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP4_ONLY));
@@ -1228,23 +1243,25 @@ void GenericHostDataSourceTest::testOptionsReservations4(const bool formatted) {
     SubnetID subnet_id = host->getIPv4SubnetID();
 
     // getAll4(address)
-    ConstHostCollection hosts_by_addr = hdsptr_->getAll4(host->getIPv4Reservation());
+    ConstHostCollection hosts_by_addr =
+        hdsptr_->getAll4(host->getIPv4Reservation());
     ASSERT_EQ(1, hosts_by_addr.size());
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_addr.begin()));
 
     // get4(subnet_id, identifier_type, identifier, identifier_size)
-    ConstHostPtr host_by_id = hdsptr_->get4(subnet_id,
-                                            host->getIdentifierType(),
-                                            &host->getIdentifier()[0],
-                                            host->getIdentifier().size());
+    ConstHostPtr host_by_id =
+        hdsptr_->get4(subnet_id, host->getIdentifierType(),
+                      &host->getIdentifier()[0], host->getIdentifier().size());
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_id));
 
     // get4(subnet_id, address)
-    ConstHostPtr host_by_addr = hdsptr_->get4(subnet_id, IOAddress("192.0.2.5"));
+    ConstHostPtr host_by_addr =
+        hdsptr_->get4(subnet_id, IOAddress("192.0.2.5"));
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_addr));
 }
 
-void GenericHostDataSourceTest::testOptionsReservations6(const bool formatted) {
+void
+GenericHostDataSourceTest::testOptionsReservations6(const bool formatted) {
     HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, false);
     // Add a bunch of DHCPv4 and DHCPv6 options for the host.
     ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP6_ONLY));
@@ -1254,9 +1271,9 @@ void GenericHostDataSourceTest::testOptionsReservations6(const bool formatted) {
     SubnetID subnet_id = host->getIPv6SubnetID();
 
     // get6(subnet_id, identifier_type, identifier, identifier_size)
-    ConstHostPtr host_by_id = hdsptr_->get6(subnet_id, host->getIdentifierType(),
-                                            &host->getIdentifier()[0],
-                                            host->getIdentifier().size());
+    ConstHostPtr host_by_id =
+        hdsptr_->get6(subnet_id, host->getIdentifierType(),
+                      &host->getIdentifier()[0], host->getIdentifier().size());
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_id));
 
     // get6(address, prefix_len)
@@ -1264,7 +1281,8 @@ void GenericHostDataSourceTest::testOptionsReservations6(const bool formatted) {
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_addr));
 }
 
-void GenericHostDataSourceTest::testOptionsReservations46(const bool formatted) {
+void
+GenericHostDataSourceTest::testOptionsReservations46(const bool formatted) {
     HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_HWADDR, false);
 
     // Add a bunch of DHCPv4 and DHCPv6 options for the host.
@@ -1273,9 +1291,9 @@ void GenericHostDataSourceTest::testOptionsReservations46(const bool formatted)
     ASSERT_NO_THROW(hdsptr_->add(host));
 
     // getAll(identifier_type, identifier, identifier_size)
-    ConstHostCollection hosts_by_id = hdsptr_->getAll(host->getIdentifierType(),
-                                                      &host->getIdentifier()[0],
-                                                      host->getIdentifier().size());
+    ConstHostCollection hosts_by_id =
+        hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
+                        host->getIdentifier().size());
     ASSERT_EQ(1, hosts_by_id.size());
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
 }
@@ -1309,8 +1327,9 @@ GenericHostDataSourceTest::testMultipleClientClasses4() {
     // Fetch the host via:
     // getAll(const Host::IdentifierType, const uint8_t* identifier_begin,
     //       const size_t identifier_len) const;
-    hosts_by_id = hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
-                                  host->getIdentifier().size());
+    hosts_by_id =
+        hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
+                        host->getIdentifier().size());
     ASSERT_EQ(1, hosts_by_id.size());
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
 
@@ -1328,10 +1347,12 @@ GenericHostDataSourceTest::testMultipleClientClasses4() {
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
 
     // Fetch the host via
-    // get4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
+    // get4(const SubnetID& subnet_id, const Host::IdentifierType&
+    // identifier_type,
     //     const uint8_t* identifier_begin, const size_t identifier_len) const;
-    from_hds = hdsptr_->get4(subnet_id, host->getIdentifierType(), &host->getIdentifier()[0],
-                             host->getIdentifier().size());
+    from_hds =
+        hdsptr_->get4(subnet_id, host->getIdentifierType(),
+                      &host->getIdentifier()[0], host->getIdentifier().size());
     ASSERT_TRUE(from_hds);
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
 
@@ -1371,23 +1392,26 @@ GenericHostDataSourceTest::testMultipleClientClasses6() {
     // getAll(const Host::IdentifierType& identifier_type,
     //        const uint8_t* identifier_begin,
     //        const size_t identifier_len) const;
-    hosts_by_id = hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
-                                  host->getIdentifier().size());
+    hosts_by_id =
+        hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
+                        host->getIdentifier().size());
     ASSERT_EQ(1, hosts_by_id.size());
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
 
     // get6(const SubnetID& subnet_id, const DuidPtr& duid,
     //      const HWAddrPtr& hwaddr = HWAddrPtr()) const;
-    ConstHostPtr from_hds = hdsptr_->get6(subnet_id, DuidPtr(), host->getHWAddress());
+    ConstHostPtr from_hds =
+        hdsptr_->get6(subnet_id, DuidPtr(), host->getHWAddress());
     ASSERT_TRUE(from_hds);
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
 
     // Fetch the host via:
-    // get6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
+    // get6(const SubnetID& subnet_id, const Host::IdentifierType&
+    // identifier_type,
     //     const uint8_t* identifier_begin, const size_t identifier_len) const;
-    from_hds = hdsptr_->get6(subnet_id, Host::IDENT_HWADDR,
-                                           &host->getIdentifier()[0],
-                                           host->getIdentifier().size());
+    from_hds =
+        hdsptr_->get6(subnet_id, Host::IDENT_HWADDR, &host->getIdentifier()[0],
+                      host->getIdentifier().size());
     ASSERT_TRUE(from_hds);
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
 
@@ -1429,9 +1453,9 @@ GenericHostDataSourceTest::testMultipleClientClassesBoth() {
     SubnetID subnet_id = host->getIPv6SubnetID();
 
     // Fetch the host from the source.
-    ConstHostPtr from_hds = hdsptr_->get6(subnet_id, Host::IDENT_HWADDR,
-                                           &host->getIdentifier()[0],
-                                           host->getIdentifier().size());
+    ConstHostPtr from_hds =
+        hdsptr_->get6(subnet_id, Host::IDENT_HWADDR, &host->getIdentifier()[0],
+                      host->getIdentifier().size());
     ASSERT_TRUE(from_hds);
 
     // Verify they match.
@@ -1466,8 +1490,9 @@ GenericHostDataSourceTest::testMessageFields4() {
     // Fetch the host via:
     // getAll(const Host::IdentifierType, const uint8_t* identifier_begin,
     //       const size_t identifier_len) const;
-    hosts_by_id = hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
-                                  host->getIdentifier().size());
+    hosts_by_id =
+        hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
+                        host->getIdentifier().size());
     ASSERT_EQ(1, hosts_by_id.size());
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
 
@@ -1485,10 +1510,12 @@ GenericHostDataSourceTest::testMessageFields4() {
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
 
     // Fetch the host via
-    // get4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
+    // get4(const SubnetID& subnet_id, const Host::IdentifierType&
+    // identifier_type,
     //     const uint8_t* identifier_begin, const size_t identifier_len) const;
-    from_hds = hdsptr_->get4(subnet_id, host->getIdentifierType(), &host->getIdentifier()[0],
-                             host->getIdentifier().size());
+    from_hds =
+        hdsptr_->get4(subnet_id, host->getIdentifierType(),
+                      &host->getIdentifier()[0], host->getIdentifier().size());
     ASSERT_TRUE(from_hds);
     ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
 
@@ -1694,4 +1721,3 @@ void GenericHostDataSourceTest::testDeleteById6Options() {
 }  // namespace test
 }  // namespace dhcp
 }  // namespace isc
-
index 3ce890956d287fc999ff97ded1e2e0b292232f2c..49f0c7277cc9e8912deeb2735c23edba7a2ecfda 100644 (file)
@@ -86,6 +86,13 @@ public:
     /// @return Identifier in textual form acceptable by Host constructor
     std::vector<uint8_t> generateIdentifier(const bool new_identifier = true);
 
+    /// @brief Checks if the reservation is in the range of reservations.
+    ///
+    /// @param resrv Reservation to be searched for.
+    /// @param range Range of reservations returned by the @c Host object
+    /// in which the reservation will be searched
+    bool reservationExists(const IPv6Resrv& resrv, const IPv6ResrvRange& range);
+
     /// @brief Compares hardware addresses of the two hosts.
     ///
     /// This method compares two hardware address and uses gtest
@@ -122,11 +129,11 @@ public:
     /// @param host2 second host to compare
     void compareHosts(const ConstHostPtr& host1, const ConstHostPtr& host2);
 
-    /// @ brief Used to sort a host collection by IPv4 subnet id.
+    /// @brief Used to sort a host collection by IPv4 subnet id.
     static bool compareHostsForSort4(const ConstHostPtr& host1,
                                      const ConstHostPtr& host2);
 
-    /// @ brief Used to sort a host collection by IPv6 subnet id.
+    /// @brief Used to sort a host collection by IPv6 subnet id.
     static bool compareHostsForSort6(const ConstHostPtr& host1,
                                      const ConstHostPtr& host2);
 
@@ -434,7 +441,7 @@ public:
     void testClientIdNotHWAddr();
 
     /// @brief Test adds specified number of hosts with unique hostnames, then
-    /// retrieves them and checks that the hostnames are set properly.
+    /// retrives them and checks that the hostnames are set properly.
     ///
     /// Uses gtest macros to report failures.
     ///