mtpfws/mtpfw/src/cmtpreferencemgr.cpp
changeset 0 d0791faffa3f
child 15 f85613f12947
equal deleted inserted replaced
-1:000000000000 0:d0791faffa3f
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <mtp/cmtptypearray.h>
       
    17 #include <mtp/mtpdatatypeconstants.h>
       
    18 #include <mtp/mtpprotocolconstants.h>
       
    19 #include <mtp/mtptypessimple.h>
       
    20 
       
    21 #include "cmtpobjectstore.h"
       
    22 #include "cmtpreferencemgr.h"
       
    23 #include "dbutility.h"
       
    24 
       
    25 
       
    26 _LIT(KSQLReferenceTableName, "ReferenceStore");
       
    27 _LIT(KSQLReferenceIndexName, "ReferenceIndex");
       
    28 _LIT(KSQLCreateReferenceTableText,"CREATE TABLE ReferenceStore (HandleId UNSIGNED INTEGER, References LONG VARBINARY)");
       
    29 _LIT(KSQLCreateReferenceIndexText,"CREATE UNIQUE INDEX ReferenceIndex on ReferenceStore (HandleId)");	
       
    30 
       
    31 
       
    32 static const TInt KMTPReferenceGranularity = 5;
       
    33 // Maximum value to use for granularity 
       
    34 // This will result in 4KB of memory used (1024 * 4bytes) for reference SUID array
       
    35 static const TInt KMTPMaxGranularity = 1024;
       
    36 
       
    37 /**
       
    38 Two phase construction
       
    39 @param aObjectMgr	Reference to the object manager
       
    40 @return a pointer to the reference manager instance
       
    41 */
       
    42 CMTPReferenceMgr* CMTPReferenceMgr::NewL(CMTPObjectStore& aObjectStore)
       
    43 	{
       
    44 	CMTPReferenceMgr* self = new (ELeave) CMTPReferenceMgr(aObjectStore);
       
    45 	CleanupStack::PushL(self);
       
    46 	self->ConstructL();
       
    47 	CleanupStack::Pop(self);
       
    48 	return self;
       
    49 	}
       
    50 
       
    51 /**
       
    52 Destructor
       
    53 */	
       
    54 CMTPReferenceMgr::~CMTPReferenceMgr()
       
    55 	{
       
    56 	iBatched.Close();
       
    57 	}
       
    58 
       
    59 /**
       
    60 Provides an MTP array of the target object handles which are referenced 
       
    61 by the specified source object handle. A pointer to the MTP array is 
       
    62 placed on the cleanup stack.
       
    63 @param aFromHandle The MTP object handle of the source object from which 
       
    64 the references originate.
       
    65 @return The MTP reference target object handle array. Ownership IS transferred.
       
    66 @leave One of the system wide error codes, if a processing failure occurs.
       
    67 */	
       
    68 CMTPTypeArray* CMTPReferenceMgr::ReferencesLC(const TMTPTypeUint32& aFromHandle) const
       
    69 	{
       
    70 	return GetReferencesLC(aFromHandle.Value());
       
    71 	}
       
    72 
       
    73 /**
       
    74 Provides an SUID array of the target object SUIDs which are referenced by 
       
    75 the specified source object SUID. A pointer to the SUID array is 
       
    76 placed on the cleanup stack.
       
    77 @param aFromSuid The SUID of the source object from which the references 
       
    78 originate.
       
    79 @return The reference target object SUID array. Ownership IS transferred.
       
    80 @leave One of the system wide error codes, if a processing failure occurs.
       
    81 */	
       
    82 CDesCArray* CMTPReferenceMgr::ReferencesLC(const TDesC& aParentSuid) const
       
    83 	{
       
    84 	TUint32 handle =  iObjectStore.HandleL(aParentSuid);
       
    85 	return GetReferencesInDesLC(handle);
       
    86 	}
       
    87 
       
    88 /**
       
    89 Removes all object reference links in which the specified SUID represents 
       
    90 either the source or target reference object.
       
    91 @param aSuid The object SUID.
       
    92 @leave One of the system wide error codes, if a processing failure occurs.
       
    93 */	
       
    94 void CMTPReferenceMgr::RemoveReferencesL(const TDesC& aSuid)
       
    95 	{
       
    96 	TUint32 handle =  iObjectStore.HandleL(aSuid);
       
    97 	RemoveReferencesL(handle);
       
    98 	}
       
    99 
       
   100 /**
       
   101 Creates an abstract reference linkage between the specified source and 
       
   102 target object SUIDs.
       
   103 @param aFromSuid The SUID of the source object from which the reference 
       
   104 originates.
       
   105 param aToSuid The SUID of the target object to which the reference is 
       
   106 made.
       
   107 @leave One of the system wide error codes, if a processing failure occurs.
       
   108 */	
       
   109 void CMTPReferenceMgr::SetReferenceL(const TDesC& aFromSuid, const TDesC& aToSuid)
       
   110 	{
       
   111 	TUint32 fromHandle =  iObjectStore.HandleL(aFromSuid);
       
   112 	TUint32 toHandle =  iObjectStore.HandleL(aToSuid);
       
   113 	SetReferenceL(fromHandle, toHandle);
       
   114 	}
       
   115 
       
   116 /**
       
   117 Replaces the abstract reference links originating from the specified 
       
   118 source object handle with the specified set of target object SUIDs.
       
   119 @param aFromHandle The SUID of the source object from which the references 
       
   120 originate.
       
   121 @param aToSuids The reference target MTP object SUID array.
       
   122 @leave One of the system wide error codes, if a processing failure occurs.
       
   123 */	
       
   124 void CMTPReferenceMgr::SetReferencesL(const TDesC& aParentSuid, const CDesCArray& aToSuids)
       
   125 	{
       
   126 	TInt count = aToSuids.Count();
       
   127 	
       
   128 	if (count > 0)
       
   129 		{
       
   130 		TUint32 fromHandle =  iObjectStore.HandleL(aParentSuid);
       
   131 	
       
   132 		// Limit granularity to something less or equal to KMTPMaxGranularity items
       
   133 		RArray<TUint> toHandles(Min(count, KMTPMaxGranularity));
       
   134 		CleanupClosePushL(toHandles);
       
   135 		
       
   136 		for(TInt i = 0; i < count; i++)
       
   137 			{
       
   138 			TUint32 toHandle =  iObjectStore.HandleL(aToSuids[i]);
       
   139 			toHandles.Append(toHandle);
       
   140 			}	
       
   141 		
       
   142 		SetReferencesL(fromHandle, toHandles);	
       
   143 		CleanupStack::PopAndDestroy(&toHandles);
       
   144 		}
       
   145 	}
       
   146 
       
   147 
       
   148 /**
       
   149 Constructor/.
       
   150 */    
       
   151 CMTPReferenceMgr::CMTPReferenceMgr(CMTPObjectStore& aObjectStore):
       
   152 	iObjectStore(aObjectStore)
       
   153 	{
       
   154 	
       
   155 	}
       
   156 
       
   157 /**
       
   158 second-phase construction
       
   159 @leave One of the system wide error codes, if a processing failure occurs.
       
   160 */	
       
   161 void CMTPReferenceMgr::ConstructL()
       
   162 	{
       
   163     iDatabase   = &iObjectStore.Database();
       
   164 
       
   165 	if(!DBUtility::IsTableExistsL(*iDatabase, KSQLReferenceTableName))
       
   166 		{
       
   167 		CreateTableL();
       
   168 		}
       
   169 	if(!DBUtility::IsIndexExistsL(*iDatabase, KSQLReferenceTableName, KSQLReferenceIndexName))
       
   170 		{
       
   171 		CreateIndexL();
       
   172 		}
       
   173 	iBatched.Open(*iDatabase, KSQLReferenceTableName, RDbRowSet::EUpdatable);
       
   174 	iBatched.SetIndex( KSQLReferenceIndexName ); 
       
   175 	}
       
   176 
       
   177 /**
       
   178 Create the reference table in the database
       
   179 @leave One of the system wide error codes, if a processing failure occurs.
       
   180 */	
       
   181 void CMTPReferenceMgr::CreateTableL()
       
   182 	{
       
   183 	User::LeaveIfError(iDatabase->Execute(KSQLCreateReferenceTableText));	
       
   184 	}
       
   185 
       
   186 /**
       
   187 Create the index in the reference table
       
   188 @leave One of the system wide error codes, if a processing failure occurs.
       
   189 */	
       
   190 void CMTPReferenceMgr::CreateIndexL()
       
   191 	{
       
   192 	User::LeaveIfError(iDatabase->Execute(KSQLCreateReferenceIndexText));	
       
   193 	}
       
   194 
       
   195 /**
       
   196 Get reference on the object identified by aIdentifier
       
   197 @param aIdentifier	The 64bit internal object identifier
       
   198 @return The array containing the handles of the references
       
   199 @leave One of the system wide error codes, if a processing failure occurs.
       
   200 */
       
   201 CMTPTypeArray* CMTPReferenceMgr::GetReferencesLC(TUint aHandle) const
       
   202 	{
       
   203 	RArray<TUint> toHandles;
       
   204 	CleanupClosePushL(toHandles);
       
   205 	GetReferencesL(aHandle, toHandles);
       
   206 	
       
   207 	CMTPTypeArray* mtpReferenceArray = CMTPTypeArray::NewLC(EMTPTypeAUINT32);	
       
   208 	mtpReferenceArray->AppendL(toHandles);
       
   209 	CleanupStack::Pop(mtpReferenceArray);
       
   210 	CleanupStack::PopAndDestroy(&toHandles);
       
   211 	CleanupStack::PushL(mtpReferenceArray);
       
   212 	return mtpReferenceArray;
       
   213 	}
       
   214 
       
   215 /**
       
   216 Get reference on the object identified by aIdentifier
       
   217 @param aIdentifier	The 64bit internal object identifier
       
   218 @return The array containing the suids of the references
       
   219 @leave One of the system wide error codes, if a processing failure occurs.
       
   220 */	
       
   221 CDesCArray*	 CMTPReferenceMgr::GetReferencesInDesLC(TUint aHandle) const
       
   222 	{
       
   223 	RArray<TUint> toHandles(KMTPReferenceGranularity);
       
   224 	CleanupClosePushL(toHandles);
       
   225 	GetReferencesL(aHandle, toHandles);	
       
   226 	const TInt count = toHandles.Count();
       
   227 	CDesCArray* mtpReferenceArray = new (ELeave) CDesCArrayFlat((count==0) ? 1 : count);
       
   228 	CleanupStack::PushL(mtpReferenceArray);
       
   229 	
       
   230 	for(TInt i = 0; i < count; i++)
       
   231 		{
       
   232 		const TDesC& suid = iObjectStore.ObjectSuidL(toHandles[i]);
       
   233 		if(suid.Length())
       
   234 			{
       
   235 			mtpReferenceArray->AppendL(suid);
       
   236 			}
       
   237 		}
       
   238 	CleanupStack::Pop(mtpReferenceArray);
       
   239 	CleanupStack::PopAndDestroy(&toHandles);
       
   240 	CleanupStack::PushL(mtpReferenceArray);
       
   241 	return mtpReferenceArray;		
       
   242 	
       
   243 	}
       
   244 
       
   245 /**
       
   246 Get references on the object identified by aIdentifier
       
   247 @param aIdentifier	The 64bit internal object identifier
       
   248 @param aReferences	The reference array, on return, containing the 64bit internal identifiers of the references
       
   249 @leave One of the system wide error codes, if a processing failure occurs.
       
   250 */	
       
   251 void CMTPReferenceMgr::GetReferencesL(TUint aHandle, RArray<TUint>& aToHandles) const
       
   252 	{
       
   253 	TUint32 temp = 0;
       
   254 	TBool   needToUpdate = EFalse;
       
   255 	aToHandles.Reset();
       
   256 	if(iBatched.SeekL(aHandle))
       
   257 		{
       
   258 		iBatched.GetL();
       
   259 	    RDbColReadStream readStream;     
       
   260         readStream.OpenLC(iBatched,2);
       
   261         TInt count = readStream.ReadInt32L();
       
   262         while(count--)
       
   263         	{
       
   264         	temp = readStream.ReadUint32L();
       
   265 			if(iObjectStore.ObjectExistsL(temp))
       
   266 	        	aToHandles.AppendL(temp);
       
   267 			else
       
   268 				needToUpdate = ETrue;
       
   269         	}
       
   270         CleanupStack::PopAndDestroy(&readStream);
       
   271 
       
   272 		
       
   273 		if(needToUpdate)
       
   274 			{//Something has been deleted. Write it back to Reference list
       
   275 			iBatched.UpdateL();
       
   276 			RDbColWriteStream writeStream;	   
       
   277 			writeStream.OpenLC(iBatched,2);
       
   278 			
       
   279 			count = aToHandles.Count();
       
   280 			writeStream.WriteInt32L(count);
       
   281 			for(TInt i = 0; i < count; i++)
       
   282 				{
       
   283 				writeStream.WriteUint32L(aToHandles[i]);
       
   284 				}
       
   285 			writeStream.CommitL(); 
       
   286 			CleanupStack::PopAndDestroy(&writeStream);
       
   287 			iBatched.PutL();			
       
   288 			}
       
   289 		
       
   290 		}	
       
   291 	return;
       
   292 
       
   293 	}
       
   294 
       
   295 
       
   296 /**
       
   297 Remove reference on the object identified by aIdentifier
       
   298 @param aIdentifier	The 64bit internal object identifier
       
   299 @leave One of the system wide error codes, if a processing failure occurs.
       
   300 */	
       
   301 void CMTPReferenceMgr::RemoveReferencesL(TUint aHandle)
       
   302 	{
       
   303 	if(iBatched.SeekL(aHandle))
       
   304 		{
       
   305 		iBatched.DeleteL();
       
   306 		IncTranOpsNumL();
       
   307 		}
       
   308 	}
       
   309 /**
       
   310 Set reference on the object identified by aFromIdentifier
       
   311 @param aFromIdentifier	The 64bit internal object identifier of the source object
       
   312 @param aToIdentifier	The 64bit internal object identifier of the referenced object
       
   313 @leave One of the system wide error codes, if a processing failure occurs.
       
   314 */	
       
   315 void CMTPReferenceMgr::SetReferenceL(TUint aFromHandle, TUint aToHandle)
       
   316 	{
       
   317 	RArray<TUint> aToHandleArray(1);
       
   318 	CleanupClosePushL(aToHandleArray);
       
   319 	aToHandleArray.AppendL(aToHandle);
       
   320 	SetReferencesL(aFromHandle, aToHandleArray);
       
   321 	CleanupStack::PopAndDestroy(&aToHandleArray);
       
   322 	}
       
   323 
       
   324 /**
       
   325 Replaces the abstract reference links originating from the specified 
       
   326 source object handle with the specified set of target object handles.
       
   327 @param aFromHandle The handle of the source object from which the references 
       
   328 originate.
       
   329 @param aToHandles The reference target object handle array.
       
   330 @leave One of the system wide error codes, if a processing failure occurs.
       
   331 */	
       
   332 void CMTPReferenceMgr::SetReferencesL(const TMTPTypeUint32& aFromHandle, const CMTPTypeArray& aToHandles)
       
   333 {
       
   334 	RArray<TUint> tempArray;
       
   335 	CleanupClosePushL(tempArray);
       
   336 	TInt count = aToHandles.NumElements();
       
   337 	for(TInt i = 0; i < count; i++)
       
   338 		{
       
   339 		tempArray.Append(aToHandles.ElementUint(i));
       
   340 		}	
       
   341 	SetReferencesL(aFromHandle.Value(), tempArray);
       
   342 	CleanupStack::PopAndDestroy(&tempArray);
       
   343 }
       
   344 
       
   345 
       
   346 
       
   347 /**
       
   348 Set references on the object identified by aFromIdentifier
       
   349 @param aFromIdentifier	The 64bit internal object identifier of the source object
       
   350 @param aToIdentifiers	The 64bit internal object identifiers of the referenced objects
       
   351 @leave One of the system wide error codes, if a processing failure occurs.
       
   352 */   	
       
   353 void CMTPReferenceMgr::SetReferencesL(TUint aHandle, const RArray<TUint>& aToHandles)
       
   354 	{
       
   355 	if(iBatched.SeekL(aHandle))
       
   356 		{
       
   357 		iBatched.UpdateL();		
       
   358 		}
       
   359 	else
       
   360 		{
       
   361 		iBatched.InsertL();		
       
   362 		}
       
   363 	
       
   364 	iBatched.SetColL(1, aHandle);
       
   365 	
       
   366 	RDbColWriteStream writeStream;     
       
   367     writeStream.OpenLC(iBatched,2);
       
   368     
       
   369     const TInt count = aToHandles.Count();
       
   370     writeStream.WriteInt32L(count);
       
   371     for(TInt i = 0; i < count; i++)
       
   372         {
       
   373         writeStream.WriteUint32L(aToHandles[i]);
       
   374         }
       
   375     writeStream.CommitL(); 
       
   376     CleanupStack::PopAndDestroy(&writeStream);
       
   377 	iBatched.PutL();			
       
   378 	IncTranOpsNumL();
       
   379 	}
       
   380 
       
   381 
       
   382 void CMTPReferenceMgr::IncTranOpsNumL()
       
   383 	{
       
   384 	iObjectStore.IncTranOpsNumL();
       
   385 	}
       
   386 
       
   387 
       
   388 /**
       
   389 Verify if every reference is pointing to a valid object. If the referenced object does not exist,
       
   390 delete the object from the reference array.
       
   391 @param aReference	The 64bit internal object identifiers of the referenced objects
       
   392 @leave One of the system wide error codes, if a processing failure occurs.
       
   393 */
       
   394 /*
       
   395 void CMTPReferenceMgr::AdjustReferencesL(RArray<TUint32>&aHandles) const
       
   396 	{
       
   397 	TInt count = aHandles.Count();
       
   398 	while(count--)
       
   399 		{
       
   400 		if(!iObjectStore.ObjectExistsL(aHandles[count]))
       
   401 			{
       
   402 			aHandles.Remove(count);
       
   403 			}
       
   404 		}
       
   405 	}
       
   406 	*/
       
   407