[odb-users] Object creator with boost::posix_time::ptime member
: exception from boost
rkadeFR
contact at rkade.fr
Thu Jun 6 13:20:05 EDT 2013
On 06/06/2013 19:12, Boris Kolpackov wrote:
> Hi,
>
> rkadeFR <contact at rkade.fr> writes:
>
>> 1- I can't change the database
>> 2- It's used as a negative infinite value :s
> Ok, so mapping it to neg_infin would be more appropriate.
>
>
>> If I understand, ODB construct an empty object with the private
>> cTor, and then fill the member with some copy?
> That's about right. The exception is thrown when ODB tries to
> initialize an instance of ptime from the loaded value, before
> assigning it to the data member in the object.
>
>
>> Can I change the behavior of this copy to handle the exception?
> Yes, ODB allows you to provide completely custom code that converts
> between the database value (in your case, that would be MYSQL_TIME
> struct) and C++ value (that would be ptime). There you can do pretty
> much any conversions you want. Also, if you are going this route,
> then you can also map DATETIME to something other than Boost ptime
> (e.g., your own date-time representation or struct tm). This guide
> has detailed information on how to do all this:
>
> http://www.codesynthesis.com/~boris/blog/2012/10/16/custom-cxx-to-database-type-mapping-in-odb/
>
> You can also use the odb/boost/date-time/mysql/posix-time-traits.hxx
> file from the libodb-boost as a reference.
>
> There is also another option which doesn't require a custom value_traits
> specialization. It is a bit "hackish" (or cool; depending on how you look
> at it ;-)) and is better suited for once-off customizations that are only
> needed in specific classes. The overall idea is to use virtual data members
> and use the image type (MYSQL_TIME in our case) as its type. We will also
> need to provide our own accessors/modifiers that convert between our
> data member (or ptime type) and the image type. Here is an outline:
>
> #include <mysql/mysql.h> // MYSQL_TIME
>
> class Person
> {
> ...
>
> void tsAddedConvert (const MYSQL_TIME& v)
> {
> using namespace boost::gregorian;
> using namespace boost::posix_time;
>
> if (v.year == 0 &&
> v.month == 0 &&
> v.day == 0 &&
> v.hour == 0 &&
> v.minute == 0 &&
> v.second == 0)
> tsAdded = ptime (neg_infin);
> else
> tsAdded = ptime (date (v.year, v.month, v.day),
> time_duration (v.hour, v.minute, v.second));
> }
>
> MYSQL_TIME tsAddedConvert () const
> {
> using namespace boost::gregorian;
> using namespace boost::posix_time;
>
> MYSQL_TIME v;
> v.neg = false;
>
> if (tsAdded.is_neg_infinity ())
> {
> v.year = 0;
> v.month = 0;
> v.day = 0;
>
> v.hour = 0;
> v.minute = 0;
> v.second = 0;
> }
> else
> {
> const date& d (tsAdded.date ());
> v.year = d.year ();
> v.month = d.month ();
> v.day = d.day ();
>
> const time_duration& t (tsAdded.time_of_day ());
> v.hour = t.hours ();
> v.minute = t.minutes ();
> v.second = t.seconds ();
> }
>
> v.second_part = 0;
> return v;
> }
>
> #pragma db column("dateTime") type("DATETIME")
> #pragma db member(dateTime) virtual(MYSQL_TIME) access(tsAddedConvert)
>
> #pragma db transient
> boost::posix_time::ptime tsAdded;
> };
>
> It is also possible to forward to the default ptime value_traits for
> the default cases (we would need to move the tsAddedConvert() functions
> to the .cxx file though).
>
> Boris
Ok great,
I'm gonna try to implement my own type :)
More information about the odb-users
mailing list