[Interest] QSqlDatabasePrivate::database: requested database does not belong to the calling thread.

Burak Arslan burak.arslan at arskom.com.tr
Mon Aug 20 16:24:05 CEST 2018


Hey Andy,

Thanks for your reply.


On 08/20/18 10:21, Andy Shaw wrote:
> Hi,
>
> The QtSql classes themselves are not set to be reentrant or thread-safe (...) it may have worked by chance before but this was never guaranteed.

We the people can read the source code just as well as anyone and can
already see that. However, it should be our decision to use the library
the way we want.

I fully understand why making QSqlDatabase thread-safe may not be
feasible and just to be clear, I'm not asking you or anyone else to make
it so. However, returning invalid handle to a supposedly non-thread-safe
operation is just arrogance. A big fat warning (in the docs) saying that
QSqlDatabase and friends are not thread-safe should be enough. From then
on, it's my problem if I choose to cross that boundary. We don't want
nor need hand-holding from Qt developers.

>
> Granted the ":memory:" case is a unique one in this regard because opening another QSqlDatabase on ":memory:" will give you a new one, however it seems you can do:
>
>   ":memory:?cache=shared"
>
> To get it to access the same one. Does that help then?

No, because that means one in-memory database per process. I'll tell you
what has the potential to help, though:

SQLite has this relatively new feature called "URI Filenames" [1].  It
lets you have named in-memory databases[2] like so:

    auto db = QSqlDatabase::addDatabase("QSQLITE",
        "file:foo?mode=memory&cache=shared");


This has two drawbacks:

1. What has been a simple incref is now a hash lookup + new connection
instantiation (and most probably some more stuff).

2. This requires the SQLITE_USE_URI=1 compile-time flag which is
disabled by default and also seems disabled in the embedded SQLite in
QtSql[3][5].

Not to mention a major refactoring effort from our side -- I think we
will need to visit every QSqlDatabase occurrence in our codebase to
restore pre-Qt-5.11 functionality.

Given all this, it is obvious to me that the right thing to do is to
revert 9b361f0e90fb1c154a16e65ec087ad36d5cca9b4[4]. I hope it is the
case for you as well.

Best regards,
Burak

[1]: https://sqlite.org/uri.html
[2]: https://sqlite.org/inmemorydb.html
[3]: https://code.qt.io/cgit/qt/qtbase.git/tree/src/3rdparty/sqlite.pri

[4]:
https://code.qt.io/cgit/qt/qtbase.git/commit/src/sql/kernel/qsqldatabase.cpp?id=9b361f0e90fb1c154a16e65ec087ad36d5cca9b4

[5]: For reference, the following code:

    int main() {
        QCoreApplication a(argc, argv);
        auto db = QSqlDatabase::addDatabase("QSQLITE", ":memory:");
        db.open();
        auto q = db.exec("pragma compile_options");
        while (q.next()) {
            qInfo() << q.value(0).toString();
        }
        return 0;
    }

prints:

    "COMPILER=msvc-1911"
    "ENABLE_COLUMN_METADATA"
    "ENABLE_FTS3"
    "ENABLE_FTS3_PARENTHESIS"
    "ENABLE_FTS5"
    "ENABLE_RTREE"
    "OMIT_COMPLETE"
    "OMIT_LOAD_EXTENSION"
    "THREADSAFE=1"

with the official Qt 5.11.1 MSVC 2017 64 bit.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20180820/53f9bca7/attachment.html>


More information about the Interest mailing list