summaryrefslogtreecommitdiff
path: root/sqlitebackend.h
blob: 4dfd2f9552c757c6c735f3340a625b299974906f (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
#ifndef SQLITEBACKEND_H
#define SQLITEBACKEND_H

#include <QObject>
#include <QPointF>
#include <QHash>
#include <QtSql>
#include <QFile>

enum TagChange {
    CREATED,
    CHANGED,
    DELETED
};

class Tag
{
public:
    Tag(long long int id, QString name, qreal anchor_x, qreal anchor_y, QByteArray metadata);
    Tag();
    Tag(long long int id, const Tag &other);

    long long int id;
    QString name;
    QPointF anchor;
    QVariantMap metadata;
};

class SQLiteSaveFile : public QObject
{
    Q_OBJECT
public:
    explicit SQLiteSaveFile(QObject *parent = nullptr, QString filename = ":memory:");
    bool connect();
    bool isOpen() { return m_isOpen; }

    QList<Tag> getAllTags();

    QByteArray getImage();

    bool updateTag(Tag tag);
    bool deleteTag(Tag tag);
    bool createTag(Tag tag);

    bool setMeta(const QString &key, const QVariant &value);
    bool setMeta(std::initializer_list<QPair<QString, QVariant>> metas);
    QVariant getMeta(const QString &key);

    QString errorString() { return lastErrorString; }
    enum Error {
        NoError = 0,
        SQLiteError,
        ImageOpenError,
        ImageReadError
    };
    inline const static QString errorNames[] =  {
                [NoError] = "No Error",
                [SQLiteError] = "Database Error",
                [ImageOpenError] = "Error Opening Image",
                [ImageReadError] = "Error Reading Image"
            };

    Error error();
    void resetError() { lastError = NoError; lastErrorString = QString(); }

public slots:
    /** Save this project file under a new name. This changes the backend database this project file object points to, and copies all data.
     * Callers can continue to use the same project file object afterwards.
     */
    bool saveAs(const QString &filename);
    bool reloadImageFromDisk();
    bool loadImageFromDisk(const QString &filename);
    bool clearNew();

signals:
    void tagChange(TagChange change, const Tag &tag);
    void fileReload();
    void fileIOError(Error e, QString errorName, QString description);

private:
    bool initDb(bool setCreationDate=true);
    bool runSql(QString query, std::initializer_list<QVariant> bindings={});

    bool setMetaLocked(const QString &key, const QVariant &value);
    bool setMetaLocked(std::initializer_list<QPair<QString, QVariant>> metas);
    QVariant getMetaLocked(const QString &key);

    void setError(Error e, QString desc) { lastError = e; lastErrorString = desc; fileIOError(e, errorNames[e], desc); }
    bool setDatabaseError(const QSqlQuery &q);
    bool setDatabaseError(const QSqlDatabase &db);

    Error lastError;
    QString lastErrorString;
    QSqlDatabase db;
    QMutex dbMut;
    QString filename;
    QByteArray imageData;
    bool m_isOpen;
};


#endif // SQLITEBACKEND_H