Reworking handling of Prepared Queries in PostgreSQL
[quassel.git] / src / core / corebuffersyncer.cpp
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 #include "corebuffersyncer.h"
22
23 #include "core.h"
24 #include "coresession.h"
25 #include "corenetwork.h"
26 #include "ircchannel.h"
27
28 class PurgeEvent : public QEvent {
29 public:
30   PurgeEvent() : QEvent(QEvent::User) {}
31 };
32
33 INIT_SYNCABLE_OBJECT(CoreBufferSyncer)
34 CoreBufferSyncer::CoreBufferSyncer(CoreSession *parent)
35   : BufferSyncer(Core::bufferLastSeenMsgIds(parent->user()), Core::bufferMarkerLineMsgIds(parent->user()), parent),
36     _coreSession(parent),
37     _purgeBuffers(false)
38 {
39 }
40
41 void CoreBufferSyncer::requestSetLastSeenMsg(BufferId buffer, const MsgId &msgId) {
42   if(setLastSeenMsg(buffer, msgId))
43     dirtyLastSeenBuffers << buffer;
44 }
45
46 void CoreBufferSyncer::requestSetMarkerLine(BufferId buffer, const MsgId &msgId) {
47   if(setMarkerLine(buffer, msgId))
48     dirtyMarkerLineBuffers << buffer;
49 }
50
51 void CoreBufferSyncer::storeDirtyIds() {
52   UserId userId = _coreSession->user();
53   MsgId msgId;
54   foreach(BufferId bufferId, dirtyLastSeenBuffers) {
55     msgId = lastSeenMsg(bufferId);
56     if(msgId.isValid())
57       Core::setBufferLastSeenMsg(userId, bufferId, msgId);
58   }
59
60   foreach(BufferId bufferId, dirtyMarkerLineBuffers) {
61     msgId = markerLine(bufferId);
62     if(msgId.isValid())
63       Core::setBufferMarkerLineMsg(userId, bufferId, msgId);
64   }
65
66   dirtyLastSeenBuffers.clear();
67   dirtyMarkerLineBuffers.clear();
68 }
69
70 void CoreBufferSyncer::removeBuffer(BufferId bufferId) {
71   BufferInfo bufferInfo = Core::getBufferInfo(_coreSession->user(), bufferId);
72   if(!bufferInfo.isValid()) {
73     qWarning() << "CoreBufferSyncer::removeBuffer(): invalid BufferId:" << bufferId << "for User:" << _coreSession->user();
74     return;
75   }
76
77   if(bufferInfo.type() == BufferInfo::StatusBuffer) {
78     qWarning() << "CoreBufferSyncer::removeBuffer(): Status Buffers cannot be removed!";
79     return;
80   }
81
82   if(bufferInfo.type() == BufferInfo::ChannelBuffer) {
83     CoreNetwork *net = _coreSession->network(bufferInfo.networkId());
84     if(!net) {
85       qWarning() << "CoreBufferSyncer::removeBuffer(): Received BufferInfo with unknown networkId!";
86       return;
87     }
88     IrcChannel *chan = net->ircChannel(bufferInfo.bufferName());
89     if(chan) {
90       qWarning() << "CoreBufferSyncer::removeBuffer(): Unable to remove Buffer for joined Channel:" << bufferInfo.bufferName();
91       return;
92     }
93   }
94   if(Core::removeBuffer(_coreSession->user(), bufferId))
95     BufferSyncer::removeBuffer(bufferId);
96 }
97
98 void CoreBufferSyncer::renameBuffer(BufferId bufferId, QString newName) {
99   BufferInfo bufferInfo = Core::getBufferInfo(_coreSession->user(), bufferId);
100   if(!bufferInfo.isValid()) {
101     qWarning() << "CoreBufferSyncer::renameBuffer(): invalid BufferId:" << bufferId << "for User:" << _coreSession->user();
102     return;
103   }
104
105   if(bufferInfo.type() != BufferInfo::QueryBuffer) {
106     qWarning() << "CoreBufferSyncer::renameBuffer(): only QueryBuffers can be renamed" << bufferId;
107     return;
108   }
109
110   if(Core::renameBuffer(_coreSession->user(), bufferId, newName))
111     BufferSyncer::renameBuffer(bufferId, newName);
112 }
113
114 void CoreBufferSyncer::mergeBuffersPermanently(BufferId bufferId1, BufferId bufferId2) {
115   BufferInfo bufferInfo1 = Core::getBufferInfo(_coreSession->user(), bufferId1);
116   BufferInfo bufferInfo2 = Core::getBufferInfo(_coreSession->user(), bufferId2);
117   if(!bufferInfo1.isValid() || !bufferInfo2.isValid()) {
118     qWarning() << "CoreBufferSyncer::mergeBufferPermanently(): invalid BufferIds:" << bufferId1 << bufferId2 << "for User:" << _coreSession->user();
119     return;
120   }
121
122   if(bufferInfo1.type() != BufferInfo::QueryBuffer || bufferInfo2.type() != BufferInfo::QueryBuffer) {
123     qWarning() << "CoreBufferSyncer::mergeBufferPermanently(): only QueryBuffers can be merged!" << bufferId1 << bufferId2;
124     return;
125   }
126
127   if(Core::mergeBuffersPermanently(_coreSession->user(), bufferId1, bufferId2)) {
128     BufferSyncer::mergeBuffersPermanently(bufferId1, bufferId2);
129   }
130 }
131
132 void CoreBufferSyncer::customEvent(QEvent *event) {
133   if(event->type() != QEvent::User)
134     return;
135
136   purgeBufferIds();
137   event->accept();
138 }
139
140 void CoreBufferSyncer::requestPurgeBufferIds() {
141   if(_purgeBuffers)
142     return;
143
144   _purgeBuffers = true;
145   QCoreApplication::postEvent(this, new PurgeEvent());
146 }
147
148 void CoreBufferSyncer::purgeBufferIds() {
149   _purgeBuffers = false;
150   QList<BufferInfo> bufferInfos = Core::requestBuffers(_coreSession->user());
151   QSet<BufferId> actualBuffers;
152   foreach(BufferInfo bufferInfo, bufferInfos) {
153     actualBuffers << bufferInfo.bufferId();
154   }
155
156   QSet<BufferId> storedIds = lastSeenBufferIds().toSet() + markerLineBufferIds().toSet();
157   foreach(BufferId bufferId, storedIds) {
158     if(!actualBuffers.contains(bufferId)) {
159       BufferSyncer::removeBuffer(bufferId);
160     }
161   }
162 }