Bug of insert bool type

Forum for posting problems using QxOrm library

Bug of insert bool type

Postby magicu » Sat Jun 02, 2012 7:15 am

My AccountType class:

-------------------
.H

class COOKIEMAIL_DLL_EXPORT AccountType
{
public:
AccountType() : id(0), port(0), ssl(false) {};
virtual ~AccountType() {};

int id;
QString name;
QString host;
int port;
bool ssl;
QString script;

AccountList accountListX;
};

QX_REGISTER_PRIMARY_KEY(AccountType, int)
QX_REGISTER_HPP_COOKIEMAIL(AccountType, qx::trait::no_base_class_defined, 0)



-------------------
.CPP


#include "StdAfx.h"
#include "accounttype.h"

QX_REGISTER_CPP_COOKIEMAIL(AccountType)

namespace qx
{
template <> void register_class(QxClass<AccountType> & t)
{
//t.setName("[AccountType]");
t.id(&AccountType::id, "id");
t.data(&AccountType::name, "name");
t.data(&AccountType::host, "host");
t.data(&AccountType::port, "port");
t.data(&AccountType::ssl, "ssl");
t.data(&AccountType::script, "script");

t.relationOneToMany(&AccountType::accountListX, "AccountList", "type_id");
}
}

-------------------

AccountTypePtr accountTypePtr1(new AccountType());
accountTypePtr1->name = "Yahoo";
accountTypePtr1->host = "pop.mail.yahoo.cn";
accountTypePtr1->port = 995;
accountTypePtr1->ssl = true;
accountTypePtr1->script = "script";
daoError = qx::dao::insert(accountTypePtr1);

When I insert accountTypePtr into Sqlite DB, the ssl is always 0. if I changed it from bool to int type, the ssl is normal 1.

This problem existed both in 1.2.4 and 1.2.3.(MT and MD)
magicu
 
Posts: 54
Joined: Fri Jan 20, 2012 9:51 am

Re: Bug of insert bool type

Postby magicu » Sat Jun 02, 2012 10:19 am

I think it because of no bool case in "QSQLiteResult::exec()" which included in "QT\src\sql\drivers\mysql\qsql_mysql.cpp"

bool QSQLiteResult::exec()
{
const QVector<QVariant> values = boundValues();

d->skippedStatus = false;
d->skipRow = false;
d->rInf.clear();
clearValues();
setLastError(QSqlError());

int res = sqlite3_reset(d->stmt);
if (res != SQLITE_OK) {
setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
"Unable to reset statement"), QSqlError::StatementError, res));
d->finalize();
return false;
}
int paramCount = sqlite3_bind_parameter_count(d->stmt);
if (paramCount == values.count()) {
for (int i = 0; i < paramCount; ++i) {
res = SQLITE_OK;
const QVariant value = values.at(i);

if (value.isNull()) {
res = sqlite3_bind_null(d->stmt, i + 1);
} else {
switch (value.type()) {
case QVariant::ByteArray: {
const QByteArray *ba = static_cast<const QByteArray*>(value.constData());
res = sqlite3_bind_blob(d->stmt, i + 1, ba->constData(),
ba->size(), SQLITE_STATIC);
break; }
case QVariant::Int:
res = sqlite3_bind_int(d->stmt, i + 1, value.toInt());
break;
case QVariant::Double:
res = sqlite3_bind_double(d->stmt, i + 1, value.toDouble());
break;
case QVariant::UInt:
case QVariant::LongLong:
res = sqlite3_bind_int64(d->stmt, i + 1, value.toLongLong());
break;
case QVariant::String: {
// lifetime of string == lifetime of its qvariant
const QString *str = static_cast<const QString*>(value.constData());
res = sqlite3_bind_text16(d->stmt, i + 1, str->utf16(),
(str->size()) * sizeof(QChar), SQLITE_STATIC);
break; }
default: {
QString str = value.toString();
// SQLITE_TRANSIENT makes sure that sqlite buffers the data
res = sqlite3_bind_text16(d->stmt, i + 1, str.utf16(),
(str.size()) * sizeof(QChar), SQLITE_TRANSIENT);
break; }
}
}
if (res != SQLITE_OK) {
setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
"Unable to bind parameters"), QSqlError::StatementError, res));
d->finalize();
return false;
}
}
} else {
setLastError(QSqlError(QCoreApplication::translate("QSQLiteResult",
"Parameter count mismatch"), QString(), QSqlError::StatementError));
return false;
}
d->skippedStatus = d->fetchNext(d->firstRow, 0, true);
if (lastError().isValid()) {
setSelect(false);
setActive(false);
return false;
}
setSelect(!d->rInf.isEmpty());
setActive(true);
return true;
}

Could you release a patch for this problem?
magicu
 
Posts: 54
Joined: Fri Jan 20, 2012 9:51 am

Re: Bug of insert bool type

Postby magicu » Sat Jun 02, 2012 10:38 am

I found a bug report about this, and no solved yet.

https://bugreports.qt-project.org/browse/QTBUG-15640
magicu
 
Posts: 54
Joined: Fri Jan 20, 2012 9:51 am

