diff -r 000000000000 -r c53acadfccc6 metadataengine/server/src/mdsmanipulationengine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/metadataengine/server/src/mdsmanipulationengine.cpp Mon Jan 18 20:34:07 2010 +0200 @@ -0,0 +1,1064 @@ +/* +* 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: This is Manipulation engine to manage adding, +* deleting and modifying metadata database entries +* +*/ + +// INCLUDE FILES +#include "mdsmanipulationengine.h" + +#include "mdcresult.h" +#include "mdcitem.h" +#include "mdsschema.h" +#include "mdsnotifier.h" +#include "mdsdbconnectionpool.h" +#include "mdslogger.h" +#include "mdssqlobjectmanipulate.h" +#include "mdssqliteconnection.h" +#include "mdsnamespacedef.h" +#include "mdcserializationbuffer.h" +#include "mdeinternalerror.h" +#include "mdeerror.h" + +__USES_LOGGER + +// ======== LOCAL FUNCTIONS ======== + +static void TransactionCleanupL(void* aConn) + { + CMdSSqLiteConnection* conn = (CMdSSqLiteConnection*)aConn; + conn->TransactionRollbackL(); + } + +// --------------------------------------------------------------------------- +// NewL +// --------------------------------------------------------------------------- +// +CMdSManipulationEngine* CMdSManipulationEngine::NewL( CMdsSchema& aSchema, + CMdSNotifier& aNotifier, CMdSObjectLockList& aLockList ) + { + CMdSManipulationEngine* self = CMdSManipulationEngine::NewLC( aSchema, + aNotifier, aLockList ); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// NewLC +// --------------------------------------------------------------------------- +// +CMdSManipulationEngine* CMdSManipulationEngine::NewLC( CMdsSchema& aSchema, + CMdSNotifier& aNotifier, CMdSObjectLockList& aLockList ) + { + CMdSManipulationEngine* self = new (ELeave) CMdSManipulationEngine( + aSchema, aNotifier, aLockList ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// --------------------------------------------------------------------------- +// Default constructor +// --------------------------------------------------------------------------- +// +CMdSManipulationEngine::CMdSManipulationEngine( CMdsSchema& aSchema, + CMdSNotifier& aNotifier, CMdSObjectLockList& aLockList ) + : iManipulate( NULL ), iSchema( aSchema ), iNotifier( aNotifier ), + iGarbageCollector( NULL ), iLockList( aLockList ) + { + } + +// --------------------------------------------------------------------------- +// ConstructL +// --------------------------------------------------------------------------- +// +void CMdSManipulationEngine::ConstructL() + { + iManipulate = CMdSSqlObjectManipulate::NewL( iSchema, iLockList ); + iGarbageCollector = CMdSGarbageCollector::NewL(*this); + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CMdSManipulationEngine::~CMdSManipulationEngine() + { + delete iManipulate; + + delete iGarbageCollector; + } + +// --------------------------------------------------------------------------- +// Manipulate +// --------------------------------------------------------------------------- +// +CMdSSqlObjectManipulate& CMdSManipulationEngine::Manipulate() + { + return *iManipulate; + } + +// --------------------------------------------------------------------------- +// GarbageCollector +// --------------------------------------------------------------------------- +// +CMdSGarbageCollector& CMdSManipulationEngine::GarbageCollector() + { + return *iGarbageCollector; + } + +// --------------------------------------------------------------------------- +// AddL adds objects from serialized buffer +// --------------------------------------------------------------------------- +// +void CMdSManipulationEngine::AddL( CMdCSerializationBuffer& aBuffer, + CMdCSerializationBuffer& aResultBuffer, + const CMdSServerSession* aServerSession ) + { + const TMdCItems& items = TMdCItems::GetFromBufferL( aBuffer ); + + const CMdsNamespaceDef* namespaceDef = iSchema.GetNamespaceByIdL( + items.iNamespaceDefId ); + if ( !namespaceDef ) + { + User::Leave( KErrMdEUnknownNamespaceDef ); + } + iManipulate->SetNamespace( namespaceDef ); + + CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL(); + + TMdCItemIds resultIds; + resultIds.iNamespaceDefId = items.iNamespaceDefId; + resultIds.iErrorCode = KErrNone; + aResultBuffer.PositionL( sizeof(TMdCItemIds) ); + + // add objects + const TInt KObjectCount = items.iObjects.iPtr.iCount; + if ( KObjectCount > 0 ) + { + resultIds.iObjectIds.iPtr.iOffset = aResultBuffer.Position(); + resultIds.iObjectIds.iPtr.iCount = items.iObjects.iPtr.iCount; + + RMdsStatement baseObjStmt; + CleanupClosePushL(baseObjStmt); + RMdsStatement objStmt; + CleanupClosePushL(objStmt); + + if( KObjectCount > 1 ) + { + RMdSTransaction transaction( connection ); + CleanupClosePushL(transaction); + const TInt beginError( transaction.Error() ); + if( beginError != KErrNone ) + { + CleanupStack::PopAndDestroy( &transaction ); + } + + for ( TInt i = 0; i < KObjectCount; ++i ) + { + aBuffer.PositionL( items.iObjects.iPtr.iOffset + i * sizeof(TMdCObject) ); + TItemId id = KNoId; + TRAPD( err, id = iManipulate->AddObjectL( connection, aBuffer, + baseObjStmt, objStmt, aServerSession ) ); + if (err == KErrNone) + { + aResultBuffer.InsertL( id ); + } + else + { + aResultBuffer.InsertL( KNoId ); + if(resultIds.iErrorCode == KErrNone) + { + resultIds.iErrorCode = err; + } + } + } + if( beginError == KErrNone ) + { + transaction.CommitL(); + CleanupStack::PopAndDestroy( &transaction ); + } + } + else + { + for ( TInt i = 0; i < KObjectCount; ++i ) + { + aBuffer.PositionL( items.iObjects.iPtr.iOffset + i * sizeof(TMdCObject) ); + TItemId id = KNoId; + TRAPD( err, id = iManipulate->AddObjectL( connection, aBuffer, + baseObjStmt, objStmt, aServerSession ) ); + if (err == KErrNone) + { + aResultBuffer.InsertL( id ); + } + else + { + aResultBuffer.InsertL( KNoId ); + if(resultIds.iErrorCode == KErrNone) + { + resultIds.iErrorCode = err; + } + } + } + } + CleanupStack::PopAndDestroy(&objStmt); + CleanupStack::PopAndDestroy(&baseObjStmt); + } + else + { + resultIds.iObjectIds.iPtr.iOffset = KNoOffset; + resultIds.iObjectIds.iPtr.iCount = 0; + } + + // add events + const TInt KEventCount = items.iEvents.iPtr.iCount; + if ( KEventCount > 0 ) + { + resultIds.iEventIds.iPtr.iOffset = aResultBuffer.Position(); + resultIds.iEventIds.iPtr.iCount = KEventCount; + + if( KEventCount > 1 ) + { + //More than 1 event, transaction will be used. + connection.TransactionBeginL(); + CleanupStack::PushL(TCleanupItem(&TransactionCleanupL, &connection)); + } + + for ( TInt i = 0; i < KEventCount; ++i ) + { + aBuffer.PositionL( items.iEvents.iPtr.iOffset + + i * sizeof(TMdCEvent) ); + + TItemId id = KNoId; + TRAPD( err, id = iManipulate->AddEventL( connection, aBuffer ) ); + if (err == KErrNone) + { + aResultBuffer.InsertL( id ); + } + else + { + aResultBuffer.InsertL( KNoId ); + if(resultIds.iErrorCode == KErrNone) + { + resultIds.iErrorCode = err; + } + } + } + + if( KEventCount > 1 ) + { + connection.TransactionCommitL(); + CleanupStack::Pop(); //TransactionCleanup() + } + } + else + { + resultIds.iEventIds.iPtr.iOffset = KNoOffset; + resultIds.iEventIds.iPtr.iCount = 0; + } + + // add relations + const TInt KRelationCount = items.iRelations.iPtr.iCount; + if ( KRelationCount > 0 ) + { + resultIds.iRelationIds.iPtr.iOffset = aResultBuffer.Position(); + resultIds.iRelationIds.iPtr.iCount = KRelationCount; + + if( KRelationCount > 1 ) + { + //More than 1 relation, transaction will be used. + connection.TransactionBeginL(); + CleanupStack::PushL(TCleanupItem(&TransactionCleanupL, &connection)); + } + + for ( TInt i = 0; i < KRelationCount; ++i ) + { + aBuffer.PositionL( items.iRelations.iPtr.iOffset + + i * sizeof(TMdCRelation) ); + + TItemId id = KNoId; + TRAPD( err, id = iManipulate->AddRelationL( connection, aBuffer ) ); + if (err == KErrNone) + { + aResultBuffer.InsertL( id ); + } + else + { + aResultBuffer.InsertL( KNoId ); + if(resultIds.iErrorCode == KErrNone) + { + resultIds.iErrorCode = err; + } + } + } + + if( KRelationCount > 1 ) + { + connection.TransactionCommitL(); + CleanupStack::Pop(); //TransactionCleanup() + } + } + else + { + resultIds.iRelationIds.iPtr.iOffset = KNoOffset; + resultIds.iRelationIds.iPtr.iCount = 0; + } + + // set up result header + aResultBuffer.PositionL( KNoOffset ); + resultIds.SerializeL( aResultBuffer ); + + iManipulate->SetNamespace( NULL ); + iNotifier.NotifyAddedL( aBuffer, aResultBuffer ); + } + +// --------------------------------------------------------------------------- +// RemoveL +// --------------------------------------------------------------------------- +// +void CMdSManipulationEngine::RemoveL( CMdCSerializationBuffer& aBuffer, + CMdCSerializationBuffer& aResultBuffer ) + { + // Read item ids from buffer. + const TMdCItemIds& itemIds = TMdCItemIds::GetFromBufferL( aBuffer ); + + const CMdsNamespaceDef* namespaceDef = iSchema.GetNamespaceByIdL( + itemIds.iNamespaceDefId ); + if ( !namespaceDef ) + { + User::Leave( KErrMdEUnknownNamespaceDef ); + } + iManipulate->SetNamespace( namespaceDef ); + + TMdCItemIds resultIds; + resultIds.iNamespaceDefId = itemIds.iNamespaceDefId; + resultIds.iErrorCode = KErrNone; + resultIds.iObjectUris.iPtr.iCount = 0; + resultIds.iObjectUris.iPtr.iOffset = KNoOffset; + + aResultBuffer.PositionL( sizeof(TMdCItemIds) ); + + RArray idArray; + CleanupClosePushL( idArray ); + RArray removedRelations; + CleanupClosePushL( removedRelations ); + RArray removedEvents; + CleanupClosePushL( removedEvents ); + + CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL(); + + // Remove objects by id or URI. + if (itemIds.iObjectIds.iPtr.iCount + itemIds.iObjectUris.iPtr.iCount > 0) + { + RMdSTransaction transaction( connection ); + CleanupClosePushL(transaction); + User::LeaveIfError( transaction.Error() ); + + if (itemIds.iObjectUris.iPtr.iCount > 0) + { + aBuffer.PositionL( itemIds.iObjectUris.iPtr.iOffset ); + iManipulate->RemoveObjectsByUriL( aBuffer, itemIds.iObjectUris.iPtr.iCount, + idArray, removedRelations, removedEvents ); + } + else + { + aBuffer.PositionL( itemIds.iObjectIds.iPtr.iOffset ); + iManipulate->RemoveObjectsByIdL( aBuffer, itemIds.iObjectIds.iPtr.iCount, + idArray, removedRelations, removedEvents ); + } + + transaction.CommitL(); + CleanupStack::PopAndDestroy( &transaction ); + + // write it to the buffer + const TInt count = idArray.Count(); + resultIds.iObjectIds.iPtr.iOffset = aResultBuffer.Position(); + resultIds.iObjectIds.iPtr.iCount = count; + + for ( TInt i = 0; i < count; ++i ) + { + aResultBuffer.InsertL( idArray[i] ); + if (idArray[i] == KNoId && resultIds.iErrorCode==KErrNone) + { + resultIds.iErrorCode = KErrNotFound; + } + } + idArray.Reset(); + } + else + { + resultIds.iObjectIds.iPtr.iCount = 0; + resultIds.iObjectIds.iPtr.iOffset = KNoOffset; + } + + // Remove events by id. + if (itemIds.iEventIds.iPtr.iCount > 0) + { + // process events + aBuffer.PositionL( itemIds.iEventIds.iPtr.iOffset ); + + RMdSTransaction transaction( connection ); + CleanupClosePushL(transaction); + User::LeaveIfError( transaction.Error() ); + + iManipulate->RemoveEventsL( aBuffer, itemIds.iEventIds.iPtr.iCount, idArray ); + + transaction.CommitL(); + CleanupStack::PopAndDestroy( &transaction ); + + const TInt count = idArray.Count(); + resultIds.iEventIds.iPtr.iOffset = aResultBuffer.Position(); + resultIds.iEventIds.iPtr.iCount = count; + + for ( TInt i = 0; i < count; ++i ) + { + aResultBuffer.InsertL( idArray[i] ); + if (idArray[i] == KNoId && resultIds.iErrorCode==KErrNone) + { + resultIds.iErrorCode = KErrNotFound; + } + } + idArray.Reset(); + } + else + { + resultIds.iEventIds.iPtr.iOffset = KNoOffset; + resultIds.iEventIds.iPtr.iCount = 0; + } + + // Remove relations by id. + if (itemIds.iRelationIds.iPtr.iCount > 0) + { + // process relations + aBuffer.PositionL( itemIds.iRelationIds.iPtr.iOffset ); + + RMdSTransaction transaction( connection ); + CleanupClosePushL(transaction); + User::LeaveIfError( transaction.Error() ); + + iManipulate->RemoveRelationsL( aBuffer, itemIds.iRelationIds.iPtr.iCount, idArray ); + + transaction.CommitL(); + CleanupStack::PopAndDestroy( &transaction ); + + const TInt count = idArray.Count(); + resultIds.iRelationIds.iPtr.iOffset = aResultBuffer.Position(); + resultIds.iRelationIds.iPtr.iCount = count; + + for ( TInt i = 0; i < count; ++i ) + { + aResultBuffer.InsertL( idArray[i] ); + if (idArray[i] == KNoId && resultIds.iErrorCode==KErrNone) + { + resultIds.iErrorCode = KErrNotFound; + } + } + } + else + { + resultIds.iRelationIds.iPtr.iOffset = KNoOffset; + resultIds.iRelationIds.iPtr.iCount = 0; + } + + aResultBuffer.PositionL( KNoOffset ); + resultIds.SerializeL( aResultBuffer ); + + // notify about items removed + const TBool notify = iNotifier.CheckForNotifier(EObjectNotifyRemove|EEventNotifyRemove|ERelationNotifyRemove); + if (notify) + { + iNotifier.NotifyRemovedL( aResultBuffer, EFalse ); + } + + // notify about additional items removed + const TInt KRemovedItemsCount = removedRelations.Count() + removedEvents.Count(); + if ( notify && KRemovedItemsCount > 0 ) + { + const TInt32 bufferSize = sizeof(TMdCItemIds) + + KRemovedItemsCount * CMdCSerializationBuffer::KRequiredSizeForTItemId; + + CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC( bufferSize ); + + buffer->PositionL( sizeof(TMdCItemIds) ); + + TMdCItemIds additResultIds; + additResultIds.iNamespaceDefId = itemIds.iNamespaceDefId; + additResultIds.iErrorCode = KErrNone; + additResultIds.iObjectIds.iPtr.iOffset = KNoOffset; + additResultIds.iObjectIds.iPtr.iCount = 0; + additResultIds.iObjectUris.iPtr.iOffset = KNoOffset; + additResultIds.iObjectUris.iPtr.iCount = 0; + + // Insert list of removed events to the serialization buffer. + const TInt KRemovedEventsCount = removedEvents.Count(); + additResultIds.iEventIds.iPtr.iCount = KRemovedEventsCount; + if ( KRemovedEventsCount > 0 ) + { + additResultIds.iEventIds.iPtr.iOffset = buffer->Position(); + for ( TInt i = 0; i < KRemovedEventsCount; ++i ) + { + buffer->InsertL( removedEvents[i] ); + } + } + else + { + additResultIds.iEventIds.iPtr.iOffset = KNoOffset; + } + + // Insert list of removed relations to the serialization buffer. + const TInt KRemovedRelationsCount = removedRelations.Count(); + additResultIds.iRelationIds.iPtr.iCount = KRemovedRelationsCount; + if ( KRemovedRelationsCount > 0 ) + { + additResultIds.iRelationIds.iPtr.iOffset = buffer->Position(); + for ( TInt i = 0; i < KRemovedRelationsCount; ++i ) + { + buffer->InsertL( removedRelations[i] ); + } + } + else + { + additResultIds.iRelationIds.iPtr.iOffset = KNoOffset; + } + + buffer->PositionL( KNoOffset ); + additResultIds.SerializeL( *buffer ); + iNotifier.NotifyRemovedL( *buffer, EFalse ); + CleanupStack::PopAndDestroy( buffer ); + } + + // notify about removed relation items + const TInt relationsCount = removedRelations.Count() + idArray.Count(); + + if ( relationsCount > 0 && iNotifier.CheckForNotifier(ERelationItemNotifyRemove) ) + { + CMdCSerializationBuffer* itemsBuffer = CMdCSerializationBuffer::NewLC( + sizeof( TMdCItems ) + + sizeof( TMdCRelation ) * relationsCount ); + + iManipulate->GetRemovedRelationItemsL( *itemsBuffer, + removedRelations, idArray ); + + iNotifier.NotifyRemovedRelationItemsL( *itemsBuffer ); + + CleanupStack::PopAndDestroy( itemsBuffer ); + } + + // start garbage collector + if( iGarbageCollector ) + { + iGarbageCollector->Start( KGarbageCollectionDelay ); + } + + // removedEvents, removedRelations, idArray + CleanupStack::PopAndDestroy( 3, &idArray ); + } + +void CMdSManipulationEngine::UpdateL( CMdCSerializationBuffer& aBuffer, + CMdCSerializationBuffer& aResultBuffer ) + { + const TMdCItems& items = TMdCItems::GetFromBufferL( aBuffer ); + + const CMdsNamespaceDef* namespaceDef = iSchema.GetNamespaceByIdL( + items.iNamespaceDefId ); + if ( !namespaceDef ) + { + User::Leave( KErrMdEUnknownNamespaceDef ); + } + iManipulate->SetNamespace( namespaceDef ); + CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL(); + + TMdCItemIds resultIds; + resultIds.iNamespaceDefId = items.iNamespaceDefId; + resultIds.iErrorCode = KErrNone; + resultIds.iObjectUris.iPtr.iOffset = KNoOffset; + resultIds.iObjectUris.iPtr.iCount = 0; + resultIds.iEventIds.iPtr.iOffset = KNoOffset; + resultIds.iEventIds.iPtr.iCount = 0; + + aResultBuffer.PositionL( sizeof(TMdCItemIds) ); + + // update objects + if ( items.iObjects.iPtr.iCount > 0 ) + { + resultIds.iObjectIds.iPtr.iOffset = aResultBuffer.Position(); + resultIds.iObjectIds.iPtr.iCount = items.iObjects.iPtr.iCount; + + for ( TInt i = 0; i < items.iObjects.iPtr.iCount; ++i ) + { + aBuffer.PositionL( items.iObjects.iPtr.iOffset + i * sizeof(TMdCObject) ); + + TItemId id = KNoId; + TRAPD( err, id = iManipulate->UpdateObjectL( connection, aBuffer ) ); + if (err == KErrNone) + { + aResultBuffer.InsertL( id ); + } + else + { + aResultBuffer.InsertL( KNoId ); + if ( resultIds.iErrorCode == KErrNone ) + { + resultIds.iErrorCode = err; + } + } + } + } + else + { + resultIds.iObjectIds.iPtr.iOffset = KNoOffset; + resultIds.iObjectIds.iPtr.iCount = 0; + } + + // update relations + if ( items.iRelations.iPtr.iCount > 0 ) + { + resultIds.iRelationIds.iPtr.iOffset = aResultBuffer.Position(); + resultIds.iRelationIds.iPtr.iCount = items.iRelations.iPtr.iCount; + + for ( TInt i = 0; i < items.iRelations.iPtr.iCount; ++i ) + { + aBuffer.PositionL( items.iRelations.iPtr.iOffset + i * sizeof(TMdCRelation) ); + + TItemId id = KNoId; + TRAPD( err, id = iManipulate->UpdateRelationsL( connection, aBuffer ) ); + if (err == KErrNone) + { + aResultBuffer.InsertL( id ); + } + else + { + aResultBuffer.InsertL( KNoId ); + if ( resultIds.iErrorCode == KErrNone ) + { + resultIds.iErrorCode = err; + } + } + } + } + else + { + resultIds.iRelationIds.iPtr.iOffset = KNoOffset; + resultIds.iRelationIds.iPtr.iCount = 0; + } + + if ( items.iEvents.iPtr.iCount > 0 ) + { + // events cannot be updated + // so just ignore it, but if possible return error code + if ( resultIds.iErrorCode == KErrNone ) + { + resultIds.iErrorCode = KErrArgument; + } + } + + iManipulate->SetNamespace( NULL ); + + // set up result header + aResultBuffer.PositionL( KNoOffset ); + resultIds.SerializeL( aResultBuffer ); + + iNotifier.NotifyModifiedL( aBuffer, aResultBuffer ); + } + +CMdCSerializationBuffer* CMdSManipulationEngine::CheckObjectL( + TInt aResultBufferSize, const TDesC& aUri, TDefId aNamespaceDefId ) + { + return iManipulate->CheckObjectL( + aResultBufferSize, aUri, aNamespaceDefId ); + } + +CMdCSerializationBuffer* CMdSManipulationEngine::CheckObjectL( + TInt aResultBufferSize, TItemId aId, TDefId aNamespaceDefId ) + { + return iManipulate->CheckObjectL( + aResultBufferSize, aId, aNamespaceDefId ); + } + +CMdCSerializationBuffer* CMdSManipulationEngine::CheckObjectL( + TInt aResultBufferSize, CMdCSerializationBuffer& aIds, + TDefId aNamespaceDefId ) + { + return iManipulate->CheckObjectL( + aResultBufferSize, aIds, aNamespaceDefId ); + } + +// --------------------------------------------------------------------------- +// AddMemoryCardL +// --------------------------------------------------------------------------- +// +void CMdSManipulationEngine::AddMemoryCardL(TUint32 aMediaId) + { + iManipulate->AddMemoryCardL( aMediaId ); + } + +// --------------------------------------------------------------------------- +// GetMemoryCardL +// --------------------------------------------------------------------------- +// +void CMdSManipulationEngine::GetMemoryCardL(TUint32& aMediaId) + { + iManipulate->GetMemoryCardL( aMediaId ); + } + +// --------------------------------------------------------------------------- +// CheckMemoryCardL +// --------------------------------------------------------------------------- +// +TBool CMdSManipulationEngine::CheckMemoryCardL(TUint32 aMediaId) + { + return iManipulate->CheckMemoryCardL( aMediaId ); + } + +// --------------------------------------------------------------------------- +// SetMediaL +// --------------------------------------------------------------------------- +// +void CMdSManipulationEngine::SetMediaL(TUint32 aMediaId, TChar aDrive, + TBool aPresentState) + { + return iManipulate->SetMediaL( aMediaId, aDrive, aPresentState ); + } + +// --------------------------------------------------------------------------- +// GetMediaL +// --------------------------------------------------------------------------- +// +TBool CMdSManipulationEngine::GetMediaL(TUint32 aMediaId, TChar& aDrive, + TBool& aPresentState) + { + return iManipulate->GetMediaL( aMediaId, aDrive, aPresentState ); + } + +// --------------------------------------------------------------------------- +// GetPresentMediasL +// --------------------------------------------------------------------------- +// +TInt32 CMdSManipulationEngine::GetPresentMediasL(TDes8& aMediaInfoBuffer) + { + return iManipulate->GetPresentMediasL( aMediaInfoBuffer ); + } + +// --------------------------------------------------------------------------- +// SetFilesToPresentL +// --------------------------------------------------------------------------- +// +void CMdSManipulationEngine::SetFilesToPresentL(TUint32 aMediaId, TUint32 aFileCount, + CMdCSerializationBuffer& aUris, CMdCSerializationBuffer& aFileInfos, + CMdCSerializationBuffer& aResults) + { + + CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL(); + RMdSTransaction transaction( connection ); + CleanupClosePushL( transaction ); + User::LeaveIfError( transaction.Error() ); + + RArray itemIds; + CleanupClosePushL( itemIds ); + itemIds.ReserveL( aFileCount ); + + RArray notifyItemIds; + CleanupClosePushL( notifyItemIds ); + notifyItemIds.ReserveL( aFileCount ); + + for( TUint32 i = 0; i < aFileCount; i++ ) + { + TPtrC16 uri = aUris.ReceivePtr16L(); + TPtr16 uriLC( CONST_CAST( TUint16*, uri.Ptr() ), uri.Length(), uri.Length() ); + uriLC.LowerCase(); + + TMdSFileInfo fileInfo; + aFileInfos.ReceiveL(fileInfo.iModifiedTime); + aFileInfos.ReceiveL(fileInfo.iSize); + +#ifdef _DEBUG + const TInt64 time = fileInfo.iModifiedTime; + RDebug::Print( _L("CMdSManipulationEngine::SetFilesToPresentL: (%d) iSize %u, iModified %Ld, uri %S"), + i, + fileInfo.iSize, + time, + &uri); +#endif + + TFilePresentStates placeHolder; + TBool notPresentState( EFalse ); + const TItemId objectId = iManipulate->SearchNotPresentFileL( /*reservation(), */ + aMediaId, uri, fileInfo, placeHolder, notPresentState ); + if ( placeHolder != EMdsNotFound ) + { + itemIds.Append( objectId ); + + if( notPresentState ) + { + notifyItemIds.Append( objectId ); + } + } + + aResults.InsertL( (TUint8)placeHolder ); + } + + iManipulate->SetFilesToPresentL( itemIds ); + + // only notify about objects in not present state and + // modify and notify relations related to those + if( notifyItemIds.Count() > 0 ) + { + iNotifier.NotifyObjectPresent( ETrue, notifyItemIds ); + + RArray relationIds; + CleanupClosePushL( relationIds ); + + const TInt itemIdCount = notifyItemIds.Count(); + for( TUint32 i = 0; i < itemIdCount; i++ ) + { + iManipulate->SetRelationsToPresentL( notifyItemIds[i], relationIds ); + } + + iNotifier.NotifyRelationPresent( ETrue, relationIds ); + + CleanupStack::PopAndDestroy( &relationIds ); + } + + transaction.CommitL(); + + CleanupStack::PopAndDestroy( ¬ifyItemIds ); + CleanupStack::PopAndDestroy( &itemIds ); + + CleanupStack::PopAndDestroy( &transaction ); + } + +// --------------------------------------------------------------------------- +// SetFilesToNotPresentL +// --------------------------------------------------------------------------- +// +void CMdSManipulationEngine::SetFilesToNotPresentL(TUint32 aMediaId, TBool aStartUp) + { + CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL(); + RMdSTransaction transaction( connection ); + CleanupClosePushL( transaction ); + User::LeaveIfError( transaction.Error() ); + + RArray objectIds; + CleanupClosePushL( objectIds ); + + iManipulate->SetFilesToNotPresentL( aMediaId, aStartUp, objectIds ); + + // if start up no need for object notifications, + // setting relations to not present and relation notifications + if( !aStartUp ) + { + iNotifier.NotifyObjectPresent( EFalse, objectIds ); + + RArray relationIds; + CleanupClosePushL( relationIds ); + + iManipulate->SetRelationsToNotPresentL( aMediaId, relationIds ); + iNotifier.NotifyRelationPresent( EFalse, relationIds ); + + CleanupStack::PopAndDestroy( &relationIds ); + } + + transaction.CommitL(); + + CleanupStack::PopAndDestroy( &objectIds ); + CleanupStack::PopAndDestroy( &transaction ); + } + +// --------------------------------------------------------------------------- +// RemoveFilesNotPresentL +// --------------------------------------------------------------------------- +// +void CMdSManipulationEngine::RemoveFilesNotPresentL(TUint32 aMediaId, TBool aStartUp) + { + CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL(); + RMdSTransaction transaction( connection ); + CleanupClosePushL( transaction ); + User::LeaveIfError( transaction.Error() ); + + if( aStartUp ) + { + RArray objectIds; + CleanupClosePushL( objectIds ); + + iManipulate->RemoveFilesNotPresentL( aMediaId, &objectIds ); + + if( objectIds.Count() > 0 ) + { + iNotifier.NotifyRemovedL( objectIds ); + } + + CleanupStack::PopAndDestroy( &objectIds ); + } + else + { + iManipulate->RemoveFilesNotPresentL( aMediaId, NULL ); + } + + transaction.CommitL(); + CleanupStack::PopAndDestroy( &transaction ); + + // start garbage collector + if( iGarbageCollector ) + { + iGarbageCollector->Start( KGarbageCollectionDelay ); + } + } + +// --------------------------------------------------------------------------- +// StartGarbageCollection +// --------------------------------------------------------------------------- +// +TBool CMdSManipulationEngine::StartGarbageCollectionL() + { +#ifdef _DEBUG + RDebug::Print( _L("CMdSManipulationEngine::StartGarbageCollection()") ); +#endif + + CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL(); + RMdSTransaction transaction( connection ); + CleanupClosePushL( transaction ); + User::LeaveIfError( transaction.Error() ); + + TBool again = EFalse; +#ifdef _DEBUG + TRAPD( err, again = iManipulate->GarbageCollectionL() ); +#else + TRAP_IGNORE( again = iManipulate->GarbageCollectionL() ); +#endif + + transaction.CommitL(); + CleanupStack::PopAndDestroy( &transaction ); + + #ifdef _DEBUG + if( err != KErrNone ) + { + _LIT( KErrLog, "CMdSManipulationEngine::StartGarbageCollection error: %d" ); + RDebug::Print( KErrLog, err ); + } + #endif + + return again; + } + +// --------------------------------------------------------------------------- +// GetSchemaVersionL +// --------------------------------------------------------------------------- +// +void CMdSManipulationEngine::GetSchemaVersionL( + TInt& aMajorVersion, TInt& aMinorVersion) + { + iManipulate->GetSchemaVersionL( aMajorVersion, aMinorVersion ); + } + +void CMdSManipulationEngine::SetObjectToPresentByGuidL( + const TInt64& aGuidHigh, const TInt64& aGuidLow ) + { + iManipulate->SetObjectToPresentByGuidL( aGuidHigh, aGuidLow ); + } + +void CMdSManipulationEngine::ChangePathL(const TDesC& aOldPath, const TDesC& aNewPath) + { + CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL(); + RMdSTransaction transaction( connection ); + CleanupClosePushL( transaction ); + User::LeaveIfError( transaction.Error() ); + + RArray objectIds; + CleanupClosePushL( objectIds ); + + iManipulate->ChangePathL( aOldPath, aNewPath, objectIds ); + + iNotifier.NotifyModifiedL( objectIds ); + + CleanupStack::PopAndDestroy( &objectIds ); + + transaction.CommitL(); + CleanupStack::PopAndDestroy( &transaction ); + } + +void CMdSManipulationEngine::ChangeMediaIdL() + { + CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL(); + RMdSTransaction transaction( connection ); + CleanupClosePushL( transaction ); + User::LeaveIfError( transaction.Error() ); + + iManipulate->ChangeMediaIdL(); + + transaction.CommitL(); + + CleanupStack::PopAndDestroy( &transaction ); + } + +void CMdSManipulationEngine::AddRelationDefL( TDefId aNamespaceId, const TDesC& aRelationDefName ) + { + CMdsNamespaceDef* namespaceDef = CONST_CAST( CMdsNamespaceDef*, iSchema.GetNamespaceByIdL( aNamespaceId ) ); + if ( !namespaceDef ) + { + User::Leave( KErrMdEUnknownNamespaceDef ); + } + if ( namespaceDef->GetReadOnly() ) + { + User::Leave( KErrLocked ); + } + + namespaceDef->AddRelationDefL( aRelationDefName ); + iSchema.StoreToDBL(); + } + +void CMdSManipulationEngine::AddEventDefL( TDefId aNamespaceId, const TDesC& aEventDefName ) + { + CMdsNamespaceDef* namespaceDef = CONST_CAST( CMdsNamespaceDef*, iSchema.GetNamespaceByIdL( aNamespaceId ) ); + if ( !namespaceDef ) + { + User::Leave( KErrMdEUnknownNamespaceDef ); + } + if ( namespaceDef->GetReadOnly() ) + { + User::Leave( KErrLocked ); + } + + namespaceDef->AddEventDefL( aEventDefName, 1 ); + iSchema.StoreToDBL(); + } + +void CMdSManipulationEngine::SetPendingL(const RArray& aObjectIds) + { + CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL(); + RMdSTransaction transaction( connection ); + CleanupClosePushL( transaction ); + User::LeaveIfError( transaction.Error() ); + + iManipulate->SetPendingL( aObjectIds, EFalse ); + + transaction.CommitL(); + CleanupStack::PopAndDestroy( &transaction ); + } + +void CMdSManipulationEngine::ResetPendingL(const RArray& aObjectIds) + { + iManipulate->SetPendingL( aObjectIds, ETrue ); + } + +TInt CMdSManipulationEngine::GetPendingCountL( TDefId aObjectDefId ) + { + return iManipulate->GetPendingCountL( aObjectDefId ); + } + +TInt CMdSManipulationEngine::GetPendingL( TDefId aObjectDefId, + TInt aBufferSize, RArray& aObjectIds ) + { + return iManipulate->GetPendingL( aObjectDefId, aBufferSize, aObjectIds ); + }