[odb-users] Mapping a templated wrapper class

Boris Kolpackov boris at codesynthesis.com
Mon Sep 9 05:59:08 EDT 2013


Hi Cort,

R. Cortland Tompkins <cort.tompkins at ipconfigure.com> writes:

> I initially attempted to specialize value_traits for my templated wrapper,
> but the callbacks for the id_long_string type in MSSQL scared me off. :)

Yes, those can be a bit intimidating ;-).


>  At this point I was trying to serialize/deserialize on-the-fly without
> maintaining a text archive in my wrapper, and there did not appear to be an
> obvious or non-trivial way to put serialization/deserialization hooks into
> the get_image/set_image methods since the callbacks that effect the get/set
> are invoked after those functions return.

You can probably make it work since the callbacks allow you to detect
the first/last calls. You could then pass your wrapper as the callback
argument and trigger its serialization/deserialization.


> Failing that, I made my wrapper change-tracking and moved the
> serialization/deserialization logic into its accessors, then followed the
> example of boost::optional<> in libodb-boost to create a wrapper_traits
> specialization whose wrapped_type is always std::string (the text archive)
> regardless of the template parameter.

That's pretty neat.


> I was hoping I could map my generic wrapper class to the various "TEXT"
> DB types (independent of the template parameter as described above), but
> it seems this is not possible.

I don't think you actually need to provide any mapping at all since ODB,
after not finding any type specification for your wrapper type, will look
for one for wrapped_type. And since it is std::string, it will automatically
map it to TEXT.

Now you may still want to customize the TEXT type used for your wrapper
(e.g., to make it large/small enough to hold your data) but without
changing the default mapping for std::string. The easiest way to 
accomplish this would probably be to provide your own string type
and map it as you wish:

struct wrapper_data: std::string
{
  ...
};

#pragma db value(wrapper_data) mssql:type("VARCHAR(1024)")

In this case you would need to also provide the value_traits specialization
for wrapper_data (including those callbacks for MSSQL). You can, however,
simply delegate to the std::string implementation and reuse all the code
(including the callbacks). Or, you could implement your own and do the
on-the-fly serialization/deserialization (I think you can still delegate
to the std::string callbacks even in this case).

Boris



More information about the odb-users mailing list