Re: Bug of insert bool type

Postby QxOrm admin » Sat Jun 02, 2012 3:28 pm

Hi,

Sorry, it's not a bug of QxOrm library, but a bug of your driver.
bool type is a little bit like date-time types, not very cross-compatible between databases.
This is why I provide a set of classes to manage easily dates and times between databases without any problem, you could take a look here :
- Date neutral : http://www.qxorm.com/doxygen/html/class ... utral.html
- Date-Time neutral : http://www.qxorm.com/doxygen/html/class ... utral.html
- Time neutral : http://www.qxorm.com/doxygen/html/class ... utral.html
- And an example to show how to use it : ./test/qxDllSample/dll2/include/Foo.h (class of your QxOrm package) with accessors to work with Qt types, but the storage is managed by QxOrm library !

Code: Select all
class QX_DLL2_EXPORT Foo
{

   QX_REGISTER_FRIEND_CLASS(Foo)

protected:

   qx::QxDateNeutral m_oDateNeutral;
   qx::QxTimeNeutral m_oTimeNeutral;
   qx::QxDateTimeNeutral m_oDateTimeNeutral;

public:

   QDate getDate() const { return m_oDateNeutral.toDate(); }
   QTime getTime() const  { return m_oTimeNeutral.toTime(); }
   QDateTime getDateTime() const { return m_oDateTimeNeutral.toDateTime(); }

   void setDate(const QDate & d) { m_oDateNeutral.setDate(d); }
   void setTime(const QTime & t) { m_oTimeNeutral.setTime(t); }
   void setDateTime(const QDateTime & dt) { m_oDateTimeNeutral.setDateTime(dt); }

};


So for your problem with bool types, you could use the same mechanism using short type for the storage, and using bool type only for your accessors, like the example above.
Then, it will be transparent for the users of your classes ;)
QxOrm admin
 

Re: Bug of insert bool type

Postby magicu » Sun Jun 03, 2012 4:35 am

QxOrm admin wrote:Hi,

Sorry, it's not a bug of QxOrm library, but a bug of your driver.
bool type is a little bit like date-time types, not very cross-compatible between databases.
This is why I provide a set of classes to manage easily dates and times between databases without any problem, you could take a look here :
- Date neutral : http://www.qxorm.com/doxygen/html/class ... utral.html
- Date-Time neutral : http://www.qxorm.com/doxygen/html/class ... utral.html
- Time neutral : http://www.qxorm.com/doxygen/html/class ... utral.html
- And an example to show how to use it : ./test/qxDllSample/dll2/include/Foo.h (class of your QxOrm package) with accessors to work with Qt types, but the storage is managed by QxOrm library !

Code: Select all
class QX_DLL2_EXPORT Foo
{

   QX_REGISTER_FRIEND_CLASS(Foo)

protected:

   qx::QxDateNeutral m_oDateNeutral;
   qx::QxTimeNeutral m_oTimeNeutral;
   qx::QxDateTimeNeutral m_oDateTimeNeutral;

public:

   QDate getDate() const { return m_oDateNeutral.toDate(); }
   QTime getTime() const  { return m_oTimeNeutral.toTime(); }
   QDateTime getDateTime() const { return m_oDateTimeNeutral.toDateTime(); }

   void setDate(const QDate & d) { m_oDateNeutral.setDate(d); }
   void setTime(const QTime & t) { m_oTimeNeutral.setTime(t); }
   void setDateTime(const QDateTime & dt) { m_oDateTimeNeutral.setDateTime(dt); }

};


So for your problem with bool types, you could use the same mechanism using short type for the storage, and using bool type only for your accessors, like the example above.
Then, it will be transparent for the users of your classes ;)





I think this bug is very not easy to be found, could you make a transparent convert about it?
magicu
 
Posts: 54
Joined: Fri Jan 20, 2012 9:51 am

Re: Bug of insert bool type

Postby QxOrm admin » Sun Jun 03, 2012 11:31 am

The bug report you provide (https://bugreports.qt-project.org/browse/QTBUG-15640) doesn't say it is not working with bool type, this is just not optimized : instead of using integer to put a "0" or a "1", QSQLite driver converts bool type to a string value, so "true" or "false".

So it must work and to verify it, I have tested with qxBlog project, adding a bool property to the author class.
If I open the database generated by qxBlog project (with SQLite Manager), I can see the behaviour reported in the Qt bug report : I see "true" value or "false" value (instead of 0 and 1 to have best performance).
But it works well for me (even it is not optimized) : if I fetch my author, the bool property has the good value stored into database !!!

The default bool type for SQLite database defined by QxOrm library is SMALLINT, maybe you are not using the same type ?
For more details about C++ types and database types, goto here : http://www.qxorm.com/qxorm_en/faq.html#faq_240

I think this bug is very not easy to be found, could you make a transparent convert about it ?

Nope, because there is no bug for me, and Qt bug report is just an issue about QSQLite driver performance, not a bad behaviour !

You could make the same test with qxBlog project adding a bool property to the author class, it works well for me...
QxOrm admin
 


Return to QxOrm - Help

Who is online

Users browsing this forum: No registered users and 32 guests