The getAsArray and getAsVector function now use StringToArrayElem template for conversion

to the array element type.

A five line construct had been copy pasted to achieve conversion by using the capabilities of the Value object
however this was not going to work for types that are not known to the database as adding support for these
to Value would be a bad idea. So StringToArrayElem was introduced with a default implementation that relies on
Value.
This commit is contained in:
eelke 2018-12-24 07:46:13 +01:00
parent 54d4dfface
commit efb3e71556

View file

@ -13,6 +13,9 @@
namespace Pgsql { namespace Pgsql {
template <typename E>
E StringToArrayElem(std::string_view sv);
/** \brief Class that is returned as value of a cell to facilitate auto conversion. /** \brief Class that is returned as value of a cell to facilitate auto conversion.
*/ */
class Value { class Value {
@ -40,6 +43,7 @@ namespace Pgsql {
bool isString() const; bool isString() const;
/// Retrieves an array type value and passes them to an insert iterator. /// Retrieves an array type value and passes them to an insert iterator.
/// ///
/// When the array it self is NULL this function behaves the same as for an empty array. No /// When the array it self is NULL this function behaves the same as for an empty array. No
@ -61,11 +65,7 @@ namespace Pgsql {
auto res = parser.GetNextElem(); auto res = parser.GetNextElem();
if (res.ok) { if (res.ok) {
if (res.value) { if (res.value) {
std::string str(res.value->data(), res.value->length()); insert_iter = StringToArrayElem<E>(*res.value);
Value val(str.c_str(), OidFor<E>::elem());
value_type v;
v << val;
insert_iter = v;
} }
else { else {
if (nullhandling == NullHandling::Throw) if (nullhandling == NullHandling::Throw)
@ -93,11 +93,7 @@ namespace Pgsql {
auto res = parser.GetNextElem(); auto res = parser.GetNextElem();
if (res.ok) { if (res.ok) {
if (res.value) { if (res.value) {
std::string str(res.value->data(), res.value->length()); insert_iter = StringToArrayElem<E>(*res.value);
Value val(str.c_str(), OidFor<E>::elem());
value_type v;
v << val;
insert_iter = v;
} }
else { else {
insert_iter = value_for_nulls; insert_iter = value_for_nulls;
@ -120,11 +116,7 @@ namespace Pgsql {
auto res = parser.GetNextElem(); auto res = parser.GetNextElem();
if (res.ok) { if (res.ok) {
if (res.value) { if (res.value) {
std::string str(res.value->data(), res.value->length()); insert_iter = StringToArrayElem<E>(*res.value);
Value val(str.c_str(), OidFor<E>::elem());
value_type v;
v << val;
insert_iter = v;
} }
else { else {
insert_iter = std::nullopt; insert_iter = std::nullopt;
@ -148,11 +140,7 @@ namespace Pgsql {
for (;;) { for (;;) {
while (*pos != 0 && *pos != ' ') ++pos; while (*pos != 0 && *pos != ' ') ++pos;
// The cast (to prevent warning) should be save as start should always be <= pos // The cast (to prevent warning) should be save as start should always be <= pos
std::string str(start, static_cast<size_t>(pos-start)); insert_iter = StringToArrayElem<E>(std::string_view(start, static_cast<size_t>(pos-start)));
Value val(str.c_str(), OidFor<E>::elem());
E v;
v << val;
insert_iter = v;
if (*pos == 0) if (*pos == 0)
break; break;
start = ++pos; // skip space and set new start to match start = ++pos; // skip space and set new start to match
@ -186,7 +174,16 @@ namespace Pgsql {
s = v.operator T(); s = v.operator T();
} }
template <typename E>
E StringToArrayElem(std::string_view sv)
{
std::string str(sv.data(), sv.length());
Value val(str.c_str(), OidFor<E>::elem());
E v;
v << val;
return v;
}
} // end namespace Pgsql } // end namespace Pgsql
#endif // PGSQL_VALUE_H #endif // PGSQL_VALUE_H