Poco::Data

template < class T >

class TypeHandler

Library: Data
Package: DataCore
Header: Poco/Data/TypeHandler.h

Description

Converts Rows to a Type and the other way around. Provide template specializations to support your own complex types.

Take as example the following (simplified) class:

class Person
{
private:
    std::string _lastName;
    std::string _firstName;
    int         _age;
    [....] // public set/get methods, a default constructor, optional < operator (for set, multiset) or function operator (for map, multimap)
};

The TypeHandler must provide a costum bind, size, prepare and extract method:

template <>
class TypeHandler<struct Person>
{
public:
    static std::size_t size()
    {
        return 3; // lastName + firstname + age occupy three columns
    }

    static void bind(std::size_t pos, const Person& obj, AbstractBinder* pBinder)
    {
        // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))
        // Note that we advance pos by the number of columns the datatype uses! For string/int this is one.
        poco_assert_dbg (pBinder != 0);
        TypeHandler<std::string>::bind(pos++, obj.getLastName(), pBinder);
        TypeHandler<std::string>::bind(pos++, obj.getFirstName(), pBinder);
        TypeHandler<int>::bind(pos++, obj.getAge(), pBinder);
    }

    static void prepare(std::size_t pos, const Person& obj, AbstractPreparation* pPrepare)
    {
        // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))
        poco_assert_dbg (pPrepare != 0);
        TypeHandler<std::string>::prepare(pos++, obj.getLastName(), pPrepare);
        TypeHandler<std::string>::prepare(pos++, obj.getFirstName(), pPrepare);
        TypeHandler<int>::prepare(pos++, obj.getAge(), pPrepare);
    }

    static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor* pExt)
    {
        // defVal is the default person we should use if we encunter NULL entries, so we take the individual fields
        // as defaults. You can do more complex checking, ie return defVal if only one single entry of the fields is null etc...
        poco_assert_dbg (pExt != 0);
        std::string lastName;
        std::string firstName;
        int age = 0;
        // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))
        TypeHandler<std::string>::extract(pos++, lastName, defVal.getLastName(), pExt);
        TypeHandler<std::string>::extract(pos++, firstName, defVal.getFirstName(), pExt);
        TypeHandler<int>::extract(pos++, age, defVal.getAge(), pExt);
        obj.setLastName(lastName);
        obj.setFirstName(firstName);
        obj.setAge(age);
    }
};

Note that the TypeHandler template specialization must always be declared in the namespace Poco::Data. Apart from that no further work is needed. One can now use Person with into and use clauses.

Member Summary

Member Functions: bind, extract, prepare, size

Constructors

Destructor

~TypeHandler protected

~TypeHandler();

Member Functions

bind static inline

static void bind(
    std::size_t pos,
    const T & obj,
    AbstractBinder * pBinder
);

extract static inline

static void extract(
    std::size_t pos,
    T & obj,
    const T & defVal,
    AbstractExtractor * pExt
);

prepare static inline

static void prepare(
    std::size_t pos,
    const T & obj,
    AbstractPreparation * pPrepare
);

size static inline

static std::size_t size();