Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ownsql.h « common « src - github.com/nextcloud/desktop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d409dc827997e2db0640c12d29fe116dd384ce24 (plain)
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*
 * Copyright (C) by Klaas Freitag <freitag@owncloud.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef OWNSQL_H
#define OWNSQL_H

#include <QLoggingCategory>
#include <QObject>
#include <QVariant>

#include "ocsynclib.h"

struct sqlite3;
struct sqlite3_stmt;

namespace OCC {
OCSYNC_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcSql)

class SqlQuery;

/**
 * @brief The SqlDatabase class
 * @ingroup libsync
 */
class OCSYNC_EXPORT SqlDatabase
{
    Q_DISABLE_COPY(SqlDatabase)
public:
    explicit SqlDatabase();
    ~SqlDatabase();

    bool isOpen();
    bool openOrCreateReadWrite(const QString &filename);
    bool openReadOnly(const QString &filename);
    bool transaction();
    bool commit();
    void close();
    QString error() const;
    sqlite3 *sqliteDb();

private:
    enum class CheckDbResult {
        Ok,
        CantPrepare,
        CantExec,
        NotOk,
    };

    bool openHelper(const QString &filename, int sqliteFlags);
    CheckDbResult checkDb();

    sqlite3 *_db = nullptr;
    QString _error; // last error string
    int _errId = 0;

    friend class SqlQuery;
    QSet<SqlQuery *> _queries;
};

/**
 * @brief The SqlQuery class
 * @ingroup libsync
 *
 * There is basically 3 ways to initialize and use a query:
 *
    SqlQuery q1;
    [...]
    q1.initOrReset(...);
    q1.bindValue(...);
    q1.exec(...)
 *
    SqlQuery q2(db);
    q2.prepare(...);
    [...]
    q2.reset_and_clear_bindings();
    q2.bindValue(...);
    q2.exec(...)
 *
    SqlQuery q3("...", db);
    q3.bindValue(...);
    q3.exec(...)
 *
 */
class OCSYNC_EXPORT SqlQuery
{
    Q_DISABLE_COPY(SqlQuery)
public:
    explicit SqlQuery() = default;
    explicit SqlQuery(SqlDatabase &db);
    explicit SqlQuery(const QByteArray &sql, SqlDatabase &db);
    /**
     * Prepare the SqlQuery.
     * If the query was already prepared, this will first call finish(), and re-prepare it.
     * This function must only be used if the constructor was setting a SqlDatabase
     */
    int prepare(const QByteArray &sql, bool allow_failure = false);

    ~SqlQuery();
    QString error() const;
    int errorId() const;

    /// Checks whether the value at the given column index is NULL
    bool nullValue(int index);

    QString stringValue(int index);
    int intValue(int index);
    quint64 int64Value(int index);
    QByteArray baValue(int index);
    bool isSelect();
    bool isPragma();
    bool exec();

    struct NextResult
    {
        bool ok = false;
        bool hasData = false;
    };
    NextResult next();

    template<class T, typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
    void bindValue(int pos, const T &value)
    {
        qCDebug(lcSql) << "SQL bind" << pos << value;
        bindValueInternal(pos, static_cast<int>(value));
    }

    template<class T, typename std::enable_if<!std::is_enum<T>::value, int>::type = 0>
    void bindValue(int pos, const T &value)
    {
        qCDebug(lcSql) << "SQL bind" << pos << value;
        bindValueInternal(pos, value);
    }

    void bindValue(int pos, const QByteArray &value)
    {
        qCDebug(lcSql) << "SQL bind" << pos << QString::fromUtf8(value);
        bindValueInternal(pos, value);
    }

    const QByteArray &lastQuery() const;
    int numRowsAffected();
    void reset_and_clear_bindings();

private:
    void bindValueInternal(int pos, const QVariant &value);
    void finish();

    SqlDatabase *_sqldb = nullptr;
    sqlite3 *_db = nullptr;
    sqlite3_stmt *_stmt = nullptr;
    QString _error;
    int _errId;
    QByteArray _sql;

    friend class SqlDatabase;
    friend class PreparedSqlQueryManager;
};

} // namespace OCC

#endif // OWNSQL_H