--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/src/cntmetadataoperation.cpp Fri Mar 19 09:27:18 2010 +0200
@@ -0,0 +1,281 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+//#include <columbo.h>
+#include <cntitem.h>
+#include <cntfldst.h>
+
+#include "cntmetadataoperation.h"
+
+CCntMetadataOperation::CCntMetadataOperation(RColumboSession& aSession)
+: CActive(EPriorityStandard), iSession(aSession), iContactId(-1)
+ {
+ }
+
+/**
+ * Construct a new metadata operation object. Note that this object will destroy
+ * itself after either save or delete operations have been called.
+ *
+ * The new object will be left on the cleanup stack.
+ *
+ * @param aSession Session with the metadata service.
+ * @return The new metadata operation instance.
+ */
+CCntMetadataOperation* CCntMetadataOperation::NewLC(RColumboSession& aSession)
+ {
+ CCntMetadataOperation* self = new (ELeave) CCntMetadataOperation(aSession);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+/**
+ * Construct a new metadata operation object. Note that this object will destroy
+ * itself after either save or delete operations have been called.
+ *
+ * @param aSession Session with the metadata service.
+ * @return The new metadata operation instance.
+ */
+CCntMetadataOperation* CCntMetadataOperation::NewL(RColumboSession& aSession)
+ {
+ CCntMetadataOperation* self = CCntMetadataOperation::NewLC(aSession);
+ CleanupStack::Pop();
+ return self;
+ }
+
+/**
+ * Note: upon construction, the active object is set active and waiting
+ * for a completion event to destroy itself.
+ */
+void CCntMetadataOperation::ConstructL()
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CCntMetadataOperation::~CCntMetadataOperation()
+ {
+ // (iSession is not owned)
+ delete iDocument;
+ delete iKey;
+ }
+
+/**
+ * The DoCancel() function will only delete the object in production builds.
+ * If __PROFILE_DEBUG__ is defined in the persistence layer MMP file,
+ * error codes will be logged should they occur.
+ */
+void CCntMetadataOperation::DoCancel()
+ {
+ // Log that the operation is cancelled.
+#ifdef __PROFILE_DEBUG__
+ _LIT(KCancelFormat, "CCntMetadataOperation::DoCancel(): Operation Cancelled: Contact ID = %d");
+ RDebug::Print(KCancelFormat(), iContactId);
+#endif
+
+ // Self destruct - operation cancelled.
+ delete this;
+ }
+
+/**
+ * The RunL() function will only delete the object in production builds.
+ * If __PROFILE_DEBUG__ is defined in the persistence layer MMP file,
+ * error codes will be logged should they occur.
+ */
+void CCntMetadataOperation::RunL()
+ {
+#ifdef __PROFILE_DEBUG__
+ if (iStatus.Int() != KErrNone)
+ {
+ _LIT(KErrorFormat, "CCntMetadataOperation::RunL(): Operation failed [Contact ID = %d] Error = %d");
+ RDebug::Print(KErrorFormat(), iContactId, iStatus.Int());
+ }
+ else
+ {
+ _LIT(KErrorFormat, "CCntMetadataOperation::RunL(): Operation complete [Contact ID = %d]");
+ RDebug::Print(KErrorFormat(), iContactId);
+ }
+#endif // __PROFILE_DEBUG__
+
+ // Self destruct - operation complete.
+ delete this;
+ }
+
+TInt CCntMetadataOperation::RunError(TInt aError)
+ {
+ // RunL() doesn't really leave, this should never happen.
+ // Log but do nothing.
+#ifdef __PROFILE_DEBUG__
+ _LIT(KRunErrorLog, "CCntMetadataOperation::RunError(): aError = %d");
+ RDebug::Print(KRunErrorLog(), aError);
+#endif // __PROFILE_DEBUG__
+ return aError;
+ }
+
+/**
+ * Save the contact @a aContact in the metadata service. If there is
+ * already a contact entry with this ID, it will be updated. Otherwise,
+ * a new contact metadata entry is added.
+ *
+ * The metadata operation object will be destroyed when the operation
+ * completes. Do not attempt to use this object after calling.
+ *
+ * @param aContact The contact item to index for metadata.
+ */
+void CCntMetadataOperation::SaveContactLD(const CContactItem& aContact)
+ {
+ // For logging purposes
+ iContactId = aContact.Id();
+
+ // Create a new generic metadata object for this contact item.
+ if (iDocument)
+ {
+ delete iDocument;
+ iDocument = NULL;
+ }
+ iDocument = DocumentFromContactL(aContact);
+ iDocument->Store(iSession, iStatus);
+ SetActive();
+ }
+
+/**
+ * Remove the contact described by @a aContactId from the metadata store.
+ *
+ * The metadata operation object will be destroyed when the operation
+ * completes. Do not attempt to use this object after calling.
+ *
+ * @param aContactId The contact to be removed from the metadata service
+ */
+void CCntMetadataOperation::DeleteContactLD(TInt aContactId)
+ {
+ // For logging purposes
+ iContactId = aContactId;
+
+ // Get the key and delete the document
+ if (iKey)
+ {
+ delete iKey;
+ iKey = NULL;
+ }
+ HBufC* iKey = ContactMetadataKeyLC(aContactId);
+ CleanupStack::Pop();
+
+ iSession.DeleteDocument(*iKey, iStatus);
+ SetActive();
+ }
+
+/**
+ * Construct a new generic metadata object to represent a contact item.
+ *
+ * @param aContact The contact item to encode as a generic metadata object.
+ * @return The newly constructed metadata object instance.
+ */
+CMetadataDocument* CCntMetadataOperation::DocumentFromContactL(const CContactItem& aContact)
+ {
+ CMetadataDocument* document = CMetadataDocument::NewLC();
+
+ // Assign a unique key for cntmodel purposes
+ HBufC* key = ContactMetadataKeyLC(aContact.Id());
+ document->SetUserKeyL(*key);
+ CleanupStack::PopAndDestroy(key);
+
+ // Iterate through fields, and produce a metadata string for this contact
+ CContactItemFieldSet& fields = aContact.CardFields();
+ const TInt KFieldCount(fields.Count());
+
+ if (KFieldCount > 0)
+ {
+ // Find out how much space we need for the metadata buffer
+ TInt bufferLength(0);
+ for(TInt i(0); i < KFieldCount; ++i)
+ {
+ CContactItemField& field = fields[i];
+ if (field.StorageType() != KStorageTypeText)
+ {
+ // Can only index text, no point if text is 0 length
+ continue;
+ }
+
+ // No point in indexing 0 length data
+ TInt fieldLength = field.TextStorage()->Text().Length();
+ if (fieldLength == 0)
+ {
+ continue;
+ }
+
+ // Add field length plus the length of a space to
+ // seperate it from the next field
+ bufferLength += (fieldLength + 1);
+ }
+
+ // Allocate a buffer and add all the fields to it
+ HBufC* metadata = HBufC::NewLC(bufferLength);
+ TPtr bufferPtr = metadata->Des();
+
+ for(TInt i(0); i < KFieldCount; ++i)
+ {
+ CContactItemField& field = fields[i];
+ if (field.StorageType() != KStorageTypeText)
+ {
+ // Can only index text
+ continue;
+ }
+
+ // No point in indexing 0 length data
+ TInt fieldLength = field.TextStorage()->Text().Length();
+ if (fieldLength == 0)
+ {
+ continue;
+ }
+
+ TPtrC fieldContent = field.TextStorage()->Text();
+ bufferPtr.Append(fieldContent);
+
+ // Add a space as a seperator
+ _LIT(KSpace, " ");
+ bufferPtr.Append(KSpace);
+ }
+
+ // Add the metadta to the generic document
+ document->SetMetadataL(*metadata);
+ CleanupStack::PopAndDestroy(metadata);
+ }
+
+ CleanupStack::Pop(document);
+ return document;
+ }
+
+/**
+ * Generate an RDNS style key to identify the metadata object for cntmodel purposes.
+ *
+ * @param aContactId The contact model assigned contact ID.
+ * @return A descriptor containing the new unique identifier for the document object.
+ */
+HBufC* CCntMetadataOperation::ContactMetadataKeyLC(TInt aContactId)
+ {
+ // Key format for cntmodel entries in the metadata service
+ _LIT(KKeyFormat, "com.nokia.contact.id.%d");
+
+ // Allocate a big enough buffer for just the key format with
+ // an integer added to the end
+ HBufC* key = HBufC::NewLC(KKeyFormat().Length() + 32);
+ TPtr keyPtr = key->Des();
+ keyPtr.AppendFormat(KKeyFormat(), aContactId);
+
+ // Leaving key on the cleanup stack
+ return key;
+ }
+