Binding Non-primitive Types
>Question:
>1) We like to store non-primitive types in the database like
>complex-numbers. We have been sniffing around in the sourcecode of DTL
>(bind_basics, BoundsIO, etc) how to extend DTL, but there seem to be
>many places where we have to add some code. Do you have some kind of
>'manual' or guideline which routines we should extend/add to DTL in
>order to support 'foreign' types?
Answer:
There are two ways to do this. The first method is to simply create
a binding operator for your non-primitive type. The second method
is to add appropriate constructors and cast operators to
the class that uses the non-primitive type.
Method 1
Suppose we have a non primitive type called "cplx" used to store complex numbers.
Suppose also that we have a simple table called multiplex that holds some complex numbers:
struct cplx
{
int re, im;
};
ostream& operator << (ostream &o, const cplx &c)
{
o << "(" << c.re << ", " << c.im << ")";
return o;
}
BoundIO operator >> (BoundIO &b, cplx &c) {
BoundIOs *pCols = b.GetBoundIOsPtr();
tstring root_name = b.GetName();
pCols->EraseColumn(root_name);
(*pCols)[root_name + "_re"] >> c.re;
return (*pCols)[root_name + "_im"] >> c.im;
}
struct multiplex
{
cplx AC1, AC2;
};
ostream& operator << (ostream &o, const multiplex &mp)
{
o << mp.AC1 << ", " << mp.AC2;
return o;
}
BEGIN_DTL_NAMESPACE
template<> class DefaultBCA<multiplex>
{
public:
void operator()(BoundIOs &cols, multiplex &row)
{
cols["AC1"] >> row.AC1;
cols["AC2"] >> row.AC2;
}
};
END_DTL_NAMESPACE
void test_non_primitive() {
DBView<multiplex> view("multiplex");
copy(view.begin(), view.end(), ostream_iterator<multiplex>(cout, "\n"));
}
Method 2
DTL_TABLE2(complex_value,
int, real,
int, imaginary
);
class cplx_value {
complex c;
public:
cplx_value(const complex_value_row &r) : c(r.real, r.imaginary) {}
operator complex_value_row() {complex_value_row r; r.real = c.re(); r.imaginary = c.im(); return r;}
}
void read_function() {
vector<cplx_value> values;
copy(complex_value_view.begin(), complex_value_view.end(), back_inserter(values));
}