#ifndef SQLITEBACKEND_H #define SQLITEBACKEND_H #include #include #include #include #include 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 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> 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 bindings={}); bool setMetaLocked(const QString &key, const QVariant &value); bool setMetaLocked(std::initializer_list> 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