Hello community, here is the log from the commit of package akonadi-runtime for openSUSE:Factory checked in at 2014-04-08 22:36:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/akonadi-runtime (Old) and /work/SRC/openSUSE:Factory/.akonadi-runtime.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "akonadi-runtime" Changes: -------- --- /work/SRC/openSUSE:Factory/akonadi-runtime/akonadi-runtime.changes 2014-03-30 07:54:02.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.akonadi-runtime.new/akonadi-runtime.changes 2014-04-08 22:36:54.000000000 +0200 @@ -1,0 +2,7 @@ +Tue Apr 8 16:44:42 UTC 2014 - [email protected] + +- Update to 1.12.1 + * Bugfix releases. Resolves performance issues with the baloo + indexer and prevents dataloss when copying large email collections + +------------------------------------------------------------------- Old: ---- akonadi-1.12.0.tar.bz2 New: ---- akonadi-1.12.1.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ akonadi-runtime.spec ++++++ --- /var/tmp/diff_new_pack.Loskmr/_old 2014-04-08 22:36:55.000000000 +0200 +++ /var/tmp/diff_new_pack.Loskmr/_new 2014-04-08 22:36:55.000000000 +0200 @@ -17,9 +17,8 @@ Name: akonadi-runtime -Version: 1.12.0 +Version: 1.12.1 Release: 0 -%define rversion %{version} %define rname akonadi Summary: PIM Storage Service License: LGPL-2.1+ @@ -68,7 +67,7 @@ service. %prep -%setup -q -n %{rname}-%{rversion} +%setup -q -n %{rname}-%{version} %build %cmake_kde4 -d build -- -DCONFIG_INSTALL_DIR=/etc -DINSTALL_QSQLITE_IN_QT_PREFIX=TRUE -DWITH_SOPRANO=FALSE ++++++ akonadi-1.12.0.tar.bz2 -> akonadi-1.12.1.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/CMakeLists.txt new/akonadi-1.12.1/CMakeLists.txt --- old/akonadi-1.12.0/CMakeLists.txt 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/CMakeLists.txt 2014-04-07 23:02:16.000000000 +0200 @@ -50,7 +50,7 @@ set(AKONADI_VERSION_MAJOR "1") set(AKONADI_VERSION_MINOR "12") -set(AKONADI_VERSION_PATCH "0") +set(AKONADI_VERSION_PATCH "1") set(AKONADI_VERSION "${AKONADI_VERSION_MAJOR}.${AKONADI_VERSION_MINOR}.${AKONADI_VERSION_PATCH}") set(AKONADI_VERSION_STRING "${AKONADI_VERSION}") @@ -125,15 +125,6 @@ include(${QT_USE_FILE}) endif() -# Missing in FindQt4.cmake until Dec 2011: setting QT_NO_DEBUG_OUTPUT -if(CMAKE_BUILD_TYPE) - string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_TOLOWER) -endif() - -if(NOT CMAKE_BUILD_TYPE_TOLOWER MATCHES "debug") - add_definitions(-DQT_NO_DEBUG_OUTPUT) -endif() - if(STATIC_LIBRARY) set(LIBRARY_TYPE STATIC) set(AKONADI_STATIC_LIBS ON) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/NEWS new/akonadi-1.12.1/NEWS --- old/akonadi-1.12.0/NEWS 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/NEWS 2014-04-07 23:02:16.000000000 +0200 @@ -1,3 +1,12 @@ +1.12.1 07-April-2014 +---------------------------------------------- +- Fixed deadlock in SearchManager +- Fixed notification emission when appending items +- Fixed ItemRetriever ignoring changeSince argument +- Fixed X-AKAPPEND command response +- Fixed RID-based FETCH +- Fixed data loss in case of long-lasting copy or move operations + 1.12.0 25-March-2014 ---------------------------------------------- - Improved 'akonadictl status' command output diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/cachecleaner.cpp new/akonadi-1.12.1/server/src/cachecleaner.cpp --- old/akonadi-1.12.0/server/src/cachecleaner.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/cachecleaner.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -28,6 +28,55 @@ using namespace Akonadi::Server; CacheCleaner *CacheCleaner::sInstance = 0; +QMutex CacheCleanerInhibitor::sLock; +int CacheCleanerInhibitor::sInhibitCount = 0; + +CacheCleanerInhibitor::CacheCleanerInhibitor( bool doInhibit ) + : mInhibited( false ) +{ + if ( doInhibit ) { + inhibit(); + } +} + +CacheCleanerInhibitor::~CacheCleanerInhibitor() +{ + if ( mInhibited ) { + uninhibit(); + } +} + +void CacheCleanerInhibitor::inhibit() +{ + if ( mInhibited ) { + akError() << "Cannot recursively inhibit an inhibitor"; + return; + } + + sLock.lock(); + if ( ++sInhibitCount == 1 ) { + CacheCleaner::self()->inhibit( true ); + } + sLock.unlock(); + mInhibited = true; +} + +void CacheCleanerInhibitor::uninhibit() +{ + if ( !mInhibited ) { + akError() << "Cannot uninhibit an uninhibited inhibitor"; // aaaw yeah + return; + } + mInhibited = false; + + sLock.lock(); + Q_ASSERT( sInhibitCount > 0 ); + if ( --sInhibitCount == 0 ) { + CacheCleaner::self()->inhibit( false ); + } + sLock.unlock(); +} + CacheCleaner::CacheCleaner( QObject *parent ) : CollectionScheduler( parent ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/cachecleaner.h new/akonadi-1.12.1/server/src/cachecleaner.h --- old/akonadi-1.12.0/server/src/cachecleaner.h 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/cachecleaner.h 2014-04-07 23:02:16.000000000 +0200 @@ -22,12 +22,39 @@ #include "collectionscheduler.h" +#include <QMutex> + namespace Akonadi { namespace Server { class Collection; /** + * A RAII helper class to temporarily stop the CacheCleaner. This allows long-lasting + * operations to safely retrieve all data from resource and perform an operation on them + * (like move or copy) without risking that the cache will be cleaned in the meanwhile + * + * The inhibitor is recursive, so it's possible to create multiple instances of the + * CacheCleanerInhibitor and the CacheCleaner will be inhibited until all instances + * are destroyed again. However it's not possible to inhibit a single inhibitor + * multiple times. + */ +class CacheCleanerInhibitor +{ + public: + CacheCleanerInhibitor( bool inhibit = true ); + ~CacheCleanerInhibitor(); + + void inhibit(); + void uninhibit(); + + private: + static QMutex sLock; + static int sInhibitCount; + bool mInhibited; +}; + +/** Cache cleaner thread. */ class CacheCleaner : public CollectionScheduler @@ -52,6 +79,9 @@ private: static CacheCleaner *sInstance; + + friend class CacheCleanerInhibitor; + }; } // namespace Server diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/collectionscheduler.cpp new/akonadi-1.12.1/server/src/collectionscheduler.cpp --- old/akonadi-1.12.0/server/src/collectionscheduler.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/collectionscheduler.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -20,10 +20,86 @@ #include "collectionscheduler.h" #include "storage/datastore.h" +#include "akdebug.h" #include <QDateTime> #include <QCoreApplication> +namespace Akonadi { +namespace Server { + +/** + * @warning: QTimer's methods are not virtual, so it's necessary to always call + * methods on pointer to PauseableTimer! + */ +class PauseableTimer : public QTimer +{ + public: + PauseableTimer( QObject *parent = 0 ) + : QTimer( parent ) + { + } + + void start( int interval ) + { + mStarted = QDateTime::currentDateTime(); + mPaused = QDateTime(); + QTimer::start( interval ); + } + + void start() + { + start( interval() ); + } + + void stop() + { + mStarted = QDateTime(); + mPaused = QDateTime(); + QTimer::stop(); + } + + void pause() + { + if ( !isActive() ) { + akError() << "Cannot pause an inactive timer"; + return; + } + if ( isPaused() ) { + akError() << "Cannot pause an already paused timer"; + return; + } + + mPaused = QDateTime::currentDateTime(); + stop(); + } + + void resume() + { + if ( !isPaused() ) { + akError() << "Cannot resume a timer that is not paused."; + return; + } + + start( interval() - ( mStarted.secsTo( mPaused ) * 1000 ) ); + mPaused = QDateTime(); + // Update mStarted so that pause() can be called repeatedly + mStarted = QDateTime::currentDateTime(); + } + + bool isPaused() const + { + return !mPaused.isNull(); + } + + private: + QDateTime mStarted; + QDateTime mPaused; +}; + +} // namespace Server +} // namespace Akonadi + using namespace Akonadi::Server; CollectionScheduler::CollectionScheduler( QObject *parent ) @@ -33,7 +109,7 @@ // make sure we are created from the main thread, ie. before all other threads start to potentially use us Q_ASSERT( QThread::currentThread() == QCoreApplication::instance()->thread() ); - mScheduler = new QTimer( this ); + mScheduler = new PauseableTimer( this ); mScheduler->setSingleShot( true ); connect( mScheduler, SIGNAL(timeout()), this, SLOT(schedulerTimeout()) ); @@ -53,6 +129,15 @@ DataStore::self()->close(); } +void CollectionScheduler::inhibit( bool inhibit ) +{ + if ( inhibit && mScheduler->isActive() && !mScheduler->isPaused() ) { + mScheduler->pause(); + } else if ( !inhibit && mScheduler->isPaused() ) { + mScheduler->resume(); + } +} + int CollectionScheduler::minimumInterval() const { return mMinInterval; @@ -123,6 +208,11 @@ void CollectionScheduler::startScheduler() { + // Don't restart timer if we are paused. + if ( mScheduler->isPaused() ) { + return; + } + QMutexLocker locker( &mScheduleLock ); if ( mSchedule.isEmpty() ) { // Stop the timer. It will be started again once some collection is scheduled @@ -188,6 +278,9 @@ void CollectionScheduler::schedulerTimeout() { + // Call stop() explicitly to reset the timer + mScheduler->stop(); + mScheduleLock.lock(); const uint timestamp = mSchedule.constBegin().key(); const QList<Collection> collections = mSchedule.values( timestamp ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/collectionscheduler.h new/akonadi-1.12.1/server/src/collectionscheduler.h --- old/akonadi-1.12.0/server/src/collectionscheduler.h 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/collectionscheduler.h 2014-04-07 23:02:16.000000000 +0200 @@ -32,6 +32,7 @@ namespace Server { class Collection; +class PauseableTimer; class CollectionScheduler: public QThread { @@ -66,6 +67,8 @@ virtual int collectionScheduleInterval( const Collection &collection ) = 0; virtual void collectionExpired( const Collection &collection ) = 0; + void inhibit( bool inhibit = true ); + protected Q_SLOTS: void initScheduler(); void schedulerTimeout(); @@ -75,7 +78,7 @@ protected: QMutex mScheduleLock; QMultiMap<uint /*timestamp*/, Collection> mSchedule; - QTimer *mScheduler; + PauseableTimer *mScheduler; int mMinInterval; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/handler/akappend.cpp new/akonadi-1.12.1/server/src/handler/akappend.cpp --- old/akonadi-1.12.0/server/src/handler/akappend.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/handler/akappend.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -220,11 +220,13 @@ // parse optional date/time string QDateTime dateTime; if ( m_streamParser->hasDateTime() ) { - dateTime = m_streamParser->readDateTime(); + dateTime = m_streamParser->readDateTime().toUTC(); // FIXME Should we return an error if m_dateTime is invalid? + } else { + // if date/time is not given then it will be set to the current date/time + // converted to UTC. + dateTime = QDateTime::currentDateTime().toUTC(); } - // if date/time is not given then it will be set to the current date/time - // by the database // FIXME: The streaming/reading of all item parts can hold the transaction for // unnecessary long time -> should we wrap the PimItem into one transaction @@ -247,7 +249,7 @@ const Collection col = HandlerHelper::collectionFromIdOrName( mailbox ); const Flag::List flagList = HandlerHelper::resolveFlags( itemFlags ); bool flagsChanged = false; - if ( !db->appendItemsFlags( PimItem::List() << item, flagList, flagsChanged, false, col ) ) { + if ( !db->appendItemsFlags( PimItem::List() << item, flagList, flagsChanged, false, col, true ) ) { return failureResponse( "Unable to append item flags." ); } @@ -303,11 +305,14 @@ PreprocessorManager::instance()->beginHandleItem( item, db ); } + // Date time is always stored in UTC time zone by the server. + const QString datetime = QLocale::c().toString( item.datetime(), QLatin1String( "dd-MMM-yyyy hh:mm:ss +0000" ) ); + // ...aaaaaand done. Response response; response.setTag( tag() ); response.setUserDefined(); - response.setString( "[UIDNEXT " + QByteArray::number( item.id() ) + ']' ); + response.setString( "[UIDNEXT " + QByteArray::number( item.id() ) + " DATETIME " + ImapParser::quote( datetime.toUtf8() ) + ']' ); Q_EMIT responseAvailable( response ); response.setSuccess(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/handler/colcopy.cpp new/akonadi-1.12.1/server/src/handler/colcopy.cpp --- old/akonadi-1.12.0/server/src/handler/colcopy.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/handler/colcopy.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -21,6 +21,7 @@ #include "connection.h" #include "handlerhelper.h" +#include "cachecleaner.h" #include "storage/datastore.h" #include "storage/transaction.h" #include "storage/itemretriever.h" @@ -98,6 +99,8 @@ return failureResponse( "No valid target specified" ); } + CacheCleanerInhibitor inhibitor; + // retrieve all not yet cached items of the source ItemRetriever retriever( connection() ); retriever.setCollection( source, true ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/handler/colmove.cpp new/akonadi-1.12.1/server/src/handler/colmove.cpp --- old/akonadi-1.12.0/server/src/handler/colmove.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/handler/colmove.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -26,6 +26,7 @@ #include <storage/transaction.h> #include <storage/collectionqueryhelper.h> #include <storage/selectquerybuilder.h> +#include <cachecleaner.h> #include <akdebug.h> using namespace Akonadi; @@ -61,6 +62,8 @@ return successResponse( "COLMOVE complete - nothing to do" ); } + CacheCleanerInhibitor inhibitor; + // retrieve all not yet cached items of the source ItemRetriever retriever( connection() ); retriever.setCollection( source, true ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/handler/copy.cpp new/akonadi-1.12.1/server/src/handler/copy.cpp --- old/akonadi-1.12.0/server/src/handler/copy.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/handler/copy.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -21,6 +21,7 @@ #include "connection.h" #include "handlerhelper.h" +#include "cachecleaner.h" #include "storage/datastore.h" #include "storage/itemqueryhelper.h" @@ -74,6 +75,8 @@ return failureResponse( "No items specified" ); } + CacheCleanerInhibitor inhibitor; + ItemRetriever retriever( connection() ); retriever.setItemSet( set ); retriever.setRetrieveFullPayload( true ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/handler/fetch.cpp new/akonadi-1.12.1/server/src/handler/fetch.cpp --- old/akonadi-1.12.0/server/src/handler/fetch.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/handler/fetch.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -23,6 +23,7 @@ #include "connection.h" #include "fetchhelper.h" #include "response.h" +#include "cachecleaner.h" #include <libs/protocol_p.h> @@ -39,6 +40,8 @@ // sequence set mScope.parseScope( m_streamParser ); + CacheCleanerInhibitor inhibitor; + FetchHelper fetchHelper( connection(), mScope, FetchScope( m_streamParser ) ); connect( &fetchHelper, SIGNAL(responseAvailable(Akonadi::Server::Response)), this, SIGNAL(responseAvailable(Akonadi::Server::Response)) ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/handler/fetchhelper.cpp new/akonadi-1.12.1/server/src/handler/fetchhelper.cpp --- old/akonadi-1.12.0/server/src/handler/fetchhelper.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/handler/fetchhelper.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -284,6 +284,7 @@ retriever.setScope( mScope ); retriever.setRetrieveParts( mFetchScope.requestedPayloads() ); retriever.setRetrieveFullPayload( mFetchScope.fullPayload() ); + retriever.setChangedSince( mFetchScope.changedSince() ); if ( !retriever.exec() && !mFetchScope.ignoreErrors() ) { // There we go, retrieve the missing parts from the resource. if ( mConnection->resourceContext().isValid() ) { throw HandlerException( QString::fromLatin1( "Unable to fetch item from backend (collection %1, resource %2) : %3" ) @@ -303,6 +304,9 @@ // error if query did not find any item and scope is not listing items but // a request for a specific item if ( !itemQuery.isValid() ) { + if ( mFetchScope.ignoreErrors() ) { + return true; + } switch ( mScope.scope() ) { case Scope::Uid: // fall through case Scope::Rid: // fall through diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/handler/modify.cpp new/akonadi-1.12.1/server/src/handler/modify.cpp --- old/akonadi-1.12.0/server/src/handler/modify.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/handler/modify.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -33,6 +33,7 @@ #include <libs/protocol_p.h> #include <search/searchmanager.h> #include <akdebug.h> +#include <cachecleaner.h> using namespace Akonadi; using namespace Akonadi::Server; @@ -63,6 +64,8 @@ QByteArray line = m_streamParser->readUntilCommandEnd(); m_streamParser->insertData( "\n" ); + CacheCleanerInhibitor inhibitor( false ); + int p = 0; if ( ( p = line.indexOf( AKONADI_PARAM_PARENT ) ) > 0 ) { QByteArray tmp; @@ -70,6 +73,7 @@ const Collection newParent = HandlerHelper::collectionFromIdOrName( tmp ); if ( newParent.isValid() && collection.parentId() != newParent.id() && collection.resourceId() != newParent.resourceId() ) { + inhibitor.inhibit(); ItemRetriever retriever( connection() ); retriever.setCollection( collection, true ); retriever.setRetrieveFullPayload( true ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/handler/move.cpp new/akonadi-1.12.1/server/src/handler/move.cpp --- old/akonadi-1.12.0/server/src/handler/move.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/handler/move.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -23,6 +23,7 @@ #include <entities.h> #include <imapstreamparser.h> #include <handlerhelper.h> +#include <cachecleaner.h> #include <storage/datastore.h> #include <storage/itemretriever.h> #include <storage/itemqueryhelper.h> @@ -46,6 +47,8 @@ const Collection destination = CollectionQueryHelper::singleCollectionFromScope( destScope, connection() ); const Resource destResource = destination.resource(); + CacheCleanerInhibitor inhibitor; + // make sure all the items we want to move are in the cache ItemRetriever retriever( connection() ); retriever.setScope( mScope ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/handler/searchpersistent.cpp new/akonadi-1.12.1/server/src/handler/searchpersistent.cpp --- old/akonadi-1.12.0/server/src/handler/searchpersistent.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/handler/searchpersistent.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -112,7 +112,7 @@ return failureResponse( "Unable to commit transaction" ); } - SearchManager::instance()->updateSearchAsync( col ); + SearchManager::instance()->updateSearch( col ); const QByteArray b = HandlerHelper::collectionToByteArray( col ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/search/searchmanager.cpp new/akonadi-1.12.1/server/src/search/searchmanager.cpp --- old/akonadi-1.12.0/server/src/search/searchmanager.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/search/searchmanager.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -202,8 +202,10 @@ void SearchManager::scheduleSearchUpdate() { - // Reset if the timer is active - mSearchUpdateTimer->start(); + // Reset if the timer is active (use QueuedConnection to invoke start() from + // the thread the QTimer lives in instead of caller's thread, otherwise crashes + // and weird things can happen. + QMetaObject::invokeMethod( mSearchUpdateTimer, "start", Qt::QueuedConnection ); } void SearchManager::searchUpdateTimeout() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/search/searchtaskmanager.cpp new/akonadi-1.12.1/server/src/search/searchtaskmanager.cpp --- old/akonadi-1.12.0/server/src/search/searchtaskmanager.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/search/searchtaskmanager.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -214,7 +214,7 @@ Q_FOREVER { akDebug() << "Search loop is waiting, will wake again in" << timeout << "ms"; - mWait.wait( &mLock, timeout ); // wait for a minute + mWait.wait( &mLock, timeout ); if ( mShouldStop ) { Q_FOREACH (SearchTask *task, mTasklist ) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/storage/datastore.cpp new/akonadi-1.12.1/server/src/storage/datastore.cpp --- old/akonadi-1.12.0/server/src/storage/datastore.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/storage/datastore.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -244,7 +244,8 @@ } bool DataStore::doAppendItemsFlag( const PimItem::List &items, const Flag &flag, - const QSet<Entity::Id> &existing, const Collection &col ) + const QSet<Entity::Id> &existing, const Collection &col, + bool silent ) { QVariantList flagIds; QVariantList appendIds; @@ -272,15 +273,17 @@ return false; } - mNotificationCollector->itemsFlagsChanged( appendItems, QSet<QByteArray>() << flag.name().toLatin1(), - QSet<QByteArray>(), col ); + if ( !silent ) { + mNotificationCollector->itemsFlagsChanged( appendItems, QSet<QByteArray>() << flag.name().toLatin1(), + QSet<QByteArray>(), col ); + } return true; } bool DataStore::appendItemsFlags( const PimItem::List &items, const QVector<Flag> &flags, bool &flagsChanged, bool checkIfExists, - const Collection &col ) + const Collection &col, bool silent ) { QSet<QByteArray> added; @@ -317,7 +320,7 @@ } } - if ( !doAppendItemsFlag( items, flag, existing, col ) ) { + if ( !doAppendItemsFlag( items, flag, existing, col, silent ) ) { return false; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/storage/datastore.h new/akonadi-1.12.1/server/src/storage/datastore.h --- old/akonadi-1.12.0/server/src/storage/datastore.h 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/storage/datastore.h 2014-04-07 23:02:16.000000000 +0200 @@ -120,7 +120,7 @@ /* --- ItemFlags ----------------------------------------------------- */ bool setItemsFlags( const PimItem::List &items, const QVector<Flag> &flags ); bool appendItemsFlags( const PimItem::List &items, const QVector<Flag> &flags, bool &flagsChanged, - bool checkIfExists = true, const Collection &col = Collection() ); + bool checkIfExists = true, const Collection &col = Collection(), bool silent = false ); bool removeItemsFlags( const PimItem::List &items, const QVector<Flag> &flags ); /* --- ItemTags ----------------------------------------------------- */ @@ -272,7 +272,8 @@ private: bool doAppendItemsFlag( const PimItem::List &items, const Flag &flag, - const QSet<PimItem::Id> &existing, const Collection &col ); + const QSet<PimItem::Id> &existing, const Collection &col, + bool silent ); bool doAppendItemsTag( const PimItem::List &items, const Tag &tag, const QSet<Entity::Id> &existing, const Collection &col ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/storage/itemqueryhelper.cpp new/akonadi-1.12.1/server/src/storage/itemqueryhelper.cpp --- old/akonadi-1.12.0/server/src/storage/itemqueryhelper.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/storage/itemqueryhelper.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -65,7 +65,8 @@ qb.addJoin( QueryBuilder::InnerJoin, Collection::tableName(), PimItem::collectionIdFullColumnName(), Collection::idFullColumnName() ); qb.addValueCondition( Collection::resourceIdFullColumnName(), Query::Equals, connection->resourceContext().id() ); - } else if ( connection->selectedCollectionId() > 0 ) { + } + if ( connection->selectedCollectionId() > 0 ) { qb.addValueCondition( PimItem::collectionIdFullColumnName(), Query::Equals, connection->selectedCollectionId() ); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/storage/itemretriever.cpp new/akonadi-1.12.1/server/src/storage/itemretriever.cpp --- old/akonadi-1.12.0/server/src/storage/itemretriever.cpp 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/storage/itemretriever.cpp 2014-04-07 23:02:16.000000000 +0200 @@ -115,6 +115,11 @@ return mScope; } +void ItemRetriever::setChangedSince( const QDateTime &changedSince ) +{ + mChangedSince = changedSince; +} + QStringList ItemRetriever::retrieveParts() const { return mParts; @@ -171,6 +176,11 @@ QString::fromLatin1( mConnection->sessionId() ) ); } + if ( mChangedSince.isValid() ) { + qb.addValueCondition( PimItem::datetimeFullColumnName(), Query::GreaterOrEqual, + mChangedSince.toUTC() ); + } + qb.addSortColumn( PimItem::idFullColumnName(), Query::Ascending ); if ( !qb.exec() ) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/akonadi-1.12.0/server/src/storage/itemretriever.h new/akonadi-1.12.1/server/src/storage/itemretriever.h --- old/akonadi-1.12.0/server/src/storage/itemretriever.h 2014-03-25 14:32:48.000000000 +0100 +++ new/akonadi-1.12.1/server/src/storage/itemretriever.h 2014-04-07 23:02:16.000000000 +0200 @@ -54,6 +54,7 @@ void setRetrieveParts( const QStringList &parts ); QStringList retrieveParts() const; void setRetrieveFullPayload( bool fullPayload ); + void setChangedSince( const QDateTime &changedSince ); void setItemSet( const ImapSet &set, const Collection &collection = Collection() ); void setItemSet( const ImapSet &set, bool isUid ); void setItem( const Entity::Id &id ); @@ -84,6 +85,7 @@ QStringList mParts; bool mFullPayload; bool mRecursive; + QDateTime mChangedSince; mutable QByteArray mLastError; }; -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
