diff -r 000000000000 -r c53acadfccc6 metadataengine/client/src/mdesessionimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/metadataengine/client/src/mdesessionimpl.cpp Mon Jan 18 20:34:07 2010 +0200 @@ -0,0 +1,2931 @@ +/* +* Copyright (c) 2007-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: Metadata engine client session implementation* +*/ + +#include +#include + +#include "mdesessionimpl.h" +#include "mdesessionstartupao.h" + +#include "mdcdef.h" +#include "mdcitem.h" +#include "mdcresult.h" +#include "mdeobjectdef.h" +#include "mderelationdef.h" +#include "mdeeventdef.h" +#include "mdeobject.h" +#include "mderelation.h" +#include "mdeevent.h" +#include "mdepanic.h" +#include "mdequeryimpl.h" +#include "mdenotifierao.h" +#include "mdeobjectdef.h" +#include "mdenamespacedef.h" +#include "mdccommon.pan" +#include "mdedatabuffer.h" +#include "mdcserializationbuffer.h" +#include "mdequerycriteriaserialization.h" +#include "mdelogiccondition.h" +#include "mdeobjectcondition.h" +#include "mdscommoninternal.h" + +RMdESessionAsyncRequest::RMdESessionAsyncRequest( TRequestType aRequestType, + CMdCSerializationBuffer* aBuffer, CMdCSerializationBuffer& aResultBuffer, + TRequestStatus& aRequestStatus) : + iRequestType(aRequestType), iBuffer(aBuffer), iResultBuffer(&aResultBuffer), + iRequestStatus(&aRequestStatus) + { + *iRequestStatus = KRequestPending; + } + +void RMdESessionAsyncRequest::Close() + { + if (iBuffer) + { + delete iBuffer; + iBuffer = NULL; + } + } + +void CMdESessionAsyncHandler::AddRequest( CMdCSerializationBuffer* aBuffer, + CMdCSerializationBuffer& aResultBuffer, + TRequestStatus& aRequestStatus ) + { + RMdESessionAsyncRequest request = RMdESessionAsyncRequest( + RMdESessionAsyncRequest::EAddRequest, + aBuffer, aResultBuffer, aRequestStatus ); + + iRequests.Append(request); + + if( !IsActive() ) + { + iEngineSession.DoAddItemsAsync( *aBuffer, aResultBuffer, + iStatus ); + SetActive(); + } + } + +void CMdESessionAsyncHandler::UpdateRequest( CMdCSerializationBuffer * aBuffer, + CMdCSerializationBuffer& aResultBuffer, + TRequestStatus& aRequestStatus ) + { + RMdESessionAsyncRequest request = RMdESessionAsyncRequest( + RMdESessionAsyncRequest::EUpdateRequest, + aBuffer, aResultBuffer, aRequestStatus); + + iRequests.Append(request); + + if( !IsActive() ) + { + iEngineSession.DoUpdateItemsAsync(*aBuffer, aResultBuffer, + iStatus); + SetActive(); + } + } + +void CMdESessionAsyncHandler::RemoveRequest( CMdCSerializationBuffer* aBuffer, + CMdCSerializationBuffer& aResultBuffer, + TRequestStatus& aRequestStatus ) + { + RMdESessionAsyncRequest request = RMdESessionAsyncRequest( + RMdESessionAsyncRequest::ERemoveRequest, + aBuffer, aResultBuffer, aRequestStatus); + + iRequests.Append(request); + + if( !IsActive() ) + { + iEngineSession.DoRemoveItemsAsync( *aBuffer, aResultBuffer, + iStatus ); + SetActive(); + } + } + +CMdESessionAsyncHandler* CMdESessionAsyncHandler::NewL(CMdESessionImpl& aSession, + RMdEEngineSession &aEngineSession) + { + CMdESessionAsyncHandler* self = CMdESessionAsyncHandler::NewLC( + aSession, aEngineSession); + CleanupStack::Pop(self); + return self; + } + +CMdESessionAsyncHandler* CMdESessionAsyncHandler::NewLC( CMdESessionImpl& aSession, + RMdEEngineSession &aEngineSession ) + { + CMdESessionAsyncHandler *self = new (ELeave) CMdESessionAsyncHandler( + aSession, aEngineSession); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +CMdESessionAsyncHandler::~CMdESessionAsyncHandler() + { + Cancel(); + + const TInt count = iRequests.Count(); + + for (TInt i = 0; i < count; i++) + { + iRequests[i].Close(); + } + iRequests.Close(); + } + +void CMdESessionAsyncHandler::RunL() + { + //Remove first from array + RMdESessionAsyncRequest& request = iRequests[0]; + iRequests.Remove(0); + + const TInt status = iStatus.Int(); + + User::RequestComplete( request.iRequestStatus, status ); + request.Close(); + + if (iRequests.Count() > 0) + { + request = iRequests[0]; + + iStatus = KRequestPending; + + switch( request.iRequestType ) + { + case RMdESessionAsyncRequest::EAddRequest: + iEngineSession.DoAddItemsAsync( *(request.iBuffer), + *(request.iResultBuffer), iStatus); + break; + case RMdESessionAsyncRequest::EUpdateRequest: + iEngineSession.DoUpdateItemsAsync( *(request.iBuffer), + *(request.iResultBuffer), iStatus); + break; + case RMdESessionAsyncRequest::ERemoveRequest: + iEngineSession.DoRemoveItemsAsync( *(request.iBuffer), + *(request.iResultBuffer), iStatus); + break; + default: + break; + } + SetActive(); + } + } + +TInt CMdESessionAsyncHandler::RunError(TInt aError) + { + if( aError == KErrServerTerminated ) + { + iSession.NotifyError( aError ); + return KErrNone; + } + else + { + return aError; + } + } + +void CMdESessionAsyncHandler::DoCancel() + { + } + +CMdESessionAsyncHandler::CMdESessionAsyncHandler(CMdESessionImpl& aSession, + RMdEEngineSession &aEngineSession) + : CActive( CActive::EPriorityStandard ), iSession( aSession ), + iEngineSession(aEngineSession) + { + } + +void CMdESessionAsyncHandler::ConstructL() + { + CActiveScheduler::Add(this); + } + +CMdESessionImpl::CMdESessionImpl(MMdESessionObserver& aObserver) + : iSessionStartupAO( NULL ), iSessionObserver(&aObserver), + iSchemaBuffer( NULL ), iAsyncHandler(NULL), iNextQueryId( 0 ), + iSession( *this ) + { + } + +CMdESessionImpl::~CMdESessionImpl() + { + Close(); + + delete iSchemaBuffer; + + iNotifiers.ResetAndDestroy(); + iNotifiers.Close(); + + iSession.Shutdown(); + iSession.Close(); + + iSchemaChunk.Close(); + + iNamespaceDefs.ResetAndDestroy(); + iNamespaceDefs.Close(); + + delete iSessionStartupAO; + + delete iAsyncHandler; + } + +void CMdESessionImpl::ConstructL() + { + iSessionStartupAO = CMdESessionStartupAO::NewL( *this, iSession ); + iAsyncHandler = CMdESessionAsyncHandler::NewL( *this, iSession ); + } + +void CMdESessionImpl::Close() + { + iSchemaObserverArray.Reset(); + iSchemaObserverArray.Close(); + } + +TInt CMdESessionImpl::NamespaceDefCount() const + { + return iNamespaceDefs.Count(); + } + +CMdENamespaceDef& CMdESessionImpl::NamespaceDefL( TInt aIndex ) + { + return *iNamespaceDefs[aIndex]; + } + +CMdENamespaceDef& CMdESessionImpl::GetNamespaceDefL( const TDesC& aName ) + { + const TInt KNamespaceCount = iNamespaceDefs.Count(); + for ( TInt i = 0; i < KNamespaceCount; ++i ) + { + if ( !aName.Compare( iNamespaceDefs[i]->Name() ) ) + { + return NamespaceDefL( i ); + } + } + + User::Leave( KErrNotFound ); + return NamespaceDefL( -1 ); // never reached + } + +CMdENamespaceDef& CMdESessionImpl::GetNamespaceDefL(TDefId aId) + { + const TInt KNamespaceCount = iNamespaceDefs.Count(); + for ( TInt i = 0; i < KNamespaceCount; ++i ) + { + if ( iNamespaceDefs[i]->Id() == aId ) + { + return NamespaceDefL( i ); + } + } + + User::Leave( KErrNotFound ); + return NamespaceDefL( -1 ); // never reached + } + +CMdENamespaceDef& CMdESessionImpl::GetDefaultNamespaceDefL() + { + return GetNamespaceDefL( KDefaultNamespaceDefId ); + } + +CMdEObject* CMdESessionImpl::NewObjectL( CMdEObjectDef& aDef, const TDesC& aUri, TUint32 aMediaId ) + { + CMdEObject* object = NewObjectLC( aDef, aUri, aMediaId ); + CleanupStack::Pop(object); + return object; + } + +CMdEObject* CMdESessionImpl::NewObjectLC( CMdEObjectDef& aDef, const TDesC& aUri, TUint32 aMediaId ) + { + CMdEObject* object = CMdEObject::NewLC( aDef, aUri, aMediaId ); + return object; + } + +void CMdESessionImpl::CommitObjectL(CMdEObject& aObject) + { + // check state + // check that object is open for modifications + if (!aObject.OpenForModifications()) + { + User::Leave( KErrMdENotLocked ); + } + + RPointerArray items; + CleanupClosePushL( items ); + items.AppendL( &aObject ); + UpdateItemsL( items ); + CleanupStack::PopAndDestroy( &items ); + } + +void CMdESessionImpl::CommitObjectsL(RPointerArray& aObjects) + { + // check state + // check that object is open for modifications + + RPointerArray items; + CleanupClosePushL( items ); + + const TInt objectsCount = aObjects.Count(); + items.ReserveL( objectsCount ); + for (TInt i = 0; i < objectsCount; ++i) + { + CMdEObject* obj = aObjects[i]; + if ( !obj->OpenForModifications() ) + { + User::Leave( KErrMdENotLocked ); + } + items.Append( obj ); + } + + UpdateItemsL(items); + + items.Reset(); + CleanupStack::PopAndDestroy( &items ); + } + +TItemId CMdESessionImpl::CancelObjectL(CMdEObject& aObject) + { + // check that object is open for modifications + if( !aObject.OpenForModifications() || !aObject.BelongsToSession() ) + { + User::Leave( KErrMdENotLocked ); + } + + CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC( + sizeof(TMdCItemIds) + + CMdCSerializationBuffer::KRequiredSizeForTItemId ); + + TMdCItemIds itemIds; + itemIds.iNamespaceDefId = aObject.Def().NamespaceDef().Id(); + itemIds.iObjectIds.iPtr.iCount = 1; + itemIds.iObjectIds.iPtr.iOffset = sizeof(TMdCItemIds); + itemIds.SerializeL( *buffer ); + + buffer->InsertL( aObject.Id() ); + + iSession.DoCancelObjectL( *buffer ); + + TItemId result; + buffer->PositionL( KNoOffset ); + itemIds.DeserializeL( *buffer ); + buffer->PositionL( itemIds.iObjectIds.iPtr.iOffset ); + buffer->ReceiveL( result ); + + CleanupStack::PopAndDestroy( buffer ); // buffer + + if (result == KNoId) + { + User::Leave( KErrNotFound ); + } + + aObject.SetNotOpenForModifications(); + return result; + } + +CMdERelation* CMdESessionImpl::NewRelationLC( CMdERelationDef& aDef, TItemId aLeftObjectId, + TItemId aRightObjectId, TInt32 aParameter ) + { + return CMdERelation::NewLC(aDef, aLeftObjectId, aRightObjectId, aParameter); + } + +CMdERelation* CMdESessionImpl::NewRelationL( CMdERelationDef& aDef, TItemId aLeftObjectId, + TItemId aRightObjectId, TInt32 aParameter ) + { + CMdERelation* rel = NewRelationLC( aDef, aLeftObjectId, aRightObjectId, aParameter ); + CleanupStack::Pop( rel ); + return rel; + } + + +CMdEEvent* CMdESessionImpl::NewEventLC(CMdEEventDef& aDef, TItemId aObjectId, TTime aTime, const TDesC* aSource, const TDesC* aParticipant) + { + return CMdEEvent::NewLC(aDef, aObjectId, aTime, aSource, aParticipant ); + } + +CMdEEvent* CMdESessionImpl::NewEventL(CMdEEventDef& aDef, TItemId aObjectId, TTime aTime, const TDesC* aSource, const TDesC* aParticipant) + { + CMdEEvent* event = NewEventLC( aDef, aObjectId, aTime, aSource, aParticipant ); + CleanupStack::Pop( event ); + return event; + } + +void CMdESessionImpl::AddSchemaObserverL(MMdESchemaObserver& aObserver) + { + CheckOpened(); + + CMdENamespaceDef& defaultNamespaceDef = GetDefaultNamespaceDefL(); + + TInt err = FindNotifier( ESchemaModify, &aObserver, defaultNamespaceDef ); + + if ( err != KErrNotFound ) + { + if ( err >= 0 ) + { + return; + } + User::LeaveIfError( err ); + } + + CMdENotifierAO* notifier = CMdENotifierAO::NewLC( *this, iSession ); + notifier->RegisterL( ESchemaModify, &aObserver, NULL, defaultNamespaceDef ); + User::LeaveIfError(iNotifiers.Append( notifier )); + CleanupStack::Pop( notifier ); + } + + +void CMdESessionImpl::RemoveSchemaObserverL(MMdESchemaObserver& aObserver) + { + CheckOpened(); + + CMdENamespaceDef& defaultNamespaceDef = GetDefaultNamespaceDefL(); + + TInt index = FindNotifier( ESchemaModify, &aObserver, defaultNamespaceDef ); + if ( index != KErrNotFound ) + { + iNotifiers[index]->Cancel(); + delete iNotifiers[index]; + iNotifiers[index] = NULL; + iNotifiers.Remove( index ); + } + else + { + User::Leave( KErrNotFound ); + } + } + +void CMdESessionImpl::NotifySessionOpened(TInt aError) + { + __ASSERT_DEBUG(iSessionObserver != 0, + TMdEPanic::Panic(TMdEPanic::EInternal)); + if(!aError) + { + iSessionState = EMdESessionOpen; + } + + if( iSessionObserver ) + { + iSessionObserver->HandleSessionOpened(*this, aError); + } + } + + +void CMdESessionImpl::NotifyError(TInt aError) + { + if(iSessionObserver) + { + iSessionObserver->HandleSessionError(*this, aError); + } + iSessionState = EMdESessionClosed; + } + +void CMdESessionImpl::LoadSchemaL() + { + DoLoadSchemaL(); + } + +RMdEEngineSession& CMdESessionImpl::EngineSession() + { + return iSession; + } + +void CMdESessionImpl::DoLoadSchemaL() + { + TInt handle( 0 ); + iSession.DoLoadSchemaL( handle ); + + TBuf<32> name( KSchemaChunkName ); + name.AppendNum( handle ); + iSchemaChunk.Close(); + User::LeaveIfError( iSchemaChunk.OpenGlobal( name, ETrue ) ); + + CMdCSerializationBuffer* schemaBuffer = + CMdCSerializationBuffer::NewLC( iSchemaChunk.Base(), iSchemaChunk.Size() ); + + if ( schemaBuffer->Size() == 0 ) + { + User::Leave( KErrNotFound ); + } + else + { + CleanupStack::Pop( schemaBuffer ); + } + + delete iSchemaBuffer; + + iSchemaBuffer = schemaBuffer; + + iNamespaceDefs.ResetAndDestroy(); + + // initialize namespacedefs + const TMdCSchema& schema = TMdCSchema::GetFromBufferL(*iSchemaBuffer); + const TUint32 namespaceCount = schema.iNamespaceDefs.iPtr.iCount; + const TMdCOffset namespaceOffset = schema.iNamespaceDefs.iPtr.iOffset; + + iNamespaceDefs.ReserveL( namespaceCount ); + for ( TUint32 i = 0; i < namespaceCount; ++i ) + { + iSchemaBuffer->PositionL( namespaceOffset + i * sizeof(TMdCNamespaceDef) ); + const TMdCNamespaceDef& namespaceDef = TMdCNamespaceDef::GetFromBufferL(*iSchemaBuffer); + iNamespaceDefs.AppendL( CMdENamespaceDef::NewL( *this, namespaceDef, *iSchemaBuffer ) ); + } + } + +void CMdESessionImpl::AddRelationDefL( const CMdENamespaceDef &aNamespaceDef, const TDesC &aName ) + { + iSession.DoAddRelationDefL(aNamespaceDef.Id(), aName); + DoLoadSchemaL(); + } + +void CMdESessionImpl::AddEventDefL( const CMdENamespaceDef &aNamespaceDef, const TDesC &aName ) + { + iSession.DoAddEventDefL(aNamespaceDef.Id(), aName); + DoLoadSchemaL(); + } + +/** +* Get methods +*/ +CMdEObject* CMdESessionImpl::GetObjectL(CMdEObjectDef& aObjectDef, + const TItemId aId, const TInt64 aGuidHigh, const TInt64 aGuidLow, const TDesC& aUri, + TMdCQueryLockType aLocktype, TBool aIncludeFreetexts ) + { + if(aUri == KNullDesC && aGuidHigh == 0 && aGuidLow == 0 && aId == KNoId) + { + User::Leave(KErrNotSupported); + } + + CMdENamespaceDef &namespacedef = aObjectDef.NamespaceDef(); + + CMdEObjectQuery* query = NewObjectQueryL(namespacedef,aObjectDef,NULL); + CleanupStack::PushL(query); + + query->SetResultMode(EQueryResultModeItem); + + if(aId != KNoId) + { + CMdEObjectCondition& cond = query->Conditions().AddObjectConditionL( aId ); + cond.SetConfidentialityLevel( EObjectConditionLevelIgnoreConfidentiality ); + } + else if(aGuidHigh != 0 && aGuidLow != 0) + { + CMdEObjectCondition& cond = query->Conditions().AddObjectConditionL( aGuidHigh, aGuidLow ); + cond.SetConfidentialityLevel( EObjectConditionLevelIgnoreConfidentiality ); + } + else if(aUri != KNullDesC) + { + CMdEObjectCondition& cond = query->Conditions().AddObjectConditionL( EObjectConditionCompareUri, aUri ); + cond.SetConfidentialityLevel( EObjectConditionLevelIgnoreConfidentiality ); + } + else + { + User::Leave( KErrArgument ); + } + + TUint32 optimizationFlags = EContainsObjectCondition; + + if( aIncludeFreetexts ) + { + optimizationFlags |= EContainsFreetextCondition; + } + + if( aLocktype == ELock ) + { + optimizationFlags |= EContainsObjectLocking; + } + + CMdEQueryCriteriaSerialization* buf = CMdEQueryCriteriaSerialization::NewLC( + query->ResultMode(), + query->Type(), + query->NamespaceDef(), + &aObjectDef, + NULL, + 1, //Max 1 + 0, // 0 offset because it's not used now + optimizationFlags , + query->Conditions(), + query->OrderRules(), + NULL); + + CMdCSerializationBuffer* resbuf = iSession.DoFindSyncLC( + query, + *buf, aLocktype, + KMdEQueryDefaultMaxCount ); + + RPointerArray items; + CleanupClosePushL( items ); + + DeserializeQueryResultL( *resbuf, items ); + + CleanupStack::Pop( &items ); + + CleanupStack::PopAndDestroy( resbuf ); + CleanupStack::PopAndDestroy( buf ); + CleanupStack::PopAndDestroy( query ); + + const TInt itemsCount( items.Count() ); + if( itemsCount== 1 ) + { + CMdEInstanceItem* item = items[0]; + +#ifdef _DEBUG + if( !item || item->InstanceType() != EMdETypeObject ) + { + User::Leave( KErrCorrupt ); + } +#endif + + items.Close(); + + return (CMdEObject*)item; + } + else if( itemsCount == 0 ) + { + items.Close(); + + return NULL; + } + +#ifdef _DEBUG + else + { + items.ResetAndDestroy(); + items.Close(); + + User::Leave( KErrCorrupt ); + } +#endif + + return NULL; // <-- just to stop compile warnings!! + } + +CMdEObject* CMdESessionImpl::GetObjectL( const TItemId aId, CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = GetNamespaceDefL( aNamespaceDef ); + + CMdEObjectDef* objectDef = namespaceDef->GetObjectDefL( KBaseObjectDefId ); + if ( !objectDef ) + { + User::Leave( KErrNotFound ); + } + return GetObjectL(*objectDef, aId, 0, 0, KNullDesC, EGet, EFalse); + } + +CMdEObject* CMdESessionImpl::GetFullObjectL( const TItemId aId, CMdENamespaceDef* aNamespaceDef ) + { + TMdEObject object; + + CheckObjectL( object, aId, aNamespaceDef ); + + if( object.NotPresent() || object.Removed() ) + { + User::Leave( KErrNotFound ); + } + + const CMdEObjectDef& objectDef = object.DefL(); + + return GetObjectL( CONST_CAST( CMdEObjectDef&, objectDef ), aId, 0, 0, KNullDesC, EGet, ETrue ); + } + +CMdEObject* CMdESessionImpl::GetObjectL( const TItemId aId, CMdEObjectDef& aObjectDef ) + { + return GetObjectL(aObjectDef, aId, 0, 0, KNullDesC, EGet, EFalse); + } + +CMdEObject* CMdESessionImpl::GetObjectL( const TInt64 aGuidHigh, const TInt64 aGuidLow, CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = GetNamespaceDefL( aNamespaceDef ); + + CMdEObjectDef* objectDef = namespaceDef->GetObjectDefL( KBaseObjectDefId ); + if ( !objectDef ) + { + User::Leave( KErrNotFound ); + } + return GetObjectL(*objectDef, KNoId, aGuidHigh, aGuidLow, KNullDesC, EGet, EFalse); + } + +CMdEObject* CMdESessionImpl::GetFullObjectL( const TInt64 aGuidHigh, const TInt64 aGuidLow, CMdENamespaceDef* aNamespaceDef ) + { + CMdEObject* object = NULL; + + object = GetObjectL( aGuidHigh, aGuidLow, aNamespaceDef ); + + if ( object ) + { + CMdEObjectDef& objectDef = object->Def(); + TItemId objId = object->Id(); + + delete object; + object = NULL; + object = GetObjectL( objectDef, objId, 0, 0, KNullDesC, EGet, ETrue ); + } + + return object; + } + +CMdEObject* CMdESessionImpl::GetObjectL( const TInt64 aGuidHigh, const TInt64 aGuidLow, CMdEObjectDef& aObjectDef ) + { + return GetObjectL(aObjectDef, KNoId, aGuidHigh, aGuidLow, KNullDesC, EGet, EFalse); + } + +CMdEObject* CMdESessionImpl::OpenObjectL( const TItemId aId, CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = GetNamespaceDefL( aNamespaceDef ); + + CMdEObjectDef* objectDef = namespaceDef->GetObjectDefL( KBaseObjectDefId ); + if ( !objectDef ) + { + User::Leave( KErrNotFound ); + } + + CMdEObject* object = GetObjectL(*objectDef, aId, 0, 0, KNullDesC, ELock, EFalse); + + if ( object && !object->OpenForModifications() ) + { + delete object; + object = NULL; + User::Leave( KErrLocked ); + } + + return object; + } + +CMdEObject* CMdESessionImpl::OpenFullObjectL( const TItemId aId, CMdENamespaceDef* aNamespaceDef ) + { + TMdEObject object; + + CheckObjectL( object, aId, aNamespaceDef ); + + if( object.NotPresent() || object.Removed() ) + { + User::Leave( KErrNotFound ); + } + + const CMdEObjectDef& objectDef = object.DefL(); + + return GetObjectL( CONST_CAST( CMdEObjectDef&, objectDef ), aId, 0, 0, KNullDesC, ELock, ETrue ); + } + +CMdEObject* CMdESessionImpl::OpenObjectL( const TItemId aId, CMdEObjectDef& aObjectDef ) + { + CMdEObject* object = GetObjectL(aObjectDef, aId, 0, 0, KNullDesC, ELock, EFalse); + + if( object && !object->OpenForModifications() ) + { + delete object; + object = NULL; + User::Leave( KErrLocked ); + } + + return object; + } + +CMdEObject* CMdESessionImpl::OpenObjectL( const TInt64 aGuidHigh, const TInt64 aGuidLow, CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = GetNamespaceDefL( aNamespaceDef ); + + CMdEObjectDef* objectDef = namespaceDef->GetObjectDefL( KBaseObjectDefId ); + if ( !objectDef ) + { + User::Leave( KErrNotFound ); + } + + CMdEObject* object = GetObjectL(*objectDef, KNoId, aGuidHigh, aGuidLow, KNullDesC, ELock, EFalse); + + if( object && !object->OpenForModifications() ) + { + delete object; + object = NULL; + User::Leave( KErrLocked ); + } + + return object; + } + +CMdEObject* CMdESessionImpl::OpenFullObjectL( const TInt64 aGuidHigh, const TInt64 aGuidLow, CMdENamespaceDef* aNamespaceDef ) + { + CMdEObject* object = NULL; + + object = GetObjectL( aGuidHigh, aGuidLow, aNamespaceDef ); + + if( object ) + { + CMdEObjectDef& objectDef = object->Def(); + TItemId objId = object->Id(); + + delete object; + object = NULL; + + object = GetObjectL( CONST_CAST( CMdEObjectDef&, objectDef ), objId, 0, 0, KNullDesC, ELock, ETrue ); + } + + return object; + } + +CMdEObject* CMdESessionImpl::OpenObjectL( const TInt64 aGuidHigh, const TInt64 aGuidLow, CMdEObjectDef& aObjectDef ) + { + CMdEObject* object = GetObjectL(aObjectDef, KNoId, aGuidHigh, aGuidLow, KNullDesC, ELock, EFalse); + + if( object && !object->OpenForModifications() ) + { + delete object; + object = NULL; + User::Leave( KErrLocked ); + } + + return object; + } + +EXPORT_C CMdEObject* CMdESessionImpl::GetObjectL( const TDesC& aUri, CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = aNamespaceDef; + + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + + CMdEObjectDef* objectDef = namespaceDef->GetObjectDefL( KBaseObjectDefId ); + if ( !objectDef ) + { + User::Leave( KErrNotFound ); + } + + return GetObjectL(*objectDef, KNoId, 0, 0, aUri, EGet, EFalse); + } + +CMdEObject* CMdESessionImpl::GetFullObjectL( const TDesC& aUri, CMdENamespaceDef* aNamespaceDef ) + { + TMdEObject object; + + CheckObjectL( object, aUri, aNamespaceDef ); + + if( object.NotPresent() || object.Removed() ) + { + User::Leave( KErrNotFound ); + } + + const CMdEObjectDef& objectDef = object.DefL(); + TItemId objId = object.Id(); + + return GetObjectL( CONST_CAST( CMdEObjectDef&, objectDef ), objId, 0, 0, KNullDesC, EGet, ETrue ); + } + +CMdEObject* CMdESessionImpl::GetObjectL( const TDesC& aUri, CMdEObjectDef& aObjectDef ) + { + return GetObjectL( aObjectDef, KNoId, 0, 0, aUri, EGet, EFalse ); + } + + +CMdEObject* CMdESessionImpl::OpenObjectL( const TDesC& aUri, CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = aNamespaceDef; + + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + + CMdEObjectDef* objectDef = namespaceDef->GetObjectDefL( KBaseObjectDefId ); + if ( !objectDef ) + { + User::Leave( KErrNotFound ); + } + + CMdEObject* object = GetObjectL(*objectDef, KNoId, 0, 0, aUri, ELock, EFalse); + + if( object && !object->OpenForModifications() ) + { + delete object; + object = NULL; + User::Leave( KErrLocked ); + } + + return object; + } + +CMdEObject* CMdESessionImpl::OpenFullObjectL( const TDesC& aUri, CMdENamespaceDef* aNamespaceDef ) + { + TMdEObject object; + + CheckObjectL( object, aUri, aNamespaceDef ); + + if( object.NotPresent() || object.Removed() ) + { + User::Leave( KErrNotFound ); + } + + const CMdEObjectDef& objectDef = object.DefL(); + TItemId objId = object.Id(); + + return GetObjectL( CONST_CAST( CMdEObjectDef&, objectDef ), objId, 0, 0, KNullDesC, ELock, ETrue ); + } + +CMdEObject* CMdESessionImpl::OpenObjectL( const TDesC& aUri, CMdEObjectDef& aObjectDef ) + { + CMdEObject* object = GetObjectL(aObjectDef, KNoId, 0, 0, aUri, ELock, EFalse); + + if( object && !object->OpenForModifications() ) + { + delete object; + object = NULL; + User::Leave( KErrLocked ); + } + + return object; + } + +void CMdESessionImpl::CheckObjectL( TMdEObject& aObject, const TDesC& aUri, + CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef& namespaceDef = *GetNamespaceDefL( aNamespaceDef ); + + CMdCSerializationBuffer* object = + CMdCSerializationBuffer::NewLC( aObject.RequiredBufferSize() ); + + iSession.DoCheckObjectL( *object, aUri, namespaceDef.Id() ); + + object->PositionL( KNoOffset ); + aObject.DeSerializeL( *object, namespaceDef ); + + CleanupStack::PopAndDestroy( object ); + } + +void CMdESessionImpl::CheckObjectL( TMdEObject& aObject, TItemId aId, + CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef& namespaceDef = *GetNamespaceDefL( aNamespaceDef ); + + CMdCSerializationBuffer* object = + CMdCSerializationBuffer::NewLC( aObject.RequiredBufferSize() ); + + iSession.DoCheckObjectL( *object, aId, namespaceDef.Id() ); + + object->PositionL( KNoOffset ); + aObject.DeSerializeL( *object, namespaceDef ); + + CleanupStack::PopAndDestroy( object ); + } + +void CMdESessionImpl::CheckObjectL( RArray& aObjects, + const RArray& aIds, CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef& namespaceDef = *GetNamespaceDefL( aNamespaceDef ); + + const TUint32 idCount = (TUint32)aIds.Count(); + + CMdCSerializationBuffer* objects = + CMdCSerializationBuffer::NewLC( + CMdCSerializationBuffer::KRequiredSizeForTUint32 + + TMdEObject::RequiredBufferSize() * idCount ); + + CMdCSerializationBuffer* ids = + CMdCSerializationBuffer::NewLC( + CMdCSerializationBuffer::KRequiredSizeForTUint32 + + CMdCSerializationBuffer::KRequiredSizeForTItemId * idCount ); + + ids->InsertL( idCount ); + for( TUint32 i = 0; i < idCount; i++ ) + { + ids->InsertL( aIds[i] ); + } + + iSession.DoCheckObjectL( *objects, *ids, namespaceDef.Id() ); + + objects->PositionL( KNoOffset ); + + TUint32 objectCount = 0; + objects->ReceiveL( objectCount ); + + aObjects.ReserveL( objectCount ); + + for( TUint32 i = 0; i < objectCount; i++ ) + { + aObjects.AppendL( TMdEObject() ); + aObjects[i].DeSerializeL( *objects, namespaceDef ); + } + + CleanupStack::PopAndDestroy( ids ); + CleanupStack::PopAndDestroy( objects ); + } + +CMdERelation* CMdESessionImpl::GetRelationL(TItemId aId, CMdENamespaceDef* aNamespaceDef) + { + CMdERelationQuery* query = NewRelationQueryL( *GetNamespaceDefL( aNamespaceDef ), NULL ); + query->SetResultMode( EQueryResultModeItem ); + CleanupStack::PushL( query ); + + query->Conditions().AddRelationConditionL( aId ); + + CMdEQueryCriteriaSerialization* buf = CMdEQueryCriteriaSerialization::NewLC( + query->ResultMode(), + query->Type(), + query->NamespaceDef(), + NULL, + NULL, + 1, //Max 1 + 0, // 0 offset because it's not used now + EContainsRelationCondition, + query->Conditions(), + query->OrderRules(), + NULL); + + + CMdCSerializationBuffer* resbuf = iSession.DoFindSyncLC( + query, + *buf, EGet, + KMdEQueryDefaultMaxCount); + + RPointerArray items; + CleanupClosePushL( items ); + + DeserializeQueryResultL( *resbuf, items ); + + CleanupStack::Pop( &items ); + + CleanupStack::PopAndDestroy(resbuf); + CleanupStack::PopAndDestroy( buf ); + CleanupStack::PopAndDestroy( query ); + + const TInt itemsCount( items.Count() ); + if( itemsCount== 1 ) + { + CMdEInstanceItem* item = items[0]; + +#ifdef _DEBUG + if ( !item || item->InstanceType() != EMdETypeRelation ) + { + User::Leave( KErrCorrupt ); + } +#endif + + items.Close(); + + return (CMdERelation*)item; + } + else if( itemsCount == 0 ) + { + items.Close(); + return NULL; + } +#ifdef _DEBUG + else + { + items.ResetAndDestroy(); + items.Close(); + + User::Leave( KErrCorrupt ); + } +#endif + + return NULL; // <-- just to stop compile warnings!! + } + +CMdEEvent* CMdESessionImpl::GetEventL(TItemId aId, + CMdENamespaceDef* aNamespaceDef) + { + CMdENamespaceDef* namespaceDef = aNamespaceDef; + + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + + CMdEEventQuery * query = NewEventQueryL(*namespaceDef,NULL); + query->SetResultMode(EQueryResultModeItem); + CleanupStack::PushL(query); + + query->Conditions().AddEventConditionL(aId); + + CMdEQueryCriteriaSerialization* buf = CMdEQueryCriteriaSerialization::NewLC( + query->ResultMode(), + query->Type(), + query->NamespaceDef(), + NULL, + NULL, + 1, //Max 1 + 0, // 0 offset because it's not used now + EContainsEventCondition, + query->Conditions(), + query->OrderRules(), + NULL); + + CMdCSerializationBuffer* resbuf = iSession.DoFindSyncLC( + query, + *buf, EGet, + KMdEQueryDefaultMaxCount); + + RPointerArray items; + CleanupClosePushL( items ); + + DeserializeQueryResultL( *resbuf, items ); + + CleanupStack::Pop( &items ); + + CleanupStack::PopAndDestroy(resbuf); + CleanupStack::PopAndDestroy( buf ); + CleanupStack::PopAndDestroy( query ); + + const TInt itemsCount( items.Count() ); + if( itemsCount == 1 ) + { + CMdEInstanceItem* item = items[0]; + +#ifdef _DEBUG + if ( !item || item->InstanceType() != EMdETypeEvent ) + { + User::Leave( KErrCorrupt ); + } +#endif + + items.Close(); + + return (CMdEEvent*)item; + } + else if( itemsCount == 0 ) + { + items.Close(); + + return NULL; + } +#ifdef _DEBUG + else + { + items.ResetAndDestroy(); + items.Close(); + + User::Leave( KErrCorrupt ); + } +#endif + + return NULL; // <-- just to stop compile warnings!! + } + +/** +* Remove methods +*/ +CMdCSerializationBuffer* CMdESessionImpl::RemoveCommonL( + CMdENamespaceDef& aNamespaceDef, const RArray* aObjects, + const RArray* aEvents, const RArray* aRelations ) + { + if ( !( (aObjects && aObjects->Count()) || + (aEvents && aEvents->Count()) || + (aRelations && aRelations->Count()) ) ) + { + User::Leave( KErrArgument ); + } + + TMdCItemIds itemIds; + itemIds.iNamespaceDefId = aNamespaceDef.Id(); + itemIds.iObjectUris.iPtr.iCount = 0; + itemIds.iObjectUris.iPtr.iOffset = KNoOffset; + + // headerSize + TUint32 bufferSize = sizeof(TMdCItemIds); + + if ( aObjects ) + { + bufferSize += aObjects->Count() * CMdCSerializationBuffer::KRequiredSizeForTItemId; + } + if ( aEvents ) + { + bufferSize += aEvents->Count() * CMdCSerializationBuffer::KRequiredSizeForTItemId; + } + if ( aRelations ) + { + bufferSize += aRelations->Count() * CMdCSerializationBuffer::KRequiredSizeForTItemId; + } + + CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC( bufferSize ); + + buffer->PositionL( sizeof(TMdCItemIds) ); + + // insert objects + if ( aObjects ) + { + const TInt count = aObjects->Count(); + itemIds.iObjectIds.iPtr.iCount = count; + itemIds.iObjectIds.iPtr.iOffset = buffer->Position(); + + for ( TInt i = 0; i < count; ++i ) + { + buffer->InsertL( (*aObjects)[i] ); + } + } + else + { + itemIds.iObjectIds.iPtr.iCount = 0; + itemIds.iObjectIds.iPtr.iOffset = KNoOffset; + } + + // insert events + if ( aEvents ) + { + const TInt count = aEvents->Count(); + itemIds.iEventIds.iPtr.iCount = count; + itemIds.iEventIds.iPtr.iOffset = buffer->Position(); + + for ( TInt i = 0; i < count; ++i ) + { + buffer->InsertL( (*aEvents)[i] ); + } + } + else + { + itemIds.iEventIds.iPtr.iCount = 0; + itemIds.iEventIds.iPtr.iOffset = KNoOffset; + } + + // insert relations + if ( aRelations ) + { + const TInt count = aRelations->Count(); + itemIds.iRelationIds.iPtr.iCount = count; + itemIds.iRelationIds.iPtr.iOffset = buffer->Position(); + + for ( TInt i = 0; i < count; ++i ) + { + buffer->InsertL( (*aRelations)[i] ); + } + } + else + { + itemIds.iRelationIds.iPtr.iCount = 0; + itemIds.iRelationIds.iPtr.iOffset = KNoOffset; + } + + // set up header correctly + buffer->PositionL( KNoOffset ); + itemIds.SerializeL( *buffer ); + + CleanupStack::Pop( buffer ); + return buffer; + } + +CMdCSerializationBuffer* CMdESessionImpl::RemoveCommonL( + CMdENamespaceDef& aNamespaceDef, + const RPointerArray* aObjects, + const RArray* aEvents, const RArray* aRelations ) + { + if ( !( (aObjects && aObjects->Count()) || + (aEvents && aEvents->Count()) || + (aRelations && aRelations->Count()) ) ) + { + User::Leave( KErrArgument ); + } + + TMdCItemIds itemIds; + itemIds.iNamespaceDefId = aNamespaceDef.Id(); + itemIds.iObjectIds.iPtr.iCount = 0; + itemIds.iObjectIds.iPtr.iOffset = KNoOffset; + + // headerSize + TUint32 bufferSize = sizeof(TMdCItemIds); + + if ( aObjects ) + { + const TInt count = aObjects->Count(); + for ( TInt i = 0; i < count; ++i ) + { + bufferSize += CMdCSerializationBuffer::RequiredSize( *((*aObjects)[i]) ); + } + } + if ( aEvents ) + { + bufferSize += aEvents->Count() * CMdCSerializationBuffer::KRequiredSizeForTItemId; + } + if ( aRelations ) + { + bufferSize += aRelations->Count() * CMdCSerializationBuffer::KRequiredSizeForTItemId; + } + + CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC( bufferSize ); + + buffer->PositionL( sizeof(TMdCItemIds) ); + + // insert objects + if ( aObjects ) + { + const TInt count = aObjects->Count(); + itemIds.iObjectUris.iPtr.iCount = count; + itemIds.iObjectUris.iPtr.iOffset = buffer->Position(); + + for ( TInt i = 0; i < count; ++i ) + { + const TDesC& uri = *((*aObjects)[i]); + HBufC* lcUri = HBufC::NewLC( uri.Length() ); + lcUri->Des().CopyLC( uri ); + buffer->InsertL( *lcUri ); + CleanupStack::PopAndDestroy( lcUri ); + } + } + else + { + itemIds.iObjectUris.iPtr.iCount = 0; + itemIds.iObjectUris.iPtr.iOffset = KNoOffset; + } + + // insert events + if ( aEvents ) + { + const TInt count = aEvents->Count(); + itemIds.iEventIds.iPtr.iCount = count; + itemIds.iEventIds.iPtr.iOffset = buffer->Position(); + + for ( TInt i = 0; i < count; ++i ) + { + buffer->InsertL( (*aEvents)[i] ); + } + } + else + { + itemIds.iEventIds.iPtr.iCount = 0; + itemIds.iEventIds.iPtr.iOffset = KNoOffset; + } + + // insert relations + if ( aRelations ) + { + const TInt count = aRelations->Count(); + itemIds.iRelationIds.iPtr.iCount = count; + itemIds.iRelationIds.iPtr.iOffset = buffer->Position(); + + for ( TInt i = 0; i < count; ++i ) + { + buffer->InsertL( (*aRelations)[i] ); + } + } + else + { + itemIds.iRelationIds.iPtr.iCount = 0; + itemIds.iRelationIds.iPtr.iOffset = KNoOffset; + } + + // set up header correctly + buffer->PositionL( KNoOffset ); + itemIds.SerializeL( *buffer ); + + CleanupStack::Pop( buffer ); + return buffer; + } + +TInt CMdESessionImpl::DeserializeIdsL( RMdEDataBuffer& aSerializedItemIds, + RArray* aResultObjects, RArray* aResultEvents, + RArray* aResultRelations ) + { + CMdCSerializationBuffer* buffer = aSerializedItemIds.GetBufferLC(); + + const TMdCItemIds& itemIds = TMdCItemIds::GetFromBufferL( *buffer ); + + if ( itemIds.iObjectIds.iPtr.iCount > 0 && aResultObjects ) + { + buffer->PositionL( itemIds.iObjectIds.iPtr.iOffset ); + TItemId objectId; + aResultObjects->ReserveL( itemIds.iObjectIds.iPtr.iCount ); + for (TUint32 i = 0; i < itemIds.iObjectIds.iPtr.iCount; ++i) + { + buffer->ReceiveL( objectId ); + aResultObjects->AppendL( objectId ); + } + } + + if ( itemIds.iEventIds.iPtr.iCount > 0 && aResultEvents ) + { + buffer->PositionL( itemIds.iEventIds.iPtr.iOffset ); + TItemId eventId; + aResultEvents->ReserveL( itemIds.iEventIds.iPtr.iCount ); + for (TUint32 i = 0; i < itemIds.iEventIds.iPtr.iCount; ++i) + { + buffer->ReceiveL( eventId ); + aResultEvents->AppendL( eventId ); + } + } + + if ( itemIds.iRelationIds.iPtr.iCount > 0 && aResultRelations ) + { + buffer->PositionL( itemIds.iRelationIds.iPtr.iOffset ); + TItemId relationId; + aResultRelations->ReserveL( itemIds.iRelationIds.iPtr.iCount ); + for (TUint32 i = 0; i < itemIds.iRelationIds.iPtr.iCount; ++i) + { + buffer->ReceiveL( relationId ); + aResultRelations->AppendL( relationId ); + } + } + + const TInt errorCode = itemIds.iErrorCode; + CleanupStack::PopAndDestroy( buffer ); + + return errorCode; + } + +TItemId CMdESessionImpl::RemoveObjectL( TItemId aId, + CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = aNamespaceDef; + + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + + RArray removeIdArray; + CleanupClosePushL( removeIdArray ); + RArray resultObjectArray; + CleanupClosePushL( resultObjectArray ); + removeIdArray.AppendL( aId ); + User::LeaveIfError( RemoveObjectsL( removeIdArray, resultObjectArray, + namespaceDef ) ); + TItemId result = KNoId; + if ( resultObjectArray.Count() ) + { + result = resultObjectArray[0]; + } + CleanupStack::PopAndDestroy( 2, &removeIdArray ); // resultObjectArray, removeIdArray + return result; + } + +TItemId CMdESessionImpl::RemoveObjectL( const TDesC& aUri, + CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = aNamespaceDef; + + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + + RPointerArray removeUriArray; + CleanupClosePushL( removeUriArray ); + RArray resultObjectArray; + CleanupClosePushL( resultObjectArray ); + removeUriArray.AppendL( &aUri ); + User::LeaveIfError( RemoveObjectsL( removeUriArray, resultObjectArray, + namespaceDef ) ); + TItemId result = KNoId; + if ( resultObjectArray.Count() ) + { + result = resultObjectArray[0]; + } + CleanupStack::PopAndDestroy( 2, &removeUriArray ); // resultObjectArray, removeUriArray + return result; + } + +TInt CMdESessionImpl::RemoveObjectsL( const RArray& aId, + RArray& aResult, CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = aNamespaceDef; + + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + + CMdCSerializationBuffer* buffer = RemoveCommonL( *namespaceDef, &aId, + NULL, NULL ); + CleanupStack::PushL( buffer ); + CMdCSerializationBuffer* resultBuffer = CMdCSerializationBuffer::NewLC( + buffer->Size() ); + RMdEDataBuffer dataBuffer; + dataBuffer.SetBufferL( resultBuffer ); + CleanupStack::Pop( resultBuffer ); + CleanupClosePushL( dataBuffer ); + + iSession.DoRemoveItemsL( *buffer, *resultBuffer ); + TInt32 firstItemError = DeserializeIdsL( dataBuffer, &aResult ); + CleanupStack::PopAndDestroy( 2, buffer ); // successfulBuffer, buffer + return firstItemError; + } + +TInt CMdESessionImpl::RemoveObjectsL( const RPointerArray& aUri, + RArray& aResult, CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = aNamespaceDef; + + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + + CMdCSerializationBuffer* buffer = RemoveCommonL( *namespaceDef, &aUri, NULL, NULL ); + CleanupStack::PushL( buffer ); + const TUint32 rbs = sizeof( TMdCItemIds ) + + ( aUri.Count() + 2 ) * CMdCSerializationBuffer::KRequiredSizeForTItemId; + + CMdCSerializationBuffer* resultBuffer = CMdCSerializationBuffer::NewLC( rbs ); + RMdEDataBuffer dataBuffer; + dataBuffer.SetBufferL( resultBuffer ); + CleanupStack::Pop( resultBuffer ); + CleanupClosePushL( dataBuffer ); + + iSession.DoRemoveItemsL( *buffer, *resultBuffer ); + TInt32 firstItemError = DeserializeIdsL( dataBuffer, &aResult ); + CleanupStack::PopAndDestroy( &dataBuffer ); + CleanupStack::PopAndDestroy( buffer ); + return firstItemError; + } + +void CMdESessionImpl::RemoveObjectsAsyncL( + const RArray& aId, TRequestStatus& aStatus, + RMdEDataBuffer& aSerializedObjectIds, + CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = aNamespaceDef; + + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + + CMdCSerializationBuffer* buffer = RemoveCommonL( *namespaceDef, &aId, + NULL, NULL ); + CleanupStack::PushL( buffer ); + CMdCSerializationBuffer* resultBuffer = CMdCSerializationBuffer::NewLC( + buffer->Size() ); + aSerializedObjectIds.SetBufferL( resultBuffer ); + CleanupStack::Pop( resultBuffer ); + + CleanupStack::Pop( buffer ); + + iAsyncHandler->RemoveRequest( buffer, *resultBuffer, aStatus ); + } + +void CMdESessionImpl::RemoveObjectsAsyncL( + const RPointerArray& aUri, TRequestStatus& aStatus, + RMdEDataBuffer& aSerializedObjectIds, + CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = aNamespaceDef; + + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + + CMdCSerializationBuffer* buffer = RemoveCommonL( *namespaceDef, &aUri, + NULL, NULL ); + CleanupStack::PushL( buffer ); + const TUint32 rbs = sizeof( TMdCItemIds ) + + ( aUri.Count() + 2 ) * CMdCSerializationBuffer::KRequiredSizeForTItemId; + + CMdCSerializationBuffer* resultBuffer = CMdCSerializationBuffer::NewLC( rbs ); + aSerializedObjectIds.SetBufferL( resultBuffer ); + CleanupStack::Pop( resultBuffer ); + CleanupStack::Pop( buffer ); + + iAsyncHandler->RemoveRequest( buffer, *resultBuffer, aStatus ); + } + +TItemId CMdESessionImpl::RemoveRelationL(TItemId aId, + CMdENamespaceDef* aNamespaceDef) + { + RArray items; + CleanupClosePushL( items ); + RArray successful; + CleanupClosePushL( successful ); + + items.AppendL( aId ); + User::LeaveIfError( RemoveRelationsL( items, successful, aNamespaceDef ) ); + + TItemId result = KNoId; + if ( successful.Count() ) + { + result = successful[0]; + } + CleanupStack::PopAndDestroy( 2, &items ); + return result; + } + +TInt CMdESessionImpl::RemoveRelationsL(const RArray& aId, + RArray& aSuccessful, CMdENamespaceDef* aNamespaceDef) + { + CMdENamespaceDef* namespaceDef = aNamespaceDef; + + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + + CMdCSerializationBuffer* buffer = RemoveCommonL( *namespaceDef, + (RArray*)NULL, NULL, &aId ); + CleanupStack::PushL( buffer ); + CMdCSerializationBuffer* successfulBuffer = CMdCSerializationBuffer::NewLC( + buffer->Size() ); + iSession.DoRemoveItemsL( *buffer, *successfulBuffer ); + + RMdEDataBuffer dataBuffer; + dataBuffer.SetBufferL( successfulBuffer ); + CleanupStack::Pop( successfulBuffer ); + CleanupClosePushL( dataBuffer ); + + TInt firstItemError = DeserializeIdsL( dataBuffer, NULL, NULL, + &aSuccessful ); + CleanupStack::PopAndDestroy( &dataBuffer ); // successfulBuffer, buffer + CleanupStack::PopAndDestroy( buffer ); // successfulBuffer, buffer + return firstItemError; + } + +void CMdESessionImpl::RemoveRelationsAsyncL( + const RArray& aId, TRequestStatus& aStatus, + RMdEDataBuffer& aSerializedRelationIds, + CMdENamespaceDef* aNamespaceDef) + { + CMdENamespaceDef* namespaceDef = aNamespaceDef; + + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + + CMdCSerializationBuffer* buffer = RemoveCommonL( *namespaceDef, + (RArray*)NULL, NULL, &aId ); + CleanupStack::PushL( buffer ); + CMdCSerializationBuffer* resultBuffer = CMdCSerializationBuffer::NewLC( + buffer->Size() ); + aSerializedRelationIds.SetBufferL( resultBuffer ); + CleanupStack::Pop( resultBuffer ); + CleanupStack::Pop( buffer ); + + iAsyncHandler->RemoveRequest( buffer, *resultBuffer, aStatus ); + } + +/** +* Add methods +*/ +TItemId CMdESessionImpl::AddItemL( CMdEInstanceItem& aItem ) + { + RPointerArray items; + CleanupClosePushL( items ); + items.Append( &aItem ); + User::LeaveIfError( AddItemsL( items ) ); + CleanupStack::PopAndDestroy( &items ); + return aItem.Id(); + } + +CMdCSerializationBuffer* CMdESessionImpl::SerializeItemsL( + RPointerArray& aItems ) + { + const TInt itemsCount = aItems.Count(); + if ( itemsCount == 0 ) + { + User::Leave(KErrArgument); + return NULL; + } + + TInt requiredBufferSize = sizeof(TMdCItems); + + // counting items and required buffer size + TMdCItems items; + items.iNamespaceDefId = KNoDefId; + items.iErrorCode = KErrNone; + items.iObjects.iPtr.iCount = 0; + items.iObjects.iPtr.iOffset = 0; + items.iRelations.iPtr.iCount = 0; + items.iRelations.iPtr.iOffset = 0; + items.iEvents.iPtr.iCount = 0; + items.iEvents.iPtr.iOffset = 0; + + for ( TInt i = 0; i < itemsCount; ++i ) + { + switch (aItems[i]->InstanceType()) + { + case EMdETypeObject: + { + requiredBufferSize += static_cast(aItems[i])->RequiredBufferSize(); + ++items.iObjects.iPtr.iCount; + const TDefId nmspId = static_cast(aItems[i])->Def().NamespaceDef().Id(); + if (items.iNamespaceDefId == KNoDefId) + { + items.iNamespaceDefId = nmspId; + } + else if ( items.iNamespaceDefId != nmspId ) + { + User::Leave(KErrArgument); + } + break; + } + case EMdETypeRelation: + { + requiredBufferSize += static_cast(aItems[i])->RequiredBufferSize(); + ++items.iRelations.iPtr.iCount; + const TDefId nmspId = static_cast(aItems[i])->Def().NamespaceDef().Id(); + if (items.iNamespaceDefId == KNoDefId) + { + items.iNamespaceDefId = nmspId; + } + else if ( items.iNamespaceDefId != nmspId ) + { + User::Leave(KErrArgument); + } + break; + } + case EMdETypeEvent: + { + requiredBufferSize += static_cast(aItems[i])->RequiredBufferSize(); + ++items.iEvents.iPtr.iCount; + const TDefId nmspId = static_cast(aItems[i])->Def().NamespaceDef().Id(); + if (items.iNamespaceDefId == KNoDefId) + { + items.iNamespaceDefId = nmspId; + } + else if ( items.iNamespaceDefId != nmspId ) + { + User::Leave(KErrArgument); + } + break; + } + default: + { + User::Leave(KErrArgument); + } + } + } + + CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC( requiredBufferSize ); + + // move after main header + TMdCOffset freespaceOffset = sizeof( TMdCItems ); + + if (items.iObjects.iPtr.iCount) + { + // add objects header + items.iObjects.iPtr.iOffset = freespaceOffset; + freespaceOffset += items.iObjects.iPtr.iCount * sizeof( TMdCObject ); + } + if (items.iEvents.iPtr.iCount) + { + // add events header + items.iEvents.iPtr.iOffset = freespaceOffset; + freespaceOffset += items.iEvents.iPtr.iCount * sizeof( TMdCEvent ); + } + if (items.iRelations.iPtr.iCount) + { + // add relations header + items.iRelations.iPtr.iOffset = freespaceOffset; + freespaceOffset += items.iRelations.iPtr.iCount * sizeof( TMdCRelation ); + } + + TUint32 objectCtr = 0; + TUint32 relationCtr = 0; + TUint32 eventCtr = 0; + for ( TInt i = 0; i < itemsCount; ++i ) + { + const TUint32 actualPosition = buffer->Position(); + switch (aItems[i]->InstanceType()) + { + case EMdETypeObject: + { + CMdEObject* object = static_cast(aItems[i]); + // set right offset + buffer->PositionL( items.iObjects.iPtr.iOffset + objectCtr * sizeof(TMdCObject) ); + freespaceOffset = object->SerializeL( *buffer, freespaceOffset ); + ++objectCtr; + break; + } + case EMdETypeRelation: + { + CMdERelation* relation = static_cast(aItems[i]); + // set right offset + buffer->PositionL( items.iRelations.iPtr.iOffset + relationCtr * sizeof(TMdCRelation) ); + freespaceOffset = relation->SerializeL( *buffer, freespaceOffset ); + ++relationCtr; + break; + } + case EMdETypeEvent: + { + CMdEEvent* event = static_cast(aItems[i]); + // set right offset + buffer->PositionL( items.iEvents.iPtr.iOffset + eventCtr * sizeof(TMdCEvent) ); + freespaceOffset = event->SerializeL( *buffer, freespaceOffset ); + ++eventCtr; + break; + } + default: + { + User::Leave(KErrArgument); + } + } + } + + // insert namespaceid + buffer->PositionL( KNoOffset ); + items.SerializeL( *buffer ); + + CleanupStack::Pop( buffer ); + return buffer; + } + +void CMdESessionImpl::DeserializeQueryResultL( + CMdCSerializationBuffer& aBuffer, + RPointerArray& aItems ) + { + const TMdCItems& items = TMdCItems::GetFromBufferL( aBuffer ); + + CMdENamespaceDef& namespaceDef = GetNamespaceDefL( items.iNamespaceDefId ); + + aItems.ReserveL( items.iObjects.iPtr.iCount + items.iEvents.iPtr.iCount + + items.iRelations.iPtr.iCount ); + + if ( items.iObjects.iPtr.iCount > 0 ) + { + for ( TUint32 i = 0; i < items.iObjects.iPtr.iCount; ++i ) + { + aBuffer.PositionL( items.iObjects.iPtr.iOffset + i * sizeof(TMdCObject) ); + CMdEObject* object = CMdEObject::NewLC( this, aBuffer, + namespaceDef ); + aItems.AppendL( object ); + CleanupStack::Pop( object ); + } + } + + if ( items.iEvents.iPtr.iCount > 0 ) + { + for ( TUint32 i = 0; i < items.iEvents.iPtr.iCount; ++i ) + { + aBuffer.PositionL( items.iEvents.iPtr.iOffset + i * sizeof(TMdCEvent) ); + CMdEEvent* event = CMdEEvent::NewLC( this, aBuffer, namespaceDef ); + aItems.AppendL( event ); + CleanupStack::Pop( event ); + } + } + + if ( items.iRelations.iPtr.iCount > 0 ) + { + for ( TUint32 i = 0; i < items.iRelations.iPtr.iCount; ++i ) + { + aBuffer.PositionL( items.iRelations.iPtr.iOffset + i * sizeof(TMdCRelation) ); + CMdERelation* relation = CMdERelation::NewLC( this, aBuffer, + namespaceDef ); + aItems.AppendL( relation ); + CleanupStack::Pop( relation ); + } + } + } + +TItemId CMdESessionImpl::AddObjectL( CMdEObject& aObject ) + { + AddItemL(aObject); + return aObject.Id(); + } + +TInt CMdESessionImpl::AddObjectsL( RPointerArray& aObjects ) + { + const TInt firstObjectError = AddItemsL( + (RPointerArray&)aObjects ); + + return firstObjectError; + } + +TItemId CMdESessionImpl::AddRelationL( CMdERelation& aRelation ) + { + return AddItemL( aRelation ); + } + +TItemId CMdESessionImpl::UpdateRelationL( CMdERelation& aRelation ) + { + RPointerArray items; + CleanupClosePushL( items ); + items.Append( &aRelation ); + User::LeaveIfError( UpdateItemsL( items ) ); + CleanupStack::PopAndDestroy( &items ); + return aRelation.Id(); + } + +TInt CMdESessionImpl::AddItemsL( RPointerArray& aItems ) + { + CMdCSerializationBuffer *buffer = SerializeItemsL( aItems ); + CleanupStack::PushL( buffer ); + CMdCSerializationBuffer* resultBuf = CMdCSerializationBuffer::NewLC( + + sizeof(TMdCItemIds) + + aItems.Count() * CMdCSerializationBuffer::KRequiredSizeForTItemId ); + RMdEDataBuffer dataBuffer; + dataBuffer.SetBufferL( resultBuf ); + CleanupStack::Pop( resultBuf ); + CleanupClosePushL( dataBuffer ); + + iSession.DoAddItemsL( *buffer, *resultBuf ); + + const TInt firstItemError = DeserializeItemsL( dataBuffer, aItems ); + + CleanupStack::PopAndDestroy( &dataBuffer ); + CleanupStack::PopAndDestroy( buffer ); + + return firstItemError; + } + +void CMdESessionImpl::AddItemsAsyncL( + RPointerArray& aItems, TRequestStatus& aStatus, + RMdEDataBuffer& aSerializedItemIds ) + { + CMdCSerializationBuffer* buffer = SerializeItemsL( aItems ); + CleanupStack::PushL( buffer ); + + CMdCSerializationBuffer* resultBuf = CMdCSerializationBuffer::NewLC( + + sizeof(TMdCItemIds) + + aItems.Count() * CMdCSerializationBuffer::KRequiredSizeForTItemId ); + aSerializedItemIds.SetBufferL( resultBuf ); + CleanupStack::Pop( resultBuf ); + CleanupStack::Pop( buffer ); + + iAsyncHandler->AddRequest( buffer, *resultBuf, aStatus ); + } + +TInt CMdESessionImpl::UpdateItemsL( RPointerArray& aItems ) + { + CMdCSerializationBuffer *buffer = SerializeItemsL( aItems ); + CleanupStack::PushL( buffer ); + + CMdCSerializationBuffer* resultBuf = CMdCSerializationBuffer::NewLC( + + sizeof(TMdCItemIds) + + aItems.Count() * CMdCSerializationBuffer::KRequiredSizeForTItemId ); + + RMdEDataBuffer dataBuffer; + dataBuffer.SetBufferL( resultBuf ); + CleanupStack::Pop( resultBuf ); + CleanupClosePushL( dataBuffer ); + + iSession.DoUpdateItemsL( *buffer, *resultBuf ); + + TInt firstItemError = DeserializeItemsL( dataBuffer, aItems ); + + CleanupStack::PopAndDestroy( &dataBuffer ); + CleanupStack::PopAndDestroy( buffer ); + return firstItemError; + } + +void CMdESessionImpl::UpdateItemsAsyncL( + RPointerArray& aItems, TRequestStatus& aStatus, + RMdEDataBuffer& aSerializedItemIds ) + { + CMdCSerializationBuffer *buffer = SerializeItemsL( aItems ); + CleanupStack::PushL( buffer ); + CMdCSerializationBuffer* resultBuf = CMdCSerializationBuffer::NewLC( + + sizeof(TMdCItemIds) + + aItems.Count() * CMdCSerializationBuffer::KRequiredSizeForTItemId ); + aSerializedItemIds.SetBufferL( resultBuf ); + CleanupStack::Pop( resultBuf ); + CleanupStack::Pop( buffer ); + + iAsyncHandler->UpdateRequest( buffer, *resultBuf, aStatus ); + } + +TInt CMdESessionImpl::DeserializeItemsL( RMdEDataBuffer& aSerializedItems, + RPointerArray& aItems ) + { + CMdCSerializationBuffer* buffer = aSerializedItems.GetBufferLC(); + + const TMdCItemIds& itemIds = TMdCItemIds::GetFromBufferL( *buffer ); + + TUint32 objectsIndex = 0; + TUint32 eventsIndex = 0; + TUint32 relationsIndex = 0; + TItemId id = 0; + + const TInt count = aItems.Count(); + + if ( count != itemIds.iObjectIds.iPtr.iCount + + itemIds.iRelationIds.iPtr.iCount + itemIds.iEventIds.iPtr.iCount ) + { + User::Leave( KErrArgument ); + } + + for ( TInt i = 0; i < count; ++i ) + { + switch ( aItems[i]->InstanceType() ) + { + case EMdETypeObject: + buffer->PositionL( itemIds.iObjectIds.iPtr.iOffset + + objectsIndex * CMdCSerializationBuffer::KRequiredSizeForTItemId ); + buffer->ReceiveL( id ); + aItems[i]->SetId( id ); + aItems[i]->SetSession( *this ); + static_cast(aItems[i])->ClearObject(); + ++objectsIndex; + break; + + case EMdETypeEvent: + buffer->PositionL( itemIds.iEventIds.iPtr.iOffset + + eventsIndex * CMdCSerializationBuffer::KRequiredSizeForTItemId ); + buffer->ReceiveL( id ); + aItems[i]->SetId( id ); + aItems[i]->SetSession( *this ); + ++eventsIndex; + break; + + case EMdETypeRelation: + buffer->PositionL( itemIds.iRelationIds.iPtr.iOffset + + relationsIndex * CMdCSerializationBuffer::KRequiredSizeForTItemId ); + buffer->ReceiveL( id ); + aItems[i]->SetId( id ); + aItems[i]->SetSession( *this ); + ++relationsIndex; + break; + + default: + User::Leave( KErrArgument ); + break; + } + } + + const TInt errorCode = itemIds.iErrorCode; + CleanupStack::PopAndDestroy( buffer ); + + return errorCode; + } + +TItemId CMdESessionImpl::AddEventL( CMdEEvent& aEvent ) + { + return AddItemL( aEvent ); + } + +TItemId CMdESessionImpl::RemoveEventL( TItemId aId, + CMdENamespaceDef* aNamespaceDef ) + { + RArray items; + CleanupClosePushL( items ); + RArray successful; + CleanupClosePushL( successful ); + + items.AppendL( aId ); + User::LeaveIfError( RemoveEventsL( items, successful, aNamespaceDef ) ); + + TItemId result = KNoId; + if ( successful.Count() > 0 ) + { + result = successful[0]; + } + + CleanupStack::PopAndDestroy( &successful ); + CleanupStack::PopAndDestroy( &items ); + + return result; + } + +TInt CMdESessionImpl::RemoveEventsL( const RArray& aId, + RArray& aSuccessful, CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = aNamespaceDef; + + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + + CMdCSerializationBuffer* buffer = RemoveCommonL( *namespaceDef, + (RArray*)NULL, &aId, NULL ); + CleanupStack::PushL( buffer ); + CMdCSerializationBuffer* successfulBuffer = CMdCSerializationBuffer::NewLC( + buffer->Size() ); + + RMdEDataBuffer dataBuffer; + dataBuffer.SetBufferL( successfulBuffer ); + CleanupStack::Pop( successfulBuffer ); + CleanupClosePushL( dataBuffer ); + + iSession.DoRemoveItemsL( *buffer, *successfulBuffer ); + TInt firstItemError = DeserializeIdsL( dataBuffer, NULL, + &aSuccessful ); + + CleanupStack::PopAndDestroy( &dataBuffer ); + CleanupStack::PopAndDestroy( buffer ); + + return firstItemError; + } + +void CMdESessionImpl::RemoveEventsAsyncL( + const RArray& aId, TRequestStatus& aStatus, + RMdEDataBuffer& aSerializedEventIds, + CMdENamespaceDef* aNamespaceDef ) + { + CMdENamespaceDef* namespaceDef = aNamespaceDef; + + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + + CMdCSerializationBuffer* buffer = RemoveCommonL( *namespaceDef, + (RArray*)NULL, &aId, NULL ); + CleanupStack::PushL( buffer ); + CMdCSerializationBuffer* resultBuffer = CMdCSerializationBuffer::NewLC( + buffer->Size() ); + aSerializedEventIds.SetBufferL( resultBuffer ); + CleanupStack::Pop( resultBuffer ); + + CleanupStack::Pop( buffer ); + + iAsyncHandler->RemoveRequest( buffer, *resultBuffer, aStatus ); + } + + +// Query + +CMdEObjectQuery* CMdESessionImpl::NewObjectQueryL( + CMdENamespaceDef& aNamespaceDef, CMdEObjectDef& aObjectDef, + MMdEQueryObserver* aObserver) + { + CMdEObjectQueryImpl* query = CMdEObjectQueryImpl::NewLC( *this, + aNamespaceDef, aObjectDef, NULL, iSession ); + if( aObserver ) + { + query->AddObserverL( *aObserver ); + } + CleanupStack::Pop( query ); + + query->SetQueryId( iNextQueryId ); + iNextQueryId++; + + return query; + } + +CMdEObjectQuery* CMdESessionImpl::NewObjectQueryL( + CMdEObjectDef& aObjectDef, RPointerArray* aObjectDefs, + MMdEQueryObserver* aObserver) + { + CleanupStack::PushL( aObjectDefs ); + + if( !aObjectDefs || ( aObjectDefs->Count() <= 0 ) ) + { + User::Leave( KErrArgument ); + } + + CMdEObjectQueryImpl* query = CMdEObjectQueryImpl::NewLC( *this, + aObjectDef.NamespaceDef(), aObjectDef, aObjectDefs, iSession ); + if( aObserver ) + { + query->AddObserverL( *aObserver ); + } + CleanupStack::Pop( query ); + + CleanupStack::Pop( aObjectDefs ); + + query->SetQueryId( iNextQueryId ); + iNextQueryId++; + + return query; + } + +CMdERelationQuery* CMdESessionImpl::NewRelationQueryL( + CMdENamespaceDef& aNamespaceDef, MMdEQueryObserver* aObserver) + { + CMdERelationQueryImpl* query = CMdERelationQueryImpl::NewLC( *this, + aNamespaceDef, iSession ); + + if( aObserver ) + { + query->AddObserverL( *aObserver ); + } + CleanupStack::Pop( query ); + + query->SetQueryId( iNextQueryId ); + iNextQueryId++; + + return query; + } + +CMdEEventQuery* CMdESessionImpl::NewEventQueryL( + CMdENamespaceDef& aNamespaceDef, MMdEQueryObserver* aObserver) + { + CMdEEventQueryImpl* query = CMdEEventQueryImpl::NewLC( *this, + aNamespaceDef, iSession ); + + if( aObserver ) + { + query->AddObserverL( *aObserver ); + } + CleanupStack::Pop( query ); + + query->SetQueryId( iNextQueryId ); + iNextQueryId++; + + return query; + } + + +// Observer handling +void CMdESessionImpl::AddObjectObserverL( MMdEObjectObserver& aObserver, + CMdELogicCondition* aCondition, + TUint32 aNotificationType, + CMdENamespaceDef* aNamespaceDef ) + { + CleanupStack::PushL( aCondition ); + + // if condition is given, check that it is correct type + if( aCondition && ( EConditionTypeLogic != aCondition->Type() ) ) + { + User::Leave( KErrArgument ); + } + + // if namespace is not given get default namespace definition + CMdENamespaceDef* namespaceDef = NULL; + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + else + { + namespaceDef = aNamespaceDef; + } + + TUint32 type = 0; + if ( aNotificationType & ENotifyAdd ) + { + type |= EObjectNotifyAdd; + } + if ( aNotificationType & ENotifyModify ) + { + type |= EObjectNotifyModify; + } + if ( aNotificationType & ENotifyRemove ) + { + type |= EObjectNotifyRemove; + } + + TInt err = FindNotifier( type, &aObserver, *namespaceDef ); + + if ( err != KErrNotFound ) + { + if ( err >= 0 ) + { + err = KErrAlreadyExists; + } + User::LeaveIfError( err ); + } + + CMdENotifierAO* notifier = CMdENotifierAO::NewLC( *this, iSession ); + notifier->RegisterL( type, &aObserver, aCondition, *namespaceDef ); + + CleanupStack::Pop( notifier ); + iNotifiers.Append( notifier ); + + CleanupStack::PopAndDestroy( aCondition ); + } + +void CMdESessionImpl::AddObjectPresentObserverL( + MMdEObjectPresentObserver& aObserver) + { + CMdENamespaceDef& namespaceDef = GetDefaultNamespaceDefL(); + + TInt err = FindNotifier( + EObjectNotifyPresent, &aObserver, namespaceDef ); + + if ( err != KErrNotFound ) + { + if ( err >= 0 ) + { + err = KErrAlreadyExists; + } + User::LeaveIfError( err ); + } + + CMdENotifierAO* notifier = CMdENotifierAO::NewLC( *this, iSession ); + notifier->RegisterL( EObjectNotifyPresent | EObjectNotifyNotPresent, + &aObserver, NULL, namespaceDef ); + + CleanupStack::Pop( notifier ); + iNotifiers.Append( notifier ); + } + +void CMdESessionImpl::AddRelationObserverL( MMdERelationObserver& aObserver, + CMdECondition* aCondition, + TUint32 aNotificationType, + CMdENamespaceDef* aNamespaceDef ) + { + CleanupStack::PushL( aCondition ); + + // if condition is given, check that it is correct type + if( aCondition && ( EConditionTypeRelation != aCondition->Type() ) ) + { + User::Leave( KErrArgument ); + } + + // if namespace is not given get default namespace definition + CMdENamespaceDef* namespaceDef = NULL; + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + else + { + namespaceDef = aNamespaceDef; + } + + TUint32 type = 0; + if ( aNotificationType & ENotifyAdd ) + { + type |= ERelationNotifyAdd; + } + if ( aNotificationType & ENotifyModify ) + { + type |= ERelationNotifyModify; + } + if ( aNotificationType & ENotifyRemove ) + { + type |= ERelationNotifyRemove; + } + + TInt err = FindNotifier( type, &aObserver, *namespaceDef ); + + if ( err != KErrNotFound ) + { + if ( err >= 0 ) + { + err = KErrAlreadyExists; + } + User::LeaveIfError( err ); + } + + CMdENotifierAO* notifier = CMdENotifierAO::NewLC( *this, iSession ); + notifier->RegisterL( type, &aObserver, aCondition, *namespaceDef ); + + CleanupStack::Pop( notifier ); + iNotifiers.Append( notifier ); + + CleanupStack::PopAndDestroy( aCondition ); + } + +void CMdESessionImpl::AddRelationItemObserverL( + MMdERelationItemObserver& aObserver, CMdECondition* aCondition, + TUint32 aNotificationType, CMdENamespaceDef* aNamespaceDef ) + { + CleanupStack::PushL( aCondition ); + + // if condition is given, check that it is correct type + if( aCondition && ( EConditionTypeRelation != aCondition->Type() ) ) + { + User::Leave( KErrArgument ); + } + + // if namespace is not given get default namespace definition + CMdENamespaceDef* namespaceDef = NULL; + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + else + { + namespaceDef = aNamespaceDef; + } + + TUint32 type = 0; + if ( aNotificationType & ENotifyAdd ) + { + User::Leave( KErrNotSupported ); + } + if ( aNotificationType & ENotifyModify ) + { + User::Leave( KErrNotSupported ); + } + if ( aNotificationType & ENotifyRemove ) + { + type |= ERelationItemNotifyRemove; + } + + TInt err = FindNotifier( type, &aObserver, *namespaceDef ); + + if ( err != KErrNotFound ) + { + if ( err >= 0 ) + { + err = KErrAlreadyExists; + } + User::LeaveIfError( err ); + } + + CMdENotifierAO* notifier = CMdENotifierAO::NewLC( *this, iSession ); + notifier->RegisterL( type, &aObserver, aCondition, *namespaceDef ); + + CleanupStack::Pop( notifier ); + iNotifiers.Append( notifier ); + + CleanupStack::PopAndDestroy( aCondition ); + } + + +void CMdESessionImpl::AddRelationPresentObserverL( + MMdERelationPresentObserver& aObserver) + { + CMdENamespaceDef& namespaceDef = GetDefaultNamespaceDefL(); + + TInt err = FindNotifier( + ERelationNotifyPresent | ERelationNotifyNotPresent, + &aObserver, namespaceDef ); + + if ( err != KErrNotFound ) + { + if ( err >= 0 ) + { + err = KErrAlreadyExists; + } + User::LeaveIfError( err ); + } + + CMdENotifierAO* notifier = CMdENotifierAO::NewLC( *this, iSession ); + notifier->RegisterL( ERelationNotifyPresent | ERelationNotifyNotPresent, + &aObserver, NULL, namespaceDef ); + + CleanupStack::Pop( notifier ); + iNotifiers.Append( notifier ); + } + +void CMdESessionImpl::AddEventObserverL( MMdEEventObserver& aObserver, + CMdECondition* aCondition, + TUint32 aNotificationType, + CMdENamespaceDef* aNamespaceDef ) + { + CleanupStack::PushL( aCondition ); + + // if condition is given, check that it is correct type + if( aCondition && ( EConditionTypeEvent != aCondition->Type() ) ) + { + User::Leave( KErrArgument ); + } + + if ( aNotificationType & ENotifyModify ) + { + User::Leave( KErrNotSupported ); + } + + // if namespace is not given get default namespace definition + CMdENamespaceDef* namespaceDef = NULL; + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + else + { + namespaceDef = aNamespaceDef; + } + + TUint32 type = 0; + if ( aNotificationType & ENotifyAdd ) + { + type |= EEventNotifyAdd; + } + if ( aNotificationType & ENotifyRemove ) + { + type |= EEventNotifyRemove; + } + + TInt err = FindNotifier( type, &aObserver, *namespaceDef ); + + if ( err != KErrNotFound ) + { + if ( err >= 0 ) + { + err = KErrAlreadyExists; + } + User::LeaveIfError( err ); + } + + CMdENotifierAO* notifier = CMdENotifierAO::NewLC( *this, iSession ); + notifier->RegisterL( type, &aObserver, aCondition, *namespaceDef ); + + CleanupStack::Pop( notifier ); + iNotifiers.Append( notifier ); + + CleanupStack::PopAndDestroy( aCondition ); + } + +void CMdESessionImpl::RemoveObjectObserverL( + MMdEObjectObserver& aObserver, CMdENamespaceDef* aNamespaceDef ) + { + // if namespace is not given get default namespace definition + CMdENamespaceDef* namespaceDef = NULL; + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + else + { + namespaceDef = aNamespaceDef; + } + + TInt index = FindNotifier( + EObjectNotifyAdd | EObjectNotifyModify | EObjectNotifyRemove, + &aObserver, *namespaceDef ); + if ( index != KErrNotFound ) + { + iNotifiers[index]->Cancel(); + delete iNotifiers[index]; + iNotifiers[index] = NULL; + iNotifiers.Remove( index ); + } + else + { + User::Leave( KErrNotFound ); + } + } + +void CMdESessionImpl::RemoveObjectPresentObserverL( + MMdEObjectPresentObserver& aObserver) + { + // if namespace is not given get default namespace definition + CMdENamespaceDef& namespaceDef = GetDefaultNamespaceDefL(); + + TInt index = FindNotifier( EObjectNotifyPresent | EObjectNotifyNotPresent, + &aObserver, namespaceDef ); + if ( index != KErrNotFound ) + { + iNotifiers[index]->Cancel(); + delete iNotifiers[index]; + iNotifiers[index] = NULL; + iNotifiers.Remove( index ); + } + else + { + User::Leave( KErrNotFound ); + } + } + +void CMdESessionImpl::RemoveRelationObserverL( + MMdERelationObserver& aObserver, CMdENamespaceDef* aNamespaceDef ) + { + // if namespace is not given get default namespace definition + CMdENamespaceDef* namespaceDef = NULL; + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + else + { + namespaceDef = aNamespaceDef; + } + + TInt index = FindNotifier( + ERelationNotifyAdd | ERelationNotifyModify | ERelationNotifyRemove, + &aObserver, *namespaceDef ); + if ( index != KErrNotFound ) + { + iNotifiers[index]->Cancel(); + delete iNotifiers[index]; + iNotifiers[index] = NULL; + iNotifiers.Remove( index ); + } + else + { + User::Leave( KErrNotFound ); + } + } + +void CMdESessionImpl::RemoveRelationItemObserverL( + MMdERelationItemObserver& aObserver, CMdENamespaceDef* aNamespaceDef ) + { + // if namespace is not given get default namespace definition + CMdENamespaceDef* namespaceDef = NULL; + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + else + { + namespaceDef = aNamespaceDef; + } + + TInt index = FindNotifier( + /*ERelationItemNotifyAdd | ERelationItemNotifyModify |*/ + ERelationItemNotifyRemove, + &aObserver, *namespaceDef ); + if ( index != KErrNotFound ) + { + iNotifiers[index]->Cancel(); + delete iNotifiers[index]; + iNotifiers[index] = NULL; + iNotifiers.Remove( index ); + } + else + { + User::Leave( KErrNotFound ); + } + } + +void CMdESessionImpl::RemoveRelationPresentObserverL( + MMdERelationPresentObserver& aObserver) + { + // if namespace is not given get default namespace definition + CMdENamespaceDef& namespaceDef = GetDefaultNamespaceDefL(); + + TInt index = FindNotifier( + ERelationNotifyPresent | ERelationNotifyNotPresent, + &aObserver, namespaceDef ); + if ( index != KErrNotFound ) + { + iNotifiers[index]->Cancel(); + delete iNotifiers[index]; + iNotifiers[index] = NULL; + iNotifiers.Remove( index ); + } + else + { + User::Leave( KErrNotFound ); + } + } + +void CMdESessionImpl::RemoveEventObserverL( + MMdEEventObserver& aObserver, CMdENamespaceDef* aNamespaceDef ) + { + // if namespace is not given get default namespace definition + CMdENamespaceDef* namespaceDef = NULL; + if ( !aNamespaceDef ) + { + namespaceDef = &GetDefaultNamespaceDefL(); + } + else + { + namespaceDef = aNamespaceDef; + } + + TInt index = FindNotifier( EEventNotifyAdd | EEventNotifyRemove, + &aObserver, *namespaceDef ); + if ( index != KErrNotFound ) + { + iNotifiers[index]->Cancel(); + delete iNotifiers[index]; + iNotifiers[index] = NULL; + iNotifiers.Remove( index ); + } + else + { + User::Leave( KErrNotFound ); + } + } + +TInt CMdESessionImpl::FindNotifier( TUint32 aNotifyType, TAny* aObserver, + CMdENamespaceDef& aNamespaceDef ) + { + const TInt notifiersCount = iNotifiers.Count(); + for( TInt i = 0; i < notifiersCount; ++i ) + { + if ( iNotifiers[i]->Match( aNotifyType, aObserver, aNamespaceDef ) ) + { + return i; + } + } + return KErrNotFound; + } + +void CMdESessionImpl::NotifierInError( CMdENotifierAO* aNotifier ) + { + TInt index = iNotifiers.Find( aNotifier ); + delete aNotifier; + iNotifiers.Remove( index ); + } + +void CMdESessionImpl::ImportSchemaL( const TDesC& aFileName ) + { + iSession.DoImportSchemaL( aFileName ); + DoLoadSchemaL(); + } + +TInt CMdESessionImpl::ImportMetadataL( const TDesC& aFileName ) + { + return iSession.DoImportMetadataL( aFileName ); + } + +void CMdESessionImpl::ImportMetadata( const TDesC& aFileName, + TPckgBuf& aResult, TRequestStatus& aStatus ) + { + return iSession.DoImportMetadata( aFileName, aResult, aStatus ); + } + +CMdCSerializationBuffer* CMdESessionImpl::ExportCommonL( + const CMdENamespaceDef* aNamespaceDef, + const RPointerArray* aObjectDefs, + const RPointerArray* aRelationDefs, + const RPointerArray* aEventDefs ) + { + // headerSize + TUint32 bufferSize = sizeof(TMdCItemIds); + + TMdCItemIds itemIds; + if ( aNamespaceDef ) + { + itemIds.iNamespaceDefId = aNamespaceDef->Id(); + } + else + { + itemIds.iNamespaceDefId = KNoDefId; + } + itemIds.iObjectUris.iPtr.iCount = 0; + itemIds.iObjectUris.iPtr.iOffset = KNoOffset; + itemIds.iObjectIds.iPtr.iCount = 0; + itemIds.iObjectIds.iPtr.iOffset = KNoOffset; + itemIds.iEventIds.iPtr.iCount = 0; + itemIds.iEventIds.iPtr.iOffset = KNoOffset; + itemIds.iRelationIds.iPtr.iCount = 0; + itemIds.iRelationIds.iPtr.iOffset = KNoOffset; + + if ( !aNamespaceDef || (!aObjectDefs && !aRelationDefs && !aEventDefs) ) + { + CMdCSerializationBuffer* buffer = + CMdCSerializationBuffer::NewLC( bufferSize ); + itemIds.SerializeL( *buffer ); + CleanupStack::Pop( buffer ); + return buffer; + } + + if ( aObjectDefs ) + { + bufferSize += aObjectDefs->Count() * CMdCSerializationBuffer::KRequiredSizeForTItemId; + } + if ( aEventDefs ) + { + bufferSize += aEventDefs->Count() * CMdCSerializationBuffer::KRequiredSizeForTItemId; + } + if ( aRelationDefs ) + { + bufferSize += aRelationDefs->Count() * CMdCSerializationBuffer::KRequiredSizeForTItemId; + } + + CMdCSerializationBuffer* buffer = + CMdCSerializationBuffer::NewLC( bufferSize ); + + buffer->PositionL( sizeof(TMdCItemIds) ); + + // insert objects + if ( aObjectDefs ) + { + itemIds.iObjectIds.iPtr.iOffset = buffer->Position(); + itemIds.iObjectIds.iPtr.iCount = aObjectDefs->Count(); + + for ( TInt i = 0; i < itemIds.iObjectIds.iPtr.iCount; ++i ) + { + buffer->InsertL( (*aObjectDefs)[i]->Id() ); + } + } + + // insert events + if ( aEventDefs ) + { + itemIds.iEventIds.iPtr.iOffset = buffer->Position(); + itemIds.iEventIds.iPtr.iCount = aEventDefs->Count(); + + for ( TInt i = 0; i < itemIds.iEventIds.iPtr.iCount; ++i ) + { + buffer->InsertL( (*aEventDefs)[i]->Id() ); + } + } + + // insert relations + if ( aRelationDefs ) + { + itemIds.iRelationIds.iPtr.iOffset = buffer->Position(); + itemIds.iRelationIds.iPtr.iCount = aRelationDefs->Count(); + + for ( TInt i = 0; i < itemIds.iRelationIds.iPtr.iCount; ++i ) + { + buffer->InsertL( (*aRelationDefs)[i]->Id() ); + } + } + + // set up header correctly + buffer->PositionL( KNoOffset ); + itemIds.SerializeL( *buffer ); + + CleanupStack::Pop( buffer ); + return buffer; + } + + +void CMdESessionImpl::ExportMetadataL( const TDesC& aFileName, + const CMdENamespaceDef* aNamespaceDef, + const RPointerArray* aObjectDefs, + const RPointerArray* aRelationDefs, + const RPointerArray* aEventDefs ) + { + CMdCSerializationBuffer* buffer = ExportCommonL( + aNamespaceDef, aObjectDefs, aRelationDefs, aEventDefs ); + CleanupStack::PushL( buffer ); + + // Export + iSession.DoExportMetadataL( aFileName, *buffer ); + + // Cleanup + CleanupStack::PopAndDestroy( buffer ); + } + +void CMdESessionImpl::ExportMetadataL( const TDesC& aFileName, + TRequestStatus& aStatus, RMdEDataBuffer& aBuffer, + const CMdENamespaceDef* aNamespaceDef, + const RPointerArray* aObjectDefs, + const RPointerArray* aRelationDefs, + const RPointerArray* aEventDefs ) + { + CMdCSerializationBuffer* buffer = ExportCommonL( + aNamespaceDef, aObjectDefs, aRelationDefs, aEventDefs ); + CleanupStack::PushL( buffer ); + + // Export + iSession.DoExportMetadataL( aFileName, *buffer, aStatus ); + + aBuffer.SetBufferL( buffer ); + CleanupStack::Pop( buffer ); + } + +void CMdESessionImpl::GetSchemaVersionL( + TInt& aMajorVersion, TInt& aMinorVersion) + { + return iSession.DoGetSchemaVersionL( aMajorVersion, aMinorVersion ); + } + +void CMdESessionImpl::SetObjectToPresentByGuidL( + const TInt64& aGuidHigh, const TInt64& aGuidLow ) + { + return iSession.DoSetObjectToPresentByGuidL( aGuidHigh, aGuidLow ); + } + +void CMdESessionImpl::CheckOpened() const + { + __ASSERT_ALWAYS(iSessionState == EMdESessionOpen, + TMdEPanic::Panic(TMdEPanic::ESessionOpenInProgress)); + } + +void CMdESessionImpl::GetCountL( CMdCSerializationBuffer* aBuffer, + TUint32& aResult ) + { + const TMdCItemCounts& itemCounts = TMdCItemCounts::GetFromBufferL( *aBuffer ); + + if( itemCounts.iObjects ) + { + aResult = itemCounts.iObjects; + __ASSERT_DEBUG( ( itemCounts.iEvents == 0 ) && ( itemCounts.iRelations == 0 ), MMdCCommon::Panic( KErrCorrupt ) ); + } + + if( itemCounts.iEvents ) + { + aResult = itemCounts.iEvents; + __ASSERT_DEBUG( ( itemCounts.iObjects == 0 ) && ( itemCounts.iRelations == 0 ), MMdCCommon::Panic( KErrCorrupt ) ); + } + + if( itemCounts.iRelations ) + { + aResult = itemCounts.iRelations; + __ASSERT_DEBUG( ( itemCounts.iObjects == 0 ) && ( itemCounts.iEvents == 0 ), MMdCCommon::Panic( KErrCorrupt ) ); + } + } + +void CMdESessionImpl::GetItemIdL( CMdCSerializationBuffer* aBuffer, + RArray& aIdArray ) + { + const TMdCItemIds& itemIds = TMdCItemIds::GetFromBufferL( *aBuffer ); + + if( itemIds.iObjectIds.iPtr.iCount > 0 ) + { + aBuffer->PositionL( itemIds.iObjectIds.iPtr.iOffset ); + } + + if( itemIds.iRelationIds.iPtr.iCount > 0 ) + { + aBuffer->PositionL( itemIds.iRelationIds.iPtr.iOffset ); + } + + if( itemIds.iEventIds.iPtr.iCount > 0 ) + { + aBuffer->PositionL( itemIds.iEventIds.iPtr.iOffset ); + } + + const TInt count = itemIds.iObjectIds.iPtr.iCount + itemIds.iRelationIds.iPtr.iCount + + itemIds.iEventIds.iPtr.iCount; + aIdArray.ReserveL( count ); + for( TUint32 i = 0; i < count; i++ ) + { + TItemId id; + aBuffer->ReceiveL( id ); + aIdArray.AppendL( id ); + } + } + +void CMdESessionImpl::GetDistinctValuesL( CMdCSerializationBuffer& aBuffer, + CDesCArray& aResults ) + { + const TMdCItemIds& itemIds = TMdCItemIds::GetFromBufferL( aBuffer ); + aBuffer.PositionL( itemIds.iObjectUris.iPtr.iOffset ); + for ( TUint32 i = 0; i < itemIds.iObjectUris.iPtr.iCount; ++i ) + { + TPtrC16 value = aBuffer.ReceivePtr16L(); + aResults.AppendL( value ); + } + } + +CMdENamespaceDef* CMdESessionImpl::GetNamespaceDefL( + CMdENamespaceDef* aNamespaceDef ) + { + if ( aNamespaceDef ) + { + return aNamespaceDef; + } + else + { + return &GetDefaultNamespaceDefL(); + } + }