#2970: Poco::Data::TypeHandler<Poco::Nullable<T>>::prepare() must prepare with underlying type, not Poco::Data::Keywords::null

This commit is contained in:
Günter Obiltschnig 2021-04-11 16:26:32 +02:00
parent 12d3bf9c75
commit 347dc840b5

View File

@ -34,7 +34,7 @@ namespace Data {
class AbstractTypeHandler
/// Parent class for type handlers.
/// Parent class for type handlers.
/// The reason for this class is to prevent instantiations of type handlers.
/// For documentation on type handlers, see TypeHandler class.
{
@ -59,12 +59,12 @@ class TypeHandler: public AbstractTypeHandler
/// int _age;
/// public:
/// const std::string& getLastName();
/// [...] // other set/get methods (returning const reference), a default constructor,
/// [...] // other set/get methods (returning const reference), a default constructor,
/// [...] // optional < operator (for set, multiset) or function operator (for map, multimap)
/// };
///
/// The TypeHandler must provide a custom bind, size, prepare and extract method:
///
///
/// template <>
/// class TypeHandler<struct Person>
/// {
@ -73,7 +73,7 @@ class TypeHandler: public AbstractTypeHandler
/// {
/// return 3; // lastName + firstname + age occupy three columns
/// }
///
///
/// static void bind(std::size_t pos, const Person& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
/// {
/// // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))
@ -83,7 +83,7 @@ class TypeHandler: public AbstractTypeHandler
/// TypeHandler<std::string>::bind(pos++, obj.getFirstName(), pBinder, dir);
/// TypeHandler<int>::bind(pos++, obj.getAge(), pBinder, dir);
/// }
///
///
/// static void prepare(std::size_t pos, const Person& obj, AbstractPreparator::Ptr pPreparator)
/// {
/// // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))
@ -92,7 +92,7 @@ class TypeHandler: public AbstractTypeHandler
/// TypeHandler<std::string>::prepare(pos++, obj.getFirstName(), pPreparator);
/// TypeHandler<int>::prepare(pos++, obj.getAge(), pPreparator);
/// }
///
///
/// static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor::Ptr pExt)
/// {
/// // defVal is the default person we should use if we encunter NULL entries, so we take the individual fields
@ -249,52 +249,52 @@ private:
};
template <typename T>
class TypeHandler<Nullable<T>>
class TypeHandler<Nullable<T>>
/// Specialization of type handler for Nullable.
{
public:
static void bind(std::size_t pos, const Nullable<T>& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
static void bind(std::size_t pos, const Nullable<T>& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
{
poco_assert_dbg (!pBinder.isNull());
if (obj.isNull())
if (obj.isNull())
{
pBinder->bind(pos++, Poco::Data::Keywords::null, dir);
}
else
else
{
pBinder->bind(pos++, obj.value(), dir);
}
}
static void prepare(std::size_t pos, const Nullable<T>& obj, AbstractPreparator::Ptr pPreparator)
static void prepare(std::size_t pos, const Nullable<T>& obj, AbstractPreparator::Ptr pPreparator)
{
poco_assert_dbg (!pPreparator.isNull());
if (obj.isNull())
if (obj.isNull())
{
pPreparator->prepare(pos++, Poco::Data::Keywords::null);
pPreparator->prepare(pos++, T());
}
else
else
{
pPreparator->prepare(pos++, obj.value());
}
}
static std::size_t size()
static std::size_t size()
{
return 1u;
}
static void extract(std::size_t pos, Nullable<T>& obj, const Nullable<T>& , AbstractExtractor::Ptr pExt)
static void extract(std::size_t pos, Nullable<T>& obj, const Nullable<T>& , AbstractExtractor::Ptr pExt)
{
poco_assert_dbg (!pExt.isNull());
T val;
if (pExt->extract(pos++, val))
if (pExt->extract(pos++, val))
{
obj = std::move(val);
}
else
else
{
obj.clear();
}
@ -343,25 +343,25 @@ void tupleExtract(std::size_t& pos, TupleType tuple, DefValType defVal, Abstract
}
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13,
class T14,
class T15,
class T16,
class T17,
class T18,
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13,
class T14,
class T15,
class T16,
class T17,
class T18,
class T19>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19>>
{
@ -474,24 +474,24 @@ private:
};
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13,
class T14,
class T15,
class T16,
class T17,
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13,
class T14,
class T15,
class T16,
class T17,
class T18>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18>>
{
@ -600,23 +600,23 @@ private:
};
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13,
class T14,
class T15,
class T16,
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13,
class T14,
class T15,
class T16,
class T17>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17>>
{
@ -721,22 +721,22 @@ private:
};
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13,
class T14,
class T15,
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13,
class T14,
class T15,
class T16>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16>>
{
@ -837,21 +837,21 @@ private:
};
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13,
class T14,
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13,
class T14,
class T15>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15>>
{
@ -948,20 +948,20 @@ private:
};
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13,
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13,
class T14>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14>>
{
@ -1054,19 +1054,19 @@ private:
};
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12,
class T13>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13>>
{
@ -1155,18 +1155,18 @@ private:
};
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11,
class T12>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12>>
{
@ -1251,17 +1251,17 @@ private:
};
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10,
class T11>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>>
{
@ -1342,16 +1342,16 @@ private:
};
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
template <class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8,
class T9,
class T10>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>>
{
@ -1956,7 +1956,7 @@ public:
return TypeHandler<T0>::size();
}
static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal,
static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal,
AbstractExtractor::Ptr pExt)
{
poco_assert_dbg (!pExt.isNull());
@ -2013,7 +2013,7 @@ public:
static void bind(std::size_t pos, const Poco::AutoPtr<T>& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
{
// *obj will trigger a nullpointer exception if empty: this is on purpose
TypeHandler<T>::bind(pos, *obj, pBinder, dir);
TypeHandler<T>::bind(pos, *obj, pBinder, dir);
}
static std::size_t size()
@ -2024,7 +2024,7 @@ public:
static void extract(std::size_t pos, Poco::AutoPtr<T>& obj, const Poco::AutoPtr<T>& defVal, AbstractExtractor::Ptr pExt)
{
poco_assert_dbg (!pExt.isNull());
obj = Poco::AutoPtr<T>(new T());
if (defVal)
TypeHandler<T>::extract(pos, *obj, *defVal, pExt);
@ -2053,7 +2053,7 @@ public:
static void bind(std::size_t pos, const Poco::SharedPtr<T>& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
{
// *obj will trigger a nullpointer exception if empty
TypeHandler<T>::bind(pos, *obj, pBinder, dir);
TypeHandler<T>::bind(pos, *obj, pBinder, dir);
}
static std::size_t size()
@ -2064,7 +2064,7 @@ public:
static void extract(std::size_t pos, Poco::SharedPtr<T>& obj, const Poco::SharedPtr<T>& defVal, AbstractExtractor::Ptr pExt)
{
poco_assert_dbg (!pExt.isNull());
obj = Poco::SharedPtr<T>(new T());
if (defVal)
TypeHandler<T>::extract(pos, *obj, *defVal, pExt);