/*
* 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::CheckMassStorageMediaIdL( const TUint32 aMediaId )
{
CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
RMdSTransaction transaction( connection );
CleanupClosePushL( transaction );
User::LeaveIfError( transaction.Error() );
iManipulate->CheckMassStorageMediaIdL( aMediaId );
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 );
}