lexical cast error - retrieval of custom date (not QDate)
Posted:
Tue Oct 02, 2012 3:27 pm
by marat
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
Re: lexical cast error - retrieval of custom date (not QDate
Posted:
Wed Oct 03, 2012 7:47 am
by qxorm
Hi,
I think you have followed this Q&R of the FAQ :
http://www.qxorm.com/qxorm_en/faq.html#faq_180Please 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...
Re: lexical cast error - retrieval of custom date (not QDate
Posted:
Wed Oct 03, 2012 9:03 pm
by marat
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(..).
Re: lexical cast error - retrieval of custom date (not QDate
Posted:
Wed Oct 03, 2012 9:47 pm
by marat
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
Re: lexical cast error - retrieval of custom date (not QDate
Posted:
Thu Oct 04, 2012 9:53 am
by qxorm
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...
Re: lexical cast error - retrieval of custom date (not QDate
Posted:
Thu Oct 04, 2012 1:43 pm
by marat
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.
Re: lexical cast error - retrieval of custom date (not QDate
Posted:
Thu Oct 04, 2012 3:13 pm
by qxorm
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.