Commit fe5098fd authored by Francis Dupont's avatar Francis Dupont

[5584] Checkpoint: updated schema, code and partially tests

parent d229ba76
......@@ -1492,6 +1492,7 @@ AC_CONFIG_FILES([Makefile
src/share/database/scripts/Makefile
src/share/database/scripts/cql/Makefile
src/share/database/scripts/cql/upgrade_1.0_to_2.0.sh
src/share/database/scripts/cql/upgrade_2.0_to_2.1.sh
src/share/database/scripts/mysql/Makefile
src/share/database/scripts/mysql/upgrade_1.0_to_2.0.sh
src/share/database/scripts/mysql/upgrade_2.0_to_3.0.sh
......@@ -1501,6 +1502,7 @@ AC_CONFIG_FILES([Makefile
src/share/database/scripts/mysql/upgrade_5.0_to_5.1.sh
src/share/database/scripts/mysql/upgrade_5.1_to_5.2.sh
src/share/database/scripts/mysql/upgrade_5.2_to_6.0.sh
src/share/database/scripts/mysql/upgrade_6.0_to_6.1.sh
src/share/database/scripts/pgsql/Makefile
src/share/database/scripts/pgsql/upgrade_1.0_to_2.0.sh
src/share/database/scripts/pgsql/upgrade_2.0_to_3.0.sh
......@@ -1508,6 +1510,7 @@ AC_CONFIG_FILES([Makefile
src/share/database/scripts/pgsql/upgrade_3.1_to_3.2.sh
src/share/database/scripts/pgsql/upgrade_3.2_to_3.3.sh
src/share/database/scripts/pgsql/upgrade_3.3_to_4.0.sh
src/share/database/scripts/pgsql/upgrade_4.0_to_4.1.sh
tools/Makefile
tools/path_replacer.sh
])
......
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-2017 Deutsche Telekom AG.
//
// Authors: Razvan Becheriu <razvan.becheriu@qualitance.com>
......@@ -48,10 +49,10 @@ constexpr uint32_t CQL_DRIVER_VERSION_MAJOR = CASS_VERSION_MAJOR;
constexpr uint32_t CQL_DRIVER_VERSION_MINOR = CASS_VERSION_MINOR;
/// @}
/// Define CQL schema version: 2.0
/// Define CQL schema version: 2.1
/// @{
constexpr uint32_t CQL_SCHEMA_VERSION_MAJOR = 2u;
constexpr uint32_t CQL_SCHEMA_VERSION_MINOR = 0u;
constexpr uint32_t CQL_SCHEMA_VERSION_MINOR = 1u;
/// @}
/// @brief Defines a single statement or query
......
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-2018 Deutsche Telekom AG.
//
// Authors: Razvan Becheriu <razvan.becheriu@qualitance.com>
......@@ -25,6 +26,7 @@
#include <asiolink/io_address.h>
using namespace isc::data;
using isc::asiolink::IOAddress;
namespace isc {
......@@ -32,6 +34,7 @@ namespace dhcp {
static constexpr size_t HOSTNAME_MAX_LEN = 255u;
static constexpr size_t ADDRESS6_TEXT_MAX_LEN = 39u;
static constexpr char NULL_USER_CONTEXT[] = "";
/// @brief Common CQL and Lease Data Methods
///
......@@ -47,7 +50,7 @@ public:
CqlLeaseExchange(const CqlConnection &connection)
: connection_(connection), valid_lifetime_(0), expire_(0),
subnet_id_(0), fqdn_fwd_(cass_false), fqdn_rev_(cass_false),
state_(0) {
state_(0), user_context_(NULL_USER_CONTEXT) {
}
/// @brief Create BIND array to receive C++ data.
......@@ -96,6 +99,9 @@ protected:
/// @brief Lease state
cass_int32_t state_;
/// @brief User context
std::string user_context_;
};
/// @brief Exchange Lease4 information between Kea and CQL
......@@ -249,9 +255,9 @@ StatementMap CqlLease4Exchange::tagged_statements_{
{INSERT_LEASE4,
"INSERT INTO lease4( "
"address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, state "
"fqdn_fwd, fqdn_rev, hostname, state, user_context "
") VALUES ( "
"?, ?, ?, ?, ?, ?, ?, ?, ?, ? "
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? "
") "
"IF NOT EXISTS "}},
......@@ -267,7 +273,8 @@ StatementMap CqlLease4Exchange::tagged_statements_{
"fqdn_fwd = ?, "
"fqdn_rev = ?, "
"hostname = ?, "
"state = ? "
"state = ?, "
"user_context = ? "
"WHERE address = ? "
"IF EXISTS "}},
......@@ -283,7 +290,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
{GET_LEASE4_EXPIRE,
"SELECT "
"address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, state "
"fqdn_fwd, fqdn_rev, hostname, state, user_context "
"FROM lease4 "
"WHERE state = ? "
"AND expire < ? "
......@@ -295,7 +302,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
{GET_LEASE4,
"SELECT "
"address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, state "
"fqdn_fwd, fqdn_rev, hostname, state, user_context "
"FROM lease4 "}},
// Gets an IPv4 lease with specified IPv4 address
......@@ -303,7 +310,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
{GET_LEASE4_ADDR,
"SELECT "
"address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, state "
"fqdn_fwd, fqdn_rev, hostname, state, user_context "
"FROM lease4 "
"WHERE address = ? "}},
......@@ -312,7 +319,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
{GET_LEASE4_CLIENTID,
"SELECT "
"address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, state "
"fqdn_fwd, fqdn_rev, hostname, state, user_context "
"FROM lease4 "
"WHERE client_id = ? "
"ALLOW FILTERING "}},
......@@ -322,7 +329,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
{GET_LEASE4_CLIENTID_SUBID,
"SELECT "
"address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, state "
"fqdn_fwd, fqdn_rev, hostname, state, user_context "
"FROM lease4 "
"WHERE client_id = ? "
"AND subnet_id = ? "
......@@ -333,7 +340,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
{GET_LEASE4_HWADDR,
"SELECT "
"address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, state "
"fqdn_fwd, fqdn_rev, hostname, state, user_context "
"FROM lease4 "
"WHERE hwaddr = ? "
"ALLOW FILTERING "}},
......@@ -343,7 +350,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
{GET_LEASE4_HWADDR_SUBID,
"SELECT "
"address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, state "
"fqdn_fwd, fqdn_rev, hostname, state, user_context "
"FROM lease4 "
"WHERE hwaddr = ? "
"AND subnet_id = ? "
......@@ -354,7 +361,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
{GET_LEASE4_SUBID,
"SELECT "
"address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, state "
"fqdn_fwd, fqdn_rev, hostname, state, user_context "
"FROM lease4 "
"WHERE subnet_id = ? "
"ALLOW FILTERING "}}
......@@ -437,6 +444,14 @@ CqlLease4Exchange::createBindForInsert(const Lease4Ptr &lease, AnyArray &data) {
// state: int
state_ = static_cast<cass_int32_t>(lease_->state_);
// user_context: text
ConstElementPtr ctx = lease_->getContext();
if (ctx) {
user_context_ = ctx->str();
} else {
user_context_ = NULL_USER_CONTEXT;
}
// Start with a fresh array.
data.clear();
data.add(&address_);
......@@ -449,6 +464,7 @@ CqlLease4Exchange::createBindForInsert(const Lease4Ptr &lease, AnyArray &data) {
data.add(&fqdn_rev_);
data.add(&hostname_);
data.add(&state_);
data.add(&user_context_);
} catch (const Exception &ex) {
isc_throw(DbOperationError, "CqlLease4Exchange::createBindForInsert(): "
......@@ -531,6 +547,14 @@ CqlLease4Exchange::createBindForUpdate(const Lease4Ptr &lease, AnyArray &data,
// state: int
state_ = static_cast<cass_int32_t>(lease_->state_);
// user_context: text
ConstElementPtr ctx = lease_->getContext();
if (ctx) {
user_context_ = ctx->str();
} else {
user_context_ = NULL_USER_CONTEXT;
}
// Start with a fresh array.
data.clear();
data.add(&hwaddr_);
......@@ -542,6 +566,7 @@ CqlLease4Exchange::createBindForUpdate(const Lease4Ptr &lease, AnyArray &data,
data.add(&fqdn_rev_);
data.add(&hostname_);
data.add(&state_);
data.add(&user_context_);
data.add(&address_);
} catch (const Exception &ex) {
......@@ -609,6 +634,9 @@ CqlLease4Exchange::createBindForSelect(AnyArray &data, StatementTag /* unused */
// state: int
data.add(&state_);
// user_context: text
data.add(&user_context_);
}
boost::any
......@@ -645,6 +673,13 @@ CqlLease4Exchange::retrieve() {
uint32_t addr4 = static_cast<uint32_t>(address_);
ConstElementPtr ctx;
if (!user_context_.empty()) {
ctx = Element::fromJSON(user_context_);
isc_throw(BadValue, "user context '" << user_context_
<< "' is not a JSON map");
}
Lease4Ptr result(new Lease4(addr4, hwaddr, client_id_.data(),
client_id_.size(), valid_lifetime_, 0, 0,
cltt, subnet_id_, fqdn_fwd_, fqdn_rev_,
......@@ -652,6 +687,10 @@ CqlLease4Exchange::retrieve() {
result->state_ = state_;
if (ctx) {
result->setContext(ctx);
}
return (result);
} catch (const Exception &ex) {
isc_throw(DbOperationError,
......@@ -885,9 +924,9 @@ StatementMap CqlLease6Exchange::tagged_statements_ = {
"INSERT INTO lease6("
"address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
"lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
"hwaddr_source, state "
"hwaddr_source, state, user_context "
") VALUES ("
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?"
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?"
") "
"IF NOT EXISTS "}},
......@@ -909,7 +948,8 @@ StatementMap CqlLease6Exchange::tagged_statements_ = {
"hwaddr = ?, "
"hwtype = ?, "
"hwaddr_source = ?, "
"state = ? "
"state = ?, "
"user_context = ? "
"WHERE address = ? "
"IF EXISTS "}},
......@@ -926,7 +966,7 @@ StatementMap CqlLease6Exchange::tagged_statements_ = {
"SELECT "
"address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
"lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
"hwaddr_source, state "
"hwaddr_source, state, user_context "
"FROM lease6 "
"WHERE state = ? "
"AND expire < ? "
......@@ -939,7 +979,7 @@ StatementMap CqlLease6Exchange::tagged_statements_ = {
"SELECT "
"address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
"lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
"hwaddr_source, state "
"hwaddr_source, state, user_context "
"FROM lease6 "
"WHERE address = ? "
"AND lease_type = ? "
......@@ -951,7 +991,7 @@ StatementMap CqlLease6Exchange::tagged_statements_ = {
"SELECT "
"address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
"lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
"hwaddr_source, state "
"hwaddr_source, state, user_context "
"FROM lease6 "
"WHERE duid = ? AND iaid = ? "
"AND lease_type = ? "
......@@ -963,7 +1003,7 @@ StatementMap CqlLease6Exchange::tagged_statements_ = {
"SELECT "
"address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
"lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
"hwaddr_source, state "
"hwaddr_source, state, user_context "
"FROM lease6 "
"WHERE duid = ? AND iaid = ? "
"AND lease_type = ? "
......@@ -1072,6 +1112,14 @@ CqlLease6Exchange::createBindForInsert(const Lease6Ptr &lease, AnyArray &data) {
// state: int
state_ = static_cast<cass_int32_t>(lease_->state_);
// user_context: text
ConstElementPtr ctx = lease_->getContext();
if (ctx) {
user_context_ = ctx->str();
} else {
user_context_ = NULL_USER_CONTEXT;
}
// Start with a fresh array.
data.clear();
......@@ -1092,6 +1140,7 @@ CqlLease6Exchange::createBindForInsert(const Lease6Ptr &lease, AnyArray &data) {
data.add(&hwtype_);
data.add(&hwaddr_source_);
data.add(&state_);
data.add(&user_context_);
} catch (const Exception &ex) {
isc_throw(DbOperationError, "CqlLease6Exchange::createBindForInsert(): "
......@@ -1205,6 +1254,14 @@ CqlLease6Exchange::createBindForUpdate(const Lease6Ptr &lease, AnyArray &data,
// state: int
state_ = static_cast<cass_int32_t>(lease_->state_);
// user_context: text
ConstElementPtr ctx = lease_->getContext();
if (ctx) {
user_context_ = ctx->str();
} else {
user_context_ = NULL_USER_CONTEXT;
}
// Start with a fresh array.
data.clear();
......@@ -1224,6 +1281,7 @@ CqlLease6Exchange::createBindForUpdate(const Lease6Ptr &lease, AnyArray &data,
data.add(&hwtype_);
data.add(&hwaddr_source_);
data.add(&state_);
data.add(&user_context_);
data.add(&address_);
} catch (const Exception &ex) {
......@@ -1309,6 +1367,9 @@ CqlLease6Exchange::createBindForSelect(AnyArray &data, StatementTag /* unused */
// state: int
data.add(&state_);
// user_context: text
data.add(&user_context_);
}
boost::any
......@@ -1360,6 +1421,13 @@ CqlLease6Exchange::retrieve() {
hwaddr->source_ = hwaddr_source_;
}
ConstElementPtr ctx;
if (!user_context_.empty()) {
ctx = Element::fromJSON(user_context_);
isc_throw(BadValue, "user context '" << user_context_
<< "' is not a JSON map");
}
// Create the lease and set the cltt (after converting from the
// expire time retrieved from the database).
Lease6Ptr result(
......@@ -1373,6 +1441,10 @@ CqlLease6Exchange::retrieve() {
result->state_ = state_;
if (ctx) {
result->setContext(ctx);
}
return (result);
} catch (const Exception &ex) {
isc_throw(DbOperationError,
......
// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -8,6 +8,7 @@
#include <dhcpsrv/csv_lease_file4.h>
using namespace isc::asiolink;
using namespace isc::data;
using namespace isc::util;
namespace isc {
......@@ -52,6 +53,10 @@ CSVLeaseFile4::append(const Lease4& lease) {
row.writeAt(getColumnIndex("fqdn_rev"), lease.fqdn_rev_);
row.writeAt(getColumnIndex("hostname"), lease.hostname_);
row.writeAt(getColumnIndex("state"), lease.state_);
// User context is optional.
if (lease.getContext()) {
row.writeAt(getColumnIndex("user_context"), lease.getContext()->str());
}
try {
VersionedCSVFile::append(row);
......@@ -103,6 +108,9 @@ CSVLeaseFile4::next(Lease4Ptr& lease) {
" valid for declined leases");
}
// Get the user context (can be NULL).
ConstElementPtr ctx = readContext(row);
lease.reset(new Lease4(readAddress(row),
HWAddrPtr(new HWAddr(hwaddr)),
client_id_vec.empty() ? NULL : &client_id_vec[0],
......@@ -116,6 +124,10 @@ CSVLeaseFile4::next(Lease4Ptr& lease) {
readHostname(row)));
lease->state_ = state;
if (ctx) {
lease->setContext(ctx);
}
} catch (std::exception& ex) {
// bump the read error count
++read_errs_;
......@@ -145,6 +157,7 @@ CSVLeaseFile4::initColumns() {
addColumn("fqdn_rev", "1.0");
addColumn("hostname", "1.0");
addColumn("state", "2.0", "0");
addColumn("user_context", "2.1");
// Any file with less than hostname is invalid
setMinimumValidColumns("hostname");
}
......@@ -217,5 +230,19 @@ CSVLeaseFile4::readState(const util::CSVRow& row) {
return (state);
}
ConstElementPtr
CSVLeaseFile4::readContext(const util::CSVRow& row) {
std::string user_context = row.readAt(getColumnIndex("user_context"));
if (user_context.empty()) {
return (ConstElementPtr());
}
ConstElementPtr ctx = Element::fromJSON(user_context);
if (!ctx || (ctx->getType() != Element::map)) {
isc_throw(isc::BadValue, "user context '" << user_context
<< "' is not a JSON map");
}
return (ctx);
}
} // end of namespace isc::dhcp
} // end of namespace isc
// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -95,6 +95,7 @@ private:
/// - fqdn_rev
/// - hostname
/// - state
/// - user_context
void initColumns();
///
......@@ -151,6 +152,11 @@ private:
///
/// @param row CSV file row holding lease information.
uint32_t readState(const util::CSVRow& row);
/// @brief Reads lease user context from the CSV file row.
///
/// @param row CSV file row holding lease information.
data::ConstElementPtr readContext(const util::CSVRow& row);
//@}
};
......
// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -9,6 +9,7 @@
#include <dhcpsrv/csv_lease_file6.h>
using namespace isc::asiolink;
using namespace isc::data;
using namespace isc::util;
namespace isc {
......@@ -52,6 +53,10 @@ CSVLeaseFile6::append(const Lease6& lease) {
row.writeAt(getColumnIndex("hwaddr"), lease.hwaddr_->toText(false));
}
row.writeAt(getColumnIndex("state"), lease.state_);
// User context is optional.
if (lease.getContext()) {
row.writeAt(getColumnIndex("user_context"), lease.getContext()->str());
}
try {
VersionedCSVFile::append(row);
} catch (const std::exception&) {
......@@ -99,6 +104,10 @@ CSVLeaseFile6::next(Lease6Ptr& lease) {
isc_throw(isc::BadValue, "The Empty DUID is"
"only valid for declined leases");
}
ConstElementPtr ctx = readContext(row);
if (ctx) {
lease->setContext(ctx);
}
} catch (std::exception& ex) {
// bump the read error count
++read_errs_;
......@@ -132,7 +141,7 @@ CSVLeaseFile6::initColumns() {
addColumn("hostname", "1.0");
addColumn("hwaddr", "2.0");
addColumn("state", "3.0", "0");
addColumn("user_context", "3.1");
// Any file with less than hostname is invalid
setMinimumValidColumns("hostname");
}
......@@ -244,5 +253,19 @@ CSVLeaseFile6::readState(const util::CSVRow& row) {
return (state);
}
ConstElementPtr
CSVLeaseFile6::readContext(const util::CSVRow& row) {
std::string user_context = row.readAt(getColumnIndex("user_context"));
if (user_context.empty()) {
return (ConstElementPtr());
}
ConstElementPtr ctx = Element::fromJSON(user_context);
if (!ctx || (ctx->getType() != Element::map)) {
isc_throw(isc::BadValue, "user context '" << user_context
<< "' is not a JSON map");
}
return (ctx);
}
} // end of namespace isc::dhcp
} // end of namespace isc
// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -98,6 +98,7 @@ private:
/// - hostname
/// - hwaddr
/// - state
/// - user_context
void initColumns();
///
......@@ -175,6 +176,11 @@ private:
///
/// @param row CSV file row holding lease information.
uint32_t readState(const util::CSVRow& row);
/// @brief Reads lease user context from the CSV file row.
///
/// @param row CSV file row holding lease information.
data::ConstElementPtr readContext(const util::CSVRow& row);
//@}
};
......
......@@ -251,6 +251,15 @@ Lease::fromElementCommon(const LeasePtr& lease, const data::ConstElementPtr& ele
}
lease->state_ = state->intValue();
// user context
ConstElementPtr ctx = element->get("user-context");
if (ctx) {
if (ctx->getType() != Element::map) {
isc_throw(BadValue, "user context is not a map");
}
lease->setContext(ctx);
}
}
Lease4::Lease4(const Lease4& other)
......@@ -275,6 +284,10 @@ Lease4::Lease4(const Lease4& other)
client_id_.reset();
}
if (other.getContext()) {
setContext(other.getContext());
}
}
Lease4::Lease4(const isc::asiolink::IOAddress& address,
......@@ -375,6 +388,10 @@ Lease4::operator=(const Lease4& other) {
} else {
client_id_.reset();
}
if (other.getContext()) {
setContext(other.getContext());
}
}
return (*this);
}
......@@ -383,6 +400,7 @@ isc::data::ElementPtr
Lease4::toElement() const {
// Prepare the map
ElementPtr map = Element::createMap();
contextToElement(map);
map->set("ip-address", Element::create(addr_.toText()));
map->set("subnet-id", Element::create(static_cast<long int>(subnet_id_)));
map->set("hw-address", Element::create(hwaddr_->toText(false)));
......@@ -526,6 +544,10 @@ Lease6::toText() const {
<< "Subnet ID: " << subnet_id_ << "\n"
<< "State: " << statesToText(state_) << "\n";
if (getContext()) {
stream << "User context: " << getContext() << "\n";
}
return (stream.str());
}
......@@ -543,6 +565,10 @@ Lease4::toText() const {
<< "Subnet ID: " << subnet_id_ << "\n"
<< "State: " << statesToText(state_) << "\n";
if (getContext()) {
stream << "User context: " << getContext() << "\n";
}
return (stream.str());
}
......@@ -560,7 +586,8 @@ Lease4::operator==(const Lease4& other) const {
hostname_ == other.hostname_ &&
fqdn_fwd_ == other.fqdn_fwd_ &&
fqdn_rev_ == other.fqdn_rev_ &&
state_ == other.state_);
state_ == other.state_ &&
nullOrEqualValues(getContext(), other.getContext()));
}
bool
......@@ -580,13 +607,15 @@ Lease6::operator==(const Lease6& other) const {
hostname_ == other.hostname_ &&
fqdn_fwd_ == other.fqdn_fwd_ &&
fqdn_rev_ == other.fqdn_rev_ &&
state_ == other.state_);
state_ == other.state_ &&
nullOrEqualValues(getContext(), other.getContext()));
}
isc::data::ElementPtr
Lease6::toElement() const {
// Prepare the map
ElementPtr map = Element::createMap();
contextToElement(map);
map->set("ip-address", Element::create(addr_.toText()));
map->set("type", Element::create(typeToText(type_)));
if (type_ == Lease::TYPE_PD) {
......
......@@ -11,6 +11,7 @@
#include <dhcp/duid.h>
#include <dhcp/option.h>
#include <dhcp/hwaddr.h>
#include <cc/user_context.h>
#include <cc/cfg_to_element.h>
namespace isc {
......@@ -31,7 +32,7 @@ typedef boost::shared_ptr<Lease> LeasePtr;
///
/// This structure holds all information that is common between IPv4 and IPv6
/// leases.
struct Lease : public isc::data::CfgToElement {
struct Lease : public UserContext, public isc::data::CfgToElement {
/// @brief Type of lease or pool
typedef enum {
......
......@@ -83,12 +83,13 @@ public:
/// Version history:
/// 1.0 - initial version (released in Kea 0.9)
/// 2.0 - hwaddr column added (to be released in Kea 0.9.1)
/// 2.1 - user context column add (to be released in Kea 1.5)
///
/// @{
static const int MAJOR_VERSION = 2;
/// Defines minor version of the memfile backend.
static const int MINOR_VERSION = 0;
static const int MINOR_VERSION = 1;
/// @}
......
......@@ -41,7 +41,7 @@ extern const int MLM_MYSQL_FETCH_FAILURE;
/// @name Current database schema version values.
//@{
const uint32_t MYSQL_SCHEMA_VERSION_MAJOR = 6;
const uint32_t MYSQL_SCHEMA_VERSION_MINOR = 0;
const uint32_t MYSQL_SCHEMA_VERSION_MINOR = 1;
//@}
......
......@@ -26,6 +26,7 @@
using namespace isc;