lexical cast error - retrieval of custom date (not QDate)

Forum for posting problems using QxOrm library

lexical cast error - retrieval of custom date (not QDate)

Postby marat » Tue Oct 02, 2012 3:27 pm

Here is the error:
[QxOrm] 'QxStringCvtGeneric::fromString()' unknown error calling 'boost::lexical_cast<T>()'

I have a DB object containing a date field. It works when the field is a QDate. I am able to retrieve the object fine.

I replaced it with a userdefined Date deriving from boost::gregorian::date.
Code: Select all
class Date : public boost::gregorian::date {...}


The Date object has a non intrusive boost serialize() like so:
Code: Select all
namespace boost {
namespace serialization {
template <class Archive>
void serialize(Archive& ar, Date& date, unsigned int version)
{
  boost::gregorian::date* boostDate = static_cast<boost::gregorian::date*>(&date);
   ar & boost::serialization::make_nvp("date", *boostDate);
}
}}


I have the following defined as well:
Code: Select all
namespace qx {
namespace cvt {
namespace detail {
 
template <> struct QxStringCvt_ToVariant<Date>
{
  static inline QVariant toVariant(const Date &t, const QString  &format, int index)
  { 
       return QDate(2012, 7, 19);   // test
  }
};

template <> struct QxStringCvt_FromVariant<Date>
{
  static inline qx_bool fromVariant(const QVariant &v, Date &t, const QString &format, int index)
    {
   t = Date(2012, 7, 19);  // test
        return qx_bool(true);
    }
};
}}}


It doesn't look like the fromVariant() is invoked. Why is the QxStringCvtGeneric::fromString() invoked?
Why the lexical cast error? What am I missing?

Thanks
marat
 
Posts: 15
Joined: Tue Jul 17, 2012 8:23 pm

