Commit e954809f authored by Thomas Markwalder's avatar Thomas Markwalder
Browse files

[3080] Replaced use of CURSORs with single step selects

    Changed the SQL statements used to retrieve data to be simple selects
    rather than declared as cursors.  This allows the selects to be executed
    with a single statemen execution, eliminating the need for BEGIN and END
    blocks.

    Other minor clean up.
parent 43a53ba8
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
......@@ -73,7 +73,6 @@ TaggedStatement tagged_statements[] = {
{PgSqlLeaseMgr::GET_LEASE4_ADDR, 1,
{ 20 },
"get_lease4_addr",
"DECLARE get_lease4_addr CURSOR FOR "
"SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire), subnet_id, fqdn_fwd, fqdn_rev, hostname "
"FROM lease4 "
......@@ -81,7 +80,6 @@ TaggedStatement tagged_statements[] = {
{PgSqlLeaseMgr::GET_LEASE4_CLIENTID, 1,
{ 17 },
"get_lease4_clientid",
"DECLARE get_lease4_clientid CURSOR FOR "
"SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire), subnet_id, fqdn_fwd, fqdn_rev, hostname "
"FROM lease4 "
......@@ -89,7 +87,6 @@ TaggedStatement tagged_statements[] = {
{PgSqlLeaseMgr::GET_LEASE4_CLIENTID_SUBID, 2,
{ 17, 20 },
"get_lease4_clientid_subid",
"DECLARE get_lease4_clientid_subid CURSOR FOR "
"SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, fqdn_fwd, fqdn_rev, hostname "
"FROM lease4 "
......@@ -97,7 +94,6 @@ TaggedStatement tagged_statements[] = {
{PgSqlLeaseMgr::GET_LEASE4_HWADDR, 1,
{ 17 },
"get_lease4_hwaddr",
"DECLARE get_lease4_hwaddr CURSOR FOR "
"SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, fqdn_fwd, fqdn_rev, hostname "
"FROM lease4 "
......@@ -105,7 +101,6 @@ TaggedStatement tagged_statements[] = {
{PgSqlLeaseMgr::GET_LEASE4_HWADDR_SUBID, 2,
{ 17, 20 },
"get_lease4_hwaddr_subid",
"DECLARE get_lease4_hwaddr_subid CURSOR FOR "
"SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, fqdn_fwd, fqdn_rev, hostname "
"FROM lease4 "
......@@ -113,7 +108,6 @@ TaggedStatement tagged_statements[] = {
{PgSqlLeaseMgr::GET_LEASE6_ADDR, 2,
{ 1043, 21 },
"get_lease6_addr",
"DECLARE get_lease6_addr CURSOR FOR "
"SELECT address, duid, valid_lifetime, "
"extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
"lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname "
......@@ -122,7 +116,6 @@ TaggedStatement tagged_statements[] = {
{PgSqlLeaseMgr::GET_LEASE6_DUID_IAID, 3,
{ 17, 20, 21 },
"get_lease6_duid_iaid",
"DECLARE get_lease6_duid_iaid CURSOR FOR "
"SELECT address, duid, valid_lifetime, "
"extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
"lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname "
......@@ -131,7 +124,6 @@ TaggedStatement tagged_statements[] = {
{PgSqlLeaseMgr::GET_LEASE6_DUID_IAID_SUBID, 4,
{ 21, 17, 20, 20 },
"get_lease6_duid_iaid_subid",
"DECLARE get_lease6_duid_iaid_subid CURSOR FOR "
"SELECT address, duid, valid_lifetime, "
"extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
"lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname "
......@@ -140,7 +132,6 @@ TaggedStatement tagged_statements[] = {
{PgSqlLeaseMgr::GET_VERSION, 0,
{ 0 },
"get_version",
"DECLARE get_version CURSOR FOR "
"SELECT version, minor FROM schema_version"},
{PgSqlLeaseMgr::INSERT_LEASE4, 9,
{ 20, 17, 17, 20, 1114, 20, 16, 16, 1043 },
......@@ -239,7 +230,7 @@ protected:
}
/// Compiled statement bind parameters
bindparams params;
BindParams params;
};
/// @brief Represents a single Lease4 exchange
......@@ -268,7 +259,7 @@ public:
params.reserve(LEASE_COLUMNS);
}
bindparams
BindParams
createBindForSend(const Lease4Ptr& lease) {
lease_ = lease;
params.clear();
......@@ -278,11 +269,14 @@ public:
params.push_back(PgSqlParam(tmp.str()));
tmp.str("");
// Although HWADDR object will always be there, it may be just an empty vector
// Although HWADDR object will always be there, it may be just an
// empty vector
if (!lease_->hwaddr_.empty()) {
if (lease->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
isc_throw(DbOperationError, "Attempted to store Hardware address longer ("
<< lease->hwaddr_.size() << " than allowed maximum of "
isc_throw(DbOperationError,
"Attempted to store Hardware address longer ("
<< lease->hwaddr_.size()
<< " than allowed maximum of "
<< HWAddr::MAX_HWADDR_LEN);
}
......@@ -326,12 +320,12 @@ public:
const char* valid_lifetime_str = PQgetvalue(r, line, 3);
const char* expire_str = PQgetvalue(r, line, 4);
const char* subnet_id_str = PQgetvalue(r, line, 5);
unsigned long valid_lifetime, subnet_id;
unsigned long valid_lifetime;
unsigned long subnet_id;
istringstream tmp;
tmp.str(addr4_str);
tmp >> addr4_;
tmp.str("");
tmp.clear();
memcpy(hwaddr_buffer_, hwaddr_str, hwaddr_length_);
......@@ -342,21 +336,19 @@ public:
tmp.str(valid_lifetime_str);
tmp >> valid_lifetime;
tmp.str("");
tmp.clear();
valid_lifetime_ = static_cast<uint32_t>(valid_lifetime);
tmp.clear();
expire_ = convertFromDatabaseTime(expire_str);
tmp.str(subnet_id_str);
tmp >> subnet_id;
subnet_id_ = static_cast<uint32_t>(subnet_id);
tmp.clear();
time_t cltt = expire_ - valid_lifetime_;
// Extract fqdn_fwd, fqdn_rev
// boolean is represented as one of 3 possible strings:
// "" (means NULL or not set), "t" (means true), "f" (means false)
bool fwd = stringToBool(PQgetvalue(r, line, 6));
bool rev = stringToBool(PQgetvalue(r, line, 7));
......@@ -407,7 +399,7 @@ public:
params.reserve(LEASE_COLUMNS);
}
bindparams
BindParams
createBindForSend(const Lease6Ptr& lease) {
lease_ = lease;
params.clear();
......@@ -482,38 +474,34 @@ public:
tmp.str(valid_lifetime_str);
tmp >> valid_lifetime;
tmp.str("");
tmp.clear();
valid_lifetime_ = static_cast<uint32_t>(valid_lifetime);
tmp.clear();
expire_ = convertFromDatabaseTime(expire_str);
tmp.str(subnet_id_str);
tmp >> subnet_id;
tmp.str("");
tmp.clear();
subnet_id_ = static_cast<uint32_t>(subnet_id);
tmp.clear();
tmp.str(pref_lifetime_str);
tmp >> pref_lifetime;
tmp.str("");
tmp.clear();
pref_lifetime_ = static_cast<uint32_t>(pref_lifetime);
tmp.clear();
tmp.str(lease_type_str);
tmp >> lease_type;
tmp.str("");
tmp.clear();
tmp.str(iaid_str);
tmp >> iaid;
tmp.str("");
tmp.clear();
iaid_ = static_cast<uint32_t>(iaid);
tmp.clear();
tmp.str(prefixlen_str);
tmp >> prefixlen;
prefixlen_ = static_cast<uint8_t>(prefixlen);
tmp.clear();
Lease6::Type type = Lease6::TYPE_NA;
switch (lease_type) {
......@@ -536,8 +524,6 @@ public:
}
// Extract fqdn_fwd, fqdn_rev
// boolean is represented as one of 3 possible strings:
// "" (means NULL or not set), "t" (means true), "f" (means false)
bool fwd = stringToBool(PQgetvalue(r, line, 9));
bool rev = stringToBool(PQgetvalue(r, line, 10));
......@@ -549,7 +535,8 @@ public:
Lease6Ptr result(new Lease6(type, addr, duid_ptr, iaid_,
pref_lifetime_, valid_lifetime_, 0, 0,
subnet_id_, fwd, rev, hostname, prefixlen_));
subnet_id_, fwd, rev, hostname,
prefixlen_));
time_t cltt = expire_ - valid_lifetime_;
result->cltt_ = cltt;
......@@ -574,8 +561,8 @@ private:
};
PgSqlLeaseMgr::PgSqlLeaseMgr(const LeaseMgr::ParameterMap& parameters)
: LeaseMgr(parameters){
status = NULL;
: LeaseMgr(parameters) {
conn_ = NULL;
openDatabase();
prepareStatements();
......@@ -584,19 +571,17 @@ PgSqlLeaseMgr::PgSqlLeaseMgr(const LeaseMgr::ParameterMap& parameters)
}
PgSqlLeaseMgr::~PgSqlLeaseMgr() {
if (status) {
// Attempt to deallocate prepared queries set previously with DEALLOCATE query
// No internal libpq function for that, no errors checking as well
/// @todo Can't this be done as a single string with list of statements?
for(int i = 0; tagged_statements[i].text != NULL; ++ i) {
string deallocate = "DEALLOCATE \"";
deallocate += tagged_statements[i].name;
deallocate += "\"";
PGresult* r = PQexec(status, deallocate.c_str());
PQclear(r);
if (conn_) {
// Deallocate the prepared queries.
PGresult* r = PQexec(conn_, "DEALLOCATE all");
if(PQresultStatus(r) != PGRES_COMMAND_OK) {
/// @todo log it for posterity but go on
std::cout << "deallocate error: "
<< PQerrorMessage(conn_) << std::endl;
}
PQfinish(status);
PQclear(r);
PQfinish(conn_);
}
}
......@@ -605,43 +590,23 @@ void PgSqlLeaseMgr::prepareStatements() {
statements_.resize(NUM_STATEMENTS, PgSqlStatementBind());
for(int i = 0; tagged_statements[i].text != NULL; ++ i) {
/// @todo why do we bother with select here? If they are already
/// defined we should let the error occur because we only do this
/// once per open anyway.
string checkstatement = "SELECT * FROM pg_prepared_statements "
"WHERE name = '";
checkstatement += tagged_statements[i].name;
checkstatement += "'";
PGresult* r = PQexec(status, checkstatement.c_str());
// Prepare all statements queries with all known fields datatype
PGresult* r = PQprepare(conn_, tagged_statements[i].name,
tagged_statements[i].text,
tagged_statements[i].nbparams,
tagged_statements[i].types);
if(!PQntuples(r)) {
PQclear(r);
r = PQexec(status, "BEGIN");
PQclear(r);
// Prepare all statements queries with all known fields datatype
// No need to remind them when called
r = PQprepare(status, tagged_statements[i].name,
tagged_statements[i].text,
tagged_statements[i].nbparams,
tagged_statements[i].types);
if(PQresultStatus(r) != PGRES_COMMAND_OK) {
PQclear(r);
isc_throw(DbOperationError, "unable to prepare PostgreSQL statement <" <<
tagged_statements[i].text << ">, reason: " << PQerrorMessage(status));
}
PQclear(r);
r = PQexec(status, "END");
if(PQresultStatus(r) != PGRES_COMMAND_OK) {
PQclear(r);
isc_throw(DbOperationError,
"unable to prepare PostgreSQL statement: "
<< tagged_statements[i].text << ", reason: "
<< PQerrorMessage(conn_));
}
statements_[i].stmt_name = tagged_statements[i].name;
statements_[i].stmt_nbparams = tagged_statements[i].nbparams;
} else {
PQclear(r);
}
statements_[i].stmt_name = tagged_statements[i].name;
statements_[i].stmt_nbparams = tagged_statements[i].nbparams;
PQclear(r);
}
}
......@@ -682,23 +647,23 @@ PgSqlLeaseMgr::openDatabase() {
isc_throw(NoDatabaseName, "must specified a name for the database");
}
status = PQconnectdb(dbconnparameters.c_str());
if (status == NULL) {
conn_ = PQconnectdb(dbconnparameters.c_str());
if (conn_ == NULL) {
isc_throw(DbOpenError, "could not allocate connection object");
}
if (PQstatus(status) != CONNECTION_OK) {
if (PQstatus(conn_) != CONNECTION_OK) {
// If we have a connection object, we have to call finish
// to release it, but grab the error message first.
std::string error_message = PQerrorMessage(status);
PQfinish(status);
std::string error_message = PQerrorMessage(conn_);
PQfinish(conn_);
isc_throw(DbOpenError, error_message);
}
}
bool
PgSqlLeaseMgr::addLeaseCommon(StatementIndex stindex,
bindparams& params) {
BindParams& params) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_ADD_ADDR4).arg(statements_[stindex].stmt_name);
......@@ -708,22 +673,26 @@ PgSqlLeaseMgr::addLeaseCommon(StatementIndex stindex,
vector<int> out_formats;
convertToQuery(params, out_values, out_lengths, out_formats);
PGresult * r = PQexecPrepared(status, statements_[stindex].stmt_name,
PGresult * r = PQexecPrepared(conn_, statements_[stindex].stmt_name,
statements_[stindex].stmt_nbparams,
&out_values[0], &out_lengths[0], &out_formats[0], 0);
&out_values[0], &out_lengths[0],
&out_formats[0], 0);
int s = PQresultStatus(r);
if (s != PGRES_COMMAND_OK) {
const char * errorMsg = PQerrorMessage(status);
const char * errorMsg = PQerrorMessage(conn_);
PQclear(r);
/// @todo - ok, do we have to rely on error message text??
/// and why is failing on duplicate key NOT an error?
/// should be looking at global sqlca struct
if(!strncmp(errorMsg, "ERROR: duplicate key",
sizeof("ERROR: duplicate key") - 1)) {
return (false);
}
isc_throw(DbOperationError, "unable to INSERT for <" <<
statements_[stindex].stmt_name << ">, " <<
isc_throw(DbOperationError, "unable to INSERT for " <<
statements_[stindex].stmt_name << ", reason: " <<
errorMsg);
}
......@@ -736,7 +705,7 @@ bool
PgSqlLeaseMgr::addLease(const Lease4Ptr& lease) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_ADD_ADDR4).arg(lease->addr_.toText());
bindparams params = exchange4_->createBindForSend(lease);
BindParams params = exchange4_->createBindForSend(lease);
return (addLeaseCommon(INSERT_LEASE4, params));
}
......@@ -745,14 +714,14 @@ bool
PgSqlLeaseMgr::addLease(const Lease6Ptr& lease) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_ADD_ADDR6).arg(lease->addr_.toText());
bindparams params = exchange6_->createBindForSend(lease);
BindParams params = exchange6_->createBindForSend(lease);
return (addLeaseCommon(INSERT_LEASE6, params));
}
template <typename Exchange, typename LeaseCollection>
void PgSqlLeaseMgr::getLeaseCollection(StatementIndex stindex,
bindparams & params,
BindParams & params,
Exchange& exchange,
LeaseCollection& result,
bool single) const {
......@@ -763,27 +732,15 @@ void PgSqlLeaseMgr::getLeaseCollection(StatementIndex stindex,
vector<int> out_lengths;
vector<int> out_formats;
convertToQuery(params, out_values, out_lengths, out_formats);
PGresult* r = PQexec(status, "BEGIN");
PQclear(r);
r = PQexecPrepared(status, statements_[stindex].stmt_name,
PGresult* r = PQexecPrepared(conn_, statements_[stindex].stmt_name,
statements_[stindex].stmt_nbparams, &out_values[0],
&out_lengths[0], &out_formats[0], 0);
checkError(r, stindex, "unable to bind WHERE clause parameter");
PQclear(r);
string fetchall = "FETCH ALL in ";
fetchall += statements_[stindex].stmt_name;
r = PQexec(status, fetchall.c_str());
checkError(r, stindex, "unable to FETCH ALL");
checkStatementError(r, stindex);
int lines = PQntuples(r);
if(single && lines > 1) {
PQclear(r);
r = PQexec(status, "END");
if (single && lines > 1) {
PQclear(r);
isc_throw(MultipleRecords, "multiple records were found in the "
"database where only one was expected for query "
......@@ -795,18 +752,10 @@ void PgSqlLeaseMgr::getLeaseCollection(StatementIndex stindex,
}
PQclear(r);
string closecursor = "CLOSE ";
closecursor += statements_[stindex].stmt_name;
r = PQexec(status, closecursor.c_str());
PQclear(r);
r = PQexec(status, "END");
PQclear(r);
}
void
PgSqlLeaseMgr::getLease(StatementIndex stindex, bindparams & params,
PgSqlLeaseMgr::getLease(StatementIndex stindex, BindParams & params,
Lease4Ptr& result) const {
// Create appropriate collection object and get all leases matching
// the selection criteria. The "single" paraeter is true to indicate
......@@ -825,7 +774,7 @@ PgSqlLeaseMgr::getLease(StatementIndex stindex, bindparams & params,
}
void
PgSqlLeaseMgr::getLease(StatementIndex stindex, bindparams & params,
PgSqlLeaseMgr::getLease(StatementIndex stindex, BindParams & params,
Lease6Ptr& result) const {
// Create appropriate collection object and get all leases matching
// the selection criteria. The "single" paraeter is true to indicate
......@@ -849,7 +798,7 @@ PgSqlLeaseMgr::getLease4(const isc::asiolink::IOAddress& addr) const {
DHCPSRV_PGSQL_GET_ADDR4).arg(addr.toText());
// Set up the WHERE clause value
bindparams inparams;
BindParams inparams;
ostringstream tmp;
tmp << static_cast<uint32_t>(addr);
......@@ -868,7 +817,7 @@ PgSqlLeaseMgr::getLease4(const HWAddr& hwaddr) const {
DHCPSRV_PGSQL_GET_HWADDR).arg(hwaddr.toText());
// Set up the WHERE clause value
bindparams inparams;
BindParams inparams;
if (!hwaddr.hwaddr_.empty()) {
inparams.push_back(PgSqlParam(hwaddr.hwaddr_));
......@@ -887,10 +836,10 @@ Lease4Ptr
PgSqlLeaseMgr::getLease4(const HWAddr& hwaddr, SubnetID subnet_id) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_GET_SUBID_HWADDR)
.arg(subnet_id).arg(hwaddr.toText());
.arg(subnet_id).arg(hwaddr.toText());
// Set up the WHERE clause value
bindparams inparams;
BindParams inparams;
ostringstream tmp;
if (!hwaddr.hwaddr_.empty()) {
......@@ -915,7 +864,7 @@ PgSqlLeaseMgr::getLease4(const ClientId& clientid) const {
DHCPSRV_PGSQL_GET_CLIENTID).arg(clientid.toText());
// Set up the WHERE clause value
bindparams inparams;
BindParams inparams;
// CLIENT_ID
inparams.push_back(PgSqlParam(clientid.getClientId()));
......@@ -934,7 +883,7 @@ PgSqlLeaseMgr::getLease4(const ClientId& clientid, SubnetID subnet_id) const {
.arg(subnet_id).arg(clientid.toText());
// Set up the WHERE clause value
bindparams inparams;
BindParams inparams;
ostringstream tmp;
// CLIENT_ID
......@@ -951,10 +900,10 @@ PgSqlLeaseMgr::getLease4(const ClientId& clientid, SubnetID subnet_id) const {
}
Lease4Ptr
PgSqlLeaseMgr::getLease4(const ClientId& /*client_id*/, const HWAddr& /*hwaddr*/,
PgSqlLeaseMgr::getLease4(const ClientId& /*client_id*/,
const HWAddr& /*hwaddr*/,
SubnetID /*subnet_id*/) const {
/// @todo
Lease4Ptr result;
return (result);
}
......@@ -966,7 +915,7 @@ PgSqlLeaseMgr::getLease6(Lease::Type lease_type,
.arg(addr.toText()).arg(lease_type);
// Set up the WHERE clause value
bindparams inparams;
BindParams inparams;
ostringstream tmp;
// ADDRESS
......@@ -984,12 +933,14 @@ PgSqlLeaseMgr::getLease6(Lease::Type lease_type,
}
Lease6Collection
PgSqlLeaseMgr::getLeases6(Lease::Type type, const DUID& duid, uint32_t iaid) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_IAID_DUID)
.arg(iaid).arg(duid.toText()).arg(type);
PgSqlLeaseMgr::getLeases6(Lease::Type type, const DUID& duid,
uint32_t iaid) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_GET_IAID_DUID)
.arg(iaid).arg(duid.toText()).arg(type);
// Set up the WHERE clause value
bindparams inparams;
BindParams inparams;
ostringstream tmp;
// DUID
......@@ -1019,7 +970,7 @@ PgSqlLeaseMgr::getLeases6(Lease::Type lease_type, const DUID& duid, uint32_t iai
.arg(iaid).arg(subnet_id).arg(duid.toText()).arg(lease_type);
// Set up the WHERE clause value
bindparams inparams;
BindParams inparams;
ostringstream tmp;
// LEASE_TYPE
......@@ -1052,7 +1003,7 @@ PgSqlLeaseMgr::getLeases6(Lease::Type lease_type, const DUID& duid, uint32_t iai
template <typename LeasePtr>
void
PgSqlLeaseMgr::updateLeaseCommon(StatementIndex stindex, bindparams & params,
PgSqlLeaseMgr::updateLeaseCommon(StatementIndex stindex, BindParams & params,
const LeasePtr& lease) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_ADD_ADDR4).arg(statements_[stindex].stmt_name);
......@@ -1062,23 +1013,29 @@ PgSqlLeaseMgr::updateLeaseCommon(StatementIndex stindex, bindparams & params,
vector<int> formats_;
convertToQuery(params, params_, lengths_, formats_);
PGresult * r = PQexecPrepared(status, statements_[stindex].stmt_name,
PGresult * r = PQexecPrepared(conn_, statements_[stindex].stmt_name,
statements_[stindex].stmt_nbparams,
&params_[0], &lengths_[0], &formats_[0], 0);
checkError(r, stindex, "unable to bind UPDATE parameters");
int affected_rows = boost::lexical_cast<int>(PQcmdTuples(r));
checkStatementError(r, stindex);
int affected_rows = boost::lexical_cast<int>(PQcmdTuples(r));
PQclear(r);
if (!affected_rows) {
// Check success case first as it is the most likely outcome.
if (affected_rows == 1) {
return;
}
// If no rows affected, lease doesn't exist.
if (affected_rows == 0) {
isc_throw(NoSuchLease, "unable to update lease for address " <<
lease->addr_.toText() << " as it does not exist");
} else if (affected_rows > 1) {
// Should not happen - primary key constraint should only have selected
// one row.
isc_throw(DbOperationError, "apparently updated more than one lease "
"that had the address " << lease->addr_.toText());
}
// Should not happen - primary key constraint should only have selected
// one row.
isc_throw(DbOperationError, "apparently updated more than one lease "
"that had the address " << lease->addr_.toText());
}
void
......@@ -1090,7 +1047,7 @@ PgSqlLeaseMgr::updateLease4(const Lease4Ptr& lease) {
// Create the MYSQL_BIND array for the data being updated
ostringstream tmp;
bindparams params = exchange4_->createBindForSend(lease);
BindParams params = exchange4_->createBindForSend(lease);
// Set up the WHERE clause and append it to the MYSQL_BIND array
tmp << static_cast<uint32_t>(lease->addr_);
......@@ -1108,7 +1065,7 @@ PgSqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
DHCPSRV_PGSQL_UPDATE_ADDR6).arg(lease->addr_.toText());
// Create the MYSQL_BIND array for the data being updated
bindparams params = exchange6_->createBindForSend(lease);
BindParams params = exchange6_->createBindForSend(lease);
// Set up the WHERE clause and append it to the MYSQL_BIND array
params.push_back(PgSqlParam(lease->addr_.toText()));
......@@ -1118,16 +1075,16 @@ PgSqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
}
bool
PgSqlLeaseMgr::deleteLeaseCommon(StatementIndex stindex, bindparams & params) {
PgSqlLeaseMgr::deleteLeaseCommon(StatementIndex stindex, BindParams & params) {
vector<const char *> params_;