Akonadi

connection.h
1/***************************************************************************
2 * SPDX-FileCopyrightText: 2006 Till Adam <adam@kde.org> *
3 * *
4 * SPDX-License-Identifier: LGPL-2.0-or-later *
5 ***************************************************************************/
6
7#pragma once
8
9#include <QElapsedTimer>
10#include <QLocalSocket>
11#include <QThread>
12#include <QTimer>
13
14#include "akonadi.h"
15#include "akthread.h"
16#include "commandcontext.h"
17#include "entities.h"
18#include "global.h"
19#include "tracer.h"
20
21#include "private/datastream_p_p.h"
22#include "private/protocol_p.h"
23
24#include <memory>
25
26namespace Akonadi
27{
28namespace Server
29{
30class Handler;
31class Response;
32class DataStore;
33class Collection;
34
35/**
36 An Connection represents one connection of a client to the server.
37*/
38class Connection : public AkThread
39{
41protected:
42 /**
43 * Use AkThread::create() to construct and start a new connection thread.
44 */
45 explicit Connection(quintptr socketDescriptor, AkonadiServer &akonadi);
46
47public:
48 ~Connection() override;
49
50 virtual DataStore *storageBackend();
51
52 const CommandContext &context() const;
53 void setContext(const CommandContext &context);
54
55 AkonadiServer &akonadi() const
56 {
57 return m_akonadi;
58 }
59
60 /**
61 Returns @c true if this connection belongs to the owning resource of @p item.
62 */
63 bool isOwnerResource(const PimItem &item) const;
64 bool isOwnerResource(const Collection &collection) const;
65
66 void setSessionId(const QByteArray &id);
67 QByteArray sessionId() const;
68
69 /** Returns @c true if permanent cache verification is enabled. */
70 bool verifyCacheOnRetrieval() const;
71
72 Protocol::CommandPtr readCommand();
73
74 void setState(ConnectionState state);
75
76 template<typename T>
77 inline typename std::enable_if<std::is_base_of<Protocol::Command, T>::value>::type sendResponse(T &&response);
78
79 void sendResponse(qint64 tag, const Protocol::CommandPtr &response);
80
82 void disconnected();
83 void connectionClosing();
84
85protected Q_SLOTS:
86 void handleIncomingData();
87
88 void slotConnectionIdle();
89 void slotSocketDisconnected();
90 void slotSendHello();
91
92 void init() override;
93 void quit() override;
94
95protected:
96 Connection(AkonadiServer &akonadi); // used for testing
97
98 std::unique_ptr<Handler> findHandlerForCommand(Protocol::Command::Type cmd);
99
100 qint64 currentTag() const;
101
102protected:
103 quintptr m_socketDescriptor = {};
104 AkonadiServer &m_akonadi;
105 std::unique_ptr<QLocalSocket> m_socket;
106 std::unique_ptr<Handler> m_currentHandler;
107 std::unique_ptr<QTimer> m_idleTimer;
108
109 ConnectionState m_connectionState = NonAuthenticated;
110
111 mutable DataStore *m_backend = nullptr;
112 QList<QByteArray> m_statusMessageQueue;
113 QString m_identifier;
114 QByteArray m_sessionId;
115 bool m_verifyCacheOnRetrieval = false;
116 CommandContext m_context;
117
118 QElapsedTimer m_time;
119 qint64 m_totalTime = 0;
120 QHash<QString, qint64> m_totalTimeByHandler;
121 QHash<QString, qint64> m_executionsByHandler;
122
123 bool m_connectionClosing = false;
124
125private:
126 void parseStream(const Protocol::CommandPtr &cmd);
127 template<typename T>
128 inline typename std::enable_if<std::is_base_of<Protocol::Command, T>::value>::type sendResponse(qint64 tag, T &&response);
129
130 /** For debugging */
131 void startTime();
132 void stopTime(const QString &identifier);
133 void reportTime() const;
134 bool m_reportTime = false;
135};
136
137template<typename T>
138inline typename std::enable_if<std::is_base_of<Protocol::Command, T>::value>::type Connection::sendResponse(T &&response)
139{
140 sendResponse<T>(currentTag(), std::move(response));
141}
142
143template<typename T>
144inline typename std::enable_if<std::is_base_of<Protocol::Command, T>::value>::type Connection::sendResponse(qint64 tag, T &&response)
145{
146 if (m_akonadi.tracer().currentTracer() != QLatin1StringView("null")) {
147 m_akonadi.tracer().connectionOutput(m_identifier, tag, response);
148 }
149 Protocol::DataStream stream(m_socket.get());
150 stream << tag;
151 stream << std::move(response);
152 stream.flush();
153 if (!m_socket->waitForBytesWritten()) {
154 if (m_socket->state() == QLocalSocket::ConnectedState) {
155 throw ProtocolException("Server write timeout");
156 } else {
157 // The client has disconnected before we managed to send our response,
158 // which is not an error
159 }
160 }
161}
162
163} // namespace Server
164} // namespace Akonadi
Represents a collection of PIM items.
Definition collection.h:62
An Connection represents one connection of a client to the server.
Definition connection.h:39
bool verifyCacheOnRetrieval() const
Returns true if permanent cache verification is enabled.
bool isOwnerResource(const PimItem &item) const
Returns true if this connection belongs to the owning resource of item.
Connection(quintptr socketDescriptor, AkonadiServer &akonadi)
Use AkThread::create() to construct and start a new connection thread.
This class handles all the database access.
Definition datastore.h:95
QString currentTracer() const
Returns the currently activated tracer type.
Definition tracer.cpp:138
Helper integration between Akonadi and Qt.
Q_OBJECTQ_OBJECT
Q_SIGNALSQ_SIGNALS
Q_SLOTSQ_SLOTS
T qobject_cast(QObject *object)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:38 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.