]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#885,!570] use thread_local when creating exchanges
authorRazvan Becheriu <razvan@isc.org>
Thu, 24 Oct 2019 06:51:04 +0000 (09:51 +0300)
committerRazvan Becheriu <razvan@isc.org>
Wed, 6 Nov 2019 15:58:59 +0000 (17:58 +0200)
src/lib/dhcpsrv/pgsql_host_data_source.cc
src/lib/dhcpsrv/pgsql_lease_mgr.cc
src/lib/dhcpsrv/pgsql_lease_mgr.h

index 7ea6f61e6b8e0308e7d25515cb4c8daaeca351df..aa6d773024edf59f5402cf791dfad508170536a7 100644 (file)
@@ -297,7 +297,7 @@ public:
         // most recently added host is different than the host id of the
         // currently processed host.
         if (hosts.empty() || row_host_id != hosts.back()->getHostId()) {
-            HostPtr host = retrieveHost(r, row, row_host_id);
+            HostPtr host(retrieveHost(r, row, row_host_id));
             hosts.push_back(host);
         }
     }
@@ -1263,7 +1263,7 @@ private:
     OptionPtr option_;
 };
 
-} // end of anonymous namespace
+}  // namespace
 
 namespace isc {
 namespace dhcp {
@@ -1397,7 +1397,7 @@ public:
     /// @param single A boolean value indicating if a single host is
     /// expected to be returned, or multiple hosts.
     void getHostCollection(StatementIndex stindex, PsqlBindArrayPtr bind,
-                           boost::shared_ptr<PgSqlHostExchange> exchange,
+                           std::shared_ptr<PgSqlHostExchange> exchange,
                            ConstHostCollection& result, bool single) const;
 
     /// @brief Retrieves a host by subnet and client's unique identifier.
@@ -1421,7 +1421,7 @@ public:
                          const uint8_t* identifier_begin,
                          const size_t identifier_len,
                          StatementIndex stindex,
-                         boost::shared_ptr<PgSqlHostExchange> exchange) const;
+                         std::shared_ptr<PgSqlHostExchange> exchange) const;
 
     /// @brief Throws exception if database is read only.
     ///
@@ -1442,28 +1442,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_;
 
