numberator/sqlitebackend.h
2020-08-16 17:04:32 +02:00

123 lines
3.7 KiB
C++

#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() : valid(false) {}
Tag(long long int id, QString name, qreal anchor_x, qreal anchor_y, QByteArray metadata);
Tag(long long int id, const Tag &other);
Tag(QString name, const QPointF &anchor, const QVariantMap metadata=QVariantMap());
bool isValid() { return valid; }
long long int id;
QString name;
QPointF anchor;
QVariantMap metadata;
private:
bool valid;
};
class SQLiteSaveFile : public QObject
{
Q_OBJECT
public:
explicit SQLiteSaveFile(QObject *parent = nullptr);
QList<Tag> getAllTags();
const QByteArray &getImage() const { return m_image; };
bool updateTag(Tag tag);
bool deleteTag(Tag tag);
bool createTag(Tag tag);
bool createTagAt(const QPointF &anchor);
QString getNextAutoTagName();
bool tagNameIsFree(const QString &name);
bool isMemory() { return m_memory; } /* backend db points to temporary memory db */
bool isDirty() { return m_dirty; } /* backend db was changed since opening */
bool isOpen() { return m_open; } /* backend db is open */
bool setMeta(const QString &key, const QVariant &value, bool setDirty=false);
bool setMeta(std::initializer_list<QPair<QString, QVariant>> metas, bool setDirty=false);
const QVariant getMeta(const QString &key) const;
const QString &errorString() const { return m_lastErrorString; }
enum Error {
NoError = 0,
FileNotFoundError,
SQLiteError,
ImageOpenError,
ImageReadError,
MaxError
};
inline const static QString errorNames[MaxError] = {
[NoError] = "No Error",
[FileNotFoundError] = "File not found",
[SQLiteError] = "Database Error",
[ImageOpenError] = "Error Opening Image",
[ImageReadError] = "Error Reading Image"
};
Error error();
void resetError() const { m_lastError = NoError; m_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 open(const QString &filename);
bool reloadImageFromDisk();
bool loadImageFromDisk(const QString &m_filename);
bool clearNew();
signals:
void tagChange(TagChange change, const Tag &tag);
void fileReload();
void fileIOError(Error e, QString errorName, QString description) const;
void imageLoaded(const QByteArray &image);
private:
bool connect();
bool initDb(bool setCreationDate=true, const QString &schema_name="main");
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);
const QVariant getMetaLocked(const QString &key) const;
void setError(Error e, QString desc) const { m_lastError = e; m_lastErrorString = desc; fileIOError(e, errorNames[e], desc); }
bool setDatabaseError(const QSqlQuery &q) const;
bool setDatabaseError(const QSqlDatabase &m_db) const;
mutable Error m_lastError;
mutable QString m_lastErrorString;
QSqlDatabase m_db;
mutable QMutex m_dbMut;
QString m_filename;
QByteArray m_image;
bool m_open;
bool m_dirty;
bool m_memory;
};
#endif // SQLITEBACKEND_H