diff -r 000000000000 -r d0791faffa3f mtpfws/mtpfw/src/cmtpreferencemgr.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mtpfws/mtpfw/src/cmtpreferencemgr.cpp Tue Feb 02 01:11:40 2010 +0200 @@ -0,0 +1,407 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include +#include +#include + +#include "cmtpobjectstore.h" +#include "cmtpreferencemgr.h" +#include "dbutility.h" + + +_LIT(KSQLReferenceTableName, "ReferenceStore"); +_LIT(KSQLReferenceIndexName, "ReferenceIndex"); +_LIT(KSQLCreateReferenceTableText,"CREATE TABLE ReferenceStore (HandleId UNSIGNED INTEGER, References LONG VARBINARY)"); +_LIT(KSQLCreateReferenceIndexText,"CREATE UNIQUE INDEX ReferenceIndex on ReferenceStore (HandleId)"); + + +static const TInt KMTPReferenceGranularity = 5; +// Maximum value to use for granularity +// This will result in 4KB of memory used (1024 * 4bytes) for reference SUID array +static const TInt KMTPMaxGranularity = 1024; + +/** +Two phase construction +@param aObjectMgr Reference to the object manager +@return a pointer to the reference manager instance +*/ +CMTPReferenceMgr* CMTPReferenceMgr::NewL(CMTPObjectStore& aObjectStore) + { + CMTPReferenceMgr* self = new (ELeave) CMTPReferenceMgr(aObjectStore); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** +Destructor +*/ +CMTPReferenceMgr::~CMTPReferenceMgr() + { + iBatched.Close(); + } + +/** +Provides an MTP array of the target object handles which are referenced +by the specified source object handle. A pointer to the MTP array is +placed on the cleanup stack. +@param aFromHandle The MTP object handle of the source object from which +the references originate. +@return The MTP reference target object handle array. Ownership IS transferred. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +CMTPTypeArray* CMTPReferenceMgr::ReferencesLC(const TMTPTypeUint32& aFromHandle) const + { + return GetReferencesLC(aFromHandle.Value()); + } + +/** +Provides an SUID array of the target object SUIDs which are referenced by +the specified source object SUID. A pointer to the SUID array is +placed on the cleanup stack. +@param aFromSuid The SUID of the source object from which the references +originate. +@return The reference target object SUID array. Ownership IS transferred. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +CDesCArray* CMTPReferenceMgr::ReferencesLC(const TDesC& aParentSuid) const + { + TUint32 handle = iObjectStore.HandleL(aParentSuid); + return GetReferencesInDesLC(handle); + } + +/** +Removes all object reference links in which the specified SUID represents +either the source or target reference object. +@param aSuid The object SUID. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPReferenceMgr::RemoveReferencesL(const TDesC& aSuid) + { + TUint32 handle = iObjectStore.HandleL(aSuid); + RemoveReferencesL(handle); + } + +/** +Creates an abstract reference linkage between the specified source and +target object SUIDs. +@param aFromSuid The SUID of the source object from which the reference +originates. +param aToSuid The SUID of the target object to which the reference is +made. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPReferenceMgr::SetReferenceL(const TDesC& aFromSuid, const TDesC& aToSuid) + { + TUint32 fromHandle = iObjectStore.HandleL(aFromSuid); + TUint32 toHandle = iObjectStore.HandleL(aToSuid); + SetReferenceL(fromHandle, toHandle); + } + +/** +Replaces the abstract reference links originating from the specified +source object handle with the specified set of target object SUIDs. +@param aFromHandle The SUID of the source object from which the references +originate. +@param aToSuids The reference target MTP object SUID array. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPReferenceMgr::SetReferencesL(const TDesC& aParentSuid, const CDesCArray& aToSuids) + { + TInt count = aToSuids.Count(); + + if (count > 0) + { + TUint32 fromHandle = iObjectStore.HandleL(aParentSuid); + + // Limit granularity to something less or equal to KMTPMaxGranularity items + RArray toHandles(Min(count, KMTPMaxGranularity)); + CleanupClosePushL(toHandles); + + for(TInt i = 0; i < count; i++) + { + TUint32 toHandle = iObjectStore.HandleL(aToSuids[i]); + toHandles.Append(toHandle); + } + + SetReferencesL(fromHandle, toHandles); + CleanupStack::PopAndDestroy(&toHandles); + } + } + + +/** +Constructor/. +*/ +CMTPReferenceMgr::CMTPReferenceMgr(CMTPObjectStore& aObjectStore): + iObjectStore(aObjectStore) + { + + } + +/** +second-phase construction +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPReferenceMgr::ConstructL() + { + iDatabase = &iObjectStore.Database(); + + if(!DBUtility::IsTableExistsL(*iDatabase, KSQLReferenceTableName)) + { + CreateTableL(); + } + if(!DBUtility::IsIndexExistsL(*iDatabase, KSQLReferenceTableName, KSQLReferenceIndexName)) + { + CreateIndexL(); + } + iBatched.Open(*iDatabase, KSQLReferenceTableName, RDbRowSet::EUpdatable); + iBatched.SetIndex( KSQLReferenceIndexName ); + } + +/** +Create the reference table in the database +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPReferenceMgr::CreateTableL() + { + User::LeaveIfError(iDatabase->Execute(KSQLCreateReferenceTableText)); + } + +/** +Create the index in the reference table +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPReferenceMgr::CreateIndexL() + { + User::LeaveIfError(iDatabase->Execute(KSQLCreateReferenceIndexText)); + } + +/** +Get reference on the object identified by aIdentifier +@param aIdentifier The 64bit internal object identifier +@return The array containing the handles of the references +@leave One of the system wide error codes, if a processing failure occurs. +*/ +CMTPTypeArray* CMTPReferenceMgr::GetReferencesLC(TUint aHandle) const + { + RArray toHandles; + CleanupClosePushL(toHandles); + GetReferencesL(aHandle, toHandles); + + CMTPTypeArray* mtpReferenceArray = CMTPTypeArray::NewLC(EMTPTypeAUINT32); + mtpReferenceArray->AppendL(toHandles); + CleanupStack::Pop(mtpReferenceArray); + CleanupStack::PopAndDestroy(&toHandles); + CleanupStack::PushL(mtpReferenceArray); + return mtpReferenceArray; + } + +/** +Get reference on the object identified by aIdentifier +@param aIdentifier The 64bit internal object identifier +@return The array containing the suids of the references +@leave One of the system wide error codes, if a processing failure occurs. +*/ +CDesCArray* CMTPReferenceMgr::GetReferencesInDesLC(TUint aHandle) const + { + RArray toHandles(KMTPReferenceGranularity); + CleanupClosePushL(toHandles); + GetReferencesL(aHandle, toHandles); + const TInt count = toHandles.Count(); + CDesCArray* mtpReferenceArray = new (ELeave) CDesCArrayFlat((count==0) ? 1 : count); + CleanupStack::PushL(mtpReferenceArray); + + for(TInt i = 0; i < count; i++) + { + const TDesC& suid = iObjectStore.ObjectSuidL(toHandles[i]); + if(suid.Length()) + { + mtpReferenceArray->AppendL(suid); + } + } + CleanupStack::Pop(mtpReferenceArray); + CleanupStack::PopAndDestroy(&toHandles); + CleanupStack::PushL(mtpReferenceArray); + return mtpReferenceArray; + + } + +/** +Get references on the object identified by aIdentifier +@param aIdentifier The 64bit internal object identifier +@param aReferences The reference array, on return, containing the 64bit internal identifiers of the references +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPReferenceMgr::GetReferencesL(TUint aHandle, RArray& aToHandles) const + { + TUint32 temp = 0; + TBool needToUpdate = EFalse; + aToHandles.Reset(); + if(iBatched.SeekL(aHandle)) + { + iBatched.GetL(); + RDbColReadStream readStream; + readStream.OpenLC(iBatched,2); + TInt count = readStream.ReadInt32L(); + while(count--) + { + temp = readStream.ReadUint32L(); + if(iObjectStore.ObjectExistsL(temp)) + aToHandles.AppendL(temp); + else + needToUpdate = ETrue; + } + CleanupStack::PopAndDestroy(&readStream); + + + if(needToUpdate) + {//Something has been deleted. Write it back to Reference list + iBatched.UpdateL(); + RDbColWriteStream writeStream; + writeStream.OpenLC(iBatched,2); + + count = aToHandles.Count(); + writeStream.WriteInt32L(count); + for(TInt i = 0; i < count; i++) + { + writeStream.WriteUint32L(aToHandles[i]); + } + writeStream.CommitL(); + CleanupStack::PopAndDestroy(&writeStream); + iBatched.PutL(); + } + + } + return; + + } + + +/** +Remove reference on the object identified by aIdentifier +@param aIdentifier The 64bit internal object identifier +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPReferenceMgr::RemoveReferencesL(TUint aHandle) + { + if(iBatched.SeekL(aHandle)) + { + iBatched.DeleteL(); + IncTranOpsNumL(); + } + } +/** +Set reference on the object identified by aFromIdentifier +@param aFromIdentifier The 64bit internal object identifier of the source object +@param aToIdentifier The 64bit internal object identifier of the referenced object +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPReferenceMgr::SetReferenceL(TUint aFromHandle, TUint aToHandle) + { + RArray aToHandleArray(1); + CleanupClosePushL(aToHandleArray); + aToHandleArray.AppendL(aToHandle); + SetReferencesL(aFromHandle, aToHandleArray); + CleanupStack::PopAndDestroy(&aToHandleArray); + } + +/** +Replaces the abstract reference links originating from the specified +source object handle with the specified set of target object handles. +@param aFromHandle The handle of the source object from which the references +originate. +@param aToHandles The reference target object handle array. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPReferenceMgr::SetReferencesL(const TMTPTypeUint32& aFromHandle, const CMTPTypeArray& aToHandles) +{ + RArray tempArray; + CleanupClosePushL(tempArray); + TInt count = aToHandles.NumElements(); + for(TInt i = 0; i < count; i++) + { + tempArray.Append(aToHandles.ElementUint(i)); + } + SetReferencesL(aFromHandle.Value(), tempArray); + CleanupStack::PopAndDestroy(&tempArray); +} + + + +/** +Set references on the object identified by aFromIdentifier +@param aFromIdentifier The 64bit internal object identifier of the source object +@param aToIdentifiers The 64bit internal object identifiers of the referenced objects +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPReferenceMgr::SetReferencesL(TUint aHandle, const RArray& aToHandles) + { + if(iBatched.SeekL(aHandle)) + { + iBatched.UpdateL(); + } + else + { + iBatched.InsertL(); + } + + iBatched.SetColL(1, aHandle); + + RDbColWriteStream writeStream; + writeStream.OpenLC(iBatched,2); + + const TInt count = aToHandles.Count(); + writeStream.WriteInt32L(count); + for(TInt i = 0; i < count; i++) + { + writeStream.WriteUint32L(aToHandles[i]); + } + writeStream.CommitL(); + CleanupStack::PopAndDestroy(&writeStream); + iBatched.PutL(); + IncTranOpsNumL(); + } + + +void CMTPReferenceMgr::IncTranOpsNumL() + { + iObjectStore.IncTranOpsNumL(); + } + + +/** +Verify if every reference is pointing to a valid object. If the referenced object does not exist, +delete the object from the reference array. +@param aReference The 64bit internal object identifiers of the referenced objects +@leave One of the system wide error codes, if a processing failure occurs. +*/ +/* +void CMTPReferenceMgr::AdjustReferencesL(RArray&aHandles) const + { + TInt count = aHandles.Count(); + while(count--) + { + if(!iObjectStore.ObjectExistsL(aHandles[count])) + { + aHandles.Remove(count); + } + } + } + */ +