Sunday, February 10, 2008

SOCI (Cont'd)

This article explained how SOCI can be extended to support user-defined types. The author applied traits technique of generic programming in c++, and showed that by making use of template specialization via TypeConversion<T>, SOCI provided a noninvasive mechanism for extending SOCI.

Since std:tm is supported natively by SOCI, to work with boost::gregorian::date, a user only needs to provide the following template specialization and the compiler will make the right conversion for us.
#include <iostream>
#include <soci.h>
#include <boost/date_time/gregorian/gregorian.hpp>

using boost::gregorian::months_of_year;
using boost::gregorian::date;

namespace SOCI
{
template<> struct TypeConversion<date>
{
typedef std::tm base_type;
static date from(std::tm& t)
{
date d( t.tm_year + 1900,
static_cast<months_of_year>(t.tm_mon + 1),
t.tm_mday );
return d;
}

static std::tm to(date& d)
{
std::tm t;
t.tm_isdst = -1;
t.tm_year = d.year() - 1900;
t.tm_mon = d.month() - 1;
t.tm_mday = d.day();
t.tm_hour = 0;
t.tm_min = 0;
t.tm_sec = 0;
std::mktime(&t);
return t;
}
};
};
#endif

No comments: