[Qt-interest] Custom SQLite Driver
Neville Dastur
qt at dastur.me.uk
Fri Jan 1 21:22:18 CET 2010
Thanks for the suggestions. The invoke method thing works for the
driver, but I also then needed to modify the QSQLiteResult class which
is not a Q_OBJECT and so neither method works.
So the solution that seems to work so far is to set a flag using
Q_PROPERTY in the driver, then in QSQLiteResult test for the flag and
act accordingly.
class Q_EXPORT_SQLDRIVER_SQLITE QSQLiteDriver : public QSqlDriver
{
Q_OBJECT
Q_PROPERTY(bool ExecNoReturn READ getExecNoReturn WRITE setExecNoReturn)
....
private:
// Property Functions
bool ExecNoReturn;
bool getExecNoReturn() { return ExecNoReturn; };
void setExecNoReturn(bool flag) {ExecNoReturn=flag;};
private:
QSQLiteDriverPrivate* d;
};
bool QSQLiteResult::reset(const QString &query)
{
// Perform as a sqlite3_exec() instead if property flag set, but reset on each use
QVariant ret = this->driver()->property("ExecNoReturn");
if (ret.isValid() & ret.toBool()) {
QSqlDriver *d = const_cast<QSqlDriver *>(driver());
d->setProperty("ExecNoReturn", QVariant::fromValue(false));
return this->_execNoReturnSet(query);
}
else {
if (!prepare(query))
return false;
return exec();
}
}
then in the QSQLiteResult class we have:
bool QSQLiteResult::_execNoReturnSet(const QString &query) {
if (!driver() || !driver()->isOpen() || driver()->isOpenError())
return false;
char* localError=0;
int res = sqlite3_exec((sqlite3*) d->access, query.toLocal8Bit().constData(), 0, 0, &localError);
if (res != SQLITE_OK) {
setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
"Unable to execute statement using sqlite3_exec"), QSqlError::StatementError, res));
return false;
}
return true;
}
In the calling source we do:
QSqlQuery q;
QSqlDriver *d = const_cast<QSqlDriver *>(q.driver());
d->setProperty("ExecNoReturn", QVariant::fromValue(true));
q.exec(SQL_CREATE_DB);
Again, just posting this to find out if there is a better solution. Also
might help someone else.
The underlying problem here is that the current SQLite driver won't
handle SQL with multiple statements i.e. separated by ; so wanted a way
to use the sqlite3_exec function.
André Somers wrote:
> Would it be sensible to express the key as a property? In that case, you
> could use setProperty("key") on your driver, and loose the conversion. Check
> out Q_PROPERTY to see how. Perhaps slightly less hackish than using
> invokeMethod(), though I use that approach myself quite frequently.
>
> André
>
>
> -----Oorspronkelijk bericht-----
> Van: qt-interest-bounces at trolltech.com
> [mailto:qt-interest-bounces at trolltech.com] Namens Mohammed Sameer
> Verzonden: zondag 29 november 2009 14:25
> Aan: qt-interest at trolltech.com
> Onderwerp: Re: [Qt-interest] Custom SQLite Driver
>
> I'm not an expert here but...
>
> On Sun, Nov 29, 2009 at 12:03:16PM +0000, Neville Dastur wrote:
>
>> I am writing a custom SQLite driver to use the encryption routines from
>> wxSqlite. I have got the whole thing compiling and working by following
>> the docs on writing your own driver
>> (http://qt.nokia.com/doc/4.5/qsqldatabase.html#addDatabase-2) , but I am
>> having a problem including a new method.
>>
>> To set a password on the database the ReKey function needs to be called.
>> I created a public method:
>> void QSQLiteDriver::ReKey(const QString & key)
>>
>> When calling QSQLDatabase m_db->driver()->ReKey("test"); the function
>> ReKey can't be found.
>> and
>>
>> QSQLiteDriver *driver = m_db->driver();
>> driver->ReKey("test");
>>
>
> QSQLiteDriver *driver = dynamic_cast<QSQLiteDriver *>(m_db->driver()); //
> Some might prefer qobject_cast
>
>
>> What is this the best way of adding new functionality to a QSQLDriver.
>>
>
> Maybe a public slot and then use QMetaObject::invokeMethod() ?
>
> Sounds ugly but I can't find something else ;-)
>
> Cheers,
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20100101/156c764f/attachment.html
More information about the Qt-interest-old
mailing list