Commit e74bc092 authored by Marcin Siodelski's avatar Marcin Siodelski

[#93,!35] Implemented fetching option definitions from the database.

parent 372b8590
......@@ -494,7 +494,7 @@ EOF
run_statement "dhcp4_global_parameter_server" "$qry"
# table: dhcp4_option_def
qry="select id, code, space, modification_ts, array, encapsulate, record_types, user_context from dhcp4_option_def"
qry="select id, code, name, space, type, modification_ts, array, encapsulate, record_types, user_context from dhcp4_option_def"
run_statement "dhcp4_option_def" "$qry"
# table: dhcp4_option_def_server
......@@ -546,7 +546,7 @@ EOF
run_statement "dhcp6_global_parameter_server" "$qry"
# table: dhcp6_option_def
qry="select id, code, space, modification_ts, array, encapsulate, record_types, user_context from dhcp6_option_def"
qry="select id, code, name, space, type, modification_ts, array, encapsulate, record_types, user_context from dhcp6_option_def"
run_statement "dhcp6_option_def" "$qry"
# table: dhcp6_option_def_server
......
......@@ -8,6 +8,7 @@
#include <database/db_exceptions.h>
#include <dhcp/classify.h>
#include <dhcp/dhcp6.h>
#include <dhcp/option_data_types.h>
#include <dhcpsrv/network.h>
#include <dhcpsrv/pool.h>
#include <dhcpsrv/lease.h>
......@@ -48,11 +49,16 @@ public:
GET_SHARED_NETWORK4_NAME,
GET_ALL_SHARED_NETWORKS4,
GET_MODIFIED_SHARED_NETWORKS4,
GET_OPTION_DEF4_CODE_SPACE,
GET_ALL_OPTION_DEFS4,
GET_MODIFIED_OPTION_DEFS4,
INSERT_SUBNET4,
INSERT_POOL4,
INSERT_SHARED_NETWORK4,
INSERT_OPTION_DEF4,
UPDATE_SUBNET4,
UPDATE_SHARED_NETWORK4,
UPDATE_OPTION_DEF4,
DELETE_POOLS4_SUBNET_ID,
NUM_STATEMENTS
};
......@@ -322,12 +328,6 @@ public:
(shared_network ? MySqlBinding::createString(shared_network->getName()) :
MySqlBinding::createNull());
// Create user context binding if user context exists.
auto context_element = subnet->getContext();
MySqlBindingPtr context_binding =
(context_element ? MySqlBinding::createString(context_element->str()) :
MySqlBinding::createNull());
// Create input bindings.
MySqlBindingCollection in_bindings = {
MySqlBinding::createInteger<uint32_t>(subnet->getID()),
......@@ -348,7 +348,7 @@ public:
MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>(subnet->getHostReservationMode())),
MySqlBinding::condCreateString(subnet->getSname()),
shared_network_binding,
context_binding,
createInputContextBinding(subnet),
MySqlBinding::createInteger<uint32_t>(subnet->getValid())
};
......@@ -452,6 +452,7 @@ public:
if ((last_network_id == 0) ||
(last_network_id != out_bindings[0]->getInteger<uint64_t>())) {
last_network_id = out_bindings[0]->getInteger<uint64_t>();
last_network.reset(new SharedNetwork4(out_bindings[1]->getString()));
// client_class
......@@ -587,7 +588,171 @@ public:
conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_SHARED_NETWORK4,
in_bindings);
}
}
/// @brief Sends query to the database to retrieve multiple option
/// definitions.
///
/// Query should order option definitions by id.
///
/// @param index Index of the query to be used.
/// @param in_bindings Input bindings specifying selection criteria. The
/// size of the bindings collection must match the number of placeholders
/// in the prepared statement. The input bindings collection must be empty
/// if the query contains no WHERE clause.
/// @param [out] option_defs Reference to the container where fetched
/// option definitions will be inserted.
void getOptionDefs4(const StatementIndex& index,
const MySqlBindingCollection& in_bindings,
OptionDefContainer& option_defs) {
// Create output bindings. The order must match that in the prepared
// statement.
MySqlBindingCollection out_bindings = {
MySqlBinding::createInteger<uint64_t>(), // id
MySqlBinding::createInteger<uint8_t>(), // code
MySqlBinding::createString(128), // name
MySqlBinding::createString(128), // space
MySqlBinding::createInteger<uint8_t>(), // type
MySqlBinding::createTimestamp(), // modification_ts
MySqlBinding::createInteger<uint8_t>(), // array
MySqlBinding::createString(128), // encapsulate
MySqlBinding::createString(512), // record_types
MySqlBinding::createString(65536) // user_context
};
uint64_t last_def_id = 0;
// Run select query.
conn_.selectQuery(index, in_bindings, out_bindings,
[&option_defs, &last_def_id]
(MySqlBindingCollection& out_bindings) {
// Get pointer to last fetched option definition.
OptionDefinitionPtr last_def;
if (!option_defs.empty()) {
last_def = *option_defs.rbegin();
}
// See if the last fetched definition is the one for which we now got
// the row of data. If not, it means that we need to create new option
// definition.
if ((last_def_id == 0) ||
(last_def_id != out_bindings[0]->getInteger<uint64_t>())) {
last_def_id = out_bindings[0]->getInteger<uint64_t>();
// Check array type, because depending on this value we have to use
// different constructor.
bool array_type = static_cast<bool>(out_bindings[6]->getInteger<uint8_t>());
if (array_type) {
// Create array option.
last_def.reset(new OptionDefinition(out_bindings[2]->getString(),
out_bindings[1]->getInteger<uint8_t>(),
static_cast<OptionDataType>
(out_bindings[4]->getInteger<uint8_t>()),
array_type));
} else {
// Create non-array option.
last_def.reset(new OptionDefinition(out_bindings[2]->getString(),
out_bindings[1]->getInteger<uint8_t>(),
static_cast<OptionDataType>
(out_bindings[4]->getInteger<uint8_t>()),
out_bindings[7]->getStringOrDefault("").c_str()));
}
// space
last_def->setOptionSpaceName(out_bindings[3]->getStringOrDefault(""));
// record_types
ElementPtr record_types_element = out_bindings[8]->getJSON();
if (record_types_element) {
if (record_types_element->getType() != Element::list) {
isc_throw(BadValue, "invalid record_types value "
<< out_bindings[8]->getString());
}
// This element must contain a list of integers specifying
// types of the record fields.
for (auto i = 0; i < record_types_element->size(); ++i) {
auto type_element = record_types_element->get(i);
if (type_element->getType() != Element::integer) {
isc_throw(BadValue, "record type values must be integers");
}
last_def->addRecordField(static_cast<OptionDataType>
(type_element->intValue()));
}
}
// Update modification time.
last_def->setModificationTime(out_bindings[5]->getTimestamp());
// Store created option definition.
option_defs.push_back(last_def);
}
});
}
/// @brief Sends query to retrieve single option definition by code and
/// option space.
///
/// @param selector Server selector.
/// @param code Option code.
/// @param space Option space name.
///
/// @return Pointer to the returned option definition or NULL if such
/// option definition doesn't exist.
OptionDefinitionPtr getOptionDef4(const ServerSelector& selector,
const uint16_t code,
const std::string& space) {
OptionDefContainer option_defs;
MySqlBindingCollection in_bindings = {
MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>(code)),
MySqlBinding::createString(space)
};
getOptionDefs4(GET_OPTION_DEF4_CODE_SPACE, in_bindings, option_defs);
return (option_defs.empty() ? OptionDefinitionPtr() : *option_defs.begin());
}
/// @brief Sends query to insert or update option definition.
///
/// @param selector Server selector.
/// @param option_def Pointer to the option definition to be inserted or updated.
void createUpdateOptionDef4(const ServerSelector& selector,
const OptionDefinitionPtr& option_def) {
ElementPtr record_types = Element::createList();
for (auto field : option_def->getRecordFields()) {
record_types->add(Element::create(static_cast<int>(field)));
}
MySqlBindingPtr record_types_binding = record_types->empty() ?
MySqlBinding::createNull() : MySqlBinding::createString(record_types->str());
MySqlBindingCollection in_bindings = {
MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>(option_def->getCode())),
MySqlBinding::createString(option_def->getName()),
MySqlBinding::createString(option_def->getOptionSpaceName().empty() ?
"dhcp4" : option_def->getOptionSpaceName()),
MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>(option_def->getType())),
MySqlBinding::createTimestamp(option_def->getModificationTime()),
MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>(option_def->getArrayType())),
MySqlBinding::createString(option_def->getEncapsulatedSpace()),
record_types_binding,
createInputContextBinding(option_def)
};
// If the shared network exists we are going to update this network.
OptionDefinitionPtr existing_definition = getOptionDef4(selector,
option_def->getCode(),
option_def->getOptionSpaceName());
if (existing_definition) {
// Need to add two more bindings for WHERE clause.
in_bindings.push_back(MySqlBinding::createInteger<uint8_t>(existing_definition->getCode()));
in_bindings.push_back(MySqlBinding::createString(existing_definition->getOptionSpaceName()));
conn_.updateDeleteQuery(MySqlConfigBackendDHCPv4Impl::UPDATE_OPTION_DEF4,
in_bindings);
} else {
// If the option definition doesn't exist, let's insert it.
conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_OPTION_DEF4,
in_bindings);
}
}
/// @brief Creates input binding for relay addresses.
......@@ -632,13 +797,14 @@ public:
/// @brief Creates input binding for user context parameter.
///
/// @param network Pointer to a shared network or subnet for which binding
/// should be created.
/// @param network Pointer to a shared network, subnet or other configuration
/// element for which binding should be created.
/// @return Pointer to the binding (possibly null binding if context is
/// null).
MySqlBindingPtr createInputContextBinding(const NetworkPtr& network) {
template<typename T>
MySqlBindingPtr createInputContextBinding(const T& config_element) {
// Create user context binding if user context exists.
auto context_element = network->getContext();
auto context_element = config_element->getContext();
return (context_element ? MySqlBinding::createString(context_element->str()) :
MySqlBinding::createNull());
}
......@@ -844,6 +1010,56 @@ TaggedStatementArray tagged_statements = { {
"WHERE n.modification_ts > ? "
"ORDER BY n.id" },
// Retrieves option definition by code and space.
{ MySqlConfigBackendDHCPv4Impl::GET_OPTION_DEF4_CODE_SPACE,
"SELECT"
" d.id,"
" d.code,"
" d.name,"
" d.space,"
" d.type,"
" d.modification_ts,"
" d.array,"
" d.encapsulate,"
" d.record_types,"
" d.user_context "
"FROM dhcp4_option_def AS d "
"WHERE d.code = ? AND d.space = ? "
"ORDER BY d.id" },
// Retrieves all option definitions.
{ MySqlConfigBackendDHCPv4Impl::GET_ALL_OPTION_DEFS4,
"SELECT"
" d.id,"
" d.code,"
" d.name,"
" d.space,"
" d.type,"
" d.modification_ts,"
" d.array,"
" d.encapsulate,"
" d.record_types,"
" d.user_context "
"FROM dhcp4_option_def AS d "
"ORDER BY d.id" },
// Retrieves modified option definitions.
{ MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_OPTION_DEFS4,
"SELECT"
" d.id,"
" d.code,"
" d.name,"
" d.space,"
" d.type,"
" d.modification_ts,"
" d.array,"
" d.encapsulate,"
" d.record_types,"
" d.user_context "
"FROM dhcp4_option_def AS d "
"WHERE modification_ts > ? "
"ORDER BY d.id" },
// Insert a subnet.
{ MySqlConfigBackendDHCPv4Impl::INSERT_SUBNET4,
"INSERT INTO dhcp4_subnet("
......@@ -870,6 +1086,7 @@ TaggedStatementArray tagged_statements = { {
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,"
"?, ?, ?, ?, ?, ?, ?, ?)" },
// Insert pool for a subnet.
{ MySqlConfigBackendDHCPv4Impl::INSERT_POOL4,
"INSERT INTO dhcp4_pool("
" start_address,"
......@@ -895,6 +1112,20 @@ TaggedStatementArray tagged_statements = { {
"valid_lifetime"
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" },
// Insert option definition.
{ MySqlConfigBackendDHCPv4Impl::INSERT_OPTION_DEF4,
"INSERT INTO dhcp4_option_def ("
"code,"
"name,"
"space,"
"type,"
"modification_ts,"
"array,"
"encapsulate,"
"record_types,"
"user_context"
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)" },
// Update existing subnet.
{ MySqlConfigBackendDHCPv4Impl::UPDATE_SUBNET4,
"UPDATE dhcp4_subnet SET"
......@@ -937,6 +1168,20 @@ TaggedStatementArray tagged_statements = { {
" valid_lifetime = ? "
"WHERE name = ?" },
// Update existing option definition.
{ MySqlConfigBackendDHCPv4Impl::UPDATE_OPTION_DEF4,
"UPDATE dhcp4_option_def SET"
" code = ?,"
" name = ?,"
" space = ?,"
" type = ?,"
" modification_ts = ?,"
" array = ?,"
" encapsulate = ?,"
" record_types = ?,"
" user_context = ? "
"WHERE code = ? AND space = ?" },
// Delete pools for a subnet.
{ MySqlConfigBackendDHCPv4Impl::DELETE_POOLS4_SUBNET_ID,
"DELETE FROM dhcp4_pool "
......@@ -1063,19 +1308,29 @@ OptionDefinitionPtr
MySqlConfigBackendDHCPv4::getOptionDef4(const ServerSelector& selector,
const uint16_t code,
const std::string& space) const {
isc_throw(NotImplemented, "not implemented");
return (impl_->getOptionDef4(selector, code, space));
}
OptionDefContainer
MySqlConfigBackendDHCPv4::getAllOptionDefs4(const ServerSelector& selector) const {
isc_throw(NotImplemented, "not implemented");
OptionDefContainer option_defs;
MySqlBindingCollection in_bindings;
impl_->getOptionDefs4(MySqlConfigBackendDHCPv4Impl::GET_ALL_OPTION_DEFS4,
in_bindings, option_defs);
return (option_defs);
}
OptionDefContainer
MySqlConfigBackendDHCPv4::
getModifiedOptionDefs4(const ServerSelector& selector,
const boost::posix_time::ptime& modification_time) const {
isc_throw(NotImplemented, "not implemented");
OptionDefContainer option_defs;
MySqlBindingCollection in_bindings = {
MySqlBinding::createTimestamp(modification_time)
};
impl_->getOptionDefs4(MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_OPTION_DEFS4,
in_bindings, option_defs);
return (option_defs);
}
util::OptionalValue<std::string>
......@@ -1110,6 +1365,7 @@ MySqlConfigBackendDHCPv4::createUpdateSharedNetwork4(const ServerSelector& selec
void
MySqlConfigBackendDHCPv4::createUpdateOptionDef4(const ServerSelector& selector,
const OptionDefinitionPtr& option_def) {
impl_->createUpdateOptionDef4(selector, option_def);
}
void
......
......@@ -51,6 +51,7 @@ public:
// Create test data.
initTestSubnets();
initTestSharedNetworks();
initTestOptionDefs();
initTimestamps();
}
......@@ -147,6 +148,31 @@ public:
test_networks_.push_back(shared_network);
}
/// @brief Creates several option definitions used in tests.
void initTestOptionDefs() {
ElementPtr user_context = Element::createMap();
user_context->set("foo", Element::create("bar"));
OptionDefinitionPtr option_def(new OptionDefinition("foo", 234, "string",
"espace"));
option_def->setOptionSpaceName("dhcp4");
test_option_defs_.push_back(option_def);
option_def.reset(new OptionDefinition("bar", 234, "uint32", true));
option_def->setOptionSpaceName("dhcp4");
test_option_defs_.push_back(option_def);
option_def.reset(new OptionDefinition("fish", 235, "record", true));
option_def->setOptionSpaceName("dhcp4");
option_def->addRecordField("uint32");
option_def->addRecordField("string");
test_option_defs_.push_back(option_def);
option_def.reset(new OptionDefinition("whale", 236, "string"));
option_def->setOptionSpaceName("xyz");
test_option_defs_.push_back(option_def);
}
/// @brief Initialize posix time values used in tests.
void initTimestamps() {
// Current time minus 1 hour to make sure it is in the past.
......@@ -164,6 +190,9 @@ public:
/// @brief Holds pointers to shared networks used in tests.
std::vector<SharedNetwork4Ptr> test_networks_;
/// @brief Holds pointers to option definitions used in tests.
std::vector<OptionDefinitionPtr> test_option_defs_;
/// @brief Holds timestamp values used in tests.
std::map<std::string, boost::posix_time::ptime> timestamps_;
......@@ -352,5 +381,95 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedSharedNetworks4) {
ASSERT_TRUE(networks.empty());
}
// Test that subnet can be inserted, fetched, updated and then fetched again.
TEST_F(MySqlConfigBackendDHCPv4Test, getOptionDef4) {
// Insert new option definition.
OptionDefinitionPtr option_def = test_option_defs_[0];
cbptr_->createUpdateOptionDef4(ServerSelector::UNASSIGNED(), option_def);
// Fetch this option_definition by subnet identifier.
OptionDefinitionPtr returned_option_def =
cbptr_->getOptionDef4(ServerSelector::UNASSIGNED(),
test_option_defs_[0]->getCode(),
test_option_defs_[0]->getOptionSpaceName());
ASSERT_TRUE(returned_option_def);
EXPECT_TRUE(returned_option_def->equals(*option_def));
// Update the option definition in the database.
OptionDefinitionPtr option_def2 = test_option_defs_[1];
cbptr_->createUpdateOptionDef4(ServerSelector::UNASSIGNED(), option_def2);
// Fetch updated option definition and see if it matches.
returned_option_def = cbptr_->getOptionDef4(ServerSelector::UNASSIGNED(),
test_option_defs_[1]->getCode(),
test_option_defs_[1]->getOptionSpaceName());
EXPECT_TRUE(returned_option_def->equals(*option_def2));
}
// Test that all shared networks can be fetched.
TEST_F(MySqlConfigBackendDHCPv4Test, getAllOptionDefs4) {
// Insert test option definitions into the database. Note that the second
// option definition will overwrite the first option definition as they use
// the same code and space.
for (auto option_def : test_option_defs_) {
cbptr_->createUpdateOptionDef4(ServerSelector::UNASSIGNED(), option_def);
}
// Fetch all option_definitions.
OptionDefContainer option_defs = cbptr_->getAllOptionDefs4(ServerSelector::UNASSIGNED());
ASSERT_EQ(test_option_defs_.size() - 1, option_defs.size());
// See if option definitions are returned ok.
for (auto def = option_defs.begin(); def != option_defs.end(); ++def) {
bool success = false;
for (auto i = 1; i < test_option_defs_.size(); ++i) {
if ((*def)->equals(*test_option_defs_[i])) {
success = true;
}
}
ASSERT_TRUE(success) << "failed for option definition " << (*def)->getCode()
<< ", option space " << (*def)->getOptionSpaceName();
}
}
// Test that option definitions modified after given time can be fetched.
TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedOptionDefinitions4) {
// Explicitly set timestamps of option definitions. First option
// definition has a timestamp pointing to the future. Second option
// definition has timestamp pointing to the past (yesterday).
// Third option definitions has a timestamp pointing to the
// past (an hour ago).
test_option_defs_[1]->setModificationTime(timestamps_["tomorrow"]);
test_option_defs_[2]->setModificationTime(timestamps_["yesterday"]);
test_option_defs_[3]->setModificationTime(timestamps_["today"]);
// Insert option definitions into the database.
for (int i = 1; i < test_networks_.size(); ++i) {
cbptr_->createUpdateOptionDef4(ServerSelector::UNASSIGNED(),
test_option_defs_[i]);
}
// Fetch option definitions with timestamp later than today. Only one
// option definition should be returned.
OptionDefContainer
option_defs = cbptr_->getModifiedOptionDefs4(ServerSelector::UNASSIGNED(),
timestamps_["today"]);
ASSERT_EQ(1, option_defs.size());
// Fetch option definitions with timestamp later than yesterday. We
// should get two option definitions.
option_defs = cbptr_->getModifiedOptionDefs4(ServerSelector::UNASSIGNED(),
timestamps_["yesterday"]);
ASSERT_EQ(2, option_defs.size());
// Fetch option definitions with timestamp later than tomorrow. Nothing
// should be returned.
option_defs = cbptr_->getModifiedOptionDefs4(ServerSelector::UNASSIGNED(),
timestamps_["tomorrow"]);
ASSERT_TRUE(option_defs.empty());
}
}
......@@ -48,7 +48,10 @@ OptionDefinition::OptionDefinition(const std::string& name,
code_(code),
type_(OPT_UNKNOWN_TYPE),
array_type_(array_type),
encapsulated_space_("") {
encapsulated_space_(""),
record_fields_(),
user_context_(),
option_space_name_() {
// Data type is held as enum value by this class.
// Use the provided option type string to get the
// corresponding enum value.
......@@ -77,7 +80,10 @@ OptionDefinition::OptionDefinition(const std::string& name,
// corresponding enum value.
type_(OptionDataTypeUtil::getDataType(type)),
array_type_(false),
encapsulated_space_(encapsulated_space) {
encapsulated_space_(encapsulated_space),
record_fields_(),
user_context_(),
option_space_name_() {
}
OptionDefinition::OptionDefinition(const std::string& name,
......@@ -88,7 +94,10 @@ OptionDefinition::OptionDefinition(const std::string& name,
code_(code),
type_(type),
array_type_(false),
encapsulated_space_(encapsulated_space) {
encapsulated_space_(encapsulated_space),
record_fields_(),
user_context_(),
option_space_name_() {
}
bool
......@@ -98,7 +107,8 @@ OptionDefinition::equals(const OptionDefinition& other) const {
type_ == other.type_ &&
array_type_ == other.array_type_ &&
encapsulated_space_ == other.encapsulated_space_ &&
record_fields_ == other.record_fields_);
record_fields_ == other.record_fields_ &&
option_space_name_ == other.option_space_name_);
}
void
......
// Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-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
......@@ -10,6 +10,7 @@
#include <dhcp/option.h>
#include <dhcp/option_data_types.h>
#include <dhcp/option_space_container.h>
#include <cc/stamped_element.h>
#include <cc/user_context.h>
#include <boost/multi_index/hashed_index.hpp>
......@@ -133,7 +134,7 @@ class OptionIntArray;
/// @todo Extend this class to use custom namespaces.
/// @todo Extend this class with more factory functions.
/// @todo Derive from UserContext without breaking the multi index.
class OptionDefinition {
class OptionDefinition : public data::StampedElement {
public:
/// List of fields within the record.
......@@ -307,6 +308,32 @@ public:
user_context_.contextToElement(map);
}
/// @brief Returns option space name.
///
/// Option definitions are associated with option spaces. Typically,
/// such association is made when the option definition is put into
/// the @c CfgOptionDef structure. However, in some cases it is also
/// required to associate option definition with the particular option
/// space outside of that structure. In particular, when the option
/// definition is fetched from a database. The database configuration
/// backend will set option space upon return of the option definition.
/// In other cases this value won't be set.
///
/// @return Option space name or empty string if option space
/// name is not set.
std::string getOptionSpaceName() const {
return (option_space_name_);
}
/// @brief Sets option space name for option definition.
///
/// See @c getOptionSpaceName to learn when option space name is set.
///
/// @param option_space_name New option space name.
void setOptionSpaceName(const std::string& option_space_name) {
option_space_name_ = option_space_name;
}
/// @brief Check if the option definition is valid.
///
/// Note that it is a responsibility of the code that created
......@@ -733,6 +760,8 @@ private:
RecordFieldsCollection record_fields_;
/// User context
data::UserContext user_context_;
/// Option space name
std::string option_space_name_;
};
......
......@@ -857,7 +857,9 @@ CREATE TABLE IF NOT EXISTS dhcp4_global_parameter_server (
CREATE TABLE IF NOT EXISTS dhcp4_option_def (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
code TINYINT(3) UNSIGNED NOT NULL,
name VARCHAR(128) NOT NULL,
space VARCHAR(128) NOT NULL,
type TINYINT UNSIGNED NOT NULL,
modification_ts TIMESTAMP NOT NULL,
array TINYINT(1) NOT NULL,
encapsulate VARCHAR(128) NOT NULL,
......@@ -1005,7 +1007,7 @@ ALTER TABLE dhcp4_options MODIFY option_id BIGINT(20) UNSIGNED NOT NULL AUTO_INC
ALTER TABLE dhcp4_options
ADD COLUMN shared_network_name VARCHAR(128) DEFAULT NULL,
ADD COLUMN pool_id BIGINT(20) UNSIGNED DEFAULT NULL,
ADD COLUMN modification_ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
ADD COLUMN modification_ts TIMESTAMP NOT NULL;
-- -----------------------------------------------------
-- Table `dhcp4_options_server`
......@@ -1096,7 +1098,9 @@ CREATE TABLE IF NOT EXISTS dhcp6_global_parameter_server (
CREATE TABLE IF NOT EXISTS dhcp6_option_def (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
code TINYINT(3) UNSIGNED NOT NULL,
name VARCHAR(128) NOT NULL,
space VARCHAR(128) NOT NULL,
type TINYINT UNSIGNED NOT NULL,
modification_ts TIMESTAMP NOT NULL,
array TINYINT(1) NOT NULL,
encapsulate VARCHAR(128) NOT NULL,
......@@ -1258,7 +1262,7 @@ ALTER TABLE dhcp6_options
ADD COLUMN shared_network_name VARCHAR(128) DEFAULT NULL,
ADD COLUMN pool_id BIGINT(20) UNSIGNED DEFAULT NULL,
ADD COLUMN pd_pool_id BIGINT(20) UNSIGNED DEFAULT NULL,
ADD COLUMN modification_ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
ADD COLUMN modification_ts TIMESTAMP NOT NULL;
-- -----------------------------------------------------
-- Table `dhcp6_options_server`
......
......@@ -192,6 +192,7 @@ CREATE TABLE IF NOT EXISTS dhcp4_global_parameter_server (
CREATE TABLE IF NOT EXISTS dhcp4_option_def (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
code TINYINT(3) UNSIGNED NOT NULL,
name VARCHAR(128) NOT NULL,
space VARCHAR(128) NOT NULL,
modification_ts TIMESTAMP NOT NULL,
array TINYINT(1) NOT NULL,
......@@ -333,7 +334,7 @@ ALTER TABLE dhcp4_options MODIFY option_id BIGINT(20) UNSIGNED NOT NULL AUTO_INC
ALTER TABLE dhcp4_options
ADD COLUMN shared_network_name VARCHAR(128) DEFAULT NULL,
ADD COLUMN pool_id BIGINT(20) UNSIGNED DEFAULT NULL,
ADD COLUMN modification_ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
ADD COLUMN modification_ts TIMESTAMP NOT NULL;
# Create table dhcp4_options_server
# M-to-M cross-reference between options and servers
......@@ -417,6 +418,7 @@ CREATE TABLE IF NOT EXISTS dhcp6_global_parameter_server (
CREATE TABLE IF NOT EXISTS dhcp6_option_def (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
code TINYINT(3) UNSIGNED NOT NULL,
name VARCHAR(128) NOT NULL,
space VARCHAR(128) NOT NULL,
modification_ts TIMESTAMP NOT NULL,
array TINYINT(1) NOT NULL,
......@@ -569,7 +571,7 @@ ALTER TABLE dhcp6_options
ADD COLUMN shared_network_name VARCHAR(128) DEFAULT NULL,
ADD COLUMN pool_id BIGINT(20) UNSIGNED DEFAULT NULL,
ADD COLUMN pd_pool_id BIGINT(20) UNSIGNED DEFAULT NULL,
ADD COLUMN modification_ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;