--- /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<TItemId> idArray;
+ CleanupClosePushL( idArray );
+ RArray<TItemId> removedRelations;
+ CleanupClosePushL( removedRelations );
+ RArray<TItemId> 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<TItemId> itemIds;
+ CleanupClosePushL( itemIds );
+ itemIds.ReserveL( aFileCount );
+
+ RArray<TItemId> 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<TItemId> 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<TItemId> 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<TItemId> 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<TItemId> 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<TItemId> 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<TItemId>& 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<TItemId>& aObjectIds)
+ {
+ iManipulate->SetPendingL( aObjectIds, ETrue );
+ }
+
+TInt CMdSManipulationEngine::GetPendingCountL( TDefId aObjectDefId )
+ {
+ return iManipulate->GetPendingCountL( aObjectDefId );
+ }
+
+TInt CMdSManipulationEngine::GetPendingL( TDefId aObjectDefId,
+ TInt aBufferSize, RArray<TItemId>& aObjectIds )
+ {
+ return iManipulate->GetPendingL( aObjectDefId, aBufferSize, aObjectIds );
+ }