[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-pim
Subject: [Kde-pim] [patch] Basic item modification time support for items
From: Bertjan Broeksema <b.broeksema () kdemail ! net>
Date: 2008-07-22 18:58:45
Message-ID: 200807222058.45950.b.broeksema () kdemail ! net
[Download RAW message or body]
For review.
These two patches add basic modification time support for items. Modification
time is set at creation and modification. A test is added to
kdepimlibs/akonadi/tests/itemstoretest.{h,cpp}.
Note: This patch does not add support for retrieving items with a modification
stamp after some given stamp.
This patch also fixes that the item that is returned by ItemCreateJob::item()
has ID 0 in stead of -1.
regards,
Bertjan Broeksema
["kdepimlibs-akonadi.dif" (text/x-diff)]
Index: itemcreatejob.cpp
===================================================================
--- itemcreatejob.cpp (revision 836665)
+++ itemcreatejob.cpp (working copy)
@@ -27,6 +27,8 @@
#include "job_p.h"
#include "protocolhelper.h"
+#include <QtCore/QDateTime>
+
#include <kdebug.h>
using namespace Akonadi;
@@ -43,6 +45,7 @@
Item mItem;
QSet<QByteArray> mParts;
Item::Id mUid;
+ QDateTime mDatetime;
QByteArray mData;
};
@@ -129,6 +132,13 @@
<< tag << data;
}
}
+ if ( int pos = data.indexOf( "DATETIME" ) ) {
+ int resultPos = ImapParser::parseDateTime( data, d->mDatetime, pos + 8 );
+ if ( resultPos == (pos + 8) ) {
+ kDebug( 5250 ) << "Invalid DATETIME response to APPEND command: "
+ << tag << data;
+ }
+ }
}
}
@@ -141,6 +151,8 @@
Item item( d->mItem );
item.setId( d->mUid );
+ item.setRevision( 0 );
+ item.setModificationTime( d->mDatetime );
return item;
}
Index: itemmodifyjob.cpp
===================================================================
--- itemmodifyjob.cpp (revision 836665)
+++ itemmodifyjob.cpp (working copy)
@@ -159,8 +159,18 @@
}
if ( _tag == d->mTag ) {
if ( data.startsWith( "OK" ) ) {
+ QDateTime modificationDateTime;
+ if ( int pos = data.indexOf( "DATETIME" ) ) {
+ int resultPos = ImapParser::parseDateTime( data, modificationDateTime, pos + \
8 ); + if ( resultPos == (pos + 8) ) {
+ kDebug( 5250 ) << "Invalid DATETIME response to STORE command: "
+ << _tag << data;
+ }
+ }
+
// increase item revision of own copy of item
d->mItem.setRevision( d->mItem.revision() + 1 );
+ d->mItem.setModificationTime( modificationDateTime );
d->mItem.d_ptr->resetChangeLog();
} else {
setError( Unknown );
Index: tests/itemstoretest.cpp
===================================================================
--- tests/itemstoretest.cpp (revision 836665)
+++ tests/itemstoretest.cpp (working copy)
@@ -24,6 +24,7 @@
#include <akonadi/attributefactory.h>
#include <akonadi/collectionfetchjob.h>
#include <akonadi/collectionselectjob.h>
+#include <akonadi/itemcreatejob.h>
#include <akonadi/itemdeletejob.h>
#include <akonadi/itemfetchjob.h>
#include <akonadi/itemfetchscope.h>
@@ -322,4 +323,52 @@
QVERIFY( !sjob->exec() );
}
+void ItemStoreTest::testModificationTime()
+{
+ Item item;
+ item.setMimeType( "text/directory" );
+ QVERIFY( item.modificationTime().isNull() );
+
+ ItemCreateJob *job = new ItemCreateJob( item, res1_foo );
+ QVERIFY( job->exec() );
+
+ // The item should have a datetime set now.
+ item = job->item();
+ QVERIFY( !item.modificationTime().isNull() );
+ QDateTime initialDateTime = item.modificationTime();
+
+ // Fetch the same item again.
+ Item item2( item.id() );
+ ItemFetchJob *fjob = new ItemFetchJob( item2, this );
+ QVERIFY( fjob->exec() );
+ item2 = fjob->items().first();
+ QCOMPARE( initialDateTime, item2.modificationTime() );
+
+ // Lets wait 5 secs.
+ QTest::qWait( 5000 );
+
+ // Modify the item
+ ItemModifyJob *mjob = new ItemModifyJob( item );
+ item.attribute<TestAttribute>( Item::AddIfMissing )->data = "extra";
+ QVERIFY( mjob->exec() );
+
+ // The item should still have a datetime set and that date should be somewhere
+ // after the initialDateTime.
+ item = mjob->item();
+ QVERIFY( !item.modificationTime().isNull() );
+ QVERIFY( initialDateTime < item.modificationTime() );
+
+ // Fetch the item after modification.
+ Item item3( item.id() );
+ ItemFetchJob *fjob2 = new ItemFetchJob( item3, this );
+ QVERIFY( fjob2->exec() );
+
+ // item3 should have the same modification time as item.
+ item3 = fjob2->items().first();
+ QCOMPARE( item3.modificationTime(), item.modificationTime() );
+
+ // Clean up
+ ItemDeleteJob *idjob = new ItemDeleteJob( item, this );
+ QVERIFY( idjob->exec() );
+}
#include "itemstoretest.moc"
Index: tests/itemstoretest.h
===================================================================
--- tests/itemstoretest.h (revision 836665)
+++ tests/itemstoretest.h (working copy)
@@ -38,6 +38,7 @@
void testMultiPart();
void testPartRemove();
void testRevisionCheck();
+ void testModificationTime();
};
#endif
Index: item.cpp
===================================================================
--- item.cpp (revision 836665)
+++ item.cpp (working copy)
@@ -91,6 +91,16 @@
d->mFlagsOverwritten = true;
}
+QDateTime Item::modificationTime() const
+{
+ return d_func()->mModificationTime;
+}
+
+void Item::setModificationTime( const QDateTime &datetime )
+{
+ d_func()->mModificationTime = datetime;
+}
+
bool Item::hasFlag( const QByteArray & name ) const
{
return d_func()->mFlags.contains( name );
Index: itemfetchjob.cpp
===================================================================
--- itemfetchjob.cpp (revision 836665)
+++ itemfetchjob.cpp (working copy)
@@ -33,6 +33,7 @@
#include <kdebug.h>
+#include <QtCore/QDateTime>
#include <QtCore/QStringList>
#include <QtCore/QTimer>
@@ -167,6 +168,7 @@
// create a new item object
Item::Id uid = -1;
int rev = -1;
+ QDateTime datetime;
QString rid;
QString mimeType;
@@ -178,20 +180,23 @@
uid = value.toLongLong();
else if ( key == "REV" )
rev = value.toInt();
+ else if ( key == "DATETIME" )
+ ImapParser::parseDateTime( value, datetime );
else if ( key == "REMOTEID" )
rid = QString::fromUtf8( value );
else if ( key == "MIMETYPE" )
mimeType = QString::fromLatin1( value );
}
- if ( uid < 0 || rev < 0 || mimeType.isEmpty() ) {
- kWarning( 5250 ) << "Broken fetch response: UID, RID, REV or MIMETYPE \
missing!"; + if ( uid < 0 || rev < 0 || datetime.isNull() || mimeType.isEmpty() \
) { + kWarning( 5250 ) << "Broken fetch response: UID, RID, REV, DATETIME or \
MIMETYPE missing!"; return;
}
Item item( uid );
item.setRemoteId( rid );
item.setRevision( rev );
+ item.setModificationTime( datetime );
item.setMimeType( mimeType );
if ( !item.isValid() )
return;
@@ -200,7 +205,7 @@
for ( int i = 0; i < fetchResponse.count() - 1; i += 2 ) {
const QByteArray key = fetchResponse.value( i );
// skip stuff we dealt with already
- if ( key == "UID" || key == "REV" || key == "REMOTEID" || key == "MIMETYPE" \
) + if ( key == "UID" || key == "REV" || key == "DATETIME" || key == \
"REMOTEID" || key == "MIMETYPE" ) continue;
// flags
if ( key == "FLAGS" ) {
Index: item.h
===================================================================
--- item.h (revision 836665)
+++ item.h (working copy)
@@ -121,6 +121,19 @@
Flags flags() const;
/**
+ * Returns the timestamp of the last modification of this item.
+ */
+ QDateTime modificationTime() const;
+
+ /**
+ * Sets the timestamp of the last modification of this item.
+ *
+ * @note Do not modify this value from within an application,
+ * it is updated automatically by the revision checking functions.
+ */
+ void setModificationTime( const QDateTime &datetime );
+
+ /**
* Returns whether the flag with the given @p name is
* set in the item.
*/
Index: item_p.h
===================================================================
--- item_p.h (revision 836665)
+++ item_p.h (working copy)
@@ -20,6 +20,7 @@
#ifndef AKONADI_ITEM_P_H
#define AKONADI_ITEM_P_H
+#include <QtCore/QDateTime>
#include <QtCore/QMap>
#include "entity_p.h"
@@ -37,6 +38,7 @@
: EntityPrivate( id ),
mPayload( 0 ),
mRevision( -1 ),
+ mModificationTime(),
mFlagsOverwritten( false )
{
}
@@ -46,6 +48,7 @@
{
mFlags = other.mFlags;
mRevision = other.mRevision;
+ mModificationTime = other.mModificationTime;
mMimeType = other.mMimeType;
if ( other.mPayload )
mPayload = other.mPayload->clone();
@@ -73,6 +76,7 @@
PayloadBase* mPayload;
Item::Flags mFlags;
int mRevision;
+ QDateTime mModificationTime;
QString mMimeType;
Item::Flags mAddedFlags;
Item::Flags mDeletedFlags;
["kdesupport-akonadi.dif" (text/x-diff)]
Index: server/src/handler/append.cpp
===================================================================
--- server/src/handler/append.cpp (revision 836660)
+++ server/src/handler/append.cpp (working copy)
@@ -116,8 +116,14 @@
if ( !mimeType.isValid() ) {
return failureResponse( QString::fromLatin1( "Unknown mime type '%1'.").arg( \
QString::fromLatin1( mt ) ) ); }
+
+ if( m_dateTime == QDateTime() ) {
+ m_dateTime = QDateTime::currentDateTime();
+ }
+
PimItem item;
item.setRev( 0 );
+ item.setDatetime( m_dateTime );
// wrap data into a part
Part part;
@@ -144,9 +150,16 @@
if ( !transaction.commit() )
return failureResponse( "Unable to commit transaction." );
+ QString datetime = item.datetime().toString( QLatin1String( "dd-MMM-yyyy \
hh:mm:ss" ) ); + datetime.append( QLatin1String( " +0000" ) );
+
+ QByteArray res( "[UIDNEXT " + QByteArray::number( item.id() ) + " " );
+ res.append( "DATETIME " + ImapParser::quote( datetime.toUtf8() ) );
+ res.append( ']' );
+
response.setTag( tag() );
response.setUserDefined();
- response.setString( "[UIDNEXT " + QByteArray::number( item.id() ) + ']' );
+ response.setString( res );
emit responseAvailable( response );
response.setSuccess();
Index: server/src/handler/store.cpp
===================================================================
--- server/src/handler/store.cpp (revision 836660)
+++ server/src/handler/store.cpp (working copy)
@@ -85,6 +85,9 @@
else if ( buffer == "NOREV" )
revCheck = false;
+ // Set the same modification time for each item.
+ QDateTime modificationtime = QDateTime::currentDateTime();
+
for ( int i = 0; i < pimItems.count(); ++i ) {
if ( revCheck ) {
// check if revision number of given items and their database equivalents \
match @@ -95,7 +98,7 @@
// update item revision
pimItems[ i ].setRev( pimItems[ i ].rev() + 1 );
- pimItems[ i ].setDatetime( QDateTime::currentDateTime() );
+ pimItems[ i ].setDatetime( modificationtime );
if ( !pimItems[ i ].update() ) {
return failureResponse( "Unable to update item revision" );
}
@@ -210,9 +213,12 @@
if ( !transaction.commit() )
return failureResponse( "Cannot commit transaction." );
+ QString datetime = modificationtime.toString( QLatin1String( "dd-MMM-yyyy \
hh:mm:ss" ) ); + datetime.append( QLatin1String( " +0000" ) );
+
response.setTag( tag() );
response.setSuccess();
- response.setString( "STORE completed" );
+ response.setString( "DATETIME " + ImapParser::quote( datetime.toUtf8() ) + " STORE \
completed" );
emit responseAvailable( response );
deleteLater();
Index: server/src/handler/fetch.cpp
===================================================================
--- server/src/handler/fetch.cpp (revision 836660)
+++ server/src/handler/fetch.cpp (working copy)
@@ -50,9 +50,10 @@
static const int itemQueryIdColumn = 0;
static const int itemQueryRevColumn = 1;
-static const int itemQueryRidColumn = 2;
-static const int itemQueryMimeTypeColumn = 3;
-static const int itemQueryResouceColumn = 4;
+static const int itemQueryDatetimeColumn = 2;
+static const int itemQueryRidColumn = 3;
+static const int itemQueryMimeTypeColumn = 4;
+static const int itemQueryResouceColumn = 5;
static const int partQueryIdColumn = 0;
static const int partQueryNameColumn = 1;
@@ -183,9 +184,15 @@
while ( mItemQuery.query().isValid() ) {
const qint64 pimItemId = mItemQuery.query().value( itemQueryIdColumn \
).toLongLong();
const int pimItemRev = mItemQuery.query().value( itemQueryRevColumn ).toInt();
+ const QDateTime pimItemDatetime = mItemQuery.query().value( \
itemQueryDatetimeColumn ).toDateTime(); +
+ QString datetime = pimItemDatetime.toString( QLatin1String( "dd-MMM-yyyy \
hh:mm:ss" ) ); + datetime.append( QLatin1String( " +0000" ) );
+
QList<QByteArray> attributes;
attributes.append( "UID " + QByteArray::number( pimItemId ) );
attributes.append( "REV " + QByteArray::number( pimItemRev ) );
+ attributes.append( "DATETIME " + ImapParser::quote( datetime.toUtf8() ) );
attributes.append( "REMOTEID " + ImapParser::quote( mItemQuery.query().value( \
itemQueryRidColumn ).toString().toUtf8() ) );
attributes.append( "MIMETYPE " + ImapParser::quote( mItemQuery.query().value( \
itemQueryMimeTypeColumn ).toString().toUtf8() ) );
@@ -323,6 +330,7 @@
// make sure the columns indexes here and in the constants defined above match
mItemQuery.addColumn( PimItem::idFullColumnName() );
mItemQuery.addColumn( PimItem::revFullColumnName() );
+ mItemQuery.addColumn( PimItem::datetimeFullColumnName() );
mItemQuery.addColumn( PimItem::remoteIdFullColumnName() );
mItemQuery.addColumn( MimeType::nameFullColumnName() );
mItemQuery.addColumn( Resource::nameFullColumnName() );
_______________________________________________
KDE PIM mailing list kde-pim@kde.org
https://mail.kde.org/mailman/listinfo/kde-pim
KDE PIM home page at http://pim.kde.org/
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic