const DbCallback db_reconnect_callback)
: conn_(parameters,
IOServiceAccessorPtr(new IOServiceAccessor(PgSqlConfigBackendImpl::getIOService)),
- db_reconnect_callback), timer_name_(""),
- audit_revision_created_(false), parameters_(parameters) {
+ db_reconnect_callback), timer_name_(""), audit_revision_created_(false),
+ parameters_(parameters) {
+
// Test schema version first.
- std::pair<uint32_t, uint32_t> code_version(PG_SCHEMA_VERSION_MAJOR,
- PG_SCHEMA_VERSION_MINOR);
- std::pair<uint32_t, uint32_t> db_version =
- PgSqlConnection::getVersion(parameters);
+ std::pair<uint32_t, uint32_t> code_version(PG_SCHEMA_VERSION_MAJOR, PG_SCHEMA_VERSION_MINOR);
+ std::pair<uint32_t, uint32_t> db_version = PgSqlConnection::getVersion(parameters);
if (code_version != db_version) {
isc_throw(DbOpenError, "Postgres schema version mismatch: need version: "
<< code_version.first << "." << code_version.second
- << " found version: " << db_version.first << "."
- << db_version.second);
+ << " found version: " << db_version.first << "." << db_version.second);
}
// Open the database.
return (bind);
}
-/* Triplet<uint32_t>
-PgSqlConfigBackendImpl::createTriplet(const PsqlBindArrayPtr& binding) {
- if (!binding) {
- isc_throw(Unexpected, "Postgres configuration backend internal error: "
- "binding pointer is NULL when creating a triplet value");
- }
-
- if (binding->empty()) {
- return (Triplet<uint32_t>());
- }
-
- return (Triplet<uint32_t>(binding->getInteger<uint32_t>()));
-} */
-
-/* Triplet<uint32_t>
-PgSqlConfigBackendImpl::createTriplet(const PsqlBindArrayPtr& def_binding,
- const PsqlBindArrayPtr& min_binding,
- const PsqlBindArrayPtr& max_binding) {
- if (!def_binding || !min_binding || !max_binding) {
- isc_throw(Unexpected, "Postgres configuration backend internal error: "
- "binding pointer is NULL when creating a triplet value");
- }
-
- // This code assumes the database was filled using the API, e.g. it
- // is not possible (so not handled) to have only the min_binding not NULL.
- if (def_binding->empty()) {
- return (Triplet<uint32_t>());
- }
-
- uint32_t value = def_binding->getInteger<uint32_t>();
- uint32_t min_value = value;
- if (!min_binding->empty()) {
- min_value = min_binding->getInteger<uint32_t>();
- }
- uint32_t max_value = value;
- if (!max_binding->empty()) {
- max_value = max_binding->getInteger<uint32_t>();
- }
-
- return (Triplet<uint32_t>(min_value, value, max_value));
-} */
-
void
PgSqlConfigBackendImpl::createAuditRevision(const int index,
const ServerSelector& server_selector,
std::string
PgSqlConfigBackendImpl::getType() const {
- return ("mysql");
+ return ("pgsql");
}
std::string
#include <config.h>
#include <pgsql_cb_impl.h>
#include <gtest/gtest.h>
+#include <dhcpsrv/testutils/pgsql_generic_backend_unittest.h>
+#include <vector>
using namespace isc::db;
using namespace isc::dhcp;
+using namespace isc::dhcp::test;
namespace {
+typedef PsqlBindArrayPtr (tripletFunc) (const Triplet<uint32_t>& triplet);
+
+class PgsqlConfigBackendTest: public PgSqlGenericBackendTest {
+public:
+ PgsqlConfigBackendTest(): PgSqlGenericBackendTest() {
+ DatabaseConnection::ParameterMap params;
+ params["name"] = "keatest";
+ params["password"] = "keatest";
+ params["user"] = "keatest";
+
+ cbptr_.reset(new PgSqlConfigBackendImpl(params, 0));
+
+ }
+
+ /// @brief checks if specified triplet generating function stores the values properly.
+ ///
+ /// @param f function pointer to a function that converts triplet to PgSqlBindArray
+ /// @param t triplet to be converted
+ /// @param exp expected value or values
+ void checkBinding(tripletFunc f, Triplet<uint32_t> t, std::vector<uint32_t> exp) {
+ PsqlBindArrayPtr binding = f(t);
+
+ // Special case: empty binding
+ if (exp.empty()) {
+ // Binding should have one field that is set to null value.
+ ASSERT_TRUE(binding);
+ EXPECT_TRUE(binding->amNull());
+ return;
+ }
+
+ // Let's check if the size of the binding equals expectations
+ ASSERT_EQ(binding->size(), exp.size());
+
+ for (int i = 0; i < exp.size(); i++) {
+ // The field should not be empty
+ ASSERT_FALSE(binding->amNull(i));
+
+ // The field should have a type set to text (Postgres stores integers as text)
+ EXPECT_EQ(PsqlBindArray::TEXT_FMT, binding->getType(i));
+
+ // Check that the correct value was stored in the binding.
+ EXPECT_EQ(exp[i], binding->getInteger<uint32_t>(i));
+ }
+ }
+
+ boost::shared_ptr<PgSqlConfigBackendImpl> cbptr_;
+};
+
+// Let's start with absolute basics. Is this the right type?
+TEST_F(PgsqlConfigBackendTest, triplet) {
+ EXPECT_EQ("pgsql", cbptr_->getType());
+}
+
+// Test that the Postgres binding can be created from a triplet.
+// the createBinding function takes the default value of a triplet.
+TEST_F(PgsqlConfigBackendTest, createBinding) {
+
+ tripletFunc &f = PgSqlConfigBackendImpl::createBinding;
+ std::vector<uint32_t> exp;
+
+ // Case 1: empty triplet creates empty binding
+ checkBinding(f, Triplet<uint32_t>(), exp);
+
+ // Case 2: triplet with just one value should create a single entry with that value
+ exp.push_back(222);
+ checkBinding(f, Triplet<uint32_t>(222), exp);
+
+ // Case 3: an actual triplet with 3 values should create a single entry with the
+ // default (middle) value
+ checkBinding(f, Triplet<uint32_t>(111, 222, 333), exp);
+}
+
+// Test that the Postgres binding can be created from a triplet.
+// the createBinding function takes the default value of a triplet.
+TEST_F(PgsqlConfigBackendTest, createMinBinding) {
+
+ tripletFunc &f = PgSqlConfigBackendImpl::createMinBinding;
+ std::vector<uint32_t> exp;
+
+ // Case 1: empty triplet creates empty binding
+ checkBinding(f, Triplet<uint32_t>(), exp);
+
+ // Case 2: triplet with just one value should not generate min binding
+ // (the value is supposed to be used in default binding)
+ checkBinding(f, Triplet<uint32_t>(111), exp);
+
+ // Case 3: an actual triplet with 3 values should create a single entry with the
+ // min (first) value
+ exp.push_back(111);
+ checkBinding(f, Triplet<uint32_t>(111, 222, 333), exp);
+}
+
// Test that the Postgres binding can be created from a triplet.
-TEST(PgSqlConfigBackendImplTest, createBindingFromTriplet) {
- // Create a binding from an unspecified triplet.
- auto binding = PgSqlConfigBackendImpl::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 = PgSqlConfigBackendImpl::createBinding(Triplet<uint32_t>(123));
- ASSERT_TRUE(binding);
- // The binding type should be non-null.
- ASSERT_FALSE(binding->amNull());
- ASSERT_EQ(PsqlBindArray::TEXT_FMT, binding->getType());
- // Check that the correct value was stored in the binding.
- EXPECT_EQ(123, binding->getInteger<uint32_t>(0));
+// the createBinding function takes the default value of a triplet.
+TEST_F(PgsqlConfigBackendTest, createMaxBinding) {
+
+ tripletFunc &f = PgSqlConfigBackendImpl::createMaxBinding;
+ std::vector<uint32_t> exp;
+
+ // Case 1: empty triplet creates empty binding
+ checkBinding(f, Triplet<uint32_t>(), exp);
+
+ // Case 2: triplet with just one value should not generate max binding
+ // (the value is supposed to be used in default binding)
+ checkBinding(f, Triplet<uint32_t>(333), exp);
+
+ // Case 3: an actual triplet with 3 values should create a single entry with the
+ // max (third) value
+ exp.push_back(333);
+ checkBinding(f, Triplet<uint32_t>(111, 222, 333), exp);
}
+
}