Execute initDbSession() on DB reconnects
[quassel.git] / src / core / abstractsqlstorage.h
index cc9f619..c39e826 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-07 by the Quassel Project                          *
+ *   Copyright (C) 2005-2015 by the Quassel Project                        *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -15,7 +15,7 @@
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
  ***************************************************************************/
 
 #ifndef ABSTRACTSQLSTORAGE_H
 class AbstractSqlMigrationReader;
 class AbstractSqlMigrationWriter;
 
-class AbstractSqlStorage : public Storage {
-  Q_OBJECT
+class AbstractSqlStorage : public Storage
+{
+    Q_OBJECT
 
 public:
-  AbstractSqlStorage(QObject *parent = 0);
-  virtual ~AbstractSqlStorage();
+    AbstractSqlStorage(QObject *parent = 0);
+    virtual ~AbstractSqlStorage();
 
-  virtual inline AbstractSqlMigrationReader *createMigrationReader() { return 0; }
-  virtual inline AbstractSqlMigrationWriter *createMigrationWriter() { return 0; }
+    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());
+    virtual State init(const QVariantMap &settings = QVariantMap());
+    virtual bool setup(const QVariantMap &settings = QVariantMap());
 
 protected:
-  inline virtual void sync() {};
+    inline virtual void sync() {};
 
-  QSqlDatabase logDb();
+    QSqlDatabase logDb();
 
-  QString queryString(const QString &queryName, int version);
-  inline QString queryString(const QString &queryName) { return queryString(queryName, 0); }
+    QString queryString(const QString &queryName, int version);
+    inline QString queryString(const QString &queryName) { return queryString(queryName, 0); }
 
-  QStringList setupQueries();
+    QStringList setupQueries();
 
-  QStringList upgradeQueries(int ver);
-  bool upgradeDb();
+    QStringList upgradeQueries(int ver);
+    bool upgradeDb();
 
-  bool watchQuery(QSqlQuery &query);
+    bool watchQuery(QSqlQuery &query);
 
-  int schemaVersion();
-  virtual int installedSchemaVersion() { return -1; };
-  virtual bool updateSchemaVersion(int newVersion) = 0;
-  virtual bool setupSchemaVersion(int version) = 0;
+    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(); }
+    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();
+    void connectionDestroyed();
 
 private:
-  void addConnectionToPool();
-
-  int _schemaVersion;
-
-  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;
+    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
+class AbstractSqlStorage::Connection : public QObject
+{
+    Q_OBJECT
 
 public:
-  Connection(const QString &name, QObject *parent = 0);
-  ~Connection();
+    Connection(const QString &name, QObject *parent = 0);
+    ~Connection();
 
-  inline QLatin1String name() const { return QLatin1String(_name); }
+    inline QLatin1String name() const { return QLatin1String(_name); }
 
 private:
-  QByteArray _name;
+    QByteArray _name;
 };
 
 
 // ========================================
 //  AbstractSqlMigrator
 // ========================================
-class AbstractSqlMigrator {
+class AbstractSqlMigrator
+{
 public:
-  // migration objects
-  struct QuasselUserMO {
-    UserId id;
-    QString username;
-    QString password;
-  };
-
-  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;
-  };
-
-  struct BufferMO {
-    BufferId bufferid;
-    UserId userid;
-    int groupid;
-    NetworkId networkid;
-    QString buffername;
-    QString buffercname;
-    int buffertype;
-    int lastseenmsgid;
-    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);
+    // migration objects
+    struct QuasselUserMO {
+        UserId id;
+        QString username;
+        QString password;
+    };
+
+    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);
 
 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;
+    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;
+    QSqlQuery *_query;
 };
 
-class AbstractSqlMigrationReader : public AbstractSqlMigrator {
+
+class AbstractSqlMigrationReader : public AbstractSqlMigrator
+{
 public:
-  AbstractSqlMigrationReader();
+    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(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;
 
-  bool migrateTo(AbstractSqlMigrationWriter *writer);
+    bool migrateTo(AbstractSqlMigrationWriter *writer);
 
 private:
-  void abortMigration(const QString &errorMsg = QString());
-  bool finalizeMigration();
+    void abortMigration(const QString &errorMsg = QString());
+    bool finalizeMigration();
 
-  template<typename T> bool transferMo(MigrationObject moType, T &mo);
+    template<typename T> bool transferMo(MigrationObject moType, T &mo);
 
-  AbstractSqlMigrationWriter *_writer;
+    AbstractSqlMigrationWriter *_writer;
 };
 
-class AbstractSqlMigrationWriter : public AbstractSqlMigrator {
+
+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;
-
-  inline bool migrateFrom(AbstractSqlMigrationReader *reader) { return reader->migrateTo(this); }
-
-  // called after migration process
-  virtual inline bool postProcess() { return true; }
-  friend class AbstractSqlMigrationReader;
+    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;
+
+    inline bool migrateFrom(AbstractSqlMigrationReader *reader) { return reader->migrateTo(this); }
+
+    // called after migration process
+    virtual inline bool postProcess() { return true; }
+    friend class AbstractSqlMigrationReader;
 };
 
+
 #endif