+ AbstractSqlStorage(QObject *parent = 0);
+ virtual ~AbstractSqlStorage();
+
+ virtual inline AbstractSqlMigrationReader *createMigrationReader() { return 0; }
+ virtual inline AbstractSqlMigrationWriter *createMigrationWriter() { return 0; }
+
+public slots:
+ virtual State init(const QVariantMap &settings = QVariantMap());
+ virtual bool setup(const QVariantMap &settings = QVariantMap());
+
+protected:
+ inline virtual void sync() {};
+
+ QSqlDatabase logDb();
+
+ QString queryString(const QString &queryName, int version);
+ inline QString queryString(const QString &queryName) { return queryString(queryName, 0); }
+
+ QStringList setupQueries();
+
+ QStringList upgradeQueries(int ver);
+ bool upgradeDb();
+
+ bool watchQuery(QSqlQuery &query);
+
+ int schemaVersion();
+ virtual int installedSchemaVersion() { return -1; };
+ virtual bool updateSchemaVersion(int newVersion) = 0;
+ virtual bool setupSchemaVersion(int version) = 0;
+
+ virtual void setConnectionProperties(const QVariantMap &properties) = 0;
+ virtual QString driverName() = 0;
+ inline virtual QString hostName() { return QString(); }
+ inline virtual int port() { return -1; }
+ virtual QString databaseName() = 0;
+ inline virtual QString userName() { return QString(); }
+ inline virtual QString password() { return QString(); }
+
+ //! Initialize db specific features on connect
+ /** This is called every time a connection to a specific SQL backend is established
+ * the default implementation does nothing.
+ *
+ * When reimplementing this method, don't use logDB() inside this function as
+ * this would cause as we're just about to initialize that DB connection.
+ */
+ inline virtual bool initDbSession(QSqlDatabase & /* db */) { return true; }
+
+private slots:
+ void connectionDestroyed();
+
+private:
+ void addConnectionToPool();
+ void dbConnect(QSqlDatabase &db);
+
+ int _schemaVersion;
+ bool _debug;
+
+ static int _nextConnectionId;
+ QMutex _connectionPoolMutex;
+ // we let a Connection Object manage each actual db connection
+ // those objects reside in the thread the connection belongs to
+ // which allows us thread safe termination of a connection
+ class Connection;
+ QHash<QThread *, Connection *> _connectionPool;
+};
+
+
+// ========================================
+// AbstractSqlStorage::Connection
+// ========================================
+class AbstractSqlStorage::Connection : public QObject
+{
+ Q_OBJECT
+
+public:
+ Connection(const QString &name, QObject *parent = 0);
+ ~Connection();
+
+ inline QLatin1String name() const { return QLatin1String(_name); }
+
+private:
+ QByteArray _name;
+};
+
+
+// ========================================
+// AbstractSqlMigrator
+// ========================================
+class AbstractSqlMigrator
+{
+public:
+ // migration objects
+ struct QuasselUserMO {
+ UserId id;
+ QString username;
+ QString password;
+ int hashversion;
+ };
+
+ struct SenderMO {
+ int senderId;
+ QString sender;
+ SenderMO() : senderId(0) {}
+ };
+
+ struct IdentityMO {
+ IdentityId id;
+ UserId userid;
+ QString identityname;
+ QString realname;
+ QString awayNick;
+ bool awayNickEnabled;
+ QString awayReason;
+ bool awayReasonEnabled;
+ bool autoAwayEnabled;
+ int autoAwayTime;
+ QString autoAwayReason;
+ bool autoAwayReasonEnabled;
+ bool detachAwayEnabled;
+ QString detachAwayReason;
+ bool detchAwayReasonEnabled;
+ QString ident;
+ QString kickReason;
+ QString partReason;
+ QString quitReason;
+ QByteArray sslCert;
+ QByteArray sslKey;
+ };
+
+ struct IdentityNickMO {
+ int nickid;
+ IdentityId identityId;
+ QString nick;
+ };
+
+ struct NetworkMO {
+ NetworkId networkid;
+ UserId userid;
+ QString networkname;
+ IdentityId identityid;
+ QString encodingcodec;
+ QString decodingcodec;
+ QString servercodec;
+ bool userandomserver;
+ QString perform;
+ bool useautoidentify;
+ QString autoidentifyservice;
+ QString autoidentifypassword;
+ bool useautoreconnect;
+ int autoreconnectinterval;
+ int autoreconnectretries;
+ bool unlimitedconnectretries;
+ bool rejoinchannels;
+ bool connected;
+ QString usermode;
+ QString awaymessage;
+ QString attachperform;
+ QString detachperform;
+ bool usesasl;
+ QString saslaccount;
+ QString saslpassword;
+ };
+
+ struct BufferMO {
+ BufferId bufferid;
+ UserId userid;
+ int groupid;
+ NetworkId networkid;
+ QString buffername;
+ QString buffercname;
+ int buffertype;
+ int lastseenmsgid;
+ int markerlinemsgid;
+ QString key;
+ bool joined;
+ };
+
+ struct BacklogMO {
+ MsgId messageid;
+ QDateTime time; // has to be in UTC!
+ BufferId bufferid;
+ int type;
+ int flags;
+ int senderid;
+ QString message;
+ };
+
+ struct IrcServerMO {
+ int serverid;
+ UserId userid;
+ NetworkId networkid;
+ QString hostname;
+ int port;
+ QString password;
+ bool ssl;
+ int sslversion;
+ bool useproxy;
+ int proxytype;
+ QString proxyhost;
+ int proxyport;
+ QString proxyuser;
+ QString proxypass;
+ };
+
+ struct UserSettingMO {
+ UserId userid;
+ QString settingname;
+ QByteArray settingvalue;
+ };
+
+ enum MigrationObject {
+ QuasselUser,
+ Sender,
+ Identity,
+ IdentityNick,
+ Network,
+ Buffer,
+ Backlog,
+ IrcServer,
+ UserSetting
+ };
+
+ AbstractSqlMigrator();
+ virtual ~AbstractSqlMigrator() {}
+
+ static QString migrationObject(MigrationObject moType);