[odb-users] Object creator with boost::posix_time::ptime member : exception from boost

rkadeFR contact at rkade.fr
Fri Jun 7 07:10:46 EDT 2013


On 06/06/2013 19:20, rkadeFR wrote:
>
> 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 :)
>
>
Ok ! Done for what I wanted :)

Thank you so much :)



More information about the odb-users mailing list