metadataengine/server/src/mdsmanipulationengine.cpp
changeset 0 c53acadfccc6
child 3 b73a2e62868f
equal deleted inserted replaced
-1:000000000000 0:c53acadfccc6
       
     1 /*
       
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This is Manipulation engine to manage adding,
       
    15 *                deleting and modifying metadata database entries
       
    16 *
       
    17 */
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "mdsmanipulationengine.h"
       
    21 
       
    22 #include "mdcresult.h"
       
    23 #include "mdcitem.h"
       
    24 #include "mdsschema.h"
       
    25 #include "mdsnotifier.h"
       
    26 #include "mdsdbconnectionpool.h"
       
    27 #include "mdslogger.h"
       
    28 #include "mdssqlobjectmanipulate.h"
       
    29 #include "mdssqliteconnection.h"
       
    30 #include "mdsnamespacedef.h"
       
    31 #include "mdcserializationbuffer.h"
       
    32 #include "mdeinternalerror.h"
       
    33 #include "mdeerror.h"
       
    34 
       
    35 __USES_LOGGER
       
    36 
       
    37 // ======== LOCAL FUNCTIONS ========
       
    38 
       
    39 static void TransactionCleanupL(void* aConn)
       
    40    {
       
    41    CMdSSqLiteConnection* conn = (CMdSSqLiteConnection*)aConn;
       
    42    conn->TransactionRollbackL();
       
    43    }
       
    44 
       
    45 // ---------------------------------------------------------------------------
       
    46 // NewL
       
    47 // ---------------------------------------------------------------------------
       
    48 //
       
    49 CMdSManipulationEngine* CMdSManipulationEngine::NewL( CMdsSchema& aSchema,
       
    50     CMdSNotifier& aNotifier, CMdSObjectLockList& aLockList )
       
    51     {
       
    52     CMdSManipulationEngine* self = CMdSManipulationEngine::NewLC( aSchema, 
       
    53     		aNotifier, aLockList );
       
    54     CleanupStack::Pop( self );
       
    55     return self;
       
    56     }
       
    57 
       
    58 // ---------------------------------------------------------------------------
       
    59 // NewLC
       
    60 // ---------------------------------------------------------------------------
       
    61 //
       
    62 CMdSManipulationEngine* CMdSManipulationEngine::NewLC( CMdsSchema& aSchema,
       
    63     CMdSNotifier& aNotifier, CMdSObjectLockList& aLockList )
       
    64     {
       
    65     CMdSManipulationEngine* self = new (ELeave) CMdSManipulationEngine(
       
    66         aSchema, aNotifier, aLockList );
       
    67     CleanupStack::PushL( self );
       
    68     self->ConstructL();
       
    69     return self;
       
    70     }
       
    71 
       
    72 // ---------------------------------------------------------------------------
       
    73 // Default constructor
       
    74 // ---------------------------------------------------------------------------
       
    75 //
       
    76 CMdSManipulationEngine::CMdSManipulationEngine( CMdsSchema& aSchema,
       
    77     CMdSNotifier& aNotifier, CMdSObjectLockList& aLockList )
       
    78     : iManipulate( NULL ), iSchema( aSchema ), iNotifier( aNotifier ), 
       
    79     iGarbageCollector( NULL ), iLockList( aLockList )
       
    80     {
       
    81     }
       
    82 
       
    83 // ---------------------------------------------------------------------------
       
    84 // ConstructL
       
    85 // ---------------------------------------------------------------------------
       
    86 //
       
    87 void CMdSManipulationEngine::ConstructL()
       
    88     {
       
    89     iManipulate = CMdSSqlObjectManipulate::NewL( iSchema, iLockList );
       
    90     iGarbageCollector = CMdSGarbageCollector::NewL(*this);
       
    91     }
       
    92 
       
    93 // ---------------------------------------------------------------------------
       
    94 // Destructor
       
    95 // ---------------------------------------------------------------------------
       
    96 //
       
    97 CMdSManipulationEngine::~CMdSManipulationEngine()
       
    98     {
       
    99     delete iManipulate;
       
   100     
       
   101     delete iGarbageCollector;
       
   102     }
       
   103 
       
   104 // ---------------------------------------------------------------------------
       
   105 // Manipulate
       
   106 // ---------------------------------------------------------------------------
       
   107 //
       
   108 CMdSSqlObjectManipulate& CMdSManipulationEngine::Manipulate()
       
   109     {
       
   110     return *iManipulate;
       
   111     }
       
   112 
       
   113 // ---------------------------------------------------------------------------
       
   114 // GarbageCollector
       
   115 // ---------------------------------------------------------------------------
       
   116 //
       
   117 CMdSGarbageCollector& CMdSManipulationEngine::GarbageCollector()
       
   118 	{
       
   119 	return *iGarbageCollector;
       
   120 	}
       
   121 
       
   122 // ---------------------------------------------------------------------------
       
   123 // AddL adds objects from serialized buffer
       
   124 // ---------------------------------------------------------------------------
       
   125 //
       
   126 void CMdSManipulationEngine::AddL( CMdCSerializationBuffer& aBuffer, 
       
   127 		CMdCSerializationBuffer& aResultBuffer, 
       
   128 		const CMdSServerSession* aServerSession )
       
   129 	{
       
   130 	const TMdCItems& items = TMdCItems::GetFromBufferL( aBuffer );
       
   131 
       
   132 	const CMdsNamespaceDef* namespaceDef = iSchema.GetNamespaceByIdL( 
       
   133 			items.iNamespaceDefId );
       
   134 	if ( !namespaceDef )
       
   135 		{
       
   136 		User::Leave( KErrMdEUnknownNamespaceDef );
       
   137 		}
       
   138 	iManipulate->SetNamespace( namespaceDef );
       
   139 
       
   140 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   141 
       
   142 	TMdCItemIds resultIds;
       
   143 	resultIds.iNamespaceDefId = items.iNamespaceDefId;
       
   144 	resultIds.iErrorCode = KErrNone;
       
   145 	aResultBuffer.PositionL( sizeof(TMdCItemIds) );
       
   146 
       
   147 	// add objects
       
   148 	const TInt KObjectCount = items.iObjects.iPtr.iCount;
       
   149 	if ( KObjectCount > 0 )
       
   150 		{
       
   151 		resultIds.iObjectIds.iPtr.iOffset = aResultBuffer.Position();
       
   152 		resultIds.iObjectIds.iPtr.iCount = items.iObjects.iPtr.iCount;
       
   153 
       
   154         RMdsStatement baseObjStmt;
       
   155         CleanupClosePushL(baseObjStmt);
       
   156         RMdsStatement objStmt;
       
   157         CleanupClosePushL(objStmt);
       
   158 		
       
   159 		if( KObjectCount > 1 )
       
   160 		    {
       
   161 	        RMdSTransaction transaction( connection );
       
   162 	        CleanupClosePushL(transaction);
       
   163 	        const TInt beginError( transaction.Error() );
       
   164 	        if( beginError != KErrNone )
       
   165 	            {
       
   166 	            CleanupStack::PopAndDestroy( &transaction );
       
   167 	            }
       
   168 	    
       
   169 		    for ( TInt i = 0; i < KObjectCount; ++i )
       
   170 			    {
       
   171 			    aBuffer.PositionL( items.iObjects.iPtr.iOffset + i * sizeof(TMdCObject) );
       
   172 			    TItemId id = KNoId;
       
   173 			    TRAPD( err, id = iManipulate->AddObjectL( connection, aBuffer, 
       
   174 			            baseObjStmt, objStmt, aServerSession ) );
       
   175 			    if (err == KErrNone)
       
   176 				    {
       
   177 				    aResultBuffer.InsertL( id );
       
   178 				    }
       
   179 			    else
       
   180 				    {
       
   181 				    aResultBuffer.InsertL( KNoId );
       
   182 				    if(resultIds.iErrorCode == KErrNone)
       
   183 					    {
       
   184 					    resultIds.iErrorCode = err;
       
   185 					    }
       
   186 				    }
       
   187 			    }
       
   188 		    if( beginError == KErrNone )
       
   189 		        {
       
   190 	            transaction.CommitL();
       
   191 	            CleanupStack::PopAndDestroy( &transaction );
       
   192 		        }
       
   193 		    }
       
   194 		else
       
   195 		    {
       
   196             for ( TInt i = 0; i < KObjectCount; ++i )
       
   197                 {
       
   198                 aBuffer.PositionL( items.iObjects.iPtr.iOffset + i * sizeof(TMdCObject) );
       
   199                 TItemId id = KNoId;
       
   200                 TRAPD( err, id = iManipulate->AddObjectL( connection, aBuffer, 
       
   201                         baseObjStmt, objStmt, aServerSession ) );
       
   202                 if (err == KErrNone)
       
   203                     {
       
   204                     aResultBuffer.InsertL( id );
       
   205                     }
       
   206                 else
       
   207                     {
       
   208                     aResultBuffer.InsertL( KNoId );
       
   209                     if(resultIds.iErrorCode == KErrNone)
       
   210                         {
       
   211                         resultIds.iErrorCode = err;
       
   212                         }
       
   213                     }
       
   214                 }
       
   215 		    }
       
   216         CleanupStack::PopAndDestroy(&objStmt);
       
   217         CleanupStack::PopAndDestroy(&baseObjStmt);
       
   218 		}
       
   219 	else
       
   220 		{
       
   221 		resultIds.iObjectIds.iPtr.iOffset = KNoOffset;
       
   222 		resultIds.iObjectIds.iPtr.iCount = 0;
       
   223 		}
       
   224 
       
   225 	 // add events
       
   226     const TInt KEventCount = items.iEvents.iPtr.iCount;
       
   227     if ( KEventCount > 0 )
       
   228 		{
       
   229 		resultIds.iEventIds.iPtr.iOffset = aResultBuffer.Position();
       
   230 		resultIds.iEventIds.iPtr.iCount = KEventCount;
       
   231 	    
       
   232 	    if( KEventCount > 1 )
       
   233 	        {
       
   234 	        //More than 1 event, transaction will be used.
       
   235 	        connection.TransactionBeginL();
       
   236 	        CleanupStack::PushL(TCleanupItem(&TransactionCleanupL, &connection));
       
   237 	        }
       
   238 
       
   239 		for ( TInt i = 0; i < KEventCount; ++i )
       
   240 			{
       
   241 			aBuffer.PositionL( items.iEvents.iPtr.iOffset + 
       
   242 					i * sizeof(TMdCEvent) );
       
   243 
       
   244 			TItemId id = KNoId;
       
   245 			TRAPD( err, id = iManipulate->AddEventL( connection, aBuffer ) );
       
   246 			if (err == KErrNone)
       
   247 				{
       
   248 				aResultBuffer.InsertL( id );
       
   249 				}
       
   250 			else
       
   251 				{
       
   252 				aResultBuffer.InsertL( KNoId );
       
   253 				if(resultIds.iErrorCode == KErrNone)
       
   254 					{
       
   255 					resultIds.iErrorCode = err;
       
   256 					}
       
   257 				}
       
   258 			}
       
   259 
       
   260 		if( KEventCount > 1 )
       
   261 		    {
       
   262 		    connection.TransactionCommitL();
       
   263 		    CleanupStack::Pop();  //TransactionCleanup()
       
   264 	        }
       
   265 		}
       
   266 	else
       
   267 		{
       
   268 		resultIds.iEventIds.iPtr.iOffset = KNoOffset;
       
   269 		resultIds.iEventIds.iPtr.iCount = 0;
       
   270 		}
       
   271 
       
   272 	// add relations
       
   273     const TInt KRelationCount = items.iRelations.iPtr.iCount;
       
   274     if ( KRelationCount > 0 )
       
   275 		{
       
   276 		resultIds.iRelationIds.iPtr.iOffset = aResultBuffer.Position();
       
   277 		resultIds.iRelationIds.iPtr.iCount = KRelationCount;
       
   278 	    
       
   279 	    if( KRelationCount > 1 )
       
   280 	        {
       
   281 	        //More than 1 relation, transaction will be used.
       
   282 	        connection.TransactionBeginL();
       
   283 	        CleanupStack::PushL(TCleanupItem(&TransactionCleanupL, &connection));
       
   284 	        }
       
   285 
       
   286 	    for ( TInt i = 0; i < KRelationCount; ++i )
       
   287 			{
       
   288 			aBuffer.PositionL( items.iRelations.iPtr.iOffset + 
       
   289 					i * sizeof(TMdCRelation) );
       
   290 
       
   291 			TItemId id = KNoId;
       
   292 			TRAPD( err, id = iManipulate->AddRelationL( connection, aBuffer ) );
       
   293 			if (err == KErrNone)
       
   294 				{
       
   295 				aResultBuffer.InsertL( id );
       
   296 				}
       
   297 			else
       
   298 				{
       
   299 				aResultBuffer.InsertL( KNoId );
       
   300 				if(resultIds.iErrorCode == KErrNone)
       
   301 					{
       
   302 					resultIds.iErrorCode = err;
       
   303 					}
       
   304 				}
       
   305 			}
       
   306 
       
   307 	    if( KRelationCount > 1 )
       
   308 	        {
       
   309 	        connection.TransactionCommitL();
       
   310 	        CleanupStack::Pop();   //TransactionCleanup()
       
   311 	        }
       
   312 		}
       
   313 	else
       
   314 		{
       
   315 		resultIds.iRelationIds.iPtr.iOffset = KNoOffset;
       
   316 		resultIds.iRelationIds.iPtr.iCount = 0;
       
   317 		}
       
   318 
       
   319 	// set up result header
       
   320 	aResultBuffer.PositionL( KNoOffset );
       
   321 	resultIds.SerializeL( aResultBuffer );
       
   322 
       
   323 	iManipulate->SetNamespace( NULL );
       
   324 	iNotifier.NotifyAddedL( aBuffer, aResultBuffer );
       
   325 	}
       
   326 
       
   327 // ---------------------------------------------------------------------------
       
   328 // RemoveL
       
   329 // ---------------------------------------------------------------------------
       
   330 //
       
   331 void CMdSManipulationEngine::RemoveL( CMdCSerializationBuffer& aBuffer, 
       
   332 		CMdCSerializationBuffer& aResultBuffer )
       
   333     {
       
   334     // Read item ids from buffer.
       
   335     const TMdCItemIds& itemIds = TMdCItemIds::GetFromBufferL( aBuffer );
       
   336     
       
   337 	const CMdsNamespaceDef* namespaceDef = iSchema.GetNamespaceByIdL( 
       
   338 			itemIds.iNamespaceDefId );
       
   339 	if ( !namespaceDef )
       
   340 		{
       
   341 		User::Leave( KErrMdEUnknownNamespaceDef );
       
   342 		}
       
   343 	iManipulate->SetNamespace( namespaceDef );
       
   344 
       
   345     TMdCItemIds resultIds;
       
   346 	resultIds.iNamespaceDefId = itemIds.iNamespaceDefId;
       
   347 	resultIds.iErrorCode = KErrNone;
       
   348 	resultIds.iObjectUris.iPtr.iCount = 0;
       
   349 	resultIds.iObjectUris.iPtr.iOffset = KNoOffset;
       
   350 
       
   351 	aResultBuffer.PositionL( sizeof(TMdCItemIds) );
       
   352 
       
   353 	RArray<TItemId> idArray;
       
   354 	CleanupClosePushL( idArray );
       
   355 	RArray<TItemId> removedRelations;
       
   356 	CleanupClosePushL( removedRelations );
       
   357 	RArray<TItemId> removedEvents;
       
   358 	CleanupClosePushL( removedEvents );
       
   359 
       
   360     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   361 
       
   362     // Remove objects by id or URI.
       
   363     if (itemIds.iObjectIds.iPtr.iCount + itemIds.iObjectUris.iPtr.iCount > 0)
       
   364 		{
       
   365 	    RMdSTransaction transaction( connection );
       
   366 	    CleanupClosePushL(transaction);
       
   367 	    User::LeaveIfError( transaction.Error() );
       
   368 
       
   369 		if (itemIds.iObjectUris.iPtr.iCount > 0)
       
   370 			{
       
   371 			aBuffer.PositionL( itemIds.iObjectUris.iPtr.iOffset );
       
   372 			iManipulate->RemoveObjectsByUriL( aBuffer, itemIds.iObjectUris.iPtr.iCount,
       
   373 					idArray, removedRelations, removedEvents );
       
   374 			}
       
   375 		else
       
   376 			{
       
   377 			aBuffer.PositionL( itemIds.iObjectIds.iPtr.iOffset );
       
   378 			iManipulate->RemoveObjectsByIdL( aBuffer, itemIds.iObjectIds.iPtr.iCount,
       
   379 					idArray, removedRelations, removedEvents );
       
   380 			}
       
   381 
       
   382 	    transaction.CommitL();
       
   383 		CleanupStack::PopAndDestroy( &transaction );
       
   384 
       
   385         // write it to the buffer
       
   386         const TInt count = idArray.Count();
       
   387 		resultIds.iObjectIds.iPtr.iOffset = aResultBuffer.Position();
       
   388         resultIds.iObjectIds.iPtr.iCount = count;
       
   389         
       
   390         for ( TInt i = 0; i < count; ++i )
       
   391         	{
       
   392         	aResultBuffer.InsertL( idArray[i] );
       
   393         	if (idArray[i] == KNoId && resultIds.iErrorCode==KErrNone)
       
   394         		{
       
   395         		resultIds.iErrorCode = KErrNotFound;
       
   396         		}
       
   397         	}
       
   398         idArray.Reset();
       
   399 		}
       
   400     else
       
   401     	{
       
   402     	resultIds.iObjectIds.iPtr.iCount = 0;
       
   403     	resultIds.iObjectIds.iPtr.iOffset = KNoOffset;
       
   404     	}
       
   405 
       
   406     // Remove events by id.
       
   407 	if (itemIds.iEventIds.iPtr.iCount > 0)
       
   408 		{
       
   409 		// process events
       
   410 		aBuffer.PositionL( itemIds.iEventIds.iPtr.iOffset );
       
   411 
       
   412 	    RMdSTransaction transaction( connection );
       
   413 	    CleanupClosePushL(transaction);
       
   414 	    User::LeaveIfError( transaction.Error() );
       
   415 
       
   416 		iManipulate->RemoveEventsL( aBuffer, itemIds.iEventIds.iPtr.iCount, idArray );
       
   417 
       
   418 	    transaction.CommitL();
       
   419 		CleanupStack::PopAndDestroy( &transaction );
       
   420 
       
   421         const TInt count = idArray.Count();
       
   422         resultIds.iEventIds.iPtr.iOffset = aResultBuffer.Position();
       
   423         resultIds.iEventIds.iPtr.iCount = count;
       
   424 
       
   425         for ( TInt i = 0; i < count; ++i )
       
   426         	{
       
   427         	aResultBuffer.InsertL( idArray[i] );
       
   428         	if (idArray[i] == KNoId && resultIds.iErrorCode==KErrNone)
       
   429         		{
       
   430         		resultIds.iErrorCode = KErrNotFound;
       
   431         		}
       
   432         	}
       
   433 		idArray.Reset();
       
   434 		}
       
   435 	else
       
   436 		{
       
   437         resultIds.iEventIds.iPtr.iOffset = KNoOffset;
       
   438         resultIds.iEventIds.iPtr.iCount = 0;
       
   439 		}
       
   440 
       
   441 	// Remove relations by id.
       
   442 	if (itemIds.iRelationIds.iPtr.iCount > 0)
       
   443 		{
       
   444 		// process relations
       
   445 		aBuffer.PositionL( itemIds.iRelationIds.iPtr.iOffset );
       
   446 
       
   447 	    RMdSTransaction transaction( connection );
       
   448 	    CleanupClosePushL(transaction);
       
   449 	    User::LeaveIfError( transaction.Error() );
       
   450 
       
   451 		iManipulate->RemoveRelationsL( aBuffer, itemIds.iRelationIds.iPtr.iCount, idArray );
       
   452 
       
   453 	    transaction.CommitL();
       
   454 		CleanupStack::PopAndDestroy( &transaction );
       
   455 
       
   456         const TInt count = idArray.Count();
       
   457         resultIds.iRelationIds.iPtr.iOffset = aResultBuffer.Position();
       
   458         resultIds.iRelationIds.iPtr.iCount = count;
       
   459 
       
   460         for ( TInt i = 0; i < count; ++i )
       
   461         	{
       
   462         	aResultBuffer.InsertL( idArray[i] );
       
   463         	if (idArray[i] == KNoId && resultIds.iErrorCode==KErrNone)
       
   464         		{
       
   465         		resultIds.iErrorCode = KErrNotFound;
       
   466         		}
       
   467         	}
       
   468 		}
       
   469 	else
       
   470 		{
       
   471         resultIds.iRelationIds.iPtr.iOffset = KNoOffset;
       
   472         resultIds.iRelationIds.iPtr.iCount = 0;
       
   473 		}
       
   474 
       
   475 	aResultBuffer.PositionL( KNoOffset );
       
   476 	resultIds.SerializeL( aResultBuffer );
       
   477 
       
   478 	// notify about items removed
       
   479 	const TBool notify = iNotifier.CheckForNotifier(EObjectNotifyRemove|EEventNotifyRemove|ERelationNotifyRemove);
       
   480 	if (notify)
       
   481 		{
       
   482 		iNotifier.NotifyRemovedL( aResultBuffer, EFalse );
       
   483 		}
       
   484 
       
   485 	// notify about additional items removed
       
   486 	const TInt KRemovedItemsCount = removedRelations.Count() + removedEvents.Count();
       
   487     if ( notify && KRemovedItemsCount > 0 )
       
   488     	{
       
   489     	const TInt32 bufferSize = sizeof(TMdCItemIds)
       
   490 							+ KRemovedItemsCount * CMdCSerializationBuffer::KRequiredSizeForTItemId;
       
   491 
       
   492 		CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC( bufferSize );
       
   493 
       
   494 		buffer->PositionL( sizeof(TMdCItemIds) );
       
   495 		
       
   496 		TMdCItemIds additResultIds;
       
   497 		additResultIds.iNamespaceDefId = itemIds.iNamespaceDefId;
       
   498 		additResultIds.iErrorCode = KErrNone;
       
   499 		additResultIds.iObjectIds.iPtr.iOffset = KNoOffset;
       
   500 		additResultIds.iObjectIds.iPtr.iCount = 0;
       
   501 		additResultIds.iObjectUris.iPtr.iOffset = KNoOffset;
       
   502 		additResultIds.iObjectUris.iPtr.iCount = 0;
       
   503 
       
   504 		// Insert list of removed events to the serialization buffer.
       
   505 		const TInt KRemovedEventsCount = removedEvents.Count();
       
   506 		additResultIds.iEventIds.iPtr.iCount = KRemovedEventsCount;
       
   507 		if ( KRemovedEventsCount > 0 )
       
   508 			{
       
   509 			additResultIds.iEventIds.iPtr.iOffset = buffer->Position();
       
   510 			for ( TInt i = 0; i < KRemovedEventsCount; ++i )
       
   511 				{
       
   512 				buffer->InsertL( removedEvents[i] );
       
   513 				}
       
   514 			}
       
   515 		else
       
   516 			{
       
   517 			additResultIds.iEventIds.iPtr.iOffset = KNoOffset;
       
   518 			}
       
   519 
       
   520 		// Insert list of removed relations to the serialization buffer.
       
   521 		const TInt KRemovedRelationsCount = removedRelations.Count();
       
   522 		additResultIds.iRelationIds.iPtr.iCount = KRemovedRelationsCount;
       
   523 		if ( KRemovedRelationsCount > 0 )
       
   524 			{
       
   525 			additResultIds.iRelationIds.iPtr.iOffset = buffer->Position();
       
   526 			for ( TInt i = 0; i < KRemovedRelationsCount; ++i )
       
   527 				{
       
   528 				buffer->InsertL( removedRelations[i] );
       
   529 				}
       
   530 			}
       
   531 		else
       
   532 			{
       
   533 			additResultIds.iRelationIds.iPtr.iOffset = KNoOffset;
       
   534 			}
       
   535 
       
   536 		buffer->PositionL( KNoOffset );
       
   537 		additResultIds.SerializeL( *buffer );
       
   538 		iNotifier.NotifyRemovedL( *buffer, EFalse );
       
   539 		CleanupStack::PopAndDestroy( buffer );
       
   540     	}
       
   541 
       
   542     // notify about removed relation items
       
   543 	const TInt relationsCount = removedRelations.Count() + idArray.Count();
       
   544 	
       
   545     if ( relationsCount > 0 && iNotifier.CheckForNotifier(ERelationItemNotifyRemove) )
       
   546     	{
       
   547 		CMdCSerializationBuffer* itemsBuffer = CMdCSerializationBuffer::NewLC( 
       
   548 				sizeof( TMdCItems ) + 
       
   549 				sizeof( TMdCRelation ) * relationsCount );
       
   550 
       
   551 		iManipulate->GetRemovedRelationItemsL( *itemsBuffer, 
       
   552 				removedRelations, idArray );
       
   553 
       
   554 		iNotifier.NotifyRemovedRelationItemsL( *itemsBuffer );
       
   555 
       
   556 		CleanupStack::PopAndDestroy( itemsBuffer );
       
   557     	}
       
   558     
       
   559 	// start garbage collector
       
   560 	if( iGarbageCollector )
       
   561 		{
       
   562 		iGarbageCollector->Start( KGarbageCollectionDelay );
       
   563 		}
       
   564 
       
   565 	// removedEvents, removedRelations, idArray
       
   566     CleanupStack::PopAndDestroy( 3, &idArray );
       
   567     }
       
   568 
       
   569 void CMdSManipulationEngine::UpdateL( CMdCSerializationBuffer& aBuffer, 
       
   570 		CMdCSerializationBuffer& aResultBuffer )
       
   571 	{
       
   572 	const TMdCItems& items = TMdCItems::GetFromBufferL( aBuffer );
       
   573 
       
   574 	const CMdsNamespaceDef* namespaceDef = iSchema.GetNamespaceByIdL( 
       
   575 			items.iNamespaceDefId );
       
   576 	if ( !namespaceDef )
       
   577 		{
       
   578 		User::Leave( KErrMdEUnknownNamespaceDef );
       
   579 		}
       
   580 	iManipulate->SetNamespace( namespaceDef );
       
   581     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   582 
       
   583 	TMdCItemIds resultIds;
       
   584 	resultIds.iNamespaceDefId = items.iNamespaceDefId;
       
   585 	resultIds.iErrorCode = KErrNone;
       
   586 	resultIds.iObjectUris.iPtr.iOffset = KNoOffset;
       
   587 	resultIds.iObjectUris.iPtr.iCount = 0;
       
   588 	resultIds.iEventIds.iPtr.iOffset = KNoOffset;
       
   589 	resultIds.iEventIds.iPtr.iCount = 0;
       
   590 
       
   591 	aResultBuffer.PositionL( sizeof(TMdCItemIds) );
       
   592 
       
   593 	// update objects
       
   594 	if ( items.iObjects.iPtr.iCount > 0 )
       
   595 		{
       
   596 		resultIds.iObjectIds.iPtr.iOffset = aResultBuffer.Position();
       
   597 		resultIds.iObjectIds.iPtr.iCount = items.iObjects.iPtr.iCount;
       
   598 
       
   599 		for ( TInt i = 0; i < items.iObjects.iPtr.iCount; ++i )
       
   600 			{
       
   601 			aBuffer.PositionL( items.iObjects.iPtr.iOffset + i * sizeof(TMdCObject) );
       
   602 
       
   603 			TItemId id = KNoId;
       
   604 			TRAPD( err, id = iManipulate->UpdateObjectL( connection, aBuffer ) );
       
   605 			if (err == KErrNone)
       
   606 				{
       
   607 				aResultBuffer.InsertL( id );
       
   608 				}
       
   609 			else
       
   610 				{
       
   611 				aResultBuffer.InsertL( KNoId );
       
   612 				if ( resultIds.iErrorCode == KErrNone )
       
   613 					{
       
   614 					resultIds.iErrorCode = err;
       
   615 					}
       
   616 				}
       
   617 			}
       
   618 		}
       
   619 	else
       
   620 		{
       
   621 		resultIds.iObjectIds.iPtr.iOffset = KNoOffset;
       
   622 		resultIds.iObjectIds.iPtr.iCount = 0;
       
   623 		}
       
   624 
       
   625 	// update relations
       
   626 	if ( items.iRelations.iPtr.iCount > 0 )
       
   627 		{
       
   628 		resultIds.iRelationIds.iPtr.iOffset = aResultBuffer.Position();
       
   629 		resultIds.iRelationIds.iPtr.iCount = items.iRelations.iPtr.iCount;
       
   630 
       
   631 		for ( TInt i = 0; i < items.iRelations.iPtr.iCount; ++i )
       
   632 			{
       
   633 			aBuffer.PositionL( items.iRelations.iPtr.iOffset + i * sizeof(TMdCRelation) );
       
   634 
       
   635 			TItemId id = KNoId;
       
   636 			TRAPD( err, id = iManipulate->UpdateRelationsL( connection, aBuffer ) );
       
   637 			if (err == KErrNone)
       
   638 				{
       
   639 				aResultBuffer.InsertL( id );
       
   640 				}
       
   641 			else
       
   642 				{
       
   643 				aResultBuffer.InsertL( KNoId );
       
   644 				if ( resultIds.iErrorCode == KErrNone )
       
   645 					{
       
   646 					resultIds.iErrorCode = err;
       
   647 					}
       
   648 				}
       
   649 			}
       
   650 		}
       
   651 	else
       
   652 		{
       
   653 		resultIds.iRelationIds.iPtr.iOffset = KNoOffset;
       
   654 		resultIds.iRelationIds.iPtr.iCount = 0;
       
   655 		}
       
   656 
       
   657 	if ( items.iEvents.iPtr.iCount > 0 )
       
   658 		{
       
   659 		// events cannot be updated
       
   660 		// so just ignore it, but if possible return error code
       
   661 		if ( resultIds.iErrorCode == KErrNone )
       
   662 			{
       
   663 			resultIds.iErrorCode = KErrArgument;
       
   664 			}
       
   665 		}
       
   666 
       
   667 	iManipulate->SetNamespace( NULL );
       
   668 
       
   669 	// set up result header
       
   670 	aResultBuffer.PositionL( KNoOffset );
       
   671 	resultIds.SerializeL( aResultBuffer );
       
   672 
       
   673 	iNotifier.NotifyModifiedL( aBuffer, aResultBuffer );
       
   674     }
       
   675 
       
   676 CMdCSerializationBuffer* CMdSManipulationEngine::CheckObjectL( 
       
   677 		TInt aResultBufferSize, const TDesC& aUri, TDefId aNamespaceDefId )
       
   678 	{
       
   679     return iManipulate->CheckObjectL( 
       
   680     		aResultBufferSize, aUri, aNamespaceDefId );
       
   681 	}
       
   682 
       
   683 CMdCSerializationBuffer* CMdSManipulationEngine::CheckObjectL( 
       
   684 		TInt aResultBufferSize, TItemId aId, TDefId aNamespaceDefId )
       
   685 	{
       
   686     return iManipulate->CheckObjectL( 
       
   687     		aResultBufferSize, aId, aNamespaceDefId );
       
   688 	}
       
   689 
       
   690 CMdCSerializationBuffer* CMdSManipulationEngine::CheckObjectL( 
       
   691 		TInt aResultBufferSize, CMdCSerializationBuffer& aIds, 
       
   692 		TDefId aNamespaceDefId )
       
   693 	{
       
   694 	return iManipulate->CheckObjectL( 
       
   695 			aResultBufferSize, aIds, aNamespaceDefId );
       
   696 	}
       
   697 
       
   698 // ---------------------------------------------------------------------------
       
   699 // AddMemoryCardL
       
   700 // ---------------------------------------------------------------------------
       
   701 //
       
   702 void CMdSManipulationEngine::AddMemoryCardL(TUint32 aMediaId)
       
   703 	{
       
   704 	iManipulate->AddMemoryCardL( aMediaId );
       
   705 	}
       
   706 
       
   707 // ---------------------------------------------------------------------------
       
   708 // GetMemoryCardL
       
   709 // ---------------------------------------------------------------------------
       
   710 //
       
   711 void CMdSManipulationEngine::GetMemoryCardL(TUint32& aMediaId)
       
   712 	{
       
   713 	iManipulate->GetMemoryCardL( aMediaId );
       
   714 	}
       
   715 
       
   716 // ---------------------------------------------------------------------------
       
   717 // CheckMemoryCardL
       
   718 // ---------------------------------------------------------------------------
       
   719 //
       
   720 TBool CMdSManipulationEngine::CheckMemoryCardL(TUint32 aMediaId)
       
   721 	{
       
   722 	return iManipulate->CheckMemoryCardL( aMediaId );
       
   723 	}
       
   724 
       
   725 // ---------------------------------------------------------------------------
       
   726 // SetMediaL
       
   727 // ---------------------------------------------------------------------------
       
   728 //
       
   729 void CMdSManipulationEngine::SetMediaL(TUint32 aMediaId, TChar aDrive, 
       
   730 		TBool aPresentState)
       
   731 	{
       
   732 	return iManipulate->SetMediaL( aMediaId, aDrive, aPresentState );
       
   733 	}
       
   734 	
       
   735 // ---------------------------------------------------------------------------
       
   736 // GetMediaL
       
   737 // ---------------------------------------------------------------------------
       
   738 //
       
   739 TBool CMdSManipulationEngine::GetMediaL(TUint32 aMediaId, TChar& aDrive, 
       
   740 		TBool& aPresentState)
       
   741 	{
       
   742 	return iManipulate->GetMediaL( aMediaId, aDrive, aPresentState );
       
   743 	}
       
   744 
       
   745 // ---------------------------------------------------------------------------
       
   746 // GetPresentMediasL
       
   747 // ---------------------------------------------------------------------------
       
   748 //
       
   749 TInt32 CMdSManipulationEngine::GetPresentMediasL(TDes8& aMediaInfoBuffer)
       
   750 	{
       
   751 	return iManipulate->GetPresentMediasL( aMediaInfoBuffer );
       
   752 	}
       
   753 
       
   754 // ---------------------------------------------------------------------------
       
   755 // SetFilesToPresentL
       
   756 // ---------------------------------------------------------------------------
       
   757 //
       
   758 void CMdSManipulationEngine::SetFilesToPresentL(TUint32 aMediaId, TUint32 aFileCount, 
       
   759 		CMdCSerializationBuffer& aUris, CMdCSerializationBuffer& aFileInfos,
       
   760 		CMdCSerializationBuffer& aResults)
       
   761 	{
       
   762 
       
   763     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   764     RMdSTransaction transaction( connection );
       
   765 	CleanupClosePushL( transaction );
       
   766 	User::LeaveIfError( transaction.Error() );
       
   767 
       
   768     RArray<TItemId> itemIds;
       
   769 	CleanupClosePushL( itemIds );
       
   770     itemIds.ReserveL( aFileCount );
       
   771 
       
   772     RArray<TItemId> notifyItemIds;
       
   773 	CleanupClosePushL( notifyItemIds );
       
   774 	notifyItemIds.ReserveL( aFileCount );
       
   775 
       
   776     for( TUint32 i = 0; i < aFileCount; i++ )
       
   777     	{
       
   778     	TPtrC16 uri = aUris.ReceivePtr16L();
       
   779     	TPtr16 uriLC( CONST_CAST( TUint16*, uri.Ptr() ), uri.Length(), uri.Length() );
       
   780     	uriLC.LowerCase();
       
   781 
       
   782     	TMdSFileInfo fileInfo;
       
   783     	aFileInfos.ReceiveL(fileInfo.iModifiedTime);
       
   784     	aFileInfos.ReceiveL(fileInfo.iSize);
       
   785 
       
   786 #ifdef _DEBUG    	
       
   787     	const TInt64 time = fileInfo.iModifiedTime;
       
   788         RDebug::Print( _L("CMdSManipulationEngine::SetFilesToPresentL: (%d) iSize %u, iModified %Ld, uri %S"),
       
   789         		i,
       
   790         		fileInfo.iSize,
       
   791         		time,
       
   792         		&uri);
       
   793 #endif
       
   794 
       
   795     	TFilePresentStates placeHolder;
       
   796     	TBool notPresentState( EFalse );
       
   797     	const TItemId objectId = iManipulate->SearchNotPresentFileL( /*reservation(), */
       
   798     			aMediaId, uri, fileInfo, placeHolder, notPresentState );
       
   799     	if ( placeHolder != EMdsNotFound )
       
   800     		{
       
   801     		itemIds.Append( objectId );
       
   802 
       
   803     		if( notPresentState )
       
   804     			{
       
   805     			notifyItemIds.Append( objectId );
       
   806     			}
       
   807     		}
       
   808 
       
   809     	aResults.InsertL( (TUint8)placeHolder );
       
   810     	}
       
   811 
       
   812 	iManipulate->SetFilesToPresentL( itemIds );
       
   813 
       
   814 	// only notify about objects in not present state and
       
   815 	// modify and notify relations related to those
       
   816 	if( notifyItemIds.Count() > 0 )
       
   817 		{
       
   818 		iNotifier.NotifyObjectPresent( ETrue, notifyItemIds );
       
   819 
       
   820 		RArray<TItemId> relationIds;
       
   821 		CleanupClosePushL( relationIds );
       
   822 
       
   823 	    const TInt itemIdCount = notifyItemIds.Count();
       
   824 		for( TUint32 i = 0; i < itemIdCount; i++ )
       
   825 			{
       
   826 			iManipulate->SetRelationsToPresentL( notifyItemIds[i], relationIds );
       
   827 			}
       
   828 
       
   829 		iNotifier.NotifyRelationPresent( ETrue, relationIds );
       
   830 
       
   831 		CleanupStack::PopAndDestroy( &relationIds );
       
   832 		}
       
   833 
       
   834 	transaction.CommitL();
       
   835 
       
   836 	CleanupStack::PopAndDestroy( &notifyItemIds );
       
   837 	CleanupStack::PopAndDestroy( &itemIds );
       
   838 
       
   839 	CleanupStack::PopAndDestroy( &transaction );
       
   840 	}
       
   841 
       
   842 // ---------------------------------------------------------------------------
       
   843 // SetFilesToNotPresentL
       
   844 // ---------------------------------------------------------------------------
       
   845 //
       
   846 void CMdSManipulationEngine::SetFilesToNotPresentL(TUint32 aMediaId, TBool aStartUp)
       
   847 	{
       
   848     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   849     RMdSTransaction transaction( connection );
       
   850 	CleanupClosePushL( transaction );
       
   851 	User::LeaveIfError( transaction.Error() );
       
   852 	
       
   853 	RArray<TItemId> objectIds;
       
   854 	CleanupClosePushL( objectIds );
       
   855 
       
   856 	iManipulate->SetFilesToNotPresentL( aMediaId, aStartUp, objectIds );
       
   857 	
       
   858 	// if start up no need for object notifications, 
       
   859 	// setting relations to not present and relation notifications
       
   860 	if( !aStartUp )
       
   861 		{
       
   862 		iNotifier.NotifyObjectPresent( EFalse, objectIds );
       
   863 		
       
   864 		RArray<TItemId> relationIds;
       
   865 		CleanupClosePushL( relationIds );
       
   866 	
       
   867         iManipulate->SetRelationsToNotPresentL( aMediaId, relationIds );
       
   868 		iNotifier.NotifyRelationPresent( EFalse, relationIds );
       
   869 		
       
   870 		CleanupStack::PopAndDestroy( &relationIds );
       
   871 		}
       
   872     
       
   873     transaction.CommitL();
       
   874 
       
   875     CleanupStack::PopAndDestroy( &objectIds );
       
   876     CleanupStack::PopAndDestroy( &transaction );
       
   877 	}
       
   878 
       
   879 // ---------------------------------------------------------------------------
       
   880 // RemoveFilesNotPresentL
       
   881 // ---------------------------------------------------------------------------
       
   882 //
       
   883 void CMdSManipulationEngine::RemoveFilesNotPresentL(TUint32 aMediaId, TBool aStartUp)
       
   884 	{
       
   885     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   886     RMdSTransaction transaction( connection );
       
   887 	CleanupClosePushL( transaction );
       
   888 	User::LeaveIfError( transaction.Error() );
       
   889 	
       
   890 	if( aStartUp )
       
   891 		{
       
   892 		RArray<TItemId> objectIds;
       
   893 		CleanupClosePushL( objectIds );
       
   894 
       
   895 		iManipulate->RemoveFilesNotPresentL( aMediaId, &objectIds );
       
   896 		
       
   897 		if( objectIds.Count() > 0 )
       
   898 			{
       
   899 			iNotifier.NotifyRemovedL( objectIds );
       
   900 			}
       
   901 		
       
   902 		CleanupStack::PopAndDestroy( &objectIds );
       
   903 		}
       
   904 	else
       
   905 		{
       
   906 		iManipulate->RemoveFilesNotPresentL( aMediaId, NULL );
       
   907 		}
       
   908 
       
   909     transaction.CommitL();
       
   910     CleanupStack::PopAndDestroy( &transaction );
       
   911 
       
   912 	// start garbage collector
       
   913 	if( iGarbageCollector )
       
   914 		{
       
   915 		iGarbageCollector->Start( KGarbageCollectionDelay );
       
   916 		}
       
   917 	}
       
   918 
       
   919 // ---------------------------------------------------------------------------
       
   920 // StartGarbageCollection
       
   921 // ---------------------------------------------------------------------------
       
   922 //
       
   923 TBool CMdSManipulationEngine::StartGarbageCollectionL()
       
   924 	{
       
   925 #ifdef _DEBUG
       
   926 	RDebug::Print( _L("CMdSManipulationEngine::StartGarbageCollection()") );
       
   927 #endif
       
   928 
       
   929     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   930     RMdSTransaction transaction( connection );
       
   931 	CleanupClosePushL( transaction );
       
   932 	User::LeaveIfError( transaction.Error() );
       
   933 	
       
   934     TBool again = EFalse;
       
   935 #ifdef _DEBUG
       
   936     TRAPD( err, again = iManipulate->GarbageCollectionL() );
       
   937 #else
       
   938     TRAP_IGNORE( again = iManipulate->GarbageCollectionL() );
       
   939 #endif
       
   940 
       
   941     transaction.CommitL();
       
   942     CleanupStack::PopAndDestroy( &transaction ); 
       
   943     
       
   944 	#ifdef _DEBUG
       
   945 	if( err != KErrNone )
       
   946 		{
       
   947 		_LIT( KErrLog, "CMdSManipulationEngine::StartGarbageCollection error: %d" );
       
   948 		RDebug::Print( KErrLog, err );		
       
   949 		}
       
   950 	#endif
       
   951 	
       
   952 	return again;
       
   953 	}
       
   954 
       
   955 // ---------------------------------------------------------------------------
       
   956 // GetSchemaVersionL
       
   957 // ---------------------------------------------------------------------------
       
   958 //
       
   959 void CMdSManipulationEngine::GetSchemaVersionL(
       
   960 		TInt& aMajorVersion, TInt& aMinorVersion)
       
   961 	{
       
   962 	iManipulate->GetSchemaVersionL( aMajorVersion, aMinorVersion );
       
   963 	}
       
   964 
       
   965 void CMdSManipulationEngine::SetObjectToPresentByGuidL( 
       
   966 		const TInt64& aGuidHigh, const TInt64& aGuidLow )
       
   967 	{
       
   968 	iManipulate->SetObjectToPresentByGuidL( aGuidHigh, aGuidLow );
       
   969 	}
       
   970 
       
   971 void CMdSManipulationEngine::ChangePathL(const TDesC& aOldPath, const TDesC& aNewPath)
       
   972 	{
       
   973 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   974     RMdSTransaction transaction( connection );
       
   975 	CleanupClosePushL( transaction );
       
   976 	User::LeaveIfError( transaction.Error() );
       
   977 	
       
   978 	RArray<TItemId> objectIds;
       
   979 	CleanupClosePushL( objectIds );
       
   980 
       
   981 	iManipulate->ChangePathL( aOldPath, aNewPath, objectIds );
       
   982 
       
   983 	iNotifier.NotifyModifiedL( objectIds );
       
   984 	
       
   985 	CleanupStack::PopAndDestroy( &objectIds );
       
   986 	
       
   987 	transaction.CommitL();
       
   988     CleanupStack::PopAndDestroy( &transaction );
       
   989 	}
       
   990 
       
   991 void CMdSManipulationEngine::ChangeMediaIdL()
       
   992 	{
       
   993 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   994     RMdSTransaction transaction( connection );
       
   995 	CleanupClosePushL( transaction );
       
   996 	User::LeaveIfError( transaction.Error() );
       
   997 	
       
   998 	iManipulate->ChangeMediaIdL();
       
   999 	
       
  1000 	transaction.CommitL();
       
  1001 
       
  1002 	CleanupStack::PopAndDestroy( &transaction );
       
  1003 	}
       
  1004 
       
  1005 void CMdSManipulationEngine::AddRelationDefL( TDefId aNamespaceId, const TDesC& aRelationDefName )
       
  1006 	{
       
  1007 	CMdsNamespaceDef* namespaceDef = CONST_CAST( CMdsNamespaceDef*, iSchema.GetNamespaceByIdL( aNamespaceId ) );
       
  1008 	if ( !namespaceDef )
       
  1009 		{
       
  1010 		User::Leave( KErrMdEUnknownNamespaceDef );
       
  1011 		}
       
  1012 	if ( namespaceDef->GetReadOnly() )
       
  1013 		{
       
  1014 		User::Leave( KErrLocked );
       
  1015 		}
       
  1016 
       
  1017 	namespaceDef->AddRelationDefL( aRelationDefName );
       
  1018 	iSchema.StoreToDBL();
       
  1019 	}
       
  1020 
       
  1021 void CMdSManipulationEngine::AddEventDefL( TDefId aNamespaceId, const TDesC& aEventDefName )
       
  1022 	{
       
  1023 	CMdsNamespaceDef* namespaceDef = CONST_CAST( CMdsNamespaceDef*, iSchema.GetNamespaceByIdL( aNamespaceId ) );
       
  1024 	if ( !namespaceDef )
       
  1025 		{
       
  1026 		User::Leave( KErrMdEUnknownNamespaceDef );
       
  1027 		}
       
  1028 	if ( namespaceDef->GetReadOnly() )
       
  1029 		{
       
  1030 		User::Leave( KErrLocked );
       
  1031 		}
       
  1032 
       
  1033 	namespaceDef->AddEventDefL( aEventDefName, 1 );
       
  1034 	iSchema.StoreToDBL();
       
  1035 	}
       
  1036 
       
  1037 void CMdSManipulationEngine::SetPendingL(const RArray<TItemId>& aObjectIds)
       
  1038 	{
       
  1039 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  1040 	RMdSTransaction transaction( connection );
       
  1041 	CleanupClosePushL( transaction );
       
  1042 	User::LeaveIfError( transaction.Error() );
       
  1043 
       
  1044 	iManipulate->SetPendingL( aObjectIds, EFalse );
       
  1045 
       
  1046 	transaction.CommitL();
       
  1047     CleanupStack::PopAndDestroy( &transaction );
       
  1048 	}
       
  1049 
       
  1050 void CMdSManipulationEngine::ResetPendingL(const RArray<TItemId>& aObjectIds)
       
  1051 	{
       
  1052 	iManipulate->SetPendingL( aObjectIds, ETrue );
       
  1053 	}
       
  1054 
       
  1055 TInt CMdSManipulationEngine::GetPendingCountL( TDefId aObjectDefId )
       
  1056 	{
       
  1057 	return iManipulate->GetPendingCountL( aObjectDefId );
       
  1058 	}
       
  1059 
       
  1060 TInt CMdSManipulationEngine::GetPendingL( TDefId aObjectDefId, 
       
  1061 		TInt aBufferSize, RArray<TItemId>& aObjectIds )
       
  1062 	{
       
  1063 	return iManipulate->GetPendingL( aObjectDefId, aBufferSize, aObjectIds );
       
  1064 	}