metadataengine/server/src/mdssqlobjectmanipulate.cpp
changeset 0 c53acadfccc6
child 3 b73a2e62868f
equal deleted inserted replaced
-1:000000000000 0:c53acadfccc6
       
     1 /*
       
     2 * Copyright (c) 2002-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:  Add, update and remove items in DB.
       
    15 *                 Basic DB manipulation engine.
       
    16 *
       
    17 */
       
    18 
       
    19 #include "mdssqlobjectmanipulate.h"
       
    20 
       
    21 #include "mdcitem.h"
       
    22 #include "mdsdbconnectionpool.h"
       
    23 #include "mdssqliteconnection.h"
       
    24 #include "mdsfindsqlclausedef.h"
       
    25 #include "mdsschema.h"
       
    26 #include "mdsnamespacedef.h"
       
    27 #include "mdsobjectdef.h"
       
    28 #include "mdspropertydef.h"
       
    29 #include "mdsclausebuffer.h"
       
    30 #include "mdsobjectlocklist.h"
       
    31 #include "mdsindexer.h"
       
    32 #include "mdspreferences.h"
       
    33 #include "mdslogger.h"
       
    34 #include "mdcserializationbuffer.h"
       
    35 #include "mdssqldbmaintenance.h"
       
    36 #include "mdcresult.h"
       
    37 #include "mdeinternalerror.h"
       
    38 
       
    39 #include "mdsgetimeiao.h"
       
    40 
       
    41 #include <e32math.h>
       
    42 
       
    43 /** logging instance */
       
    44 __USES_LOGGER
       
    45 
       
    46 const TInt KMaxBuffers = 3;
       
    47 
       
    48 _LIT( KMemoryCard, "MC" );
       
    49 
       
    50 
       
    51 //------------------------------------------------------------------------------------
       
    52 // CLASS      CMdSSqlObjectManipulate
       
    53 //------------------------------------------------------------------------------------
       
    54 
       
    55 CMdSIdentifierGenerator* CMdSIdentifierGenerator::NewL( )
       
    56     {
       
    57     CMdSIdentifierGenerator* self = CMdSIdentifierGenerator::NewLC( );
       
    58     CleanupStack::Pop( self );
       
    59     return self;
       
    60     }
       
    61 
       
    62 CMdSIdentifierGenerator* CMdSIdentifierGenerator::NewLC( )
       
    63     {
       
    64     CMdSIdentifierGenerator* self = new ( ELeave ) CMdSIdentifierGenerator( );
       
    65     CleanupStack::PushL( self );
       
    66     self->ConstructL( );
       
    67     return self;
       
    68     }
       
    69 
       
    70 CMdSIdentifierGenerator::~CMdSIdentifierGenerator()
       
    71     {
       
    72     delete iDigest;
       
    73     }
       
    74 
       
    75 void CMdSIdentifierGenerator::ConstructL( )
       
    76     {
       
    77     CMdsGetImeiAO * imeigetter = CMdsGetImeiAO::NewLC();
       
    78     iImei = imeigetter->GetIMEI();
       
    79     
       
    80     TTime uTime;
       
    81     uTime.UniversalTime();
       
    82     TInt64 intTime = uTime.Int64();
       
    83     TUint32 rand = Math::Rand( intTime );
       
    84 
       
    85     iImei ^= (TInt64)(rand & 0xFF000000) << ( sizeof( TUint32 ) * 8 );
       
    86     
       
    87     CleanupStack::PopAndDestroy(imeigetter);
       
    88     iLastTime = 0;
       
    89     
       
    90     iDigest = CMessageDigestFactory::NewDigestL( CMessageDigest::EMD5 );
       
    91     }
       
    92 
       
    93 void CMdSIdentifierGenerator::GenerateGuid( TInt64& aGuidHigh, TInt64& aGuidLow )
       
    94 	{
       
    95 	if (aGuidHigh == 0 && aGuidLow == 0)
       
    96 		{
       
    97 		TTime currTime;
       
    98 		currTime.UniversalTime();
       
    99 		const TInt64 tickCount = currTime.Int64();
       
   100 		if (iLastTime < tickCount)
       
   101 			{
       
   102 			iLastTime = tickCount;
       
   103 			}
       
   104 		else
       
   105 			{
       
   106 			++iLastTime;
       
   107 			}
       
   108 
       
   109 		//MD5 hash GUID
       
   110 		const TInt64 KXorImei = I64LIT( 0x2C3E773D1A25916E );
       
   111 		const TInt64 xorImei = iImei ^ KXorImei;
       
   112 
       
   113 		const TInt KMaxQuidLength = 16;
       
   114 		TBuf8<KMaxQuidLength> message;
       
   115 		message.SetLength( KMaxQuidLength );
       
   116 		Mem::Copy( (TAny*)( message.Ptr() ), &xorImei, sizeof( TInt64 ) );
       
   117 		Mem::Copy( (TAny*)( message.Ptr() + sizeof( TInt64 ) ), &iLastTime, sizeof( TInt64 ) );
       
   118 
       
   119 		TPtrC8 hash = iDigest->Final( message );
       
   120 
       
   121 		__ASSERT_DEBUG( hash.Size() >= KMaxQuidLength, User::Panic( _L("CMdSIdentifierGenerator::GenerateGuid"), KErrGeneral ) );
       
   122 
       
   123 		Mem::Copy( &aGuidHigh, hash.Ptr(), sizeof( TInt64 ) );
       
   124 		Mem::Copy( &aGuidLow, hash.Ptr() + sizeof( TInt64 ), sizeof( TInt64 ) );
       
   125 		//MD5 hash GUID end
       
   126 		}
       
   127 	}
       
   128 
       
   129 HBufC* CMdSIdentifierGenerator::GenerateUriL( const CMdsObjectDef& aObjectDef, 
       
   130 		const TInt64& aGuidHigh, const TInt64& aGuidLow ) const
       
   131 	{
       
   132 	_LIT( KDot, "." );
       
   133 	HBufC* uri = HBufC::NewLC( aObjectDef.GetName().Length() + 2 /*two dots*/+ 
       
   134 			2*KMaxUint64ValueLength );
       
   135 
       
   136 	TPtr uriPtr( uri->Des() );
       
   137 	uriPtr.Append( aObjectDef.GetName() );
       
   138 	uriPtr.Append( KDot );
       
   139 	uriPtr.AppendNum( aGuidHigh );
       
   140 	uriPtr.Append( KDot );
       
   141 	uriPtr.AppendNum( aGuidLow );
       
   142 	CleanupStack::Pop( uri );
       
   143 	return uri;
       
   144 	}
       
   145 
       
   146 
       
   147 //-----------------------------------------------------------------------------
       
   148 // CLASS      CMdSSqlObjectManipulate
       
   149 //-----------------------------------------------------------------------------
       
   150 
       
   151 CMdSSqlObjectManipulate* CMdSSqlObjectManipulate::NewL( 
       
   152 		const CMdsSchema& aSchema, CMdSObjectLockList& aLockList )
       
   153     {
       
   154     CMdSSqlObjectManipulate* self = CMdSSqlObjectManipulate::NewLC( aSchema, 
       
   155     		aLockList );
       
   156     CleanupStack::Pop( self );
       
   157     return self;
       
   158     }
       
   159 
       
   160 CMdSSqlObjectManipulate* CMdSSqlObjectManipulate::NewLC( 
       
   161 		const CMdsSchema& aSchema, CMdSObjectLockList& aLockList )
       
   162     {
       
   163     CMdSSqlObjectManipulate* self = new ( ELeave ) CMdSSqlObjectManipulate( 
       
   164     		aSchema, aLockList );
       
   165     CleanupStack::PushL( self );
       
   166     self->ConstructL( );
       
   167     return self;
       
   168     }
       
   169 
       
   170 CMdSSqlObjectManipulate::~CMdSSqlObjectManipulate()
       
   171     {
       
   172     // doesn't own namespace definition
       
   173 	iNamespaceDef = NULL;
       
   174 
       
   175 	const TInt count = iBuffers.Count();
       
   176 	
       
   177 	for (TInt i = 0; i < count; ++i)
       
   178 		{
       
   179 		delete iBuffers[i].iBuffer;
       
   180 		}
       
   181 	iBuffers.Close();
       
   182 
       
   183 	delete iGenerator;
       
   184     }
       
   185 
       
   186 CMdSSqlObjectManipulate::CMdSSqlObjectManipulate( const CMdsSchema& aSchema, 
       
   187 		CMdSObjectLockList& aLockList )
       
   188 	: iSchema( aSchema ), iGenerator(NULL), iLockList( aLockList ) 
       
   189     {
       
   190     }
       
   191 
       
   192 void CMdSSqlObjectManipulate::ConstructL( )
       
   193     {
       
   194     
       
   195 	iGenerator = CMdSIdentifierGenerator::NewL();
       
   196 
       
   197 	iNamespaceDef = NULL;
       
   198 	
       
   199 	TLockBuffer lockBuffer;
       
   200 	lockBuffer.iLock = EFalse;
       
   201 	for (TInt i = 0; i < KMaxBuffers; ++i)
       
   202 		{
       
   203 	    CMdsClauseBuffer* buffer = CMdsClauseBuffer::NewLC( 1024 );
       
   204 		lockBuffer.iBuffer = buffer;
       
   205 		iBuffers.AppendL( lockBuffer );
       
   206 		CleanupStack::Pop(); // buffer
       
   207 		}
       
   208 
       
   209     }
       
   210 
       
   211 TBool CMdSSqlObjectManipulate::GarbageCollectionL()
       
   212 	{
       
   213 	return DoGarbageCollectionL();
       
   214 	}
       
   215 
       
   216 void CMdSSqlObjectManipulate::SetNamespace( 
       
   217 		const CMdsNamespaceDef* aNamespaceDef )
       
   218 	{
       
   219 	iNamespaceDef = aNamespaceDef;
       
   220 	}
       
   221 
       
   222 void CMdSSqlObjectManipulate::AddMemoryCardL(TUint32 aMediaId)
       
   223 	{
       
   224 	TTime currentTime;
       
   225 	currentTime.UniversalTime();
       
   226 
       
   227 	TInt modifiedRowCount = MMdsPreferences::UpdateL( KMemoryCard, 
       
   228 			MMdsPreferences::EPreferenceExtraSet, aMediaId, 
       
   229 			currentTime.Int64() );
       
   230 
       
   231 	if( modifiedRowCount <= 0 )
       
   232 		{
       
   233 		MMdsPreferences::InsertL( KMemoryCard, 
       
   234 								  MMdsPreferences::EPreferenceBothSet, 
       
   235 								  aMediaId, currentTime.Int64() );
       
   236 		}
       
   237 	}
       
   238 
       
   239 void CMdSSqlObjectManipulate::GetMemoryCardL(TUint32& aMediaId)
       
   240 	{
       
   241 	TInt rowCount = MMdsPreferences::GetL( KMemoryCard, 
       
   242 										   MMdsPreferences::EPreferenceValueGet | MMdsPreferences::EPreferenceExtraSortDesc, 
       
   243 								  		   aMediaId );
       
   244 
       
   245 	// if no rows found leave
       
   246 	if( rowCount <= 0 )
       
   247 		{
       
   248 		User::Leave( KErrNotFound );
       
   249 		}
       
   250 	}
       
   251 
       
   252 TBool CMdSSqlObjectManipulate::CheckMemoryCardL(TUint32 aMediaId)
       
   253 	{
       
   254 	TInt rowCount = MMdsPreferences::GetL( KMemoryCard, 
       
   255 										   MMdsPreferences::EPreferenceValueGet | MMdsPreferences::EPreferenceValueSet, 
       
   256 								  		   aMediaId );
       
   257 
       
   258 	if( rowCount > 0 )
       
   259 		{
       
   260 		return ETrue;
       
   261 		}
       
   262 	return EFalse;
       
   263 	}
       
   264 
       
   265 
       
   266 void CMdSSqlObjectManipulate::SetMediaL(TUint32 aMediaId, TChar aDrive,
       
   267 		TBool aPresentState)
       
   268 	{
       
   269 	_LIT( KInsertMedia, "INSERT OR REPLACE INTO MdS_Medias VALUES(?,?,?,?);" );
       
   270 
       
   271 	RClauseBuffer commonClause( *this, KInsertMedia.iTypeLength );
       
   272 	CleanupClosePushL( commonClause );
       
   273 	CMdsClauseBuffer& clauseBuffer = commonClause.BufferL();
       
   274 	clauseBuffer.BufferL() = KInsertMedia;
       
   275 
       
   276 	TTime currentTime;
       
   277 	currentTime.UniversalTime();
       
   278 	const TInt64 currentTime64 = currentTime.Int64();
       
   279 	
       
   280     RRowData var;
       
   281     CleanupClosePushL( var );
       
   282     var.ReserveL( 4 ); // reserve space for media ID, drive, present state and time
       
   283     var.AppendL( TColumn( aMediaId ) );
       
   284     var.AppendL( TColumn( (TInt32)aDrive ) );
       
   285     var.AppendL( TColumn( aPresentState ) );
       
   286     var.AppendL( TColumn( currentTime64 ) );
       
   287 
       
   288     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   289 
       
   290 	connection.ExecuteL( clauseBuffer.ConstBufferL(), var );
       
   291 
       
   292 	CleanupStack::PopAndDestroy( 2, &commonClause ); // var, commonClauseOne
       
   293 	}
       
   294 
       
   295 TBool CMdSSqlObjectManipulate::GetMediaL(TUint32 aMediaId, TChar& aDrive, 
       
   296 		TBool& aPresentState)
       
   297 	{
       
   298 	_LIT( KGetMedia, "SELECT Drive, PresentState FROM MdS_Medias WHERE MediaId=?;" );
       
   299 
       
   300 	RClauseBuffer commonClause( *this, KGetMedia.iTypeLength );
       
   301 	CleanupClosePushL( commonClause );
       
   302 	CMdsClauseBuffer& clauseBuffer = commonClause.BufferL();
       
   303 	clauseBuffer.BufferL() = KGetMedia;
       
   304 
       
   305     RRowData var;
       
   306     CleanupClosePushL( var );
       
   307     var.AppendL( TColumn( aMediaId ) );
       
   308 
       
   309     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   310 	RMdsStatement statement;
       
   311 	CleanupClosePushL( statement );
       
   312 	connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
       
   313 
       
   314 	var.Free();
       
   315 	var.Reset();
       
   316 
       
   317 	TInt32 drive = 0;
       
   318 	
       
   319     var.ReserveL( 2 ); // reserve space for drive and present state
       
   320 	var.AppendL( TColumn( drive ) );
       
   321 	var.AppendL( TColumn( aPresentState ) );
       
   322 
       
   323 	TBool found = EFalse;
       
   324 
       
   325 	if( connection.NextRowL( statement, var ) )
       
   326 		{
       
   327 		var.Column( 0 ).Get( drive );
       
   328 		var.Column( 1 ).Get( aPresentState );
       
   329 		
       
   330 		aDrive = drive;
       
   331 		
       
   332 		found = ETrue;
       
   333 		}
       
   334 
       
   335 	CleanupStack::PopAndDestroy( 3, &commonClause ); // statement, var, commonClauseOne
       
   336 
       
   337 	return found;
       
   338 	}
       
   339 
       
   340 TInt32 CMdSSqlObjectManipulate::GetPresentMediasL(TDes8& aMediaInfoBuffer)
       
   341 	{
       
   342 	_LIT( KGetPresentMedias, "SELECT MediaId, Drive FROM MdS_Medias WHERE PresentState!=?;" );
       
   343 
       
   344 	RClauseBuffer commonClause( *this, KGetPresentMedias.iTypeLength );
       
   345 	CleanupClosePushL( commonClause );
       
   346 	CMdsClauseBuffer& clauseBuffer = commonClause.BufferL();
       
   347 	clauseBuffer.BufferL() = KGetPresentMedias;
       
   348 
       
   349 	const TBool notPresentState = EFalse;
       
   350 
       
   351     RRowData var;
       
   352     CleanupClosePushL( var );
       
   353     var.AppendL( TColumn( notPresentState ) );
       
   354 
       
   355     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   356 	RMdsStatement statement;
       
   357 	CleanupClosePushL( statement );
       
   358 	connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
       
   359 
       
   360 	var.Free();
       
   361 	var.Reset();
       
   362 
       
   363 	TUint32 mediaId = 0;
       
   364 	TInt32 drive = 0;
       
   365 
       
   366     var.ReserveL( 2 ); // reserve space for drive and present state
       
   367 	var.AppendL( TColumn( mediaId ) );
       
   368 	var.AppendL( TColumn( drive ) );
       
   369 
       
   370 	TInt32 count = 0;
       
   371 
       
   372 	TInt bufferPosition = 0;
       
   373 	
       
   374 	const TInt lastBufferPosition = aMediaInfoBuffer.MaxSize() - sizeof( TMdEMediaInfo );
       
   375 
       
   376 	const TUint8* aMediaInfoBufferPtr = aMediaInfoBuffer.Ptr();
       
   377 	
       
   378 	while( connection.NextRowL( statement, var ) )
       
   379 		{
       
   380 		var.Column( 0 ).Get( mediaId );
       
   381 		var.Column( 1 ).Get( drive );
       
   382 		
       
   383 		TMdEMediaInfo mediaInfo;
       
   384 		mediaInfo.iMediaId = mediaId;
       
   385 		mediaInfo.iDrive = drive;
       
   386 
       
   387 		if( bufferPosition > lastBufferPosition )
       
   388 			{
       
   389 			User::Leave( KErrBadDescriptor );
       
   390 			}
       
   391 	
       
   392 		TUint8* ptr = (TUint8*)( aMediaInfoBufferPtr + bufferPosition );
       
   393 		
       
   394 		Mem::Copy( ptr, &mediaInfo, sizeof( TMdEMediaInfo ) );
       
   395 		
       
   396 		bufferPosition += sizeof( TMdEMediaInfo );
       
   397 		
       
   398 		++count;
       
   399 		}
       
   400 	
       
   401 	aMediaInfoBuffer.SetLength( bufferPosition );
       
   402 
       
   403 	CleanupStack::PopAndDestroy( 3, &commonClause ); // statement, var, commonClauseOne
       
   404 
       
   405 	return count;
       
   406 	}
       
   407 
       
   408 TItemId CMdSSqlObjectManipulate::SearchNotPresentFileL(TUint32 aMediaId, 
       
   409 		TDesC16& aUri, TMdSFileInfo& aFileInfo,
       
   410 		TFilePresentStates& aPlaceHolder, TBool& aNotPresentState)
       
   411 	{
       
   412 	_LIT( KSearchNotPresentFile, "SELECT ObjectId, Flags, LastModifiedDate, Size FROM Object%u WHERE NOT Flags&? AND (Flags&? OR Flags&? OR Flags&? ) AND MediaId=? AND URI=?;" );
       
   413 
       
   414 	RClauseBuffer commonClauseOne(*this, KSearchNotPresentFile.iTypeLength + KMaxUintValueLength);
       
   415 	CleanupClosePushL( commonClauseOne );
       
   416 	CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
       
   417 	clauseBuffer.BufferL().Format( KSearchNotPresentFile, KDefaultNamespaceDefId );
       
   418 
       
   419 	TItemId objectId = KNoId;
       
   420 	TUint32 flags = 0;
       
   421 
       
   422     RRowData var;
       
   423     CleanupClosePushL( var );
       
   424     var.ReserveL( 5 );
       
   425     var.AppendL( TColumn( EMdEObjectFlagRemoved ) );
       
   426     var.AppendL( TColumn( EMdEObjectFlagNotPresent ) ); // not present flag
       
   427     var.AppendL( TColumn( EMdEObjectFlagStartUpNotPresent ) ); // start up not present flag
       
   428     var.AppendL( TColumn( EMdeObjectFlagPending ) ); // pending for composing - needed to complete composing
       
   429     var.AppendL( TColumn( aMediaId ) );
       
   430     var.AppendL( TColumn( aUri ) );
       
   431 
       
   432     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   433 	RMdsStatement statement;
       
   434 	CleanupClosePushL( statement );
       
   435     connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
       
   436 
       
   437     TInt64 modifiedTime(0);
       
   438     TUint32 size(0);
       
   439 
       
   440     RRowData result;
       
   441     CleanupClosePushL( result );
       
   442     result.ReserveL( 4 );
       
   443     result.AppendL( TColumn( objectId ) );
       
   444     result.AppendL( TColumn( flags ) );
       
   445     result.AppendL( TColumn( modifiedTime ) );
       
   446     result.AppendL( TColumn( size ) );
       
   447 
       
   448     // default values (used if object doesn't exist)
       
   449 	aPlaceHolder = EMdsNotFound;
       
   450 	aNotPresentState = EFalse;
       
   451 
       
   452 	if( connection.NextRowL( statement, result ) )
       
   453 		{
       
   454 		result.Column( 0 ).Get( objectId );
       
   455 		result.Column( 1 ).Get( flags );
       
   456 
       
   457 		if ( flags & EMdEObjectFlagPlaceholder )
       
   458 			{
       
   459 			aPlaceHolder = EMdsPlaceholder;
       
   460 			}
       
   461 		else
       
   462 			{
       
   463 			result.Column( 2 ).Get( modifiedTime );
       
   464 			result.Column( 3 ).Get( size );
       
   465 
       
   466 			// check if file is modified
       
   467     		if ( ( aFileInfo.iModifiedTime == modifiedTime ) && ( aFileInfo.iSize == size ) )
       
   468     			{
       
   469     			aPlaceHolder = EMdsNormal;
       
   470     			
       
   471     	        // If images were pending for composing, composer needs to be notified for the composing to complete 
       
   472     	        if( (flags & EMdeObjectFlagPending) && (flags & EMdEObjectFlagStartUpNotPresent) )
       
   473     	            {
       
   474     	            aNotPresentState = ETrue;
       
   475     	            }
       
   476     			}
       
   477     		else
       
   478     			{
       
   479     			aPlaceHolder = EMdsModified;
       
   480     			}
       
   481 			}
       
   482 
       
   483 		if( flags & EMdEObjectFlagNotPresent )
       
   484 			{
       
   485 			aNotPresentState = ETrue;
       
   486 			}
       
   487 		}
       
   488 
       
   489 	CleanupStack::PopAndDestroy( &result );
       
   490 	CleanupStack::PopAndDestroy( &statement );
       
   491 	CleanupStack::PopAndDestroy( &var );
       
   492 	CleanupStack::PopAndDestroy( &commonClauseOne );
       
   493 	return objectId;
       
   494 	}
       
   495 
       
   496 void CMdSSqlObjectManipulate::SetFilesToPresentL(const RArray<TItemId>& aObjectIds)
       
   497 	{
       
   498 	const TInt objectCount = aObjectIds.Count();
       
   499     if ( objectCount > 0 )
       
   500     	{
       
   501 		_LIT( KSetFileToPresent, "UPDATE Object%u SET Flags=Flags&? WHERE (Flags&?)<>0 AND ObjectId IN (?" );
       
   502 		_LIT( KCommaQuestionmark, ",?");
       
   503 		_LIT( KBracketSemicolon, ");");
       
   504 		
       
   505 		RClauseBuffer commonClauseOne(*this, KSetFileToPresent.iTypeLength + KMaxUintValueLength +
       
   506 				( KCommaQuestionmark.iTypeLength * ( objectCount-1 ) ) +
       
   507 				KBracketSemicolon.iTypeLength );
       
   508 		CleanupClosePushL( commonClauseOne );
       
   509 		CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
       
   510 		clauseBuffer.BufferL().Format( KSetFileToPresent, KDefaultNamespaceDefId );
       
   511 
       
   512 	    RRowData var;
       
   513 	    CleanupClosePushL( var );
       
   514 	    // reset not present and start up not present flags
       
   515 	    var.AppendL( TColumn( ~(EMdEObjectFlagNotPresent | EMdEObjectFlagStartUpNotPresent) ) );
       
   516 	    var.AppendL( TColumn( (EMdEObjectFlagNotPresent | EMdEObjectFlagStartUpNotPresent) ) );
       
   517 	    var.AppendL( TColumn( aObjectIds[0] ) );
       
   518 
       
   519 	    for ( TInt i = 1; i < objectCount; i++ )
       
   520 	    	{
       
   521 	    	clauseBuffer.AppendL( KCommaQuestionmark );
       
   522 		    var.AppendL( TColumn( aObjectIds[i] ) );
       
   523 	    	}
       
   524 	    
       
   525 	    clauseBuffer.AppendL( KBracketSemicolon );
       
   526 	    CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   527 	    connection.ExecuteL( clauseBuffer.ConstBufferL(), var );
       
   528 	
       
   529 		CleanupStack::PopAndDestroy( &var );
       
   530 		CleanupStack::PopAndDestroy( &commonClauseOne ); 
       
   531     	}
       
   532 	}
       
   533 
       
   534 void CMdSSqlObjectManipulate::SetRelationsToPresentL(TItemId aObjectId, 
       
   535 		RArray<TItemId>& aIdArray)
       
   536 	{
       
   537 	_LIT( KSearchNotPresentRelations, "SELECT RelationId FROM Relations%u WHERE NOT Flags&? AND Flags&? AND (LeftObjectId=? OR RightObjectId=?);" );
       
   538 	_LIT( KSetRelationsToPresent, "UPDATE Relations%u SET Flags=Flags&? WHERE Flags&? AND (LeftObjectId=? OR RightObjectId=?);" );
       
   539 
       
   540 	RClauseBuffer commonClauseOne(*this, KSearchNotPresentRelations.iTypeLength + KMaxUintValueLength);
       
   541 	CleanupClosePushL( commonClauseOne );
       
   542 	CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
       
   543 	clauseBuffer.BufferL().Format( KSearchNotPresentRelations, KDefaultNamespaceDefId );
       
   544 
       
   545     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   546     RRowData var;
       
   547     CleanupClosePushL( var );
       
   548     
       
   549     var.ReserveL( 4 ); // reserve space for flags and object IDs
       
   550     var.AppendL( TColumn( EMdERelationFlagDeleted ) );
       
   551     var.AppendL( TColumn( EMdERelationFlagNotPresent ) );
       
   552     var.AppendL( TColumn( aObjectId ) );
       
   553     var.AppendL( TColumn( aObjectId ) );
       
   554 
       
   555 	RMdsStatement statement;
       
   556 	CleanupClosePushL( statement );
       
   557 	connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
       
   558 
       
   559 	var.Free();	var.Reset();
       
   560     TItemId relationId(0);
       
   561     var.AppendL( TColumn( relationId ) );
       
   562 	while( connection.NextRowL( statement, var ) )
       
   563 		{
       
   564 		var.Column( 0 ).Get( relationId );
       
   565 		aIdArray.AppendL( relationId );
       
   566 		}
       
   567 
       
   568 	clauseBuffer.ReserveSpaceL( KSetRelationsToPresent.iTypeLength + KMaxUintValueLength );
       
   569 	clauseBuffer.BufferL().Format( KSetRelationsToPresent, KDefaultNamespaceDefId );
       
   570 
       
   571     var.Free(); 
       
   572     var.Reset();
       
   573 
       
   574     var.AppendL( TColumn( ~EMdERelationFlagNotPresent ) ); // reset not present flag
       
   575     var.AppendL( TColumn( EMdERelationFlagNotPresent ) );
       
   576     var.AppendL( TColumn( aObjectId ) );
       
   577     var.AppendL( TColumn( aObjectId ) );
       
   578 
       
   579     connection.ExecuteL( clauseBuffer.ConstBufferL(), var );
       
   580 
       
   581 	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // statement, var, clauseBuffer
       
   582 	}
       
   583 
       
   584 void CMdSSqlObjectManipulate::SetFilesToNotPresentL(TUint32 aMediaId, TBool aStartUp,
       
   585 		RArray<TItemId>& aObjectIds)
       
   586 	{
       
   587 	
       
   588 	_LIT( KSearchPresentFilesStartUpL, "SELECT ObjectId FROM Object%u WHERE NOT Flags&? AND MediaId=?;" );
       
   589 	_LIT( KSearchPresentFilesL, "SELECT ObjectId FROM Object%u WHERE NOT Flags&? AND NOT Flags&? AND MediaId=?;" );
       
   590 	
       
   591 	RClauseBuffer commonClauseOne(*this, ( aStartUp ? KSearchPresentFilesStartUpL.iTypeLength : KSearchPresentFilesL.iTypeLength )+ 
       
   592 			KMaxUintValueLength);
       
   593 	CleanupClosePushL( commonClauseOne );
       
   594 	CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
       
   595 	
       
   596 	if( aStartUp )
       
   597 		{
       
   598 		clauseBuffer.BufferL().Format( KSearchPresentFilesStartUpL, KDefaultNamespaceDefId );
       
   599 		}
       
   600 	else
       
   601 		{
       
   602 		clauseBuffer.BufferL().Format( KSearchPresentFilesL, KDefaultNamespaceDefId );
       
   603 		}
       
   604 
       
   605 	TItemId objectId = 0;
       
   606 
       
   607     RRowData var;
       
   608     CleanupClosePushL( var );
       
   609     
       
   610     var.ReserveL( 3 ); // reserve space for flags and media ID
       
   611     var.AppendL( TColumn( EMdEObjectFlagRemoved ) );
       
   612     if ( !aStartUp )
       
   613     	{
       
   614     	var.AppendL( TColumn( EMdEObjectFlagNotPresent ) ); // present flag
       
   615     	}
       
   616     var.AppendL( TColumn( aMediaId ) );
       
   617 
       
   618 	RMdsStatement statement;
       
   619 	CleanupClosePushL( statement );
       
   620 
       
   621     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   622 
       
   623     connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
       
   624 
       
   625     var.Free(); 
       
   626     var.Reset();
       
   627 
       
   628     var.AppendL( TColumn( objectId ) );
       
   629 	while( connection.NextRowL( statement, var ) )
       
   630 		{
       
   631 		var.Column( 0 ).Get( objectId );
       
   632 		aObjectIds.AppendL( objectId );
       
   633 		}
       
   634 
       
   635 	_LIT( KSetFilesToNotPresent, "UPDATE Object%u SET Flags=Flags|? WHERE MediaId=?;" );
       
   636 	clauseBuffer.ReserveSpaceL( 
       
   637 			KSetFilesToNotPresent.iTypeLength + 
       
   638 			KMaxUintValueLength ); // TUint32 max value's lenght is 10 numbers so %u + 8
       
   639 	clauseBuffer.BufferL().Format( KSetFilesToNotPresent, KDefaultNamespaceDefId );
       
   640 
       
   641 	var.Free(); 
       
   642 	var.Reset();
       
   643 
       
   644 	if( aStartUp )
       
   645 		{
       
   646 		var.AppendL( TColumn( EMdEObjectFlagStartUpNotPresent ) ); // set not present flag
       
   647 		}
       
   648 	else 
       
   649 		{
       
   650 		var.AppendL( TColumn( EMdEObjectFlagNotPresent ) ); // set not present flag
       
   651 		}
       
   652 	var.AppendL( TColumn( aMediaId ) );
       
   653 
       
   654     connection.ExecuteL( clauseBuffer.ConstBufferL(), var );
       
   655 
       
   656     // statement, var, commonClauseOne
       
   657 	CleanupStack::PopAndDestroy( 3, &commonClauseOne );
       
   658 	}
       
   659 
       
   660 void CMdSSqlObjectManipulate::SetRelationsToNotPresentL(
       
   661 		TUint32 aMediaId, RArray<TItemId>& aRelationIds)
       
   662 	{
       
   663 	_LIT( KSearchPresentRelations, "SELECT DISTINCT A.RelationId FROM Relations%u AS A LEFT JOIN object%u AS B On A.LeftObjectId = B.ObjectId OR A.RightObjectId = B.ObjectId WHERE NOT A.Flags&%u AND NOT A.Flags&%u AND B.MediaId=%u" );
       
   664 	_LIT( KSetRelationsToPresent, "UPDATE Relations%u SET Flags=Flags|? WHERE NOT Flags&? AND RelationId IN (%S);" );
       
   665 
       
   666 	// RelationIDs query sql statement
       
   667 	RClauseBuffer commonClauseOne(*this, 
       
   668 			KSearchPresentRelations.iTypeLength + 
       
   669 			KMaxUintValueLength  );
       
   670     CleanupClosePushL( commonClauseOne );
       
   671 	CMdsClauseBuffer& clauseBufferOne = commonClauseOne.BufferL();
       
   672 	clauseBufferOne.BufferL().Format( KSearchPresentRelations, 
       
   673                 KDefaultNamespaceDefId,
       
   674                 KDefaultNamespaceDefId,
       
   675                 EMdERelationFlagDeleted,
       
   676                 EMdERelationFlagNotPresent,
       
   677                 aMediaId );
       
   678 	
       
   679     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   680     	
       
   681     RRowData var;
       
   682     CleanupClosePushL( var );
       
   683     
       
   684 	RMdsStatement statement;
       
   685 	CleanupClosePushL( statement );
       
   686 
       
   687 	connection.ExecuteQueryL( clauseBufferOne.ConstBufferL(), statement, var );
       
   688 
       
   689     // Get RelationIDs From query result
       
   690     TItemId relationId(0);
       
   691     var.AppendL( TColumn( relationId ) );
       
   692 	while( connection.NextRowL( statement, var ) )
       
   693 		{
       
   694 		var.Column( 0 ).Get( relationId );
       
   695 		aRelationIds.AppendL( relationId );
       
   696 		}
       
   697 	
       
   698     // Set objects' relations not present by MediaID
       
   699 	RClauseBuffer commonClauseTwo(*this, 
       
   700 			KSetRelationsToPresent.iTypeLength + 
       
   701 			clauseBufferOne.ConstBufferL().Length() );
       
   702 	
       
   703     CleanupClosePushL( commonClauseTwo );
       
   704 	CMdsClauseBuffer& clauseBufferTwo = commonClauseTwo.BufferL();
       
   705 	clauseBufferTwo.BufferL().Format( KSetRelationsToPresent, 
       
   706                                    KDefaultNamespaceDefId,
       
   707                                    &clauseBufferOne.ConstBufferL() );
       
   708 
       
   709 	var.Free();
       
   710 	var.Reset();
       
   711     var.ReserveL( 2 ); 
       
   712     var.AppendL( TColumn( EMdERelationFlagNotPresent ) );
       
   713     var.AppendL( TColumn( EMdERelationFlagNotPresent ) );
       
   714 
       
   715     connection.ExecuteL( clauseBufferTwo.ConstBufferL(), var );
       
   716 
       
   717     // commonClauseTwo, statement, var, commonClauseOne
       
   718 	CleanupStack::PopAndDestroy( 4, &commonClauseOne );
       
   719 	}
       
   720 
       
   721 void CMdSSqlObjectManipulate::RemoveFilesNotPresentL(TUint32 aMediaId, RArray<TItemId>* aObjectIds)
       
   722 	{
       
   723 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   724 	
       
   725 	// collect object IDs from start up not present objects
       
   726 	if( aObjectIds )
       
   727 		{
       
   728 		_LIT( KSelectFilesStartUpNotPresent, "SELECT ObjectId FROM Object%u WHERE NOT Flags&? AND NOT Flags&? AND Flags&? AND MediaId=?;" );
       
   729 
       
   730 		RClauseBuffer commonClauseOne(*this, 
       
   731 				KSelectFilesStartUpNotPresent.iTypeLength + KMaxUintValueLength );
       
   732 		CleanupClosePushL( commonClauseOne );
       
   733 		CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
       
   734 
       
   735 		clauseBuffer.BufferL().Format( KSelectFilesStartUpNotPresent, KDefaultNamespaceDefId );
       
   736 
       
   737 		RRowData var;
       
   738 		CleanupClosePushL( var );
       
   739 		var.AppendL( TColumn( EMdEObjectFlagRemoved ) );
       
   740 		var.AppendL( TColumn( EMdEObjectFlagNotPresent ) );
       
   741 		var.AppendL( TColumn( EMdEObjectFlagStartUpNotPresent ) );
       
   742 		var.AppendL( TColumn( aMediaId ) );
       
   743 
       
   744 		RMdsStatement statement;
       
   745 		CleanupClosePushL( statement );
       
   746 	    connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
       
   747 
       
   748 		RRowData result;
       
   749 	    CleanupClosePushL( result );
       
   750 	    TItemId objectId( KNoId );
       
   751 	    result.AppendL( TColumn( objectId ) );
       
   752 
       
   753 		while( connection.NextRowL( statement, result ) )
       
   754 			{
       
   755 			result.Column( 0 ).Get( objectId );
       
   756 			aObjectIds->AppendL( objectId );
       
   757 			}
       
   758 
       
   759 		CleanupStack::PopAndDestroy( &result );
       
   760 		CleanupStack::PopAndDestroy( &statement );
       
   761 		CleanupStack::PopAndDestroy( &var );
       
   762 		CleanupStack::PopAndDestroy( &commonClauseOne );
       
   763 		}
       
   764 
       
   765 	_LIT( KRemoveFilesNotPresent, "UPDATE Object%u SET Flags=Flags|? WHERE NOT Flags&? AND (Flags&? OR Flags&?) AND MediaId=?;" );
       
   766 
       
   767 	RClauseBuffer commonClauseOne(*this, 
       
   768 			KRemoveFilesNotPresent.iTypeLength + KMaxUintValueLength);
       
   769 	CleanupClosePushL( commonClauseOne );
       
   770 	CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
       
   771 	clauseBuffer.BufferL().Format( KRemoveFilesNotPresent, KDefaultNamespaceDefId );
       
   772 
       
   773     RRowData var;
       
   774     CleanupClosePushL( var );
       
   775     var.AppendL( TColumn( EMdEObjectFlagRemoved ) );
       
   776     var.AppendL( TColumn( EMdEObjectFlagRemoved ) );
       
   777     var.AppendL( TColumn( EMdEObjectFlagNotPresent ) ); // not present flag
       
   778     var.AppendL( TColumn( EMdEObjectFlagStartUpNotPresent ) ); // start up not present flag
       
   779     var.AppendL( TColumn( aMediaId ) );
       
   780 
       
   781 	__LOGQUERY_16( _L("RemoveFilesNotPresentL:"), clauseBuffer.ConstBufferL(), var);
       
   782     connection.ExecuteL( clauseBuffer.ConstBufferL(), var );
       
   783 
       
   784 	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // var, commonClauseOne
       
   785 	}
       
   786 
       
   787 void CMdSSqlObjectManipulate::GetSchemaVersionL(
       
   788 		TInt& aMajorVersion, TInt& aMinorVersion)
       
   789 	{
       
   790 	TInt64 minorVersion;
       
   791 	TInt rowCount = MMdsPreferences::GetL( KMdsSchemaVersionName, 
       
   792 			MMdsPreferences::EPreferenceBothGet, 
       
   793 			aMajorVersion, &minorVersion );
       
   794 
       
   795 	aMinorVersion = minorVersion;
       
   796 
       
   797 	// if no rows found leave
       
   798 	if( rowCount <= 0 )
       
   799 		{
       
   800 		User::Leave( KErrNotFound );
       
   801 		}
       
   802 	}
       
   803 
       
   804 void CMdSSqlObjectManipulate::SetObjectToPresentByGuidL( 
       
   805 		const TInt64& aGuidHigh, const TInt64& aGuidLow )
       
   806 	{
       
   807 	// get object ID for later queries
       
   808 	_LIT( KGetObjectIdByGuid, "SELECT ObjectId FROM Object%u WHERE Flags&? AND GuidHigh=? AND GuidLow=?;" );
       
   809 
       
   810 	RClauseBuffer commonClauseOne(*this, 
       
   811 			KGetObjectIdByGuid.iTypeLength + KMaxUintValueLength);
       
   812 	CleanupClosePushL( commonClauseOne );
       
   813 	CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
       
   814 	clauseBuffer.BufferL().Format( KGetObjectIdByGuid, KDefaultNamespaceDefId );
       
   815 
       
   816     RRowData var;
       
   817     CleanupClosePushL( var );
       
   818     var.ReserveL( 3 ); // for flags and GUID high/low in WHERE
       
   819 
       
   820     var.AppendL( TColumn( (TUint32)EMdEObjectFlagNotPresent ) );
       
   821     var.AppendL( TColumn( aGuidHigh ) );
       
   822     var.AppendL( TColumn( aGuidLow ) );
       
   823 
       
   824 	RMdsStatement statement;
       
   825 	CleanupClosePushL( statement );
       
   826 
       
   827     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   828 
       
   829 	__LOGQUERY_16( _L("SetObjectToPresentByGuidL q1:"), clauseBuffer.ConstBufferL(), var);
       
   830 
       
   831     connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
       
   832 
       
   833 	var.Free();
       
   834 	var.Reset();
       
   835 	TItemId objectId = KNoId;
       
   836 	var.AppendL( TColumn( objectId ) );
       
   837 
       
   838 	if( connection.NextRowL( statement, var ) )
       
   839 		{
       
   840 		var.Column( 0 ).Get( objectId );
       
   841 
       
   842 		// set object, which object ID is matching, to present state
       
   843 		_LIT( KSetObjectToPresentByGuid, "UPDATE Object%u SET Flags=Flags&? WHERE ObjectId=? AND (Flags&?)<>0;" );
       
   844 
       
   845 		RClauseBuffer commonClauseTwo(*this, 
       
   846 				KSetObjectToPresentByGuid.iTypeLength + KMaxUintValueLength);
       
   847 		CleanupClosePushL( commonClauseTwo );
       
   848 		CMdsClauseBuffer& clauseBuffer2 = commonClauseTwo.BufferL();
       
   849 		clauseBuffer2.BufferL().Format( KSetObjectToPresentByGuid, 
       
   850 				KDefaultNamespaceDefId );
       
   851 
       
   852 		var.Free();
       
   853 		var.Reset();
       
   854 		var.AppendL( TColumn( (TUint32)~EMdEObjectFlagNotPresent ) );
       
   855 		var.AppendL( TColumn( objectId ) );
       
   856 		
       
   857 		var.AppendL( TColumn( (TUint32)EMdEObjectFlagNotPresent ) );
       
   858 
       
   859 		__LOGQUERY_16( _L("SetObjectToPresentByGuidL q2:"), 
       
   860 				clauseBuffer2.ConstBufferL(), var);
       
   861 		
       
   862 		connection.ExecuteL( clauseBuffer2.ConstBufferL(), var );
       
   863 		
       
   864 		CleanupStack::PopAndDestroy( &commonClauseTwo );
       
   865 
       
   866 		// set relations, which left or right object ID is matching, 
       
   867 		// to present state
       
   868 		_LIT( KSetRelationToPresentByGuid, "UPDATE Relations%u SET Flags=Flags&? WHERE LeftObjectId=? OR RightObjectId=?;" );
       
   869 		
       
   870 		RClauseBuffer commonClauseThree(*this, 
       
   871 				KSetRelationToPresentByGuid.iTypeLength + KMaxUintValueLength);
       
   872 		CleanupClosePushL( commonClauseThree );
       
   873 		CMdsClauseBuffer& clauseBuffer3 = commonClauseThree.BufferL();
       
   874 		clauseBuffer3.BufferL().Format( KSetRelationToPresentByGuid, 
       
   875 				KDefaultNamespaceDefId );
       
   876 
       
   877 		var.Free();
       
   878 		var.Reset();
       
   879 		var.AppendL( TColumn( (TUint32)~EMdERelationFlagNotPresent ) );
       
   880 		var.AppendL( TColumn( objectId ) );
       
   881 		var.AppendL( TColumn( objectId ) );
       
   882 
       
   883 		__LOGQUERY_16( _L("SetObjectToPresentByGuidL q3:"), 
       
   884 				clauseBuffer3.ConstBufferL(), var);
       
   885 
       
   886 		connection.ExecuteL( clauseBuffer3.ConstBufferL(), var );
       
   887 		
       
   888 		CleanupStack::PopAndDestroy( &commonClauseThree );
       
   889 		}
       
   890 	// no any matching object
       
   891 	else
       
   892 		{
       
   893 		User::Leave( KErrNotFound );
       
   894 		}
       
   895 
       
   896 	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // statement, var, commonClauseOne
       
   897 	}
       
   898 
       
   899 void CMdSSqlObjectManipulate::ChangePathL(
       
   900 		const TDesC& aOldPath, const TDesC& aNewPath, 
       
   901 		RArray<TItemId>& aObjectIds)
       
   902 	{
       
   903 	// collect object IDs from object which match to the old path
       
   904 	_LIT( KGetObjectIdByBeginOfUri, "SELECT ObjectId FROM Object%u WHERE NOT Flags&? AND substr(URI, 1, ?) = ?;" );
       
   905 
       
   906 	RClauseBuffer commonClauseOne(*this, 
       
   907 			KGetObjectIdByBeginOfUri.iTypeLength + KMaxUintValueLength);
       
   908 	CleanupClosePushL( commonClauseOne );
       
   909 	CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
       
   910 	clauseBuffer.BufferL().Format( KGetObjectIdByBeginOfUri, KDefaultNamespaceDefId );
       
   911 
       
   912 	const TUint32 flags = EMdEObjectFlagNotPresent | EMdEObjectFlagRemoved | EMdEObjectFlagGarbage;
       
   913 
       
   914 	const TInt oldPathLength = aOldPath.Length();
       
   915 
       
   916 	RRowData var;
       
   917     CleanupClosePushL( var );
       
   918 	var.ReserveL( 3 );
       
   919     var.AppendL( TColumn( flags ) );
       
   920     var.AppendL( TColumn( oldPathLength ) );
       
   921     var.AppendL( TColumn( aOldPath ) );
       
   922 
       
   923     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   924 
       
   925 	RMdsStatement statement;
       
   926 	CleanupClosePushL( statement );
       
   927 
       
   928 	__LOGQUERY_16( _L("ChangePathL q1:"), clauseBuffer.ConstBufferL(), var);
       
   929 
       
   930     connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
       
   931 
       
   932     var.Free();
       
   933     var.Reset();
       
   934     TItemId objectId( 0 );
       
   935     var.AppendL( TColumn( objectId ) );
       
   936 
       
   937 	while( connection.NextRowL( statement, var ) )
       
   938 		{
       
   939 		var.Column( 0 ).Get( objectId );
       
   940 		aObjectIds.AppendL( objectId );
       
   941 		}
       
   942 
       
   943 	// update the new path to objects which match with the old path
       
   944 	_LIT( KChangeOldPathToNewPath, "UPDATE Object%u SET URI=? || substr(URI, ?, length(URI)) WHERE NOT Flags&? AND substr(URI, 1, ?) = ?;" );
       
   945 
       
   946 	RClauseBuffer commonClauseTwo(*this, 
       
   947 			KChangeOldPathToNewPath.iTypeLength + KMaxUintValueLength);
       
   948 	CleanupClosePushL( commonClauseTwo );
       
   949 	CMdsClauseBuffer& clauseBuffer2 = commonClauseTwo.BufferL();
       
   950 	clauseBuffer2.BufferL().Format( KChangeOldPathToNewPath, KDefaultNamespaceDefId );
       
   951 
       
   952 	var.Free();
       
   953 	var.Reset();
       
   954 
       
   955 	var.ReserveL( 5 );
       
   956     var.AppendL( TColumn( aNewPath ) );
       
   957     var.AppendL( TColumn( oldPathLength + 1 ) );
       
   958     var.AppendL( TColumn( flags ) );
       
   959     var.AppendL( TColumn( oldPathLength ) );
       
   960     var.AppendL( TColumn( aOldPath ) );
       
   961 
       
   962 	__LOGQUERY_16( _L("ChangePathL q2:"), clauseBuffer2.ConstBufferL(), var);
       
   963 
       
   964 	connection.ExecuteL( clauseBuffer2.ConstBufferL(), var );
       
   965 
       
   966 	CleanupStack::PopAndDestroy( 4, &commonClauseOne ); // commonClauseTwo, statement, var, commonClauseOne
       
   967 	}
       
   968 
       
   969 void CMdSSqlObjectManipulate::ChangeMediaIdL()
       
   970 	{
       
   971 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   972 	
       
   973 	TVolumeInfo volumeInfo;
       
   974 	RFs fs;
       
   975 	User::LeaveIfError( fs.Connect() );
       
   976 	CleanupClosePushL( fs );
       
   977 
       
   978 	fs.Volume( volumeInfo, EDriveC );
       
   979 	CleanupStack::PopAndDestroy( &fs );
       
   980 
       
   981 	// update the new media id to objects which match with the old id
       
   982 	_LIT( KChangeOldIdToNewId, "UPDATE Object%u SET MediaId=? WHERE NOT Flags&? AND MediaId = (SELECT Value FROM MdE_Preferences WHERE Key=?);" );
       
   983 
       
   984 	RClauseBuffer clauseOne( *this, KChangeOldIdToNewId.iTypeLength + KMaxUintValueLength );
       
   985 	CleanupClosePushL( clauseOne );
       
   986 	CMdsClauseBuffer& clauseBuffer = clauseOne.BufferL();
       
   987 	clauseBuffer.BufferL().Format( KChangeOldIdToNewId, KDefaultNamespaceDefId );
       
   988 
       
   989 	const TUint32 flags = EMdEObjectFlagNotPresent | EMdEObjectFlagRemoved | EMdEObjectFlagGarbage;
       
   990 
       
   991 	RRowData var;
       
   992 	CleanupClosePushL( var );
       
   993 
       
   994 	var.ReserveL( 3 );
       
   995 	var.AppendL( TColumn( (TUint32) volumeInfo.iUniqueID ) );
       
   996 	var.AppendL( TColumn( flags ) );
       
   997 	var.AppendL( TColumn( KCMediaIdKey ) );
       
   998 
       
   999 	__LOGQUERY_16( _L("ChangeMediaIdL q2:"), clauseBuffer.ConstBufferL(), var);
       
  1000 
       
  1001 	connection.ExecuteL( clauseBuffer.ConstBufferL(), var );
       
  1002 	
       
  1003 	// update the new media id to objects which match with the old id
       
  1004 	_LIT( KUpdateMediaId, "UPDATE MdE_Preferences SET Value=? WHERE Key = ?;" );
       
  1005 	
       
  1006 	var.Free();
       
  1007 	var.Reset();
       
  1008 	
       
  1009 	TTime currentTime;
       
  1010 	currentTime.UniversalTime();
       
  1011 	const TInt64 currentTime64 = currentTime.Int64();
       
  1012 
       
  1013 	var.ReserveL( 2 );
       
  1014 	var.AppendL( TColumn( (TUint32) volumeInfo.iUniqueID ) );
       
  1015 	var.AppendL( TColumn( KCMediaIdKey ) );
       
  1016 
       
  1017 	connection.ExecuteL( KUpdateMediaId, var );
       
  1018 
       
  1019 	CleanupStack::PopAndDestroy( &var );
       
  1020 	CleanupStack::PopAndDestroy( &clauseOne );
       
  1021 	}
       
  1022 
       
  1023 const CMdsPropertyDef& CMdSSqlObjectManipulate::ReadPropertyL( 
       
  1024 		CMdCSerializationBuffer& aBuffer, const CMdsObjectDef& aObjectDef,
       
  1025 		CMdsClauseBuffer& aBaseObjectClause, CMdsClauseBuffer& aObjectClause,
       
  1026 		RRowData& aBaseObjectDataRow, RRowData& aObjectDataRow, TUint8& aFlags)
       
  1027 	{
       
  1028 	const TMdCProperty& property = TMdCProperty::GetFromBufferL( aBuffer );
       
  1029 	const CMdsPropertyDef* propertyDef = aObjectDef.GetPropertyByIdL( 
       
  1030 			property.iPropertyDefId );
       
  1031 	if ( !propertyDef )
       
  1032 		{
       
  1033 #ifdef _DEBUG
       
  1034 		WRITELOG( "Incorrect property" );
       
  1035 #endif
       
  1036 		User::Leave( KErrMdEUnknownPropertyDef );
       
  1037 		}
       
  1038 	aFlags = property.iModFlags;
       
  1039 
       
  1040 	if (property.iModFlags == EMdEPropertyModNone)
       
  1041 		{
       
  1042 		return *propertyDef;
       
  1043 		}
       
  1044 
       
  1045 	const TBool baseObjectProperty = 
       
  1046 		iBaseObjectDef->GetPropertyByIdL(property.iPropertyDefId) != NULL;
       
  1047 
       
  1048 	// if property is not removed add actual value
       
  1049 	if( !( property.iModFlags & EMdEPropertyModRemove ) )
       
  1050 		{
       
  1051 		switch(propertyDef->GetType())
       
  1052 			{
       
  1053 			case EPropertyBool:
       
  1054 				{
       
  1055 				const TBool boolValue = property.iValue.iInt32;
       
  1056 				if ( baseObjectProperty )
       
  1057 					{
       
  1058 					aBaseObjectDataRow.AppendL( TColumn( boolValue ) );
       
  1059 					}
       
  1060 				else
       
  1061 					{
       
  1062 					aObjectDataRow.AppendL( TColumn( boolValue ) );
       
  1063 					}
       
  1064 				break;
       
  1065 				}
       
  1066 			case EPropertyInt8:
       
  1067 				{
       
  1068 				const TInt8 int8Value = property.iValue.iInt32;
       
  1069 				if ( !propertyDef->CheckMinMaxValue( (TInt32)int8Value ) )
       
  1070 					{
       
  1071 #ifdef _DEBUG
       
  1072 					TInt32 debugValue = int8Value;
       
  1073 					WRITELOG2( "Incorrect property[%S] value: %d", 
       
  1074 							&propertyDef->GetName(), debugValue );
       
  1075 #endif
       
  1076 					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
       
  1077 					}
       
  1078 				if ( baseObjectProperty )
       
  1079 					{
       
  1080 					aBaseObjectDataRow.AppendL( TColumn( int8Value ) );
       
  1081 					}
       
  1082 				else
       
  1083 					{
       
  1084 					aObjectDataRow.AppendL( TColumn( int8Value ) );
       
  1085 					}
       
  1086 				break;
       
  1087 				}
       
  1088 			case EPropertyUint8:
       
  1089 				{
       
  1090 				const TUint8 uInt8Value = property.iValue.iUint32;
       
  1091 				if ( !propertyDef->CheckMinMaxValue( (TInt32)uInt8Value ) )
       
  1092 					{
       
  1093 #ifdef _DEBUG
       
  1094 					TInt32 debugValue = uInt8Value;
       
  1095 					WRITELOG2( "Incorrect property[%S] value: %d", 
       
  1096 							&propertyDef->GetName(), debugValue );
       
  1097 #endif
       
  1098 					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
       
  1099 					}
       
  1100 				if ( baseObjectProperty )
       
  1101 					{
       
  1102 					aBaseObjectDataRow.AppendL( TColumn( uInt8Value ) );
       
  1103 					}
       
  1104 				else
       
  1105 					{
       
  1106 					aObjectDataRow.AppendL( TColumn( uInt8Value ) );
       
  1107 					}
       
  1108 				break;
       
  1109 				}
       
  1110 			case EPropertyInt16:
       
  1111 				{
       
  1112 				const TInt16 int16Value = property.iValue.iInt32;
       
  1113 				if ( !propertyDef->CheckMinMaxValue( (TInt32)int16Value ) )
       
  1114 					{
       
  1115 #ifdef _DEBUG
       
  1116 					TInt32 debugValue = int16Value;
       
  1117 					WRITELOG2( "Incorrect property[%S] value: %d", 
       
  1118 							&propertyDef->GetName(), debugValue );
       
  1119 #endif
       
  1120 					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
       
  1121 					}
       
  1122 				if ( baseObjectProperty )
       
  1123 					{
       
  1124 					aBaseObjectDataRow.AppendL( TColumn( int16Value ) );
       
  1125 					}
       
  1126 				else
       
  1127 					{
       
  1128 					aObjectDataRow.AppendL( TColumn( int16Value ) );
       
  1129 					}
       
  1130 				break;
       
  1131 				}
       
  1132 			case EPropertyUint16:
       
  1133 				{
       
  1134 				const TUint16 uInt16Value = property.iValue.iUint32;
       
  1135 				if ( !propertyDef->CheckMinMaxValue( (TInt32)uInt16Value ) )
       
  1136 					{
       
  1137 #ifdef _DEBUG
       
  1138 					TInt32 debugValue = uInt16Value;
       
  1139 					WRITELOG2( "Incorrect property[%S] value: %d", 
       
  1140 							&propertyDef->GetName(), debugValue );
       
  1141 #endif
       
  1142 					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
       
  1143 					}
       
  1144 				if ( baseObjectProperty )
       
  1145 					{
       
  1146 					aBaseObjectDataRow.AppendL( TColumn( uInt16Value ) );
       
  1147 					}
       
  1148 				else
       
  1149 					{
       
  1150 					aObjectDataRow.AppendL( TColumn( uInt16Value ) );
       
  1151 					}
       
  1152 				break;
       
  1153 				}
       
  1154 			case EPropertyInt32:
       
  1155 				{
       
  1156 				const TInt32 int32Value = property.iValue.iInt32;
       
  1157 				if ( !propertyDef->CheckMinMaxValue( int32Value ) )
       
  1158 					{
       
  1159 #ifdef _DEBUG
       
  1160 					WRITELOG2( "Incorrect property[%S] value: %d", 
       
  1161 							&propertyDef->GetName(), int32Value );
       
  1162 #endif
       
  1163 					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
       
  1164 					}
       
  1165 				if ( baseObjectProperty )
       
  1166 					{
       
  1167 					aBaseObjectDataRow.AppendL( TColumn( int32Value ) );
       
  1168 					}
       
  1169 				else
       
  1170 					{
       
  1171 					aObjectDataRow.AppendL( TColumn( int32Value ) );
       
  1172 					}
       
  1173 				break;
       
  1174 				}
       
  1175 			case EPropertyUint32:
       
  1176 				{
       
  1177 				const TUint32 uInt32Value = property.iValue.iUint32;
       
  1178 				if ( !propertyDef->CheckMinMaxValue( uInt32Value ) )
       
  1179 					{
       
  1180 #ifdef _DEBUG
       
  1181 					WRITELOG2( "Incorrect property[%S] value: %u", 
       
  1182 							&propertyDef->GetName(), uInt32Value );
       
  1183 #endif
       
  1184 					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
       
  1185 					}
       
  1186 				if ( baseObjectProperty )
       
  1187 					{
       
  1188 					aBaseObjectDataRow.AppendL( TColumn( uInt32Value ) );
       
  1189 					}
       
  1190 				else
       
  1191 					{
       
  1192 					aObjectDataRow.AppendL( TColumn( uInt32Value ) );
       
  1193 					}
       
  1194 				break;
       
  1195 				}
       
  1196 			case EPropertyInt64:
       
  1197 				{
       
  1198 				const TInt64 int64Value = property.iValue.iInt64;
       
  1199 				if ( !propertyDef->CheckMinMaxValue( int64Value ) )
       
  1200 					{
       
  1201 #ifdef _DEBUG
       
  1202 					WRITELOG2( "Incorrect property[%S] value: %Ld", 
       
  1203 							&propertyDef->GetName(), int64Value );
       
  1204 #endif
       
  1205 					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
       
  1206 					}
       
  1207 				if ( baseObjectProperty )
       
  1208 					{
       
  1209 					aBaseObjectDataRow.AppendL( TColumn( int64Value ) );
       
  1210 					}
       
  1211 				else
       
  1212 					{
       
  1213 					aObjectDataRow.AppendL( TColumn( int64Value ) );
       
  1214 					}
       
  1215 				break;
       
  1216 				}
       
  1217 			case EPropertyTime:
       
  1218 				{
       
  1219 				const TInt64 int64Value = property.iValue.iInt64;
       
  1220 				if ( !propertyDef->CheckMinMaxValue( int64Value ) )
       
  1221 					{
       
  1222 #ifdef _DEBUG					
       
  1223 					WRITELOG2( "Incorrect property[%S] value: %Ld", 
       
  1224 							&propertyDef->GetName(), int64Value );
       
  1225 #endif
       
  1226 					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
       
  1227 					}
       
  1228 				if ( baseObjectProperty )
       
  1229 					{
       
  1230 					aBaseObjectDataRow.AppendL( TColumn( int64Value ) );
       
  1231 					}
       
  1232 				else
       
  1233 					{
       
  1234 					aObjectDataRow.AppendL( TColumn( int64Value ) );
       
  1235 					}
       
  1236 				break;
       
  1237 				}
       
  1238 			case EPropertyReal32:
       
  1239 				{
       
  1240 				const TReal32 real32Value = property.iValue.iReal;
       
  1241 				if ( !propertyDef->CheckMinMaxValue( real32Value ) )
       
  1242 					{
       
  1243 #ifdef _DEBUG
       
  1244 					TReal64 debugValue = real32Value;
       
  1245 					WRITELOG2( "Incorrect property[%S] value: %.2f", 
       
  1246 							&propertyDef->GetName(), debugValue );
       
  1247 #endif
       
  1248 					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
       
  1249 					}
       
  1250 				if ( baseObjectProperty )
       
  1251 					{
       
  1252 					aBaseObjectDataRow.AppendL( TColumn( real32Value ) );
       
  1253 					}
       
  1254 				else
       
  1255 					{
       
  1256 					aObjectDataRow.AppendL( TColumn( real32Value ) );
       
  1257 					}
       
  1258 				break;
       
  1259 				}
       
  1260 			case EPropertyReal64:
       
  1261 				{
       
  1262 				const TReal64 real64Value = property.iValue.iReal;
       
  1263 				if ( !propertyDef->CheckMinMaxValue( real64Value ) )
       
  1264 					{
       
  1265 #ifdef _DEBUG					
       
  1266 					WRITELOG2( "Incorrect property[%S] value: %.2f", 
       
  1267 							&propertyDef->GetName(), real64Value );
       
  1268 #endif
       
  1269 					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
       
  1270 					}
       
  1271 				if ( baseObjectProperty )
       
  1272 					{
       
  1273 					aBaseObjectDataRow.AppendL( TColumn( real64Value ) );
       
  1274 					}
       
  1275 				else
       
  1276 					{
       
  1277 					aObjectDataRow.AppendL( TColumn( real64Value ) );
       
  1278 					}
       
  1279 				break;
       
  1280 				}
       
  1281 			case EPropertyText:
       
  1282 				{
       
  1283 				aBuffer.PositionL( property.iValue.iPtr.iOffset );
       
  1284 				TPtrC16 textValue( aBuffer.ReceivePtr16L() );
       
  1285 				if ( !propertyDef->CheckMinMaxValue( (TInt32)textValue.Length() ) )
       
  1286 					{
       
  1287 #ifdef _DEBUG
       
  1288 					WRITELOG3( "Incorrect property[%S] value: \"%S\", length: %d", 
       
  1289 							&propertyDef->GetName(), &textValue, 
       
  1290 							textValue.Length() );
       
  1291 #endif
       
  1292 					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
       
  1293 					}
       
  1294 				if ( baseObjectProperty )
       
  1295 					{
       
  1296 					aBaseObjectDataRow.AppendL( TColumn( textValue ) );
       
  1297 					}
       
  1298 				else
       
  1299 					{
       
  1300 					aObjectDataRow.AppendL( TColumn( textValue ) );
       
  1301 					}
       
  1302 				break;
       
  1303 				}
       
  1304 			default:
       
  1305 				User::Leave( KErrMdEUnknownPropertyType );
       
  1306 			}
       
  1307 		}
       
  1308 	// if property is removed add null value
       
  1309 	else
       
  1310 		{
       
  1311 		TPtrC16 val = TPtr16((TUint16*)0, 0);
       
  1312 		if( baseObjectProperty )
       
  1313 			{
       
  1314 			aBaseObjectDataRow.AppendL( TColumn( val ) );
       
  1315 			}
       
  1316 		else
       
  1317 			{
       
  1318 			aObjectDataRow.AppendL( TColumn( val ) );
       
  1319 			}
       
  1320 		}
       
  1321 
       
  1322 	if( baseObjectProperty )
       
  1323 		{
       
  1324 		aBaseObjectClause.AppendL( KComma );
       
  1325 		aBaseObjectClause.AppendL( propertyDef->GetName() );
       
  1326 		}
       
  1327 	else
       
  1328 		{
       
  1329 		aObjectClause.AppendL( KComma );
       
  1330 		aObjectClause.AppendL( propertyDef->GetName() );
       
  1331 		}
       
  1332 	
       
  1333 	return *propertyDef;
       
  1334 	}
       
  1335 
       
  1336 TItemId CMdSSqlObjectManipulate::AddObjectL( CMdSSqLiteConnection& aConnection, 
       
  1337        CMdCSerializationBuffer& aBuffer,
       
  1338        RMdsStatement& aMdsBaseObjStatement, RMdsStatement& aMdsObjStatement,
       
  1339        const CMdSServerSession* aServerSession )
       
  1340 	{
       
  1341 	_LIT( KMdsObjectAddBaseObjectBegin, "INSERT INTO Object%u(ObjectId,ObjectDefId,Flags,MediaId,GuidHigh,GuidLow,URI" );
       
  1342 	_LIT( KMdsObjectAddBaseObjectMiddle, ") VALUES(?,?,?,?,?,?,?" );
       
  1343 	_LIT( KMdsObjectAddObjectBegin, "INSERT INTO %S%u(ObjectId" );
       
  1344 	_LIT( KMdsObjectAddObjectMiddle, ") VALUES(?" );
       
  1345 	_LIT( KMdsObjectAddObjectEnd,   ");" );
       
  1346 
       
  1347 	if ( !iNamespaceDef )
       
  1348 		{
       
  1349 		User::Leave( KErrMdEUnknownNamespaceDef );
       
  1350 		}
       
  1351 
       
  1352 	RRowData baseObjectRow;
       
  1353 	CleanupClosePushL( baseObjectRow );
       
  1354 	RRowData objectRow;
       
  1355 	CleanupClosePushL( objectRow );
       
  1356 
       
  1357 	const TMdCObject& object = TMdCObject::GetFromBufferL( aBuffer );
       
  1358 	// there must be at least one property (btw. base object have 7 properties)
       
  1359 	if (object.iProperties.iPtr.iCount < 1)
       
  1360 		{
       
  1361 		User::Leave( KErrMdEMandatoryPropertyMissing );
       
  1362 		}
       
  1363 
       
  1364 	// objectid
       
  1365 	if (object.iId != KNoId)
       
  1366 		{
       
  1367 		User::Leave( KErrAlreadyExists );
       
  1368 		}
       
  1369 
       
  1370 	RSQLIndex sqlIndex;
       
  1371 	CleanupClosePushL( sqlIndex );
       
  1372 	const TItemId objectId = sqlIndex.GetId();
       
  1373 
       
  1374 	baseObjectRow.AppendL( TColumn( objectId ) );
       
  1375 	objectRow.AppendL( TColumn( objectId ) );
       
  1376 
       
  1377 	// objectdefid
       
  1378 	const CMdsObjectDef* objectDef = iNamespaceDef->GetObjectByIdL( object.iDefId );
       
  1379 	if ( !objectDef )
       
  1380 		{
       
  1381 		// objectDef doesn't exist
       
  1382 		User::Leave( KErrMdEUnknownObjectDef );
       
  1383 		}
       
  1384 	baseObjectRow.AppendL( TColumn( object.iDefId ) );
       
  1385 
       
  1386 	// get BaseObjectDef
       
  1387 	iBaseObjectDef = iNamespaceDef->GetObjectByIdL( KBaseObjectDefId );
       
  1388 
       
  1389 	RClauseBuffer commonClauseOne(*this);
       
  1390 	CleanupClosePushL( commonClauseOne );
       
  1391 	CMdsClauseBuffer& clauseBaseObject = commonClauseOne.BufferL(); 
       
  1392 	RClauseBuffer commonClauseTwo(*this);
       
  1393 	CleanupClosePushL( commonClauseTwo );
       
  1394 	CMdsClauseBuffer& clauseObject = commonClauseTwo.BufferL(); 
       
  1395 
       
  1396 	const TDesC& objName = objectDef->GetName();
       
  1397 	if(objName != iLastAddedObjName)
       
  1398 	    {
       
  1399         iLastAddedObjName = objName;
       
  1400         aMdsBaseObjStatement.Close();
       
  1401         aMdsBaseObjStatement = RMdsStatement();
       
  1402 	    aMdsObjStatement.Close();
       
  1403         aMdsObjStatement = RMdsStatement();
       
  1404         }
       
  1405  
       
  1406     clauseObject.BufferL().Format( KMdsObjectAddObjectBegin, &objName, iNamespaceDef->GetId() );
       
  1407 	clauseBaseObject.BufferL().Format( KMdsObjectAddBaseObjectBegin, iNamespaceDef->GetId() );
       
  1408 
       
  1409 	TUint32 objectFlags = 0;
       
  1410 	if ( !( object.iFlags & ( EMdEObjectFlagModOpen | EMdEObjectFlagAutoLock ) ) )
       
  1411 		{
       
  1412 		User::Leave( KErrMdENotLocked );
       
  1413 		}
       
  1414 
       
  1415 	if (object.iFlags & EMdEObjectFlagConfidential) 
       
  1416 		{
       
  1417 		objectFlags |= EMdEObjectFlagConfidential;
       
  1418 		}
       
  1419 	if (object.iFlags & EMdEObjectFlagModFreeText)
       
  1420 		{
       
  1421 		objectFlags |= EMdEObjectFlagFreetexts;
       
  1422 		}
       
  1423 	if (object.iFlags & EMdEObjectFlagPlaceholder)
       
  1424 		{
       
  1425 		objectFlags |= EMdEObjectFlagPlaceholder;
       
  1426 		}
       
  1427 	if (objectDef->GetFlags() == CMdsObjectDef::EObjectDefFlagsContext)
       
  1428 		{
       
  1429 		objectFlags |= EMdEObjectFlagContext;
       
  1430 		}
       
  1431 	baseObjectRow.AppendL( TColumn( objectFlags ) );
       
  1432 
       
  1433 	// mediaId
       
  1434 	baseObjectRow.AppendL( TColumn( object.iMediaId ) );
       
  1435 
       
  1436 	TInt64 guidHigh = object.iGuidHigh;
       
  1437 	TInt64 guidLow = object.iGuidLow;
       
  1438 
       
  1439 	if (guidLow == 0 && guidHigh == 0)
       
  1440 		{
       
  1441 		iGenerator->GenerateGuid( guidHigh, guidLow );
       
  1442 		}
       
  1443 
       
  1444 	baseObjectRow.AppendL( TColumn( guidHigh ) );
       
  1445 	baseObjectRow.AppendL( TColumn( guidLow ) );
       
  1446 
       
  1447 	// uri
       
  1448 	HBufC* uriBuf = NULL;
       
  1449 	if (object.iUri.iPtr.iCount == 0)
       
  1450 		{
       
  1451 		uriBuf = iGenerator->GenerateUriL( *objectDef, guidHigh, guidLow );
       
  1452 		}
       
  1453 	else
       
  1454 		{
       
  1455 		aBuffer.PositionL( object.iUri.iPtr.iOffset );
       
  1456 		uriBuf = aBuffer.ReceiveDes16L();
       
  1457 		}
       
  1458 	CleanupStack::PushL( uriBuf );
       
  1459 	TPtr16 uri( uriBuf->Des() );
       
  1460 	uri.LowerCase();
       
  1461 	baseObjectRow.AppendL( TColumn( uri ) );
       
  1462 
       
  1463 	const TInt baseObjectRowSizeWithoutProperties = baseObjectRow.Size();
       
  1464 
       
  1465 	TInt mandatoryPropertyCount = objectDef->GetMandatoryPropertyCount();
       
  1466 	
       
  1467 	// try to add property
       
  1468 	for ( TUint32 i = 0; i < object.iProperties.iPtr.iCount; ++i )
       
  1469 		{
       
  1470 		aBuffer.PositionL( object.iProperties.iPtr.iOffset + i * sizeof(TMdCProperty) );
       
  1471 		TUint8 modFlags;
       
  1472 		const CMdsPropertyDef& propertyDef = ReadPropertyL( aBuffer, *objectDef, clauseBaseObject, clauseObject, baseObjectRow, objectRow, modFlags );
       
  1473 		if ( modFlags == EMdEPropertyModNone )
       
  1474 			{
       
  1475 			continue;
       
  1476 			}
       
  1477 
       
  1478 		// check if mandatory property is removed
       
  1479 		if( propertyDef.GetMandatory() )
       
  1480 			{
       
  1481 			if( modFlags & EMdEPropertyModRemove )
       
  1482 				{
       
  1483 				User::Leave( KErrMdEMandatoryPropertyMissing );
       
  1484 				}
       
  1485 			else
       
  1486 				{
       
  1487 				--mandatoryPropertyCount;
       
  1488 				}
       
  1489 			}
       
  1490 		}
       
  1491 
       
  1492 	if( mandatoryPropertyCount != 0 )
       
  1493 		{
       
  1494 		User::Leave( KErrMdEMandatoryPropertyMissing );
       
  1495 		}
       
  1496 
       
  1497 	clauseBaseObject.AppendL( KMdsObjectAddBaseObjectMiddle );
       
  1498 
       
  1499 	const TInt baseObjectPropertyCount = baseObjectRow.Size() - 
       
  1500 		baseObjectRowSizeWithoutProperties;
       
  1501 
       
  1502 	for ( TInt i = 0; i < baseObjectPropertyCount; ++i )
       
  1503 		{
       
  1504 		clauseBaseObject.AppendL( KComma );
       
  1505 		clauseBaseObject.AppendL( KVariable );
       
  1506 		}
       
  1507 
       
  1508 	clauseObject.AppendL( KMdsObjectAddObjectMiddle );
       
  1509 
       
  1510 	// object row property count (object row size without object ID)
       
  1511 	const TInt objectPropertyCount = objectRow.Size() - 1;
       
  1512 
       
  1513 	for ( TInt i = 0; i < objectPropertyCount; ++i )
       
  1514 		{
       
  1515 		clauseObject.AppendL( KComma );
       
  1516 		clauseObject.AppendL( KVariable );
       
  1517 		}
       
  1518 	
       
  1519 	clauseBaseObject.AppendL( KMdsObjectAddObjectEnd );
       
  1520 	clauseObject.AppendL( KMdsObjectAddObjectEnd );
       
  1521 
       
  1522 	// EVERYTHING IS OK - add object to DB
       
  1523 
       
  1524 	TInt queryResult = 0, err;
       
  1525 	// add base object properties
       
  1526 	__LOGQUERY_16( _L("Add BaseObject to DB:"), clauseBaseObject.ConstBufferL(), baseObjectRow);
       
  1527 	TRAP( err, aConnection.ExecuteL( clauseBaseObject.ConstBufferL(), baseObjectRow, &aMdsBaseObjStatement ) );
       
  1528 	if (err == KSqlErrConstraint)
       
  1529 		{
       
  1530 		__LOG1( ELogQuery, "Adding baseObject constraint error - err:%d", err );
       
  1531 		TRAP_IGNORE( RemoveObjectForceL( uri, KNoId ) );
       
  1532 		__LOGQUERY_16( _L("Add AGAIN BaseObject to DB:"), clauseBaseObject.ConstBufferL(), baseObjectRow);
       
  1533 		TRAP( err, aConnection.ExecuteL( clauseBaseObject.ConstBufferL(), baseObjectRow, &aMdsBaseObjStatement ) );
       
  1534 		}
       
  1535 
       
  1536 	if (err != KErrNone)
       
  1537 		{
       
  1538 		__LOG1( ELogQuery, "Adding baseObject failed - err:%d", err );
       
  1539 		User::Leave( KErrGeneral );
       
  1540 		}
       
  1541 
       
  1542 	if( !( // skip if object definition is "base object"
       
  1543 		   // and object is placeholder
       
  1544 			(object.iDefId == KBaseObjectDefId) &&
       
  1545 			(object.iFlags & EMdEObjectFlagPlaceholder)
       
  1546 		 ) 
       
  1547 	  )
       
  1548 		{	
       
  1549 		__LOGQUERY_16( _L("Add Object to DB:"), clauseObject.ConstBufferL(), 
       
  1550 				objectRow);
       
  1551 		TRAP( err, queryResult = aConnection.ExecuteL( 
       
  1552 		        clauseObject.ConstBufferL(), objectRow, &aMdsObjStatement ) );
       
  1553 		if (err != KErrNone || queryResult != 1)
       
  1554 			{
       
  1555 			__LOG2( ELogQuery, "Adding object failed - err:%d, queryResult:%d", err, queryResult );
       
  1556 			TRAP_IGNORE( RemoveObjectForceL( objectId ) );
       
  1557 			User::Leave( err );
       
  1558 			}
       
  1559 		}
       
  1560 
       
  1561 	CleanupStack::PopAndDestroy( uriBuf );
       
  1562 	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // commonClauseTwo, commonClauseOne
       
  1563 
       
  1564 	// add freetext to DB
       
  1565 	if ( object.iFreeTexts.iPtr.iCount > 0 )
       
  1566 		{
       
  1567 		aBuffer.PositionL( object.iFreeTexts.iPtr.iOffset );
       
  1568 		TRAP( err, AddFreeTextL( aBuffer, object.iFreeTexts.iPtr.iCount, objectId ) );
       
  1569 		if (err != KErrNone)
       
  1570 			{
       
  1571 			__LOG1( ELogQuery, "Adding object freetext failed - err:%d", err );
       
  1572 			TRAP_IGNORE( RemoveObjectForceL( objectId ) );
       
  1573 			User::Leave( err );
       
  1574 			}
       
  1575 		}
       
  1576 
       
  1577 	sqlIndex.Commit();
       
  1578 	CleanupStack::PopAndDestroy( &sqlIndex );
       
  1579 	CleanupStack::PopAndDestroy( 2, &baseObjectRow ); // objectRow, baseObjectRow
       
  1580 
       
  1581 	if( ( object.iFlags & EMdEObjectFlagAutoLock ) && aServerSession )
       
  1582 		{
       
  1583 		iLockList.LockObjectL( *aServerSession, *iNamespaceDef, objectId );
       
  1584 		}
       
  1585 	
       
  1586 	return objectId;
       
  1587 	}
       
  1588 
       
  1589 TUint32 CMdSSqlObjectManipulate::AddFreeTextToDBL( TPtrC16& aWord, TItemId aObjectId,
       
  1590     TInt32 aPosition, TBool aSearch )
       
  1591 	{
       
  1592 	_LIT( KMdsFreeTextAdd, "INSERT INTO TextSearch%d(WordId,ObjectId,Position) VALUES(?,?,?)" );
       
  1593 	_LIT( KMdsFreeTextDictAdd, "INSERT INTO TextSearchDictionary%d(Word) VALUES(?)" );
       
  1594 
       
  1595 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  1596 
       
  1597 	RClauseBuffer commonClauseOne(*this);
       
  1598 	CleanupClosePushL( commonClauseOne );
       
  1599 	CMdsClauseBuffer& freeTextAdd     = commonClauseOne.BufferL(); 
       
  1600 	RClauseBuffer commonClauseTwo(*this);
       
  1601 	CleanupClosePushL( commonClauseTwo );
       
  1602 	CMdsClauseBuffer& freeTextDictAdd = commonClauseTwo.BufferL();
       
  1603 
       
  1604 	freeTextAdd.BufferL().Format( KMdsFreeTextAdd, iNamespaceDef->GetId() );
       
  1605 	freeTextDictAdd.BufferL().Format( KMdsFreeTextDictAdd, iNamespaceDef->GetId() );
       
  1606 
       
  1607 	TItemId freeTextId = KNoId;
       
  1608 	RRowData freeTextRow;
       
  1609 	CleanupClosePushL( freeTextRow );
       
  1610 	RRowData freeTextRowDict;
       
  1611 	CleanupClosePushL( freeTextRowDict );
       
  1612 
       
  1613 	freeTextRow.ReserveL( 3 );
       
  1614 
       
  1615 	freeTextRow.AppendL( TColumn(KNoId) );
       
  1616 	freeTextRow.AppendL( TColumn(aObjectId) );
       
  1617 	freeTextRow.AppendL( TColumn(aPosition) );
       
  1618 
       
  1619     freeTextId = FindFreeTextInDbL( aWord );
       
  1620 	if ( aSearch && freeTextId )
       
  1621 		{
       
  1622 		freeTextRow.Column(0).Set( freeTextId );
       
  1623 		__LOGQUERY_16( _L("Add FreeText index to DB:"), 
       
  1624 				freeTextAdd.ConstBufferL(), freeTextRow);
       
  1625 		connection.ExecuteL( freeTextAdd.ConstBufferL(), freeTextRow );
       
  1626 		}
       
  1627 	else
       
  1628 		{
       
  1629 		freeTextRowDict.AppendL( TColumn( aWord ) );
       
  1630 		__LOGQUERY_16( _L("Add FreeText to DB:"), 
       
  1631 				freeTextDictAdd.ConstBufferL(), freeTextRowDict);
       
  1632 		TRAPD( err, freeTextId = MMdSIndexer::ExecuteAndGetIndexL( 
       
  1633 				freeTextDictAdd.ConstBufferL(), freeTextRowDict ) );
       
  1634 		if (err != KErrNone || freeTextId == KNoId)
       
  1635 			{
       
  1636 			__LOG2( ELogQuery, "Adding freetextDict failed - err:%d, freeTextId:%d", 
       
  1637 					err, freeTextId );
       
  1638 			User::Leave( KErrGeneral );
       
  1639 			}
       
  1640 		
       
  1641 		freeTextRow.Column(0).Set( freeTextId );
       
  1642 		connection.ExecuteL( freeTextAdd.ConstBufferL(), freeTextRow );
       
  1643 		}
       
  1644 
       
  1645 	CleanupStack::PopAndDestroy( 4, &commonClauseOne ); // freeTextRowDict, freeTextRow, commonClauseTwo, commonClauseOne
       
  1646 	return freeTextId;
       
  1647 	}
       
  1648 
       
  1649 TInt CMdSSqlObjectManipulate::AddFreeTextL( CMdCSerializationBuffer& aBuffer, TInt aFreeTextCount, TItemId aObjectId )
       
  1650 	{
       
  1651 	TInt freeTextAdded = 0;
       
  1652 
       
  1653 	for ( TUint32 i = 0; i < aFreeTextCount; ++i )
       
  1654 		{
       
  1655 		TPtrC16 freeText = aBuffer.ReceivePtr16L();
       
  1656 		AddFreeTextToDBL( freeText, aObjectId, i );
       
  1657 		++freeTextAdded;
       
  1658 		}
       
  1659 	return freeTextAdded;
       
  1660 	}
       
  1661 
       
  1662 TItemId CMdSSqlObjectManipulate::FindFreeTextInDbL( TPtrC16 aFreeText )
       
  1663 	{
       
  1664 	_LIT( KMdsFreeTextSearch, "SELECT WordId FROM TextSearchDictionary%d WHERE Word=? LIMIT 1;" );
       
  1665 	
       
  1666 	RClauseBuffer commonClauseOne(*this, KMdsFreeTextSearch.iTypeLength + KMaxUintValueLength);
       
  1667 	CleanupClosePushL( commonClauseOne );
       
  1668 	CMdsClauseBuffer& freeTextSearchClause = commonClauseOne.BufferL();
       
  1669 	freeTextSearchClause.BufferL().Format( KMdsFreeTextSearch, iNamespaceDef->GetId() );
       
  1670 
       
  1671 	TItemId freeTextId = 0;
       
  1672 	RRowData wordRow;
       
  1673 	CleanupClosePushL( wordRow );
       
  1674 	RRowData idRow;
       
  1675 	CleanupClosePushL( idRow );
       
  1676 	RMdsStatement query;
       
  1677 	CleanupClosePushL( query );
       
  1678 	
       
  1679 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  1680 
       
  1681 	wordRow.AppendL( TColumn( aFreeText ) );
       
  1682 	idRow.AppendL( TColumn( freeTextId ) );
       
  1683 	connection.ExecuteQueryL( freeTextSearchClause.ConstBufferL(), query, wordRow );
       
  1684 	if( connection.NextRowL( query, idRow ) )
       
  1685 		{
       
  1686 		idRow.Column( 0 ).Get( freeTextId );
       
  1687 		}
       
  1688 
       
  1689 	CleanupStack::PopAndDestroy( 4, &commonClauseOne ); // query, idRow, wordRow, commonClauseOne
       
  1690 	return freeTextId;
       
  1691 	}
       
  1692 
       
  1693 void CMdSSqlObjectManipulate::RemoveObjectForceL( const TDesC16& aUri, TItemId aObjectId )
       
  1694 	{
       
  1695 	_LIT( KMdsRemoveObjectByUri, "DELETE FROM Object%u WHERE Flags&? AND ObjectId!=? AND URI=?;" );
       
  1696 
       
  1697 	if ( !iNamespaceDef )
       
  1698 		{
       
  1699 		User::Leave( KErrMdEUnknownNamespaceDef );
       
  1700 		}
       
  1701 
       
  1702 	RClauseBuffer commonClauseOne(*this, KMdsRemoveObjectByUri.iTypeLength + KMaxUintValueLength);
       
  1703 	CleanupClosePushL( commonClauseOne );
       
  1704 	CMdsClauseBuffer& removeObjectClause = commonClauseOne.BufferL();
       
  1705 
       
  1706 	removeObjectClause.BufferL().Format( KMdsRemoveObjectByUri, 
       
  1707 			iNamespaceDef->GetId() );
       
  1708 
       
  1709 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  1710 
       
  1711     // do remove
       
  1712     RRowData varRemove;
       
  1713     CleanupClosePushL( varRemove );
       
  1714     varRemove.AppendL( TColumn( EMdEObjectFlagRemoved ) );
       
  1715     varRemove.AppendL( TColumn( aObjectId ) );
       
  1716     varRemove.AppendL( TColumn( aUri ) );
       
  1717 
       
  1718 #ifdef _DEBUG    
       
  1719 #ifdef LOG_MASTER_FLAG
       
  1720 	TInt queryResult = 0; // For debug
       
  1721 	__LOGQUERY_16( _L("Remove FORCE object using URI:"), 
       
  1722 			removeObjectClause.ConstBufferL(), varRemove);
       
  1723 	TRAPD( err, queryResult = connection.ExecuteL( 
       
  1724 			removeObjectClause.ConstBufferL(), varRemove ) );
       
  1725 	if( err != KErrNone )
       
  1726 		{
       
  1727 		__LOG2( ELogQuery, "Remove FORCE object err:%d, queryResult:%d", err, queryResult );
       
  1728 		}
       
  1729 #else
       
  1730     TRAP_IGNORE( connection.ExecuteL( removeObjectClause.ConstBufferL(), varRemove ) );
       
  1731 #endif // LOG_MASTER_FLAG
       
  1732 #else
       
  1733     TRAP_IGNORE( connection.ExecuteL( removeObjectClause.ConstBufferL(), varRemove ) );    
       
  1734 #endif // _DEBUG
       
  1735 	
       
  1736 	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // varRemove, commonClauseOne
       
  1737 	}
       
  1738 
       
  1739 // USE WITH CAUTION !!!
       
  1740 // THIS FUNCTION REMOVES OBJECT WITHOUT ANY CHECKING
       
  1741 // ONLY FOR INTERNAL USE !!!
       
  1742 void CMdSSqlObjectManipulate::RemoveObjectForceL( TItemId aObjectId )
       
  1743 	{
       
  1744 	_LIT( KMdsRemoveObjectById, "DELETE FROM Object%u WHERE ObjectId=?;" );
       
  1745 
       
  1746 	if ( !iNamespaceDef )
       
  1747 		{
       
  1748 		User::Leave( KErrMdEUnknownNamespaceDef );
       
  1749 		}
       
  1750 
       
  1751 	RClauseBuffer commonClauseOne(*this,  KMdsRemoveObjectById.iTypeLength + KMaxUintValueLength );
       
  1752 	CleanupClosePushL( commonClauseOne );
       
  1753 	CMdsClauseBuffer& removeObjectClause = commonClauseOne.BufferL();
       
  1754 
       
  1755 	removeObjectClause.BufferL().Format( KMdsRemoveObjectById, iNamespaceDef->GetId() );
       
  1756 
       
  1757 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  1758 
       
  1759     // do remove
       
  1760     RRowData varRemove;
       
  1761     CleanupClosePushL( varRemove );
       
  1762     varRemove.AppendL( TColumn( aObjectId ) );
       
  1763 
       
  1764 #ifdef _DEBUG    
       
  1765 #ifdef LOG_MASTER_FLAG
       
  1766 	TInt queryResult = 0; // For debug
       
  1767 	__LOGQUERY_16( _L("Remove object using ID:"), 
       
  1768 			removeObjectClause.ConstBufferL(), varRemove);
       
  1769 	TRAPD( err, queryResult = connection.ExecuteL( 
       
  1770 			removeObjectClause.ConstBufferL(), varRemove ) );
       
  1771 	if ( err != KErrNone )
       
  1772 		{
       
  1773 		__LOG2( ELogQuery, "Remove FORCE Object err:%d, queryResult:%d", err, queryResult );
       
  1774 		}
       
  1775 #else
       
  1776     TRAP_IGNORE( connection.ExecuteL( removeObjectClause.ConstBufferL(), varRemove ) );
       
  1777 #endif // LOG_MASTER_FLAG
       
  1778 #else
       
  1779     TRAP_IGNORE( connection.ExecuteL( removeObjectClause.ConstBufferL(), varRemove ) );  
       
  1780 #endif // _DEBUG
       
  1781     
       
  1782 	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // varRemove, commonClauseOne
       
  1783 	}
       
  1784 
       
  1785 CMdCSerializationBuffer* CMdSSqlObjectManipulate::CheckObjectL( TInt aResultBufferSize, 
       
  1786 		const TDesC& aUri, TDefId aNamespaceDefId )
       
  1787 	{
       
  1788 	_LIT( KMdsCheckObjectByUri, "SELECT ObjectId, ObjectDefId, Flags FROM Object%u WHERE URI=?;" );
       
  1789 
       
  1790 	RClauseBuffer commonClauseOne(*this, KMdsCheckObjectByUri.iTypeLength + KMaxUintValueLength);
       
  1791 	CleanupClosePushL( commonClauseOne );
       
  1792 	CMdsClauseBuffer& checkObjectClause = commonClauseOne.BufferL();
       
  1793 
       
  1794 	checkObjectClause.BufferL().Format( KMdsCheckObjectByUri, aNamespaceDefId );
       
  1795 
       
  1796     RRowData rowData;
       
  1797     CleanupClosePushL( rowData );
       
  1798     rowData.AppendL( TColumn( aUri ) );
       
  1799     
       
  1800     RMdsStatement query;
       
  1801 	CleanupClosePushL( query );
       
  1802 
       
  1803 	CMdSSqLiteConnection& db = MMdSDbConnectionPool::GetDefaultDBL();
       
  1804 
       
  1805 	db.ExecuteQueryL( checkObjectClause.ConstBufferL(), query, rowData );
       
  1806 
       
  1807 	rowData.Free();	rowData.Reset();
       
  1808 	rowData.ReserveL( 3 ); // space for SELECTs
       
  1809 
       
  1810 	TMdCObject object;
       
  1811     rowData.AppendL( TColumn( object.iId ) );
       
  1812     rowData.AppendL( TColumn( object.iDefId ) );
       
  1813     rowData.AppendL( TColumn( object.iFlags ) );
       
  1814 
       
  1815     CMdCSerializationBuffer* buffer = NULL;
       
  1816 	if ( db.NextRowL( query, rowData ) )
       
  1817 		{
       
  1818 		rowData.Column(0).Get( object.iId );
       
  1819 		rowData.Column(1).Get( object.iDefId );
       
  1820 		rowData.Column(2).Get( object.iFlags );
       
  1821 
       
  1822 		buffer = CMdCSerializationBuffer::NewLC( aResultBufferSize );
       
  1823 		object.SerializeL( *buffer );
       
  1824 		CleanupStack::Pop( buffer );
       
  1825 		}
       
  1826 	else
       
  1827 		{
       
  1828 		User::Leave( KErrNotFound );
       
  1829 		}
       
  1830 
       
  1831 	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // query, rowData, commonClauseOne
       
  1832 
       
  1833 	return buffer;
       
  1834 	}
       
  1835 
       
  1836 CMdCSerializationBuffer* CMdSSqlObjectManipulate::CheckObjectL( TInt aResultBufferSize, 
       
  1837 		TItemId aId, TDefId aNamespaceDefId )
       
  1838 	{
       
  1839 	_LIT( KMdsCheckObjectById, "SELECT ObjectDefId, Flags FROM Object%u WHERE ObjectId=?;" );
       
  1840 
       
  1841 	RClauseBuffer commonClauseOne(*this, KMdsCheckObjectById.iTypeLength + KMaxUintValueLength);
       
  1842 	CleanupClosePushL( commonClauseOne );
       
  1843 	CMdsClauseBuffer& checkObjectClause = commonClauseOne.BufferL();
       
  1844 
       
  1845 	checkObjectClause.BufferL().Format( KMdsCheckObjectById, aNamespaceDefId );
       
  1846 	
       
  1847     RRowData rowData;
       
  1848     CleanupClosePushL( rowData );
       
  1849     rowData.AppendL( TColumn( aId ) );
       
  1850 
       
  1851     RMdsStatement query;
       
  1852 	CleanupClosePushL( query );
       
  1853 
       
  1854 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  1855 
       
  1856 	connection.ExecuteQueryL( checkObjectClause.ConstBufferL(), query, rowData );
       
  1857 
       
  1858 	rowData.Free();	rowData.Reset();
       
  1859 	rowData.ReserveL( 2 ); // space for SELECTs
       
  1860 
       
  1861 	TMdCObject object;
       
  1862 	object.iId = aId;
       
  1863     rowData.AppendL( TColumn( object.iDefId ) );
       
  1864     rowData.AppendL( TColumn( object.iFlags ) );
       
  1865 
       
  1866     CMdCSerializationBuffer* buffer = NULL;
       
  1867 	if ( connection.NextRowL( query, rowData ) )
       
  1868 		{
       
  1869 		rowData.Column(0).Get( object.iDefId );
       
  1870 		rowData.Column(1).Get( object.iFlags );
       
  1871 
       
  1872 		buffer = CMdCSerializationBuffer::NewLC( aResultBufferSize );
       
  1873 		object.SerializeL( *buffer );
       
  1874 		CleanupStack::Pop( buffer );
       
  1875 		}
       
  1876 	else
       
  1877 		{
       
  1878 		User::Leave( KErrNotFound );
       
  1879 		}
       
  1880 
       
  1881 	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // query, rowData, commonClauseOne
       
  1882 
       
  1883 	return buffer;
       
  1884 	}
       
  1885 
       
  1886 CMdCSerializationBuffer* CMdSSqlObjectManipulate::CheckObjectL( TInt aResultBufferSize, 
       
  1887 		CMdCSerializationBuffer& aIds, TDefId aNamespaceDefId )
       
  1888 	{
       
  1889 
       
  1890 	aIds.PositionL( KNoOffset );
       
  1891 	TUint32 idCount = 0;
       
  1892 	aIds.ReceiveL( idCount );
       
  1893 
       
  1894 	// if no IDs, just return 0 objects
       
  1895 	if( idCount == 0 )
       
  1896 		{
       
  1897 		CMdCSerializationBuffer* buffer = 
       
  1898 			CMdCSerializationBuffer::NewLC( CMdCSerializationBuffer::KRequiredSizeForTUint32 );
       
  1899 		buffer->InsertL( idCount );
       
  1900 		return buffer;
       
  1901 		}
       
  1902 
       
  1903 	_LIT( KMdsCheckObjectByIds, "SELECT ObjectId, ObjectDefId, Flags FROM Object%u WHERE ObjectId IN(?" );
       
  1904 	_LIT( KMdsCheckObjectByIdsAppend, ",?" );
       
  1905 	_LIT( KMdsCheckObjectByIdsEnd, ");" );
       
  1906 
       
  1907 	RClauseBuffer commonClauseOne(*this, KMdsCheckObjectByIds.iTypeLength + KMaxUintValueLength + 
       
  1908 										 KMdsCheckObjectByIdsAppend.iTypeLength * (idCount - 1) + 
       
  1909 										 KMdsCheckObjectByIdsEnd.iTypeLength);
       
  1910 	CleanupClosePushL( commonClauseOne );
       
  1911 	CMdsClauseBuffer& checkObjectClause = commonClauseOne.BufferL();
       
  1912 	
       
  1913 	RRowData rowData;
       
  1914 	CleanupClosePushL( rowData );
       
  1915 
       
  1916 	checkObjectClause.BufferL().Format( KMdsCheckObjectByIds, aNamespaceDefId );
       
  1917 	TItemId id;
       
  1918 	aIds.ReceiveL( id );
       
  1919 	rowData.AppendL( TColumn( id ) );
       
  1920 	
       
  1921 	for( TUint32 i = 1; i < idCount; i++ )
       
  1922 		{
       
  1923 		checkObjectClause.BufferL().Append( KMdsCheckObjectByIdsAppend );
       
  1924 		aIds.ReceiveL( id );
       
  1925 		rowData.AppendL( TColumn( id ) );
       
  1926 		}
       
  1927 
       
  1928 	checkObjectClause.BufferL().Append( KMdsCheckObjectByIdsEnd );
       
  1929 
       
  1930 	RMdsStatement query;
       
  1931 	CleanupClosePushL( query );
       
  1932 
       
  1933 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  1934 
       
  1935 	connection.ExecuteQueryL( checkObjectClause.ConstBufferL(), query, rowData );
       
  1936 
       
  1937 	CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC( aResultBufferSize );
       
  1938 	
       
  1939 	// initialize with 0 objects (will be updated later)
       
  1940 	TUint32 resultObjectCount = 0;
       
  1941 	buffer->InsertL( resultObjectCount );
       
  1942 
       
  1943 	rowData.Free();
       
  1944 	rowData.Reset();
       
  1945 
       
  1946 	rowData.ReserveL( 3 ); // space for SELECT's object
       
  1947 	
       
  1948 	TMdCObject object;
       
  1949 	rowData.AppendL( TColumn( object.iId ) );
       
  1950 	rowData.AppendL( TColumn( object.iDefId ) );
       
  1951 	rowData.AppendL( TColumn( object.iFlags ) );
       
  1952 
       
  1953 	while( connection.NextRowL( query, rowData ) )
       
  1954 		{
       
  1955 		rowData.Column(0).Get( object.iId );
       
  1956 		rowData.Column(1).Get( object.iDefId );
       
  1957 		rowData.Column(2).Get( object.iFlags );
       
  1958 
       
  1959 		object.SerializeL( *buffer );
       
  1960 		++resultObjectCount;
       
  1961 		}
       
  1962 
       
  1963 	// update object count
       
  1964 	buffer->PositionL( KNoOffset );
       
  1965 	buffer->InsertL( resultObjectCount );
       
  1966 
       
  1967 	CleanupStack::Pop( buffer );
       
  1968 	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // query, rowData, commonClauseOne
       
  1969 	
       
  1970 	return buffer;
       
  1971 	}
       
  1972 
       
  1973 static TInt CompareTItemIds( const TItemId& aLeft, const TItemId& aRight )
       
  1974 	{
       
  1975 	return aLeft - aRight;
       
  1976 	}
       
  1977 
       
  1978 void CMdSSqlObjectManipulate::CollectRemovedItemsL( RArray<TItemId>& aRemoveIds, RArray<TItemId>& aObjectIds,
       
  1979                                                     RArray<TItemId>& aRelationIds, RArray<TItemId>& /*aEventIds*/ )
       
  1980 	{
       
  1981 	_LIT( KCollectGetDeleteId,          "SELECT O.ObjectId, R.RelationId FROM Object%u AS O LEFT JOIN Relations%u AS R ON O.ObjectId=R.LeftObjectId OR O.ObjectId=R.RightObjectId WHERE NOT O.Flags&? AND ObjectId IN(?" );
       
  1982 	_LIT( KCollectUpdateObjectBegin,    "UPDATE Object%u SET Flags=Flags|? WHERE ObjectId IN(?" );
       
  1983 	_LIT( KCollectUpdateRelationsBegin, "UPDATE Relations%u SET Flags=Flags|? WHERE RelationId IN(?" );
       
  1984 	_LIT( KCollectMiddle, ",?" );
       
  1985 	_LIT( KCollectEnd,    ");" );
       
  1986 
       
  1987 	const TInt removeIdsCount = aRemoveIds.Count();
       
  1988 	if (removeIdsCount < 1)
       
  1989 		{
       
  1990 		return;
       
  1991 		}
       
  1992 
       
  1993 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  1994 	RClauseBuffer commonClauseOne(*this,  KCollectGetDeleteId().Length() + 2 * KMaxUintValueLength +
       
  1995 											(removeIdsCount-1) * KCollectMiddle().Length() +
       
  1996 											KCollectEnd().Length());
       
  1997 	CleanupClosePushL( commonClauseOne );
       
  1998 	CMdsClauseBuffer& buffer = commonClauseOne.BufferL();
       
  1999 
       
  2000 	// getting removed object id and relation id
       
  2001 	RRowData dataRow;
       
  2002 	CleanupClosePushL( dataRow );
       
  2003 	dataRow.ReserveL( removeIdsCount );
       
  2004 	dataRow.AppendL( TColumn( EMdEObjectFlagRemoved ) );
       
  2005 	buffer.BufferL().Format( KCollectGetDeleteId, iNamespaceDef->GetId(), iNamespaceDef->GetId() );
       
  2006 	for (TInt i = 0; i < removeIdsCount; ++i)
       
  2007 		{
       
  2008 		if(i>0)
       
  2009 			{
       
  2010 			buffer.AppendL( KCollectMiddle );
       
  2011 			}
       
  2012 		dataRow.AppendL( TColumn( aRemoveIds[i] ) );
       
  2013 		}
       
  2014 	buffer.AppendL( KCollectEnd );
       
  2015 
       
  2016 	RMdsStatement objectQuery;
       
  2017 	CleanupClosePushL( objectQuery );
       
  2018 
       
  2019 	__LOGQUERY_16( _L("Find objects to delete:"), buffer.ConstBufferL(), dataRow);
       
  2020 	connection.ExecuteQueryL( buffer.ConstBufferL(), objectQuery, dataRow );
       
  2021 
       
  2022 	dataRow.Free();	dataRow.Reset();
       
  2023 	TItemId objectId = KNoId;
       
  2024     TItemId prevId = objectId;
       
  2025     TItemId relationId = KNoId;
       
  2026 	dataRow.AppendL( TColumn( objectId ) );
       
  2027 	dataRow.AppendL( TColumn( relationId ) );
       
  2028 	while ( connection.NextRowL( objectQuery, dataRow ) )
       
  2029 		{
       
  2030 		dataRow.Column(0).Get( objectId );
       
  2031 		if (objectId != prevId)
       
  2032 			{
       
  2033 			aObjectIds.AppendL( objectId );
       
  2034 			prevId = objectId;
       
  2035 			}
       
  2036 		if (!dataRow.Column(1).IsNull())
       
  2037 			{
       
  2038 			dataRow.Column(1).Get( relationId );
       
  2039 			aRelationIds.InsertInOrder( relationId, TLinearOrder<TItemId>( CompareTItemIds ) );
       
  2040 			}
       
  2041 		else
       
  2042 			{
       
  2043 			dataRow.Column(1).Set( relationId );
       
  2044 			}
       
  2045 		}
       
  2046 
       
  2047 	// mark object's as removed
       
  2048 	// remove only item that are OK to remove (not removed earlier)
       
  2049 	const TInt removeObjectCount = aObjectIds.Count();
       
  2050 	if ( removeObjectCount > 0 )
       
  2051 		{
       
  2052 		buffer.ReserveSpaceL( KCollectUpdateObjectBegin().Length() + KMaxUintValueLength +
       
  2053 							   (removeObjectCount-1) * KCollectMiddle().Length() +
       
  2054 							   KCollectEnd().Length() );
       
  2055 
       
  2056 		buffer.BufferL().Format( KCollectUpdateObjectBegin, iNamespaceDef->GetId() );
       
  2057 
       
  2058 		dataRow.Free();
       
  2059 		dataRow.Reset();
       
  2060 		dataRow.AppendL( TColumn( EMdEObjectFlagRemoved ) );
       
  2061 
       
  2062 		for (TInt i = 0; i < removeObjectCount; ++i)
       
  2063 			{
       
  2064 			if(i>0)
       
  2065 				{
       
  2066 				buffer.AppendL( KCollectMiddle );
       
  2067 				}
       
  2068 			dataRow.AppendL( TColumn( aObjectIds[i] ) );
       
  2069 			}
       
  2070 		buffer.AppendL( KCollectEnd );
       
  2071 
       
  2072 		__LOGQUERY_16( _L("Remove objects:"), buffer.ConstBufferL(), dataRow);
       
  2073 		connection.ExecuteL( buffer.ConstBufferL(), dataRow );
       
  2074 		}
       
  2075 
       
  2076 	// mark relations as removed
       
  2077 	// remove only item that are OK to remove (not removed earlier)
       
  2078 	const TInt removeRelationCount = aRelationIds.Count();
       
  2079 	if ( removeRelationCount > 0 )
       
  2080 		{
       
  2081 		buffer.ReserveSpaceL( KCollectUpdateRelationsBegin().Length() + KMaxUintValueLength +
       
  2082 							   (removeRelationCount-1) * KCollectMiddle().Length() +
       
  2083 							   KCollectEnd().Length() );
       
  2084 
       
  2085 		buffer.BufferL().Format( KCollectUpdateRelationsBegin, iNamespaceDef->GetId() );
       
  2086 
       
  2087 		dataRow.Free();	dataRow.Reset();
       
  2088 		dataRow.ReserveL( 1 + removeRelationCount );
       
  2089 		dataRow.AppendL( TColumn( EMdERelationFlagDeleted ) );
       
  2090 
       
  2091 		for ( TInt i = 0; i < removeRelationCount; ++i )
       
  2092 			{
       
  2093 			if( i > 0 )
       
  2094 				{
       
  2095 				buffer.AppendL( KCollectMiddle );
       
  2096 				}
       
  2097 			dataRow.AppendL( TColumn( aRelationIds[i] ) );
       
  2098 			}
       
  2099 		buffer.AppendL( KCollectEnd );
       
  2100 
       
  2101 		__LOGQUERY_16( _L("Remove relations:"), buffer.ConstBufferL(), dataRow);
       
  2102 		connection.ExecuteL( buffer.ConstBufferL(), dataRow );
       
  2103 		}
       
  2104 
       
  2105 
       
  2106 	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // objectQuery, dataRow, commonClauseOne
       
  2107 	}
       
  2108 
       
  2109 void CMdSSqlObjectManipulate::RemoveObjectsByIdL( 
       
  2110 		CMdCSerializationBuffer& aBuffer, TInt aCount, RArray<TItemId>& aIdArray, 
       
  2111 		RArray<TItemId>& aRelationIds, RArray<TItemId>& aEventIds )
       
  2112 	{
       
  2113 	if ( !iNamespaceDef )
       
  2114 		{
       
  2115 		User::Leave( KErrMdEUnknownNamespaceDef );
       
  2116 		}
       
  2117 
       
  2118 	RArray<TItemId> objectIds;
       
  2119 	CleanupClosePushL( objectIds );
       
  2120 
       
  2121 	TItemId objectId = KNoId;
       
  2122 
       
  2123 	objectIds.ReserveL( aCount );
       
  2124 	for (TUint32 i = 0; i < aCount; ++i)
       
  2125 		{
       
  2126 		aBuffer.ReceiveL( objectId );
       
  2127 		if ( objectId != KNoId )
       
  2128 			{
       
  2129 			if ( iLockList.IsLocked( *iNamespaceDef, objectId ) )
       
  2130 				{
       
  2131 				iLockList.UnlockById( *iNamespaceDef, objectId );
       
  2132 				}
       
  2133 
       
  2134 			objectIds.AppendL( objectId );
       
  2135 			}
       
  2136 		}
       
  2137 
       
  2138 	CollectRemovedItemsL( objectIds, aIdArray, aRelationIds, aEventIds );
       
  2139 
       
  2140     CleanupStack::PopAndDestroy( &objectIds );
       
  2141 	}
       
  2142 
       
  2143 void CMdSSqlObjectManipulate::RemoveObjectsByUriL( 
       
  2144 		CMdCSerializationBuffer& aBuffer, TInt aCount, RArray<TItemId>& aIdArray,
       
  2145         RArray<TItemId>& aRelationIds, RArray<TItemId>& aEventIds )
       
  2146 	{
       
  2147 	if ( !iNamespaceDef )
       
  2148 		{
       
  2149 		User::Leave( KErrMdEUnknownNamespaceDef );
       
  2150 		}
       
  2151 
       
  2152 	RArray<TItemId> objectIds;
       
  2153 	CleanupClosePushL( objectIds );
       
  2154 
       
  2155 	TUint32 flags;
       
  2156 	TItemId objectId = KNoId;
       
  2157 	objectIds.ReserveL( aCount );
       
  2158 	for (TUint32 i = 0; i < aCount; ++i)
       
  2159 		{
       
  2160 		TPtrC16 uri = aBuffer.ReceivePtr16L();
       
  2161         objectId = SearchObjectByUriL( uri, flags );
       
  2162 		if ( objectId != KNoId )
       
  2163 			{
       
  2164 			// unlock object, so update is no possible anymore
       
  2165 			if ( iLockList.IsLocked( *iNamespaceDef, objectId ) )
       
  2166 				{
       
  2167 				iLockList.UnlockById( *iNamespaceDef, objectId );
       
  2168 				}
       
  2169 			
       
  2170 			objectIds.AppendL( objectId );
       
  2171 			}
       
  2172 		}
       
  2173 
       
  2174 	CollectRemovedItemsL( objectIds, aIdArray, aRelationIds, aEventIds );
       
  2175 
       
  2176     CleanupStack::PopAndDestroy( &objectIds );
       
  2177 	}
       
  2178 
       
  2179 TItemId CMdSSqlObjectManipulate::SearchObjectByUriL( const TDesC16& aUri, 
       
  2180 		TUint32& aFlags )
       
  2181 	{
       
  2182 	_LIT( KMdsSearchObjectbyUri, "SELECT ObjectId,Flags FROM Object%u WHERE NOT Flags&? AND NOT Flags&? AND URI=? LIMIT 1;" );
       
  2183 
       
  2184 	if ( !iNamespaceDef )
       
  2185 		{
       
  2186 		User::Leave( KErrMdEUnknownNamespaceDef );
       
  2187 		}
       
  2188 
       
  2189 	RClauseBuffer commonClauseOne(*this, KMdsSearchObjectbyUri.iTypeLength + KMaxUintValueLength );
       
  2190 	CleanupClosePushL( commonClauseOne );
       
  2191 	CMdsClauseBuffer& searchUriClause = commonClauseOne.BufferL();
       
  2192 
       
  2193 	searchUriClause.BufferL().Format( KMdsSearchObjectbyUri, iNamespaceDef->GetId() );
       
  2194 
       
  2195 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  2196 
       
  2197 	TItemId objectId = KNoId;
       
  2198 	aFlags = 0;
       
  2199 
       
  2200     RRowData varSearch;
       
  2201     CleanupClosePushL( varSearch );
       
  2202     varSearch.AppendL( TColumn( EMdEObjectFlagNotPresent ) );
       
  2203     varSearch.AppendL( TColumn( EMdEObjectFlagRemoved ) );
       
  2204     varSearch.AppendL( TColumn( aUri ) );
       
  2205 
       
  2206 	RMdsStatement getQuery;
       
  2207     CleanupClosePushL( getQuery );
       
  2208 
       
  2209 	__LOGQUERY_16( _L("Search object by URI:"), 
       
  2210 			searchUriClause.ConstBufferL(), varSearch);
       
  2211 	TRAPD( err, connection.ExecuteQueryL( 
       
  2212 			searchUriClause.ConstBufferL(), getQuery, varSearch ) );
       
  2213 
       
  2214 	varSearch.Free();
       
  2215 	varSearch.Reset();
       
  2216 	varSearch.AppendL( TColumn( objectId ) );
       
  2217 	varSearch.AppendL( TColumn( aFlags ) );
       
  2218 	if ( err == KErrNone && connection.NextRowL( getQuery, varSearch ) )
       
  2219 		{
       
  2220 		varSearch.Column(0).Get( objectId );
       
  2221 		varSearch.Column(1).Get( aFlags );
       
  2222 		}
       
  2223 
       
  2224 	CleanupStack::PopAndDestroy( 2, &varSearch ); // getQuery, varSearch
       
  2225 	CleanupStack::PopAndDestroy( &commonClauseOne );
       
  2226 	return objectId;
       
  2227 	}
       
  2228 
       
  2229 TItemId CMdSSqlObjectManipulate::UpdateObjectL( 
       
  2230 		CMdSSqLiteConnection& aConnection, CMdCSerializationBuffer& aBuffer )
       
  2231 	{
       
  2232 	_LIT( KMdsObjectUpdateBaseObjectBegin,     "UPDATE Object%u SET " );
       
  2233 	_LIT( KMdsObjectUpdateBaseObjectFlags,     "Flags=? " );
       
  2234 	_LIT( KMdsObjectUpdateBaseObjectEnd,       ",MediaId=?,GuidHigh=?,GuidLow=?,URI=? ");
       
  2235 	_LIT( KMdsObjectUpdateObjectBegin,         "UPDATE %S%u SET " );
       
  2236 	_LIT( KMdsObjectUpdateEnd,                 " WHERE ObjectId=?;" );
       
  2237 	_LIT( KUpdateEqual, "=?" );
       
  2238 
       
  2239 	if ( !iNamespaceDef )
       
  2240 		{
       
  2241 		User::Leave( KErrMdEUnknownNamespaceDef );
       
  2242 		}
       
  2243 
       
  2244 	const TMdCObject& object = TMdCObject::GetFromBufferL( aBuffer );
       
  2245 
       
  2246 	// objectid
       
  2247 	if (object.iId == KNoId)
       
  2248 		{
       
  2249 		User::Leave( KErrArgument );
       
  2250 		}
       
  2251 
       
  2252 	// object must be locked
       
  2253 	if (!iLockList.IsLocked(*iNamespaceDef, object.iId))
       
  2254 		{
       
  2255 		User::Leave( KErrMdENotLocked );
       
  2256 		}
       
  2257 
       
  2258 	// objectdefid
       
  2259 	// objectDef exists ??
       
  2260 	const CMdsObjectDef* objectDef = iNamespaceDef->GetObjectByIdL( 
       
  2261 			object.iDefId );
       
  2262 	if ( !objectDef )
       
  2263 		{
       
  2264 		User::Leave( KErrMdEUnknownObjectDef );
       
  2265 		}
       
  2266 
       
  2267 	// get BaseObjectDef
       
  2268 	iBaseObjectDef = iNamespaceDef->GetObjectByIdL( KBaseObjectDefId );
       
  2269 
       
  2270 	TUint32 objectFlags = 0;
       
  2271 	if (object.iFlags & EMdEObjectFlagConfidential)
       
  2272 		{
       
  2273 		objectFlags |= EMdEObjectFlagConfidential;
       
  2274 		}
       
  2275 	if (object.iFlags & EMdEObjectFlagModFreeText)
       
  2276 		{
       
  2277 		objectFlags |= EMdEObjectFlagFreetexts;
       
  2278 		}
       
  2279 	if (object.iFlags & EMdEObjectFlagPlaceholder)
       
  2280 		{
       
  2281 		objectFlags |= EMdEObjectFlagPlaceholder;
       
  2282 		}
       
  2283 	if (objectDef->GetFlags() == CMdsObjectDef::EObjectDefFlagsContext)
       
  2284 		{
       
  2285 		objectFlags |= EMdEObjectFlagContext;
       
  2286 		}
       
  2287 
       
  2288 	if (!(object.iFlags & EMdEObjectFlagModOpen))
       
  2289 		{
       
  2290 		User::Leave( KErrMdENotLocked );
       
  2291 		}
       
  2292 
       
  2293 	const TBool KUpdateModObject   = 
       
  2294 		object.iFlags & EMdEObjectFlagModObject   ? ETrue : EFalse;
       
  2295 	const TBool KUpdateModFreeText = 
       
  2296 		object.iFlags & EMdEObjectFlagModFreeText ? ETrue : EFalse;
       
  2297 	const TBool KUpdateModProperty = 
       
  2298 		object.iFlags & EMdEObjectFlagModProperty ? ETrue : EFalse;
       
  2299 
       
  2300 	if ( !( KUpdateModObject || KUpdateModFreeText || KUpdateModProperty ) )
       
  2301 		{
       
  2302 		// nothing to change, so unlock object and return
       
  2303 		iLockList.UnlockById( *iNamespaceDef, object.iId );
       
  2304 		return object.iId;
       
  2305 		}
       
  2306 
       
  2307 	RRowData baseObjectRow;
       
  2308 	CleanupClosePushL( baseObjectRow );
       
  2309 	RRowData objectRow;
       
  2310 	CleanupClosePushL( objectRow );
       
  2311 
       
  2312 	RClauseBuffer commonClauseOne(*this);
       
  2313 	CleanupClosePushL( commonClauseOne );
       
  2314 	CMdsClauseBuffer& clauseObject = commonClauseOne.BufferL();
       
  2315 	
       
  2316 	if (KUpdateModProperty)
       
  2317 		{
       
  2318 		clauseObject.BufferL().Format( KMdsObjectUpdateObjectBegin, 
       
  2319 				&objectDef->GetName(), iNamespaceDef->GetId() );
       
  2320 		}
       
  2321 
       
  2322 	RClauseBuffer commonClauseTwo(*this);
       
  2323 	CleanupClosePushL( commonClauseTwo );
       
  2324 	CMdsClauseBuffer& clauseBaseObject = commonClauseTwo.BufferL();
       
  2325 	if (KUpdateModObject || KUpdateModProperty)
       
  2326 		{
       
  2327 		clauseBaseObject.BufferL().Format( KMdsObjectUpdateBaseObjectBegin, 
       
  2328 				iNamespaceDef->GetId() );
       
  2329 		}
       
  2330 
       
  2331 	aBuffer.PositionL( object.iUri.iPtr.iOffset );
       
  2332 	HBufC* uriBuf = aBuffer.ReceiveDes16L();
       
  2333 	CleanupStack::PushL( uriBuf );
       
  2334 	TPtr16 uri( uriBuf->Des() );
       
  2335 	uri.LowerCase();
       
  2336 
       
  2337 	// if auto locking, skip extra checks, because only flags can be changed
       
  2338 	if( !(object.iFlags & EMdEObjectFlagAutoLock) )
       
  2339 		{
       
  2340 		// leave if GUID high and low are 0
       
  2341 		if( object.iGuidHigh == 0 && object.iGuidLow == 0 )
       
  2342 			{
       
  2343 			User::Leave( KErrCorrupt );
       
  2344 			}
       
  2345 
       
  2346 		// leave if URI is "empty"
       
  2347 		if( uri.Length() == 0 )
       
  2348 			{
       
  2349 			User::Leave( KErrCorrupt );
       
  2350 			}
       
  2351 		}
       
  2352 
       
  2353 	TBool KBaseObjectPropertyMod = EFalse;
       
  2354 	TBool KObjectPropertyMod     = EFalse;
       
  2355 
       
  2356 	if (KUpdateModObject)
       
  2357 		{
       
  2358 		clauseBaseObject.AppendL( KMdsObjectUpdateBaseObjectFlags );
       
  2359 		baseObjectRow.AppendL( TColumn( objectFlags ) );
       
  2360 
       
  2361 		if( !(object.iFlags & EMdEObjectFlagAutoLock) )
       
  2362 			{
       
  2363 			clauseBaseObject.AppendL( KMdsObjectUpdateBaseObjectEnd );
       
  2364 			baseObjectRow.AppendL( TColumn( object.iMediaId ) );
       
  2365 			baseObjectRow.AppendL( TColumn( object.iGuidHigh ) );
       
  2366 			baseObjectRow.AppendL( TColumn( object.iGuidLow ) );
       
  2367 			baseObjectRow.AppendL( TColumn( uri ) );
       
  2368 			}
       
  2369 		KBaseObjectPropertyMod = ETrue;
       
  2370 		}
       
  2371 
       
  2372 	// read properties array
       
  2373 	if ( KUpdateModProperty )
       
  2374 		{
       
  2375 		// try to add property and increase property count
       
  2376 		for ( TUint32 i = 0; i < object.iProperties.iPtr.iCount; ++i )
       
  2377 			{
       
  2378 			aBuffer.PositionL( object.iProperties.iPtr.iOffset + 
       
  2379 					i * sizeof(TMdCProperty) );
       
  2380 			TUint8 modFlags;
       
  2381 			const CMdsPropertyDef& propertyDef = ReadPropertyL( aBuffer, 
       
  2382 					*objectDef, clauseBaseObject, clauseObject, baseObjectRow, 
       
  2383 					objectRow, modFlags );
       
  2384 			// check if property is already in array
       
  2385 			if ( modFlags == EMdEPropertyModNone )
       
  2386 				{
       
  2387 				continue;
       
  2388 				}
       
  2389 
       
  2390 			if( ( modFlags & EMdEPropertyModRemove ) && propertyDef.GetMandatory() )
       
  2391 				{
       
  2392 				User::Leave( KErrMdEMandatoryPropertyMissing );
       
  2393 				}
       
  2394 
       
  2395 			const TDefId propertyId = propertyDef.GetId();
       
  2396 
       
  2397 			if ( iBaseObjectDef->GetPropertyByIdL( propertyId ) )
       
  2398 				{
       
  2399 				if (!KBaseObjectPropertyMod)
       
  2400 					{
       
  2401 					// remove comma before first property
       
  2402 					clauseBaseObject.BufferL().Delete( 
       
  2403 							clauseBaseObject.ConstBufferL().LocateReverse( ',' ), 1 );
       
  2404 					KBaseObjectPropertyMod = ETrue;
       
  2405 					}
       
  2406 				clauseBaseObject.AppendL( KUpdateEqual );
       
  2407 				}
       
  2408 			else
       
  2409 				{
       
  2410 				if (!KObjectPropertyMod)
       
  2411 					{
       
  2412 					// remove comma before first property
       
  2413 					clauseObject.BufferL().Delete( 
       
  2414 							clauseObject.ConstBufferL().LocateReverse( ',' ), 1 );
       
  2415 					KObjectPropertyMod = ETrue;
       
  2416 					}
       
  2417 				clauseObject.AppendL( KUpdateEqual );
       
  2418 				}
       
  2419 			}
       
  2420 		}
       
  2421 
       
  2422 	if (KUpdateModObject || KBaseObjectPropertyMod)
       
  2423 		{
       
  2424 		clauseBaseObject.AppendL( KMdsObjectUpdateEnd );
       
  2425 		// append confidential and deleted flags
       
  2426 		baseObjectRow.AppendL( TColumn( object.iId ) );
       
  2427 		}
       
  2428 
       
  2429 	if (KObjectPropertyMod)
       
  2430 		{
       
  2431 		clauseObject.AppendL( KMdsObjectUpdateEnd );
       
  2432 		// append confidential and deleted flags
       
  2433 		objectRow.AppendL( TColumn( object.iId ) );
       
  2434 		}
       
  2435 
       
  2436 	TInt queryResult = 0, err;
       
  2437     RMdSTransaction transaction( aConnection );
       
  2438     CleanupClosePushL( transaction );
       
  2439     User::LeaveIfError( transaction.Error() );
       
  2440 
       
  2441 	if ( KUpdateModObject || KBaseObjectPropertyMod )
       
  2442 		{
       
  2443 		__LOGQUERY_16( _L("Update BaseObject:"), 
       
  2444 				clauseBaseObject.ConstBufferL(), baseObjectRow);
       
  2445 		TRAP( err, queryResult = aConnection.ExecuteL( 
       
  2446 				clauseBaseObject.ConstBufferL(), baseObjectRow ) );
       
  2447 
       
  2448 		// Try to remove the object which caused the constraint error and try add the object again.
       
  2449 		if ( err == KSqlErrConstraint )
       
  2450 			{
       
  2451 			__LOG2( ELogQuery, "Update baseObject constraint error - err:%d, queryResult:%d", err, queryResult );
       
  2452 			// The reason of the constraint error is not checked due to performance hit.
       
  2453 			TRAP_IGNORE( RemoveObjectForceL( uri, object.iId ) );
       
  2454 			__LOGQUERY_16( _L("Update AGAIN BaseObject:"), 
       
  2455 					clauseBaseObject.ConstBufferL(), baseObjectRow);
       
  2456 			// Fails if the object was not marked as removed.
       
  2457 			TRAP( err, queryResult = aConnection.ExecuteL( 
       
  2458 					clauseBaseObject.ConstBufferL(), baseObjectRow ) );
       
  2459 			}
       
  2460 
       
  2461 		if ( err != KErrNone || queryResult != 1 )
       
  2462 			{
       
  2463 			__LOG2( ELogQuery, "Update baseObject failed - err:%d, queryResult:%d", err, queryResult );
       
  2464 			User::Leave( KErrGeneral );
       
  2465 			}
       
  2466 		}
       
  2467 
       
  2468 	if ( KObjectPropertyMod )
       
  2469 		{
       
  2470 		__LOGQUERY_16( _L("Update Object:"), clauseObject.ConstBufferL(), 
       
  2471 				objectRow);
       
  2472 		TRAP( err, queryResult = aConnection.ExecuteL( 
       
  2473 				clauseObject.ConstBufferL(), objectRow ) );
       
  2474 		if (err != KErrNone || queryResult != 1)
       
  2475 			{
       
  2476 			__LOG2( ELogQuery, "Update Object failed - err:%d, queryResult:%d", err, queryResult );
       
  2477 			User::Leave( KErrGeneral );
       
  2478 			}
       
  2479 		}
       
  2480 
       
  2481 	if ( KUpdateModFreeText )
       
  2482 		{
       
  2483 		if ( object.iFreeTexts.iPtr.iCount > 0 )
       
  2484 			{
       
  2485 			aBuffer.PositionL( object.iFreeTexts.iPtr.iOffset );
       
  2486 			UpdateFreeTextL( aBuffer, object.iFreeTexts.iPtr.iCount, object.iId );
       
  2487 			}
       
  2488 		}
       
  2489 
       
  2490     transaction.CommitL();
       
  2491     CleanupStack::PopAndDestroy( &transaction );
       
  2492 
       
  2493     CleanupStack::PopAndDestroy( uriBuf );
       
  2494     CleanupStack::PopAndDestroy( &commonClauseTwo );
       
  2495 	CleanupStack::PopAndDestroy( &commonClauseOne );
       
  2496 
       
  2497     // objectRow, baseObjectRow
       
  2498 	CleanupStack::PopAndDestroy( 2, &baseObjectRow );
       
  2499 
       
  2500 	iLockList.UnlockById( *iNamespaceDef, object.iId );
       
  2501 	return object.iId;
       
  2502 	}
       
  2503 
       
  2504 
       
  2505 void CMdSSqlObjectManipulate::UpdateFreeTextL( CMdCSerializationBuffer& aBuffer,
       
  2506 		TInt aCount, TItemId aObjectId )
       
  2507 	{
       
  2508 	_LIT( KMdSUpdateFreeTextDelete,     "DELETE FROM TextSearch%u WHERE ObjectId=?;" );
       
  2509 	_LIT( KMdSUpdateFreeTextDictDelete, "DELETE FROM TextSearchDictionary%u WHERE WordId NOT IN(SELECT WordId FROM TextSearch%u);" );
       
  2510 	_LIT( KMdSUpdateFreeTextObjectFlagSet,   "UPDATE Object%u SET Flags=Flags|? WHERE ObjectId=?;" );
       
  2511 	_LIT( KMdSUpdateFreeTextObjectFlagReset, "UPDATE Object%u SET Flags=Flags&? WHERE ObjectId=?;" );
       
  2512 
       
  2513 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  2514 
       
  2515 	RClauseBuffer commonClauseOne(*this, KMdSUpdateFreeTextDictDelete.iTypeLength + 2*KMaxUintValueLength);
       
  2516 	CleanupClosePushL( commonClauseOne );
       
  2517 	CMdsClauseBuffer& buffer = commonClauseOne.BufferL();
       
  2518 	RRowData delRow;
       
  2519 	CleanupClosePushL( delRow );
       
  2520 
       
  2521 	delRow.AppendL( TColumn( aObjectId ) );
       
  2522 	buffer.BufferL().Format( KMdSUpdateFreeTextDelete, iNamespaceDef->GetId() );
       
  2523 	connection.ExecuteL( buffer.ConstBufferL(), delRow );
       
  2524 
       
  2525 	delRow.Free(); delRow.Reset();
       
  2526 	buffer.BufferL().Format( KMdSUpdateFreeTextDictDelete, iNamespaceDef->GetId(), 
       
  2527 			iNamespaceDef->GetId() );
       
  2528 	connection.ExecuteL( buffer.ConstBufferL(), delRow );
       
  2529 
       
  2530 	// update object flags
       
  2531 	delRow.Free(); delRow.Reset();
       
  2532 	delRow.AppendL( TColumn( EMdEObjectFlagFreetexts ) );
       
  2533 	delRow.AppendL( TColumn( aObjectId ) );
       
  2534 	if ( AddFreeTextL( aBuffer, aCount, aObjectId ) > 0 )
       
  2535 		{
       
  2536 		buffer.BufferL().Format( KMdSUpdateFreeTextObjectFlagSet, iNamespaceDef->GetId() );
       
  2537 		}
       
  2538 	else
       
  2539 		{
       
  2540 		buffer.BufferL().Format( KMdSUpdateFreeTextObjectFlagReset, iNamespaceDef->GetId() );
       
  2541 		delRow.Column(0).Set( ~EMdEObjectFlagFreetexts );
       
  2542 		}
       
  2543 	connection.ExecuteL( buffer.ConstBufferL(), delRow );
       
  2544 
       
  2545 	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // delRow, commonClauseOne
       
  2546 	}
       
  2547 
       
  2548 TItemId CMdSSqlObjectManipulate::AddEventL( CMdSSqLiteConnection& aConnection, 
       
  2549 		CMdCSerializationBuffer& aBuffer )
       
  2550 	{
       
  2551 	_LIT( KAddEvent, "INSERT INTO Event%u(EventId,ObjectId,EventDefId,Timestamp,Source,Participant) VALUES(?,?,?,?,?,?);" );
       
  2552 
       
  2553 	if ( !iNamespaceDef )
       
  2554 		{
       
  2555 		User::Leave( KErrMdEUnknownNamespaceDef );
       
  2556 		}
       
  2557 	
       
  2558 	RClauseBuffer commonClauseOne(*this, KAddEvent().Length() + KMaxUintValueLength);
       
  2559 	CleanupClosePushL( commonClauseOne );
       
  2560 	CMdsClauseBuffer& sqlBuf = commonClauseOne.BufferL();
       
  2561 	sqlBuf.BufferL().Format( KAddEvent, iNamespaceDef->GetId() );
       
  2562 
       
  2563    	RRowData var;
       
  2564     CleanupClosePushL( var );
       
  2565 
       
  2566     const TMdCEvent& event = TMdCEvent::GetFromBufferL( aBuffer );
       
  2567 
       
  2568     TItemId eventId = event.iId;
       
  2569 	if ( eventId != KNoId )
       
  2570 		{
       
  2571 		User::Leave( KErrArgument );
       
  2572 		}
       
  2573 	
       
  2574 	RSQLIndex sqlIndex;
       
  2575 	CleanupClosePushL( sqlIndex );
       
  2576 	eventId = sqlIndex.GetId();
       
  2577 
       
  2578 	if ( !iNamespaceDef->GetEventByIdL( event.iDefId ) )
       
  2579 		{
       
  2580 		User::Leave( KErrMdEUnknownEventDef );
       
  2581 		}
       
  2582 
       
  2583     if ( event.iObjectId == KNoId )
       
  2584     	{
       
  2585     	User::Leave( KErrCorrupt );
       
  2586     	}
       
  2587 
       
  2588     var.AppendL( TColumn( eventId ) );
       
  2589     var.AppendL( TColumn( event.iObjectId ) );
       
  2590     var.AppendL( TColumn( event.iDefId ) );
       
  2591     var.AppendL( TColumn( event.iTime.Int64() ) );
       
  2592 
       
  2593     TPtrC16 source;
       
  2594     if ( event.iSourceText.iPtr.iCount > 0 )
       
  2595     	{
       
  2596     	aBuffer.PositionL( event.iSourceText.iPtr.iOffset );
       
  2597         source.Set( aBuffer.ReceivePtr16L() );
       
  2598     	}
       
  2599     else
       
  2600     	{
       
  2601     	source.Set( TPtr16((TUint16*)0, 0) );
       
  2602     	}
       
  2603     var.AppendL( TColumn( source ) );
       
  2604 
       
  2605 	TPtrC16 participant;
       
  2606     if ( event.iParticipantText.iPtr.iCount > 0 )
       
  2607     	{
       
  2608     	aBuffer.PositionL( event.iParticipantText.iPtr.iOffset );
       
  2609     	participant.Set( aBuffer.ReceivePtr16L() );
       
  2610     	}
       
  2611     else
       
  2612     	{
       
  2613     	participant.Set( TPtr16((TUint16*)0, 0) );
       
  2614     	}
       
  2615     var.AppendL( TColumn( participant ) );
       
  2616 
       
  2617     aConnection.ExecuteL( sqlBuf.ConstBufferL(), var );
       
  2618 
       
  2619 	sqlIndex.Commit();
       
  2620 	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // sqlIndex, var, commonClauseOne
       
  2621 	return eventId;
       
  2622 	}
       
  2623         
       
  2624 TItemId CMdSSqlObjectManipulate::AddRelationL( 
       
  2625 		CMdSSqLiteConnection& aConnection, CMdCSerializationBuffer& aBuffer )
       
  2626 	{
       
  2627 	_LIT( KAddRelation, "INSERT INTO Relations%u(RelationId,Flags,RelationDefId,LeftObjectId,RightObjectId,Parameter,GuidHigh,GuidLow,LastModifiedDate) VALUES(?,?,?,?,?,?,?,?,?);" );
       
  2628 
       
  2629 	if ( !iNamespaceDef )
       
  2630 		{
       
  2631 		User::Leave( KErrMdEUnknownNamespaceDef );
       
  2632 		}
       
  2633 	
       
  2634 	RClauseBuffer commonClauseOne(*this, KAddRelation().Length() + KMaxUintValueLength);
       
  2635 	CleanupClosePushL( commonClauseOne );
       
  2636 	CMdsClauseBuffer& buffer = commonClauseOne.BufferL();
       
  2637 	buffer.BufferL().Format( KAddRelation, iNamespaceDef->GetId() );
       
  2638 
       
  2639     RRowData var;
       
  2640 	CleanupClosePushL( var );
       
  2641 
       
  2642 	const TMdCRelation& relation = TMdCRelation::GetFromBufferL( aBuffer );
       
  2643 	TItemId relationId = relation.iId;
       
  2644 
       
  2645 	if ( relationId != KNoId )
       
  2646 		{
       
  2647 		User::Leave( KErrArgument );
       
  2648 		}
       
  2649 	
       
  2650 	RSQLIndex sqlIndex;
       
  2651 	CleanupClosePushL( sqlIndex );
       
  2652 	relationId = sqlIndex.GetId();
       
  2653 
       
  2654 	if ( !iNamespaceDef->GetRelationByIdL( relation.iDefId ) )
       
  2655 		{
       
  2656 		User::Leave( KErrMdEUnknownRelationDef );
       
  2657 		}
       
  2658 
       
  2659     if ( relation.iLeftObjectId == KNoId || relation.iRightObjectId == KNoId )
       
  2660     	{
       
  2661     	User::Leave( KErrCorrupt );
       
  2662     	}
       
  2663 
       
  2664 	TInt64 guidHigh = relation.iGuidHigh;
       
  2665 	TInt64 guidLow = relation.iGuidLow;
       
  2666 	if ( guidHigh == 0 && guidLow == 0 )
       
  2667 		{
       
  2668 		iGenerator->GenerateGuid( guidHigh, guidLow );
       
  2669 		}
       
  2670 
       
  2671 	// if last modified date is 0, set it to current universal time
       
  2672 	TInt64 lastModifiedDate = relation.iLastModifiedDate.Int64();
       
  2673 	if( lastModifiedDate == 0 )
       
  2674 		{
       
  2675 		TTime currentTime;
       
  2676 		currentTime.UniversalTime();
       
  2677 		lastModifiedDate = currentTime.Int64();
       
  2678 		}
       
  2679 
       
  2680     var.AppendL( TColumn( relationId ) );
       
  2681     var.AppendL( TColumn( TUint32(0) ) ); // no flags
       
  2682     var.AppendL( TColumn( relation.iDefId) );
       
  2683     var.AppendL( TColumn( relation.iLeftObjectId ) );
       
  2684     var.AppendL( TColumn( relation.iRightObjectId ) );
       
  2685     var.AppendL( TColumn( relation.iParameter ) );
       
  2686     var.AppendL( TColumn( guidHigh ) );
       
  2687     var.AppendL( TColumn( guidLow ) );
       
  2688     var.AppendL( TColumn( lastModifiedDate ) );
       
  2689 
       
  2690     aConnection.ExecuteL( buffer.ConstBufferL(), var );
       
  2691 
       
  2692 	sqlIndex.Commit();
       
  2693 	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // sqlIndex, var, commonClauseOne
       
  2694 	return relationId;
       
  2695 	}
       
  2696 
       
  2697 void CMdSSqlObjectManipulate::RemoveRelationsL( CMdCSerializationBuffer& aBuffer,
       
  2698 		TInt aCount, RArray<TItemId>& aIdArray )
       
  2699     {	
       
  2700 	_LIT( KRemoveRelation, "UPDATE Relations%u SET Flags=Flags|? WHERE RelationId=? AND NOT Flags&?;" );
       
  2701     CMdSSqLiteConnection& db = MMdSDbConnectionPool::GetDefaultDBL();
       
  2702     
       
  2703 	RClauseBuffer commonClauseOne(*this, KRemoveRelation().Length() + KMaxUintValueLength);
       
  2704 	CleanupClosePushL( commonClauseOne );
       
  2705 	CMdsClauseBuffer& buf = commonClauseOne.BufferL();
       
  2706     buf.BufferL().Format( KRemoveRelation, iNamespaceDef->GetId() );
       
  2707 
       
  2708 	TInt queryResult = 0;
       
  2709 	TItemId relationId = KNoId;
       
  2710 
       
  2711     RRowData varRemove;
       
  2712     CleanupClosePushL( varRemove );
       
  2713     varRemove.AppendL( TColumn( 
       
  2714     		EMdERelationFlagDeleted | EMdERelationFlagGarbageDeleted ) );
       
  2715     varRemove.AppendL( TColumn( relationId ) );
       
  2716     varRemove.AppendL( TColumn( 
       
  2717     		EMdERelationFlagDeleted | EMdERelationFlagNotPresent ) );
       
  2718 
       
  2719 	for ( TUint32 i = 0; i < aCount; ++i )
       
  2720 		{
       
  2721 		aBuffer.ReceiveL( relationId );
       
  2722 		varRemove.Column( 1 ).Set( relationId );
       
  2723 		TRAPD( err, queryResult = db.ExecuteL( buf.ConstBufferL(), varRemove ) );
       
  2724 		if ( err == KErrNone && queryResult == 1 )
       
  2725 			{
       
  2726 			aIdArray.AppendL( relationId );
       
  2727 			}
       
  2728 		else
       
  2729 			{
       
  2730 			aIdArray.AppendL( KNoId );
       
  2731 			}
       
  2732 		}
       
  2733 	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // varRemove, commonClauseOne
       
  2734     }
       
  2735 
       
  2736 void CMdSSqlObjectManipulate::RemoveEventsL( CMdCSerializationBuffer& aBuffer, 
       
  2737 		TInt aCount, RArray<TItemId>& aIdArray )
       
  2738     {
       
  2739 	_LIT( KRemoveEvent, "DELETE FROM Event%u WHERE EventId=?;" );
       
  2740 
       
  2741     CMdSSqLiteConnection& db = MMdSDbConnectionPool::GetDefaultDBL();
       
  2742 
       
  2743 	RClauseBuffer commonClauseOne(*this, KRemoveEvent().Length() + KMaxUintValueLength);
       
  2744 	CleanupClosePushL( commonClauseOne );
       
  2745 	CMdsClauseBuffer& buf = commonClauseOne.BufferL();
       
  2746     buf.BufferL().Format( KRemoveEvent, iNamespaceDef->GetId() );
       
  2747 
       
  2748 	TInt queryResult = 0;
       
  2749 	TItemId eventId = KNoId;
       
  2750 
       
  2751     RRowData varRemove;
       
  2752     CleanupClosePushL( varRemove );
       
  2753     varRemove.AppendL( TColumn( eventId ) );
       
  2754 
       
  2755 	for ( TUint32 i = 0; i < aCount; ++i )
       
  2756 		{
       
  2757 		aBuffer.ReceiveL( eventId );
       
  2758 		varRemove.Column( 0 ).Set( eventId );
       
  2759 		TRAPD( err, queryResult = db.ExecuteL( buf.ConstBufferL(), varRemove ) );
       
  2760 		if ( err == KErrNone && queryResult == 1 )
       
  2761 			{
       
  2762 			aIdArray.AppendL( eventId );
       
  2763 			}
       
  2764 		else
       
  2765 			{
       
  2766 			aIdArray.AppendL( KNoId );
       
  2767 			}
       
  2768 		}
       
  2769 	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // varRemove, commonClauseOne
       
  2770     }
       
  2771 
       
  2772 TItemId CMdSSqlObjectManipulate::UpdateRelationsL(
       
  2773 		CMdSSqLiteConnection& aConnection, CMdCSerializationBuffer& aBuffer )
       
  2774     {	
       
  2775 	_LIT( KUpdateRelation, "UPDATE Relations%u SET RelationDefId=?,LeftObjectId=?,RightObjectId=?,Parameter=?,GuidHigh=?,GuidLow=?,LastModifiedDate=? WHERE NOT Flags&? AND NOT Flags&? AND RelationId=?;" );
       
  2776 
       
  2777 if ( !iNamespaceDef )
       
  2778 		{
       
  2779 		User::Leave( KErrMdEUnknownNamespaceDef );
       
  2780 		}
       
  2781 	
       
  2782 	RClauseBuffer commonClauseOne(*this, KUpdateRelation().Length() + KMaxUintValueLength);
       
  2783 	CleanupClosePushL( commonClauseOne );
       
  2784 	CMdsClauseBuffer& sqlBuf = commonClauseOne.BufferL();
       
  2785     sqlBuf.BufferL().Format( KUpdateRelation, iNamespaceDef->GetId() );
       
  2786 
       
  2787     RRowData var;
       
  2788     CleanupClosePushL( var );
       
  2789 
       
  2790     const TMdCRelation& relation = TMdCRelation::GetFromBufferL( aBuffer );
       
  2791 
       
  2792     if ( relation.iId == KNoId )
       
  2793     	{
       
  2794     	User::Leave( KErrArgument );
       
  2795     	}
       
  2796 
       
  2797     if ( !iNamespaceDef->GetRelationByIdL( relation.iDefId ) )
       
  2798 		{
       
  2799 		User::Leave( KErrMdEUnknownRelationDef );
       
  2800 		}
       
  2801 
       
  2802 	// leave if GUID high and low are 0
       
  2803 	if( relation.iGuidHigh == 0 && relation.iGuidLow == 0 )
       
  2804 		{
       
  2805 		User::Leave( KErrCorrupt );
       
  2806 		}
       
  2807 
       
  2808 	// if last modified date is 0, set it to current universal time
       
  2809 	TInt64 lastModifiedDate = relation.iLastModifiedDate.Int64();
       
  2810 	if( lastModifiedDate == 0 )
       
  2811 		{
       
  2812 		TTime currentTime;
       
  2813 		currentTime.UniversalTime();
       
  2814 		lastModifiedDate = currentTime.Int64();
       
  2815 		}
       
  2816 
       
  2817     var.AppendL( TColumn( relation.iDefId ) );
       
  2818     var.AppendL( TColumn( relation.iLeftObjectId ) );
       
  2819     var.AppendL( TColumn( relation.iRightObjectId ) );
       
  2820     var.AppendL( TColumn( relation.iParameter ) );
       
  2821     var.AppendL( TColumn( relation.iGuidHigh ) );
       
  2822     var.AppendL( TColumn( relation.iGuidLow ) );
       
  2823     var.AppendL( TColumn( lastModifiedDate ) );
       
  2824     var.AppendL( TColumn( EMdERelationFlagNotPresent ) );
       
  2825     var.AppendL( TColumn( EMdERelationFlagDeleted ) );
       
  2826 	var.AppendL( TColumn( relation.iId ) );
       
  2827 
       
  2828 	aConnection.ExecuteL( sqlBuf.ConstBufferL(), var );
       
  2829 
       
  2830 	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // var, commonClauseOne
       
  2831 
       
  2832 	return relation.iId;
       
  2833     }
       
  2834 
       
  2835 void CMdSSqlObjectManipulate::GetRemovedRelationItemsL( CMdCSerializationBuffer& aBuffer,
       
  2836 		const RArray<TItemId>& aRemovedRelations,
       
  2837 		const RArray<TItemId>& aAdditionalRemovedRelations )
       
  2838 	{
       
  2839 	_LIT( KGetRelationItemsStart, "SELECT RelationId,RelationDefId,LeftObjectId,RightObjectId FROM Relations%u WHERE Flags&? AND RelationId IN(?" );
       
  2840 	_LIT( KGetRelationItemsMiddle, ",?" );
       
  2841 	_LIT( KGetRelationItemsEnd, ");" );
       
  2842 
       
  2843 	const TInt relationsCount = aRemovedRelations.Count() + aAdditionalRemovedRelations.Count();
       
  2844 	
       
  2845 	TMdCItems relationItems;
       
  2846 	
       
  2847 	relationItems.iNamespaceDefId = iNamespaceDef->GetId();
       
  2848 	relationItems.iRelations.iPtr.iCount = 0; // will be updated later
       
  2849 	relationItems.iRelations.iPtr.iOffset = sizeof( TMdCItems );
       
  2850 
       
  2851 	if ( relationsCount == 0 )
       
  2852 		{
       
  2853 		relationItems.SerializeL( aBuffer );
       
  2854 
       
  2855 		return;
       
  2856 		}
       
  2857 	
       
  2858 	RClauseBuffer commonClauseOne(*this, KGetRelationItemsStart().Length() + KMaxUintValueLength
       
  2859 			+ KGetRelationItemsMiddle().Length() * relationsCount 
       
  2860 			+ KGetRelationItemsEnd().Length() );
       
  2861 	CleanupClosePushL( commonClauseOne );
       
  2862 	CMdsClauseBuffer& sqlBuffer = commonClauseOne.BufferL();
       
  2863 	sqlBuffer.BufferL().Format( KGetRelationItemsStart, iNamespaceDef->GetId() );
       
  2864 
       
  2865     RRowData var;
       
  2866     CleanupClosePushL( var );
       
  2867     var.ReserveL( 1 + relationsCount );
       
  2868     var.AppendL( EMdERelationFlagDeleted );
       
  2869 
       
  2870     const TInt removedRelationsCount = aRemovedRelations.Count();
       
  2871     for (TInt i = 0; i < removedRelationsCount-1; ++i)
       
  2872     	{
       
  2873     	sqlBuffer.AppendL( KGetRelationItemsMiddle );
       
  2874     	var.AppendL( aRemovedRelations[i] );
       
  2875     	}
       
  2876     if ( removedRelationsCount )
       
  2877     	{
       
  2878 	    var.AppendL( aRemovedRelations[removedRelationsCount-1] );
       
  2879     	}
       
  2880 
       
  2881     const TInt additionalRemovedRelationsCount = aAdditionalRemovedRelations.Count();
       
  2882     for (TInt i = 0; i < additionalRemovedRelationsCount-1; ++i)
       
  2883     	{
       
  2884     	sqlBuffer.AppendL( KGetRelationItemsMiddle );
       
  2885     	var.AppendL( aAdditionalRemovedRelations[i] );
       
  2886     	}
       
  2887     if ( removedRelationsCount == 0 /*&& additionalRemovedRelationsCount*/ )
       
  2888     	{
       
  2889     	// cannot be empty
       
  2890     	var.AppendL( aAdditionalRemovedRelations[additionalRemovedRelationsCount-1] );
       
  2891     	}
       
  2892     
       
  2893     sqlBuffer.AppendL( KGetRelationItemsEnd );
       
  2894     
       
  2895 	RMdsStatement getQuery;
       
  2896     CleanupClosePushL( getQuery );
       
  2897 
       
  2898 	__LOGQUERY_16( _L("CMdSSqlObjectManipulate::GetRemovedRelationItemsL:"), 
       
  2899 			sqlBuffer.ConstBufferL(), var);
       
  2900     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  2901 	
       
  2902     connection.ExecuteQueryL( sqlBuffer.ConstBufferL(), getQuery, var );
       
  2903 
       
  2904 	var.Free(); 
       
  2905 	var.Reset();
       
  2906 
       
  2907     var.ReserveL( 4 );
       
  2908     
       
  2909     TMdCRelation relation;
       
  2910 	var.AppendL( relation.iId );
       
  2911 	var.AppendL( relation.iDefId );
       
  2912 	var.AppendL( relation.iLeftObjectId );
       
  2913 	var.AppendL( relation.iRightObjectId );
       
  2914 	
       
  2915     TUint32 resultCount = 0;
       
  2916     
       
  2917     // move position after items
       
  2918 	aBuffer.PositionL( relationItems.iRelations.iPtr.iOffset );
       
  2919 
       
  2920 	while( connection.NextRowL( getQuery, var ) )
       
  2921 		{
       
  2922 		++resultCount;
       
  2923 
       
  2924 		var.Column( 0 ).Get( relation.iId );
       
  2925 		var.Column( 1 ).Get( relation.iDefId );
       
  2926 		var.Column( 2 ).Get( relation.iLeftObjectId );
       
  2927 		var.Column( 3 ).Get( relation.iRightObjectId );
       
  2928 
       
  2929 		relation.SerializeL( aBuffer );
       
  2930 		}
       
  2931 
       
  2932 	// update relation count
       
  2933 	relationItems.iRelations.iPtr.iCount = resultCount;
       
  2934 
       
  2935 	// move position to begin of buffer and serialize items
       
  2936 	aBuffer.PositionL( KNoOffset );
       
  2937 	relationItems.SerializeL( aBuffer );
       
  2938 
       
  2939 	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // getQuery, var, commonClauseOne
       
  2940 	}
       
  2941 
       
  2942 void CMdSSqlObjectManipulate::SetPendingL(const RArray<TItemId>& aObjectIds, 
       
  2943 		TBool aReset)
       
  2944 	{
       
  2945 	_LIT( KUpdatePending,   "UPDATE Object%u SET Flags=Flags%c? WHERE ObjectId IN(?" );
       
  2946 	_LIT( KUpdatePendingMiddle, ",?" );
       
  2947 	_LIT( KUpdatePendingEnd, ");" );
       
  2948 
       
  2949     CMdSSqLiteConnection& db = MMdSDbConnectionPool::GetDefaultDBL();
       
  2950 
       
  2951     const TInt objectIdsCount = aObjectIds.Count();
       
  2952 
       
  2953 	RClauseBuffer commonClause(*this, KUpdatePending().Length() + KMaxUintValueLength + 
       
  2954 			KUpdatePendingMiddle().Length() * (objectIdsCount - 1) + 
       
  2955 			KUpdatePendingEnd().Length() );
       
  2956 	CleanupClosePushL( commonClause );
       
  2957 	CMdsClauseBuffer& buf = commonClause.BufferL();
       
  2958 
       
  2959 	const TChar KSetUpdateFlag = '|';
       
  2960 	const TChar KResetUpdateFlag = '&';
       
  2961 	
       
  2962 	TChar flagUpdate = KSetUpdateFlag; // set flag
       
  2963 	TUint32 objectFlag = EMdeObjectFlagPending;
       
  2964 
       
  2965 	if( aReset )
       
  2966 		{
       
  2967 		flagUpdate = KResetUpdateFlag; // reset flag
       
  2968 		objectFlag = ~objectFlag; // not pending flag
       
  2969 		}
       
  2970 	
       
  2971     buf.BufferL().Format( KUpdatePending, KDefaultNamespaceDefId, (TUint)flagUpdate );
       
  2972 
       
  2973     RRowData var;
       
  2974     CleanupClosePushL( var );
       
  2975 
       
  2976     var.ReserveL( 1 + objectIdsCount );
       
  2977     
       
  2978     var.AppendL( TColumn( objectFlag ) );
       
  2979 
       
  2980 	var.AppendL( aObjectIds[0] );
       
  2981     for (TInt i = 1; i < objectIdsCount; ++i)
       
  2982     	{
       
  2983     	buf.AppendL( KUpdatePendingMiddle );
       
  2984     	var.AppendL( aObjectIds[i] );
       
  2985     	}
       
  2986     buf.AppendL( KUpdatePendingEnd );
       
  2987 
       
  2988     db.ExecuteL( buf.ConstBufferL(), var );
       
  2989 
       
  2990 	CleanupStack::PopAndDestroy( 2, &commonClause ); // var, commonClause
       
  2991 	}
       
  2992 
       
  2993 TInt CMdSSqlObjectManipulate::GetPendingCountL(TDefId aObjectDefId)
       
  2994 	{
       
  2995 	_LIT( KGetPendingCount,   "SELECT count(*) FROM Object%u WHERE Flags&? AND NOT Flags&?" );
       
  2996 	_LIT( KGetPendingCountObjectDefId, " AND ObjectDefId=?" );
       
  2997 	_LIT( KGetPendingCountEnd, ";" );
       
  2998 
       
  2999     CMdSSqLiteConnection& db = MMdSDbConnectionPool::GetDefaultDBL();
       
  3000 
       
  3001     TInt bufferSize = KGetPendingCount().Length() + KMaxUintValueLength + 
       
  3002     		KGetPendingCountEnd().Length();
       
  3003     
       
  3004 	if( aObjectDefId != KNoDefId )	
       
  3005 		{
       
  3006 		bufferSize += KGetPendingCountObjectDefId().Length();
       
  3007 		}
       
  3008     
       
  3009 	RClauseBuffer commonClause( *this, bufferSize );
       
  3010 	CleanupClosePushL( commonClause );
       
  3011 	CMdsClauseBuffer& buf = commonClause.BufferL();
       
  3012     buf.BufferL().Format( KGetPendingCount, KDefaultNamespaceDefId );
       
  3013     
       
  3014     TInt varReservation = 2;
       
  3015     
       
  3016 	if( aObjectDefId != KNoDefId )	
       
  3017 		{
       
  3018 		buf.AppendL( KGetPendingCountObjectDefId );
       
  3019 		++varReservation;
       
  3020 		}
       
  3021 
       
  3022 	buf.AppendL( KGetPendingCountEnd );
       
  3023 	
       
  3024     RRowData var;
       
  3025     CleanupClosePushL( var );
       
  3026 
       
  3027     var.ReserveL( varReservation );
       
  3028 
       
  3029     var.AppendL( TColumn( EMdeObjectFlagPending ) );
       
  3030     var.AppendL( TColumn( EMdEObjectFlagNotPresent | EMdEObjectFlagRemoved | 
       
  3031     		EMdEObjectFlagPlaceholder | EMdEObjectFlagStartUpNotPresent ) );
       
  3032 
       
  3033     if( aObjectDefId != KNoDefId )
       
  3034     	{
       
  3035     	var.AppendL( TColumn( aObjectDefId ) );
       
  3036     	}
       
  3037     
       
  3038 	RMdsStatement getQuery;
       
  3039     CleanupClosePushL( getQuery );
       
  3040 
       
  3041 	db.ExecuteQueryL( buf.ConstBufferL(), getQuery, var );
       
  3042 
       
  3043 	var.Free();
       
  3044 	var.Reset();
       
  3045 
       
  3046 	TUint32 count = 0;
       
  3047 	
       
  3048 	var.AppendL( TColumn( count ) );
       
  3049 
       
  3050 	if ( db.NextRowL( getQuery, var ) )
       
  3051 		{
       
  3052 		var.Column(0).Get( count );
       
  3053 		}
       
  3054 
       
  3055 	CleanupStack::PopAndDestroy( 2, &var ); // getQuery, varSearch
       
  3056 	CleanupStack::PopAndDestroy( &commonClause );
       
  3057 	
       
  3058 	return count;
       
  3059 	}
       
  3060 
       
  3061 TInt CMdSSqlObjectManipulate::GetPendingL(TDefId aObjectDefId, 
       
  3062 		TInt aBufferSize, RArray<TItemId>& aObjectIds)
       
  3063 	{
       
  3064 	_LIT( KGetPending,   "SELECT ObjectId FROM Object%u WHERE Flags&? AND NOT Flags&?" );
       
  3065 	_LIT( KGetPendingObjectDefId, " AND ObjectDefId=?" );
       
  3066 	_LIT( KGetPendingEnd, " LIMIT ?;" );
       
  3067 
       
  3068     CMdSSqLiteConnection& db = MMdSDbConnectionPool::GetDefaultDBL();
       
  3069 
       
  3070     TInt bufferSize = KGetPending().Length() + KMaxUintValueLength + 
       
  3071     		KGetPendingEnd().Length();
       
  3072 
       
  3073 	if( aObjectDefId != KNoDefId )	
       
  3074 		{
       
  3075 		bufferSize += KGetPendingObjectDefId().Length();
       
  3076 		}
       
  3077 
       
  3078 	RClauseBuffer commonClause( *this, bufferSize );
       
  3079 	CleanupClosePushL( commonClause );
       
  3080 	CMdsClauseBuffer& buf = commonClause.BufferL();
       
  3081     buf.BufferL().Format( KGetPending, KDefaultNamespaceDefId );
       
  3082 
       
  3083     TInt varReservation = 3;
       
  3084 
       
  3085 	if( aObjectDefId != KNoDefId )	
       
  3086 		{
       
  3087 		buf.AppendL( KGetPendingObjectDefId );
       
  3088 		++varReservation;
       
  3089 		}
       
  3090 
       
  3091 	buf.AppendL( KGetPendingEnd );
       
  3092 
       
  3093     RRowData var;
       
  3094     CleanupClosePushL( var );
       
  3095 
       
  3096     var.ReserveL( varReservation );
       
  3097 
       
  3098     var.AppendL( TColumn( EMdeObjectFlagPending ) );
       
  3099     var.AppendL( TColumn( EMdEObjectFlagNotPresent | EMdEObjectFlagRemoved | 
       
  3100     		EMdEObjectFlagPlaceholder | EMdEObjectFlagStartUpNotPresent ) );
       
  3101 
       
  3102     if( aObjectDefId != KNoDefId )
       
  3103     	{
       
  3104     	var.AppendL( TColumn( aObjectDefId ) );
       
  3105     	}
       
  3106 
       
  3107     // get as much as possible to buffer and check if there is more than that
       
  3108     var.AppendL( TColumn( aBufferSize + 1 ) );
       
  3109 
       
  3110 	RMdsStatement getQuery;
       
  3111     CleanupClosePushL( getQuery );
       
  3112 
       
  3113 	db.ExecuteQueryL( buf.ConstBufferL(), getQuery, var );
       
  3114 
       
  3115 	var.Free();
       
  3116 	var.Reset();
       
  3117 
       
  3118 	TItemId objectId = 0;
       
  3119 
       
  3120 	var.AppendL( TColumn( objectId ) );
       
  3121 
       
  3122 	TInt extraRows = 0;
       
  3123 
       
  3124 	while( db.NextRowL( getQuery, var ) )
       
  3125 		{
       
  3126 		var.Column(0).Get( objectId );
       
  3127 		
       
  3128 		if( aObjectIds.Count() < aBufferSize )
       
  3129 			{
       
  3130 			aObjectIds.Append( objectId );
       
  3131 			}
       
  3132 		else
       
  3133 			{
       
  3134 			extraRows = 1;
       
  3135 			break;
       
  3136 			}
       
  3137 		}
       
  3138 
       
  3139 	CleanupStack::PopAndDestroy( 2, &var ); // getQuery, varSearch
       
  3140 	CleanupStack::PopAndDestroy( &commonClause );
       
  3141 
       
  3142 	return extraRows;
       
  3143 	}
       
  3144 
       
  3145 TBool CMdSSqlObjectManipulate::DoGarbageCollectionL()
       
  3146 	{
       
  3147 	_LIT( KDeleteObject,                 "DELETE FROM Object%u WHERE Flags&?;" );
       
  3148 	_LIT( KUpdateDeleteObject,           "UPDATE Object%u SET Flags=Flags|? WHERE Flags&?;" );
       
  3149 	_LIT( KDeleteRelations,              "DELETE FROM Relations%u WHERE Flags&?;" );
       
  3150 	_LIT( KUpdateDeleteRelations,        "UPDATE Relations%u SET Flags=Flags|? WHERE Flags&?;" );
       
  3151 	_LIT( KUpdateDeleteContextObjects,   "UPDATE Object%u SET Flags=Flags|? WHERE ObjectId IN ( SELECT ObjectId FROM Object%u AS O WHERE Flags&? AND UsageCount=0 AND ( SELECT count(*) FROM Relations%u WHERE NOT Flags&? AND ( LeftObjectId = O.ObjectId OR RightObjectId = O.ObjectId ) )= 0 );" );
       
  3152     _LIT( KDeleteWordFromTextSearchDict, "DELETE FROM TextSearchDictionary%u WHERE NOT EXISTS(SELECT WordId FROM TextSearch%u WHERE WordId = TextSearchDictionary%u.WordId);");
       
  3153 
       
  3154 
       
  3155 	RClauseBuffer commonClauseOne(*this, KUpdateDeleteContextObjects().Length() + 3 * KMaxUintValueLength);
       
  3156 	CleanupClosePushL( commonClauseOne );
       
  3157 	CMdsClauseBuffer& buffer = commonClauseOne.BufferL();
       
  3158 
       
  3159     RRowData rowDataDel;
       
  3160     CleanupClosePushL( rowDataDel );
       
  3161     rowDataDel.AppendL( TColumn( EMdEObjectFlagGarbage ) );
       
  3162 
       
  3163     RRowData rowDataUpd;
       
  3164     CleanupClosePushL( rowDataUpd );
       
  3165     rowDataUpd.AppendL( TColumn( EMdEObjectFlagGarbage ) );
       
  3166     rowDataUpd.AppendL( TColumn( EMdEObjectFlagRemoved ) );
       
  3167 
       
  3168     RRowData rowDataDelRel;
       
  3169     CleanupClosePushL( rowDataDelRel );
       
  3170     rowDataDelRel.AppendL( TColumn( EMdERelationFlagGarbageDeleted ) );
       
  3171 
       
  3172     RRowData rowDataUpdRel;
       
  3173     CleanupClosePushL( rowDataUpdRel );
       
  3174     rowDataUpdRel.AppendL( TColumn( EMdERelationFlagGarbageDeleted ) );
       
  3175     rowDataUpdRel.AppendL( TColumn( EMdERelationFlagDeleted ) );
       
  3176 
       
  3177     RRowData rowDataDelContext;
       
  3178     CleanupClosePushL( rowDataDelContext );
       
  3179     rowDataDelContext.AppendL( TColumn( EMdEObjectFlagRemoved ) );
       
  3180     rowDataDelContext.AppendL( TColumn( EMdEObjectFlagContext ) );
       
  3181     rowDataDelContext.AppendL( TColumn( EMdERelationFlagDeleted ) );
       
  3182 
       
  3183 	RRowData emptyRow;
       
  3184 	CleanupClosePushL( emptyRow );
       
  3185 
       
  3186    	const RPointerArray<CMdsNamespaceDef>& namespaceDefs = 
       
  3187    		iSchema.NamespaceDefs();
       
  3188 
       
  3189 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  3190 	TInt deleteObjectResult;
       
  3191 	TInt updateResult = 0;
       
  3192 	
       
  3193 	const TInt count = namespaceDefs.Count();
       
  3194 	
       
  3195    	for( TInt i = 0; i < count; ++i )
       
  3196    	    {
       
  3197    	    const TDefId nmspId = namespaceDefs[i]->GetId();
       
  3198 
       
  3199 		// deleting objects
       
  3200 		buffer.BufferL().Format( KDeleteObject, nmspId );
       
  3201    	    User::LeaveIfError( deleteObjectResult = connection.ExecuteL( 
       
  3202    	    		buffer.ConstBufferL(), rowDataDel ) );
       
  3203 
       
  3204         buffer.BufferL().Format( KUpdateDeleteObject, nmspId );
       
  3205    	    User::LeaveIfError( updateResult += connection.ExecuteL(
       
  3206    	    		buffer.ConstBufferL(), rowDataUpd ) );
       
  3207 
       
  3208 		// deleting relations
       
  3209 		buffer.BufferL().Format( KDeleteRelations, nmspId );
       
  3210    	    User::LeaveIfError( connection.ExecuteL( 
       
  3211    	    		buffer.ConstBufferL(), rowDataDelRel ) );
       
  3212 
       
  3213 		buffer.BufferL().Format( KUpdateDeleteRelations, nmspId );
       
  3214    	    User::LeaveIfError( updateResult += connection.ExecuteL( 
       
  3215    	    		buffer.ConstBufferL(), rowDataUpdRel ) );
       
  3216 
       
  3217 		// deleting context objects
       
  3218 		buffer.BufferL().Format( KUpdateDeleteContextObjects, nmspId, nmspId, nmspId );
       
  3219    	    User::LeaveIfError( updateResult += connection.ExecuteL( 
       
  3220    	    		buffer.ConstBufferL(), rowDataDelContext ) );
       
  3221 
       
  3222 		// deleting words from text search dictionary
       
  3223 		if ( deleteObjectResult > 0 )
       
  3224 			{
       
  3225 			buffer.BufferL().Format( KDeleteWordFromTextSearchDict, nmspId, nmspId, 
       
  3226 					nmspId );
       
  3227 	   	    User::LeaveIfError( connection.ExecuteL( 
       
  3228 	   	    		buffer.ConstBufferL(), emptyRow ) );
       
  3229 			}
       
  3230    	    }
       
  3231 
       
  3232    	// empryRow, rowDataDelContext, rowDataUpdRel, rowDataDelRel, rowDataUpd, 
       
  3233    	// rowDataDel, commonClauseOne
       
  3234 	CleanupStack::PopAndDestroy( 7, &commonClauseOne );
       
  3235 
       
  3236 	return updateResult != 0;
       
  3237 	}
       
  3238 
       
  3239 CMdSSqlObjectManipulate::RClauseBuffer::RClauseBuffer( CMdSSqlObjectManipulate& aSOM, TInt aSize )
       
  3240 	: iBuffers( aSOM.iBuffers ), iBuffer( NULL ), iNr( -1 ), iSize( aSize )
       
  3241 	{
       
  3242 	// search for available buffer
       
  3243 	// or create new one
       
  3244 	for (TInt i = 0; i < iBuffers.Count(); ++i)
       
  3245 		{
       
  3246 		if (!iBuffers[i].iLock)
       
  3247 			{
       
  3248 			iBuffers[i].iLock = ETrue;
       
  3249 			iBuffer = iBuffers[i].iBuffer;
       
  3250 			iNr = i;
       
  3251 			TRAP_IGNORE( iBuffer->ReserveSpaceL(aSize) );
       
  3252 			TRAP_IGNORE( iBuffer->BufferL().Zero() );
       
  3253 			return;
       
  3254 			}
       
  3255 		}
       
  3256 	}
       
  3257 
       
  3258 CMdsClauseBuffer& CMdSSqlObjectManipulate::RClauseBuffer::BufferL()
       
  3259 	{
       
  3260 	if ( iNr < 0 && !iBuffer )
       
  3261 		{
       
  3262 		iBuffer = CMdsClauseBuffer::NewL( iSize );
       
  3263 		}
       
  3264 	return *iBuffer;
       
  3265 	}
       
  3266 
       
  3267 void CMdSSqlObjectManipulate::RClauseBuffer::Close()
       
  3268 	{
       
  3269 	if ( iNr < 0 )
       
  3270 		{
       
  3271 		__ASSERT_DEBUG( iBuffer, _L("RClauseBuffer::Close()") );
       
  3272 		if ( iBuffer )
       
  3273 			{
       
  3274 			delete iBuffer;
       
  3275 			iBuffer = NULL;
       
  3276 			}
       
  3277 		}
       
  3278 	else
       
  3279 		{
       
  3280 		iBuffers[iNr].iLock = EFalse;
       
  3281 		iBuffer = NULL;
       
  3282 		}
       
  3283 	}