]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1848] Added test methods to PsqlBindArray
authorTomek Mrugalski <tomek@isc.org>
Thu, 1 Jul 2021 14:22:05 +0000 (16:22 +0200)
committerTomek Mrugalski <tomek@isc.org>
Wed, 17 Nov 2021 14:35:18 +0000 (15:35 +0100)
 - amNull(), getInteger<T>, getType()

src/lib/pgsql/pgsql_exchange.cc
src/lib/pgsql/pgsql_exchange.h
src/lib/pgsql/tests/pgsql_exchange_unittest.cc

index d65aa6dee67e79119d4cc896b7fea531a96410db..2c8d8158d5b56d593829556e147a10ccc8b2c729 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <pgsql/pgsql_exchange.h>
 #include <pgsql/pgsql_connection.h>
+#include <exceptions/exceptions.h>
 
 #include <boost/lexical_cast.hpp>
 
@@ -117,6 +118,19 @@ std::string PsqlBindArray::toText() const {
     return (stream.str());
 }
 
+bool
+PsqlBindArray::amNull(size_t index) const {
+    if (values_.size() < index + 1) {
+        isc_throw(OutOfRange, "The index " << index << " is larger than the "
+        " array size " << values_.size());
+    }
+
+    // We assume lengths_.size() always equals values_.size(). If not, the
+    // at() operator will throw.
+    return ( (values_.at(index) == NULL) && (lengths_.at(index) == 0) );
+}
+
+
 std::string
 PgSqlExchange::convertToDatabaseTime(const time_t input_time) {
     struct tm tinfo;
index 8d166e3af61544184b28daaca73c825087dde829..0535dce605a901aec1862be6abe2a3caa9fd62dd 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <asiolink/io_address.h>
 #include <pgsql/pgsql_connection.h>
+#include <exceptions/exceptions.h>
 
 #include <boost/lexical_cast.hpp>
 #include <boost/noncopyable.hpp>
@@ -183,6 +184,47 @@ struct PsqlBindArray {
     /// @return std::string containing the dump
     std::string toText() const;
 
+    // --- the following methods are mostly useful for testing -----
+
+    /// @brief Determines if specified value is null
+    /// @param index if array holds more than one value, this index determines
+    ///         which column to use
+    /// @return true if the column is defined and is null
+    bool amNull(size_t index = 0) const;
+
+    /// @brief Returns the value as an integer.
+    /// @param index if array holds more than one value, this index determines
+    ///         which column to use
+    /// @return value interpreted as specified integer type
+    /// @throw OutOfRange if the offset is too large
+    /// @throw BadValue if the data is null
+    /// @throw boost::bad_lexical_cast if value is not an integer
+    template<typename T>
+    T getInteger(size_t index = 0) {
+        if (values_.size() < index + 1) {
+            isc_throw(OutOfRange, "Invalid index " << index << ", the values array has "
+                                << values_.size() << " element(s)");
+        }
+        auto x = values_.at(index);
+        if (!x) {
+            isc_throw(BadValue, "the data in column " << index << " is null");
+        }
+        return (boost::lexical_cast<T>(x));
+    }
+
+    /// @brief Returns the column type
+    /// @param index if array holds more than one value, this index determines
+    ///         which column to use
+    /// @return the type of specified column
+    /// @throw BadValue if the offset is too large
+    int getType(size_t index = 0 ) {
+        if (formats_.size() < index + 1) {
+            isc_throw(OutOfRange, "Invalid index " << index << ", the formats_ array has "
+                                << formats_.size() << " element(s)");
+        }
+        return formats_.at(index);
+    }
+
 private:
     /// @brief vector of strings which supplied the values
     std::vector<ConstStringPtr> bound_strs_;
index 81a996f11ccd914cfb8854ddc1639037bf9ed56e..de45fda0b76697b4ce07096185ef09834f7a7b18 100644 (file)
@@ -757,6 +757,33 @@ TEST_F(PgSqlBasicsTest, intTest) {
     ASSERT_TRUE(PgSqlExchange::isColumnNull(*r, 0, INT_COL));
 }
 
+/// @brief Verify that we use the methods used for testing:
+/// amNull(), getInteger<T>(), getType()
+TEST_F(PgSqlBasicsTest, get) {
+    PsqlBindArray bind_array;
+
+    // The array itself is empty, its first column is not null
+    EXPECT_THROW(bind_array.amNull(), OutOfRange);
+    EXPECT_THROW(bind_array.getInteger<uint32_t>(), OutOfRange);
+    EXPECT_THROW(bind_array.getType(), OutOfRange);
+
+    // Now try again wi
+    bind_array.add(123); // This will be converted to "123" string.
+    bind_array.addNull();
+    bind_array.add("sagittarius");
+    EXPECT_FALSE(bind_array.amNull(0)); // first column is not null
+    EXPECT_TRUE(bind_array.amNull(1)); // second column is null
+    EXPECT_FALSE(bind_array.amNull(2)); // third column is not null
+
+    EXPECT_EQ(123, bind_array.getInteger<uint32_t>(0)); // first column is 123
+    EXPECT_THROW(bind_array.getInteger<uint32_t>(1), BadValue);
+    EXPECT_THROW(bind_array.getInteger<uint32_t>(2), boost::bad_lexical_cast);
+
+    EXPECT_EQ(PsqlBindArray::TEXT_FMT, bind_array.getType(0));
+    EXPECT_EQ(PsqlBindArray::TEXT_FMT, bind_array.getType(1));
+    EXPECT_EQ(PsqlBindArray::TEXT_FMT, bind_array.getType(2));
+}
+
 /// @brief Verify that we can read and write TEXT columns
 TEST_F(PgSqlBasicsTest, textTest) {
     // Create a prepared statement for inserting TEXT