File indexing completed on 2025-01-19 03:53:33
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2007-04-15 0007 * Description : Database engine abstract database backend 0008 * 0009 * SPDX-FileCopyrightText: 2007-2010 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0010 * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #ifndef DIGIKAM_DB_ENGINE_BACKEND_PRIVATE_H 0017 #define DIGIKAM_DB_ENGINE_BACKEND_PRIVATE_H 0018 0019 #include "dbenginebackend.h" 0020 0021 // Qt includes 0022 0023 #include <QHash> 0024 #include <QSqlDatabase> 0025 #include <QThread> 0026 #include <QThreadStorage> 0027 #include <QWaitCondition> 0028 0029 // Local includes 0030 0031 #include "digikam_export.h" 0032 #include "dbengineparameters.h" 0033 #include "dbengineerrorhandler.h" 0034 0035 namespace Digikam 0036 { 0037 0038 class Q_DECL_HIDDEN DbEngineThreadData 0039 { 0040 public: 0041 0042 explicit DbEngineThreadData(); 0043 ~DbEngineThreadData(); 0044 0045 void closeDatabase(); 0046 0047 public: 0048 0049 int valid; 0050 int transactionCount; 0051 QString connectionName; 0052 QSqlError lastError; 0053 }; 0054 0055 // ------------------------------------------------------------------------ 0056 0057 class DIGIKAM_EXPORT BdEngineBackendPrivate : public DbEngineErrorAnswer 0058 { 0059 public: 0060 0061 explicit BdEngineBackendPrivate(BdEngineBackend* const backend); 0062 ~BdEngineBackendPrivate() override; 0063 0064 void init(const QString& connectionName, DbEngineLocking* const locking); 0065 0066 QSqlDatabase databaseForThread(); 0067 QSqlError databaseErrorForThread(); 0068 void setDatabaseErrorForThread(const QSqlError& lastError); 0069 0070 QString connectionName(); 0071 QSqlDatabase createDatabaseConnection(); 0072 0073 void closeDatabaseForThread(); 0074 bool incrementTransactionCount(); 0075 bool decrementTransactionCount(); 0076 0077 bool isInMainThread() const; 0078 bool isInUIThread() const; 0079 0080 bool reconnectOnError() const; 0081 bool isSQLiteLockError(const DbEngineSqlQuery& query) const; 0082 bool isSQLiteLockTransactionError(const QSqlError& lastError) const; 0083 bool isConnectionError(const DbEngineSqlQuery& query) const; 0084 bool needToConsultUserForError(const DbEngineSqlQuery& query) const; 0085 bool needToHandleWithErrorHandler(const DbEngineSqlQuery& query) const; 0086 void debugOutputFailedQuery(const QSqlQuery& query) const; 0087 void debugOutputFailedTransaction(const QSqlError& error) const; 0088 0089 bool checkRetrySQLiteLockError(int retries); 0090 bool checkOperationStatus(); 0091 bool handleWithErrorHandler(const DbEngineSqlQuery* const query); 0092 void setQueryOperationFlag(BdEngineBackend::QueryOperationStatus status); 0093 void queryOperationWakeAll(BdEngineBackend::QueryOperationStatus status); 0094 0095 /// called by DbEngineErrorHandler, implementing DbEngineErrorAnswer 0096 void connectionErrorContinueQueries() override; 0097 void connectionErrorAbortQueries() override; 0098 0099 virtual void transactionFinished(); 0100 0101 public: 0102 0103 QThreadStorage<DbEngineThreadData*> threadDataStorage; 0104 0105 /** 0106 * This compares to DbEngineThreadData's valid. 0107 * If currentValidity is increased and > valid, the db is marked as invalid 0108 */ 0109 int currentValidity; 0110 0111 bool isInTransaction; 0112 0113 QString backendName; 0114 0115 DbEngineParameters parameters; 0116 0117 BdEngineBackend::Status status; 0118 0119 DbEngineLocking* lock; 0120 0121 BdEngineBackend::QueryOperationStatus operationStatus; 0122 0123 QMutex errorLockMutex; 0124 QWaitCondition errorLockCondVar; 0125 BdEngineBackend::QueryOperationStatus errorLockOperationStatus; 0126 0127 QMutex busyWaitMutex; 0128 QWaitCondition busyWaitCondVar; 0129 0130 DbEngineErrorHandler* errorHandler; 0131 0132 public: 0133 0134 class Q_DECL_HIDDEN AbstractUnlocker 0135 { 0136 public: 0137 0138 explicit AbstractUnlocker(BdEngineBackendPrivate* const d); 0139 ~AbstractUnlocker(); 0140 0141 void finishAcquire(); 0142 0143 protected: 0144 0145 int count; 0146 BdEngineBackendPrivate* const d; 0147 }; 0148 0149 friend class AbstractUnlocker; 0150 0151 // ------------------------------------------------------------------ 0152 0153 class Q_DECL_HIDDEN AbstractWaitingUnlocker : public AbstractUnlocker 0154 { 0155 public: 0156 0157 explicit AbstractWaitingUnlocker(BdEngineBackendPrivate* const d, 0158 QMutex* const mutex, 0159 QWaitCondition* const condVar); 0160 ~AbstractWaitingUnlocker(); 0161 0162 bool wait(unsigned long time = ULONG_MAX); 0163 0164 protected: 0165 0166 QMutex* const mutex; 0167 QWaitCondition* const condVar; 0168 }; 0169 0170 // ------------------------------------------------------------------ 0171 0172 class Q_DECL_HIDDEN ErrorLocker : public AbstractWaitingUnlocker 0173 { 0174 public: 0175 0176 explicit ErrorLocker(BdEngineBackendPrivate* const d); 0177 void wait(); 0178 }; 0179 0180 // ------------------------------------------------------------------ 0181 0182 class Q_DECL_HIDDEN BusyWaiter : public AbstractWaitingUnlocker 0183 { 0184 public: 0185 0186 explicit BusyWaiter(BdEngineBackendPrivate* const d); 0187 }; 0188 0189 public: 0190 0191 BdEngineBackend* const q; 0192 }; 0193 0194 } // namespace Digikam 0195 0196 #endif // DIGIKAM_DB_ENGINE_BACKEND_PRIVATE_H