# 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: const std::string& getLastName(); [...] // 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> { 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::Ptr pBinder, AbstractBinder::Direction dir) {

    // 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.isNull());
       TypeHandler<std::string>::bind(pos++, obj.getLastName(), pBinder, dir);
       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))
    poco_assert_dbg (!pPreparator.isNull());
       TypeHandler<std::string>::prepare(pos++, obj.getLastName(), pPreparator);
       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
    // 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.isNull());
    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.

## Inheritance

Direct Base Classes: AbstractTypeHandler

All Base Classes: AbstractTypeHandler

## Member Summary

Member Functions: bind, extract, prepare, size

Inherited Functions: operator =

## Constructors

## Member Functions

### bind

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

### extract

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

### prepare

static void prepare(
std::size_t pos,
const T & obj,
AbstractPreparator::Ptr pPreparator
);

### size

static std::size_t size();