16 #include <boost/static_assert.hpp>
40 "DELETE FROM lease4 WHERE address = $1"},
44 "delete_lease4_state_expired",
46 "WHERE state = $1 AND expire < $2"},
51 "DELETE FROM lease6 WHERE address = $1"},
55 "delete_lease6_state_expired",
57 "WHERE state = $1 AND expire < $2"},
62 "SELECT address, hwaddr, client_id, "
63 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
64 "fqdn_fwd, fqdn_rev, hostname, "
65 "state, user_context "
71 "SELECT address, hwaddr, client_id, "
72 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
73 "fqdn_fwd, fqdn_rev, hostname, "
74 "state, user_context "
76 "WHERE address = $1"},
80 "get_lease4_clientid",
81 "SELECT address, hwaddr, client_id, "
82 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
83 "fqdn_fwd, fqdn_rev, hostname, "
84 "state, user_context "
86 "WHERE client_id = $1"},
90 "get_lease4_clientid_subid",
91 "SELECT address, hwaddr, client_id, "
92 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
93 "fqdn_fwd, fqdn_rev, hostname, "
94 "state, user_context "
96 "WHERE client_id = $1 AND subnet_id = $2"},
101 "SELECT address, hwaddr, client_id, "
102 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
103 "fqdn_fwd, fqdn_rev, hostname, "
104 "state, user_context "
106 "WHERE hwaddr = $1"},
110 "get_lease4_hwaddr_subid",
111 "SELECT address, hwaddr, client_id, "
112 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
113 "fqdn_fwd, fqdn_rev, hostname, "
114 "state, user_context "
116 "WHERE hwaddr = $1 AND subnet_id = $2"},
121 "SELECT address, hwaddr, client_id, "
122 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
123 "fqdn_fwd, fqdn_rev, hostname, "
124 "state, user_context "
126 "WHERE address > $1 "
133 "SELECT address, hwaddr, client_id, "
134 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
135 "fqdn_fwd, fqdn_rev, hostname, "
136 "state, user_context "
138 "WHERE subnet_id = $1"},
143 "SELECT address, hwaddr, client_id, "
144 "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
145 "fqdn_fwd, fqdn_rev, hostname, "
146 "state, user_context "
148 "WHERE state != $1 AND expire < $2 "
155 "SELECT address, duid, valid_lifetime, "
156 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
157 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
158 "hwaddr, hwtype, hwaddr_source, "
159 "state, user_context "
165 "SELECT address, duid, valid_lifetime, "
166 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
167 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
168 "hwaddr, hwtype, hwaddr_source, "
169 "state, user_context "
171 "WHERE address = $1 AND lease_type = $2"},
175 "get_lease6_duid_iaid",
176 "SELECT address, duid, valid_lifetime, "
177 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
178 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
179 "hwaddr, hwtype, hwaddr_source, "
180 "state, user_context "
182 "WHERE duid = $1 AND iaid = $2 AND lease_type = $3"},
186 "get_lease6_duid_iaid_subid",
187 "SELECT address, duid, valid_lifetime, "
188 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
189 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
190 "hwaddr, hwtype, hwaddr_source, "
191 "state, user_context "
193 "WHERE lease_type = $1 "
194 "AND duid = $2 AND iaid = $3 AND subnet_id = $4"},
199 "SELECT address, duid, valid_lifetime, "
200 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
201 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
202 "hwaddr, hwtype, hwaddr_source, "
203 "state, user_context "
205 "WHERE address > $1 "
212 "SELECT address, duid, valid_lifetime, "
213 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
214 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
215 "hwaddr, hwtype, hwaddr_source, "
216 "state, user_context "
218 "WHERE subnet_id = $1"},
223 "SELECT address, duid, valid_lifetime, "
224 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
225 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
226 "hwaddr, hwtype, hwaddr_source, "
227 "state, user_context "
234 "SELECT address, duid, valid_lifetime, "
235 "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
236 "lease_type, iaid, prefix_len, "
237 "fqdn_fwd, fqdn_rev, hostname, "
238 "hwaddr, hwtype, hwaddr_source, "
239 "state, user_context "
241 "WHERE state != $1 AND expire < $2 "
249 "INSERT INTO lease4(address, hwaddr, client_id, "
250 "valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, "
251 "state, user_context) "
252 "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)"},
259 "INSERT INTO lease6(address, duid, valid_lifetime, "
260 "expire, subnet_id, pref_lifetime, "
261 "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
262 "hwaddr, hwtype, hwaddr_source, "
263 "state, user_context) "
264 "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)"},
270 "UPDATE lease4 SET address = $1, hwaddr = $2, "
271 "client_id = $3, valid_lifetime = $4, expire = $5, "
272 "subnet_id = $6, fqdn_fwd = $7, fqdn_rev = $8, hostname = $9, "
273 "state = $10, user_context = $11 "
274 "WHERE address = $12"},
282 "UPDATE lease6 SET address = $1, duid = $2, "
283 "valid_lifetime = $3, expire = $4, subnet_id = $5, "
284 "pref_lifetime = $6, lease_type = $7, iaid = $8, "
285 "prefix_len = $9, fqdn_fwd = $10, fqdn_rev = $11, hostname = $12, "
286 "hwaddr = $13, hwtype = $14, hwaddr_source = $15, "
287 "state = $16, user_context = $17 "
288 "WHERE address = $18"},
292 "SELECT subnet_id, state, leases as state_count"
293 " FROM lease4_stat ORDER BY subnet_id, state"},
297 "subnet_lease4_stats",
298 "SELECT subnet_id, state, leases as state_count"
300 " WHERE subnet_id = $1 "
305 "subnet_range_lease4_stats",
306 "SELECT subnet_id, state, leases as state_count"
308 " WHERE subnet_id >= $1 and subnet_id <= $2 "
309 " ORDER BY subnet_id, state"},
314 "SELECT subnet_id, lease_type, state, leases as state_count"
315 " FROM lease6_stat ORDER BY subnet_id, lease_type, state" },
319 "subnet_lease6_stats",
320 "SELECT subnet_id, lease_type, state, leases as state_count"
322 " WHERE subnet_id = $1 "
323 " ORDER BY lease_type, state" },
327 "subnet_range_lease6_stats",
328 "SELECT subnet_id, lease_type, state, leases as state_count"
330 " WHERE subnet_id >= $1 and subnet_id <= $2 "
331 " ORDER BY subnet_id, lease_type, state" },
333 { 0, { 0 }, NULL, NULL}
349 : addr_str_(
""), valid_lifetime_(0), valid_lifetime_str_(
""),
350 expire_(0), expire_str_(
""), subnet_id_(0), subnet_id_str_(
""),
351 cltt_(0), fqdn_fwd_(false), fqdn_rev_(false), hostname_(
""),
352 state_str_(
""), user_context_(
"") {
384 static const size_t ADDRESS_COL = 0;
385 static const size_t HWADDR_COL = 1;
386 static const size_t CLIENT_ID_COL = 2;
387 static const size_t VALID_LIFETIME_COL = 3;
388 static const size_t EXPIRE_COL = 4;
389 static const size_t SUBNET_ID_COL = 5;
390 static const size_t FQDN_FWD_COL = 6;
391 static const size_t FQDN_REV_COL = 7;
392 static const size_t HOSTNAME_COL = 8;
393 static const size_t STATE_COL = 9;
394 static const size_t USER_CONTEXT_COL = 10;
396 static const size_t LEASE_COLUMNS = 11;
402 : lease_(), addr4_(0), hwaddr_length_(0), hwaddr_(hwaddr_length_),
403 client_id_length_(0) {
405 BOOST_STATIC_ASSERT(9 < LEASE_COLUMNS);
407 memset(hwaddr_buffer_, 0,
sizeof(hwaddr_buffer_));
408 memset(client_id_buffer_, 0,
sizeof(client_id_buffer_));
411 columns_.push_back(
"address");
412 columns_.push_back(
"hwaddr");
413 columns_.push_back(
"client_id");
414 columns_.push_back(
"valid_lifetime");
415 columns_.push_back(
"expire");
416 columns_.push_back(
"subnet_id");
417 columns_.push_back(
"fqdn_fwd");
418 columns_.push_back(
"fqdn_rev");
419 columns_.push_back(
"hostname");
420 columns_.push_back(
"state");
421 columns_.push_back(
"user_context");
445 addr_str_ = boost::lexical_cast<std::string>
446 (lease->addr_.toUint32());
447 bind_array.
add(addr_str_);
449 if (lease->hwaddr_ && !lease->hwaddr_->hwaddr_.empty()) {
452 if (lease->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
454 << lease_->hwaddr_->hwaddr_.size()
455 <<
" exceeds maximum allowed of: "
456 << HWAddr::MAX_HWADDR_LEN);
458 bind_array.
add(lease->hwaddr_->hwaddr_);
463 if (lease->client_id_) {
464 bind_array.
add(lease->client_id_->getClientId());
469 valid_lifetime_str_ = boost::lexical_cast<std::string>(lease->valid_lft_);
470 bind_array.
add(valid_lifetime_str_);
472 expire_str_ = convertToDatabaseTime(lease->cltt_, lease_->valid_lft_);
473 bind_array.
add(expire_str_);
475 subnet_id_str_ = boost::lexical_cast<std::string>(lease->subnet_id_);
476 bind_array.
add(subnet_id_str_);
478 bind_array.
add(lease->fqdn_fwd_);
480 bind_array.
add(lease->fqdn_rev_);
482 bind_array.
add(lease->hostname_);
484 state_str_ = boost::lexical_cast<std::string>(lease->state_);
485 bind_array.
add(state_str_);
489 user_context_ = ctx->str();
493 bind_array.
add(user_context_);
495 }
catch (
const std::exception& ex) {
497 "Could not create bind array from Lease4: "
498 << lease_->addr_.toText() <<
", reason: " << ex.
what());
512 getColumnValue(r, row, ADDRESS_COL, addr4_);
514 convertFromBytea(r, row, HWADDR_COL, hwaddr_buffer_,
515 sizeof(hwaddr_buffer_), hwaddr_length_);
517 convertFromBytea(r, row, CLIENT_ID_COL, client_id_buffer_,
518 sizeof(client_id_buffer_), client_id_length_);
520 getColumnValue(r, row, VALID_LIFETIME_COL, valid_lifetime_);
522 expire_ = convertFromDatabaseTime(getRawColumnValue(r, row,
525 getColumnValue(r, row , SUBNET_ID_COL, subnet_id_);
527 cltt_ = expire_ - valid_lifetime_;
529 getColumnValue(r, row, FQDN_FWD_COL, fqdn_fwd_);
531 getColumnValue(r, row, FQDN_REV_COL, fqdn_rev_);
533 hostname_ = getRawColumnValue(r, row, HOSTNAME_COL);
536 getColumnValue(r, row , STATE_COL, state);
541 user_context_ = getRawColumnValue(r, row, USER_CONTEXT_COL);
543 if (!user_context_.empty()) {
544 ctx = Element::fromJSON(user_context_);
545 if (!ctx || (ctx->getType() != Element::map)) {
547 <<
"' is not a JSON map");
552 client_id_buffer_, client_id_length_,
553 valid_lifetime_, 0, 0, cltt_,
554 subnet_id_, fqdn_fwd_, fqdn_rev_,
557 result->state_ = state;
560 result->setContext(ctx);
564 }
catch (
const std::exception& ex) {
566 "Could not convert data to Lease4, reason: "
579 size_t hwaddr_length_;
580 std::vector<uint8_t> hwaddr_;
581 uint8_t hwaddr_buffer_[HWAddr::MAX_HWADDR_LEN];
582 size_t client_id_length_;
583 uint8_t client_id_buffer_[ClientId::MAX_CLIENT_ID_LEN];
595 static const int ADDRESS_COL = 0;
596 static const int DUID_COL = 1;
597 static const int VALID_LIFETIME_COL = 2;
598 static const int EXPIRE_COL = 3;
599 static const int SUBNET_ID_COL = 4;
600 static const int PREF_LIFETIME_COL = 5;
601 static const int LEASE_TYPE_COL = 6;
602 static const int IAID_COL = 7;
603 static const int PREFIX_LEN_COL = 8;
604 static const int FQDN_FWD_COL = 9;
605 static const int FQDN_REV_COL = 10;
606 static const int HOSTNAME_COL = 11;
607 static const int HWADDR_COL = 12;
608 static const int HWTYPE_COL = 13;
609 static const int HWADDR_SOURCE_COL = 14;
610 static const int STATE_COL = 15;
611 static const size_t USER_CONTEXT_COL = 16;
613 static const size_t LEASE_COLUMNS = 17;
618 : lease_(), duid_length_(0), duid_(), iaid_u_(0), iaid_str_(
""),
619 lease_type_(
Lease6::TYPE_NA), lease_type_str_(
""), prefix_len_(0),
620 prefix_len_str_(
""), pref_lifetime_(0), preferred_lifetime_str_(
"") {
622 BOOST_STATIC_ASSERT(15 < LEASE_COLUMNS);
624 memset(duid_buffer_, 0,
sizeof(duid_buffer_));
627 columns_.push_back(
"address");
628 columns_.push_back(
"duid");
629 columns_.push_back(
"valid_lifetime");
630 columns_.push_back(
"expire");
631 columns_.push_back(
"subnet_id");
632 columns_.push_back(
"pref_lifetime");
633 columns_.push_back(
"lease_type");
634 columns_.push_back(
"iaid");
635 columns_.push_back(
"prefix_len");
636 columns_.push_back(
"fqdn_fwd");
637 columns_.push_back(
"fqdn_rev");
638 columns_.push_back(
"hostname");
639 columns_.push_back(
"hwaddr");
640 columns_.push_back(
"hwtype");
641 columns_.push_back(
"hwaddr_source");
642 columns_.push_back(
"state");
643 columns_.push_back(
"user_context");
666 addr_str_ = lease_->addr_.toText();
667 bind_array.
add(addr_str_);
670 bind_array.
add(lease_->duid_->getDuid());
675 valid_lifetime_str_ = boost::lexical_cast<std::string>(lease->valid_lft_);
676 bind_array.
add(valid_lifetime_str_);
678 expire_str_ = convertToDatabaseTime(lease->cltt_, lease_->valid_lft_);
679 bind_array.
add(expire_str_);
681 subnet_id_str_ = boost::lexical_cast<std::string>(lease->subnet_id_);
682 bind_array.
add(subnet_id_str_);
684 preferred_lifetime_str_ = boost::lexical_cast<std::string>(lease_->preferred_lft_);
685 bind_array.
add(preferred_lifetime_str_);
687 lease_type_str_ = boost::lexical_cast<std::string>(lease_->type_);
688 bind_array.
add(lease_type_str_);
693 iaid_u_.uval_ = lease_->iaid_;
694 iaid_str_ = boost::lexical_cast<std::string>(iaid_u_.ival_);
695 bind_array.
add(iaid_str_);
697 prefix_len_str_ = boost::lexical_cast<std::string>
698 (
static_cast<unsigned int>(lease_->prefixlen_));
699 bind_array.
add(prefix_len_str_);
701 bind_array.
add(lease->fqdn_fwd_);
703 bind_array.
add(lease->fqdn_rev_);
705 bind_array.
add(lease->hostname_);
707 if (lease->hwaddr_ && !lease->hwaddr_->hwaddr_.empty()) {
710 if (lease->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
712 << lease_->hwaddr_->hwaddr_.size()
713 <<
" exceeds maximum allowed of: "
714 << HWAddr::MAX_HWADDR_LEN);
716 bind_array.
add(lease->hwaddr_->hwaddr_);
721 if (lease->hwaddr_) {
722 hwtype_str_ = boost::lexical_cast<std::string>
723 (
static_cast<unsigned int>(lease_->hwaddr_->htype_));
724 hwaddr_source_str_ = boost::lexical_cast<std::string>
725 (
static_cast<unsigned int>(lease_->hwaddr_->source_));
727 hwtype_str_ = boost::lexical_cast<std::string>
729 hwaddr_source_str_ = boost::lexical_cast<std::string>
730 (
static_cast<unsigned int>(HWAddr::HWADDR_SOURCE_UNKNOWN));
733 bind_array.
add(hwtype_str_);
735 bind_array.
add(hwaddr_source_str_);
737 state_str_ = boost::lexical_cast<std::string>(lease->state_);
738 bind_array.
add(state_str_);
742 user_context_ = ctx->str();
746 bind_array.
add(user_context_);
748 }
catch (
const std::exception& ex) {
750 "Could not create bind array from Lease6: "
751 << lease_->addr_.toText() <<
", reason: " << ex.
what());
776 convertFromBytea(r, row, DUID_COL, duid_buffer_,
sizeof(duid_buffer_), duid_length_);
777 DuidPtr duid_ptr(
new DUID(duid_buffer_, duid_length_));
779 getColumnValue(r, row, VALID_LIFETIME_COL, valid_lifetime_);
781 expire_ = convertFromDatabaseTime(getRawColumnValue(r, row,
784 cltt_ = expire_ - valid_lifetime_;
786 getColumnValue(r, row , SUBNET_ID_COL, subnet_id_);
788 getColumnValue(r, row , PREF_LIFETIME_COL, pref_lifetime_);
790 getLeaseTypeColumnValue(r, row, LEASE_TYPE_COL, lease_type_);
792 getColumnValue(r, row , IAID_COL, iaid_u_.ival_);
794 getColumnValue(r, row , PREFIX_LEN_COL, prefix_len_);
796 getColumnValue(r, row, FQDN_FWD_COL, fqdn_fwd_);
798 getColumnValue(r, row, FQDN_REV_COL, fqdn_rev_);
800 hostname_ = getRawColumnValue(r, row, HOSTNAME_COL);
802 convertFromBytea(r, row, HWADDR_COL, hwaddr_buffer_,
803 sizeof(hwaddr_buffer_), hwaddr_length_);
805 getColumnValue(r, row , HWTYPE_COL, hwtype_);
807 getColumnValue(r, row , HWADDR_SOURCE_COL, hwaddr_source_);
811 if (hwaddr_length_) {
812 hwaddr.reset(
new HWAddr(hwaddr_buffer_, hwaddr_length_,
815 hwaddr->source_ = hwaddr_source_;
819 getColumnValue(r, row , STATE_COL, state);
821 user_context_ = getRawColumnValue(r, row, USER_CONTEXT_COL);
823 if (!user_context_.empty()) {
824 ctx = Element::fromJSON(user_context_);
825 if (!ctx || (ctx->getType() != Element::map)) {
827 <<
"' is not a JSON map");
832 iaid_u_.uval_, pref_lifetime_,
833 valid_lifetime_, 0, 0,
834 subnet_id_, fqdn_fwd_, fqdn_rev_,
835 hostname_, hwaddr, prefix_len_));
836 result->cltt_ = cltt_;
838 result->state_ = state;
841 result->setContext(ctx);
845 }
catch (
const std::exception& ex) {
847 "Could not convert data to Lease6, reason: "
866 uint32_t raw_value = 0;
867 getColumnValue(r, row , col, raw_value);
869 case Lease6::TYPE_NA:
870 case Lease6::TYPE_TA:
871 case Lease6::TYPE_PD:
877 <<
" for: " << getColumnLabel(r, col) <<
" row:" << row);
890 vector<uint8_t> duid_;
891 uint8_t duid_buffer_[DUID::MAX_DUID_LEN];
900 Uiaid(uint32_t val) : uval_(val){};
901 Uiaid(int32_t val) : ival_(val){};
906 std::string iaid_str_;
907 Lease6::Type lease_type_;
908 std::string lease_type_str_;
910 std::string prefix_len_str_;
911 uint32_t pref_lifetime_;
912 std::string preferred_lifetime_str_;
913 size_t hwaddr_length_;
914 vector<uint8_t> hwaddr_;
915 uint8_t hwaddr_buffer_[HWAddr::MAX_HWADDR_LEN];
917 std::string hwtype_str_;
918 uint32_t hwaddr_source_;
919 std::string hwaddr_source_str_;
939 const bool fetch_type)
940 : conn_(conn), statement_(statement), result_set_(), next_row_(0),
941 fetch_type_(fetch_type) {
953 const bool fetch_type,
const SubnetID& subnet_id)
954 :
LeaseStatsQuery(subnet_id), conn_(conn), statement_(statement), result_set_(),
955 next_row_(0), fetch_type_(fetch_type) {
969 const bool fetch_type,
const SubnetID& first_subnet_id,
971 :
LeaseStatsQuery(first_subnet_id, last_subnet_id), conn_(conn), statement_(statement),
972 result_set_(), next_row_(0), fetch_type_(fetch_type) {
989 if (getSelectMode() == ALL_SUBNETS) {
991 result_set_.reset(
new PgSqlResult(PQexecPrepared(conn_, statement_.name,
998 std::string subnet_id_str = boost::lexical_cast<std::string>(getFirstSubnetID());
999 parms.
add(subnet_id_str);
1002 if (getSelectMode() == SUBNET_RANGE) {
1004 string subnet_id_str = boost::lexical_cast<std::string>(getLastSubnetID());
1005 parms.
add(subnet_id_str);
1009 result_set_.reset(
new PgSqlResult(PQexecPrepared(conn_, statement_.name,
1014 conn_.checkStatementError(*result_set_, statement_);
1030 if (next_row_ >= result_set_->getRows()) {
1037 PgSqlExchange::getColumnValue(*result_set_, next_row_, col, subnet_id);
1043 uint32_t lease_type;
1044 PgSqlExchange::getColumnValue(*result_set_, next_row_ , col,
1053 PgSqlExchange::getColumnValue(*result_set_, next_row_ , col,
1058 PgSqlExchange::getColumnValue(*result_set_, next_row_, col,
1091 std::pair<uint32_t, uint32_t> db_version =
getVersion();
1092 if (code_version != db_version) {
1094 "PostgreSQL schema version mismatch: need version: "
1095 << code_version.first <<
"." << code_version.second
1096 <<
" found version: " << db_version.first <<
"."
1097 << db_version.second);
1118 std::stringstream tmp;
1121 tmp <<
", library " << PQlibVersion();
1126 PgSqlLeaseMgr::addLeaseCommon(StatementIndex stindex,
1134 int s = PQresultStatus(r);
1136 if (s != PGRES_COMMAND_OK) {
1140 if (conn_.
compareError(r, PgSqlConnection::DUPLICATE_KEY)) {
1153 DHCPSRV_PGSQL_ADD_ADDR4).arg(lease->addr_.toText());
1156 exchange4_->createBindForSend(lease, bind_array);
1163 DHCPSRV_PGSQL_ADD_ADDR6).arg(lease->addr_.toText());
1165 exchange6_->createBindForSend(lease, bind_array);
1170 template <
typename Exchange,
typename LeaseCollection>
1171 void PgSqlLeaseMgr::getLeaseCollection(StatementIndex stindex,
1174 LeaseCollection& result,
1175 bool single)
const {
1178 n > 0 ? &bind_array.
values_[0] : NULL,
1179 n > 0 ? &bind_array.
lengths_[0] : NULL,
1180 n > 0 ? &bind_array.
formats_[0] : NULL, 0));
1184 int rows = PQntuples(r);
1185 if (single && rows > 1) {
1187 "database where only one was expected for query "
1191 for(
int i = 0; i < rows; ++ i) {
1192 result.push_back(exchange->convertFromDatabase(r, i));
1197 PgSqlLeaseMgr::getLease(StatementIndex stindex,
PsqlBindArray& bind_array,
1205 getLeaseCollection(stindex, bind_array, exchange4_, collection,
true);
1208 if (collection.empty()) {
1211 result = *collection.begin();
1216 PgSqlLeaseMgr::getLease(StatementIndex stindex,
PsqlBindArray& bind_array,
1224 getLeaseCollection(stindex, bind_array, exchange6_, collection,
true);
1227 if (collection.empty()) {
1230 result = *collection.begin();
1237 DHCPSRV_PGSQL_GET_ADDR4).arg(addr.
toText());
1243 std::string addr_str = boost::lexical_cast<std::string>
1245 bind_array.
add(addr_str);
1257 DHCPSRV_PGSQL_GET_HWADDR).arg(hwaddr.
toText());
1263 if (!hwaddr.
hwaddr_.empty()) {
1279 DHCPSRV_PGSQL_GET_SUBID_HWADDR)
1280 .arg(subnet_id).arg(hwaddr.
toText());
1286 if (!hwaddr.
hwaddr_.empty()) {
1293 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
1294 bind_array.
add(subnet_id_str);
1306 DHCPSRV_PGSQL_GET_CLIENTID).arg(clientid.
toText());
1328 " called, but it is not implemented");
1334 DHCPSRV_PGSQL_GET_SUBID_CLIENTID)
1335 .arg(subnet_id).arg(clientid.
toText());
1344 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
1345 bind_array.
add(subnet_id_str);
1363 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
1364 bind_array.
add(subnet_id_str);
1381 getLeaseCollection(
GET_LEASE4, bind_array, result);
1390 if (!lower_bound_address.
isV4()) {
1392 "retrieving leases from the lease database, got "
1393 << lower_bound_address);
1398 .arg(lower_bound_address.
toText());
1404 std::string lb_address_data = boost::lexical_cast<std::string>
1406 bind_array.
add(lb_address_data);
1409 std::string page_size_data = boost::lexical_cast<std::string>(page_size.
page_size_);
1410 bind_array.
add(page_size_data);
1423 .arg(addr.
toText()).arg(lease_type);
1429 std::string addr_str = addr.
toText();
1430 bind_array.
add(addr_str);
1433 std::string type_str_ = boost::lexical_cast<std::string>(lease_type);
1434 bind_array.
add(type_str_);
1445 uint32_t iaid)
const {
1447 DHCPSRV_PGSQL_GET_IAID_DUID)
1448 .arg(iaid).arg(duid.
toText()).arg(lease_type);
1457 std::string iaid_str = boost::lexical_cast<std::string>(iaid);
1458 bind_array.
add(iaid_str);
1461 std::string lease_type_str = boost::lexical_cast<std::string>(lease_type);
1462 bind_array.
add(lease_type_str);
1473 uint32_t iaid,
SubnetID subnet_id)
const {
1475 DHCPSRV_PGSQL_GET_IAID_SUBID_DUID)
1476 .arg(iaid).arg(subnet_id).arg(duid.
toText()).arg(lease_type);
1482 std::string lease_type_str = boost::lexical_cast<std::string>(lease_type);
1483 bind_array.
add(lease_type_str);
1489 std::string iaid_str = boost::lexical_cast<std::string>(iaid);
1490 bind_array.
add(iaid_str);
1493 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
1494 bind_array.
add(subnet_id_str);
1512 std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
1513 bind_array.
add(subnet_id_str);
1525 DHCPSRV_PGSQL_GET_DUID)
1549 getLeaseCollection(
GET_LEASE6, bind_array, result);
1558 if (!lower_bound_address.
isV6()) {
1560 "retrieving leases from the lease database, got "
1561 << lower_bound_address);
1566 .arg(lower_bound_address.
toText());
1574 std::string lb_address_data =
"0";
1575 if (!lower_bound_address.
isV6Zero()) {
1576 lb_address_data = lower_bound_address.
toText();
1580 bind_array.
add(lb_address_data);
1583 std::string page_size_data = boost::lexical_cast<std::string>(page_size.
page_size_);
1584 bind_array.
add(page_size_data);
1595 const size_t max_leases)
const {
1603 const size_t max_leases)
const {
1609 template<
typename LeaseCollection>
1611 PgSqlLeaseMgr::getExpiredLeasesCommon(LeaseCollection& expired_leases,
1612 const size_t max_leases,
1613 StatementIndex statement_index)
const {
1618 bind_array.
add(state_str);
1622 bind_array.
add(timestamp_str);
1626 uint32_t limit = max_leases > 0 ?
static_cast<uint32_t
>(max_leases) :
1627 std::numeric_limits<uint32_t>::max();
1628 std::string limit_str = boost::lexical_cast<std::string>(limit);
1629 bind_array.
add(limit_str);
1632 getLeaseCollection(statement_index, bind_array, expired_leases);
1635 template<
typename LeasePtr>
1637 PgSqlLeaseMgr::updateLeaseCommon(StatementIndex stindex,
1651 int affected_rows = boost::lexical_cast<int>(PQcmdTuples(r));
1654 if (affected_rows == 1) {
1659 if (affected_rows == 0) {
1661 lease->addr_.toText() <<
" as it does not exist");
1667 "that had the address " << lease->addr_.toText());
1675 DHCPSRV_PGSQL_UPDATE_ADDR4).arg(lease->addr_.toText());
1679 exchange4_->createBindForSend(lease, bind_array);
1682 std::string addr4_ = boost::lexical_cast<std::string>
1683 (lease->addr_.toUint32());
1684 bind_array.
add(addr4_);
1687 updateLeaseCommon(stindex, bind_array, lease);
1695 DHCPSRV_PGSQL_UPDATE_ADDR6).arg(lease->addr_.toText());
1699 exchange6_->createBindForSend(lease, bind_array);
1702 std::string addr_str = lease->addr_.toText();
1703 bind_array.
add(addr_str);
1706 updateLeaseCommon(stindex, bind_array, lease);
1710 PgSqlLeaseMgr::deleteLeaseCommon(StatementIndex stindex,
1719 int affected_rows = boost::lexical_cast<int>(PQcmdTuples(r));
1721 return (affected_rows);
1727 DHCPSRV_PGSQL_DELETE_ADDR).arg(addr.
toText());
1733 std::string addr4_str = boost::lexical_cast<std::string>
1735 bind_array.
add(addr4_str);
1739 std::string addr6_str = addr.
toText();
1740 bind_array.
add(addr6_str);
1747 DHCPSRV_PGSQL_DELETE_EXPIRED_RECLAIMED4)
1755 DHCPSRV_PGSQL_DELETE_EXPIRED_RECLAIMED6)
1761 PgSqlLeaseMgr::deleteExpiredReclaimedLeasesCommon(
const uint32_t secs,
1762 StatementIndex statement_index) {
1767 bind_array.
add(state_str);
1770 std::string expiration_str =
1772 bind_array.
add(expiration_str);
1775 return (deleteLeaseCommon(statement_index, bind_array));
1800 false, first_subnet_id, last_subnet_id));
1827 true, first_subnet_id, last_subnet_id));
1855 return (
string(
"PostgreSQL Database"));
1858 pair<uint32_t, uint32_t>
1861 DHCPSRV_PGSQL_GET_VERSION);
1863 const char* version_sql =
"SELECT version, minor FROM schema_version;";
1865 if(PQresultStatus(r) != PGRES_TUPLES_OK) {
1867 << version_sql <<
", reason: " << PQerrorMessage(conn_));
1872 tmp.str(PQgetvalue(r, 0, 0));
1878 tmp.str(PQgetvalue(r, 0, 1));
1881 return (make_pair(
version, minor));