Suppose we want a PostgreSQL database where all the uint16_t
s
are mapped by
reinterpret_cast_mapper<uint16_t, direct_mapper<int16_t>>
, all the uint32_t
s are
mapped by
reinterpret_cast_mapper<uint32_t, direct_mapper<int32_t>>
, and all the other polymorphically mapped types use quince_postgresql's default mappers. Then the steps are:
mapping_customization
object.
mapping_customization
object, using its customize()
method.
mapping_customization
object as an extra argument to the database constructor.
So this would do it:
mapping_customization custom; custom.customize<uint16_t, reinterpret_cast_mapper<uint16_t, direct_mapper<int16_t>>>(); custom.customize<uint32_t, reinterpret_cast_mapper<uint32_t, direct_mapper<int32_t>>>(); const quince_postgresql::database special_db( "localhost", "postgres", "postgres", "quincetest", "test", "", boost::none, custom );
In each call to mapping_customization::customize()
, we use template parameters to supply
two types:
T
, and
abstract_mapper<
T
>
) that will perform mappings for
T
wherever the mapping_customization
is deployed.
To deploy it to a database, we pass the mapping_customization
as an argument to the database constructor. (The constructor argument
lists are described in full here
and here.)
The code above includes function calls, so it must be inside the body
of some function; ergo special_db
is a local variable.
I don't know about you, but I usually want my database
object to be a global variable. So I need some other means to ensure
that steps 1-3 are carried out in order. There are several techniques,
but this is my personal favorite:
struct my_customization : mapping_customization { my_customization() { customize<uint16_t, reinterpret_cast_mapper<uint16_t, direct_mapper<int16_t>>>(); customize<uint32_t, reinterpret_cast_mapper<uint32_t, direct_mapper<int32_t>>>(); } }; const quince_postgresql::database special_db( "localhost", "postgres", "postgres", "quincetest", "test", "", boost::none, my_customization() );