File indexing completed on 2025-01-05 03:53:58

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2007-03-18
0007  * Description : Core database access wrapper.
0008  *
0009  * SPDX-FileCopyrightText: 2007-2008 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_CORE_DB_ACCESS_H
0017 #define DIGIKAM_CORE_DB_ACCESS_H
0018 
0019 // Local includes
0020 
0021 #include "digikam_export.h"
0022 #include "dbengineparameters.h"
0023 
0024 namespace Digikam
0025 {
0026 
0027 class CoreDbBackend;
0028 class CoreDB;
0029 class CoreDbWatch;
0030 class InitializationObserver;
0031 class DbEngineErrorHandler;
0032 class CoreDbAccessStaticPriv;
0033 
0034 /**
0035  * The CoreDbAccess provides access to the database:
0036  * Create an instance of this class on the stack to retrieve a pointer to the database.
0037  * While you hold an instance of CoreDbAccess, the database access is locked for other threads,
0038  * but _not_ for other processes. This is due to the fact that while databases allow
0039  * concurrent access (of course), their client libs may not be thread-safe.
0040  *
0041  * When initializing your application, you need to call two methods:
0042  * - in a not-yet-multithreaded context, you need to call setParameters
0043  * - to make sure that the database is available and the schema
0044  *   is properly initialized, call checkReadyForUse()
0045  */
0046 class DIGIKAM_DATABASE_EXPORT CoreDbAccess
0047 {
0048 public:
0049 
0050     enum ApplicationStatus
0051     {
0052         MainApplication,
0053         DatabaseSlave
0054     };
0055 
0056 public:
0057 
0058     /**
0059      * Create a CoreDbAccess object for the default database.
0060      * Note that when initializing your app, setParameters need to be called
0061      * (in a not-yet-multithreaded context) for this to work.
0062      * If the database is not yet opened, it will be opened.
0063      * The schema will not be checked, use checkReadyForUse()
0064      * for a full opening process including schema update and error messages.
0065      */
0066     explicit CoreDbAccess();
0067     ~CoreDbAccess();
0068 
0069     /**
0070      * Retrieve a pointer to the album database
0071      */
0072     CoreDB* db()             const;
0073 
0074     /**
0075      * Retrieve a pointer to the database backend
0076      */
0077     CoreDbBackend* backend() const;
0078 
0079     /**
0080      * Returns the error message for the last error that occurred,
0081      * or a null QString of no error occurred.
0082      */
0083     QString lastError();
0084 
0085     /**
0086      * Set the "last error" message. This method is not for public use.
0087      */
0088     void setLastError(const QString& error);
0089 
0090 public:
0091 
0092     /**
0093      * Return the default parameters
0094      */
0095     static DbEngineParameters parameters();
0096 
0097     /**
0098      * Set the default parameters.
0099      * Call this function at least once in the starting phase of your application,
0100      * when no other threads will yet access the database, to initialize DatabaseAcccess.
0101      * After this initial call, it is thread-safe to call this function again.
0102      * In a subsequent call, if the parameters are identical, nothing is done.
0103      * If the parameters change, the current database will be closed.
0104      * When parameters have been set or changed, the new one will be opened on-demand,
0105      * i.e. when the first CoreDbAccess object is constructed.
0106      */
0107     static void setParameters(const DbEngineParameters& parameters);
0108     static void setParameters(const DbEngineParameters& parameters, ApplicationStatus status);
0109 
0110     /**
0111      * Method to one-time initialize a database when new parameters have been set:
0112      * Make sure that the database is open, that the schema has properly been initialized.
0113      * If the parameters were not changed, this method has no effect.
0114      * @returns if the database is ready for use
0115      */
0116     static bool checkReadyForUse(InitializationObserver* const observer = nullptr);
0117 
0118     /**
0119      * Clean up the database access.
0120      * When this function has been called, the access can be restored by calling setParameters.
0121      * Construction a database access object otherwise after calling this method will crash.
0122      */
0123     static void cleanUpDatabase();
0124 
0125     /**
0126      * Return the CoreDbWatch.
0127      */
0128     static CoreDbWatch* databaseWatch();
0129 
0130     /**
0131      * Setup the errors handler instance.
0132      */
0133     static void initDbEngineErrorHandler(DbEngineErrorHandler* const errorhandler);
0134 
0135 private:
0136 
0137     // Disable
0138     explicit CoreDbAccess(bool);
0139 
0140     friend class CoreDbAccessUnlock;
0141     static CoreDbAccessStaticPriv* d;
0142 };
0143 
0144 // -----------------------------------------------------------------------------
0145 
0146 class CoreDbAccessUnlock
0147 {
0148 public:
0149 
0150     /**
0151      * Acquire an object of this class if you want to assure
0152      * that the CoreDbAccess is _not_ held during the lifetime of the object.
0153      * At creation, the lock is obtained shortly, then all locks are released.
0154      * At destruction, all locks are acquired again.
0155      * If you need to access any locked structures during lifetime, acquire a new
0156      * CoreDbAccess.
0157      */
0158     CoreDbAccessUnlock();
0159     explicit CoreDbAccessUnlock(CoreDbAccess* const access);
0160     ~CoreDbAccessUnlock();
0161 
0162 private:
0163 
0164     int count;
0165 };
0166 
0167 } // namespace Digikam
0168 
0169 #endif // DIGIKAM_CORE_DB_ACCESS_H