aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/coreSQLiteStudio/common/readwritelocker.h
blob: cac9368ff7f5b4774d550b77a111e9e5f9545427 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#ifndef READWRITELOCKER_H
#define READWRITELOCKER_H

#include "coreSQLiteStudio_global.h"
#include "dialect.h"

class QReadLocker;
class QWriteLocker;
class QReadWriteLock;

/**
 * @brief The ReadWriteLocker class
 *
 * This class behaves pretty much like QReadLocker or QWriteLocker
 * (it actually uses those internally), except it can be either
 * of those and this is to be decided at the moment of creation.
 * Therefore the locker can work as read or write locker depending
 * on an external condition.
 * There's also a possibility to not lock anything as a third
 * choice of working mode, so this also can be decided
 * at construction moment.
 */
class API_EXPORT ReadWriteLocker
{
    public:
        enum Mode
        {
            READ,
            WRITE,
            NONE
        };

        ReadWriteLocker(QReadWriteLock* lock, Mode mode);
        ReadWriteLocker(QReadWriteLock* lock, const QString& query, Dialect dialect, bool noLock);
        virtual ~ReadWriteLocker();

        /**
         * @brief Provides required locking mode for given query.
         * @param query Query to be executed.
         * @return Locking mode: READ or WRITE.
         *
         * Given the query this method analyzes what is the query and provides information if the query
         * will do some changes on the database, or not. Then it returns proper locking mode that should
         * be used for this query execution.
         *
         * Query execution methods from this class check if lock mode of the query to be executed isn't
         * in conflict with the lock being currently applied on the dbOperLock (if any is applied at the moment).
         *
         * This method works on a very simple rule. It assumes that queries: SELECT, ANALYZE, EXPLAIN,
         * and PRAGMA - are read-only, while all other queries are read-write.
         * In case of PRAGMA this is not entirely true, but it's not like using PRAGMA for changing
         * some setting would cause database state inconsistency. At least not from perspective of SQLiteStudio.
         *
         * In case of WITH statement it filters out the "WITH clause" and then checks for SELECT keyword.
         */
        static ReadWriteLocker::Mode getMode(const QString& query, Dialect dialect, bool noLock);

    private:
        void init(QReadWriteLock* lock, Mode mode);

        QReadLocker* readLocker = nullptr;
        QWriteLocker* writeLocker = nullptr;
};

#endif // READWRITELOCKER_H