@@ -1854,7 +1832,7 @@ TaggedStatementArray tagged_statements = { {
     // Using fixed scope_id = 3, which associates an option with host.
     {7,
      { OID_INT2, OID_BYTEA, OID_TEXT,
-       OID_VARCHAR, OID_BOOL, OID_TEXT, OID_INT8},
+       OID_VARCHAR, OID_BOOL, OID_TEXT, OID_INT8 },
      "insert_v4_host_option",
      "INSERT INTO dhcp4_options(code, value, formatted_value, space, "
      "  persistent, user_context, host_id, scope_id) "
@@ -1866,7 +1844,7 @@ TaggedStatementArray tagged_statements = { {
     // Using fixed scope_id = 3, which associates an option with host.
     {7,
      { OID_INT2, OID_BYTEA, OID_TEXT,
-       OID_VARCHAR, OID_BOOL, OID_TEXT, OID_INT8},
+       OID_VARCHAR, OID_BOOL, OID_TEXT, OID_INT8 },
      "insert_v6_host_option",
      "INSERT INTO dhcp6_options(code, value, formatted_value, space, "
      "  persistent, user_context, host_id, scope_id) "
@@ -1903,17 +1881,11 @@ TaggedStatementArray tagged_statements = { {
 }
 };
 
-}; // end anonymous namespace
+}  // namespace
 
 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),
+PgSqlHostDataSourceImpl(const PgSqlConnection::ParameterMap& parameters) :
+    conn_(parameters),
       is_readonly_(false) {
 
     // Open the database.
@@ -1927,7 +1899,7 @@ PgSqlHostDataSourceImpl(const PgSqlConnection::ParameterMap& parameters)
         isc_throw(DbOpenError,
                   "PostgreSQL schema version mismatch: need version: "
                       << code_version.first << "." << code_version.second
-                      << " found version:  " << db_version.first << "."
+                      << " found version: " << db_version.first << "."
                       << db_version.second);
     }
 
@@ -2014,8 +1986,12 @@ PgSqlHostDataSourceImpl::delStatement(StatementIndex stindex,
 void
 PgSqlHostDataSourceImpl::addResv(const IPv6Resrv& resv,
                                  const HostID& id) {
+    thread_local std::shared_ptr<PgSqlIPv6ReservationExchange> host_ipv6_reservation_exchange(
+        std::make_shared<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);
 }
 
@@ -2025,9 +2001,12 @@ PgSqlHostDataSourceImpl::addOption(const StatementIndex& stindex,
                                    const std::string& opt_space,
                                    const Optional<SubnetID>&,
                                    const HostID& id) {
+    thread_local std::shared_ptr<PgSqlOptionExchange> host_option_exchange(
+        std::make_shared<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);
 }
 
@@ -2060,7 +2039,7 @@ PgSqlHostDataSourceImpl::addOptions(const StatementIndex& stindex,
 void
 PgSqlHostDataSourceImpl::
 getHostCollection(StatementIndex stindex, PsqlBindArrayPtr bind_array,
-                  boost::shared_ptr<PgSqlHostExchange> exchange,
+                  std::shared_ptr<PgSqlHostExchange> exchange,
                   ConstHostCollection& result, bool single) const {
 
     exchange->clear();
@@ -2091,7 +2070,7 @@ getHost(const SubnetID& subnet_id,
         const uint8_t* identifier_begin,
         const size_t identifier_len,
         StatementIndex stindex,
-        boost::shared_ptr<PgSqlHostExchange> exchange) const {
+        std::shared_ptr<PgSqlHostExchange> exchange) const {
 
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
@@ -2110,13 +2089,15 @@ 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);
 }
 
-std::pair<uint32_t, uint32_t> PgSqlHostDataSourceImpl::getVersion() const {
+pair<uint32_t, uint32_t>
+PgSqlHostDataSourceImpl::getVersion() const {
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_PGSQL_HOST_DB_GET_VERSION);
     const char* version_sql =  "SELECT version, minor FROM schema_version;";
@@ -2126,13 +2107,13 @@ std::pair<uint32_t, uint32_t> PgSqlHostDataSourceImpl::getVersion() const {
                   << version_sql << ">, reason: " << PQerrorMessage(conn_));
     }
 
-    uint32_t version;
-    PgSqlExchange::getColumnValue(r, 0, 0, version);
+    uint32_t major;
+    PgSqlExchange::getColumnValue(r, 0, 0, major);
 
     uint32_t minor;
     PgSqlExchange::getColumnValue(r, 0, 1, minor);
 
-    return (std::make_pair(version, minor));
+    return (make_pair(major, minor));
 }
 
 void
@@ -2159,6 +2140,9 @@ PgSqlHostDataSource::add(const HostPtr& host) {
     // If operating in read-only mode, throw exception.
     impl_->checkReadOnly();
 
+    thread_local std::shared_ptr<PgSqlHostWithOptionsExchange> host_ipv4_exchange(
+        std::make_shared<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
@@ -2166,7 +2150,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,
@@ -2266,6 +2250,9 @@ ConstHostCollection
 PgSqlHostDataSource::getAll(const Host::IdentifierType& identifier_type,
                             const uint8_t* identifier_begin,
                             const size_t identifier_len) const {
+    thread_local std::shared_ptr<PgSqlHostIPv6Exchange> host_ipv46_exchange(
+        std::make_shared<PgSqlHostIPv6Exchange>(PgSqlHostWithOptionsExchange::DHCP4_AND_DHCP6));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2277,13 +2264,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 {
+    thread_local std::shared_ptr<PgSqlHostWithOptionsExchange> host_ipv4_exchange(
+        std::make_shared<PgSqlHostWithOptionsExchange>(PgSqlHostWithOptionsExchange::DHCP4_ONLY));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2292,14 +2281,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 {
+    thread_local std::shared_ptr<PgSqlHostIPv6Exchange> host_ipv6_exchange(
+        std::make_shared<PgSqlHostIPv6Exchange>(PgSqlHostWithOptionsExchange::DHCP6_ONLY));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2308,14 +2299,16 @@ 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);
 }
 
 ConstHostCollection
 PgSqlHostDataSource::getAllbyHostname(const std::string& hostname) const {
+    thread_local std::shared_ptr<PgSqlHostIPv6Exchange> host_ipv46_exchange(
+        std::make_shared<PgSqlHostIPv6Exchange>(PgSqlHostWithOptionsExchange::DHCP4_AND_DHCP6));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2324,14 +2317,17 @@ PgSqlHostDataSource::getAllbyHostname(const std::string& hostname) const {
 
     ConstHostCollection result;
     impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_HOSTNAME,
-                             bind_array, impl_->host_ipv46_exchange_,
-                             result, false);
+                             bind_array, host_ipv46_exchange, result, false);
+
     return (result);
 }
 
 ConstHostCollection
 PgSqlHostDataSource::getAllbyHostname4(const std::string& hostname,
                                        const SubnetID& subnet_id) const {
+    thread_local std::shared_ptr<PgSqlHostWithOptionsExchange> host_ipv4_exchange(
+        std::make_shared<PgSqlHostWithOptionsExchange>(PgSqlHostWithOptionsExchange::DHCP4_ONLY));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2343,8 +2339,7 @@ PgSqlHostDataSource::getAllbyHostname4(const std::string& hostname,
 
     ConstHostCollection result;
     impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_HOSTNAME_SUBID4,
-                             bind_array, impl_->host_exchange_,
-                             result, false);
+                             bind_array, host_ipv4_exchange, result, false);
 
     return (result);
 }
@@ -2352,6 +2347,9 @@ PgSqlHostDataSource::getAllbyHostname4(const std::string& hostname,
 ConstHostCollection
 PgSqlHostDataSource::getAllbyHostname6(const std::string& hostname,
                                        const SubnetID& subnet_id) const {
+    thread_local std::shared_ptr<PgSqlHostIPv6Exchange> host_ipv6_exchange(
+        std::make_shared<PgSqlHostIPv6Exchange>(PgSqlHostWithOptionsExchange::DHCP6_ONLY));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2363,8 +2361,7 @@ PgSqlHostDataSource::getAllbyHostname6(const std::string& hostname,
 
     ConstHostCollection result;
     impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_HOSTNAME_SUBID6,
-                             bind_array, impl_->host_ipv6_exchange_,
-                             result, false);
+                             bind_array, host_ipv6_exchange, result, false);
 
     return (result);
 }
@@ -2374,6 +2371,9 @@ PgSqlHostDataSource::getPage4(const SubnetID& subnet_id,
                               size_t& /*source_index*/,
                               uint64_t lower_host_id,
                               const HostPageSize& page_size) const {
+    thread_local std::shared_ptr<PgSqlHostWithOptionsExchange> host_ipv4_exchange(
+        std::make_shared<PgSqlHostWithOptionsExchange>(PgSqlHostWithOptionsExchange::DHCP4_ONLY));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2390,8 +2390,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);
 }
@@ -2401,6 +2400,9 @@ PgSqlHostDataSource::getPage6(const SubnetID& subnet_id,
                               size_t& /*source_index*/,
                               uint64_t lower_host_id,
                               const HostPageSize& page_size) const {
+    thread_local std::shared_ptr<PgSqlHostIPv6Exchange> host_ipv6_exchange(
+        std::make_shared<PgSqlHostIPv6Exchange>(PgSqlHostWithOptionsExchange::DHCP6_ONLY));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2417,14 +2419,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 {
+    thread_local std::shared_ptr<PgSqlHostWithOptionsExchange> host_ipv4_exchange(
+        std::make_shared<PgSqlHostWithOptionsExchange>(PgSqlHostWithOptionsExchange::DHCP4_ONLY));
 
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
@@ -2434,7 +2437,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);
 }
@@ -2444,21 +2447,26 @@ PgSqlHostDataSource::get4(const SubnetID& subnet_id,
                           const Host::IdentifierType& identifier_type,
                           const uint8_t* identifier_begin,
                           const size_t identifier_len) const {
+    thread_local std::shared_ptr<PgSqlHostWithOptionsExchange> host_ipv4_exchange(
+        std::make_shared<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");
     }
 
+    thread_local std::shared_ptr<PgSqlHostWithOptionsExchange> host_ipv4_exchange(
+        std::make_shared<PgSqlHostWithOptionsExchange>(PgSqlHostWithOptionsExchange::DHCP4_ONLY));
+
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
 
@@ -2470,13 +2478,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);
 }
@@ -2486,16 +2494,24 @@ PgSqlHostDataSource::get6(const SubnetID& subnet_id,
                           const Host::IdentifierType& identifier_type,
                           const uint8_t* identifier_begin,
                           const size_t identifier_len) const {
+    thread_local std::shared_ptr<PgSqlHostIPv6Exchange> host_ipv6_exchange(
+        std::make_shared<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");
+    }
+
+    thread_local std::shared_ptr<PgSqlHostIPv6Exchange> host_ipv6_exchange(
+        std::make_shared<PgSqlHostIPv6Exchange>(PgSqlHostWithOptionsExchange::DHCP6_ONLY));
 
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
@@ -2508,8 +2524,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;
@@ -2523,7 +2538,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");
+    }
+
+    thread_local std::shared_ptr<PgSqlHostIPv6Exchange> host_ipv6_exchange(
+        std::make_shared<PgSqlHostIPv6Exchange>(PgSqlHostWithOptionsExchange::DHCP6_ONLY));
 
     // Set up the WHERE clause value
     PsqlBindArrayPtr bind_array(new PsqlBindArray());
@@ -2536,8 +2557,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;
@@ -2550,7 +2570,8 @@ PgSqlHostDataSource::get6(const SubnetID& subnet_id,
 
 // Miscellaneous database methods.
 
-std::string PgSqlHostDataSource::getName() const {
+std::string
+PgSqlHostDataSource::getName() const {
     std::string name = "";
     try {
         name = impl_->conn_.getParameter("name");
@@ -2560,7 +2581,8 @@ std::string PgSqlHostDataSource::getName() const {
     return (name);
 }
 
-std::string PgSqlHostDataSource::getDescription() const {
+std::string
+PgSqlHostDataSource::getDescription() const {
     return (std::string("Host data source that stores host information"
                         "in PostgreSQL database"));
 }
@@ -2583,5 +2605,5 @@ PgSqlHostDataSource::rollback() {
     impl_->conn_.rollback();
 }
 
-}; // end of isc::dhcp namespace
-}; // end of isc namespace
+}  // namespace dhcp
+}  // namespace isc
index 1ade37364974a196e1c400e8a6e0592f1b6b69ff..83ce3c21d5156dd5b23b229f6bb93488fcf9c392 100644 (file)
@@ -133,7 +133,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT address, hwaddr, client_id, "
         "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
         "fqdn_fwd, fqdn_rev, hostname, "
-      "state, user_context "
+        "state, user_context "
       "FROM lease4 "
       "WHERE subnet_id = $1"},
 
@@ -307,6 +307,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "hwaddr = $13, hwtype = $14, hwaddr_source = $15, "
         "state = $16, user_context = $17 "
       "WHERE address = $18"},
