]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
added exchanges on the stack
authorRazvan Becheriu <razvan@isc.org>
Wed, 3 Apr 2019 16:30:27 +0000 (19:30 +0300)
committerRazvan Becheriu <razvan@isc.org>
Fri, 12 Apr 2019 12:10:41 +0000 (15:10 +0300)
src/hooks/dhcp/mysql_cb/mysql_cb_impl.cc
src/lib/dhcpsrv/mysql_host_data_source.cc
src/lib/dhcpsrv/mysql_lease_mgr.cc
src/lib/dhcpsrv/mysql_lease_mgr.h
src/lib/dhcpsrv/pgsql_host_data_source.cc
src/lib/dhcpsrv/pgsql_lease_mgr.cc
src/lib/dhcpsrv/pgsql_lease_mgr.h
src/lib/mysql/mysql_connection.cc
src/lib/mysql/mysql_connection.h
src/lib/mysql/tests/mysql_connection_unittest.cc

index 7ed30a279cdac6c6586952948e17437d22a2307c..40ebbdcb4849d19e987fcc4bb2329a34bfae7883 100644 (file)
@@ -57,18 +57,6 @@ MySqlConfigBackendImpl(const DatabaseConnection::ParameterMap& parameters)
                   << " found version:  " << db_version.first << "."
                   << db_version.second);
     } */
-
-    // Enable autocommit. In case transaction is explicitly used, this
-    // setting will be overwritten for the transaction. However, there are
-    // cases when lack of autocommit could cause transactions to hang
-    // until commit or rollback is explicitly called. This already
-    // caused issues for some unit tests which were unable to cleanup
-    // the database after the test because of pending transactions.
-    // Use of autocommit will eliminate this problem.
-    my_bool result = mysql_autocommit(conn_.mysql_, 1);
-    if (result != MLM_FALSE) {
-        isc_throw(DbOperationError, mysql_error(conn_.mysql_));
-    }
 }
 
 MySqlConfigBackendImpl::~MySqlConfigBackendImpl() {
index c53ee404226da432050e565bda3966e0fc9ddbf7..d5e562972b20da9f5cf674c1464c069cb3c0af23 100644 (file)
@@ -1948,6 +1948,10 @@ public:
         GET_HOST_SUBID_ADDR,    // Gets host by IPv4 SubnetID and IPv4 address
         GET_HOST_PREFIX,        // Gets host by IPv6 prefix
         GET_HOST_SUBID6_ADDR,   // Gets host by IPv6 SubnetID and IPv6 prefix
+        GET_HOST_SUBID4,        // Get hosts by IPv4 SubnetID
+        GET_HOST_SUBID6,        // Get hosts by IPv6 SubnetID
+        GET_HOST_SUBID4_PAGE,   // Get hosts by IPv4 SubnetID beginning by HID
+        GET_HOST_SUBID6_PAGE,   // Get hosts by IPv6 SubnetID beginning by HID
         INSERT_HOST,            // Insert new host to collection
         INSERT_V6_RESRV,        // Insert v6 reservation
         INSERT_V4_OPTION,       // Insert DHCPv4 option
@@ -1955,10 +1959,6 @@ public:
         DEL_HOST_ADDR4,         // Delete v4 host (subnet-id, addr4)
         DEL_HOST_SUBID4_ID,     // Delete v4 host (subnet-id, ident.type, identifier)
         DEL_HOST_SUBID6_ID,     // Delete v6 host (subnet-id, ident.type, identifier)
-        GET_HOST_SUBID4,        // Get hosts by IPv4 SubnetID
-        GET_HOST_SUBID6,        // Get hosts by IPv6 SubnetID
-        GET_HOST_SUBID4_PAGE,   // Get hosts by IPv4 SubnetID beginning by HID
-        GET_HOST_SUBID6_PAGE,   // Get hosts by IPv6 SubnetID beginning by HID
         NUM_STATEMENTS          // Number of statements
     };
 
@@ -2107,28 +2107,6 @@ public:
     /// @throw DbReadOnly if backend is operating in read only mode.
     void checkReadOnly() const;
 
-    /// @brief Pointer to the object representing an exchange which
-    /// can be used to retrieve hosts and DHCPv4 options.
-    boost::shared_ptr<MySqlHostWithOptionsExchange> host_exchange_;
-
-    /// @brief Pointer to an object representing an exchange which can
-    /// be used to retrieve hosts, DHCPv6 options and IPv6 reservations.
-    boost::shared_ptr<MySqlHostIPv6Exchange> host_ipv6_exchange_;
-
-    /// @brief Pointer to an object representing an exchange which can
-    /// be used to retrieve hosts, DHCPv4 and DHCPv6 options, and
-    /// IPv6 reservations using a single query.
-    boost::shared_ptr<MySqlHostIPv6Exchange> host_ipv46_exchange_;
-
-    /// @brief Pointer to an object representing an exchange which can
-    /// be used to insert new IPv6 reservation.
-    boost::shared_ptr<MySqlIPv6ReservationExchange> host_ipv6_reservation_exchange_;
-
-    /// @brief Pointer to an object representing an exchange which can
-    /// be used to insert DHCPv4 or DHCPv6 option into dhcp4_options
-    /// or dhcp6_options table.
-    boost::shared_ptr<MySqlOptionExchange> host_option_exchange_;
-
     /// @brief MySQL connection
     MySqlConnection conn_;
 
@@ -2440,13 +2418,7 @@ TaggedStatementArray tagged_statements = { {
 
 MySqlHostDataSourceImpl::
 MySqlHostDataSourceImpl(const MySqlConnection::ParameterMap& parameters)
-    : host_exchange_(new MySqlHostWithOptionsExchange(MySqlHostWithOptionsExchange::DHCP4_ONLY)),
-      host_ipv6_exchange_(new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP6_ONLY)),
-      host_ipv46_exchange_(new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::
-                                                     DHCP4_AND_DHCP6)),
-      host_ipv6_reservation_exchange_(new MySqlIPv6ReservationExchange()),
-      host_option_exchange_(new MySqlOptionExchange()),
-      conn_(parameters),
+    : conn_(parameters),
       is_readonly_(false) {
 
     // Open the database.
@@ -2463,18 +2435,6 @@ MySqlHostDataSourceImpl(const MySqlConnection::ParameterMap& parameters)
                   << db_version.second);
     }
 
-    // Enable autocommit. In case transaction is explicitly used, this
-    // setting will be overwritten for the transaction. However, there are
-    // cases when lack of autocommit could cause transactions to hang
-    // until commit or rollback is explicitly called. This already
-    // caused issues for some unit tests which were unable to cleanup
-    // the database after the test because of pending transactions.
-    // Use of autocommit will eliminate this problem.
-    my_bool result = mysql_autocommit(conn_.mysql_, 1);
-    if (result != 0) {
-        isc_throw(DbOperationError, mysql_error(conn_.mysql_));
-    }
-
     // Prepare query statements. Those are will be only used to retrieve
     // information from the database, so they can be used even if the
     // database is read only for the current user.
