...
 
Commits (16)
1521. [func] marcin
Removed subsecond precision for the timestamps in MySQL config
backend. It caused issues on systems with MySQL version prior
to 5.6.4 which don't support subsecond timestamp values.
(Gitlab #444,!229, git 71200e98f5a862908240a0d2e269b5da23290af9)
1520. [build] fdupont
Made perfdhcp build optional and off by default: to build it
please use the new --enable-perfdhcp configure flag.
......
......@@ -736,11 +736,21 @@ if test "$MYSQL_CONFIG" != "" ; then
AC_MSG_ERROR([Needs MySQL library])]
)
# Note that MYSQL is present in the config.h file
AC_DEFINE([HAVE_MYSQL], [1], [MySQL is present])
# Check is my_bool is defined.
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([#include <mysql.h>
const my_bool MLM_FALSE = 0;]
[])],
[AC_MSG_RESULT([checking for MySQL my_bool... yes])
AC_DEFINE([HAVE_MYSQL_MY_BOOL], [1], [MySQL uses my_bool])],
[AC_MSG_RESULT([checking for MySQL my_bool... no])])
CPPFLAGS=$CPPFLAGS_SAVED
LIBS=$LIBS_SAVED
# Note that MYSQL is present in the config.h file
AC_DEFINE([HAVE_MYSQL], [1], [MySQL is present])
fi
# Solaris puts FIONREAD in filio.h
......
......@@ -101,6 +101,11 @@ The following environment variable can affect the unit tests:
mysql> GRANT ALL ON keatest.* TO 'keatest'@'localhost';
mysql> GRANT SELECT ON keatest.* TO 'keatest_readonly'@'localhost';
mysql>@endverbatim\n
-# If you get <i>You do not have the SUPER privilege and binary logging is
enabled</i> error message, you need to add:
@verbatim
mysql> SET GLOBAL LOG_BIN_TRUST_FUNCTION_CREATORS = 1;
mysql>@endverbatim\n
-# Exit MySQL:
@verbatim
mysql> quit
......
......@@ -120,17 +120,6 @@ public:
explicit MySqlConfigBackendDHCPv4Impl(const DatabaseConnection::ParameterMap&
parameters);
/// @brief Sends query to insert an audit entry.
///
/// @param in_bindings Collection of bindings representing an option.
void insertAuditEntry4(const MySqlBindingCollection& in_bindings) {
// Fetch unique identifier of the inserted option.
uint64_t id = mysql_insert_id(conn_.mysql_);
// Create bindings needed to insert association of that option with
// a server into the dhcp4_options_server table.
}
/// @brief Sends query to retrieve multiple global parameters.
///
/// @param index Index of the query to be used.
......@@ -367,11 +356,11 @@ public:
std::string subnet_prefix = out_bindings[1]->getString();
auto prefix_pair = Subnet4::parsePrefix(subnet_prefix);
// renew_timer
uint32_t renew_timer = out_bindings[13]->getIntegerOrDefault<uint32_t>(0);
auto renew_timer = createTriplet(out_bindings[13]);
// rebind_timer
uint32_t rebind_timer = out_bindings[11]->getIntegerOrDefault<uint32_t>(0);
auto rebind_timer = createTriplet(out_bindings[11]);
// valid_lifetime
uint32_t valid_lifetime = out_bindings[19]->getIntegerOrDefault<uint32_t>(0);
auto valid_lifetime = createTriplet(out_bindings[19]);
// Create subnet with basic settings.
last_subnet.reset(new Subnet4(prefix_pair.first, prefix_pair.second,
......@@ -789,15 +778,15 @@ public:
MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>(subnet->getMatchClientId())),
MySqlBinding::createTimestamp(subnet->getModificationTime()),
MySqlBinding::condCreateInteger<uint32_t>(subnet->getSiaddr().toUint32()),
MySqlBinding::createInteger<uint32_t>(subnet->getT2()),
createBinding(subnet->getT2()),
createInputRelayBinding(subnet),
MySqlBinding::createInteger<uint32_t>(subnet->getT1()),
createBinding(subnet->getT1()),
createInputRequiredClassesBinding(subnet),
MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>(subnet->getHostReservationMode())),
MySqlBinding::condCreateString(subnet->getSname()),
shared_network_binding,
createInputContextBinding(subnet),
MySqlBinding::createInteger<uint32_t>(subnet->getValid())
createBinding(subnet->getValid())
};
MySqlTransaction transaction(conn_);
......@@ -1038,7 +1027,7 @@ public:
// rebind_timer
if (!out_bindings[6]->amNull()) {
last_network->setT2(out_bindings[6]->getInteger<uint32_t>());
last_network->setT2(createTriplet(out_bindings[6]));
}
// relay
......@@ -1059,7 +1048,7 @@ public:
// renew_timer
if (!out_bindings[8]->amNull()) {
last_network->setT1(out_bindings[8]->getInteger<uint32_t>());
last_network->setT1(createTriplet(out_bindings[8]));
}
// require_client_classes
......@@ -1091,7 +1080,7 @@ public:
// valid_lifetime
if (!out_bindings[12]->amNull()) {
last_network->setValid(out_bindings[12]->getInteger<uint32_t>());
last_network->setValid(createTriplet(out_bindings[12]));
}
shared_networks.push_back(last_network);
......@@ -1198,14 +1187,14 @@ public:
MySqlBinding::condCreateString(shared_network->getIface()),
MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>(shared_network->getMatchClientId())),
MySqlBinding::createTimestamp(shared_network->getModificationTime()),
MySqlBinding::condCreateInteger<uint32_t>(shared_network->getT2()),
createBinding(shared_network->getT2()),
createInputRelayBinding(shared_network),
MySqlBinding::condCreateInteger<uint32_t>(shared_network->getT1()),
createBinding(shared_network->getT1()),
createInputRequiredClassesBinding(shared_network),
MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>
(shared_network->getHostReservationMode())),
createInputContextBinding(shared_network),
MySqlBinding::condCreateInteger<uint32_t>(shared_network->getValid())
createBinding(shared_network->getValid())
};
MySqlTransaction transaction(conn_);
......@@ -2090,6 +2079,8 @@ public:
}
};
namespace {
/// @brief Array of tagged statements.
typedef std::array<TaggedStatement, MySqlConfigBackendDHCPv4Impl::NUM_STATEMENTS>
TaggedStatementArray;
......@@ -2479,6 +2470,8 @@ TaggedStatementArray tagged_statements = { {
}
};
}; // end anonymous namespace
MySqlConfigBackendDHCPv4Impl::
MySqlConfigBackendDHCPv4Impl(const DatabaseConnection::ParameterMap& parameters)
: MySqlConfigBackendImpl(parameters) {
......
......@@ -4,6 +4,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <mysql_cb_impl.h>
#include <asiolink/io_address.h>
#include <config_backend/constants.h>
......@@ -68,7 +69,7 @@ MySqlConfigBackendImpl(const DatabaseConnection::ParameterMap& parameters)
// the database after the test because of pending transactions.
// Use of autocommit will eliminate this problem.
my_bool result = mysql_autocommit(conn_.mysql_, 1);
if (result != 0) {
if (result != MLM_FALSE) {
isc_throw(DbOperationError, mysql_error(conn_.mysql_));
}
}
......@@ -85,6 +86,28 @@ MySqlConfigBackendImpl::~MySqlConfigBackendImpl() {
}
}
MySqlBindingPtr
MySqlConfigBackendImpl::createBinding(const Triplet<uint32_t>& triplet) {
if (triplet.unspecified()) {
return (MySqlBinding::createNull());
}
return (MySqlBinding::createInteger<uint32_t>(triplet.get()));
}
Triplet<uint32_t>
MySqlConfigBackendImpl::createTriplet(const MySqlBindingPtr& binding) {
if (!binding) {
isc_throw(Unexpected, "MySQL configuration backend internal error: "
"binding pointer is NULL when creating a triplet value");
}
if (binding->amNull()) {
return (Triplet<uint32_t>());
}
return (Triplet<uint32_t>(binding->getInteger<uint32_t>()));
}
void
MySqlConfigBackendImpl::createAuditRevision(const int index,
const ServerSelector& server_selector,
......
......@@ -106,6 +106,25 @@ public:
/// @brief Destructor.
~MySqlConfigBackendImpl();
/// @brief Creates MySQL binding from a @c Triplet.
///
/// @param triplet Triplet value from which the binding should be created.
/// @return Pointer to a null binding if the triplet is "unspecified" or
/// a pointer to a binding representing 32-bit unsigned integer value
/// otherwise.
static db::MySqlBindingPtr createBinding(const Triplet<uint32_t>& triplet);
/// @brief Creates @c Triplet object from MySQL binding.
///
/// @param binding Pointer to the MySQL binding.
/// @return Triplet value set to "unspecified" if the MySQL binding
/// represents a NULL value or a Triplet value encapsulating 32-bit
/// unsigned integer if the MySQL represents an integer.
/// @throw isc::Unexpected if the provided binding pointer is NULL.
/// @throw isc::InvalidOperation if the binding does not represent
/// a 32-bit unsigned integer.
static Triplet<uint32_t> createTriplet(const db::MySqlBindingPtr& binding);
/// @brief Returns server tags associated with the particular selector.
///
/// @param server_selector Server selector.
......
......@@ -2,7 +2,7 @@ SUBDIRS = .
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/mysql_cb -I$(top_srcdir)/src/hooks/dhcp/mysql_cb
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CPPFLAGS += $(BOOST_INCLUDES) $(MYSQL_CPPFLAGS)
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
AM_CXXFLAGS = $(KEA_CXXFLAGS)
......@@ -25,6 +25,7 @@ TESTS += mysql_cb_unittests
mysql_cb_unittests_SOURCES = mysql_cb_dhcp4_unittest.cc
mysql_cb_unittests_SOURCES += mysql_cb_dhcp4_mgr_unittest.cc
mysql_cb_unittests_SOURCES += mysql_cb_impl_unittest.cc
mysql_cb_unittests_SOURCES += run_unittests.cc
mysql_cb_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
......
......@@ -152,6 +152,10 @@ public:
test_subnets_.push_back(subnet);
subnet.reset(new Subnet4(IOAddress("192.0.3.0"), 24, 20, 30, 40, 2048));
Triplet<uint32_t> null_timer;
subnet->setT1(null_timer);
subnet->setT2(null_timer);
subnet->setValid(null_timer);
test_subnets_.push_back(subnet);
subnet.reset(new Subnet4(IOAddress("192.0.4.0"), 24, 30, 40, 60, 4096));
......@@ -200,6 +204,10 @@ public:
// Add more shared networks.
shared_network.reset(new SharedNetwork4("level2"));
Triplet<uint32_t> null_timer;
shared_network->setT1(null_timer);
shared_network->setT2(null_timer);
shared_network->setValid(null_timer);
test_networks_.push_back(shared_network);
shared_network.reset(new SharedNetwork4("level3"));
......
// Copyright (C) 2019 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
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <mysql_cb_impl.h>
#include <gtest/gtest.h>
using namespace isc::db;
using namespace isc::dhcp;
namespace {
// Test that the MySQL binding can be created from a triplet.
TEST(MySqlConfigBackendImplTest, createBindingFromTriplet) {
// Create a binding from an unspecified triplet.
auto binding = MySqlConfigBackendImpl::createBinding(Triplet<uint32_t>());
// The binding pointer should be non-null but the type of the binding
// should be null.
ASSERT_TRUE(binding);
EXPECT_TRUE(binding->amNull());
// This time create a triplet encapsulating a number.
binding = MySqlConfigBackendImpl::createBinding(Triplet<uint32_t>(123));
ASSERT_TRUE(binding);
// The binding type should be non-null.
ASSERT_FALSE(binding->amNull());
ASSERT_EQ(MYSQL_TYPE_LONG, binding->getType());
// Check that the correct value was stored in the binding.
EXPECT_EQ(123, binding->getInteger<uint32_t>());
}
// Test that the triplet can be created from the MySQL binding.
TEST(MySqlConfigBackendImplTest, createTripletFromBinding) {
// Create a binding encapsulating a number and try to create a triplet
// from this binding.
MySqlBindingPtr binding = MySqlBinding::createInteger<uint32_t>(234);
Triplet<uint32_t> triplet;
ASSERT_NO_THROW(triplet = MySqlConfigBackendImpl::createTriplet(binding));
// The triplet should be specified and equal to the value stored in the
// binding.
ASSERT_FALSE(triplet.unspecified());
EXPECT_EQ(234, triplet.get());
// Create a null binding and then use it to create a triplet.
binding = MySqlBinding::createNull();
ASSERT_NO_THROW(triplet = MySqlConfigBackendImpl::createTriplet(binding));
// This time the triplet should be unspecified.
EXPECT_TRUE(triplet.unspecified());
// Finally, make sure that the null binding pointer is rejected.
EXPECT_THROW(MySqlConfigBackendImpl::createTriplet(MySqlBindingPtr()),
isc::Unexpected);
}
}
......@@ -10,12 +10,16 @@ namespace isc {
namespace data {
StampedElement::StampedElement()
: timestamp_(boost::posix_time::microsec_clock::local_time()) {
/// @todo Change it to microsec_clock once we transition to subsecond
/// precision.
: timestamp_(boost::posix_time::second_clock::local_time()) {
}
void
StampedElement::updateModificationTime() {
setModificationTime(boost::posix_time::microsec_clock::local_time());
/// @todo Change it to microsec_clock once we transition to subsecond
/// precision.
setModificationTime(boost::posix_time::second_clock::local_time());
}
} // end of namespace isc::data
......
// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-2019 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 <cql/cql_connection.h>
#include <cql/testutils/cql_schema.h>
#include <exceptions/exceptions.h>
#include <stdlib.h>
......@@ -79,6 +80,7 @@ runCqlScript(const std::string& path,
int32_t retval = ::system(cmd.str().c_str());
if (retval) {
std::cerr << "runCqlSchema failed:" << cmd.str() << std::endl;
isc_throw(Unexpected, "runCqlSchema failed:" << cmd.str());
}
}
......
// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-2019 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
......@@ -57,11 +57,12 @@ void createCqlSchema(bool force_wipe, bool show_err = false);
/// Submits the given CQL script to CQL via cqlsh CLI. The output of
/// stderr is suppressed unless the parameter, show_err is true. The is done
/// to suppress warnings that might otherwise make test output needlessly
/// noisy. A gtest assertion occurs if the script fails to execute.
/// noisy. An exception is thrown if the script fails to execute.
///
/// @param path - path (if not blank) of the script to execute
/// @param script_name - file name of the path to execute
/// @param show_err flag which governs whether or not stderr is suppressed.
/// @throw Unexpected when the script returns an error.
void runCqlScript(const std::string& path, const std::string& script_name,
bool show_err);
......
......@@ -220,10 +220,14 @@ public:
/// data associated with one of the "bind" elements, the
/// corresponding element in the error array is set to MLM_TRUE.
static void setErrorIndicators(std::vector<MYSQL_BIND>& bind,
std::vector<my_bool>& error) {
std::vector<my_bools>& error) {
for (size_t i = 0; i < error.size(); ++i) {
error[i] = MLM_FALSE;
#ifdef HAVE_MYSQL_MY_BOOL
bind[i].error = reinterpret_cast<char*>(&error[i]);
#else
bind[i].error = reinterpret_cast<bool*>(&error[i]);
#endif
}
};
......@@ -240,7 +244,7 @@ public:
/// the error.
/// @param names Array of column names, the same size as the error array.
/// @param count Size of each of the arrays.
static std::string getColumnsInError(std::vector<my_bool>& error,
static std::string getColumnsInError(std::vector<my_bools>& error,
const std::vector<std::string>& names) {
std::string result = "";
......@@ -723,7 +727,7 @@ protected:
std::vector<std::string> columns_;
/// Error array.
std::vector<my_bool> error_;
std::vector<my_bools> error_;
/// Pointer to Host object holding information to be inserted into
/// Hosts table.
......@@ -2132,6 +2136,8 @@ public:
bool is_readonly_;
};
namespace {
/// @brief Array of tagged statements.
typedef boost::array<TaggedStatement, MySqlHostDataSourceImpl::NUM_STATEMENTS>
TaggedStatementArray;
......@@ -2430,6 +2436,8 @@ TaggedStatementArray tagged_statements = { {
}
};
}; // anonymous namespace
MySqlHostDataSourceImpl::
MySqlHostDataSourceImpl(const MySqlConnection::ParameterMap& parameters)
: host_exchange_(new MySqlHostWithOptionsExchange(MySqlHostWithOptionsExchange::DHCP4_ONLY)),
......
......@@ -336,7 +336,11 @@ public:
size_t count) {
for (size_t i = 0; i < count; ++i) {
error[i] = MLM_FALSE;
#ifdef HAVE_MYSQL_MY_BOOL
bind[i].error = reinterpret_cast<char*>(&error[i]);
#else
bind[i].error = &error[i];
#endif
}
}
......
......@@ -158,8 +158,11 @@ MySqlBinding::convertToDatabaseTime(const boost::posix_time::ptime& input_time,
output_time.hour = input_time.time_of_day().hours();
output_time.minute = input_time.time_of_day().minutes();
output_time.second = input_time.time_of_day().seconds();
output_time.second_part = input_time.time_of_day().fractional_seconds()
*1000000/time_duration::ticks_per_second();
/// @todo Use fractional seconds instead of 0 when minimum supported
/// MySQL version has it.
output_time.second_part = 0;
/* output_time.second_part = input_time.time_of_day().fractional_seconds()
*1000000/time_duration::ticks_per_second(); */
output_time.neg = my_bool(0);
}
......@@ -218,7 +221,10 @@ MySqlBinding::convertFromDatabaseTime(const MYSQL_TIME& expire,
ptime
MySqlBinding::convertFromDatabaseTime(const MYSQL_TIME& database_time) {
long fractional = database_time.second_part * time_duration::ticks_per_second()/1000000;
/// @todo Use fractional seconds instead of 0 when minimum supported
/// MySQL version has it.
long fractional = 0;
// long fractional = database_time.second_part * time_duration::ticks_per_second()/1000000;
ptime pt(boost::gregorian::date(database_time.year,
boost::gregorian::greg_month(database_time.month),
database_time.day),
......
......@@ -23,6 +23,8 @@ using namespace std;
namespace isc {
namespace db {
bool MySqlHolder::atexit_ = false;
/// @todo: Migrate this default value to src/bin/dhcpX/simple_parserX.cc
const int MYSQL_DEFAULT_CONNECTION_TIMEOUT = 5; // seconds
......
......@@ -92,10 +92,15 @@ public:
/// @brief Constructor
///
/// Push a call to mysql_library_end() at exit time.
/// Initialize MySql and store the associated context object.
///
/// @throw DbOpenError Unable to initialize MySql handle.
MySqlHolder() : mysql_(mysql_init(NULL)) {
if (!atexit_) {
atexit([]{ mysql_library_end(); });
atexit_ = true;
}
if (mysql_ == NULL) {
isc_throw(db::DbOpenError, "unable to initialize MySQL");
}
......@@ -108,8 +113,7 @@ public:
if (mysql_ != NULL) {
mysql_close(mysql_);
}
// The library itself shouldn't be needed anymore
mysql_library_end();
// @note Moved the call to mysql_library_end() to atexit.
}
/// @brief Conversion Operator
......@@ -121,6 +125,8 @@ public:
}
private:
static bool atexit_; ///< Flag to call atexit once.
MYSQL* mysql_; ///< Initialization context
};
......
......@@ -16,12 +16,31 @@ namespace db {
///
//@{
#ifdef HAVE_MYSQL_MY_BOOL
/// @brief my_bools type for vectors.
typedef my_bool my_bools;
/// @brief MySQL false value.
const my_bool MLM_FALSE = 0;
/// @brief MySQL true value.
const my_bool MLM_TRUE = 1;
#else
/// @brief my_bool type in MySQL 8.x.
typedef bool my_bool;
/// @brief my_bools type for vectors in MySQL 8.x.
/// @note vector<my_bool> is specialized into a bitset.
typedef char my_bools;
/// @brief MySQL false value.
const my_bool MLM_FALSE = false;
/// @brief MySQL true value.
const my_bool MLM_TRUE = true;
#endif
/// @brief MySQL fetch success code.
const int MLM_MYSQL_FETCH_SUCCESS = 0;
......
......@@ -96,7 +96,9 @@ TEST(MySqlBindingTest, defaultTimestamp) {
// This test verifies that the binding preserves fractional seconds in
// millisecond precision.
TEST(MySqlBindingTest, millisecondTimestampPrecision) {
/// @todo This test is disabled until we decide that the minimum
/// supported MySQL version has a fractional seconds precision.
TEST(MySqlBindingTest, DISABLED_millisecondTimestampPrecision) {
// Set timestamp of 2019-01-28 01:12:10.123
// Fractional part depends on the clock resolution.
......
......@@ -99,13 +99,19 @@ public:
/// The new table contains 6 columns of various data types. All of
/// the columns accept null values.
void createTestTable() {
/// @todo TIMESTAMP value lacks sub second precision because
/// it is supported since MySQL 5.6.4, which is still not a
/// default version on some OSes. When the subsecond precision
/// is available on all OSes that Kea supports, the timestamp
/// column should be turned to TIMESTAMP(6). Until then, it
/// must remain TIMESTAMP.
runQuery("CREATE TABLE IF NOT EXISTS mysql_connection_test ("
"tinyint_value TINYINT NULL,"
"int_value INT NULL,"
"bigint_value BIGINT NULL,"
"string_value TEXT NULL,"
"blob_value BLOB NULL,"
"timestamp_value TIMESTAMP(6) NULL"
"timestamp_value TIMESTAMP NULL"
")");
}
......@@ -236,7 +242,9 @@ TEST_F(MySqlConnectionTest, select) {
MySqlBinding::createInteger<int64_t>(-4096),
MySqlBinding::createString("shellfish"),
MySqlBinding::createBlob(blob.begin(), blob.end()),
MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::local_time())
/// @todo Change it to microsec_clock once we transition to subsecond
/// precision.
MySqlBinding::createTimestamp(boost::posix_time::second_clock::local_time())
};
testInsertSelect(in_bindings);
......@@ -252,7 +260,9 @@ TEST_F(MySqlConnectionTest, selectNullInteger) {
MySqlBinding::createInteger<int64_t>(-4096),
MySqlBinding::createString("shellfish"),
MySqlBinding::createBlob(blob.begin(), blob.end()),
MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::local_time())
/// @todo Change it to microsec_clock once we transition to subsecond
/// precision.
MySqlBinding::createTimestamp(boost::posix_time::second_clock::local_time())
};
testInsertSelect(in_bindings);
......@@ -269,7 +279,9 @@ TEST_F(MySqlConnectionTest, selectNullString) {
MySqlBinding::createInteger<int64_t>(-4096),
MySqlBinding::createNull(),
MySqlBinding::createBlob(blob.begin(), blob.end()),
MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::local_time())
/// @todo Change it to microsec_clock once we transition to subsecond
/// precision.
MySqlBinding::createTimestamp(boost::posix_time::second_clock::local_time())
};
testInsertSelect(in_bindings);
......@@ -284,7 +296,9 @@ TEST_F(MySqlConnectionTest, selectNullBlob) {
MySqlBinding::createInteger<int64_t>(-4096),
MySqlBinding::createString("shellfish"),
MySqlBinding::createNull(),
MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::local_time())
/// @todo Change it to microsec_clock once we transition to subsecond
/// precision.
MySqlBinding::createTimestamp(boost::posix_time::second_clock::local_time())
};
testInsertSelect(in_bindings);
......@@ -315,7 +329,9 @@ TEST_F(MySqlConnectionTest, selectEmptyStringBlob) {
MySqlBinding::createInteger<int64_t>(-4096),
MySqlBinding::createString(""),
MySqlBinding::createBlob(blob.begin(), blob.end()),
MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::local_time())
/// @todo Change it to microsec_clock once we transition to subsecond
/// precision.
MySqlBinding::createTimestamp(boost::posix_time::second_clock::local_time())
};
testInsertSelect(in_bindings);
......
// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-2019 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 <mysql.h>
#include <mysql/testutils/mysql_schema.h>
#include <mysql/mysql_connection.h>
#include <exceptions/exceptions.h>
#include <fstream>
#include <iostream>
......@@ -54,6 +55,7 @@ void runMySQLScript(const std::string& path, const std::string& script_name,
int retval = ::system(cmd.str().c_str());
if (retval) {
std::cerr << "runMySQLSchema failed:" << cmd.str() << std::endl;
isc_throw(Unexpected, "runMySQLSchema failed:" << cmd.str());
}
}
......
// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-2019 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
......@@ -53,11 +53,12 @@ void createMySQLSchema(bool show_err = false);
/// Submits the given SQL script to MySQL via mysql CLI. The output of
/// stderr is suppressed unless the parameter, show_err is true. The is done
/// to suppress warnings that might otherwise make test output needlessly
/// noisy. A gtest assertion occurs if the script fails to execute.
/// noisy. An exception is thrown if the script fails to execute.
///
/// @param path - path (if not blank) of the script to execute
/// @param script_name - file name of the path to execute
/// @param show_err flag which governs whether or not stderr is suppressed.
/// @throw Unexpected when the script returns an error.
void runMySQLScript(const std::string& path, const std::string& script_name,
bool show_err);
......
// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2016-2019 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
......@@ -7,6 +7,7 @@
#include <config.h>
#include <string>
#include <pgsql/testutils/pgsql_schema.h>
#include <exceptions/exceptions.h>
#include <libpq-fe.h>
......@@ -56,6 +57,7 @@ void runPgSQLScript(const std::string& path, const std::string& script_name,
int retval = ::system(cmd.str().c_str());
if (retval) {
std::cerr << "runPgSQLSchema failed:" << cmd.str() << std::endl;
isc_throw(Unexpected, "runPgSQLSchema failed:" << cmd.str());
}
}
......
// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2016-2019 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
......@@ -53,11 +53,12 @@ void createPgSQLSchema(bool show_err = false);
/// Submits the given SQL script to Postgresql via psql CLI. The output of
/// stderr is suppressed unless the parameter, show_err is true. The is done
/// to suppress warnings that might otherwise make test output needlessly
/// noisy. A gtest assertion occurs if the script fails to execute.
/// noisy. An exception is thrown if the script fails to execute.
///
/// @param path - path (if not blank) of the script to execute
/// @param script_name - file name of the path to execute
/// @param show_err flag which governs whether or not stderr is suppressed.
/// @throw Unexpected when the script returns an error.
void runPgSQLScript(const std::string& path, const std::string& script_name,
bool show_err);
......
// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2010-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,7 +98,15 @@ recv_fd(const int sock) {
int fd = FD_OTHER_ERROR;
if (cmsg != NULL && cmsg->cmsg_len == cmsg_len(sizeof(int)) &&
cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
// Some systems (e.g. recent NetBSD) converted all CMSG access macros
// to static_cast when used in C++ code. As cmsg is declared const
// this makes the CMSG_DATA macro to not compile. But fortunately
// these systems provide a const alternative named CCMSG_DATA.
#ifdef CCMSG_DATA
std::memcpy(&fd, CCMSG_DATA(cmsg), sizeof(int));
#else
std::memcpy(&fd, CMSG_DATA(cmsg), sizeof(int));
#endif
}
free(msghdr.msg_control);
int new_fd = -1;
......
......@@ -1334,89 +1334,14 @@ SET version = '7', minor = '0';
# This line concludes database upgrade to version 7.0.
-- -----------------------------------------------------
-- Modify timestamps in the Configuration Backend
-- specific tables to use fractional seconds with
-- 6 decimal places precision.
-- -----------------------------------------------------
ALTER TABLE dhcp4_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_audit
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_global_parameter
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_global_parameter_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_option_def
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_option_def_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_shared_network
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_shared_network_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_subnet
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_pool
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_subnet_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_options
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_options_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_audit
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_global_parameter
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_global_parameter_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_option_def
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_option_def_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_shared_network
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_shared_network_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_subnet
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_pool
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_subnet_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
MODIFY COLUMN modification_ts TIMESTAMP NOT NULL
DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE dhcp6_options
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_options_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
MODIFY COLUMN modification_ts TIMESTAMP NOT NULL
DEFAULT CURRENT_TIMESTAMP;
-- -----------------------------------------------------
-- Make sure that constraints on the 7.0 schema tables
......@@ -1520,7 +1445,7 @@ ALTER TABLE dhcp6_options_server
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS dhcp4_audit_revision (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
modification_ts TIMESTAMP(6) NOT NULL,
modification_ts TIMESTAMP NOT NULL,
log_message TEXT,
server_id BIGINT(10) UNSIGNED,
PRIMARY KEY (id),
......@@ -1577,7 +1502,7 @@ ALTER TABLE dhcp4_audit
-- -----------------------------------------------------
DROP PROCEDURE IF EXISTS createAuditRevisionDHCP4;
DELIMITER $$
CREATE PROCEDURE createAuditRevisionDHCP4(IN audit_ts TIMESTAMP(6),
CREATE PROCEDURE createAuditRevisionDHCP4(IN audit_ts TIMESTAMP,
IN server_tag VARCHAR(256),
IN audit_log_message TEXT,
IN cascade_transaction TINYINT(1))
......
......@@ -17,89 +17,14 @@ fi
mysql "$@" <<EOF
-- -----------------------------------------------------
-- Modify timestamps in the Configuration Backend
-- specific tables to use fractional seconds with
-- 6 decimal places precision.
-- -----------------------------------------------------
ALTER TABLE dhcp4_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_audit
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_global_parameter
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_global_parameter_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_option_def
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_option_def_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_shared_network
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_shared_network_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_subnet
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_pool
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_subnet_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_options
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp4_options_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_audit
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_global_parameter
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_global_parameter_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_option_def
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_option_def_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_shared_network
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_shared_network_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_subnet
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_pool
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_subnet_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
MODIFY COLUMN modification_ts TIMESTAMP NOT NULL
DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE dhcp6_options
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
ALTER TABLE dhcp6_options_server
MODIFY COLUMN modification_ts TIMESTAMP(6) NOT NULL;
MODIFY COLUMN modification_ts TIMESTAMP NOT NULL
DEFAULT CURRENT_TIMESTAMP;
-- -----------------------------------------------------
-- Make sure that constraints on the 7.0 schema tables
......@@ -203,7 +128,7 @@ ALTER TABLE dhcp6_options_server
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS dhcp4_audit_revision (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
modification_ts TIMESTAMP(6) NOT NULL,
modification_ts TIMESTAMP NOT NULL,
log_message TEXT,
server_id BIGINT(10) UNSIGNED,
PRIMARY KEY (id),
......@@ -260,7 +185,7 @@ ALTER TABLE dhcp4_audit
-- -----------------------------------------------------
DROP PROCEDURE IF EXISTS createAuditRevisionDHCP4;
DELIMITER $$
CREATE PROCEDURE createAuditRevisionDHCP4(IN audit_ts TIMESTAMP(6),
CREATE PROCEDURE createAuditRevisionDHCP4(IN audit_ts TIMESTAMP,
IN server_tag VARCHAR(256),
IN audit_log_message TEXT,
IN cascade_transaction TINYINT(1))
......