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:
872 value = static_cast<Lease6::Type>(raw_value);
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);
1038 row.
subnet_id_ = static_cast<SubnetID>(subnet_id);
1043 uint32_t lease_type;
1044 PgSqlExchange::getColumnValue(*result_set_, next_row_ , col,
1046 row.
lease_type_ = static_cast<Lease::Type>(lease_type);
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));
virtual ~PgSqlLeaseMgr()
Destructor (closes database)
PgSqlLeaseStatsQuery(PgSqlConnection &conn, PgSqlTaggedStatement &statement, const bool fetch_type, const SubnetID &subnet_id)
Constructor to query for a single subnet's stats.
boost::shared_ptr< DUID > DuidPtr
RAII wrapper for PostgreSQL Result sets.
boost::shared_ptr< LeaseStatsQuery > LeaseStatsQueryPtr
Defines a pointer to a LeaseStatsQuery.
void createBindForSend(const Lease6Ptr &lease, PsqlBindArray &bind_array)
Creates the bind array for sending Lease6 data to the database.
A generic exception that is thrown when a function is not implemented.
static const uint32_t STATE_EXPIRED_RECLAIMED
Expired and reclaimed lease.
const std::vector< uint8_t > & getClientId() const
Returns reference to the client-id data.
Structure that holds a lease for IPv4 address.
static std::string convertToDatabaseTime(const time_t input_time)
Converts time_t value to a text representation in local time.
virtual std::string getName() const
Returns name of the database.
std::string valid_lifetime_str_
void getLeaseTypeColumnValue(const PgSqlResult &r, const int row, const size_t col, Lease6::Type &value) const
Fetches an integer text column as a Lease6::Type.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
std::vector< int > formats_
Vector of "format" for each value.
boost::shared_ptr< PgSqlResult > result_set_
The result set returned by Postgres.
uint32_t next_row_
Index of the next row to fetch.
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID &subnet_id)
Creates and runs the IPv6 lease stats query for a single subnet.
bool getNextRow(LeaseStatsRow &row)
Fetches the next row in the result set.
Base class for marshalling leases to and from PostgreSQL.
std::vector< int > lengths_
Vector of data lengths for each value.
std::string user_context_
Attempt to update lease that was not there.
bool compareError(const PgSqlResult &r, const char *error_state)
Checks a result set's SQL state against an error state.
virtual std::pair< uint32_t, uint32_t > getVersion() const
Returns backend version.
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs)
Deletes all expired-reclaimed DHCPv6 leases.
std::vector< uint8_t > hwaddr_
Base class for fulfilling a statistical lease data query.
Base class for marshalling data to and from PostgreSQL.
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Creates and runs the IPv6 lease stats query for a single subnet.
PgSqlLease4Exchange()
Default constructor.
void createBindForSend(const Lease4Ptr &lease, PsqlBindArray &bind_array)
Creates the bind array for sending Lease4 data to the database.
boost::shared_ptr< Lease > LeasePtr
Pointer to the lease object.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
std::vector< const char * > values_
Vector of pointers to the data values.
Holds DUID (DHCPv6 Unique Identifier)
Exception thrown on failure to open database.
not specified or undefined
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery4(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Creates and runs the IPv4 lease stats query for a single subnet.
void commit()
Commit Transactions.
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID &subnet_id)
Creates and runs the IPv4 lease stats query for a single subnet.
TaggedStatementArray tagged_statements
Prepared MySQL statements used by the backend to insert and retrieve hosts from the database.
Multiple lease records found where one expected.
Lease6Ptr convertFromDatabase(const PgSqlResult &r, int row)
Creates a Lease6 object from a given row in a result set.
virtual void getExpiredLeases6(Lease6Collection &expired_leases, const size_t max_leases) const
Returns a collection of expired DHCPv6 leases.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
void add(const char *value)
Adds a char array to bind array based.
virtual void updateLease4(const Lease4Ptr &lease4)
Updates IPv4 lease.
const size_t page_size_
Holds page size.
const uint32_t PG_SCHEMA_VERSION_MINOR
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
std::string subnet_id_str_
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
bool isV6Zero() const
Convenience function to check if it is an IPv4 zero address.
SubnetID subnet_id_
The subnet ID to which this data applies.
static std::string getDBVersion()
Local version of getDBVersion() class method.
void rollback()
Rollback Transactions.
virtual void updateLease6(const Lease6Ptr &lease6)
Updates IPv6 lease.
virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs)
Deletes all expired-reclaimed DHCPv4 leases.
boost::shared_ptr< const Element > ConstElementPtr
Structure that holds a lease for IPv6 address and/or prefix.
PgSqlTaggedStatement & statement_
The query's prepared statement.
std::string getParameter(const std::string &name) const
Returns value of a connection parameter.
virtual size_t wipeLeases6(const SubnetID &subnet_id)
Removed specified IPv6 leases.
virtual LeaseStatsQueryPtr startLeaseStatsQuery4()
Creates and runs the IPv4 lease stats query.
virtual void rollback()
Rollback Transactions.
std::string addr_str_
Common Instance members used for binding and conversion.
Common PgSql Connector Pool.
virtual ~PgSqlLeaseExchange()
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
virtual std::string getDescription() const
Returns description of the backend.
bool isV6() const
Convenience function to check for an IPv6 address.
bool isV4() const
Convenience function to check for an IPv4 address.
const std::vector< uint8_t > & getDuid() const
Returns a const reference to the actual DUID value.
void prepareStatement(const PgSqlTaggedStatement &statement)
Prepare Single Statement.
virtual void getExpiredLeases4(Lease4Collection &expired_leases, const size_t max_leases) const
Returns a collection of expired DHCPv4 leases.
Invalid address family used as input to Lease Manager.
Defines the logger used by the top-level component of kea-dhcp-ddns.
Lease4Ptr convertFromDatabase(const PgSqlResult &r, int row)
Creates a Lease4 object from a given row in a result set.
Define a PostgreSQL statement.
void start()
Creates the lease statistical data result set.
size_t size() const
Fetches the number of entries in the array.
std::string toText() const
Convert the address to a string.
void checkStatementError(const PgSqlResult &r, PgSqlTaggedStatement &statement) const
Checks result of the r object.
PgSqlConnection & conn_
Database connection to use to execute the query.
virtual Lease6Collection getLeases6() const
Returns all IPv6 leases.
uint32_t lease_state_
The lease_state to which the count applies.
Type
Type of lease or pool.
virtual bool deleteLease(const isc::asiolink::IOAddress &addr)
Deletes a lease.
Holds Client identifier or client IPv4 address.
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const
Returns an IPv4 lease for specified IPv4 address.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
StatementIndex
Statement Tags.
Hardware type that represents information from DHCPv4 packet.
PgSqlLeaseStatsQuery(PgSqlConnection &conn, PgSqlTaggedStatement &statement, const bool fetch_type, const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Constructor to query for the stats for a range of subnets.
virtual bool addLease(const Lease4Ptr &lease)
Adds an IPv4 lease.
int64_t state_count_
state_count The count of leases in the lease state
void openDatabase()
Open Database.
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Contains a single row of lease statistical data.
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
Wraps value holding size of the page with leases.
const size_t OID_NONE
Constants for PostgreSQL data types These are defined by PostgreSQL in <catalog/pg_type....
Lease::Type lease_type_
The lease_type to which the count applies.
virtual void commit()
Commit Transactions.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const
Returns existing IPv6 lease for a given IPv6 address.
The IOAddress class represents an IP addresses (version agnostic)
int version()
returns Kea hooks version.
virtual size_t wipeLeases4(const SubnetID &subnet_id)
Removes specified IPv4 leases.
const uint32_t PG_SCHEMA_VERSION_MAJOR
Define PostgreSQL backend version: 5.0.
virtual ~PgSqlLeaseStatsQuery()
Destructor.
Base PgSql derivation of the statistical lease data query.
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
virtual Lease4Collection getLeases4() const
Returns all IPv4 leases.
PgSqlLeaseStatsQuery(PgSqlConnection &conn, PgSqlTaggedStatement &statement, const bool fetch_type)
Constructor to query for all subnets' stats.
const size_t OID_TIMESTAMP
virtual LeaseStatsQueryPtr startLeaseStatsQuery6()
Creates and runs the IPv6 lease stats query.
Supports exchanging IPv6 leases with PostgreSQL.
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
Exception thrown on failure to execute a database function.
Supports exchanging IPv4 leases with PostgreSQL.
std::string toText(bool include_htype=true) const
Returns textual representation of a hardware address (e.g.
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)
bool fetch_type_
Indicates if query supplies lease type.