[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