Re: lexical cast error - retrieval of custom date (not QDate

Postby qxorm » Wed Oct 03, 2012 7:47 am

Hi,

I think you have followed this Q&R of the FAQ : http://www.qxorm.com/qxorm_en/faq.html#faq_180

Please could you provide :
- the source code of your Date class (*.h and *.cpp files) ;
- the source code of all template written for your Date class (non intrusive boost serialization, QxStringCvt_ToVariant, etc...) ;
- the source code called to obtain your error : [QxOrm] 'QxStringCvtGeneric::fromString()' unknown error calling 'boost::lexical_cast<T>()'

Then, I'll be able to test your Date class to see what happens...
qxorm
Site Admin
 
Posts: 481
Joined: Mon Apr 12, 2010 7:45 am

Re: lexical cast error - retrieval of custom date (not QDate

Postby marat » Wed Oct 03, 2012 9:03 pm

Date.hpp:
Code: Select all
#pragma once
#include <boost/shared_ptr.hpp>
#include <boost/date_time/date.hpp>
#include "boost/date_time/gregorian/gregorian.hpp"
#include "boost/date_time/gregorian/greg_serialize.hpp"
#include "boost/date_time/gregorian/formatters.hpp"
#include <string>
namespace q
{
class  Date : public boost::gregorian::date
{
public:

  Date() {}

  Date(const std::string& str) { }

  // Ctor
  Date(year_type y, month_type m, day_type d);

  // Copy Ctor
  Date(const ymd_type& ymd);

  // Assignment Op
  Date& operator=(const Date& rhs);

  std::string toString();

  virtual ~Date() {}

private:
};
}


Date.cpp
Code: Select all
#include "Date.hpp"
#include <sstream>

using namespace boost::gregorian;
using namespace std;

namespace q
{

Date::Date(year_type y, month_type m, day_type d)
  :date(y, m, d)
{
}

Date::Date(const ymd_type& ymd)
  :date(ymd)
{
}



Date&
Date::operator=(const Date& rhs)
{
  if (this != &rhs)
  {
    date::operator=(rhs);
  }

  return *this;
}
}


Serializations.hpp
Code: Select all
#pragma once
#include "Date.hpp"
#include <boost/date_time/date.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/gregorian/greg_serialize.hpp>
#include <boost/date_time/posix_time/time_serialize.hpp>
#include "boost/serialization/nvp.hpp"
#include <boost/serialization/split_free.hpp>

#include <string>

////////////////////////////////////////////////////////////////////////////////
//
// Provides non-intrusive boost serializations to core objects
//
///////////////////////////////////////////////////////////////////////////////

namespace boost
{
namespace serialization
{

///////  Date non intrusive serialization ///////

template <class Archive>
void serialize(Archive& ar, qfr::QFRDate& date, unsigned int version)
{
  boost::gregorian::date* boostDate = static_cast<boost::gregorian::date*>(&date);

   ar & boost::serialization::make_nvp("date", *boostDate);
}
}
}


There is a table (MySQL with Date field) and a corresponding object that has a data member of type q::Date like so:
Code: Select all
class QX_DLL_EXPORT TestObj
{
public:
   std::string id_;
   q::Date dt_;   // when of type QDate it works
};


And that object is registered into QxOrm using register_class() - it works for objects containing a QDate instead of my q::Date .

The code just loads records from MySQL DB using the qx::dao::fetch_by_query(..).
marat
 
Posts: 15
Joined: Tue Jul 17, 2012 8:23 pm

Re: lexical cast error - retrieval of custom date (not QDate

Postby marat » Wed Oct 03, 2012 9:47 pm

Here is the stack trace of what leads to the lexical cast within QxStringCvtGeneric::fromString()

#0 qx::cvt::detail::QxStringCvtGeneric<q::Date>::fromString (s=..., t=...,
format=..., index=-1)
at /home/m/q/trunk/3rdParty/common/qxorm/1.2.4/include/QxCommon/QxStringCvt_Impl.h:103
#1 0x00000000006fe990 in qx::cvt::detail::QxStringCvt_FromString<q::Date>::fromString (s=..., t=..., format=..., index=-1)
at /home/m/q/trunk/3rdParty/common/qxorm/1.2.4/include/QxCommon/QxStringCvt_Impl.h:235
#2 0x00000000006fb179 in qx::cvt::detail::QxStringCvt_WithIndex<q::Date>::fromString (data=..., s=..., format=..., index=-1)
at /home/m/q/trunk/3rdParty/common/qxorm/1.2.4/include/QxCommon/../../inl/QxCommon/QxStringCvt_WithIndex.inl:34
#3 0x00000000006f2b15 in qx::cvt::from_string<q::Date> (s=..., t=...,
format=..., index=-1)
at /home/m/q/trunk/3rdParty/common/qxorm/1.2.4/include/QxCommon/QxStringCvt.h:65
#4 0x0000000000703f9f in cvtQVariant<false, 0>::fromVariant (v=..., t=...,
format=..., index=-1)
at /home/m/q/trunk/3rdParty/common/qxorm/1.2.4/include/QxCommon/QxStringCvt_Impl.h:120
#5 0x0000000000701b0a in qx::cvt::detail::QxStringCvtGeneric<q::Date>::fromVariant (v=..., t=..., format=..., index=-1)
at /home/m/q/trunk/3rdParty/common/qxorm/1.2.4/include/QxCommon/QxStringCvt_Impl.h:112
#6 0x00000000006fea10 in qx::cvt::detail::QxStringCvt_FromVariant<q::Date>::fromVariant (v=..., t=..., format=..., index=-1)
at /home/m/q/trunk/3rdParty/common/qxorm/1.2.4/include/QxCommon/QxStringCvt_Impl.h:245
#7 0x00000000006fb1f9 in qx::cvt::detail::QxStringCvt_WithIndex<q::Date>::fromVariant (data=..., v=..., format=..., index=-1)
at /home/m/q/trunk/3rdParty/common/qxorm/1.2.4/include/QxCommon/../../inl/QxCommon/QxStringCvt_WithIndex.inl:36
#8 0x00000000006f2b95 in qx::cvt::from_variant<q::Date> (v=..., t=...,
format=..., index=-1)
at /home/m/q/trunk/3rdParty/common/qxorm/1.2.4/include/QxCommon/QxStringCvt.h:67
#9 0x00000000006dc10e in qx::QxDataMember<q::Date, JpmCds>::fromVariant (
this=0xb66fd0, pOwner=0xb3d550, v=..., sFormat=..., iIndexName=-1)
at /home/m/q/trunk/3rdParty/common/qxorm/1.2.4/include/QxDataMember/QxDataMember.h:85
#10 0x000000000051f599 in qx::IxDataMember::fromVariant (this=0xb66fd0, pOwner=
0xb3d550, v=..., iIndexName=-1)
at /home/m/q/trunk/3rdParty/common/qxorm/1.2.4/include/QxDataMember/IxDataMember.h:188
#11 0x0000000000532400 in qx::dao::detail::QxSqlQueryHelper_FetchAll<JpmCds>::resolveOutput (t=..., query=..., builder=...)
at /home/m/q/trunk/3rdParty/common/qxorm/1.2.4/include/QxDao/../../inl/QxDao/QxSqlQueryHelper_FetchAll.inl:71
#12 0x000000000052f973 in qx::dao::detail::QxSqlQueryHelper_FetchAll<JpmCds>::resolveOutput (t=..., query=..., builder=..., columns=...)
---Type <return> to continue, or q <return> to quit---
at /home/m/q/trunk/3rdParty/common/qxorm/1.2.4/include/QxDao/../../inl/QxDao/QxSqlQueryHelper_FetchAll.inl:101
marat
 
