[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