@@ -2614,8 +2574,11 @@ MySqlHostDataSourceImpl::delStatement(StatementIndex stindex,
 void
 MySqlHostDataSourceImpl::addResv(const IPv6Resrv& resv,
                                  const HostID& id) {
+    boost::shared_ptr<MySqlIPv6ReservationExchange> host_ipv6_reservation_exchange(
+            new MySqlIPv6ReservationExchange());
+
     std::vector<MYSQL_BIND> bind =
-        host_ipv6_reservation_exchange_->createBindForSend(resv, id);
+        host_ipv6_reservation_exchange->createBindForSend(resv, id);
 
     addStatement(INSERT_V6_RESRV, bind);
 }
@@ -2626,8 +2589,10 @@ MySqlHostDataSourceImpl::addOption(const StatementIndex& stindex,
                                    const std::string& opt_space,
                                    const Optional<SubnetID>& subnet_id,
                                    const HostID& id) {
+    boost::shared_ptr<MySqlOptionExchange> host_option_exchange(new MySqlOptionExchange());
+
     std::vector<MYSQL_BIND> bind =
-        host_option_exchange_->createBindForSend(opt_desc, opt_space,
+        host_option_exchange->createBindForSend(opt_desc, opt_space,
                                                  subnet_id, id);
 
     addStatement(stindex, bind);
@@ -2766,8 +2731,9 @@ getHost(const SubnetID& subnet_id,
 
     // Return single record if present, else clear the host.
     ConstHostPtr result;
-    if (!collection.empty())
+    if (!collection.empty()) {
         result = *collection.begin();
+    }
 
     return (result);
 }
@@ -2794,6 +2760,9 @@ MySqlHostDataSource::add(const HostPtr& host) {
     // If operating in read-only mode, throw exception.
     impl_->checkReadOnly();
 
+    boost::shared_ptr<MySqlHostWithOptionsExchange> host_ipv4_exchange(
+            new MySqlHostWithOptionsExchange(MySqlHostWithOptionsExchange::DHCP4_ONLY));
+
     // Initiate MySQL transaction as we will have to make multiple queries
     // to insert host information into multiple tables. If that fails on
     // any stage, the transaction will be rolled back by the destructor of
@@ -2801,7 +2770,7 @@ MySqlHostDataSource::add(const HostPtr& host) {
     MySqlTransaction transaction(impl_->conn_);
 
     // Create the MYSQL_BIND array for the host
-    std::vector<MYSQL_BIND> bind = impl_->host_exchange_->createBindForSend(host);
+    std::vector<MYSQL_BIND> bind = host_ipv4_exchange->createBindForSend(host);
 
     // ... and insert the host.
     impl_->addStatement(MySqlHostDataSourceImpl::INSERT_HOST, bind);
@@ -2947,6 +2916,9 @@ ConstHostCollection
 MySqlHostDataSource::getAll(const Host::IdentifierType& identifier_type,
                             const uint8_t* identifier_begin,
                             const size_t identifier_len) const {
+    boost::shared_ptr<MySqlHostIPv6Exchange> host_ipv46_exchange(
+            new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP4_AND_DHCP6));
+
     // Set up the WHERE clause value
     MYSQL_BIND inbind[2];
     memset(inbind, 0, sizeof(inbind));
@@ -2968,13 +2940,15 @@ MySqlHostDataSource::getAll(const Host::IdentifierType& identifier_type,
 
     ConstHostCollection result;
     impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_DHCPID, inbind,
-                             impl_->host_ipv46_exchange_,
-                             result, false);
+                             host_ipv46_exchange, result, false);
     return (result);
 }
 
 ConstHostCollection
 MySqlHostDataSource::getAll4(const SubnetID& subnet_id) const {
+    boost::shared_ptr<MySqlHostWithOptionsExchange> host_ipv4_exchange(
+            new MySqlHostWithOptionsExchange(MySqlHostWithOptionsExchange::DHCP4_ONLY));
+
     // Set up the WHERE clause value
     MYSQL_BIND inbind[1];
     memset(inbind, 0, sizeof(inbind));
@@ -2985,13 +2959,15 @@ MySqlHostDataSource::getAll4(const SubnetID& subnet_id) const {
 
     ConstHostCollection result;
     impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_SUBID4,
-                             inbind, impl_->host_exchange_,
-                             result, false);
+                             inbind, host_ipv4_exchange, result, false);
     return (result);
 }
 
 ConstHostCollection
 MySqlHostDataSource::getAll6(const SubnetID& subnet_id) const {
+    boost::shared_ptr<MySqlHostIPv6Exchange> host_ipv6_exchange(
+            new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP6_ONLY));
+
     // Set up the WHERE clause value
     MYSQL_BIND inbind[1];
     memset(inbind, 0, sizeof(inbind));
@@ -3002,8 +2978,7 @@ MySqlHostDataSource::getAll6(const SubnetID& subnet_id) const {
 
     ConstHostCollection result;
     impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_SUBID6,
-                             inbind, impl_->host_ipv6_exchange_,
-                             result, false);
+                             inbind, host_ipv6_exchange, result, false);
     return (result);
 }
 
@@ -3012,6 +2987,9 @@ MySqlHostDataSource::getPage4(const SubnetID& subnet_id,
                               size_t& /*source_index*/,
                               uint64_t lower_host_id,
                               const HostPageSize& page_size) const {
+    boost::shared_ptr<MySqlHostWithOptionsExchange> host_ipv4_exchange(
+            new MySqlHostWithOptionsExchange(MySqlHostWithOptionsExchange::DHCP4_ONLY));
+
     // Set up the WHERE clause value
     MYSQL_BIND inbind[3];
     memset(inbind, 0, sizeof(inbind));
@@ -3036,8 +3014,7 @@ MySqlHostDataSource::getPage4(const SubnetID& subnet_id,
 
     ConstHostCollection result;
     impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_SUBID4_PAGE,
-                             inbind, impl_->host_exchange_,
-                             result, false);
+                             inbind, host_ipv4_exchange, result, false);
     return (result);
 }
 
@@ -3046,6 +3023,9 @@ MySqlHostDataSource::getPage6(const SubnetID& subnet_id,
                               size_t& /*source_index*/,
                               uint64_t lower_host_id,
                               const HostPageSize& page_size) const {
+    boost::shared_ptr<MySqlHostIPv6Exchange> host_ipv6_exchange(
+            new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP6_ONLY));
+
     // Set up the WHERE clause value
     MYSQL_BIND inbind[3];
     memset(inbind, 0, sizeof(inbind));
@@ -3070,13 +3050,14 @@ MySqlHostDataSource::getPage6(const SubnetID& subnet_id,
 
     ConstHostCollection result;
     impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_SUBID6_PAGE,
-                             inbind, impl_->host_ipv6_exchange_,
-                             result, false);
+                             inbind, host_ipv6_exchange, result, false);
     return (result);
 }
 
 ConstHostCollection
 MySqlHostDataSource::getAll4(const asiolink::IOAddress& address) const {
+    boost::shared_ptr<MySqlHostWithOptionsExchange> host_ipv4_exchange(
+            new MySqlHostWithOptionsExchange(MySqlHostWithOptionsExchange::DHCP4_ONLY));
 
     // Set up the WHERE clause value
     MYSQL_BIND inbind[1];
@@ -3088,8 +3069,8 @@ MySqlHostDataSource::getAll4(const asiolink::IOAddress& address) const {
     inbind[0].is_unsigned = MLM_TRUE;
 
     ConstHostCollection result;
-    impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_ADDR, inbind,
-                             impl_->host_exchange_, result, false);
+    impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_ADDR,
+                             inbind, host_ipv4_exchange, result, false);
 
     return (result);
 }
