diff --git a/src/libs/sqlite/sqlitedatabase.cpp b/src/libs/sqlite/sqlitedatabase.cpp index f5c554548fa..994dfd3c036 100644 --- a/src/libs/sqlite/sqlitedatabase.cpp +++ b/src/libs/sqlite/sqlitedatabase.cpp @@ -61,7 +61,7 @@ Database::Database() } Database::Database(Utils::PathString &&databaseFilePath, JournalMode journalMode) - : Database(std::move(databaseFilePath), 1000ms, journalMode) + : Database{std::move(databaseFilePath), 0ms, journalMode} {} Database::Database(Utils::PathString &&databaseFilePath, @@ -89,7 +89,10 @@ void Database::open() { m_databaseBackend.open(m_databaseFilePath, m_openMode); m_databaseBackend.setJournalMode(m_journalMode); - m_databaseBackend.setBusyTimeout(m_busyTimeout); + if (m_busyTimeout > 0ms) + m_databaseBackend.setBusyTimeout(m_busyTimeout); + else + m_databaseBackend.registerBusyHandler(); registerTransactionStatements(); initializeTables(); m_isOpen = true; diff --git a/src/libs/sqlite/sqlitedatabase.h b/src/libs/sqlite/sqlitedatabase.h index c62ab92e251..b765f5bd648 100644 --- a/src/libs/sqlite/sqlitedatabase.h +++ b/src/libs/sqlite/sqlitedatabase.h @@ -55,13 +55,13 @@ public: using MutexType = std::mutex; using ReadStatement = Sqlite::ReadStatement; using WriteStatement = Sqlite::WriteStatement; + using BusyHandler = DatabaseBackend::BusyHandler; Database(); + Database(Utils::PathString &&databaseFilePath, JournalMode journalMode = JournalMode::Wal); Database(Utils::PathString &&databaseFilePath, - JournalMode journalMode); - Database(Utils::PathString &&databaseFilePath, - std::chrono::milliseconds busyTimeout = 1000ms, - JournalMode journalMode=JournalMode::Wal); + std::chrono::milliseconds busyTimeout, + JournalMode journalMode = JournalMode::Wal); ~Database(); Database(const Database &) = delete; @@ -132,6 +132,11 @@ public: void setAttachedTables(const Utils::SmallStringVector &tables) override; void applyAndUpdateSessions() override; + void setBusyHandler(BusyHandler busyHandler) + { + m_databaseBackend.setBusyHandler(std::move(busyHandler)); + } + SessionChangeSets changeSets() const; private: diff --git a/src/libs/sqlite/sqlitedatabasebackend.cpp b/src/libs/sqlite/sqlitedatabasebackend.cpp index 20af7589dbd..46097406e8c 100644 --- a/src/libs/sqlite/sqlitedatabasebackend.cpp +++ b/src/libs/sqlite/sqlitedatabasebackend.cpp @@ -37,15 +37,24 @@ #include "sqlite3.h" +#include +#include + extern "C" { int sqlite3_carray_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi); } namespace Sqlite { +using namespace std::literals; + DatabaseBackend::DatabaseBackend(Database &database) : m_database(database) , m_databaseHandle(nullptr) + , m_busyHandler([](int) { + std::this_thread::sleep_for(10ms); + return true; + }) { } @@ -197,28 +206,24 @@ void DatabaseBackend::closeWithoutException() } } +namespace { + +int busyHandlerCallback(void *userData, int counter) +{ + auto &&busyHandler = *static_cast(userData); + + return busyHandler(counter); +} + +} // namespace + void DatabaseBackend::registerBusyHandler() { - int resultCode = sqlite3_busy_handler(sqliteDatabaseHandle(), &busyHandlerCallback, nullptr); + int resultCode = sqlite3_busy_handler(sqliteDatabaseHandle(), &busyHandlerCallback, &m_busyHandler); checkIfBusyTimeoutWasSet(resultCode); } -void DatabaseBackend::registerRankingFunction() -{ -} - -int DatabaseBackend::busyHandlerCallback(void *, int counter) -{ - Q_UNUSED(counter) -#ifdef QT_DEBUG - //qWarning() << "Busy handler invoked" << counter << "times!"; -#endif - QThread::msleep(10); - - return true; -} - void DatabaseBackend::checkForOpenDatabaseWhichCanBeClosed() { if (m_databaseHandle == nullptr) @@ -416,6 +421,12 @@ void DatabaseBackend::resetUpdateHook() sqlite3_update_hook(m_databaseHandle, nullptr, nullptr); } +void DatabaseBackend::setBusyHandler(DatabaseBackend::BusyHandler &&busyHandler) +{ + m_busyHandler = std::move(busyHandler); + registerBusyHandler(); +} + void DatabaseBackend::throwExceptionStatic(const char *whatHasHappens) { throw Exception(whatHasHappens); diff --git a/src/libs/sqlite/sqlitedatabasebackend.h b/src/libs/sqlite/sqlitedatabasebackend.h index 624d16eee53..c26108f6e8a 100644 --- a/src/libs/sqlite/sqlitedatabasebackend.h +++ b/src/libs/sqlite/sqlitedatabasebackend.h @@ -41,6 +41,8 @@ class Database; class SQLITE_EXPORT DatabaseBackend { public: + using BusyHandler = std::function; + DatabaseBackend(Database &database); ~DatabaseBackend(); @@ -90,15 +92,16 @@ public: void (*callback)(void *object, int, char const *database, char const *, long long rowId)); void resetUpdateHook(); + void setBusyHandler(BusyHandler &&busyHandler); + + void registerBusyHandler(); + protected: bool databaseIsOpen() const; void setPragmaValue(Utils::SmallStringView pragma, Utils::SmallStringView value); Utils::SmallString pragmaValue(Utils::SmallStringView pragma); - void registerBusyHandler(); - void registerRankingFunction(); - static int busyHandlerCallback(void*, int counter); void checkForOpenDatabaseWhichCanBeClosed(); void checkDatabaseClosing(int resultCode); @@ -126,6 +129,7 @@ protected: private: Database &m_database; sqlite3 *m_databaseHandle; + BusyHandler m_busyHandler; }; } // namespace Sqlite