Posts: 15
Joined: Tue Jul 17, 2012 8:23 pm

Re: lexical cast error - retrieval of custom date (not QDate

Postby marat » Wed Oct 03, 2012 9:49 pm

Code: Select all
namespace cvt {
namespace detail {

template <typename T>
struct QxStringCvtGeneric
{
   static inline qx_bool fromString(const QString & s, T & t, const QString & format, int index)
   {
      Q_UNUSED(format); Q_UNUSED(index);
    [b]  try { t = boost::lexical_cast<T>(s.toStdString()); }[/b]
      catch (...) {[b] qDebug("[QxOrm] %s", "'QxStringCvtGeneric::fromString()' unknown error calling 'boost::lexical_cast<T>()'"); [/b]return qx_bool(false); }
      return qx_bool(true);
   }
marat
 
Posts: 15
Joined: Tue Jul 17, 2012 8:23 pm

Re: lexical cast error - retrieval of custom date (not QDate

Postby qxorm » Thu Oct 04, 2012 9:53 am

I have tested your q::Date class and it works fine for me (using q::Date as a property of a persistent class) !

But I had to modify some things :

1- It's better to add the macro QX_REGISTER_TRAIT_GET_SQL_TYPE(q::Date, "MY_SQL_TYPE") to associate your C++ class to a SQL type, it is explained in the FAQ here : http://www.qxorm.com/qxorm_en/faq.html#faq_240 ;

2- What is "qfr::QFRDate" in your serialization function ? ==> I fixed it replacing by q::Date ;

3- Be careful with your namespace !!! Your Date class is inside the namespace q ===> don't forget it, it's very important when you specialize a template.

So here is your source code modified to work fine on my computer (toVariant() and fromVariant() for q::Date type are called correctly to transfer data to database) :

Date.hpp file :
Code: Select all
#include <boost/shared_ptr.hpp>
#include <boost/date_time/date.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/gregorian/greg_serialize.hpp>
#include <boost/date_time/gregorian/formatters.hpp>
#include <string>

namespace q
{

class Date : public boost::gregorian::date
{

public:

  Date() {}
  Date(const std::string& str) { Q_UNUSED(str); }
  Date(year_type y, month_type m, day_type d);
  Date(const ymd_type& ymd);
  virtual ~Date() {}

  Date& operator=(const Date& rhs);

  std::string toString();

};

} // namespace q

QX_REGISTER_TRAIT_GET_SQL_TYPE(q::Date, "VARCHAR")

#include "Serializations.hpp" // Important here !!! To be sure to not forget it in the *.cpp files !!!


Date.cpp file :
Code: Select all
#include <sstream>
#include "Date.hpp"

using namespace boost::gregorian;
using namespace std;

namespace q
{

Date::Date(year_type y, month_type m, day_type d) : date(y, m, d) { }

Date::Date(const ymd_type& ymd) : date(ymd) { }

Date& Date::operator=(const Date& rhs) { if (this != &rhs) { date::operator=(rhs); } return *this; }

} // namespace q


Serializations.hpp file :
Code: Select all
#include <boost/date_time/date.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/gregorian/greg_serialize.hpp>
#include <boost/date_time/posix_time/time_serialize.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/split_free.hpp>

#include <string>
#include "Date.hpp"

namespace boost {
namespace serialization {

template <class Archive>
void serialize(Archive& ar, q::Date & date, unsigned int version)
{
   Q_UNUSED(version); Q_UNUSED(date); Q_UNUSED(ar);
   //boost::gregorian::date* boostDate = static_cast<boost::gregorian::date*>(&date);
   //ar & boost::serialization::make_nvp("date", *boostDate);
}

} // namespace serialization
} // namespace boost

namespace qx {
namespace cvt {
namespace detail {

template <>
struct QxStringCvt_ToVariant<q::Date>
{
   static inline QVariant toVariant(const q::Date &t, const QString  &format, int index)
   {
      Q_UNUSED(t); Q_UNUSED(format); Q_UNUSED(index);
      return QDate(2012, 7, 19);
   }
};

template <>
struct QxStringCvt_FromVariant<q::Date>
{
   static inline qx_bool fromVariant(const QVariant &v, q::Date &t, const QString &format, int index)
   {
      Q_UNUSED(v); Q_UNUSED(format); Q_UNUSED(index);
      t = q::Date(2012, 7, 19);
      return qx_bool(true);
   }
};

}}} // namespace qx::cvt::detail


PS : Why do you want to create your own date class ?
It's strange because Qt and boost provide all functionalities to use dates and times...
qxorm
Site Admin
 
Posts: 481
Joined: Mon Apr 12, 2010 7:45 am

Re: lexical cast error - retrieval of custom date (not QDate

Postby marat » Thu Oct 04, 2012 1:43 pm

A couple questions. As you mentioned you added this -

QX_REGISTER_TRAIT_GET_SQL_TYPE(q::Date, "VARCHAR")

In my DB Table, the MySQL type is "Date" not "Varchar". Did you try with a date or varchar field?

Also do I need to register the date class using QX_REGISTER_* ?

We wanted to provide our own "Date" class (by extending boost) with additional functionality for financial calendars.
marat
 
Posts: 15
Joined: Tue Jul 17, 2012 8:23 pm

Re: lexical cast error - retrieval of custom date (not QDate

Postby qxorm » Thu Oct 04, 2012 3:13 pm

QX_REGISTER_TRAIT_GET_SQL_TYPE(q::Date, "VARCHAR")
In my DB Table, the MySQL type is "Date" not "Varchar". Did you try with a date or varchar field?

You can put here what you want, so if your database type is "Date", just write :
QX_REGISTER_TRAIT_GET_SQL_TYPE(q::Date, "Date")

Also do I need to register the date class using QX_REGISTER_* ?

No because it is not a persistent class : your q::Date class will just be used as a property of a persistent class.
qxorm
Site Admin
 
Posts: 481
Joined: Mon Apr 12, 2010 7:45 am


Return to QxOrm - Help

Who is online

Users browsing this forum: No registered users and 5 guests

cron