@@ -3099,21 +3080,25 @@ MySqlHostDataSource::get4(const SubnetID& subnet_id,
                           const Host::IdentifierType& identifier_type,
                           const uint8_t* identifier_begin,
                           const size_t identifier_len) const {
+    boost::shared_ptr<MySqlHostWithOptionsExchange> host_ipv4_exchange(
+            new MySqlHostWithOptionsExchange(MySqlHostWithOptionsExchange::DHCP4_ONLY));
 
     return (impl_->getHost(subnet_id, identifier_type, identifier_begin,
                    identifier_len, MySqlHostDataSourceImpl::GET_HOST_SUBID4_DHCPID,
-                   impl_->host_exchange_));
+                   host_ipv4_exchange));
 }
 
 ConstHostPtr
 MySqlHostDataSource::get4(const SubnetID& subnet_id,
                           const asiolink::IOAddress& address) const {
-    // Check that address is IPv4, not IPv6.
     if (!address.isV4()) {
-        isc_throw(BadValue, "MySqlHostDataSource::get4(2): wrong address type, "
-                            "address supplied is not an IPv4 address");
+        isc_throw(BadValue, "MySqlHostDataSource::get4(id, address): "
+                  "wrong address type, address supplied is an IPv6 address");
     }
 
+    boost::shared_ptr<MySqlHostWithOptionsExchange> host_ipv4_exchange(
+            new MySqlHostWithOptionsExchange(MySqlHostWithOptionsExchange::DHCP4_ONLY));
+
     // Set up the WHERE clause value
     MYSQL_BIND inbind[2];
     uint32_t subnet = subnet_id;
@@ -3129,12 +3114,13 @@ MySqlHostDataSource::get4(const SubnetID& subnet_id,
 
     ConstHostCollection collection;
     impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_SUBID_ADDR,
-                             inbind, impl_->host_exchange_, collection, true);
+                             inbind, host_ipv4_exchange, collection, true);
 
     // Return single record if present, else clear the host.
     ConstHostPtr result;
-    if (!collection.empty())
+    if (!collection.empty()) {
         result = *collection.begin();
+    }
 
     return (result);
 }
@@ -3144,16 +3130,24 @@ MySqlHostDataSource::get6(const SubnetID& subnet_id,
                           const Host::IdentifierType& identifier_type,
                           const uint8_t* identifier_begin,
                           const size_t identifier_len) const {
+    boost::shared_ptr<MySqlHostIPv6Exchange> host_ipv6_exchange(
+            new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP6_ONLY));
 
     return (impl_->getHost(subnet_id, identifier_type, identifier_begin,
                    identifier_len, MySqlHostDataSourceImpl::GET_HOST_SUBID6_DHCPID,
-                   impl_->host_ipv6_exchange_));
+                   host_ipv6_exchange));
 }
 
 ConstHostPtr
 MySqlHostDataSource::get6(const asiolink::IOAddress& prefix,
                           const uint8_t prefix_len) const {
-    /// @todo: Check that prefix is v6 address, not v4.
+    if (!prefix.isV6()) {
+        isc_throw(BadValue, "MySqlHostDataSource::get6(prefix, prefix_len): "
+                  "wrong address type, address supplied is an IPv4 address");
+    }
+
+    boost::shared_ptr<MySqlHostIPv6Exchange> host_ipv6_exchange(
+            new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP6_ONLY));
 
     // Set up the WHERE clause value
     MYSQL_BIND inbind[2];
@@ -3175,8 +3169,7 @@ MySqlHostDataSource::get6(const asiolink::IOAddress& prefix,
 
     ConstHostCollection collection;
     impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_PREFIX,
-                             inbind, impl_->host_ipv6_exchange_,
-                             collection, true);
+                             inbind, host_ipv6_exchange, collection, true);
 
     // Return single record if present, else clear the host.
     ConstHostPtr result;
@@ -3190,6 +3183,14 @@ MySqlHostDataSource::get6(const asiolink::IOAddress& prefix,
 ConstHostPtr
 MySqlHostDataSource::get6(const SubnetID& subnet_id,
                           const asiolink::IOAddress& address) const {
+    if (!address.isV6()) {
+        isc_throw(BadValue, "MySqlHostDataSource::get6(id, address): "
+                  "wrong address type, address supplied is an IPv4 address");
+    }
+
+    boost::shared_ptr<MySqlHostIPv6Exchange> host_ipv6_exchange(
+            new MySqlHostIPv6Exchange(MySqlHostWithOptionsExchange::DHCP6_ONLY));
+
     // Set up the WHERE clause value
     MYSQL_BIND inbind[2];
     memset(inbind, 0, sizeof(inbind));
@@ -3210,8 +3211,7 @@ MySqlHostDataSource::get6(const SubnetID& subnet_id,
 
     ConstHostCollection collection;
     impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_SUBID6_ADDR,
-                             inbind, impl_->host_ipv6_exchange_,
-                             collection, true);
+                             inbind, host_ipv6_exchange, collection, true);
 
     // Return single record if present, else clear the host.
     ConstHostPtr result;
index ef41e92e04c80aa7eb8bba85e0cd5efd67fc8b06..8869dcd6e980cffb3a02e0690e5834a6836ba693 100644 (file)
@@ -1679,30 +1679,14 @@ MySqlLeaseMgr::MySqlLeaseMgr(const MySqlConnection::ParameterMap& parameters)
                                                MYSQL_SCHEMA_VERSION_MINOR);
     std::pair<uint32_t, uint32_t> db_version = getVersion();
     if (code_version != db_version) {
-        isc_throw(DbOpenError,
-                  "MySQL schema version mismatch: need version: "
-                      << code_version.first << "." << code_version.second
-                      << " found version:  " << db_version.first << "."
-                      << db_version.second);
-    }
-
-    // Enable autocommit.  To avoid a flush to disk on every commit, the global
-    // parameter innodb_flush_log_at_trx_commit should be set to 2.  This will
-    // cause the changes to be written to the log, but flushed to disk in the
-    // background every second.  Setting the parameter to that value will speed
-    // up the system, but at the risk of losing data if the system crashes.
-    my_bool result = mysql_autocommit(conn_.mysql_, 1);
-    if (result != 0) {
-        isc_throw(DbOperationError, mysql_error(conn_.mysql_));
+        isc_throw(DbOpenError, "MySQL schema version mismatch: need version: "
+                  << code_version.first << "." << code_version.second
+                  << " found version:  " << db_version.first << "."
+                  << db_version.second);
     }
 
     // Prepare all statements likely to be used.
     conn_.prepareStatements(tagged_statements.begin(), tagged_statements.end());
