Commit d631e1ba authored by Volker Krause's avatar Volker Krause

Extract the protocol code for writing item sets and add unit tests for

it. This also adds support for remote identifier based operations on
more than one item (so far only supported when working with uids).

svn path=/trunk/KDE/kdepimlibs/; revision=968468
parent 140482e8
......@@ -23,6 +23,7 @@
#include "collectionselectjob_p.h"
#include "item.h"
#include "job_p.h"
#include "protocolhelper_p.h"
#include <akonadi/private/imapparser_p.h>
#include <akonadi/private/imapset_p.h>
......@@ -30,9 +31,6 @@
#include <KLocale>
#include <boost/bind.hpp>
#include <algorithm>
using namespace Akonadi;
class Akonadi::ItemDeleteJobPrivate : public JobPrivate
......@@ -92,30 +90,13 @@ void ItemDeleteJob::doStart()
if ( !d->mItems.isEmpty() ) {
QByteArray command = d->newTag();
std::sort( d->mItems.begin(), d->mItems.end(), boost::bind( &Item::id, _1 ) < boost::bind( &Item::id, _2 ) );
if ( d->mItems.first().isValid() ) {
// all items have a uid set
command += " " AKONADI_CMD_UID " " AKONADI_CMD_ITEMDELETE " ";
QList<Item::Id> uids;
foreach ( const Item &item, d->mItems )
uids << item.id();
ImapSet set;
set.add( uids );
command += set.toImapSequenceSet();
} else {
// delete by remote identifier
foreach ( const Item &item, d->mItems ) {
if ( item.remoteId().isEmpty() ) {
setError( Unknown );
setErrorText( i18n( "No remote identifier specified" ) );
emitResult();
return;
}
}
command += " " AKONADI_CMD_RID " " AKONADI_CMD_ITEMDELETE " ";
Q_ASSERT( d->mItems.count() == 1 ); // TODO implement support for multiple items
command += ImapParser::quote( d->mItems.first().remoteId().toUtf8() );
try {
command += ProtocolHelper::itemSetToByteArray( d->mItems, AKONADI_CMD_ITEMDELETE );
} catch ( const std::exception &e ) {
setError( Unknown );
setErrorText( QString::fromUtf8( e.what() ) );
emitResult();
return;
}
command += '\n';
d->writeData( command );
......
......@@ -20,11 +20,17 @@
#include "protocolhelper_p.h"
#include "attributefactory.h"
#include "imapparser_p.h"
#include "exception.h"
#include <akonadi/private/imapparser_p.h>
#include <akonadi/private/protocol_p.h>
#include <QtCore/QVarLengthArray>
#include <kdebug.h>
#include <klocale.h>
#include <boost/bind.hpp>
#include <algorithm>
using namespace Akonadi;
......@@ -170,3 +176,41 @@ QByteArray ProtocolHelper::decodePartIdentifier( const QByteArray &data, PartNam
return data;
}
}
QByteArray ProtocolHelper::itemSetToByteArray( const Item::List &_items, const QByteArray &command )
{
if ( _items.isEmpty() )
throw Exception( "No items specified" );
Item::List items( _items );
QByteArray rv;
std::sort( items.begin(), items.end(), boost::bind( &Item::id, _1 ) < boost::bind( &Item::id, _2 ) );
if ( items.first().isValid() ) {
// all items have a uid set
rv += " " AKONADI_CMD_UID " ";
rv += command;
rv += ' ';
QList<Item::Id> uids;
foreach ( const Item &item, items )
uids << item.id();
ImapSet set;
set.add( uids );
rv += set.toImapSequenceSet();
} else {
// check if all items have a remote id
QList<QByteArray> rids;
foreach ( const Item &item, items ) {
if ( item.remoteId().isEmpty() )
throw Exception( i18n( "No remote identifier specified" ) );
rids << ImapParser::quote( item.remoteId().toUtf8() );
}
rv += " " AKONADI_CMD_RID " ";
rv += command;
rv += " (";
rv += ImapParser::join( rids, " " );
rv += ')';
}
return rv;
}
......@@ -22,6 +22,7 @@
#include <akonadi/cachepolicy.h>
#include <akonadi/collection.h>
#include <akonadi/item.h>
namespace Akonadi {
......@@ -80,6 +81,12 @@ class ProtocolHelper
Decode part label and namespace.
*/
static QByteArray decodePartIdentifier( const QByteArray &data, PartNamespace &ns );
/**
Converts the given set of items into a protocol representation.
@throws A Akonadi::Exception if the item set contains items with missing/invalid identifiers.
*/
static QByteArray itemSetToByteArray( const Item::List &items, const QByteArray &command );
};
}
......
......@@ -90,7 +90,7 @@ class SessionPrivate
*/
void writeData( const QByteArray &data );
static int minimumProtocolVersion() { return 11; }
static int minimumProtocolVersion() { return 12; }
Session *mParent;
QByteArray sessionId;
......
......@@ -87,6 +87,7 @@ add_akonadi_test(itemtest.cpp)
add_akonadi_test(itemserializertest.cpp)
add_akonadi_test(mimetypecheckertest.cpp)
add_akonadi_test(notificationmessagetest.cpp)
add_akonadi_test(protocolhelpertest.cpp)
# testrunner tests
add_akonadi_isolated_test(testenvironmenttest.cpp)
......
/*
Copyright (c) 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.
*/
#include "test_utils.h"
#include "protocolhelper.cpp"
using namespace Akonadi;
class ProtocolHelperTest : public QObject
{
Q_OBJECT
private slots:
void testItemSetToByteArray_data()
{
QTest::addColumn<Item::List>( "items" );
QTest::addColumn<QByteArray>( "result" );
QTest::addColumn<bool>( "shouldThrow" );
Item u1; u1.setId( 1 );
Item u2; u2.setId( 2 );
Item u3; u3.setId( 3 );
Item r1; r1.setRemoteId( "A" );
Item r2; r2.setRemoteId( "B" );
QTest::newRow( "empty" ) << Item::List() << QByteArray() << true;
QTest::newRow( "single uid" ) << (Item::List() << u1) << QByteArray( " UID CMD 1" ) << false;
QTest::newRow( "multi uid" ) << (Item::List() << u1 << u3) << QByteArray( " UID CMD 1,3" ) << false;
QTest::newRow( "block uid" ) << (Item::List() << u1 << u2 << u3) << QByteArray( " UID CMD 1:3" ) << false;
QTest::newRow( "single rid" ) << (Item::List() << r1) << QByteArray( " RID CMD (\"A\")" ) << false;
QTest::newRow( "multi rid" ) << (Item::List() << r1 << r2) << QByteArray( " RID CMD (\"A\" \"B\")" ) << false;
QTest::newRow( "invalid" ) << (Item::List() << Item()) << QByteArray() << true;
QTest::newRow( "mixed" ) << (Item::List() << u1 << r1) << QByteArray() << true;
}
void testItemSetToByteArray()
{
QFETCH( Item::List, items );
QFETCH( QByteArray, result );
QFETCH( bool, shouldThrow );
bool didThrow = false;
try {
const QByteArray r = ProtocolHelper::itemSetToByteArray( items, "CMD" );
QCOMPARE( r, result );
} catch ( const std::exception &e ) {
qDebug() << e.what();
didThrow = true;
}
QCOMPARE( didThrow, shouldThrow );
}
};
QTEST_KDEMAIN( ProtocolHelperTest, NoGUI )
#include "protocolhelpertest.moc"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment