Remove unused cipher map.
[quassel.git] / src / core / abstractsqlstorage.h
1 /***************************************************************************
2  *   Copyright (C) 2005-2013 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
30 class AbstractSqlMigrationReader;
31 class AbstractSqlMigrationWriter;
32
33 class AbstractSqlStorage : public Storage
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
76     //! Initialize db specific features on connect
77     /** This is called every time a connection to a specific SQL backend is established
78      *  the default implementation does nothing.
79      *
80      *  When reimplementing this method, don't use logDB() inside this function as
81      *  this would cause as we're just about to initialize that DB connection.
82      */
83     inline virtual void initDbSession(QSqlDatabase & /* db */) {}
84
85 private slots:
86     void connectionDestroyed();
87
88 private:
89     void addConnectionToPool();
90
91     int _schemaVersion;
92     bool _debug;
93
94     static int _nextConnectionId;
95     QMutex _connectionPoolMutex;
96     // we let a Connection Object manage each actual db connection
97     // those objects reside in the thread the connection belongs to
98     // which allows us thread safe termination of a connection
99     class Connection;
100     QHash<QThread *, Connection *> _connectionPool;
101 };
102
103
104 // ========================================
105 //  AbstractSqlStorage::Connection
106 // ========================================
107 class AbstractSqlStorage::Connection : public QObject
108 {
109     Q_OBJECT
110
111 public:
112     Connection(const QString &name, QObject *parent = 0);
113     ~Connection();
114
115     inline QLatin1String name() const { return QLatin1String(_name); }
116
117 private:
118     QByteArray _name;
119 };
120
121
122 // ========================================
123 //  AbstractSqlMigrator
124 // ========================================
125 class AbstractSqlMigrator
126 {
127 public:
128     // migration objects
129     struct QuasselUserMO {
130         UserId id;
131         QString username;
132         QString password;
133     };
134
135     struct SenderMO {
136         int senderId;
137         QString sender;
138         SenderMO() : senderId(0) {}
139     };
140
141     struct IdentityMO {
142         IdentityId id;
143         UserId userid;
144         QString identityname;
145         QString realname;
146         QString awayNick;
147         bool awayNickEnabled;
148         QString awayReason;
149         bool awayReasonEnabled;
150         bool autoAwayEnabled;
151         int autoAwayTime;
152         QString autoAwayReason;
153         bool autoAwayReasonEnabled;
154         bool detachAwayEnabled;
155         QString detachAwayReason;
156         bool detchAwayReasonEnabled;
157         QString ident;
158         QString kickReason;
159         QString partReason;
160         QString quitReason;
161         QByteArray sslCert;
162         QByteArray sslKey;
163     };
164
165     struct IdentityNickMO {
166         int nickid;
167         IdentityId identityId;
168         QString nick;
169     };
170
171     struct NetworkMO {
172         NetworkId networkid;
173         UserId userid;
174         QString networkname;
175         IdentityId identityid;
176         QString encodingcodec;
177         QString decodingcodec;
178         QString servercodec;
179         bool userandomserver;
180         QString perform;
181         bool useautoidentify;
182         QString autoidentifyservice;
183         QString autoidentifypassword;
184         bool useautoreconnect;
185         int autoreconnectinterval;
186         int autoreconnectretries;
187         bool unlimitedconnectretries;
188         bool rejoinchannels;
189         bool connected;
190         QString usermode;
191         QString awaymessage;
192         QString attachperform;
193         QString detachperform;
194         bool usesasl;
195         QString saslaccount;
196         QString saslpassword;
197     };
198
199     struct BufferMO {
200         BufferId bufferid;
201         UserId userid;
202         int groupid;
203         NetworkId networkid;
204         QString buffername;
205         QString buffercname;
206         int buffertype;
207         int lastseenmsgid;
208         int markerlinemsgid;
209         QString key;
210         bool joined;
211     };
212
213     struct BacklogMO {
214         MsgId messageid;
215         QDateTime time; // has to be in UTC!
216         BufferId bufferid;
217         int type;
218         int flags;
219         int senderid;
220         QString message;
221     };
222
223     struct IrcServerMO {
224         int serverid;
225         UserId userid;
226         NetworkId networkid;
227         QString hostname;
228         int port;
229         QString password;
230         bool ssl;
231         int sslversion;
232         bool useproxy;
233         int proxytype;
234         QString proxyhost;
235         int proxyport;
236         QString proxyuser;
237         QString proxypass;
238     };
239
240     struct UserSettingMO {
241         UserId userid;
242         QString settingname;
243         QByteArray settingvalue;
244     };
245
246     enum MigrationObject {
247         QuasselUser,
248         Sender,
249         Identity,
250         IdentityNick,
251         Network,
252         Buffer,
253         Backlog,
254         IrcServer,
255         UserSetting
256     };
257
258     AbstractSqlMigrator();
259     virtual ~AbstractSqlMigrator() {}
260
261     static QString migrationObject(MigrationObject moType);
262
263 protected:
264     void newQuery(const QString &query, QSqlDatabase db);
265     virtual void resetQuery();
266     virtual bool prepareQuery(MigrationObject mo) = 0;
267     bool exec();
268     inline bool next() { return _query->next(); }
269     inline QVariant value(int index) { return _query->value(index); }
270     inline void bindValue(const QString &placeholder, const QVariant &val) { _query->bindValue(placeholder, val); }
271     inline void bindValue(int pos, const QVariant &val) { _query->bindValue(pos, val); }
272
273     inline QSqlError lastError() { return _query ? _query->lastError() : QSqlError(); }
274     void dumpStatus();
275     inline QString executedQuery() { return _query ? _query->executedQuery() : QString(); }
276     inline QVariantList boundValues();
277
278     virtual bool transaction() = 0;
279     virtual void rollback() = 0;
280     virtual bool commit() = 0;
281
282 private:
283     QSqlQuery *_query;
284 };
285
286
287 class AbstractSqlMigrationReader : public AbstractSqlMigrator
288 {
289 public:
290     AbstractSqlMigrationReader();
291
292     virtual bool readMo(QuasselUserMO &user) = 0;
293     virtual bool readMo(IdentityMO &identity) = 0;
294     virtual bool readMo(IdentityNickMO &identityNick) = 0;
295     virtual bool readMo(NetworkMO &network) = 0;
296     virtual bool readMo(BufferMO &buffer) = 0;
297     virtual bool readMo(SenderMO &sender) = 0;
298     virtual bool readMo(BacklogMO &backlog) = 0;
299     virtual bool readMo(IrcServerMO &ircserver) = 0;
300     virtual bool readMo(UserSettingMO &userSetting) = 0;
301
302     bool migrateTo(AbstractSqlMigrationWriter *writer);
303
304 private:
305     void abortMigration(const QString &errorMsg = QString());
306     bool finalizeMigration();
307
308     template<typename T> bool transferMo(MigrationObject moType, T &mo);
309
310     AbstractSqlMigrationWriter *_writer;
311 };
312
313
314 class AbstractSqlMigrationWriter : public AbstractSqlMigrator
315 {
316 public:
317     virtual bool writeMo(const QuasselUserMO &user) = 0;
318     virtual bool writeMo(const IdentityMO &identity) = 0;
319     virtual bool writeMo(const IdentityNickMO &identityNick) = 0;
320     virtual bool writeMo(const NetworkMO &network) = 0;
321     virtual bool writeMo(const BufferMO &buffer) = 0;
322     virtual bool writeMo(const SenderMO &sender) = 0;
323     virtual bool writeMo(const BacklogMO &backlog) = 0;
324     virtual bool writeMo(const IrcServerMO &ircserver) = 0;
325     virtual bool writeMo(const UserSettingMO &userSetting) = 0;
326
327     inline bool migrateFrom(AbstractSqlMigrationReader *reader) { return reader->migrateTo(this); }
328
329     // called after migration process
330     virtual inline bool postProcess() { return true; }
331     friend class AbstractSqlMigrationReader;
332 };
333
334
335 #endif