Quassel IRC  Pre-Release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
abstractsqlstorage.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2015 by the Quassel Project *
3  * devel@quassel-irc.org *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) version 3. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19  ***************************************************************************/
20 
21 #ifndef ABSTRACTSQLSTORAGE_H
22 #define ABSTRACTSQLSTORAGE_H
23 
24 #include "storage.h"
25 
26 #include <QSqlDatabase>
27 #include <QSqlQuery>
28 #include <QSqlError>
29 
32 
34 {
35  Q_OBJECT
36 
37 public:
38  AbstractSqlStorage(QObject *parent = 0);
39  virtual ~AbstractSqlStorage();
40 
41  virtual inline AbstractSqlMigrationReader *createMigrationReader() { return 0; }
42  virtual inline AbstractSqlMigrationWriter *createMigrationWriter() { return 0; }
43 
44 public slots:
45  virtual State init(const QVariantMap &settings = QVariantMap());
46  virtual bool setup(const QVariantMap &settings = QVariantMap());
47 
48 protected:
49  inline virtual void sync() {};
50 
51  QSqlDatabase logDb();
52 
53  QString queryString(const QString &queryName, int version);
54  inline QString queryString(const QString &queryName) { return queryString(queryName, 0); }
55 
56  QStringList setupQueries();
57 
58  QStringList upgradeQueries(int ver);
59  bool upgradeDb();
60 
61  bool watchQuery(QSqlQuery &query);
62 
63  int schemaVersion();
64  virtual int installedSchemaVersion() { return -1; };
65  virtual bool updateSchemaVersion(int newVersion) = 0;
66  virtual bool setupSchemaVersion(int version) = 0;
67 
68  virtual void setConnectionProperties(const QVariantMap &properties) = 0;
69  virtual QString driverName() = 0;
70  inline virtual QString hostName() { return QString(); }
71  inline virtual int port() { return -1; }
72  virtual QString databaseName() = 0;
73  inline virtual QString userName() { return QString(); }
74  inline virtual QString password() { return QString(); }
75 
77 
83  inline virtual bool initDbSession(QSqlDatabase & /* db */) { return true; }
84 
85 private slots:
86  void connectionDestroyed();
87 
88 private:
89  void addConnectionToPool();
90  void dbConnect(QSqlDatabase &db);
91 
93  bool _debug;
94 
95  static int _nextConnectionId;
97  // we let a Connection Object manage each actual db connection
98  // those objects reside in the thread the connection belongs to
99  // which allows us thread safe termination of a connection
100  class Connection;
101  QHash<QThread *, Connection *> _connectionPool;
102 };
103 
104 
105 // ========================================
106 // AbstractSqlStorage::Connection
107 // ========================================
108 class AbstractSqlStorage::Connection : public QObject
109 {
110  Q_OBJECT
111 
112 public:
113  Connection(const QString &name, QObject *parent = 0);
114  ~Connection();
115 
116  inline QLatin1String name() const { return QLatin1String(_name); }
117 
118 private:
119  QByteArray _name;
120 };
121 
122 
123 // ========================================
124 // AbstractSqlMigrator
125 // ========================================
127 {
128 public:
129  // migration objects
130  struct QuasselUserMO {
132  QString username;
133  QString password;
134  };
135 
136  struct SenderMO {
137  int senderId;
138  QString sender;
139  SenderMO() : senderId(0) {}
140  };
141 
142  struct IdentityMO {
145  QString identityname;
146  QString realname;
147  QString awayNick;
149  QString awayReason;
153  QString autoAwayReason;
158  QString ident;
159  QString kickReason;
160  QString partReason;
161  QString quitReason;
162  QByteArray sslCert;
163  QByteArray sslKey;
164  };
165 
166  struct IdentityNickMO {
167  int nickid;
169  QString nick;
170  };
171 
172  struct NetworkMO {
175  QString networkname;
177  QString encodingcodec;
178  QString decodingcodec;
179  QString servercodec;
181  QString perform;
190  bool connected;
191  QString usermode;
192  QString awaymessage;
193  QString attachperform;
194  QString detachperform;
195  bool usesasl;
196  QString saslaccount;
197  QString saslpassword;
198  };
199 
200  struct BufferMO {
203  int groupid;
205  QString buffername;
206  QString buffercname;
210  QString key;
211  bool joined;
212  };
213 
214  struct BacklogMO {
216  QDateTime time; // has to be in UTC!
218  int type;
219  int flags;
220  int senderid;
221  QString message;
222  };
223 
224  struct IrcServerMO {
225  int serverid;
228  QString hostname;
229  int port;
230  QString password;
231  bool ssl;
233  bool useproxy;
235  QString proxyhost;
237  QString proxyuser;
238  QString proxypass;
239  };
240 
241  struct UserSettingMO {
243  QString settingname;
244  QByteArray settingvalue;
245  };
246 
257  };
258 
260  virtual ~AbstractSqlMigrator() {}
261 
262  static QString migrationObject(MigrationObject moType);
263 
264 protected:
265  void newQuery(const QString &query, QSqlDatabase db);
266  virtual void resetQuery();
267  virtual bool prepareQuery(MigrationObject mo) = 0;
268  bool exec();
269  inline bool next() { return _query->next(); }
270  inline QVariant value(int index) { return _query->value(index); }
271  inline void bindValue(const QString &placeholder, const QVariant &val) { _query->bindValue(placeholder, val); }
272  inline void bindValue(int pos, const QVariant &val) { _query->bindValue(pos, val); }
273 
274  inline QSqlError lastError() { return _query ? _query->lastError() : QSqlError(); }
275  void dumpStatus();
276  inline QString executedQuery() { return _query ? _query->executedQuery() : QString(); }
277  inline QVariantList boundValues();
278 
279  virtual bool transaction() = 0;
280  virtual void rollback() = 0;
281  virtual bool commit() = 0;
282 
283 private:
284  QSqlQuery *_query;
285 };
286 
287 
289 {
290 public:
292 
293  virtual bool readMo(QuasselUserMO &user) = 0;
294  virtual bool readMo(IdentityMO &identity) = 0;
295  virtual bool readMo(IdentityNickMO &identityNick) = 0;
296  virtual bool readMo(NetworkMO &network) = 0;
297  virtual bool readMo(BufferMO &buffer) = 0;
298  virtual bool readMo(SenderMO &sender) = 0;
299  virtual bool readMo(BacklogMO &backlog) = 0;
300  virtual bool readMo(IrcServerMO &ircserver) = 0;
301  virtual bool readMo(UserSettingMO &userSetting) = 0;
302 
304 
305 private:
306  void abortMigration(const QString &errorMsg = QString());
307  bool finalizeMigration();
308 
309  template<typename T> bool transferMo(MigrationObject moType, T &mo);
310 
312 };
313 
314 
316 {
317 public:
318  virtual bool writeMo(const QuasselUserMO &user) = 0;
319  virtual bool writeMo(const IdentityMO &identity) = 0;
320  virtual bool writeMo(const IdentityNickMO &identityNick) = 0;
321  virtual bool writeMo(const NetworkMO &network) = 0;
322  virtual bool writeMo(const BufferMO &buffer) = 0;
323  virtual bool writeMo(const SenderMO &sender) = 0;
324  virtual bool writeMo(const BacklogMO &backlog) = 0;
325  virtual bool writeMo(const IrcServerMO &ircserver) = 0;
326  virtual bool writeMo(const UserSettingMO &userSetting) = 0;
327 
328  inline bool migrateFrom(AbstractSqlMigrationReader *reader) { return reader->migrateTo(this); }
329 
330  // called after migration process
331  virtual inline bool postProcess() { return true; }
333 };
334 
335 
336 #endif