diff --git a/pgsql/Pgsql_Col.h b/pgsql/Pgsql_Col.h index 5003d79..8136eb7 100644 --- a/pgsql/Pgsql_Col.h +++ b/pgsql/Pgsql_Col.h @@ -12,10 +12,39 @@ namespace Pgsql { {} void reset() { col = -1; } + Pgsql::Value nextValue() { return row.get(++col); } + + template + Col& getAsArray(I insert_iter, NullHandling nullhandling = NullHandling::Throw) + { + nextValue().getAsArray(insert_iter, nullhandling); + return *this; + } + + template + void getAsArray(I insert_iter, const E &value_for_nulls) const + { + nextValue().getAsArray(insert_iter, value_for_nulls); + return *this; + } + + template + void getAsArrayOfOptional(I insert_iter) const + { + nextValue().getAsArrayOfOptional(insert_iter); + return *this; + } + + template + Col& getAsVector(I insert_iter) + { + nextValue().getAsVector(insert_iter); + return *this; + } private: const Pgsql::Row &row; int col = -1; @@ -28,6 +57,7 @@ namespace Pgsql { return c; } + } // end namespace Pgsql #endif // PGSQL_COL_H diff --git a/pgsql/Pgsql_Value.h b/pgsql/Pgsql_Value.h index 3e4daaa..0e44db8 100644 --- a/pgsql/Pgsql_Value.h +++ b/pgsql/Pgsql_Value.h @@ -2,6 +2,7 @@ #define PGSQL_VALUE_H #include "Pgsql_declare.h" +#include "Pgsql_oids.h" #include "ArrayParser.h" #include #include @@ -33,10 +34,6 @@ namespace Pgsql { bool isString() const; - enum class NullHandling { - Ignore, - Throw - }; /** * * \param insert_iter An insert_iterator which is used to add the elements of the array to a container. @@ -51,7 +48,7 @@ namespace Pgsql { if (res.ok) { if (res.value) { std::string str(res.value->data(), res.value->length()); - Value val(str.c_str(), ANYOID); + Value val(str.c_str(), OidFor::elem()); value_type v; v << val; insert_iter = v; @@ -76,7 +73,7 @@ namespace Pgsql { if (res.ok) { if (res.value) { std::string str(res.value->data(), res.value->length()); - Value val(str.c_str(), ANYOID); + Value val(str.c_str(), OidFor::elem()); value_type v; v << val; insert_iter = v; @@ -100,7 +97,7 @@ namespace Pgsql { if (res.ok) { if (res.value) { std::string str(res.value->data(), res.value->length()); - Value val(str.c_str(), ANYOID); + Value val(str.c_str(), OidFor::elem()); value_type v; v << val; insert_iter = v; @@ -113,6 +110,28 @@ namespace Pgsql { break; } } + + /** De catalog uses vector types which are similar to array + * but uses spaces as seperators. AFAIK there are only integral + * vector types so this implementation is only tested for those + */ + template + void getAsVector(I insert_iter) const + { + const char * pos = m_val; + const char * start = pos; + for (;;) { + while (*pos != 0 && *pos != ' ') ++pos; + std::string str(start, pos-start); + Value val(str.c_str(), OidFor::elem()); + E v; + v << val; + insert_iter = v; + if (*pos == 0) + break; + start = ++pos; // skip space and set new start to match + } + } private: const char *m_val; Oid m_typ; diff --git a/pgsql/Pgsql_declare.h b/pgsql/Pgsql_declare.h index f54c6a8..47f76eb 100644 --- a/pgsql/Pgsql_declare.h +++ b/pgsql/Pgsql_declare.h @@ -102,6 +102,12 @@ namespace Pgsql { class Value; class Row; + enum class NullHandling { + Ignore, + Throw + }; + + } // END namespace Pgsql #endif // PGSQL_DECLARE_H diff --git a/pgsql/Pgsql_oids.h b/pgsql/Pgsql_oids.h index 4367683..295ef5c 100644 --- a/pgsql/Pgsql_oids.h +++ b/pgsql/Pgsql_oids.h @@ -2,6 +2,8 @@ #define PGSQL_OIDS_H #include +#include +#include namespace Pgsql { constexpr Oid bool_oid = 16; @@ -141,6 +143,47 @@ namespace Pgsql { Oid ElemOidFromArrayOid(Oid oid); Oid ArrayOidFromElemOid(Oid oid); + template + class OidFor { + public: + static Oid elem(); + static Oid array(); + }; + + template <> + class OidFor { + public: + static Oid elem() { return int2_oid; } + static Oid array() { return int2_array_oid; } + }; + + template <> + class OidFor { + public: + static Oid elem() { return int4_oid; } + static Oid array() { return int4_array_oid; } + }; + + template <> + class OidFor { + public: + static Oid elem() { return oid_oid; } + static Oid array() { return oid_array_oid; } + }; + + template <> + class OidFor { + public: + static Oid elem() { return timestamptz_oid; } + static Oid array() { return timestamptz_array_oid; } + }; +// template <> +// class OidFor<> { +// public: +// static Oid elem() { return _oid; } +// static Oid array() { return _array_oid; } +// }; + } // end of namespace Pgsql #endif // PGSQL_OIDS_H diff --git a/tests/PgsqlTests/tst_Value.cpp b/tests/PgsqlTests/tst_Value.cpp index 5d68f25..2f4385b 100644 --- a/tests/PgsqlTests/tst_Value.cpp +++ b/tests/PgsqlTests/tst_Value.cpp @@ -68,6 +68,19 @@ TEST(Pgsql_Value, isString_varchar) ASSERT_EQ(v.isString(), true); } +TEST(Pgsql_Value, getAsVector_Ints) +{ + Pgsql::Value v("1 2", ANYOID); + std::vector r; + v.getAsVector(std::back_inserter(r)); + + ASSERT_EQ(r.size(), 2); + ASSERT_EQ(r[0], 1); + ASSERT_EQ(r[1], 2); +} + + + TEST(Pgsql_Value, getAsArray_Ints) { Pgsql::Value v("{1,2}", TEXTARRAYOID); @@ -122,7 +135,7 @@ TEST(Pgsql_Value, getAsArray_ignore_NULL) Pgsql::Value v("{1,NULL,2}", TEXTARRAYOID); std::vector r; try { - v.getAsArray(std::back_inserter(r), Value::NullHandling::Ignore); + v.getAsArray(std::back_inserter(r), NullHandling::Ignore); ASSERT_EQ(r.size(), 2); ASSERT_EQ(r[0], 1); ASSERT_EQ(r[1], 2);