+ struct BufferMO
+ {
+ BufferId bufferid;
+ UserId userid;
+ int groupid;
+ NetworkId networkid;
+ QString buffername;
+ QString buffercname;
+ int buffertype;
+ qint64 lastmsgid;
+ qint64 lastseenmsgid;
+ qint64 markerlinemsgid;
+ int bufferactivity;
+ int highlightcount;
+ QString key;
+ bool joined;
+ QString cipher;
+ };
+
+ struct BacklogMO
+ {
+ MsgId messageid;
+ QDateTime time; // has to be in UTC!
+ BufferId bufferid;
+ int type;
+ int flags;
+ qint64 senderid;
+ QString senderprefixes;
+ QString message;
+ };
+
+ struct IrcServerMO
+ {
+ int serverid;
+ UserId userid;
+ NetworkId networkid;
+ QString hostname;
+ int port;
+ QString password;
+ bool ssl;
+ bool sslverify; /// If true, validate SSL certificates
+ int sslversion;
+ bool useproxy;
+ int proxytype;
+ QString proxyhost;
+ int proxyport;
+ QString proxyuser;
+ QString proxypass;
+ };
+
+ struct UserSettingMO
+ {
+ UserId userid;
+ QString settingname;
+ QByteArray settingvalue;
+ };
+
+ struct CoreStateMO
+ {
+ QString key;
+ QByteArray value;
+ };
+
+ enum MigrationObject
+ {
+ QuasselUser,
+ Sender,
+ Identity,
+ IdentityNick,
+ Network,
+ Buffer,
+ Backlog,
+ IrcServer,
+ UserSetting,
+ CoreState
+ };
+
+ virtual ~AbstractSqlMigrator() = default;
+
+ static QString migrationObject(MigrationObject moType);
+
+protected:
+ void newQuery(const QString& query, QSqlDatabase db);
+ virtual void resetQuery();
+ virtual bool prepareQuery(MigrationObject mo) = 0;
+ bool exec();
+ inline bool next() { return _query->next(); }
+ inline QVariant value(int index) { return _query->value(index); }
+ inline void bindValue(const QString& placeholder, const QVariant& val) { _query->bindValue(placeholder, val); }
+ inline void bindValue(int pos, const QVariant& val) { _query->bindValue(pos, val); }
+
+ inline QSqlError lastError() { return _query ? _query->lastError() : QSqlError(); }
+ void dumpStatus();
+ inline QString executedQuery() { return _query ? _query->executedQuery() : QString(); }
+ inline QVariantList boundValues();
+
+ virtual bool transaction() = 0;
+ virtual void rollback() = 0;
+ virtual bool commit() = 0;
+
+private:
+ QSqlQuery* _query{nullptr};
+};
+
+class AbstractSqlMigrationReader : public AbstractSqlMigrator
+{
+public:
+ AbstractSqlMigrationReader();
+
+ virtual bool readMo(QuasselUserMO& user) = 0;
+ virtual bool readMo(IdentityMO& identity) = 0;
+ virtual bool readMo(IdentityNickMO& identityNick) = 0;
+ virtual bool readMo(NetworkMO& network) = 0;
+ virtual bool readMo(BufferMO& buffer) = 0;
+ virtual bool readMo(SenderMO& sender) = 0;
+ virtual bool readMo(BacklogMO& backlog) = 0;
+ virtual bool readMo(IrcServerMO& ircserver) = 0;
+ virtual bool readMo(UserSettingMO& userSetting) = 0;
+ virtual bool readMo(CoreStateMO& coreState) = 0;
+
+ bool migrateTo(AbstractSqlMigrationWriter* writer);
+
+private:
+ void abortMigration(const QString& errorMsg = QString());
+ bool finalizeMigration();
+
+ template<typename T>
+ bool transferMo(MigrationObject moType, T& mo);
+
+ AbstractSqlMigrationWriter* _writer{nullptr};
+};
+
+class AbstractSqlMigrationWriter : public AbstractSqlMigrator
+{
+public:
+ virtual bool writeMo(const QuasselUserMO& user) = 0;
+ virtual bool writeMo(const IdentityMO& identity) = 0;
+ virtual bool writeMo(const IdentityNickMO& identityNick) = 0;
+ virtual bool writeMo(const NetworkMO& network) = 0;
+ virtual bool writeMo(const BufferMO& buffer) = 0;
+ virtual bool writeMo(const SenderMO& sender) = 0;
+ virtual bool writeMo(const BacklogMO& backlog) = 0;
+ virtual bool writeMo(const IrcServerMO& ircserver) = 0;
+ virtual bool writeMo(const UserSettingMO& userSetting) = 0;
+ virtual bool writeMo(const CoreStateMO& coreState) = 0;
+
+ inline bool migrateFrom(AbstractSqlMigrationReader* reader) { return reader->migrateTo(this); }
+
+ // called after migration process
+ virtual inline bool postProcess() { return true; }
+ friend class AbstractSqlMigrationReader;
+};