+
     // ALL_LEASE4_STATS
     { 0, { OID_NONE },
       "all_lease4_stats",
@@ -333,7 +334,7 @@ PgSqlTaggedStatement tagged_statements[] = {
     { 0, { OID_NONE },
      "all_lease6_stats",
      "SELECT subnet_id, lease_type, state, leases as state_count"
-     "  FROM lease6_stat ORDER BY subnet_id, lease_type, state" },
+     "  FROM lease6_stat ORDER BY subnet_id, lease_type, state"},
 
     // SUBNET_LEASE6_STATS
     { 1, { OID_INT8 },
@@ -341,7 +342,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT subnet_id, lease_type, state, leases as state_count"
       "  FROM lease6_stat "
       "  WHERE subnet_id = $1 "
-      "  ORDER BY lease_type, state" },
+      "  ORDER BY lease_type, state"},
 
     // SUBNET_RANGE_LEASE6_STATS
     { 2, { OID_INT8, OID_INT8 },
@@ -349,7 +350,8 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT subnet_id, lease_type, state, leases as state_count"
       "  FROM lease6_stat "
       "  WHERE subnet_id >= $1 and subnet_id <= $2 "
-      "  ORDER BY subnet_id, lease_type, state" },
+      "  ORDER BY subnet_id, lease_type, state"},
+
     // End of list sentinel
     { 0,  { 0 }, NULL, NULL}
 };
