#include <pgsql/pgsql_exchange.h>
#include <pgsql/pgsql_connection.h>
+#include <exceptions/exceptions.h>
#include <boost/lexical_cast.hpp>
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;
#include <asiolink/io_address.h>
#include <pgsql/pgsql_connection.h>
+#include <exceptions/exceptions.h>
#include <boost/lexical_cast.hpp>
#include <boost/noncopyable.hpp>
/// @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_;
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