127 lines
3.9 KiB
C++
127 lines
3.9 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=QPointF(), const QVariantMap metadata=QVariantMap());
|
|
|
|
bool operator==(const Tag &t2) const { return id == t2.id; }
|
|
|
|
bool isValid() const { return valid; }
|
|
QString humanReadableAnchor() { return QString("%1, %2").arg(anchor.x()).arg(anchor.y()); }
|
|
|
|
long long int id;
|
|
QString name;
|
|
QPointF anchor;
|
|
QPointF labelPos;
|
|
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
|