-
-    // Create the exchange objects for use in exchanging data between the
-    // program and the database.
-    exchange4_.reset(new MySqlLease4Exchange());
-    exchange6_.reset(new MySqlLease6Exchange());
 }
 
 MySqlLeaseMgr::~MySqlLeaseMgr() {
@@ -1750,11 +1734,13 @@ MySqlLeaseMgr::addLeaseCommon(StatementIndex stindex,
 
 bool
 MySqlLeaseMgr::addLease(const Lease4Ptr& lease) {
+    boost::scoped_ptr<MySqlLease4Exchange> exchange4(new MySqlLease4Exchange());
+
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_MYSQL_ADD_ADDR4).arg(lease->addr_.toText());
 
     // Create the MYSQL_BIND array for the lease
-    std::vector<MYSQL_BIND> bind = exchange4_->createBindForSend(lease);
+    std::vector<MYSQL_BIND> bind = exchange4->createBindForSend(lease);
 
     // ... and drop to common code.
     return (addLeaseCommon(INSERT_LEASE4, bind));
@@ -1762,12 +1748,14 @@ MySqlLeaseMgr::addLease(const Lease4Ptr& lease) {
 
 bool
 MySqlLeaseMgr::addLease(const Lease6Ptr& lease) {
+    boost::scoped_ptr<MySqlLease6Exchange> exchange6(new MySqlLease6Exchange());
+
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_MYSQL_ADD_ADDR6).arg(lease->addr_.toText())
               .arg(lease->type_);
 
     // Create the MYSQL_BIND array for the lease
-    std::vector<MYSQL_BIND> bind = exchange6_->createBindForSend(lease);
+    std::vector<MYSQL_BIND> bind = exchange6->createBindForSend(lease);
 
     // ... and drop to common code.
     return (addLeaseCommon(INSERT_LEASE6, bind));
@@ -1862,15 +1850,29 @@ void MySqlLeaseMgr::getLeaseCollection(StatementIndex stindex,
     }
 }
 
+void MySqlLeaseMgr::getLeaseCollection(StatementIndex stindex, MYSQL_BIND* bind,
+                                       Lease4Collection& result) const {
+    boost::scoped_ptr<MySqlLease4Exchange> exchange4(new MySqlLease4Exchange());
+    getLeaseCollection(stindex, bind, exchange4, result);
+}
+
+void MySqlLeaseMgr::getLeaseCollection(StatementIndex stindex, MYSQL_BIND* bind,
+                                       Lease6Collection& result) const {
+    boost::scoped_ptr<MySqlLease6Exchange> exchange6(new MySqlLease6Exchange());
+    getLeaseCollection(stindex, bind, exchange6, result);
+}
+
 void MySqlLeaseMgr::getLease(StatementIndex stindex, MYSQL_BIND* bind,
                              Lease4Ptr& result) const {
+    boost::scoped_ptr<MySqlLease4Exchange> exchange4(new MySqlLease4Exchange());
+
     // Create appropriate collection object and get all leases matching
     // the selection criteria.  The "single" parameter is true to indicate
     // that the called method should throw an exception if multiple
     // matching records are found: this particular method is called when only
     // one or zero matches is expected.
     Lease4Collection collection;
-    getLeaseCollection(stindex, bind, exchange4_, collection, true);
+    getLeaseCollection(stindex, bind, exchange4, collection, true);
 
     // Return single record if present, else clear the lease.
     if (collection.empty()) {
@@ -1882,13 +1884,15 @@ void MySqlLeaseMgr::getLease(StatementIndex stindex, MYSQL_BIND* bind,
 
 void MySqlLeaseMgr::getLease(StatementIndex stindex, MYSQL_BIND* bind,
                              Lease6Ptr& result) const {
+    boost::scoped_ptr<MySqlLease6Exchange> exchange6(new MySqlLease6Exchange());
+
     // Create appropriate collection object and get all leases matching
     // the selection criteria.  The "single" parameter is true to indicate
     // that the called method should throw an exception if multiple
     // matching records are found: this particular method is called when only
     // one or zero matches is expected.
     Lease6Collection collection;
-    getLeaseCollection(stindex, bind, exchange6_, collection, true);
+    getLeaseCollection(stindex, bind, exchange6, collection, true);
 
     // Return single record if present, else clear the lease.
     if (collection.empty()) {
@@ -2463,13 +2467,15 @@ MySqlLeaseMgr::updateLeaseCommon(StatementIndex stindex, MYSQL_BIND* bind,
 
 void
 MySqlLeaseMgr::updateLease4(const Lease4Ptr& lease) {
+    boost::scoped_ptr<MySqlLease4Exchange> exchange4(new MySqlLease4Exchange());
+
     const StatementIndex stindex = UPDATE_LEASE4;
 
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_MYSQL_UPDATE_ADDR4).arg(lease->addr_.toText());
 
     // Create the MYSQL_BIND array for the data being updated
-    std::vector<MYSQL_BIND> bind = exchange4_->createBindForSend(lease);
+    std::vector<MYSQL_BIND> bind = exchange4->createBindForSend(lease);
 
     // Set up the WHERE clause and append it to the MYSQL_BIND array
     MYSQL_BIND where;
@@ -2487,6 +2493,8 @@ MySqlLeaseMgr::updateLease4(const Lease4Ptr& lease) {
 
 void
 MySqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
+    boost::scoped_ptr<MySqlLease6Exchange> exchange6(new MySqlLease6Exchange());
+
     const StatementIndex stindex = UPDATE_LEASE6;
 
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
@@ -2494,7 +2502,7 @@ MySqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
               .arg(lease->type_);
 
     // Create the MYSQL_BIND array for the data being updated
-    std::vector<MYSQL_BIND> bind = exchange6_->createBindForSend(lease);
+    std::vector<MYSQL_BIND> bind = exchange6->createBindForSend(lease);
 
     // Set up the WHERE clause value
     MYSQL_BIND where;
index a11009c8749c89748e76d82732614e898a20b5f4..e918e15512ac6bc614243a40bf56bd66b5deb187 100644 (file)
@@ -663,9 +663,7 @@ private:
     /// @throw isc::db::MultipleRecords Multiple records were retrieved
     ///        from the database where only one was expected.
     void getLeaseCollection(StatementIndex stindex, MYSQL_BIND* bind,
-                            Lease4Collection& result) const {
-        getLeaseCollection(stindex, bind, exchange4_, result);
-    }
+                            Lease4Collection& result) const;
 
     /// @brief Get Lease Collection
     ///
@@ -683,9 +681,7 @@ private:
     /// @throw isc::db::MultipleRecords Multiple records were retrieved
     ///        from the database where only one was expected.
     void getLeaseCollection(StatementIndex stindex, MYSQL_BIND* bind,
-                            Lease6Collection& result) const {
-        getLeaseCollection(stindex, bind, exchange6_, result);
-    }
+                            Lease6Collection& result) const;
 
     /// @brief Get Lease4 Common Code
     ///
@@ -793,15 +789,6 @@ private:
     void checkError(int status, StatementIndex index,
                     const char* what) const;
 
-    // Members
-
-    /// The exchange objects are used for transfer of data to/from the database.
-    /// They are pointed-to objects as the contents may change in "const" calls,
-    /// while the rest of this object does not.  (At alternative would be to
-    /// declare them as "mutable".)
-    boost::scoped_ptr<MySqlLease4Exchange> exchange4_; ///< Exchange object
-    boost::scoped_ptr<MySqlLease6Exchange> exchange6_; ///< Exchange object
-
     /// @brief MySQL connection
     db::MySqlConnection conn_;
 };
index 88e3070ea2061b462ed3bb80d5b6fd90cbc9aa7e..12db8f62674f2265f8823fed3038ec1e835124ea 100644 (file)
@@ -1286,6 +1286,10 @@ public:
         GET_HOST_SUBID_ADDR,    // Gets host by IPv4 SubnetID and IPv4 address
         GET_HOST_PREFIX,        // Gets host by IPv6 prefix
         GET_HOST_SUBID6_ADDR,   // Gets host by IPv6 SubnetID and IPv6 prefix
+        GET_HOST_SUBID4,        // Gets hosts by IPv4 SubnetID
+        GET_HOST_SUBID6,        // Gets hosts by IPv6 SubnetID
+        GET_HOST_SUBID4_PAGE,   // Gets hosts by IPv4 SubnetID beginning by HID
+        GET_HOST_SUBID6_PAGE,   // Gets hosts by IPv6 SubnetID beginning by HID
         INSERT_HOST,            // Insert new host to collection
         INSERT_V6_RESRV,        // Insert v6 reservation
         INSERT_V4_HOST_OPTION,  // Insert DHCPv4 option
@@ -1293,10 +1297,6 @@ public:
         DEL_HOST_ADDR4,         // Delete v4 host (subnet-id, addr4)
         DEL_HOST_SUBID4_ID,     // Delete v4 host (subnet-id, ident.type, identifier)
         DEL_HOST_SUBID6_ID,     // Delete v6 host (subnet-id, ident.type, identifier)
-        GET_HOST_SUBID4,        // Gets hosts by IPv4 SubnetID
-        GET_HOST_SUBID6,        // Gets hosts by IPv6 SubnetID
-        GET_HOST_SUBID4_PAGE,   // Gets hosts by IPv4 SubnetID beginning by HID
-        GET_HOST_SUBID6_PAGE,   // Gets hosts by IPv6 SubnetID beginning by HID
         NUM_STATEMENTS          // Number of statements
     };
 
@@ -1437,28 +1437,6 @@ public:
     ///        has failed.
     std::pair<uint32_t, uint32_t> getVersion() const;
 
-    /// @brief Pointer to the object representing an exchange which
-    /// can be used to retrieve hosts and DHCPv4 options.
-    boost::shared_ptr<PgSqlHostWithOptionsExchange> host_exchange_;
-
-    /// @brief Pointer to an object representing an exchange which can
-    /// be used to retrieve hosts, DHCPv6 options and IPv6 reservations.
-    boost::shared_ptr<PgSqlHostIPv6Exchange> host_ipv6_exchange_;
-
-    /// @brief Pointer to an object representing an exchange which can
-    /// be used to retrieve hosts, DHCPv4 and DHCPv6 options, and
-    /// IPv6 reservations using a single query.
-    boost::shared_ptr<PgSqlHostIPv6Exchange> host_ipv46_exchange_;
-
-    /// @brief Pointer to an object representing an exchange which can
-    /// be used to insert new IPv6 reservation.
-    boost::shared_ptr<PgSqlIPv6ReservationExchange> host_ipv6_reservation_exchange_;
-
-    /// @brief Pointer to an object representing an exchange which can
-    /// be used to insert DHCPv4 or DHCPv6 option into dhcp4_options
-    /// or dhcp6_options table.
-    boost::shared_ptr<PgSqlOptionExchange> host_option_exchange_;
-
     /// @brief PgSQL connection
     PgSqlConnection conn_;
 
@@ -1826,13 +1804,7 @@ TaggedStatementArray tagged_statements = { {
 
 PgSqlHostDataSourceImpl::
 PgSqlHostDataSourceImpl(const PgSqlConnection::ParameterMap& parameters)
-    : host_exchange_(new PgSqlHostWithOptionsExchange(PgSqlHostWithOptionsExchange::DHCP4_ONLY)),
-      host_ipv6_exchange_(new PgSqlHostIPv6Exchange(PgSqlHostWithOptionsExchange::DHCP6_ONLY)),
-      host_ipv46_exchange_(new PgSqlHostIPv6Exchange(PgSqlHostWithOptionsExchange::
-                                                     DHCP4_AND_DHCP6)),
-      host_ipv6_reservation_exchange_(new PgSqlIPv6ReservationExchange()),
-      host_option_exchange_(new PgSqlOptionExchange()),
-      conn_(parameters),
+    : conn_(parameters),
       is_readonly_(false) {
 
     // Open the database.
@@ -1933,8 +1905,12 @@ PgSqlHostDataSourceImpl::delStatement(StatementIndex stindex,
 void
 PgSqlHostDataSourceImpl::addResv(const IPv6Resrv& resv,
                                  const HostID& id) {
+    boost::shared_ptr<PgSqlIPv6ReservationExchange> host_ipv6_reservation_exchange(
+            new PgSqlIPv6ReservationExchange());
+
     PsqlBindArrayPtr bind_array;
-    bind_array = host_ipv6_reservation_exchange_->createBindForSend(resv, id);
+    bind_array = host_ipv6_reservation_exchange->createBindForSend(resv, id);
+
     addStatement(INSERT_V6_RESRV, bind_array);
 }
 
@@ -1944,9 +1920,11 @@ PgSqlHostDataSourceImpl::addOption(const StatementIndex& stindex,
                                    const std::string& opt_space,
                                    const Optional<SubnetID>&,
                                    const HostID& id) {
+    boost::shared_ptr<PgSqlOptionExchange> host_option_exchange(new PgSqlOptionExchange());
+
     PsqlBindArrayPtr bind_array;
-    bind_array = host_option_exchange_->createBindForSend(opt_desc, opt_space,
-                                                          id);
+    bind_array = host_option_exchange->createBindForSend(opt_desc, opt_space, id);
+
     addStatement(stindex, bind_array);
 }
 
@@ -2029,8 +2007,9 @@ getHost(const SubnetID& subnet_id,
 
     // Return single record if present, else clear the host.
     ConstHostPtr result;
-    if (!collection.empty())
+    if (!collection.empty()) {
         result = *collection.begin();
+    }
 
     return (result);
 }
@@ -2078,6 +2057,9 @@ PgSqlHostDataSource::add(const HostPtr& host) {
     // If operating in read-only mode, throw exception.
     impl_->checkReadOnly();
 
+    boost::shared_ptr<PgSqlHostWithOptionsExchange> host_ipv4_exchange(
+            new PgSqlHostWithOptionsExchange(PgSqlHostWithOptionsExchange::DHCP4_ONLY));
+
     // Initiate PostgreSQL transaction as we will have to make multiple queries
     // to insert host information into multiple tables. If that fails on
     // any stage, the transaction will be rolled back by the destructor of
@@ -2085,7 +2067,7 @@ PgSqlHostDataSource::add(const HostPtr& host) {
     PgSqlTransaction transaction(impl_->conn_);
 
     // Create the PgSQL Bind array for the host
-    PsqlBindArrayPtr bind_array = impl_->host_exchange_->createBindForSend(host);
+    PsqlBindArrayPtr bind_array = host_ipv4_exchange->createBindForSend(host);
 
     // ... and insert the host.
     uint32_t host_id = impl_->addStatement(PgSqlHostDataSourceImpl::INSERT_HOST,
@@ -2185,6 +2167,9 @@ ConstHostCollection
 PgSqlHostDataSource::getAll(const Host::IdentifierType& identifier_type,
                             const uint8_t* identifier_begin,
                             const size_t identifier_len) const {
+    boost::shared_ptr<PgSqlHostIPv6Exchange> host_ipv46_exchange(
+            new PgSqlHostIPv6Exchange(PgSqlHostWithOptionsExchange::DHCP4_AND_DHCP6));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2196,13 +2181,15 @@ PgSqlHostDataSource::getAll(const Host::IdentifierType& identifier_type,
 
     ConstHostCollection result;
     impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_DHCPID,
-                             bind_array, impl_->host_ipv46_exchange_,
-                             result, false);
+                             bind_array, host_ipv46_exchange, result, false);
     return (result);
 }
 
 ConstHostCollection
 PgSqlHostDataSource::getAll4(const SubnetID& subnet_id) const {
+    boost::shared_ptr<PgSqlHostWithOptionsExchange> host_ipv4_exchange(
+            new PgSqlHostWithOptionsExchange(PgSqlHostWithOptionsExchange::DHCP4_ONLY));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2211,14 +2198,16 @@ PgSqlHostDataSource::getAll4(const SubnetID& subnet_id) const {
 
     ConstHostCollection result;
     impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_SUBID4,
-                             bind_array, impl_->host_exchange_,
-                             result, false);
+                             bind_array, host_ipv4_exchange, result, false);
 
     return (result);
 }
 
 ConstHostCollection
 PgSqlHostDataSource::getAll6(const SubnetID& subnet_id) const {
+    boost::shared_ptr<PgSqlHostIPv6Exchange> host_ipv6_exchange(
+            new PgSqlHostIPv6Exchange(PgSqlHostWithOptionsExchange::DHCP6_ONLY));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2227,8 +2216,7 @@ PgSqlHostDataSource::getAll6(const SubnetID& subnet_id) const {
 
     ConstHostCollection result;
     impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_SUBID6,
-                             bind_array, impl_->host_ipv6_exchange_,
-                             result, false);
+                             bind_array, host_ipv6_exchange, result, false);
 
     return (result);
 }
@@ -2238,6 +2226,9 @@ PgSqlHostDataSource::getPage4(const SubnetID& subnet_id,
                               size_t& /*source_index*/,
                               uint64_t lower_host_id,
                               const HostPageSize& page_size) const {
+    boost::shared_ptr<PgSqlHostWithOptionsExchange> host_ipv4_exchange(
+            new PgSqlHostWithOptionsExchange(PgSqlHostWithOptionsExchange::DHCP4_ONLY));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2254,8 +2245,7 @@ PgSqlHostDataSource::getPage4(const SubnetID& subnet_id,
 
     ConstHostCollection result;
     impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_SUBID4_PAGE,
-                             bind_array, impl_->host_exchange_,
-                             result, false);
+                             bind_array, host_ipv4_exchange, result, false);
 
     return (result);
 }
@@ -2265,6 +2255,9 @@ PgSqlHostDataSource::getPage6(const SubnetID& subnet_id,
                               size_t& /*source_index*/,
                               uint64_t lower_host_id,
                               const HostPageSize& page_size) const {
+    boost::shared_ptr<PgSqlHostIPv6Exchange> host_ipv6_exchange(
+            new PgSqlHostIPv6Exchange(PgSqlHostWithOptionsExchange::DHCP6_ONLY));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2281,14 +2274,15 @@ PgSqlHostDataSource::getPage6(const SubnetID& subnet_id,
 
     ConstHostCollection result;
     impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_SUBID6_PAGE,
-                             bind_array, impl_->host_ipv6_exchange_,
-                             result, false);
+                             bind_array, host_ipv6_exchange, result, false);
 
     return (result);
 }
 
 ConstHostCollection
 PgSqlHostDataSource::getAll4(const asiolink::IOAddress& address) const {
+    boost::shared_ptr<PgSqlHostWithOptionsExchange> host_ipv4_exchange(
+            new PgSqlHostWithOptionsExchange(PgSqlHostWithOptionsExchange::DHCP4_ONLY));
 
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
@@ -2298,7 +2292,7 @@ PgSqlHostDataSource::getAll4(const asiolink::IOAddress& address) const {
 
     ConstHostCollection result;
     impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_ADDR, bind_array,
-                             impl_->host_exchange_, result, false);
+                             host_ipv4_exchange, result, false);
 
     return (result);
 }
@@ -2308,21 +2302,26 @@ PgSqlHostDataSource::get4(const SubnetID& subnet_id,
                           const Host::IdentifierType& identifier_type,
                           const uint8_t* identifier_begin,
                           const size_t identifier_len) const {
+    boost::shared_ptr<PgSqlHostWithOptionsExchange> host_ipv4_exchange(
+            new PgSqlHostWithOptionsExchange(PgSqlHostWithOptionsExchange::DHCP4_ONLY));
 
     return (impl_->getHost(subnet_id, identifier_type, identifier_begin,
                            identifier_len,
                            PgSqlHostDataSourceImpl::GET_HOST_SUBID4_DHCPID,
-                           impl_->host_exchange_));
+                           host_ipv4_exchange));
 }
 
 ConstHostPtr
 PgSqlHostDataSource::get4(const SubnetID& subnet_id,
                           const asiolink::IOAddress& address) const {
     if (!address.isV4()) {
-        isc_throw(BadValue, "PgSqlHostDataSource::get4(id, address) - "
-                  " wrong address type, address supplied is an IPv6 address");
+        isc_throw(BadValue, "PgSqlHostDataSource::get4(id, address): "
+                  "wrong address type, address supplied is an IPv6 address");
     }
 
+    boost::shared_ptr<PgSqlHostWithOptionsExchange> host_ipv4_exchange(
+            new PgSqlHostWithOptionsExchange(PgSqlHostWithOptionsExchange::DHCP4_ONLY));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2334,13 +2333,13 @@ PgSqlHostDataSource::get4(const SubnetID& subnet_id,
 
     ConstHostCollection collection;
     impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_SUBID_ADDR,
-                             bind_array, impl_->host_exchange_, collection,
-                             true);
+                             bind_array, host_ipv4_exchange, collection, true);
 
     // Return single record if present, else clear the host.
     ConstHostPtr result;
-    if (!collection.empty())
+    if (!collection.empty()) {
         result = *collection.begin();
+    }
 
     return (result);
 }
@@ -2350,16 +2349,24 @@ PgSqlHostDataSource::get6(const SubnetID& subnet_id,
                           const Host::IdentifierType& identifier_type,
                           const uint8_t* identifier_begin,
                           const size_t identifier_len) const {
+    boost::shared_ptr<PgSqlHostIPv6Exchange> host_ipv6_exchange(
+            new PgSqlHostIPv6Exchange(PgSqlHostWithOptionsExchange::DHCP6_ONLY));
 
     return (impl_->getHost(subnet_id, identifier_type, identifier_begin,
                    identifier_len, PgSqlHostDataSourceImpl::GET_HOST_SUBID6_DHCPID,
-                   impl_->host_ipv6_exchange_));
+                   host_ipv6_exchange));
 }
 
 ConstHostPtr
 PgSqlHostDataSource::get6(const asiolink::IOAddress& prefix,
                           const uint8_t prefix_len) const {
-    /// @todo: Check that prefix is v6 address, not v4.
+    if (!prefix.isV6()) {
+        isc_throw(BadValue, "PgSqlHostDataSource::get6(prefix, prefix_len): "
+                  "wrong address type, address supplied is an IPv4 address");
+    }
+
+    boost::shared_ptr<PgSqlHostIPv6Exchange> host_ipv6_exchange(
+            new PgSqlHostIPv6Exchange(PgSqlHostWithOptionsExchange::DHCP6_ONLY));
 
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
@@ -2372,8 +2379,7 @@ PgSqlHostDataSource::get6(const asiolink::IOAddress& prefix,
 
     ConstHostCollection collection;
     impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_PREFIX,
-                             bind_array, impl_->host_ipv6_exchange_,
-                             collection, true);
+                             bind_array, host_ipv6_exchange, collection, true);
 
     // Return single record if present, else clear the host.
     ConstHostPtr result;
@@ -2387,7 +2393,13 @@ PgSqlHostDataSource::get6(const asiolink::IOAddress& prefix,
 ConstHostPtr
 PgSqlHostDataSource::get6(const SubnetID& subnet_id,
                           const asiolink::IOAddress& address) const {
-    /// @todo: Check that prefix is v6 address, not v4.
+    if (!address.isV6()) {
+        isc_throw(BadValue, "PgSqlHostDataSource::get6(id, address): "
+                  "wrong address type, address supplied is an IPv4 address");
+    }
+
+    boost::shared_ptr<PgSqlHostIPv6Exchange> host_ipv6_exchange(
+            new PgSqlHostIPv6Exchange(PgSqlHostWithOptionsExchange::DHCP6_ONLY));
 
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
@@ -2400,8 +2412,7 @@ PgSqlHostDataSource::get6(const SubnetID& subnet_id,
 
     ConstHostCollection collection;
     impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_SUBID6_ADDR,
-                             bind_array, impl_->host_ipv6_exchange_,
-                             collection, true);
+                             bind_array, host_ipv6_exchange, collection, true);
 
     // Return single record if present, else clear the host.
     ConstHostPtr result;
index 3878f7d5896950058fb548b9caa148f77c3b4397..2fddbb70580853d379e964a31de7124e438c8ae5 100644 (file)
@@ -442,8 +442,7 @@ public:
         lease_ = lease;
 
         try {
-            addr_str_ = boost::lexical_cast<std::string>
-                        (lease->addr_.toUint32());
+            addr_str_ = boost::lexical_cast<std::string>(lease->addr_.toUint32());
             bind_array.add(addr_str_);
 
             if (lease->hwaddr_ && !lease->hwaddr_->hwaddr_.empty()) {
@@ -1081,8 +1080,7 @@ protected:
 };
 
 PgSqlLeaseMgr::PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters)
-    : LeaseMgr(), exchange4_(new PgSqlLease4Exchange()),
-    exchange6_(new PgSqlLease6Exchange()), conn_(parameters) {
+    : LeaseMgr(), conn_(parameters) {
     conn_.openDatabase();
 
     // Validate schema version first.
@@ -1149,20 +1147,24 @@ PgSqlLeaseMgr::addLeaseCommon(StatementIndex stindex,
 
 bool
 PgSqlLeaseMgr::addLease(const Lease4Ptr& lease) {
+    boost::scoped_ptr<PgSqlLease4Exchange> exchange4(new PgSqlLease4Exchange());
+
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_PGSQL_ADD_ADDR4).arg(lease->addr_.toText());
 
     PsqlBindArray bind_array;
-    exchange4_->createBindForSend(lease, bind_array);
+    exchange4->createBindForSend(lease, bind_array);
     return (addLeaseCommon(INSERT_LEASE4, bind_array));
 }
 
 bool
 PgSqlLeaseMgr::addLease(const Lease6Ptr& lease) {
+    boost::scoped_ptr<PgSqlLease6Exchange> exchange6(new PgSqlLease6Exchange());
+
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_PGSQL_ADD_ADDR6).arg(lease->addr_.toText());
     PsqlBindArray bind_array;
-    exchange6_->createBindForSend(lease, bind_array);
+    exchange6->createBindForSend(lease, bind_array);
 
     return (addLeaseCommon(INSERT_LEASE6, bind_array));
 }
@@ -1193,16 +1195,34 @@ void PgSqlLeaseMgr::getLeaseCollection(StatementIndex stindex,
     }
 }
 
+void
+PgSqlLeaseMgr::getLeaseCollection(StatementIndex stindex, db::PsqlBindArray& bind_array,
+                                  Lease4Collection& result) const {
+    boost::scoped_ptr<PgSqlLease4Exchange> exchange4(new PgSqlLease4Exchange());
+
+    getLeaseCollection(stindex, bind_array, exchange4, result);
+}
+
+void
+PgSqlLeaseMgr::getLeaseCollection(StatementIndex stindex, db::PsqlBindArray& bind_array,
+                                  Lease6Collection& result) const {
+    boost::scoped_ptr<PgSqlLease6Exchange> exchange6(new PgSqlLease6Exchange());
+
+    getLeaseCollection(stindex, bind_array, exchange6, result);
+}
+
 void
 PgSqlLeaseMgr::getLease(StatementIndex stindex, PsqlBindArray& bind_array,
                              Lease4Ptr& result) const {
+    boost::scoped_ptr<PgSqlLease4Exchange> exchange4(new PgSqlLease4Exchange());
+
     // Create appropriate collection object and get all leases matching
     // the selection criteria.  The "single" parameter is true to indicate
     // that the called method should throw an exception if multiple
     // matching records are found: this particular method is called when only
     // one or zero matches is expected.
     Lease4Collection collection;
-    getLeaseCollection(stindex, bind_array, exchange4_, collection, true);
+    getLeaseCollection(stindex, bind_array, exchange4, collection, true);
 
     // Return single record if present, else clear the lease.
     if (collection.empty()) {
@@ -1215,13 +1235,15 @@ PgSqlLeaseMgr::getLease(StatementIndex stindex, PsqlBindArray& bind_array,
 void
 PgSqlLeaseMgr::getLease(StatementIndex stindex, PsqlBindArray& bind_array,
                              Lease6Ptr& result) const {
+    boost::scoped_ptr<PgSqlLease6Exchange> exchange6(new PgSqlLease6Exchange());
+
     // Create appropriate collection object and get all leases matching
     // the selection criteria.  The "single" parameter is true to indicate
     // that the called method should throw an exception if multiple
     // matching records are found: this particular method is called when only
     // one or zero matches is expected.
     Lease6Collection collection;
-    getLeaseCollection(stindex, bind_array, exchange6_, collection, true);
+    getLeaseCollection(stindex, bind_array, exchange6, collection, true);
 
     // Return single record if present, else clear the lease.
     if (collection.empty()) {
@@ -1240,8 +1262,7 @@ PgSqlLeaseMgr::getLease4(const isc::asiolink::IOAddress& addr) const {
     PsqlBindArray bind_array;
 
     // LEASE ADDRESS
-    std::string addr_str = boost::lexical_cast<std::string>
-                           (addr.toUint32());
+    std::string addr_str = boost::lexical_cast<std::string>(addr.toUint32());
     bind_array.add(addr_str);
 
     // Get the data
@@ -1669,6 +1690,8 @@ PgSqlLeaseMgr::updateLeaseCommon(StatementIndex stindex,
 
 void
 PgSqlLeaseMgr::updateLease4(const Lease4Ptr& lease) {
+    boost::scoped_ptr<PgSqlLease4Exchange> exchange4(new PgSqlLease4Exchange());
+
     const StatementIndex stindex = UPDATE_LEASE4;
 
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
@@ -1676,12 +1699,11 @@ PgSqlLeaseMgr::updateLease4(const Lease4Ptr& lease) {
 
     // Create the BIND array for the data being updated
     PsqlBindArray bind_array;
-    exchange4_->createBindForSend(lease, bind_array);
+    exchange4->createBindForSend(lease, bind_array);
 
     // Set up the WHERE clause and append it to the SQL_BIND array
-    std::string addr4_ = boost::lexical_cast<std::string>
-                         (lease->addr_.toUint32());
-    bind_array.add(addr4_);
+    std::string addr_str = boost::lexical_cast<std::string>(lease->addr_.toUint32());
+    bind_array.add(addr_str);
 
     // Drop to common update code
     updateLeaseCommon(stindex, bind_array, lease);
@@ -1689,6 +1711,8 @@ PgSqlLeaseMgr::updateLease4(const Lease4Ptr& lease) {
 
 void
 PgSqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
+    boost::scoped_ptr<PgSqlLease6Exchange> exchange6(new PgSqlLease6Exchange());
+
     const StatementIndex stindex = UPDATE_LEASE6;
 
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
@@ -1696,7 +1720,7 @@ PgSqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
 
     // Create the BIND array for the data being updated
     PsqlBindArray bind_array;
-    exchange6_->createBindForSend(lease, bind_array);
+    exchange6->createBindForSend(lease, bind_array);
 
     // Set up the WHERE clause and append it to the BIND array
     std::string addr_str = lease->addr_.toText();
index c779fafaa6eb80dd5349efdeca4db75f2e1afce0..f2d4a87b89d5e22579aa0c29692f1dc21c5ee9ce 100644 (file)
@@ -632,9 +632,7 @@ private:
     /// @throw isc::db::MultipleRecords Multiple records were retrieved
     ///        from the database where only one was expected.
     void getLeaseCollection(StatementIndex stindex, db::PsqlBindArray& bind_array,
-                            Lease4Collection& result) const {
-        getLeaseCollection(stindex, bind_array, exchange4_, result);
-    }
+                            Lease4Collection& result) const;
 
     /// @brief Get Lease6 Collection
     ///
@@ -652,9 +650,7 @@ private:
     /// @throw isc::db::MultipleRecords Multiple records were retrieved
     ///        from the database where only one was expected.
     void getLeaseCollection(StatementIndex stindex, db::PsqlBindArray& bind_array,
-                            Lease6Collection& result) const {
-        getLeaseCollection(stindex, bind_array, exchange6_, result);
-    }
+                            Lease6Collection& result) const;
 
     /// @brief Get Lease4 Common Code
     ///
@@ -747,13 +743,6 @@ private:
     uint64_t deleteExpiredReclaimedLeasesCommon(const uint32_t secs,
                                                 StatementIndex statement_index);
 
-    /// The exchange objects are used for transfer of data to/from the database.
-    /// They are pointed-to objects as the contents may change in "const" calls,
-    /// while the rest of this object does not.  (At alternative would be to
-    /// declare them as "mutable".)
-    boost::scoped_ptr<PgSqlLease4Exchange> exchange4_; ///< Exchange object
-    boost::scoped_ptr<PgSqlLease6Exchange> exchange6_; ///< Exchange object
-
     /// PostgreSQL connection handle
     db::PgSqlConnection conn_;
 };
index 0e9f001d5b6d7c90827abbafd3a05bc963d7b210..89ebf341d154b12d6f4151936e1276788373477c 100644 (file)
@@ -210,6 +210,18 @@ MySqlConnection::openDatabase() {
     if (status != mysql_) {
         isc_throw(DbOpenError, mysql_error(mysql_));
     }
+
+    // Enable autocommit. In case transaction is explicitly used, this
+    // setting will be overwritten for the transaction. However, there are
+    // cases when lack of autocommit could cause transactions to hang
+    // until commit or rollback is explicitly called. This already
+    // caused issues for some unit tests which were unable to cleanup
+    // the database after the test because of pending transactions.
+    // Use of autocommit will eliminate this problem.
+    my_bool auto_commit = mysql_autocommit(mysql_, 1);
+    if (auto_commit != MLM_FALSE) {
+        isc_throw(DbOperationError, mysql_error(mysql_));
+    }
 }
 
 
@@ -261,11 +273,6 @@ MySqlConnection::prepareStatements(const TaggedStatement* start_statement,
     }
 }
 
-void MySqlConnection::clearStatements() {
-    statements_.clear();
-    text_statements_.clear();
-}
-
 /// @brief Destructor
 MySqlConnection::~MySqlConnection() {
     // Free up the prepared statements, ignoring errors. (What would we do
index 714af49bb29adb8cc65851f9dcbc1c302920209e..f2d6c95d21a9f7e7b40aba05bf795b93e2d66a75 100644 (file)
@@ -242,9 +242,6 @@ public:
     void prepareStatements(const TaggedStatement* start_statement,
                            const TaggedStatement* end_statement);
 
-    /// @brief Clears prepared statements and text statements.
-    void clearStatements();
-
     /// @brief Open Database
     ///
     /// Opens the database using the information supplied in the parameters
index 6d54857b6b5bea234679dd0795a0a89eda5f1d4a..7895b471157f89def7881b23fe968d0099cf72ea 100644 (file)
@@ -63,11 +63,6 @@ public:
         try {
             // Open new connection.
             conn_.openDatabase();
-            my_bool result = mysql_autocommit(conn_.mysql_, 1);
-            if (result != 0) {
-                isc_throw(DbOperationError, "failed to set autocommit option "
-                          "for test MySQL connection");
-            }
 
             // Create mysql_connection_test table.
             createTestTable();