Commit f02236bd authored by Daniel Vrátil's avatar Daniel Vrátil 🤖

Port the remaining Akonadi jobs to the new Protocol API

parent d5ab6167
......@@ -26,7 +26,6 @@
#include "notificationsourceinterface.h"
#include "job_p.h"
#include "itemmovejob.h"
#include "movejobimpl_p.h"
#include "collection.h"
#include "item.h"
......@@ -156,6 +155,7 @@ void ChangeMediator::do_unregisterSession(const QByteArray &id)
void ChangeMediator::do_beginMoveItems(JobPrivate *movePrivate, const QByteArray &id)
{
#if 0
if (!m_sessions.contains(id)) {
return;
}
......@@ -179,7 +179,7 @@ void ChangeMediator::do_beginMoveItems(JobPrivate *movePrivate, const QByteArray
}
// if (itemsDataAvailable.isEmpty())
#endif
}
void ChangeMediator::do_itemsMoved(const Item::List &items, const Collection &sourceParent, const QByteArray &id)
......
......@@ -93,7 +93,7 @@ public:
protected:
void doStart() Q_DECL_OVERRIDE;
void doHandleResponse(const QByteArray &tag, const QByteArray &data) Q_DECL_OVERRIDE;
void doHandleResponse(qint64 tag, const Protocol::Command &response) Q_DECL_OVERRIDE;
private:
Q_DECLARE_PRIVATE(CollectionStatisticsJob)
......
......@@ -22,13 +22,13 @@
#include "attributefactory.h"
#include "collection.h"
#include "collectionselectjob_p.h"
#include <akonadi/private/imapparser_p.h>
#include "itemfetchscope.h"
#include "job_p.h"
#include <akonadi/private/protocol_p.h>
#include "protocolhelper_p.h"
#include "session_p.h"
#include <akonadi/private/protocol_p.h>
#include <qdebug.h>
#include <QtCore/QStringList>
......@@ -169,64 +169,55 @@ void ItemFetchJob::doStart()
{
Q_D(ItemFetchJob);
QByteArray command = d->newTag();
try {
command += ProtocolHelper::commandContextToByteArray(d->mCollection, d->mTag, d->mRequestedItems, AKONADI_CMD_ITEMFETCH);
d->sendCommand(Protocol::FetchItemsCommand(
ProtocolHelper::entitySetToScope(d->mRequestedItems),
ProtocolHelper::commandContextToProtocol(d->mCollection, d->mTag, d->mRequestedItems),
ProtocolHelper::itemFetchScopeToProtocol(d->mFetchScope)));
} catch (const Akonadi::Exception &e) {
setError(Job::Unknown);
setErrorText(QString::fromUtf8(e.what()));
emitResult();
return;
}
// This is only required for 4.10
if (d->protocolVersion() < 30) {
if (d->mFetchScope.ignoreRetrievalErrors()) {
qDebug() << "IGNOREERRORS is not available with this version of Akonadi server";
}
d->mFetchScope.setIgnoreRetrievalErrors(false);
}
command += ProtocolHelper::itemFetchScopeToByteArray(d->mFetchScope);
d->writeData(command);
}
void ItemFetchJob::doHandleResponse(const QByteArray &tag, const QByteArray &data)
void ItemFetchJob::doHandleResponse(qint64 tag, const Protocol::Command &response)
{
Q_D(ItemFetchJob);
if (tag == "*") {
int begin = data.indexOf("FETCH");
if (begin >= 0) {
if (!response.isResponse() || response.type() != Protocol::Command::FetchItems) {
Job::doHandleResponse(tag, response);
return;
}
// split fetch response into key/value pairs
QList<QByteArray> fetchResponse;
ImapParser::parseParenthesizedList(data, fetchResponse, begin + 6);
Protocol::FetchItemsResponse resp(response);
// Invalid ID marks the last part of the response
if (resp.id() < 0) {
emitResult();
return;
}
Item item;
ProtocolHelper::parseItemFetchResult(fetchResponse, item, d->mValuePool);
if (!item.isValid()) {
return;
}
const Item item = ProtocolHelper::parseItemFetchResult(resp, d->mValuePool);
if (!item.isValid()) {
return;
}
d->mCount++;
d->mCount++;
if (d->mDeliveryOptions & ItemGetter) {
d->mResultItems.append(item);
}
if (d->mDeliveryOptions & ItemGetter) {
d->mResultItems.append(item);
}
if (d->mDeliveryOptions & EmitItemsInBatches) {
d->mPendingItems.append(item);
if (!d->mEmitTimer->isActive()) {
d->mEmitTimer->start();
}
} else if (d->mDeliveryOptions & EmitItemsIndividually) {
emit itemsReceived(Item::List() << item);
}
return;
if (d->mDeliveryOptions & EmitItemsInBatches) {
d->mPendingItems.append(item);
if (!d->mEmitTimer->isActive()) {
d->mEmitTimer->start();
}
} else if (d->mDeliveryOptions & EmitItemsIndividually) {
emit itemsReceived(Item::List() << item);
}
qDebug() << "Unhandled response: " << tag << data;
}
Item::List ItemFetchJob::items() const
......
......@@ -19,12 +19,13 @@
#include "itemsearchjob.h"
#include <akonadi/private/imapparser_p.h>
#include "itemfetchscope.h"
#include "job_p.h"
#include "protocolhelper_p.h"
#include "searchquery.h"
#include <akonadi/private/protocol_p.h>
#include <QtCore/QTimer>
#include <QThreadStorage>
......@@ -64,7 +65,7 @@ public:
mPendingItems.clear();
}
}
QString jobDebuggingString() const Q_DECL_OVERRIDE /*Q_DECL_OVERRIDE*/ {
QString jobDebuggingString() const Q_DECL_OVERRIDE {
QStringList flags;
if ( mRecursive ) {
flags.append( QStringLiteral( "recursive" ) );
......@@ -208,57 +209,43 @@ void ItemSearchJob::doStart()
{
Q_D(ItemSearchJob);
QByteArray command = d->newTag() + " SEARCH ";
if (!d->mMimeTypes.isEmpty()) {
command += "MIMETYPE (" + d->mMimeTypes.join(QStringLiteral(" ")).toLatin1() + ") ";
}
Protocol::SearchCommand cmd;
cmd.setMimeTypes(d->mMimeTypes);
if (!d->mCollections.isEmpty()) {
command += "COLLECTIONS (";
Q_FOREACH (const Collection &collection, d->mCollections) {
command += QByteArray::number(collection.id()) + ' ';
QVector<qint64> ids;
ids.reserve(d->mCollections.size());
for (const Collection &col : d->mCollections) {
ids << col.id();
}
command += ") ";
}
if (d->mRecursive) {
command += "RECURSIVE ";
}
if (d->mRemote) {
command += "REMOTE ";
cmd.setCollections(ids);
}
cmd.setRecursive(d->mRecursive);
cmd.setRemote(d->mRemote);
cmd.setQuery(d->mQuery.toJSON());
cmd.setFetchScope(ProtocolHelper::itemFetchScopeToProtocol(d->mFetchScope));
command += "QUERY " + ImapParser::quote(d->mQuery.toJSON());
command += ' ' + ProtocolHelper::itemFetchScopeToByteArray(d->mFetchScope);
command += '\n';
d->writeData(command);
d->sendCommand(cmd);
}
void ItemSearchJob::doHandleResponse(const QByteArray &tag, const QByteArray &data)
void ItemSearchJob::doHandleResponse(qint64 tag, const Protocol::Command &response)
{
Q_D(ItemSearchJob);
if (tag == "*") {
int begin = data.indexOf("SEARCH");
if (begin >= 0) {
// split fetch response into key/value pairs
QList<QByteArray> fetchResponse;
ImapParser::parseParenthesizedList(data, fetchResponse, begin + 7);
Item item;
ProtocolHelper::parseItemFetchResult(fetchResponse, item);
if (!item.isValid()) {
return;
}
d->mItems.append(item);
d->mPendingItems.append(item);
if (!d->mEmitTimer->isActive()) {
d->mEmitTimer->start();
}
if (response.isResponse() && response.type() == Protocol::Command::FetchItems) {
const Item item = ProtocolHelper::parseItemFetchResult(response);
if (!item.isValid()) {
return;
}
d->mItems.append(item);
d->mPendingItems.append(item);
if (!d->mEmitTimer->isActive()) {
d->mEmitTimer->start();
}
} else if (response.isResponse() && response.type() == Protocol::Command::Search) {
emitResult();
} else {
Job::doHandleResponse(tag, response);
}
qDebug() << "Unhandled response: " << tag << data;
}
Item::List ItemSearchJob::items() const
......
......@@ -49,5 +49,11 @@ LinkJob::~LinkJob()
void LinkJob::doStart()
{
Q_D(LinkJob);
d->sendCommand("LINK");
d->sendCommand(Protocol::LinkItemsCommand::Link);
}
void LinkJob::doHandleResponse(qint64 tag, const Protocol::Command &response)
{
d->handleResponse(tag, response);
}
......@@ -84,6 +84,7 @@ public:
protected:
void doStart() Q_DECL_OVERRIDE;
void doHandleResponse(qint64 tag, const Protocol::Command &response) Q_DECL_OVERRIDE;
private:
Q_DECLARE_PRIVATE(LinkJob)
......
......@@ -26,6 +26,8 @@
#include "job_p.h"
#include "protocolhelper_p.h"
#include <akonadi/private/protocol_p.h>
#include <qdebug.h>
#include <KLocalizedString>
......@@ -40,7 +42,7 @@ public:
{
}
inline void sendCommand(const char *asapCommand)
inline void sendCommand(Protocol::LinkItemsCommand::Action action)
{
LinkJob *q = static_cast<LinkJob *>(q_func()); // Job would be enough already, but then we don't have access to the non-public stuff...
if (objectsToLink.isEmpty()) {
......@@ -54,27 +56,26 @@ public:
return;
}
QByteArray command = newTag();
try {
command += ProtocolHelper::entitySetToByteArray(Collection::List() << destination, asapCommand);
sendCommand(Protocol::LinkItemsCommand(action,
ProtocolHelper::entitySetToScope(objectsToLink),
ProtocolHelper::entityToScope(destination)));
} catch (const std::exception &e) {
q->setError(Job::Unknown);
q->setErrorText(QString::fromUtf8(e.what()));
q->emitResult();
return;
}
}
try {
command += ProtocolHelper::entitySetToByteArray(objectsToLink, QByteArray());
} catch (const std::exception &e) {
q->setError(Job::Unknown);
q->setErrorText(QString::fromUtf8(e.what()));
inline void handleResponse(qint64 tag, const Protocol::Command &response)
{
LinkJob *q = static_cast<LinkJob *>(q_func());
if (!response.isResponse() || response.type() != Protocol::Command::LinkItems) {
q->Job::doHandleResponse(tag, response);
} else {
q->emitResult();
return;
}
command += '\n';
writeData(command);
}
Item::List objectsToLink;
......
/*
Copyright (c) 2008,2009 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef AKONADI_MOVEJOBIMPL_P_H
#define AKONADI_MOVEJOBIMPL_P_H
#include "collection.h"
#include "job.h"
#include "job_p.h"
#include "protocolhelper_p.h"
#include <akonadi/private/protocol_p.h>
#include <KLocalizedString>
namespace Akonadi {
/** Shared implementation details between item and collection move jobs. */
template <typename T, typename MoveJob> class MoveJobImpl : public JobPrivate
{
public:
MoveJobImpl(Job *parent)
: JobPrivate(parent)
{
}
inline void sendCommand(const char *asapCommand)
{
MoveJob *q = static_cast<MoveJob *>(q_func()); // Job would be enough already, but then we don't have access to the non-public stuff...
if (objectsToMove.isEmpty()) {
q->setError(Job::Unknown);
q->setErrorText(i18n("No objects specified for moving"));
q->emitResult();
return;
}
if (!destination.isValid() && destination.remoteId().isEmpty()) {
q->setError(Job::Unknown);
q->setErrorText(i18n("No valid destination specified"));
q->emitResult();
return;
}
QByteArray command = newTag();
try {
command += ProtocolHelper::entitySetToByteArray(objectsToMove, asapCommand);
} catch (const std::exception &e) {
q->setError(Job::Unknown);
q->setErrorText(QString::fromUtf8(e.what()));
q->emitResult();
return;
}
command += ' ';
// with all the checks done before this indicates now whether this is a UID or RID based operation
if (objectsToMove.first().isValid()) {
command += QByteArray::number(destination.id());
} else {
command += ImapParser::quote(destination.remoteId().toUtf8());
}
// Source is optional
if (source.isValid()) {
command += ' ' + QByteArray::number(source.id());
} else if (!source.remoteId().isEmpty()) {
command += ' ' + ImapParser::quote(source.remoteId().toUtf8());
}
command += '\n';
writeData(command);
}
typename T::List objectsToMove;
Collection destination;
Collection source;
};
}
#endif
......@@ -23,6 +23,8 @@
#include "protocolhelper_p.h"
#include <KLocalizedString>
#include <akonadi/private/protocol_p.h>
using namespace Akonadi;
struct Akonadi::RelationCreateJobPrivate : public JobPrivate
......@@ -54,29 +56,19 @@ void RelationCreateJob::doStart()
return;
}
QByteArray command = d->newTag() + " UID RELATIONSTORE ";
QList<QByteArray> list;
list << "LEFT";
list << QByteArray::number(d->mRelation.left().id());
list << "RIGHT";
list << QByteArray::number(d->mRelation.right().id());
list << "TYPE";
list << ImapParser::quote(d->mRelation.type());
if (!d->mRelation.remoteId().isEmpty()) {
list << "REMOTEID";
list << d->mRelation.remoteId();
}
command += ImapParser::join(list, " ") + "\n";
d->writeData(command);
d->sendCommand(Protocol::ModifyRelationCommand(d->mRelation.left(),
d->mRelation.right(),
d->mRelation.type(),
d->mRelation.remoteId()));
}
void RelationCreateJob::doHandleResponse(const QByteArray &tag, const QByteArray &data)
void RelationCreateJob::doHandleResponse(qint64 tag, const Protocol::Command &response)
{
Q_D(RelationCreateJob);
qWarning() << "Unhandled response: " << tag << data;
if (!response.isResponse() || response.type() != Protocol::Command::ModifyRelation) {
Job::doHandleResponse(tag, response);
} else {
emitResult();
}
}
Relation RelationCreateJob::relation() const
......
......@@ -51,7 +51,7 @@ public:
protected:
void doStart() Q_DECL_OVERRIDE;
void doHandleResponse(const QByteArray &tag, const QByteArray &data) Q_DECL_OVERRIDE;
void doHandleResponse(qint64 tag, const Protocol::Command &response) Q_DECL_OVERRIDE;
private:
Q_DECLARE_PRIVATE(RelationCreateJob)
......
......@@ -23,6 +23,8 @@
#include "protocolhelper_p.h"
#include <KLocalizedString>
#include <akonadi/private/protocol_p.h>
using namespace Akonadi;
struct Akonadi::RelationDeleteJobPrivate : public JobPrivate
......@@ -54,27 +56,18 @@ void RelationDeleteJob::doStart()
return;
}
QByteArray command = d->newTag() + " UID RELATIONREMOVE ";
QList<QByteArray> list;
list << "LEFT";
list << QByteArray::number(d->mRelation.left().id());
list << "RIGHT";
list << QByteArray::number(d->mRelation.right().id());
if (!d->mRelation.type().isEmpty()) {
list << "TYPE";
list << ImapParser::quote(d->mRelation.type());
}
command += ImapParser::join(list, " ") + "\n";
d->writeData(command);
d->sendCommand(Protocol::RemoveRelationsCommand(d->mRelation.left(),
d->mRelation.right(),
d->mRelation.type()));
}
void RelationDeleteJob::doHandleResponse(const QByteArray &tag, const QByteArray &data)
void RelationDeleteJob::doHandleResponse(qint64 tag, const Protocol::Command &response)
{
Q_D(RelationDeleteJob);
qWarning() << "Unhandled response: " << tag << data;
if (!response.isResponse() || response.type() != Protocol::Command::RemoveRelations) {
Job::doHandleResponse(tag, response);
} else {
emitResult();
}
}
Relation RelationDeleteJob::relation() const
......
......@@ -51,7 +51,7 @@ public:
protected:
void doStart() Q_DECL_OVERRIDE;
void doHandleResponse(const QByteArray &tag, const QByteArray &data) Q_DECL_OVERRIDE;
void doHandleResponse(qint64 tag, const Protocol::Command &response) Q_DECL_OVERRIDE;
private:
Q_DECLARE_PRIVATE(RelationDeleteJob)
......
......@@ -23,6 +23,8 @@
#include "protocolhelper_p.h"
#include <QTimer>
#include <akonadi/private/protocol_p.h>
using namespace Akonadi;
class Akonadi::RelationFetchJobPrivate : public JobPrivate
......@@ -90,64 +92,32 @@ void RelationFetchJob::doStart()
{
Q_D(RelationFetchJob);
QByteArray command = d->newTag();
command += " UID RELATIONFETCH ";
QList<QByteArray> filter;
if (!d->mResource.isEmpty()) {
filter.append("RESOURCE");
filter.append(d->mResource.toUtf8());
}
if (!d->mTypes.isEmpty()) {
filter.append("TYPE");
QList<QByteArray> types;
types.reserve(d->mTypes.count());
foreach (const QString &t, d->mTypes) {
types.append(t.toUtf8());
}
filter.append('(' + ImapParser::join(types, " ") + ')');
} else if (!d->mRequestedRelation.type().isEmpty()) {
filter.append("TYPE");
filter.append('(' + d->mRequestedRelation.type() + ')');
}
if (d->mRequestedRelation.left().id() >= 0) {
filter << "LEFT" << QByteArray::number(d->mRequestedRelation.left().id());
}
if (d->mRequestedRelation.right().id() >= 0) {
filter << "RIGHT" << QByteArray::number(d->mRequestedRelation.right().id());
}
command += "(" + ImapParser::join(filter, " ") + ")\n";
qDebug() << command;
d->writeData(command);
d->sendCommand(Protocol::FetchRelationsCommand(
d->mRequestedRelation.left().id(),
d->mRequestedRelation.right().id(),
d->mResource,
d->mTypes.isEmpty() ? QStringList() << d->mRequestedRelation.type() : d->mTypes));
}
void RelationFetchJob::doHandleResponse(const QByteArray &tag, const QByteArray &data)
void RelationFetchJob::doHandleResponse(qint64 tag, const Protocol::Command &response)
{
Q_D(RelationFetchJob);