@@ -463,8 +465,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()) {
@@ -1113,9 +1114,8 @@ protected:
     bool fetch_type_;
 };
 
-PgSqlLeaseMgr::PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters)
-    : LeaseMgr(), exchange4_(new PgSqlLease4Exchange()),
-    exchange6_(new PgSqlLease6Exchange()), conn_(parameters) {
+PgSqlLeaseMgr::PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters) :
+    conn_(parameters) {
     conn_.openDatabase();
 
     // Validate schema version first.
@@ -1132,7 +1132,7 @@ PgSqlLeaseMgr::PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters)
 
     // Now prepare the SQL statements.
     int i = 0;
-    for( ; tagged_statements[i].text != NULL ; ++i) {
+    for(; tagged_statements[i].text != NULL; ++i) {
         conn_.prepareStatement(tagged_statements[i]);
     }
 
@@ -1182,20 +1182,26 @@ PgSqlLeaseMgr::addLeaseCommon(StatementIndex stindex,
 
 bool
 PgSqlLeaseMgr::addLease(const Lease4Ptr& lease) {
+    thread_local std::shared_ptr<PgSqlLease4Exchange> exchange4(
+        std::make_shared<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) {
+    thread_local std::shared_ptr<PgSqlLease6Exchange> exchange6(
+        std::make_shared<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));
 }
@@ -1226,16 +1232,37 @@ void PgSqlLeaseMgr::getLeaseCollection(StatementIndex stindex,
     }
 }
 
+void
+PgSqlLeaseMgr::getLeaseCollection(StatementIndex stindex, db::PsqlBindArray& bind_array,
+                                  Lease4Collection& result) const {
+    thread_local std::shared_ptr<PgSqlLease4Exchange> exchange4(
+        std::make_shared<PgSqlLease4Exchange>());
+
+    getLeaseCollection(stindex, bind_array, exchange4, result);
+}
+
+void
+PgSqlLeaseMgr::getLeaseCollection(StatementIndex stindex, db::PsqlBindArray& bind_array,
+                                  Lease6Collection& result) const {
+    thread_local std::shared_ptr<PgSqlLease6Exchange> exchange6(
+        std::make_shared<PgSqlLease6Exchange>());
+
+    getLeaseCollection(stindex, bind_array, exchange6, result);
+}
+
 void
 PgSqlLeaseMgr::getLease(StatementIndex stindex, PsqlBindArray& bind_array,
-                             Lease4Ptr& result) const {
+                        Lease4Ptr& result) const {
+    thread_local std::shared_ptr<PgSqlLease4Exchange> exchange4(
+        std::make_shared<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()) {
@@ -1247,14 +1274,17 @@ PgSqlLeaseMgr::getLease(StatementIndex stindex, PsqlBindArray& bind_array,
 
 void
 PgSqlLeaseMgr::getLease(StatementIndex stindex, PsqlBindArray& bind_array,
-                             Lease6Ptr& result) const {
+                        Lease6Ptr& result) const {
+    thread_local std::shared_ptr<PgSqlLease6Exchange> exchange6(
+        std::make_shared<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()) {
@@ -1273,8 +1303,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
@@ -1738,6 +1767,9 @@ PgSqlLeaseMgr::updateLeaseCommon(StatementIndex stindex,
 
 void
 PgSqlLeaseMgr::updateLease4(const Lease4Ptr& lease) {
+    thread_local std::shared_ptr<PgSqlLease4Exchange> exchange4(
+        std::make_shared<PgSqlLease4Exchange>());
+
     const StatementIndex stindex = UPDATE_LEASE4;
 
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
@@ -1745,12 +1777,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);
@@ -1758,6 +1789,9 @@ PgSqlLeaseMgr::updateLease4(const Lease4Ptr& lease) {
 
 void
 PgSqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
+    thread_local std::shared_ptr<PgSqlLease6Exchange> exchange6(
+        std::make_shared<PgSqlLease6Exchange>());
+
     const StatementIndex stindex = UPDATE_LEASE6;
 
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
@@ -1765,7 +1799,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();
@@ -1936,18 +1970,13 @@ PgSqlLeaseMgr::getVersion() const {
                   << version_sql << ", reason: " << PQerrorMessage(conn_));
     }
 
-    istringstream tmp;
-    uint32_t version;
-    tmp.str(PQgetvalue(r, 0, 0));
-    tmp >> version;
-    tmp.str("");
-    tmp.clear();
+    uint32_t major;
+    PgSqlExchange::getColumnValue(r, 0, 0, major);
 
     uint32_t minor;
-    tmp.str(PQgetvalue(r, 0, 1));
-    tmp >> minor;
+    PgSqlExchange::getColumnValue(r, 0, 1, minor);
 
-    return (make_pair(version, minor));
+    return (make_pair(major, minor));
 }
 
 void
@@ -1960,5 +1989,5 @@ PgSqlLeaseMgr::rollback() {
     conn_.rollback();
 }
 
-}; // end of isc::dhcp namespace
-}; // end of isc namespace
+}  // namespace dhcp
+}  // namespace isc
index cd1ccbf74d041911f85906732047b5b9e335ccc2..27ae79384d0611d3c9039c1940bcff7dac1d6dfb 100644 (file)
@@ -648,9 +648,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
     ///
@@ -668,9 +666,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
     ///
@@ -763,13 +759,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_;
 };