Reformat ALL the source!
[quassel.git] / src / core / core.h
1 /***************************************************************************
2  *   Copyright (C) 2005-09 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  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #ifndef CORE_H
22 #define CORE_H
23
24 #include <QDateTime>
25 #include <QString>
26 #include <QVariant>
27 #include <QTimer>
28
29 #ifdef HAVE_SSL
30 #  include <QSslSocket>
31 #  include "sslserver.h"
32 #else
33 #  include <QTcpSocket>
34 #  include <QTcpServer>
35 #endif
36
37 #include "bufferinfo.h"
38 #include "message.h"
39 #include "oidentdconfiggenerator.h"
40 #include "sessionthread.h"
41 #include "storage.h"
42 #include "types.h"
43
44 class CoreSession;
45 class SessionThread;
46 class SignalProxy;
47 struct NetworkInfo;
48
49 class AbstractSqlMigrationReader;
50 class AbstractSqlMigrationWriter;
51
52 class Core : public QObject
53 {
54     Q_OBJECT
55
56 public:
57     static Core *instance();
58     static void destroy();
59
60     static void saveState();
61     static void restoreState();
62
63     /*** Storage access ***/
64     // These methods are threadsafe.
65
66     //! Store a user setting persistently
67     /**
68      * \param userId       The users Id
69      * \param settingName  The Name of the Setting
70      * \param data         The Value
71      */
72     static inline void setUserSetting(UserId userId, const QString &settingName, const QVariant &data)
73     {
74         instance()->_storage->setUserSetting(userId, settingName, data);
75     }
76
77
78     //! Retrieve a persistent user setting
79     /**
80      * \param userId       The users Id
81      * \param settingName  The Name of the Setting
82      * \param defaultValue Value to return in case it's unset.
83      * \return the Value of the Setting or the default value if it is unset.
84      */
85     static inline QVariant getUserSetting(UserId userId, const QString &settingName, const QVariant &defaultValue = QVariant())
86     {
87         return instance()->_storage->getUserSetting(userId, settingName, defaultValue);
88     }
89
90
91     /* Identity handling */
92     static inline IdentityId createIdentity(UserId user, CoreIdentity &identity)
93     {
94         return instance()->_storage->createIdentity(user, identity);
95     }
96
97
98     static bool updateIdentity(UserId user, const CoreIdentity &identity)
99     {
100         return instance()->_storage->updateIdentity(user, identity);
101     }
102
103
104     static void removeIdentity(UserId user, IdentityId identityId)
105     {
106         instance()->_storage->removeIdentity(user, identityId);
107     }
108
109
110     static QList<CoreIdentity> identities(UserId user)
111     {
112         return instance()->_storage->identities(user);
113     }
114
115
116     //! Create a Network in the Storage and store it's Id in the given NetworkInfo
117     /** \note This method is thredsafe.
118      *
119      *  \param user        The core user
120      *  \param networkInfo a NetworkInfo definition to store the newly created ID in
121      *  \return true if successfull.
122      */
123     static bool createNetwork(UserId user, NetworkInfo &info);
124
125     //! Apply the changes to NetworkInfo info to the storage engine
126     /** \note This method is thredsafe.
127      *
128      *  \param user        The core user
129      *  \param networkInfo The Updated NetworkInfo
130      *  \return true if successfull.
131      */
132     static inline bool updateNetwork(UserId user, const NetworkInfo &info)
133     {
134         return instance()->_storage->updateNetwork(user, info);
135     }
136
137
138     //! Permanently remove a Network and all the data associated with it.
139     /** \note This method is thredsafe.
140      *
141      *  \param user        The core user
142      *  \param networkId   The network to delete
143      *  \return true if successfull.
144      */
145     static inline bool removeNetwork(UserId user, const NetworkId &networkId)
146     {
147         return instance()->_storage->removeNetwork(user, networkId);
148     }
149
150
151     //! Returns a list of all NetworkInfos for the given UserId user
152     /** \note This method is thredsafe.
153      *
154      *  \param user        The core user
155      *  \return QList<NetworkInfo>.
156      */
157     static inline QList<NetworkInfo> networks(UserId user)
158     {
159         return instance()->_storage->networks(user);
160     }
161
162
163     //! Get a list of Networks to restore
164     /** Return a list of networks the user was connected at the time of core shutdown
165      *  \note This method is threadsafe.
166      *
167      *  \param user  The User Id in question
168      */
169     static inline QList<NetworkId> connectedNetworks(UserId user)
170     {
171         return instance()->_storage->connectedNetworks(user);
172     }
173
174
175     //! Update the connected state of a network
176     /** \note This method is threadsafe
177      *
178      *  \param user        The Id of the networks owner
179      *  \param networkId   The Id of the network
180      *  \param isConnected whether the network is connected or not
181      */
182     static inline void setNetworkConnected(UserId user, const NetworkId &networkId, bool isConnected)
183     {
184         return instance()->_storage->setNetworkConnected(user, networkId, isConnected);
185     }
186
187
188     //! Get a hash of channels with their channel keys for a given network
189     /** The keys are channel names and values are passwords (possibly empty)
190      *  \note This method is threadsafe
191      *
192      *  \param user       The id of the networks owner
193      *  \param networkId  The Id of the network
194      */
195     static inline QHash<QString, QString> persistentChannels(UserId user, const NetworkId &networkId)
196     {
197         return instance()->_storage->persistentChannels(user, networkId);
198     }
199
200
201     //! Update the connected state of a channel
202     /** \note This method is threadsafe
203      *
204      *  \param user       The Id of the networks owner
205      *  \param networkId  The Id of the network
206      *  \param channel    The name of the channel
207      *  \param isJoined   whether the channel is connected or not
208      */
209     static inline void setChannelPersistent(UserId user, const NetworkId &networkId, const QString &channel, bool isJoined)
210     {
211         return instance()->_storage->setChannelPersistent(user, networkId, channel, isJoined);
212     }
213
214
215     //! Update the key of a channel
216     /** \note This method is threadsafe
217      *
218      *  \param user       The Id of the networks owner
219      *  \param networkId  The Id of the network
220      *  \param channel    The name of the channel
221      *  \param key        The key of the channel (possibly empty)
222      */
223     static inline void setPersistentChannelKey(UserId user, const NetworkId &networkId, const QString &channel, const QString &key)
224     {
225         return instance()->_storage->setPersistentChannelKey(user, networkId, channel, key);
226     }
227
228
229     //! retrieve last known away message for session restore
230     /** \note This method is threadsafe
231      *
232      *  \param user       The Id of the networks owner
233      *  \param networkId  The Id of the network
234      */
235     static inline QString awayMessage(UserId user, NetworkId networkId)
236     {
237         return instance()->_storage->awayMessage(user, networkId);
238     }
239
240
241     //! Make away message persistent for session restore
242     /** \note This method is threadsafe
243      *
244      *  \param user       The Id of the networks owner
245      *  \param networkId  The Id of the network
246      *  \param awayMsg    The current away message of own user
247      */
248     static inline void setAwayMessage(UserId user, NetworkId networkId, const QString &awayMsg)
249     {
250         return instance()->_storage->setAwayMessage(user, networkId, awayMsg);
251     }
252
253
254     //! retrieve last known user mode for session restore
255     /** \note This method is threadsafe
256      *
257      *  \param user       The Id of the networks owner
258      *  \param networkId  The Id of the network
259      */
260     static inline QString userModes(UserId user, NetworkId networkId)
261     {
262         return instance()->_storage->userModes(user, networkId);
263     }
264
265
266     //! Make our user modes persistent for session restore
267     /** \note This method is threadsafe
268      *
269      *  \param user       The Id of the networks owner
270      *  \param networkId  The Id of the network
271      *  \param userModes  The current user modes of own user
272      */
273     static inline void setUserModes(UserId user, NetworkId networkId, const QString &userModes)
274     {
275         return instance()->_storage->setUserModes(user, networkId, userModes);
276     }
277
278
279     //! Get the unique BufferInfo for the given combination of network and buffername for a user.
280     /** \note This method is threadsafe.
281      *
282      *  \param user      The core user who owns this buffername
283      *  \param networkId The network id
284      *  \param type      The type of the buffer (StatusBuffer, Channel, etc.)
285      *  \param buffer    The buffer name (if empty, the net's status buffer is returned)
286      *  \param create    Whether or not the buffer should be created if it doesnt exist
287      *  \return The BufferInfo corresponding to the given network and buffer name, or 0 if not found
288      */
289     static inline BufferInfo bufferInfo(UserId user, const NetworkId &networkId, BufferInfo::Type type, const QString &buffer = "", bool create = true)
290     {
291         return instance()->_storage->bufferInfo(user, networkId, type, buffer, create);
292     }
293
294
295     //! Get the unique BufferInfo for a bufferId
296     /** \note This method is threadsafe
297      *  \param user      The core user who owns this buffername
298      *  \param bufferId  The id of the buffer
299      *  \return The BufferInfo corresponding to the given buffer id, or an invalid BufferInfo if not found.
300      */
301     static inline BufferInfo getBufferInfo(UserId user, const BufferId &bufferId)
302     {
303         return instance()->_storage->getBufferInfo(user, bufferId);
304     }
305
306
307     //! Store a Message in the storage backend and set it's unique Id.
308     /** \note This method is threadsafe.
309      *
310      *  \param message The message object to be stored
311      *  \return true on success
312      */
313     static inline bool storeMessage(Message &message)
314     {
315         return instance()->_storage->logMessage(message);
316     }
317
318
319     //! Store a list of Messages in the storage backend and set their unique Id.
320     /** \note This method is threadsafe.
321      *
322      *  \param messages The list message objects to be stored
323      *  \return true on success
324      */
325     static inline bool storeMessages(MessageList &messages)
326     {
327         return instance()->_storage->logMessages(messages);
328     }
329
330
331     //! Request a certain number messages stored in a given buffer.
332     /** \param buffer   The buffer we request messages from
333      *  \param first    if != -1 return only messages with a MsgId >= first
334      *  \param last     if != -1 return only messages with a MsgId < last
335      *  \param limit    if != -1 limit the returned list to a max of \limit entries
336      *  \return The requested list of messages
337      */
338     static inline QList<Message> requestMsgs(UserId user, BufferId bufferId, MsgId first = -1, MsgId last = -1, int limit = -1)
339     {
340         return instance()->_storage->requestMsgs(user, bufferId, first, last, limit);
341     }
342
343
344     //! Request a certain number of messages across all buffers
345     /** \param first    if != -1 return only messages with a MsgId >= first
346      *  \param last     if != -1 return only messages with a MsgId < last
347      *  \param limit    Max amount of messages
348      *  \return The requested list of messages
349      */
350     static inline QList<Message> requestAllMsgs(UserId user, MsgId first = -1, MsgId last = -1, int limit = -1)
351     {
352         return instance()->_storage->requestAllMsgs(user, first, last, limit);
353     }
354
355
356     //! Request a list of all buffers known to a user.
357     /** This method is used to get a list of all buffers we have stored a backlog from.
358      *  \note This method is threadsafe.
359      *
360      *  \param user  The user whose buffers we request
361      *  \return A list of the BufferInfos for all buffers as requested
362      */
363     static inline QList<BufferInfo> requestBuffers(UserId user)
364     {
365         return instance()->_storage->requestBuffers(user);
366     }
367
368
369     //! Request a list of BufferIds for a given NetworkId
370     /** \note This method is threadsafe.
371      *
372      *  \param user  The user whose buffers we request
373      *  \param networkId  The NetworkId of the network in question
374      *  \return List of BufferIds belonging to the Network
375      */
376     static inline QList<BufferId> requestBufferIdsForNetwork(UserId user, NetworkId networkId)
377     {
378         return instance()->_storage->requestBufferIdsForNetwork(user, networkId);
379     }
380
381
382     //! Remove permanently a buffer and it's content from the storage backend
383     /** This call cannot be reverted!
384      *  \note This method is threadsafe.
385      *
386      *  \param user      The user who is the owner of the buffer
387      *  \param bufferId  The bufferId
388      *  \return true if successfull
389      */
390     static inline bool removeBuffer(const UserId &user, const BufferId &bufferId)
391     {
392         return instance()->_storage->removeBuffer(user, bufferId);
393     }
394
395
396     //! Rename a Buffer
397     /** \note This method is threadsafe.
398      *  \param user      The id of the buffer owner
399      *  \param bufferId  The bufferId
400      *  \param newName   The new name of the buffer
401      *  \return true if successfull
402      */
403     static inline bool renameBuffer(const UserId &user, const BufferId &bufferId, const QString &newName)
404     {
405         return instance()->_storage->renameBuffer(user, bufferId, newName);
406     }
407
408
409     //! Merge the content of two Buffers permanently. This cannot be reversed!
410     /** \note This method is threadsafe.
411      *  \param user      The id of the buffer owner
412      *  \param bufferId1 The bufferId of the remaining buffer
413      *  \param bufferId2 The buffer that is about to be removed
414      *  \return true if successfulln
415      */
416     static inline bool mergeBuffersPermanently(const UserId &user, const BufferId &bufferId1, const BufferId &bufferId2)
417     {
418         return instance()->_storage->mergeBuffersPermanently(user, bufferId1, bufferId2);
419     }
420
421
422     //! Update the LastSeenDate for a Buffer
423     /** This Method is used to make the LastSeenDate of a Buffer persistent
424      *  \note This method is threadsafe.
425      *
426      * \param user      The Owner of that Buffer
427      * \param bufferId  The buffer id
428      * \param MsgId     The Message id of the message that has been just seen
429      */
430     static inline void setBufferLastSeenMsg(UserId user, const BufferId &bufferId, const MsgId &msgId)
431     {
432         return instance()->_storage->setBufferLastSeenMsg(user, bufferId, msgId);
433     }
434
435
436     //! Get a Hash of all last seen message ids
437     /** This Method is called when the Quassel Core is started to restore the lastSeenMsgIds
438      *  \note This method is threadsafe.
439      *
440      * \param user      The Owner of the buffers
441      */
442     static inline QHash<BufferId, MsgId> bufferLastSeenMsgIds(UserId user)
443     {
444         return instance()->_storage->bufferLastSeenMsgIds(user);
445     }
446
447
448     //! Update the MarkerLineMsgId for a Buffer
449     /** This Method is used to make the marker line position of a Buffer persistent
450      *  \note This method is threadsafe.
451      *
452      * \param user      The Owner of that Buffer
453      * \param bufferId  The buffer id
454      * \param MsgId     The Message id where the marker line should be placed
455      */
456     static inline void setBufferMarkerLineMsg(UserId user, const BufferId &bufferId, const MsgId &msgId)
457     {
458         return instance()->_storage->setBufferMarkerLineMsg(user, bufferId, msgId);
459     }
460
461
462     //! Get a Hash of all marker line message ids
463     /** This Method is called when the Quassel Core is started to restore the MarkerLineMsgIds
464      *  \note This method is threadsafe.
465      *
466      * \param user      The Owner of the buffers
467      */
468     static inline QHash<BufferId, MsgId> bufferMarkerLineMsgIds(UserId user)
469     {
470         return instance()->_storage->bufferMarkerLineMsgIds(user);
471     }
472
473
474     const QDateTime &startTime() const { return _startTime; }
475
476     static inline QTimer &syncTimer() { return instance()->_storageSyncTimer; }
477
478     inline OidentdConfigGenerator *oidentdConfigGenerator() const { return _oidentdConfigGenerator; }
479
480     static const int AddClientEventId;
481
482 public slots:
483     //! Make storage data persistent
484     /** \note This method is threadsafe.
485      */
486     void syncStorage();
487     void setupInternalClientSession(SignalProxy *proxy);
488
489 signals:
490     //! Sent when a BufferInfo is updated in storage.
491     void bufferInfoUpdated(UserId user, const BufferInfo &info);
492
493     //! Relay From CoreSession::sessionState(const QVariant &). Used for internal connection only
494     void sessionState(const QVariant &);
495
496 protected:
497     virtual void customEvent(QEvent *event);
498
499 private slots:
500     bool startListening();
501     void stopListening(const QString &msg = QString());
502     void incomingConnection();
503     void clientHasData();
504     void clientDisconnected();
505
506     bool initStorage(const QString &backend, QVariantMap settings, bool setup = false);
507     bool initStorage(QVariantMap dbSettings, bool setup = false);
508
509 #ifdef HAVE_SSL
510     void sslErrors(const QList<QSslError> &errors);
511 #endif
512     void socketError(QAbstractSocket::SocketError);
513
514 private:
515     Core();
516     ~Core();
517     void init();
518     static Core *instanceptr;
519
520     SessionThread *createSession(UserId userId, bool restoreState = false);
521     void setupClientSession(QTcpSocket *socket, UserId uid);
522     void addClientHelper(QTcpSocket *socket, UserId uid);
523     void processClientMessage(QTcpSocket *socket, const QVariantMap &msg);
524     //void processCoreSetup(QTcpSocket *socket, QVariantMap &msg);
525     QString setupCoreForInternalUsage();
526     QString setupCore(QVariantMap setupData);
527
528     void registerStorageBackends();
529     bool registerStorageBackend(Storage *);
530     void unregisterStorageBackends();
531     void unregisterStorageBackend(Storage *);
532     bool selectBackend(const QString &backend);
533     void createUser();
534     void changeUserPass(const QString &username);
535     void saveBackendSettings(const QString &backend, const QVariantMap &settings);
536     QVariantMap promptForSettings(const Storage *storage);
537
538     QHash<UserId, SessionThread *> sessions;
539     Storage *_storage;
540     QTimer _storageSyncTimer;
541
542 #ifdef HAVE_SSL
543     SslServer _server, _v6server;
544 #else
545     QTcpServer _server, _v6server;
546 #endif
547
548     OidentdConfigGenerator *_oidentdConfigGenerator;
549
550     QHash<QTcpSocket *, quint32> blocksizes;
551     QHash<QTcpSocket *, QVariantMap> clientInfo;
552
553     QHash<QString, Storage *> _storageBackends;
554
555     QDateTime _startTime;
556
557     bool _configured;
558
559     static AbstractSqlMigrationReader *getMigrationReader(Storage *storage);
560     static AbstractSqlMigrationWriter *getMigrationWriter(Storage *storage);
561     static void stdInEcho(bool on);
562     static inline void enableStdInEcho() { stdInEcho(true); }
563     static inline void disableStdInEcho() { stdInEcho(false); }
564 };
565
566
567 #endif