File: Database.h

package info (click to toggle)
kio-extras 4%3A22.12.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 10,768 kB
  • sloc: cpp: 26,898; ansic: 4,443; perl: 1,058; xml: 97; sh: 69; python: 28; makefile: 9
file content (129 lines) | stat: -rw-r--r-- 3,493 bytes parent folder | download
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 *   SPDX-FileCopyrightText: 2014-2016 Ivan Cukic <ivan.cukic@kde.org>
 *
 *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
 */

#ifndef COMMON_DATABASE_H
#define COMMON_DATABASE_H

#include <utils/d_ptr.h>
#include <memory>
#include <QSqlQuery>

namespace Common {

class Database {
public:
    typedef std::shared_ptr<Database> Ptr;

    enum Source {
        ResourcesDatabase
    };

    enum OpenMode {
        ReadWrite,
        ReadOnly
    };

    static Ptr instance(Source source, OpenMode openMode);

    QSqlQuery execQueries(const QStringList &queries) const;
    QSqlQuery execQuery(const QString &query, bool ignoreErrors = false) const;
    QSqlQuery createQuery() const;

    void setPragma(const QString &pragma);
    QVariant pragma(const QString &pragma) const;
    QVariant value(const QString &query) const;

    // For debugging purposes only
    QString lastQuery() const;

    ~Database();
    Database();

    friend class Locker;
    class Locker {
    public:
        explicit Locker(Database &database);
        ~Locker();

    private:
        QSqlDatabase &m_database;
    };

#define DATABASE_TRANSACTION(A) \
        /* enable this for debugging only: qDebug() << "Location:" << __FILE__ << __LINE__; */ \
        Common::Database::Locker lock(A)

private:
    D_PTR;
};

template <typename EscapeFunction>
QString parseStarPattern(const QString &pattern, const QString &joker,
                         EscapeFunction escape)
{
    const auto begin     = pattern.constBegin();
    const auto end       = pattern.constEnd();

    auto currentStart    = pattern.constBegin();
    auto currentPosition = pattern.constBegin();

    bool isEscaped = false;

    // This should be available in the QString class...
    auto stringFromIterators = [&](const QString::const_iterator &currentStart,
    const QString::const_iterator &currentPosition) {
        return pattern.mid(
                   std::distance(begin, currentStart),
                   std::distance(currentStart, currentPosition));
    };

    // Escaping % and _ for sql like
    // auto escape = [] (QString str) {
    //     return str.replace("%", "\\%").replace("_", "\\_");
    // };

    QString resultPattern;
    resultPattern.reserve(pattern.size() * 1.5);

    for (; currentPosition != end; ++currentPosition) {
        if (isEscaped) {
            // Just skip the current character
            isEscaped = false;

        } else if (*currentPosition == '\\') {
            // Skip two characters
            isEscaped = true;

        } else if (*currentPosition == '*') {
            // Replacing the star with the sql like joker - %
            resultPattern.append(escape(stringFromIterators(
                                            currentStart, currentPosition)) + joker);
            currentStart = currentPosition + 1;

        } else {
            // This one is boring, nothing to do
        }
    }

    if (currentStart != currentPosition) {
        resultPattern.append(escape(stringFromIterators(
                                        currentStart, currentPosition)));
    }

    return resultPattern;
}

inline QString starPatternToLike(const QString &pattern)
{
    return parseStarPattern(pattern, QStringLiteral("%"), [] (QString str) {
        return str.replace(QLatin1String("%"), QLatin1String("\\%")).replace(QLatin1String("_"), QLatin1String("\\_"));
    });
}

} // namespace Common

#endif // COMMON_DATABASE_H