mtpfws/mtpfw/src/cmtpreferencemgr.cpp
changeset 0 d0791faffa3f
child 15 f85613f12947
--- /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 <mtp/cmtptypearray.h>
+#include <mtp/mtpdatatypeconstants.h>
+#include <mtp/mtpprotocolconstants.h>
+#include <mtp/mtptypessimple.h>
+
+#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<TUint> 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<TUint> 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<TUint> 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<TUint>& 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<TUint> 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<TUint> 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<TUint>& 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<TUint32>&aHandles) const
+	{
+	TInt count = aHandles.Count();
+	while(count--)
+		{
+		if(!iObjectStore.ObjectExistsL(aHandles[count]))
+			{
+			aHandles.Remove(count);
+			}
+		}
+	}
+	*/
+