Page 1 of 1

Bug of insert bool type

PostPosted: Sat Jun 02, 2012 7:15 am
by magicu
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)

Re: Bug of insert bool type

PostPosted: Sat Jun 02, 2012 10:19 am
by magicu
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?

Re: Bug of insert bool type

PostPosted: Sat Jun 02, 2012 10:38 am
by magicu
I found a bug report about this, and no solved yet.

https://bugreports.qt-project.org/browse/QTBUG-15640

Re: Bug of insert bool type

PostPosted: Sat Jun 02, 2012 3:28 pm
by QxOrm admin
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 ;)

Re: Bug of insert bool type

PostPosted: Sun Jun 03, 2012 4:35 am
by magicu
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?

Re: Bug of insert bool type

PostPosted: Sun Jun 03, 2012 11:31 am
by QxOrm admin
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...