metadataengine/server/src/mdssqlobjectmanipulate.cpp
changeset 0 c53acadfccc6
child 3 b73a2e62868f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/metadataengine/server/src/mdssqlobjectmanipulate.cpp	Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,3283 @@
+/*
+* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Add, update and remove items in DB.
+*                 Basic DB manipulation engine.
+*
+*/
+
+#include "mdssqlobjectmanipulate.h"
+
+#include "mdcitem.h"
+#include "mdsdbconnectionpool.h"
+#include "mdssqliteconnection.h"
+#include "mdsfindsqlclausedef.h"
+#include "mdsschema.h"
+#include "mdsnamespacedef.h"
+#include "mdsobjectdef.h"
+#include "mdspropertydef.h"
+#include "mdsclausebuffer.h"
+#include "mdsobjectlocklist.h"
+#include "mdsindexer.h"
+#include "mdspreferences.h"
+#include "mdslogger.h"
+#include "mdcserializationbuffer.h"
+#include "mdssqldbmaintenance.h"
+#include "mdcresult.h"
+#include "mdeinternalerror.h"
+
+#include "mdsgetimeiao.h"
+
+#include <e32math.h>
+
+/** logging instance */
+__USES_LOGGER
+
+const TInt KMaxBuffers = 3;
+
+_LIT( KMemoryCard, "MC" );
+
+
+//------------------------------------------------------------------------------------
+// CLASS      CMdSSqlObjectManipulate
+//------------------------------------------------------------------------------------
+
+CMdSIdentifierGenerator* CMdSIdentifierGenerator::NewL( )
+    {
+    CMdSIdentifierGenerator* self = CMdSIdentifierGenerator::NewLC( );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+CMdSIdentifierGenerator* CMdSIdentifierGenerator::NewLC( )
+    {
+    CMdSIdentifierGenerator* self = new ( ELeave ) CMdSIdentifierGenerator( );
+    CleanupStack::PushL( self );
+    self->ConstructL( );
+    return self;
+    }
+
+CMdSIdentifierGenerator::~CMdSIdentifierGenerator()
+    {
+    delete iDigest;
+    }
+
+void CMdSIdentifierGenerator::ConstructL( )
+    {
+    CMdsGetImeiAO * imeigetter = CMdsGetImeiAO::NewLC();
+    iImei = imeigetter->GetIMEI();
+    
+    TTime uTime;
+    uTime.UniversalTime();
+    TInt64 intTime = uTime.Int64();
+    TUint32 rand = Math::Rand( intTime );
+
+    iImei ^= (TInt64)(rand & 0xFF000000) << ( sizeof( TUint32 ) * 8 );
+    
+    CleanupStack::PopAndDestroy(imeigetter);
+    iLastTime = 0;
+    
+    iDigest = CMessageDigestFactory::NewDigestL( CMessageDigest::EMD5 );
+    }
+
+void CMdSIdentifierGenerator::GenerateGuid( TInt64& aGuidHigh, TInt64& aGuidLow )
+	{
+	if (aGuidHigh == 0 && aGuidLow == 0)
+		{
+		TTime currTime;
+		currTime.UniversalTime();
+		const TInt64 tickCount = currTime.Int64();
+		if (iLastTime < tickCount)
+			{
+			iLastTime = tickCount;
+			}
+		else
+			{
+			++iLastTime;
+			}
+
+		//MD5 hash GUID
+		const TInt64 KXorImei = I64LIT( 0x2C3E773D1A25916E );
+		const TInt64 xorImei = iImei ^ KXorImei;
+
+		const TInt KMaxQuidLength = 16;
+		TBuf8<KMaxQuidLength> message;
+		message.SetLength( KMaxQuidLength );
+		Mem::Copy( (TAny*)( message.Ptr() ), &xorImei, sizeof( TInt64 ) );
+		Mem::Copy( (TAny*)( message.Ptr() + sizeof( TInt64 ) ), &iLastTime, sizeof( TInt64 ) );
+
+		TPtrC8 hash = iDigest->Final( message );
+
+		__ASSERT_DEBUG( hash.Size() >= KMaxQuidLength, User::Panic( _L("CMdSIdentifierGenerator::GenerateGuid"), KErrGeneral ) );
+
+		Mem::Copy( &aGuidHigh, hash.Ptr(), sizeof( TInt64 ) );
+		Mem::Copy( &aGuidLow, hash.Ptr() + sizeof( TInt64 ), sizeof( TInt64 ) );
+		//MD5 hash GUID end
+		}
+	}
+
+HBufC* CMdSIdentifierGenerator::GenerateUriL( const CMdsObjectDef& aObjectDef, 
+		const TInt64& aGuidHigh, const TInt64& aGuidLow ) const
+	{
+	_LIT( KDot, "." );
+	HBufC* uri = HBufC::NewLC( aObjectDef.GetName().Length() + 2 /*two dots*/+ 
+			2*KMaxUint64ValueLength );
+
+	TPtr uriPtr( uri->Des() );
+	uriPtr.Append( aObjectDef.GetName() );
+	uriPtr.Append( KDot );
+	uriPtr.AppendNum( aGuidHigh );
+	uriPtr.Append( KDot );
+	uriPtr.AppendNum( aGuidLow );
+	CleanupStack::Pop( uri );
+	return uri;
+	}
+
+
+//-----------------------------------------------------------------------------
+// CLASS      CMdSSqlObjectManipulate
+//-----------------------------------------------------------------------------
+
+CMdSSqlObjectManipulate* CMdSSqlObjectManipulate::NewL( 
+		const CMdsSchema& aSchema, CMdSObjectLockList& aLockList )
+    {
+    CMdSSqlObjectManipulate* self = CMdSSqlObjectManipulate::NewLC( aSchema, 
+    		aLockList );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+CMdSSqlObjectManipulate* CMdSSqlObjectManipulate::NewLC( 
+		const CMdsSchema& aSchema, CMdSObjectLockList& aLockList )
+    {
+    CMdSSqlObjectManipulate* self = new ( ELeave ) CMdSSqlObjectManipulate( 
+    		aSchema, aLockList );
+    CleanupStack::PushL( self );
+    self->ConstructL( );
+    return self;
+    }
+
+CMdSSqlObjectManipulate::~CMdSSqlObjectManipulate()
+    {
+    // doesn't own namespace definition
+	iNamespaceDef = NULL;
+
+	const TInt count = iBuffers.Count();
+	
+	for (TInt i = 0; i < count; ++i)
+		{
+		delete iBuffers[i].iBuffer;
+		}
+	iBuffers.Close();
+
+	delete iGenerator;
+    }
+
+CMdSSqlObjectManipulate::CMdSSqlObjectManipulate( const CMdsSchema& aSchema, 
+		CMdSObjectLockList& aLockList )
+	: iSchema( aSchema ), iGenerator(NULL), iLockList( aLockList ) 
+    {
+    }
+
+void CMdSSqlObjectManipulate::ConstructL( )
+    {
+    
+	iGenerator = CMdSIdentifierGenerator::NewL();
+
+	iNamespaceDef = NULL;
+	
+	TLockBuffer lockBuffer;
+	lockBuffer.iLock = EFalse;
+	for (TInt i = 0; i < KMaxBuffers; ++i)
+		{
+	    CMdsClauseBuffer* buffer = CMdsClauseBuffer::NewLC( 1024 );
+		lockBuffer.iBuffer = buffer;
+		iBuffers.AppendL( lockBuffer );
+		CleanupStack::Pop(); // buffer
+		}
+
+    }
+
+TBool CMdSSqlObjectManipulate::GarbageCollectionL()
+	{
+	return DoGarbageCollectionL();
+	}
+
+void CMdSSqlObjectManipulate::SetNamespace( 
+		const CMdsNamespaceDef* aNamespaceDef )
+	{
+	iNamespaceDef = aNamespaceDef;
+	}
+
+void CMdSSqlObjectManipulate::AddMemoryCardL(TUint32 aMediaId)
+	{
+	TTime currentTime;
+	currentTime.UniversalTime();
+
+	TInt modifiedRowCount = MMdsPreferences::UpdateL( KMemoryCard, 
+			MMdsPreferences::EPreferenceExtraSet, aMediaId, 
+			currentTime.Int64() );
+
+	if( modifiedRowCount <= 0 )
+		{
+		MMdsPreferences::InsertL( KMemoryCard, 
+								  MMdsPreferences::EPreferenceBothSet, 
+								  aMediaId, currentTime.Int64() );
+		}
+	}
+
+void CMdSSqlObjectManipulate::GetMemoryCardL(TUint32& aMediaId)
+	{
+	TInt rowCount = MMdsPreferences::GetL( KMemoryCard, 
+										   MMdsPreferences::EPreferenceValueGet | MMdsPreferences::EPreferenceExtraSortDesc, 
+								  		   aMediaId );
+
+	// if no rows found leave
+	if( rowCount <= 0 )
+		{
+		User::Leave( KErrNotFound );
+		}
+	}
+
+TBool CMdSSqlObjectManipulate::CheckMemoryCardL(TUint32 aMediaId)
+	{
+	TInt rowCount = MMdsPreferences::GetL( KMemoryCard, 
+										   MMdsPreferences::EPreferenceValueGet | MMdsPreferences::EPreferenceValueSet, 
+								  		   aMediaId );
+
+	if( rowCount > 0 )
+		{
+		return ETrue;
+		}
+	return EFalse;
+	}
+
+
+void CMdSSqlObjectManipulate::SetMediaL(TUint32 aMediaId, TChar aDrive,
+		TBool aPresentState)
+	{
+	_LIT( KInsertMedia, "INSERT OR REPLACE INTO MdS_Medias VALUES(?,?,?,?);" );
+
+	RClauseBuffer commonClause( *this, KInsertMedia.iTypeLength );
+	CleanupClosePushL( commonClause );
+	CMdsClauseBuffer& clauseBuffer = commonClause.BufferL();
+	clauseBuffer.BufferL() = KInsertMedia;
+
+	TTime currentTime;
+	currentTime.UniversalTime();
+	const TInt64 currentTime64 = currentTime.Int64();
+	
+    RRowData var;
+    CleanupClosePushL( var );
+    var.ReserveL( 4 ); // reserve space for media ID, drive, present state and time
+    var.AppendL( TColumn( aMediaId ) );
+    var.AppendL( TColumn( (TInt32)aDrive ) );
+    var.AppendL( TColumn( aPresentState ) );
+    var.AppendL( TColumn( currentTime64 ) );
+
+    CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+
+	connection.ExecuteL( clauseBuffer.ConstBufferL(), var );
+
+	CleanupStack::PopAndDestroy( 2, &commonClause ); // var, commonClauseOne
+	}
+
+TBool CMdSSqlObjectManipulate::GetMediaL(TUint32 aMediaId, TChar& aDrive, 
+		TBool& aPresentState)
+	{
+	_LIT( KGetMedia, "SELECT Drive, PresentState FROM MdS_Medias WHERE MediaId=?;" );
+
+	RClauseBuffer commonClause( *this, KGetMedia.iTypeLength );
+	CleanupClosePushL( commonClause );
+	CMdsClauseBuffer& clauseBuffer = commonClause.BufferL();
+	clauseBuffer.BufferL() = KGetMedia;
+
+    RRowData var;
+    CleanupClosePushL( var );
+    var.AppendL( TColumn( aMediaId ) );
+
+    CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+	RMdsStatement statement;
+	CleanupClosePushL( statement );
+	connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
+
+	var.Free();
+	var.Reset();
+
+	TInt32 drive = 0;
+	
+    var.ReserveL( 2 ); // reserve space for drive and present state
+	var.AppendL( TColumn( drive ) );
+	var.AppendL( TColumn( aPresentState ) );
+
+	TBool found = EFalse;
+
+	if( connection.NextRowL( statement, var ) )
+		{
+		var.Column( 0 ).Get( drive );
+		var.Column( 1 ).Get( aPresentState );
+		
+		aDrive = drive;
+		
+		found = ETrue;
+		}
+
+	CleanupStack::PopAndDestroy( 3, &commonClause ); // statement, var, commonClauseOne
+
+	return found;
+	}
+
+TInt32 CMdSSqlObjectManipulate::GetPresentMediasL(TDes8& aMediaInfoBuffer)
+	{
+	_LIT( KGetPresentMedias, "SELECT MediaId, Drive FROM MdS_Medias WHERE PresentState!=?;" );
+
+	RClauseBuffer commonClause( *this, KGetPresentMedias.iTypeLength );
+	CleanupClosePushL( commonClause );
+	CMdsClauseBuffer& clauseBuffer = commonClause.BufferL();
+	clauseBuffer.BufferL() = KGetPresentMedias;
+
+	const TBool notPresentState = EFalse;
+
+    RRowData var;
+    CleanupClosePushL( var );
+    var.AppendL( TColumn( notPresentState ) );
+
+    CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+	RMdsStatement statement;
+	CleanupClosePushL( statement );
+	connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
+
+	var.Free();
+	var.Reset();
+
+	TUint32 mediaId = 0;
+	TInt32 drive = 0;
+
+    var.ReserveL( 2 ); // reserve space for drive and present state
+	var.AppendL( TColumn( mediaId ) );
+	var.AppendL( TColumn( drive ) );
+
+	TInt32 count = 0;
+
+	TInt bufferPosition = 0;
+	
+	const TInt lastBufferPosition = aMediaInfoBuffer.MaxSize() - sizeof( TMdEMediaInfo );
+
+	const TUint8* aMediaInfoBufferPtr = aMediaInfoBuffer.Ptr();
+	
+	while( connection.NextRowL( statement, var ) )
+		{
+		var.Column( 0 ).Get( mediaId );
+		var.Column( 1 ).Get( drive );
+		
+		TMdEMediaInfo mediaInfo;
+		mediaInfo.iMediaId = mediaId;
+		mediaInfo.iDrive = drive;
+
+		if( bufferPosition > lastBufferPosition )
+			{
+			User::Leave( KErrBadDescriptor );
+			}
+	
+		TUint8* ptr = (TUint8*)( aMediaInfoBufferPtr + bufferPosition );
+		
+		Mem::Copy( ptr, &mediaInfo, sizeof( TMdEMediaInfo ) );
+		
+		bufferPosition += sizeof( TMdEMediaInfo );
+		
+		++count;
+		}
+	
+	aMediaInfoBuffer.SetLength( bufferPosition );
+
+	CleanupStack::PopAndDestroy( 3, &commonClause ); // statement, var, commonClauseOne
+
+	return count;
+	}
+
+TItemId CMdSSqlObjectManipulate::SearchNotPresentFileL(TUint32 aMediaId, 
+		TDesC16& aUri, TMdSFileInfo& aFileInfo,
+		TFilePresentStates& aPlaceHolder, TBool& aNotPresentState)
+	{
+	_LIT( KSearchNotPresentFile, "SELECT ObjectId, Flags, LastModifiedDate, Size FROM Object%u WHERE NOT Flags&? AND (Flags&? OR Flags&? OR Flags&? ) AND MediaId=? AND URI=?;" );
+
+	RClauseBuffer commonClauseOne(*this, KSearchNotPresentFile.iTypeLength + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
+	clauseBuffer.BufferL().Format( KSearchNotPresentFile, KDefaultNamespaceDefId );
+
+	TItemId objectId = KNoId;
+	TUint32 flags = 0;
+
+    RRowData var;
+    CleanupClosePushL( var );
+    var.ReserveL( 5 );
+    var.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+    var.AppendL( TColumn( EMdEObjectFlagNotPresent ) ); // not present flag
+    var.AppendL( TColumn( EMdEObjectFlagStartUpNotPresent ) ); // start up not present flag
+    var.AppendL( TColumn( EMdeObjectFlagPending ) ); // pending for composing - needed to complete composing
+    var.AppendL( TColumn( aMediaId ) );
+    var.AppendL( TColumn( aUri ) );
+
+    CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+	RMdsStatement statement;
+	CleanupClosePushL( statement );
+    connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
+
+    TInt64 modifiedTime(0);
+    TUint32 size(0);
+
+    RRowData result;
+    CleanupClosePushL( result );
+    result.ReserveL( 4 );
+    result.AppendL( TColumn( objectId ) );
+    result.AppendL( TColumn( flags ) );
+    result.AppendL( TColumn( modifiedTime ) );
+    result.AppendL( TColumn( size ) );
+
+    // default values (used if object doesn't exist)
+	aPlaceHolder = EMdsNotFound;
+	aNotPresentState = EFalse;
+
+	if( connection.NextRowL( statement, result ) )
+		{
+		result.Column( 0 ).Get( objectId );
+		result.Column( 1 ).Get( flags );
+
+		if ( flags & EMdEObjectFlagPlaceholder )
+			{
+			aPlaceHolder = EMdsPlaceholder;
+			}
+		else
+			{
+			result.Column( 2 ).Get( modifiedTime );
+			result.Column( 3 ).Get( size );
+
+			// check if file is modified
+    		if ( ( aFileInfo.iModifiedTime == modifiedTime ) && ( aFileInfo.iSize == size ) )
+    			{
+    			aPlaceHolder = EMdsNormal;
+    			
+    	        // If images were pending for composing, composer needs to be notified for the composing to complete 
+    	        if( (flags & EMdeObjectFlagPending) && (flags & EMdEObjectFlagStartUpNotPresent) )
+    	            {
+    	            aNotPresentState = ETrue;
+    	            }
+    			}
+    		else
+    			{
+    			aPlaceHolder = EMdsModified;
+    			}
+			}
+
+		if( flags & EMdEObjectFlagNotPresent )
+			{
+			aNotPresentState = ETrue;
+			}
+		}
+
+	CleanupStack::PopAndDestroy( &result );
+	CleanupStack::PopAndDestroy( &statement );
+	CleanupStack::PopAndDestroy( &var );
+	CleanupStack::PopAndDestroy( &commonClauseOne );
+	return objectId;
+	}
+
+void CMdSSqlObjectManipulate::SetFilesToPresentL(const RArray<TItemId>& aObjectIds)
+	{
+	const TInt objectCount = aObjectIds.Count();
+    if ( objectCount > 0 )
+    	{
+		_LIT( KSetFileToPresent, "UPDATE Object%u SET Flags=Flags&? WHERE (Flags&?)<>0 AND ObjectId IN (?" );
+		_LIT( KCommaQuestionmark, ",?");
+		_LIT( KBracketSemicolon, ");");
+		
+		RClauseBuffer commonClauseOne(*this, KSetFileToPresent.iTypeLength + KMaxUintValueLength +
+				( KCommaQuestionmark.iTypeLength * ( objectCount-1 ) ) +
+				KBracketSemicolon.iTypeLength );
+		CleanupClosePushL( commonClauseOne );
+		CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
+		clauseBuffer.BufferL().Format( KSetFileToPresent, KDefaultNamespaceDefId );
+
+	    RRowData var;
+	    CleanupClosePushL( var );
+	    // reset not present and start up not present flags
+	    var.AppendL( TColumn( ~(EMdEObjectFlagNotPresent | EMdEObjectFlagStartUpNotPresent) ) );
+	    var.AppendL( TColumn( (EMdEObjectFlagNotPresent | EMdEObjectFlagStartUpNotPresent) ) );
+	    var.AppendL( TColumn( aObjectIds[0] ) );
+
+	    for ( TInt i = 1; i < objectCount; i++ )
+	    	{
+	    	clauseBuffer.AppendL( KCommaQuestionmark );
+		    var.AppendL( TColumn( aObjectIds[i] ) );
+	    	}
+	    
+	    clauseBuffer.AppendL( KBracketSemicolon );
+	    CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+	    connection.ExecuteL( clauseBuffer.ConstBufferL(), var );
+	
+		CleanupStack::PopAndDestroy( &var );
+		CleanupStack::PopAndDestroy( &commonClauseOne ); 
+    	}
+	}
+
+void CMdSSqlObjectManipulate::SetRelationsToPresentL(TItemId aObjectId, 
+		RArray<TItemId>& aIdArray)
+	{
+	_LIT( KSearchNotPresentRelations, "SELECT RelationId FROM Relations%u WHERE NOT Flags&? AND Flags&? AND (LeftObjectId=? OR RightObjectId=?);" );
+	_LIT( KSetRelationsToPresent, "UPDATE Relations%u SET Flags=Flags&? WHERE Flags&? AND (LeftObjectId=? OR RightObjectId=?);" );
+
+	RClauseBuffer commonClauseOne(*this, KSearchNotPresentRelations.iTypeLength + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
+	clauseBuffer.BufferL().Format( KSearchNotPresentRelations, KDefaultNamespaceDefId );
+
+    CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+    RRowData var;
+    CleanupClosePushL( var );
+    
+    var.ReserveL( 4 ); // reserve space for flags and object IDs
+    var.AppendL( TColumn( EMdERelationFlagDeleted ) );
+    var.AppendL( TColumn( EMdERelationFlagNotPresent ) );
+    var.AppendL( TColumn( aObjectId ) );
+    var.AppendL( TColumn( aObjectId ) );
+
+	RMdsStatement statement;
+	CleanupClosePushL( statement );
+	connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
+
+	var.Free();	var.Reset();
+    TItemId relationId(0);
+    var.AppendL( TColumn( relationId ) );
+	while( connection.NextRowL( statement, var ) )
+		{
+		var.Column( 0 ).Get( relationId );
+		aIdArray.AppendL( relationId );
+		}
+
+	clauseBuffer.ReserveSpaceL( KSetRelationsToPresent.iTypeLength + KMaxUintValueLength );
+	clauseBuffer.BufferL().Format( KSetRelationsToPresent, KDefaultNamespaceDefId );
+
+    var.Free(); 
+    var.Reset();
+
+    var.AppendL( TColumn( ~EMdERelationFlagNotPresent ) ); // reset not present flag
+    var.AppendL( TColumn( EMdERelationFlagNotPresent ) );
+    var.AppendL( TColumn( aObjectId ) );
+    var.AppendL( TColumn( aObjectId ) );
+
+    connection.ExecuteL( clauseBuffer.ConstBufferL(), var );
+
+	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // statement, var, clauseBuffer
+	}
+
+void CMdSSqlObjectManipulate::SetFilesToNotPresentL(TUint32 aMediaId, TBool aStartUp,
+		RArray<TItemId>& aObjectIds)
+	{
+	
+	_LIT( KSearchPresentFilesStartUpL, "SELECT ObjectId FROM Object%u WHERE NOT Flags&? AND MediaId=?;" );
+	_LIT( KSearchPresentFilesL, "SELECT ObjectId FROM Object%u WHERE NOT Flags&? AND NOT Flags&? AND MediaId=?;" );
+	
+	RClauseBuffer commonClauseOne(*this, ( aStartUp ? KSearchPresentFilesStartUpL.iTypeLength : KSearchPresentFilesL.iTypeLength )+ 
+			KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
+	
+	if( aStartUp )
+		{
+		clauseBuffer.BufferL().Format( KSearchPresentFilesStartUpL, KDefaultNamespaceDefId );
+		}
+	else
+		{
+		clauseBuffer.BufferL().Format( KSearchPresentFilesL, KDefaultNamespaceDefId );
+		}
+
+	TItemId objectId = 0;
+
+    RRowData var;
+    CleanupClosePushL( var );
+    
+    var.ReserveL( 3 ); // reserve space for flags and media ID
+    var.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+    if ( !aStartUp )
+    	{
+    	var.AppendL( TColumn( EMdEObjectFlagNotPresent ) ); // present flag
+    	}
+    var.AppendL( TColumn( aMediaId ) );
+
+	RMdsStatement statement;
+	CleanupClosePushL( statement );
+
+    CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+
+    connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
+
+    var.Free(); 
+    var.Reset();
+
+    var.AppendL( TColumn( objectId ) );
+	while( connection.NextRowL( statement, var ) )
+		{
+		var.Column( 0 ).Get( objectId );
+		aObjectIds.AppendL( objectId );
+		}
+
+	_LIT( KSetFilesToNotPresent, "UPDATE Object%u SET Flags=Flags|? WHERE MediaId=?;" );
+	clauseBuffer.ReserveSpaceL( 
+			KSetFilesToNotPresent.iTypeLength + 
+			KMaxUintValueLength ); // TUint32 max value's lenght is 10 numbers so %u + 8
+	clauseBuffer.BufferL().Format( KSetFilesToNotPresent, KDefaultNamespaceDefId );
+
+	var.Free(); 
+	var.Reset();
+
+	if( aStartUp )
+		{
+		var.AppendL( TColumn( EMdEObjectFlagStartUpNotPresent ) ); // set not present flag
+		}
+	else 
+		{
+		var.AppendL( TColumn( EMdEObjectFlagNotPresent ) ); // set not present flag
+		}
+	var.AppendL( TColumn( aMediaId ) );
+
+    connection.ExecuteL( clauseBuffer.ConstBufferL(), var );
+
+    // statement, var, commonClauseOne
+	CleanupStack::PopAndDestroy( 3, &commonClauseOne );
+	}
+
+void CMdSSqlObjectManipulate::SetRelationsToNotPresentL(
+		TUint32 aMediaId, RArray<TItemId>& aRelationIds)
+	{
+	_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" );
+	_LIT( KSetRelationsToPresent, "UPDATE Relations%u SET Flags=Flags|? WHERE NOT Flags&? AND RelationId IN (%S);" );
+
+	// RelationIDs query sql statement
+	RClauseBuffer commonClauseOne(*this, 
+			KSearchPresentRelations.iTypeLength + 
+			KMaxUintValueLength  );
+    CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& clauseBufferOne = commonClauseOne.BufferL();
+	clauseBufferOne.BufferL().Format( KSearchPresentRelations, 
+                KDefaultNamespaceDefId,
+                KDefaultNamespaceDefId,
+                EMdERelationFlagDeleted,
+                EMdERelationFlagNotPresent,
+                aMediaId );
+	
+    CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+    	
+    RRowData var;
+    CleanupClosePushL( var );
+    
+	RMdsStatement statement;
+	CleanupClosePushL( statement );
+
+	connection.ExecuteQueryL( clauseBufferOne.ConstBufferL(), statement, var );
+
+    // Get RelationIDs From query result
+    TItemId relationId(0);
+    var.AppendL( TColumn( relationId ) );
+	while( connection.NextRowL( statement, var ) )
+		{
+		var.Column( 0 ).Get( relationId );
+		aRelationIds.AppendL( relationId );
+		}
+	
+    // Set objects' relations not present by MediaID
+	RClauseBuffer commonClauseTwo(*this, 
+			KSetRelationsToPresent.iTypeLength + 
+			clauseBufferOne.ConstBufferL().Length() );
+	
+    CleanupClosePushL( commonClauseTwo );
+	CMdsClauseBuffer& clauseBufferTwo = commonClauseTwo.BufferL();
+	clauseBufferTwo.BufferL().Format( KSetRelationsToPresent, 
+                                   KDefaultNamespaceDefId,
+                                   &clauseBufferOne.ConstBufferL() );
+
+	var.Free();
+	var.Reset();
+    var.ReserveL( 2 ); 
+    var.AppendL( TColumn( EMdERelationFlagNotPresent ) );
+    var.AppendL( TColumn( EMdERelationFlagNotPresent ) );
+
+    connection.ExecuteL( clauseBufferTwo.ConstBufferL(), var );
+
+    // commonClauseTwo, statement, var, commonClauseOne
+	CleanupStack::PopAndDestroy( 4, &commonClauseOne );
+	}
+
+void CMdSSqlObjectManipulate::RemoveFilesNotPresentL(TUint32 aMediaId, RArray<TItemId>* aObjectIds)
+	{
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+	
+	// collect object IDs from start up not present objects
+	if( aObjectIds )
+		{
+		_LIT( KSelectFilesStartUpNotPresent, "SELECT ObjectId FROM Object%u WHERE NOT Flags&? AND NOT Flags&? AND Flags&? AND MediaId=?;" );
+
+		RClauseBuffer commonClauseOne(*this, 
+				KSelectFilesStartUpNotPresent.iTypeLength + KMaxUintValueLength );
+		CleanupClosePushL( commonClauseOne );
+		CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
+
+		clauseBuffer.BufferL().Format( KSelectFilesStartUpNotPresent, KDefaultNamespaceDefId );
+
+		RRowData var;
+		CleanupClosePushL( var );
+		var.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+		var.AppendL( TColumn( EMdEObjectFlagNotPresent ) );
+		var.AppendL( TColumn( EMdEObjectFlagStartUpNotPresent ) );
+		var.AppendL( TColumn( aMediaId ) );
+
+		RMdsStatement statement;
+		CleanupClosePushL( statement );
+	    connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
+
+		RRowData result;
+	    CleanupClosePushL( result );
+	    TItemId objectId( KNoId );
+	    result.AppendL( TColumn( objectId ) );
+
+		while( connection.NextRowL( statement, result ) )
+			{
+			result.Column( 0 ).Get( objectId );
+			aObjectIds->AppendL( objectId );
+			}
+
+		CleanupStack::PopAndDestroy( &result );
+		CleanupStack::PopAndDestroy( &statement );
+		CleanupStack::PopAndDestroy( &var );
+		CleanupStack::PopAndDestroy( &commonClauseOne );
+		}
+
+	_LIT( KRemoveFilesNotPresent, "UPDATE Object%u SET Flags=Flags|? WHERE NOT Flags&? AND (Flags&? OR Flags&?) AND MediaId=?;" );
+
+	RClauseBuffer commonClauseOne(*this, 
+			KRemoveFilesNotPresent.iTypeLength + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
+	clauseBuffer.BufferL().Format( KRemoveFilesNotPresent, KDefaultNamespaceDefId );
+
+    RRowData var;
+    CleanupClosePushL( var );
+    var.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+    var.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+    var.AppendL( TColumn( EMdEObjectFlagNotPresent ) ); // not present flag
+    var.AppendL( TColumn( EMdEObjectFlagStartUpNotPresent ) ); // start up not present flag
+    var.AppendL( TColumn( aMediaId ) );
+
+	__LOGQUERY_16( _L("RemoveFilesNotPresentL:"), clauseBuffer.ConstBufferL(), var);
+    connection.ExecuteL( clauseBuffer.ConstBufferL(), var );
+
+	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // var, commonClauseOne
+	}
+
+void CMdSSqlObjectManipulate::GetSchemaVersionL(
+		TInt& aMajorVersion, TInt& aMinorVersion)
+	{
+	TInt64 minorVersion;
+	TInt rowCount = MMdsPreferences::GetL( KMdsSchemaVersionName, 
+			MMdsPreferences::EPreferenceBothGet, 
+			aMajorVersion, &minorVersion );
+
+	aMinorVersion = minorVersion;
+
+	// if no rows found leave
+	if( rowCount <= 0 )
+		{
+		User::Leave( KErrNotFound );
+		}
+	}
+
+void CMdSSqlObjectManipulate::SetObjectToPresentByGuidL( 
+		const TInt64& aGuidHigh, const TInt64& aGuidLow )
+	{
+	// get object ID for later queries
+	_LIT( KGetObjectIdByGuid, "SELECT ObjectId FROM Object%u WHERE Flags&? AND GuidHigh=? AND GuidLow=?;" );
+
+	RClauseBuffer commonClauseOne(*this, 
+			KGetObjectIdByGuid.iTypeLength + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
+	clauseBuffer.BufferL().Format( KGetObjectIdByGuid, KDefaultNamespaceDefId );
+
+    RRowData var;
+    CleanupClosePushL( var );
+    var.ReserveL( 3 ); // for flags and GUID high/low in WHERE
+
+    var.AppendL( TColumn( (TUint32)EMdEObjectFlagNotPresent ) );
+    var.AppendL( TColumn( aGuidHigh ) );
+    var.AppendL( TColumn( aGuidLow ) );
+
+	RMdsStatement statement;
+	CleanupClosePushL( statement );
+
+    CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+
+	__LOGQUERY_16( _L("SetObjectToPresentByGuidL q1:"), clauseBuffer.ConstBufferL(), var);
+
+    connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
+
+	var.Free();
+	var.Reset();
+	TItemId objectId = KNoId;
+	var.AppendL( TColumn( objectId ) );
+
+	if( connection.NextRowL( statement, var ) )
+		{
+		var.Column( 0 ).Get( objectId );
+
+		// set object, which object ID is matching, to present state
+		_LIT( KSetObjectToPresentByGuid, "UPDATE Object%u SET Flags=Flags&? WHERE ObjectId=? AND (Flags&?)<>0;" );
+
+		RClauseBuffer commonClauseTwo(*this, 
+				KSetObjectToPresentByGuid.iTypeLength + KMaxUintValueLength);
+		CleanupClosePushL( commonClauseTwo );
+		CMdsClauseBuffer& clauseBuffer2 = commonClauseTwo.BufferL();
+		clauseBuffer2.BufferL().Format( KSetObjectToPresentByGuid, 
+				KDefaultNamespaceDefId );
+
+		var.Free();
+		var.Reset();
+		var.AppendL( TColumn( (TUint32)~EMdEObjectFlagNotPresent ) );
+		var.AppendL( TColumn( objectId ) );
+		
+		var.AppendL( TColumn( (TUint32)EMdEObjectFlagNotPresent ) );
+
+		__LOGQUERY_16( _L("SetObjectToPresentByGuidL q2:"), 
+				clauseBuffer2.ConstBufferL(), var);
+		
+		connection.ExecuteL( clauseBuffer2.ConstBufferL(), var );
+		
+		CleanupStack::PopAndDestroy( &commonClauseTwo );
+
+		// set relations, which left or right object ID is matching, 
+		// to present state
+		_LIT( KSetRelationToPresentByGuid, "UPDATE Relations%u SET Flags=Flags&? WHERE LeftObjectId=? OR RightObjectId=?;" );
+		
+		RClauseBuffer commonClauseThree(*this, 
+				KSetRelationToPresentByGuid.iTypeLength + KMaxUintValueLength);
+		CleanupClosePushL( commonClauseThree );
+		CMdsClauseBuffer& clauseBuffer3 = commonClauseThree.BufferL();
+		clauseBuffer3.BufferL().Format( KSetRelationToPresentByGuid, 
+				KDefaultNamespaceDefId );
+
+		var.Free();
+		var.Reset();
+		var.AppendL( TColumn( (TUint32)~EMdERelationFlagNotPresent ) );
+		var.AppendL( TColumn( objectId ) );
+		var.AppendL( TColumn( objectId ) );
+
+		__LOGQUERY_16( _L("SetObjectToPresentByGuidL q3:"), 
+				clauseBuffer3.ConstBufferL(), var);
+
+		connection.ExecuteL( clauseBuffer3.ConstBufferL(), var );
+		
+		CleanupStack::PopAndDestroy( &commonClauseThree );
+		}
+	// no any matching object
+	else
+		{
+		User::Leave( KErrNotFound );
+		}
+
+	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // statement, var, commonClauseOne
+	}
+
+void CMdSSqlObjectManipulate::ChangePathL(
+		const TDesC& aOldPath, const TDesC& aNewPath, 
+		RArray<TItemId>& aObjectIds)
+	{
+	// collect object IDs from object which match to the old path
+	_LIT( KGetObjectIdByBeginOfUri, "SELECT ObjectId FROM Object%u WHERE NOT Flags&? AND substr(URI, 1, ?) = ?;" );
+
+	RClauseBuffer commonClauseOne(*this, 
+			KGetObjectIdByBeginOfUri.iTypeLength + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& clauseBuffer = commonClauseOne.BufferL();
+	clauseBuffer.BufferL().Format( KGetObjectIdByBeginOfUri, KDefaultNamespaceDefId );
+
+	const TUint32 flags = EMdEObjectFlagNotPresent | EMdEObjectFlagRemoved | EMdEObjectFlagGarbage;
+
+	const TInt oldPathLength = aOldPath.Length();
+
+	RRowData var;
+    CleanupClosePushL( var );
+	var.ReserveL( 3 );
+    var.AppendL( TColumn( flags ) );
+    var.AppendL( TColumn( oldPathLength ) );
+    var.AppendL( TColumn( aOldPath ) );
+
+    CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+
+	RMdsStatement statement;
+	CleanupClosePushL( statement );
+
+	__LOGQUERY_16( _L("ChangePathL q1:"), clauseBuffer.ConstBufferL(), var);
+
+    connection.ExecuteQueryL( clauseBuffer.ConstBufferL(), statement, var );
+
+    var.Free();
+    var.Reset();
+    TItemId objectId( 0 );
+    var.AppendL( TColumn( objectId ) );
+
+	while( connection.NextRowL( statement, var ) )
+		{
+		var.Column( 0 ).Get( objectId );
+		aObjectIds.AppendL( objectId );
+		}
+
+	// update the new path to objects which match with the old path
+	_LIT( KChangeOldPathToNewPath, "UPDATE Object%u SET URI=? || substr(URI, ?, length(URI)) WHERE NOT Flags&? AND substr(URI, 1, ?) = ?;" );
+
+	RClauseBuffer commonClauseTwo(*this, 
+			KChangeOldPathToNewPath.iTypeLength + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseTwo );
+	CMdsClauseBuffer& clauseBuffer2 = commonClauseTwo.BufferL();
+	clauseBuffer2.BufferL().Format( KChangeOldPathToNewPath, KDefaultNamespaceDefId );
+
+	var.Free();
+	var.Reset();
+
+	var.ReserveL( 5 );
+    var.AppendL( TColumn( aNewPath ) );
+    var.AppendL( TColumn( oldPathLength + 1 ) );
+    var.AppendL( TColumn( flags ) );
+    var.AppendL( TColumn( oldPathLength ) );
+    var.AppendL( TColumn( aOldPath ) );
+
+	__LOGQUERY_16( _L("ChangePathL q2:"), clauseBuffer2.ConstBufferL(), var);
+
+	connection.ExecuteL( clauseBuffer2.ConstBufferL(), var );
+
+	CleanupStack::PopAndDestroy( 4, &commonClauseOne ); // commonClauseTwo, statement, var, commonClauseOne
+	}
+
+void CMdSSqlObjectManipulate::ChangeMediaIdL()
+	{
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+	
+	TVolumeInfo volumeInfo;
+	RFs fs;
+	User::LeaveIfError( fs.Connect() );
+	CleanupClosePushL( fs );
+
+	fs.Volume( volumeInfo, EDriveC );
+	CleanupStack::PopAndDestroy( &fs );
+
+	// update the new media id to objects which match with the old id
+	_LIT( KChangeOldIdToNewId, "UPDATE Object%u SET MediaId=? WHERE NOT Flags&? AND MediaId = (SELECT Value FROM MdE_Preferences WHERE Key=?);" );
+
+	RClauseBuffer clauseOne( *this, KChangeOldIdToNewId.iTypeLength + KMaxUintValueLength );
+	CleanupClosePushL( clauseOne );
+	CMdsClauseBuffer& clauseBuffer = clauseOne.BufferL();
+	clauseBuffer.BufferL().Format( KChangeOldIdToNewId, KDefaultNamespaceDefId );
+
+	const TUint32 flags = EMdEObjectFlagNotPresent | EMdEObjectFlagRemoved | EMdEObjectFlagGarbage;
+
+	RRowData var;
+	CleanupClosePushL( var );
+
+	var.ReserveL( 3 );
+	var.AppendL( TColumn( (TUint32) volumeInfo.iUniqueID ) );
+	var.AppendL( TColumn( flags ) );
+	var.AppendL( TColumn( KCMediaIdKey ) );
+
+	__LOGQUERY_16( _L("ChangeMediaIdL q2:"), clauseBuffer.ConstBufferL(), var);
+
+	connection.ExecuteL( clauseBuffer.ConstBufferL(), var );
+	
+	// update the new media id to objects which match with the old id
+	_LIT( KUpdateMediaId, "UPDATE MdE_Preferences SET Value=? WHERE Key = ?;" );
+	
+	var.Free();
+	var.Reset();
+	
+	TTime currentTime;
+	currentTime.UniversalTime();
+	const TInt64 currentTime64 = currentTime.Int64();
+
+	var.ReserveL( 2 );
+	var.AppendL( TColumn( (TUint32) volumeInfo.iUniqueID ) );
+	var.AppendL( TColumn( KCMediaIdKey ) );
+
+	connection.ExecuteL( KUpdateMediaId, var );
+
+	CleanupStack::PopAndDestroy( &var );
+	CleanupStack::PopAndDestroy( &clauseOne );
+	}
+
+const CMdsPropertyDef& CMdSSqlObjectManipulate::ReadPropertyL( 
+		CMdCSerializationBuffer& aBuffer, const CMdsObjectDef& aObjectDef,
+		CMdsClauseBuffer& aBaseObjectClause, CMdsClauseBuffer& aObjectClause,
+		RRowData& aBaseObjectDataRow, RRowData& aObjectDataRow, TUint8& aFlags)
+	{
+	const TMdCProperty& property = TMdCProperty::GetFromBufferL( aBuffer );
+	const CMdsPropertyDef* propertyDef = aObjectDef.GetPropertyByIdL( 
+			property.iPropertyDefId );
+	if ( !propertyDef )
+		{
+#ifdef _DEBUG
+		WRITELOG( "Incorrect property" );
+#endif
+		User::Leave( KErrMdEUnknownPropertyDef );
+		}
+	aFlags = property.iModFlags;
+
+	if (property.iModFlags == EMdEPropertyModNone)
+		{
+		return *propertyDef;
+		}
+
+	const TBool baseObjectProperty = 
+		iBaseObjectDef->GetPropertyByIdL(property.iPropertyDefId) != NULL;
+
+	// if property is not removed add actual value
+	if( !( property.iModFlags & EMdEPropertyModRemove ) )
+		{
+		switch(propertyDef->GetType())
+			{
+			case EPropertyBool:
+				{
+				const TBool boolValue = property.iValue.iInt32;
+				if ( baseObjectProperty )
+					{
+					aBaseObjectDataRow.AppendL( TColumn( boolValue ) );
+					}
+				else
+					{
+					aObjectDataRow.AppendL( TColumn( boolValue ) );
+					}
+				break;
+				}
+			case EPropertyInt8:
+				{
+				const TInt8 int8Value = property.iValue.iInt32;
+				if ( !propertyDef->CheckMinMaxValue( (TInt32)int8Value ) )
+					{
+#ifdef _DEBUG
+					TInt32 debugValue = int8Value;
+					WRITELOG2( "Incorrect property[%S] value: %d", 
+							&propertyDef->GetName(), debugValue );
+#endif
+					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
+					}
+				if ( baseObjectProperty )
+					{
+					aBaseObjectDataRow.AppendL( TColumn( int8Value ) );
+					}
+				else
+					{
+					aObjectDataRow.AppendL( TColumn( int8Value ) );
+					}
+				break;
+				}
+			case EPropertyUint8:
+				{
+				const TUint8 uInt8Value = property.iValue.iUint32;
+				if ( !propertyDef->CheckMinMaxValue( (TInt32)uInt8Value ) )
+					{
+#ifdef _DEBUG
+					TInt32 debugValue = uInt8Value;
+					WRITELOG2( "Incorrect property[%S] value: %d", 
+							&propertyDef->GetName(), debugValue );
+#endif
+					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
+					}
+				if ( baseObjectProperty )
+					{
+					aBaseObjectDataRow.AppendL( TColumn( uInt8Value ) );
+					}
+				else
+					{
+					aObjectDataRow.AppendL( TColumn( uInt8Value ) );
+					}
+				break;
+				}
+			case EPropertyInt16:
+				{
+				const TInt16 int16Value = property.iValue.iInt32;
+				if ( !propertyDef->CheckMinMaxValue( (TInt32)int16Value ) )
+					{
+#ifdef _DEBUG
+					TInt32 debugValue = int16Value;
+					WRITELOG2( "Incorrect property[%S] value: %d", 
+							&propertyDef->GetName(), debugValue );
+#endif
+					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
+					}
+				if ( baseObjectProperty )
+					{
+					aBaseObjectDataRow.AppendL( TColumn( int16Value ) );
+					}
+				else
+					{
+					aObjectDataRow.AppendL( TColumn( int16Value ) );
+					}
+				break;
+				}
+			case EPropertyUint16:
+				{
+				const TUint16 uInt16Value = property.iValue.iUint32;
+				if ( !propertyDef->CheckMinMaxValue( (TInt32)uInt16Value ) )
+					{
+#ifdef _DEBUG
+					TInt32 debugValue = uInt16Value;
+					WRITELOG2( "Incorrect property[%S] value: %d", 
+							&propertyDef->GetName(), debugValue );
+#endif
+					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
+					}
+				if ( baseObjectProperty )
+					{
+					aBaseObjectDataRow.AppendL( TColumn( uInt16Value ) );
+					}
+				else
+					{
+					aObjectDataRow.AppendL( TColumn( uInt16Value ) );
+					}
+				break;
+				}
+			case EPropertyInt32:
+				{
+				const TInt32 int32Value = property.iValue.iInt32;
+				if ( !propertyDef->CheckMinMaxValue( int32Value ) )
+					{
+#ifdef _DEBUG
+					WRITELOG2( "Incorrect property[%S] value: %d", 
+							&propertyDef->GetName(), int32Value );
+#endif
+					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
+					}
+				if ( baseObjectProperty )
+					{
+					aBaseObjectDataRow.AppendL( TColumn( int32Value ) );
+					}
+				else
+					{
+					aObjectDataRow.AppendL( TColumn( int32Value ) );
+					}
+				break;
+				}
+			case EPropertyUint32:
+				{
+				const TUint32 uInt32Value = property.iValue.iUint32;
+				if ( !propertyDef->CheckMinMaxValue( uInt32Value ) )
+					{
+#ifdef _DEBUG
+					WRITELOG2( "Incorrect property[%S] value: %u", 
+							&propertyDef->GetName(), uInt32Value );
+#endif
+					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
+					}
+				if ( baseObjectProperty )
+					{
+					aBaseObjectDataRow.AppendL( TColumn( uInt32Value ) );
+					}
+				else
+					{
+					aObjectDataRow.AppendL( TColumn( uInt32Value ) );
+					}
+				break;
+				}
+			case EPropertyInt64:
+				{
+				const TInt64 int64Value = property.iValue.iInt64;
+				if ( !propertyDef->CheckMinMaxValue( int64Value ) )
+					{
+#ifdef _DEBUG
+					WRITELOG2( "Incorrect property[%S] value: %Ld", 
+							&propertyDef->GetName(), int64Value );
+#endif
+					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
+					}
+				if ( baseObjectProperty )
+					{
+					aBaseObjectDataRow.AppendL( TColumn( int64Value ) );
+					}
+				else
+					{
+					aObjectDataRow.AppendL( TColumn( int64Value ) );
+					}
+				break;
+				}
+			case EPropertyTime:
+				{
+				const TInt64 int64Value = property.iValue.iInt64;
+				if ( !propertyDef->CheckMinMaxValue( int64Value ) )
+					{
+#ifdef _DEBUG					
+					WRITELOG2( "Incorrect property[%S] value: %Ld", 
+							&propertyDef->GetName(), int64Value );
+#endif
+					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
+					}
+				if ( baseObjectProperty )
+					{
+					aBaseObjectDataRow.AppendL( TColumn( int64Value ) );
+					}
+				else
+					{
+					aObjectDataRow.AppendL( TColumn( int64Value ) );
+					}
+				break;
+				}
+			case EPropertyReal32:
+				{
+				const TReal32 real32Value = property.iValue.iReal;
+				if ( !propertyDef->CheckMinMaxValue( real32Value ) )
+					{
+#ifdef _DEBUG
+					TReal64 debugValue = real32Value;
+					WRITELOG2( "Incorrect property[%S] value: %.2f", 
+							&propertyDef->GetName(), debugValue );
+#endif
+					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
+					}
+				if ( baseObjectProperty )
+					{
+					aBaseObjectDataRow.AppendL( TColumn( real32Value ) );
+					}
+				else
+					{
+					aObjectDataRow.AppendL( TColumn( real32Value ) );
+					}
+				break;
+				}
+			case EPropertyReal64:
+				{
+				const TReal64 real64Value = property.iValue.iReal;
+				if ( !propertyDef->CheckMinMaxValue( real64Value ) )
+					{
+#ifdef _DEBUG					
+					WRITELOG2( "Incorrect property[%S] value: %.2f", 
+							&propertyDef->GetName(), real64Value );
+#endif
+					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
+					}
+				if ( baseObjectProperty )
+					{
+					aBaseObjectDataRow.AppendL( TColumn( real64Value ) );
+					}
+				else
+					{
+					aObjectDataRow.AppendL( TColumn( real64Value ) );
+					}
+				break;
+				}
+			case EPropertyText:
+				{
+				aBuffer.PositionL( property.iValue.iPtr.iOffset );
+				TPtrC16 textValue( aBuffer.ReceivePtr16L() );
+				if ( !propertyDef->CheckMinMaxValue( (TInt32)textValue.Length() ) )
+					{
+#ifdef _DEBUG
+					WRITELOG3( "Incorrect property[%S] value: \"%S\", length: %d", 
+							&propertyDef->GetName(), &textValue, 
+							textValue.Length() );
+#endif
+					User::Leave( KErrMdEPropertyValueNotBetweenAllowedMinMax );
+					}
+				if ( baseObjectProperty )
+					{
+					aBaseObjectDataRow.AppendL( TColumn( textValue ) );
+					}
+				else
+					{
+					aObjectDataRow.AppendL( TColumn( textValue ) );
+					}
+				break;
+				}
+			default:
+				User::Leave( KErrMdEUnknownPropertyType );
+			}
+		}
+	// if property is removed add null value
+	else
+		{
+		TPtrC16 val = TPtr16((TUint16*)0, 0);
+		if( baseObjectProperty )
+			{
+			aBaseObjectDataRow.AppendL( TColumn( val ) );
+			}
+		else
+			{
+			aObjectDataRow.AppendL( TColumn( val ) );
+			}
+		}
+
+	if( baseObjectProperty )
+		{
+		aBaseObjectClause.AppendL( KComma );
+		aBaseObjectClause.AppendL( propertyDef->GetName() );
+		}
+	else
+		{
+		aObjectClause.AppendL( KComma );
+		aObjectClause.AppendL( propertyDef->GetName() );
+		}
+	
+	return *propertyDef;
+	}
+
+TItemId CMdSSqlObjectManipulate::AddObjectL( CMdSSqLiteConnection& aConnection, 
+       CMdCSerializationBuffer& aBuffer,
+       RMdsStatement& aMdsBaseObjStatement, RMdsStatement& aMdsObjStatement,
+       const CMdSServerSession* aServerSession )
+	{
+	_LIT( KMdsObjectAddBaseObjectBegin, "INSERT INTO Object%u(ObjectId,ObjectDefId,Flags,MediaId,GuidHigh,GuidLow,URI" );
+	_LIT( KMdsObjectAddBaseObjectMiddle, ") VALUES(?,?,?,?,?,?,?" );
+	_LIT( KMdsObjectAddObjectBegin, "INSERT INTO %S%u(ObjectId" );
+	_LIT( KMdsObjectAddObjectMiddle, ") VALUES(?" );
+	_LIT( KMdsObjectAddObjectEnd,   ");" );
+
+	if ( !iNamespaceDef )
+		{
+		User::Leave( KErrMdEUnknownNamespaceDef );
+		}
+
+	RRowData baseObjectRow;
+	CleanupClosePushL( baseObjectRow );
+	RRowData objectRow;
+	CleanupClosePushL( objectRow );
+
+	const TMdCObject& object = TMdCObject::GetFromBufferL( aBuffer );
+	// there must be at least one property (btw. base object have 7 properties)
+	if (object.iProperties.iPtr.iCount < 1)
+		{
+		User::Leave( KErrMdEMandatoryPropertyMissing );
+		}
+
+	// objectid
+	if (object.iId != KNoId)
+		{
+		User::Leave( KErrAlreadyExists );
+		}
+
+	RSQLIndex sqlIndex;
+	CleanupClosePushL( sqlIndex );
+	const TItemId objectId = sqlIndex.GetId();
+
+	baseObjectRow.AppendL( TColumn( objectId ) );
+	objectRow.AppendL( TColumn( objectId ) );
+
+	// objectdefid
+	const CMdsObjectDef* objectDef = iNamespaceDef->GetObjectByIdL( object.iDefId );
+	if ( !objectDef )
+		{
+		// objectDef doesn't exist
+		User::Leave( KErrMdEUnknownObjectDef );
+		}
+	baseObjectRow.AppendL( TColumn( object.iDefId ) );
+
+	// get BaseObjectDef
+	iBaseObjectDef = iNamespaceDef->GetObjectByIdL( KBaseObjectDefId );
+
+	RClauseBuffer commonClauseOne(*this);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& clauseBaseObject = commonClauseOne.BufferL(); 
+	RClauseBuffer commonClauseTwo(*this);
+	CleanupClosePushL( commonClauseTwo );
+	CMdsClauseBuffer& clauseObject = commonClauseTwo.BufferL(); 
+
+	const TDesC& objName = objectDef->GetName();
+	if(objName != iLastAddedObjName)
+	    {
+        iLastAddedObjName = objName;
+        aMdsBaseObjStatement.Close();
+        aMdsBaseObjStatement = RMdsStatement();
+	    aMdsObjStatement.Close();
+        aMdsObjStatement = RMdsStatement();
+        }
+ 
+    clauseObject.BufferL().Format( KMdsObjectAddObjectBegin, &objName, iNamespaceDef->GetId() );
+	clauseBaseObject.BufferL().Format( KMdsObjectAddBaseObjectBegin, iNamespaceDef->GetId() );
+
+	TUint32 objectFlags = 0;
+	if ( !( object.iFlags & ( EMdEObjectFlagModOpen | EMdEObjectFlagAutoLock ) ) )
+		{
+		User::Leave( KErrMdENotLocked );
+		}
+
+	if (object.iFlags & EMdEObjectFlagConfidential) 
+		{
+		objectFlags |= EMdEObjectFlagConfidential;
+		}
+	if (object.iFlags & EMdEObjectFlagModFreeText)
+		{
+		objectFlags |= EMdEObjectFlagFreetexts;
+		}
+	if (object.iFlags & EMdEObjectFlagPlaceholder)
+		{
+		objectFlags |= EMdEObjectFlagPlaceholder;
+		}
+	if (objectDef->GetFlags() == CMdsObjectDef::EObjectDefFlagsContext)
+		{
+		objectFlags |= EMdEObjectFlagContext;
+		}
+	baseObjectRow.AppendL( TColumn( objectFlags ) );
+
+	// mediaId
+	baseObjectRow.AppendL( TColumn( object.iMediaId ) );
+
+	TInt64 guidHigh = object.iGuidHigh;
+	TInt64 guidLow = object.iGuidLow;
+
+	if (guidLow == 0 && guidHigh == 0)
+		{
+		iGenerator->GenerateGuid( guidHigh, guidLow );
+		}
+
+	baseObjectRow.AppendL( TColumn( guidHigh ) );
+	baseObjectRow.AppendL( TColumn( guidLow ) );
+
+	// uri
+	HBufC* uriBuf = NULL;
+	if (object.iUri.iPtr.iCount == 0)
+		{
+		uriBuf = iGenerator->GenerateUriL( *objectDef, guidHigh, guidLow );
+		}
+	else
+		{
+		aBuffer.PositionL( object.iUri.iPtr.iOffset );
+		uriBuf = aBuffer.ReceiveDes16L();
+		}
+	CleanupStack::PushL( uriBuf );
+	TPtr16 uri( uriBuf->Des() );
+	uri.LowerCase();
+	baseObjectRow.AppendL( TColumn( uri ) );
+
+	const TInt baseObjectRowSizeWithoutProperties = baseObjectRow.Size();
+
+	TInt mandatoryPropertyCount = objectDef->GetMandatoryPropertyCount();
+	
+	// try to add property
+	for ( TUint32 i = 0; i < object.iProperties.iPtr.iCount; ++i )
+		{
+		aBuffer.PositionL( object.iProperties.iPtr.iOffset + i * sizeof(TMdCProperty) );
+		TUint8 modFlags;
+		const CMdsPropertyDef& propertyDef = ReadPropertyL( aBuffer, *objectDef, clauseBaseObject, clauseObject, baseObjectRow, objectRow, modFlags );
+		if ( modFlags == EMdEPropertyModNone )
+			{
+			continue;
+			}
+
+		// check if mandatory property is removed
+		if( propertyDef.GetMandatory() )
+			{
+			if( modFlags & EMdEPropertyModRemove )
+				{
+				User::Leave( KErrMdEMandatoryPropertyMissing );
+				}
+			else
+				{
+				--mandatoryPropertyCount;
+				}
+			}
+		}
+
+	if( mandatoryPropertyCount != 0 )
+		{
+		User::Leave( KErrMdEMandatoryPropertyMissing );
+		}
+
+	clauseBaseObject.AppendL( KMdsObjectAddBaseObjectMiddle );
+
+	const TInt baseObjectPropertyCount = baseObjectRow.Size() - 
+		baseObjectRowSizeWithoutProperties;
+
+	for ( TInt i = 0; i < baseObjectPropertyCount; ++i )
+		{
+		clauseBaseObject.AppendL( KComma );
+		clauseBaseObject.AppendL( KVariable );
+		}
+
+	clauseObject.AppendL( KMdsObjectAddObjectMiddle );
+
+	// object row property count (object row size without object ID)
+	const TInt objectPropertyCount = objectRow.Size() - 1;
+
+	for ( TInt i = 0; i < objectPropertyCount; ++i )
+		{
+		clauseObject.AppendL( KComma );
+		clauseObject.AppendL( KVariable );
+		}
+	
+	clauseBaseObject.AppendL( KMdsObjectAddObjectEnd );
+	clauseObject.AppendL( KMdsObjectAddObjectEnd );
+
+	// EVERYTHING IS OK - add object to DB
+
+	TInt queryResult = 0, err;
+	// add base object properties
+	__LOGQUERY_16( _L("Add BaseObject to DB:"), clauseBaseObject.ConstBufferL(), baseObjectRow);
+	TRAP( err, aConnection.ExecuteL( clauseBaseObject.ConstBufferL(), baseObjectRow, &aMdsBaseObjStatement ) );
+	if (err == KSqlErrConstraint)
+		{
+		__LOG1( ELogQuery, "Adding baseObject constraint error - err:%d", err );
+		TRAP_IGNORE( RemoveObjectForceL( uri, KNoId ) );
+		__LOGQUERY_16( _L("Add AGAIN BaseObject to DB:"), clauseBaseObject.ConstBufferL(), baseObjectRow);
+		TRAP( err, aConnection.ExecuteL( clauseBaseObject.ConstBufferL(), baseObjectRow, &aMdsBaseObjStatement ) );
+		}
+
+	if (err != KErrNone)
+		{
+		__LOG1( ELogQuery, "Adding baseObject failed - err:%d", err );
+		User::Leave( KErrGeneral );
+		}
+
+	if( !( // skip if object definition is "base object"
+		   // and object is placeholder
+			(object.iDefId == KBaseObjectDefId) &&
+			(object.iFlags & EMdEObjectFlagPlaceholder)
+		 ) 
+	  )
+		{	
+		__LOGQUERY_16( _L("Add Object to DB:"), clauseObject.ConstBufferL(), 
+				objectRow);
+		TRAP( err, queryResult = aConnection.ExecuteL( 
+		        clauseObject.ConstBufferL(), objectRow, &aMdsObjStatement ) );
+		if (err != KErrNone || queryResult != 1)
+			{
+			__LOG2( ELogQuery, "Adding object failed - err:%d, queryResult:%d", err, queryResult );
+			TRAP_IGNORE( RemoveObjectForceL( objectId ) );
+			User::Leave( err );
+			}
+		}
+
+	CleanupStack::PopAndDestroy( uriBuf );
+	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // commonClauseTwo, commonClauseOne
+
+	// add freetext to DB
+	if ( object.iFreeTexts.iPtr.iCount > 0 )
+		{
+		aBuffer.PositionL( object.iFreeTexts.iPtr.iOffset );
+		TRAP( err, AddFreeTextL( aBuffer, object.iFreeTexts.iPtr.iCount, objectId ) );
+		if (err != KErrNone)
+			{
+			__LOG1( ELogQuery, "Adding object freetext failed - err:%d", err );
+			TRAP_IGNORE( RemoveObjectForceL( objectId ) );
+			User::Leave( err );
+			}
+		}
+
+	sqlIndex.Commit();
+	CleanupStack::PopAndDestroy( &sqlIndex );
+	CleanupStack::PopAndDestroy( 2, &baseObjectRow ); // objectRow, baseObjectRow
+
+	if( ( object.iFlags & EMdEObjectFlagAutoLock ) && aServerSession )
+		{
+		iLockList.LockObjectL( *aServerSession, *iNamespaceDef, objectId );
+		}
+	
+	return objectId;
+	}
+
+TUint32 CMdSSqlObjectManipulate::AddFreeTextToDBL( TPtrC16& aWord, TItemId aObjectId,
+    TInt32 aPosition, TBool aSearch )
+	{
+	_LIT( KMdsFreeTextAdd, "INSERT INTO TextSearch%d(WordId,ObjectId,Position) VALUES(?,?,?)" );
+	_LIT( KMdsFreeTextDictAdd, "INSERT INTO TextSearchDictionary%d(Word) VALUES(?)" );
+
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+
+	RClauseBuffer commonClauseOne(*this);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& freeTextAdd     = commonClauseOne.BufferL(); 
+	RClauseBuffer commonClauseTwo(*this);
+	CleanupClosePushL( commonClauseTwo );
+	CMdsClauseBuffer& freeTextDictAdd = commonClauseTwo.BufferL();
+
+	freeTextAdd.BufferL().Format( KMdsFreeTextAdd, iNamespaceDef->GetId() );
+	freeTextDictAdd.BufferL().Format( KMdsFreeTextDictAdd, iNamespaceDef->GetId() );
+
+	TItemId freeTextId = KNoId;
+	RRowData freeTextRow;
+	CleanupClosePushL( freeTextRow );
+	RRowData freeTextRowDict;
+	CleanupClosePushL( freeTextRowDict );
+
+	freeTextRow.ReserveL( 3 );
+
+	freeTextRow.AppendL( TColumn(KNoId) );
+	freeTextRow.AppendL( TColumn(aObjectId) );
+	freeTextRow.AppendL( TColumn(aPosition) );
+
+    freeTextId = FindFreeTextInDbL( aWord );
+	if ( aSearch && freeTextId )
+		{
+		freeTextRow.Column(0).Set( freeTextId );
+		__LOGQUERY_16( _L("Add FreeText index to DB:"), 
+				freeTextAdd.ConstBufferL(), freeTextRow);
+		connection.ExecuteL( freeTextAdd.ConstBufferL(), freeTextRow );
+		}
+	else
+		{
+		freeTextRowDict.AppendL( TColumn( aWord ) );
+		__LOGQUERY_16( _L("Add FreeText to DB:"), 
+				freeTextDictAdd.ConstBufferL(), freeTextRowDict);
+		TRAPD( err, freeTextId = MMdSIndexer::ExecuteAndGetIndexL( 
+				freeTextDictAdd.ConstBufferL(), freeTextRowDict ) );
+		if (err != KErrNone || freeTextId == KNoId)
+			{
+			__LOG2( ELogQuery, "Adding freetextDict failed - err:%d, freeTextId:%d", 
+					err, freeTextId );
+			User::Leave( KErrGeneral );
+			}
+		
+		freeTextRow.Column(0).Set( freeTextId );
+		connection.ExecuteL( freeTextAdd.ConstBufferL(), freeTextRow );
+		}
+
+	CleanupStack::PopAndDestroy( 4, &commonClauseOne ); // freeTextRowDict, freeTextRow, commonClauseTwo, commonClauseOne
+	return freeTextId;
+	}
+
+TInt CMdSSqlObjectManipulate::AddFreeTextL( CMdCSerializationBuffer& aBuffer, TInt aFreeTextCount, TItemId aObjectId )
+	{
+	TInt freeTextAdded = 0;
+
+	for ( TUint32 i = 0; i < aFreeTextCount; ++i )
+		{
+		TPtrC16 freeText = aBuffer.ReceivePtr16L();
+		AddFreeTextToDBL( freeText, aObjectId, i );
+		++freeTextAdded;
+		}
+	return freeTextAdded;
+	}
+
+TItemId CMdSSqlObjectManipulate::FindFreeTextInDbL( TPtrC16 aFreeText )
+	{
+	_LIT( KMdsFreeTextSearch, "SELECT WordId FROM TextSearchDictionary%d WHERE Word=? LIMIT 1;" );
+	
+	RClauseBuffer commonClauseOne(*this, KMdsFreeTextSearch.iTypeLength + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& freeTextSearchClause = commonClauseOne.BufferL();
+	freeTextSearchClause.BufferL().Format( KMdsFreeTextSearch, iNamespaceDef->GetId() );
+
+	TItemId freeTextId = 0;
+	RRowData wordRow;
+	CleanupClosePushL( wordRow );
+	RRowData idRow;
+	CleanupClosePushL( idRow );
+	RMdsStatement query;
+	CleanupClosePushL( query );
+	
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+
+	wordRow.AppendL( TColumn( aFreeText ) );
+	idRow.AppendL( TColumn( freeTextId ) );
+	connection.ExecuteQueryL( freeTextSearchClause.ConstBufferL(), query, wordRow );
+	if( connection.NextRowL( query, idRow ) )
+		{
+		idRow.Column( 0 ).Get( freeTextId );
+		}
+
+	CleanupStack::PopAndDestroy( 4, &commonClauseOne ); // query, idRow, wordRow, commonClauseOne
+	return freeTextId;
+	}
+
+void CMdSSqlObjectManipulate::RemoveObjectForceL( const TDesC16& aUri, TItemId aObjectId )
+	{
+	_LIT( KMdsRemoveObjectByUri, "DELETE FROM Object%u WHERE Flags&? AND ObjectId!=? AND URI=?;" );
+
+	if ( !iNamespaceDef )
+		{
+		User::Leave( KErrMdEUnknownNamespaceDef );
+		}
+
+	RClauseBuffer commonClauseOne(*this, KMdsRemoveObjectByUri.iTypeLength + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& removeObjectClause = commonClauseOne.BufferL();
+
+	removeObjectClause.BufferL().Format( KMdsRemoveObjectByUri, 
+			iNamespaceDef->GetId() );
+
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+
+    // do remove
+    RRowData varRemove;
+    CleanupClosePushL( varRemove );
+    varRemove.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+    varRemove.AppendL( TColumn( aObjectId ) );
+    varRemove.AppendL( TColumn( aUri ) );
+
+#ifdef _DEBUG    
+#ifdef LOG_MASTER_FLAG
+	TInt queryResult = 0; // For debug
+	__LOGQUERY_16( _L("Remove FORCE object using URI:"), 
+			removeObjectClause.ConstBufferL(), varRemove);
+	TRAPD( err, queryResult = connection.ExecuteL( 
+			removeObjectClause.ConstBufferL(), varRemove ) );
+	if( err != KErrNone )
+		{
+		__LOG2( ELogQuery, "Remove FORCE object err:%d, queryResult:%d", err, queryResult );
+		}
+#else
+    TRAP_IGNORE( connection.ExecuteL( removeObjectClause.ConstBufferL(), varRemove ) );
+#endif // LOG_MASTER_FLAG
+#else
+    TRAP_IGNORE( connection.ExecuteL( removeObjectClause.ConstBufferL(), varRemove ) );    
+#endif // _DEBUG
+	
+	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // varRemove, commonClauseOne
+	}
+
+// USE WITH CAUTION !!!
+// THIS FUNCTION REMOVES OBJECT WITHOUT ANY CHECKING
+// ONLY FOR INTERNAL USE !!!
+void CMdSSqlObjectManipulate::RemoveObjectForceL( TItemId aObjectId )
+	{
+	_LIT( KMdsRemoveObjectById, "DELETE FROM Object%u WHERE ObjectId=?;" );
+
+	if ( !iNamespaceDef )
+		{
+		User::Leave( KErrMdEUnknownNamespaceDef );
+		}
+
+	RClauseBuffer commonClauseOne(*this,  KMdsRemoveObjectById.iTypeLength + KMaxUintValueLength );
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& removeObjectClause = commonClauseOne.BufferL();
+
+	removeObjectClause.BufferL().Format( KMdsRemoveObjectById, iNamespaceDef->GetId() );
+
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+
+    // do remove
+    RRowData varRemove;
+    CleanupClosePushL( varRemove );
+    varRemove.AppendL( TColumn( aObjectId ) );
+
+#ifdef _DEBUG    
+#ifdef LOG_MASTER_FLAG
+	TInt queryResult = 0; // For debug
+	__LOGQUERY_16( _L("Remove object using ID:"), 
+			removeObjectClause.ConstBufferL(), varRemove);
+	TRAPD( err, queryResult = connection.ExecuteL( 
+			removeObjectClause.ConstBufferL(), varRemove ) );
+	if ( err != KErrNone )
+		{
+		__LOG2( ELogQuery, "Remove FORCE Object err:%d, queryResult:%d", err, queryResult );
+		}
+#else
+    TRAP_IGNORE( connection.ExecuteL( removeObjectClause.ConstBufferL(), varRemove ) );
+#endif // LOG_MASTER_FLAG
+#else
+    TRAP_IGNORE( connection.ExecuteL( removeObjectClause.ConstBufferL(), varRemove ) );  
+#endif // _DEBUG
+    
+	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // varRemove, commonClauseOne
+	}
+
+CMdCSerializationBuffer* CMdSSqlObjectManipulate::CheckObjectL( TInt aResultBufferSize, 
+		const TDesC& aUri, TDefId aNamespaceDefId )
+	{
+	_LIT( KMdsCheckObjectByUri, "SELECT ObjectId, ObjectDefId, Flags FROM Object%u WHERE URI=?;" );
+
+	RClauseBuffer commonClauseOne(*this, KMdsCheckObjectByUri.iTypeLength + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& checkObjectClause = commonClauseOne.BufferL();
+
+	checkObjectClause.BufferL().Format( KMdsCheckObjectByUri, aNamespaceDefId );
+
+    RRowData rowData;
+    CleanupClosePushL( rowData );
+    rowData.AppendL( TColumn( aUri ) );
+    
+    RMdsStatement query;
+	CleanupClosePushL( query );
+
+	CMdSSqLiteConnection& db = MMdSDbConnectionPool::GetDefaultDBL();
+
+	db.ExecuteQueryL( checkObjectClause.ConstBufferL(), query, rowData );
+
+	rowData.Free();	rowData.Reset();
+	rowData.ReserveL( 3 ); // space for SELECTs
+
+	TMdCObject object;
+    rowData.AppendL( TColumn( object.iId ) );
+    rowData.AppendL( TColumn( object.iDefId ) );
+    rowData.AppendL( TColumn( object.iFlags ) );
+
+    CMdCSerializationBuffer* buffer = NULL;
+	if ( db.NextRowL( query, rowData ) )
+		{
+		rowData.Column(0).Get( object.iId );
+		rowData.Column(1).Get( object.iDefId );
+		rowData.Column(2).Get( object.iFlags );
+
+		buffer = CMdCSerializationBuffer::NewLC( aResultBufferSize );
+		object.SerializeL( *buffer );
+		CleanupStack::Pop( buffer );
+		}
+	else
+		{
+		User::Leave( KErrNotFound );
+		}
+
+	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // query, rowData, commonClauseOne
+
+	return buffer;
+	}
+
+CMdCSerializationBuffer* CMdSSqlObjectManipulate::CheckObjectL( TInt aResultBufferSize, 
+		TItemId aId, TDefId aNamespaceDefId )
+	{
+	_LIT( KMdsCheckObjectById, "SELECT ObjectDefId, Flags FROM Object%u WHERE ObjectId=?;" );
+
+	RClauseBuffer commonClauseOne(*this, KMdsCheckObjectById.iTypeLength + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& checkObjectClause = commonClauseOne.BufferL();
+
+	checkObjectClause.BufferL().Format( KMdsCheckObjectById, aNamespaceDefId );
+	
+    RRowData rowData;
+    CleanupClosePushL( rowData );
+    rowData.AppendL( TColumn( aId ) );
+
+    RMdsStatement query;
+	CleanupClosePushL( query );
+
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+
+	connection.ExecuteQueryL( checkObjectClause.ConstBufferL(), query, rowData );
+
+	rowData.Free();	rowData.Reset();
+	rowData.ReserveL( 2 ); // space for SELECTs
+
+	TMdCObject object;
+	object.iId = aId;
+    rowData.AppendL( TColumn( object.iDefId ) );
+    rowData.AppendL( TColumn( object.iFlags ) );
+
+    CMdCSerializationBuffer* buffer = NULL;
+	if ( connection.NextRowL( query, rowData ) )
+		{
+		rowData.Column(0).Get( object.iDefId );
+		rowData.Column(1).Get( object.iFlags );
+
+		buffer = CMdCSerializationBuffer::NewLC( aResultBufferSize );
+		object.SerializeL( *buffer );
+		CleanupStack::Pop( buffer );
+		}
+	else
+		{
+		User::Leave( KErrNotFound );
+		}
+
+	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // query, rowData, commonClauseOne
+
+	return buffer;
+	}
+
+CMdCSerializationBuffer* CMdSSqlObjectManipulate::CheckObjectL( TInt aResultBufferSize, 
+		CMdCSerializationBuffer& aIds, TDefId aNamespaceDefId )
+	{
+
+	aIds.PositionL( KNoOffset );
+	TUint32 idCount = 0;
+	aIds.ReceiveL( idCount );
+
+	// if no IDs, just return 0 objects
+	if( idCount == 0 )
+		{
+		CMdCSerializationBuffer* buffer = 
+			CMdCSerializationBuffer::NewLC( CMdCSerializationBuffer::KRequiredSizeForTUint32 );
+		buffer->InsertL( idCount );
+		return buffer;
+		}
+
+	_LIT( KMdsCheckObjectByIds, "SELECT ObjectId, ObjectDefId, Flags FROM Object%u WHERE ObjectId IN(?" );
+	_LIT( KMdsCheckObjectByIdsAppend, ",?" );
+	_LIT( KMdsCheckObjectByIdsEnd, ");" );
+
+	RClauseBuffer commonClauseOne(*this, KMdsCheckObjectByIds.iTypeLength + KMaxUintValueLength + 
+										 KMdsCheckObjectByIdsAppend.iTypeLength * (idCount - 1) + 
+										 KMdsCheckObjectByIdsEnd.iTypeLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& checkObjectClause = commonClauseOne.BufferL();
+	
+	RRowData rowData;
+	CleanupClosePushL( rowData );
+
+	checkObjectClause.BufferL().Format( KMdsCheckObjectByIds, aNamespaceDefId );
+	TItemId id;
+	aIds.ReceiveL( id );
+	rowData.AppendL( TColumn( id ) );
+	
+	for( TUint32 i = 1; i < idCount; i++ )
+		{
+		checkObjectClause.BufferL().Append( KMdsCheckObjectByIdsAppend );
+		aIds.ReceiveL( id );
+		rowData.AppendL( TColumn( id ) );
+		}
+
+	checkObjectClause.BufferL().Append( KMdsCheckObjectByIdsEnd );
+
+	RMdsStatement query;
+	CleanupClosePushL( query );
+
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+
+	connection.ExecuteQueryL( checkObjectClause.ConstBufferL(), query, rowData );
+
+	CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC( aResultBufferSize );
+	
+	// initialize with 0 objects (will be updated later)
+	TUint32 resultObjectCount = 0;
+	buffer->InsertL( resultObjectCount );
+
+	rowData.Free();
+	rowData.Reset();
+
+	rowData.ReserveL( 3 ); // space for SELECT's object
+	
+	TMdCObject object;
+	rowData.AppendL( TColumn( object.iId ) );
+	rowData.AppendL( TColumn( object.iDefId ) );
+	rowData.AppendL( TColumn( object.iFlags ) );
+
+	while( connection.NextRowL( query, rowData ) )
+		{
+		rowData.Column(0).Get( object.iId );
+		rowData.Column(1).Get( object.iDefId );
+		rowData.Column(2).Get( object.iFlags );
+
+		object.SerializeL( *buffer );
+		++resultObjectCount;
+		}
+
+	// update object count
+	buffer->PositionL( KNoOffset );
+	buffer->InsertL( resultObjectCount );
+
+	CleanupStack::Pop( buffer );
+	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // query, rowData, commonClauseOne
+	
+	return buffer;
+	}
+
+static TInt CompareTItemIds( const TItemId& aLeft, const TItemId& aRight )
+	{
+	return aLeft - aRight;
+	}
+
+void CMdSSqlObjectManipulate::CollectRemovedItemsL( RArray<TItemId>& aRemoveIds, RArray<TItemId>& aObjectIds,
+                                                    RArray<TItemId>& aRelationIds, RArray<TItemId>& /*aEventIds*/ )
+	{
+	_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(?" );
+	_LIT( KCollectUpdateObjectBegin,    "UPDATE Object%u SET Flags=Flags|? WHERE ObjectId IN(?" );
+	_LIT( KCollectUpdateRelationsBegin, "UPDATE Relations%u SET Flags=Flags|? WHERE RelationId IN(?" );
+	_LIT( KCollectMiddle, ",?" );
+	_LIT( KCollectEnd,    ");" );
+
+	const TInt removeIdsCount = aRemoveIds.Count();
+	if (removeIdsCount < 1)
+		{
+		return;
+		}
+
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+	RClauseBuffer commonClauseOne(*this,  KCollectGetDeleteId().Length() + 2 * KMaxUintValueLength +
+											(removeIdsCount-1) * KCollectMiddle().Length() +
+											KCollectEnd().Length());
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& buffer = commonClauseOne.BufferL();
+
+	// getting removed object id and relation id
+	RRowData dataRow;
+	CleanupClosePushL( dataRow );
+	dataRow.ReserveL( removeIdsCount );
+	dataRow.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+	buffer.BufferL().Format( KCollectGetDeleteId, iNamespaceDef->GetId(), iNamespaceDef->GetId() );
+	for (TInt i = 0; i < removeIdsCount; ++i)
+		{
+		if(i>0)
+			{
+			buffer.AppendL( KCollectMiddle );
+			}
+		dataRow.AppendL( TColumn( aRemoveIds[i] ) );
+		}
+	buffer.AppendL( KCollectEnd );
+
+	RMdsStatement objectQuery;
+	CleanupClosePushL( objectQuery );
+
+	__LOGQUERY_16( _L("Find objects to delete:"), buffer.ConstBufferL(), dataRow);
+	connection.ExecuteQueryL( buffer.ConstBufferL(), objectQuery, dataRow );
+
+	dataRow.Free();	dataRow.Reset();
+	TItemId objectId = KNoId;
+    TItemId prevId = objectId;
+    TItemId relationId = KNoId;
+	dataRow.AppendL( TColumn( objectId ) );
+	dataRow.AppendL( TColumn( relationId ) );
+	while ( connection.NextRowL( objectQuery, dataRow ) )
+		{
+		dataRow.Column(0).Get( objectId );
+		if (objectId != prevId)
+			{
+			aObjectIds.AppendL( objectId );
+			prevId = objectId;
+			}
+		if (!dataRow.Column(1).IsNull())
+			{
+			dataRow.Column(1).Get( relationId );
+			aRelationIds.InsertInOrder( relationId, TLinearOrder<TItemId>( CompareTItemIds ) );
+			}
+		else
+			{
+			dataRow.Column(1).Set( relationId );
+			}
+		}
+
+	// mark object's as removed
+	// remove only item that are OK to remove (not removed earlier)
+	const TInt removeObjectCount = aObjectIds.Count();
+	if ( removeObjectCount > 0 )
+		{
+		buffer.ReserveSpaceL( KCollectUpdateObjectBegin().Length() + KMaxUintValueLength +
+							   (removeObjectCount-1) * KCollectMiddle().Length() +
+							   KCollectEnd().Length() );
+
+		buffer.BufferL().Format( KCollectUpdateObjectBegin, iNamespaceDef->GetId() );
+
+		dataRow.Free();
+		dataRow.Reset();
+		dataRow.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+
+		for (TInt i = 0; i < removeObjectCount; ++i)
+			{
+			if(i>0)
+				{
+				buffer.AppendL( KCollectMiddle );
+				}
+			dataRow.AppendL( TColumn( aObjectIds[i] ) );
+			}
+		buffer.AppendL( KCollectEnd );
+
+		__LOGQUERY_16( _L("Remove objects:"), buffer.ConstBufferL(), dataRow);
+		connection.ExecuteL( buffer.ConstBufferL(), dataRow );
+		}
+
+	// mark relations as removed
+	// remove only item that are OK to remove (not removed earlier)
+	const TInt removeRelationCount = aRelationIds.Count();
+	if ( removeRelationCount > 0 )
+		{
+		buffer.ReserveSpaceL( KCollectUpdateRelationsBegin().Length() + KMaxUintValueLength +
+							   (removeRelationCount-1) * KCollectMiddle().Length() +
+							   KCollectEnd().Length() );
+
+		buffer.BufferL().Format( KCollectUpdateRelationsBegin, iNamespaceDef->GetId() );
+
+		dataRow.Free();	dataRow.Reset();
+		dataRow.ReserveL( 1 + removeRelationCount );
+		dataRow.AppendL( TColumn( EMdERelationFlagDeleted ) );
+
+		for ( TInt i = 0; i < removeRelationCount; ++i )
+			{
+			if( i > 0 )
+				{
+				buffer.AppendL( KCollectMiddle );
+				}
+			dataRow.AppendL( TColumn( aRelationIds[i] ) );
+			}
+		buffer.AppendL( KCollectEnd );
+
+		__LOGQUERY_16( _L("Remove relations:"), buffer.ConstBufferL(), dataRow);
+		connection.ExecuteL( buffer.ConstBufferL(), dataRow );
+		}
+
+
+	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // objectQuery, dataRow, commonClauseOne
+	}
+
+void CMdSSqlObjectManipulate::RemoveObjectsByIdL( 
+		CMdCSerializationBuffer& aBuffer, TInt aCount, RArray<TItemId>& aIdArray, 
+		RArray<TItemId>& aRelationIds, RArray<TItemId>& aEventIds )
+	{
+	if ( !iNamespaceDef )
+		{
+		User::Leave( KErrMdEUnknownNamespaceDef );
+		}
+
+	RArray<TItemId> objectIds;
+	CleanupClosePushL( objectIds );
+
+	TItemId objectId = KNoId;
+
+	objectIds.ReserveL( aCount );
+	for (TUint32 i = 0; i < aCount; ++i)
+		{
+		aBuffer.ReceiveL( objectId );
+		if ( objectId != KNoId )
+			{
+			if ( iLockList.IsLocked( *iNamespaceDef, objectId ) )
+				{
+				iLockList.UnlockById( *iNamespaceDef, objectId );
+				}
+
+			objectIds.AppendL( objectId );
+			}
+		}
+
+	CollectRemovedItemsL( objectIds, aIdArray, aRelationIds, aEventIds );
+
+    CleanupStack::PopAndDestroy( &objectIds );
+	}
+
+void CMdSSqlObjectManipulate::RemoveObjectsByUriL( 
+		CMdCSerializationBuffer& aBuffer, TInt aCount, RArray<TItemId>& aIdArray,
+        RArray<TItemId>& aRelationIds, RArray<TItemId>& aEventIds )
+	{
+	if ( !iNamespaceDef )
+		{
+		User::Leave( KErrMdEUnknownNamespaceDef );
+		}
+
+	RArray<TItemId> objectIds;
+	CleanupClosePushL( objectIds );
+
+	TUint32 flags;
+	TItemId objectId = KNoId;
+	objectIds.ReserveL( aCount );
+	for (TUint32 i = 0; i < aCount; ++i)
+		{
+		TPtrC16 uri = aBuffer.ReceivePtr16L();
+        objectId = SearchObjectByUriL( uri, flags );
+		if ( objectId != KNoId )
+			{
+			// unlock object, so update is no possible anymore
+			if ( iLockList.IsLocked( *iNamespaceDef, objectId ) )
+				{
+				iLockList.UnlockById( *iNamespaceDef, objectId );
+				}
+			
+			objectIds.AppendL( objectId );
+			}
+		}
+
+	CollectRemovedItemsL( objectIds, aIdArray, aRelationIds, aEventIds );
+
+    CleanupStack::PopAndDestroy( &objectIds );
+	}
+
+TItemId CMdSSqlObjectManipulate::SearchObjectByUriL( const TDesC16& aUri, 
+		TUint32& aFlags )
+	{
+	_LIT( KMdsSearchObjectbyUri, "SELECT ObjectId,Flags FROM Object%u WHERE NOT Flags&? AND NOT Flags&? AND URI=? LIMIT 1;" );
+
+	if ( !iNamespaceDef )
+		{
+		User::Leave( KErrMdEUnknownNamespaceDef );
+		}
+
+	RClauseBuffer commonClauseOne(*this, KMdsSearchObjectbyUri.iTypeLength + KMaxUintValueLength );
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& searchUriClause = commonClauseOne.BufferL();
+
+	searchUriClause.BufferL().Format( KMdsSearchObjectbyUri, iNamespaceDef->GetId() );
+
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+
+	TItemId objectId = KNoId;
+	aFlags = 0;
+
+    RRowData varSearch;
+    CleanupClosePushL( varSearch );
+    varSearch.AppendL( TColumn( EMdEObjectFlagNotPresent ) );
+    varSearch.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+    varSearch.AppendL( TColumn( aUri ) );
+
+	RMdsStatement getQuery;
+    CleanupClosePushL( getQuery );
+
+	__LOGQUERY_16( _L("Search object by URI:"), 
+			searchUriClause.ConstBufferL(), varSearch);
+	TRAPD( err, connection.ExecuteQueryL( 
+			searchUriClause.ConstBufferL(), getQuery, varSearch ) );
+
+	varSearch.Free();
+	varSearch.Reset();
+	varSearch.AppendL( TColumn( objectId ) );
+	varSearch.AppendL( TColumn( aFlags ) );
+	if ( err == KErrNone && connection.NextRowL( getQuery, varSearch ) )
+		{
+		varSearch.Column(0).Get( objectId );
+		varSearch.Column(1).Get( aFlags );
+		}
+
+	CleanupStack::PopAndDestroy( 2, &varSearch ); // getQuery, varSearch
+	CleanupStack::PopAndDestroy( &commonClauseOne );
+	return objectId;
+	}
+
+TItemId CMdSSqlObjectManipulate::UpdateObjectL( 
+		CMdSSqLiteConnection& aConnection, CMdCSerializationBuffer& aBuffer )
+	{
+	_LIT( KMdsObjectUpdateBaseObjectBegin,     "UPDATE Object%u SET " );
+	_LIT( KMdsObjectUpdateBaseObjectFlags,     "Flags=? " );
+	_LIT( KMdsObjectUpdateBaseObjectEnd,       ",MediaId=?,GuidHigh=?,GuidLow=?,URI=? ");
+	_LIT( KMdsObjectUpdateObjectBegin,         "UPDATE %S%u SET " );
+	_LIT( KMdsObjectUpdateEnd,                 " WHERE ObjectId=?;" );
+	_LIT( KUpdateEqual, "=?" );
+
+	if ( !iNamespaceDef )
+		{
+		User::Leave( KErrMdEUnknownNamespaceDef );
+		}
+
+	const TMdCObject& object = TMdCObject::GetFromBufferL( aBuffer );
+
+	// objectid
+	if (object.iId == KNoId)
+		{
+		User::Leave( KErrArgument );
+		}
+
+	// object must be locked
+	if (!iLockList.IsLocked(*iNamespaceDef, object.iId))
+		{
+		User::Leave( KErrMdENotLocked );
+		}
+
+	// objectdefid
+	// objectDef exists ??
+	const CMdsObjectDef* objectDef = iNamespaceDef->GetObjectByIdL( 
+			object.iDefId );
+	if ( !objectDef )
+		{
+		User::Leave( KErrMdEUnknownObjectDef );
+		}
+
+	// get BaseObjectDef
+	iBaseObjectDef = iNamespaceDef->GetObjectByIdL( KBaseObjectDefId );
+
+	TUint32 objectFlags = 0;
+	if (object.iFlags & EMdEObjectFlagConfidential)
+		{
+		objectFlags |= EMdEObjectFlagConfidential;
+		}
+	if (object.iFlags & EMdEObjectFlagModFreeText)
+		{
+		objectFlags |= EMdEObjectFlagFreetexts;
+		}
+	if (object.iFlags & EMdEObjectFlagPlaceholder)
+		{
+		objectFlags |= EMdEObjectFlagPlaceholder;
+		}
+	if (objectDef->GetFlags() == CMdsObjectDef::EObjectDefFlagsContext)
+		{
+		objectFlags |= EMdEObjectFlagContext;
+		}
+
+	if (!(object.iFlags & EMdEObjectFlagModOpen))
+		{
+		User::Leave( KErrMdENotLocked );
+		}
+
+	const TBool KUpdateModObject   = 
+		object.iFlags & EMdEObjectFlagModObject   ? ETrue : EFalse;
+	const TBool KUpdateModFreeText = 
+		object.iFlags & EMdEObjectFlagModFreeText ? ETrue : EFalse;
+	const TBool KUpdateModProperty = 
+		object.iFlags & EMdEObjectFlagModProperty ? ETrue : EFalse;
+
+	if ( !( KUpdateModObject || KUpdateModFreeText || KUpdateModProperty ) )
+		{
+		// nothing to change, so unlock object and return
+		iLockList.UnlockById( *iNamespaceDef, object.iId );
+		return object.iId;
+		}
+
+	RRowData baseObjectRow;
+	CleanupClosePushL( baseObjectRow );
+	RRowData objectRow;
+	CleanupClosePushL( objectRow );
+
+	RClauseBuffer commonClauseOne(*this);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& clauseObject = commonClauseOne.BufferL();
+	
+	if (KUpdateModProperty)
+		{
+		clauseObject.BufferL().Format( KMdsObjectUpdateObjectBegin, 
+				&objectDef->GetName(), iNamespaceDef->GetId() );
+		}
+
+	RClauseBuffer commonClauseTwo(*this);
+	CleanupClosePushL( commonClauseTwo );
+	CMdsClauseBuffer& clauseBaseObject = commonClauseTwo.BufferL();
+	if (KUpdateModObject || KUpdateModProperty)
+		{
+		clauseBaseObject.BufferL().Format( KMdsObjectUpdateBaseObjectBegin, 
+				iNamespaceDef->GetId() );
+		}
+
+	aBuffer.PositionL( object.iUri.iPtr.iOffset );
+	HBufC* uriBuf = aBuffer.ReceiveDes16L();
+	CleanupStack::PushL( uriBuf );
+	TPtr16 uri( uriBuf->Des() );
+	uri.LowerCase();
+
+	// if auto locking, skip extra checks, because only flags can be changed
+	if( !(object.iFlags & EMdEObjectFlagAutoLock) )
+		{
+		// leave if GUID high and low are 0
+		if( object.iGuidHigh == 0 && object.iGuidLow == 0 )
+			{
+			User::Leave( KErrCorrupt );
+			}
+
+		// leave if URI is "empty"
+		if( uri.Length() == 0 )
+			{
+			User::Leave( KErrCorrupt );
+			}
+		}
+
+	TBool KBaseObjectPropertyMod = EFalse;
+	TBool KObjectPropertyMod     = EFalse;
+
+	if (KUpdateModObject)
+		{
+		clauseBaseObject.AppendL( KMdsObjectUpdateBaseObjectFlags );
+		baseObjectRow.AppendL( TColumn( objectFlags ) );
+
+		if( !(object.iFlags & EMdEObjectFlagAutoLock) )
+			{
+			clauseBaseObject.AppendL( KMdsObjectUpdateBaseObjectEnd );
+			baseObjectRow.AppendL( TColumn( object.iMediaId ) );
+			baseObjectRow.AppendL( TColumn( object.iGuidHigh ) );
+			baseObjectRow.AppendL( TColumn( object.iGuidLow ) );
+			baseObjectRow.AppendL( TColumn( uri ) );
+			}
+		KBaseObjectPropertyMod = ETrue;
+		}
+
+	// read properties array
+	if ( KUpdateModProperty )
+		{
+		// try to add property and increase property count
+		for ( TUint32 i = 0; i < object.iProperties.iPtr.iCount; ++i )
+			{
+			aBuffer.PositionL( object.iProperties.iPtr.iOffset + 
+					i * sizeof(TMdCProperty) );
+			TUint8 modFlags;
+			const CMdsPropertyDef& propertyDef = ReadPropertyL( aBuffer, 
+					*objectDef, clauseBaseObject, clauseObject, baseObjectRow, 
+					objectRow, modFlags );
+			// check if property is already in array
+			if ( modFlags == EMdEPropertyModNone )
+				{
+				continue;
+				}
+
+			if( ( modFlags & EMdEPropertyModRemove ) && propertyDef.GetMandatory() )
+				{
+				User::Leave( KErrMdEMandatoryPropertyMissing );
+				}
+
+			const TDefId propertyId = propertyDef.GetId();
+
+			if ( iBaseObjectDef->GetPropertyByIdL( propertyId ) )
+				{
+				if (!KBaseObjectPropertyMod)
+					{
+					// remove comma before first property
+					clauseBaseObject.BufferL().Delete( 
+							clauseBaseObject.ConstBufferL().LocateReverse( ',' ), 1 );
+					KBaseObjectPropertyMod = ETrue;
+					}
+				clauseBaseObject.AppendL( KUpdateEqual );
+				}
+			else
+				{
+				if (!KObjectPropertyMod)
+					{
+					// remove comma before first property
+					clauseObject.BufferL().Delete( 
+							clauseObject.ConstBufferL().LocateReverse( ',' ), 1 );
+					KObjectPropertyMod = ETrue;
+					}
+				clauseObject.AppendL( KUpdateEqual );
+				}
+			}
+		}
+
+	if (KUpdateModObject || KBaseObjectPropertyMod)
+		{
+		clauseBaseObject.AppendL( KMdsObjectUpdateEnd );
+		// append confidential and deleted flags
+		baseObjectRow.AppendL( TColumn( object.iId ) );
+		}
+
+	if (KObjectPropertyMod)
+		{
+		clauseObject.AppendL( KMdsObjectUpdateEnd );
+		// append confidential and deleted flags
+		objectRow.AppendL( TColumn( object.iId ) );
+		}
+
+	TInt queryResult = 0, err;
+    RMdSTransaction transaction( aConnection );
+    CleanupClosePushL( transaction );
+    User::LeaveIfError( transaction.Error() );
+
+	if ( KUpdateModObject || KBaseObjectPropertyMod )
+		{
+		__LOGQUERY_16( _L("Update BaseObject:"), 
+				clauseBaseObject.ConstBufferL(), baseObjectRow);
+		TRAP( err, queryResult = aConnection.ExecuteL( 
+				clauseBaseObject.ConstBufferL(), baseObjectRow ) );
+
+		// Try to remove the object which caused the constraint error and try add the object again.
+		if ( err == KSqlErrConstraint )
+			{
+			__LOG2( ELogQuery, "Update baseObject constraint error - err:%d, queryResult:%d", err, queryResult );
+			// The reason of the constraint error is not checked due to performance hit.
+			TRAP_IGNORE( RemoveObjectForceL( uri, object.iId ) );
+			__LOGQUERY_16( _L("Update AGAIN BaseObject:"), 
+					clauseBaseObject.ConstBufferL(), baseObjectRow);
+			// Fails if the object was not marked as removed.
+			TRAP( err, queryResult = aConnection.ExecuteL( 
+					clauseBaseObject.ConstBufferL(), baseObjectRow ) );
+			}
+
+		if ( err != KErrNone || queryResult != 1 )
+			{
+			__LOG2( ELogQuery, "Update baseObject failed - err:%d, queryResult:%d", err, queryResult );
+			User::Leave( KErrGeneral );
+			}
+		}
+
+	if ( KObjectPropertyMod )
+		{
+		__LOGQUERY_16( _L("Update Object:"), clauseObject.ConstBufferL(), 
+				objectRow);
+		TRAP( err, queryResult = aConnection.ExecuteL( 
+				clauseObject.ConstBufferL(), objectRow ) );
+		if (err != KErrNone || queryResult != 1)
+			{
+			__LOG2( ELogQuery, "Update Object failed - err:%d, queryResult:%d", err, queryResult );
+			User::Leave( KErrGeneral );
+			}
+		}
+
+	if ( KUpdateModFreeText )
+		{
+		if ( object.iFreeTexts.iPtr.iCount > 0 )
+			{
+			aBuffer.PositionL( object.iFreeTexts.iPtr.iOffset );
+			UpdateFreeTextL( aBuffer, object.iFreeTexts.iPtr.iCount, object.iId );
+			}
+		}
+
+    transaction.CommitL();
+    CleanupStack::PopAndDestroy( &transaction );
+
+    CleanupStack::PopAndDestroy( uriBuf );
+    CleanupStack::PopAndDestroy( &commonClauseTwo );
+	CleanupStack::PopAndDestroy( &commonClauseOne );
+
+    // objectRow, baseObjectRow
+	CleanupStack::PopAndDestroy( 2, &baseObjectRow );
+
+	iLockList.UnlockById( *iNamespaceDef, object.iId );
+	return object.iId;
+	}
+
+
+void CMdSSqlObjectManipulate::UpdateFreeTextL( CMdCSerializationBuffer& aBuffer,
+		TInt aCount, TItemId aObjectId )
+	{
+	_LIT( KMdSUpdateFreeTextDelete,     "DELETE FROM TextSearch%u WHERE ObjectId=?;" );
+	_LIT( KMdSUpdateFreeTextDictDelete, "DELETE FROM TextSearchDictionary%u WHERE WordId NOT IN(SELECT WordId FROM TextSearch%u);" );
+	_LIT( KMdSUpdateFreeTextObjectFlagSet,   "UPDATE Object%u SET Flags=Flags|? WHERE ObjectId=?;" );
+	_LIT( KMdSUpdateFreeTextObjectFlagReset, "UPDATE Object%u SET Flags=Flags&? WHERE ObjectId=?;" );
+
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+
+	RClauseBuffer commonClauseOne(*this, KMdSUpdateFreeTextDictDelete.iTypeLength + 2*KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& buffer = commonClauseOne.BufferL();
+	RRowData delRow;
+	CleanupClosePushL( delRow );
+
+	delRow.AppendL( TColumn( aObjectId ) );
+	buffer.BufferL().Format( KMdSUpdateFreeTextDelete, iNamespaceDef->GetId() );
+	connection.ExecuteL( buffer.ConstBufferL(), delRow );
+
+	delRow.Free(); delRow.Reset();
+	buffer.BufferL().Format( KMdSUpdateFreeTextDictDelete, iNamespaceDef->GetId(), 
+			iNamespaceDef->GetId() );
+	connection.ExecuteL( buffer.ConstBufferL(), delRow );
+
+	// update object flags
+	delRow.Free(); delRow.Reset();
+	delRow.AppendL( TColumn( EMdEObjectFlagFreetexts ) );
+	delRow.AppendL( TColumn( aObjectId ) );
+	if ( AddFreeTextL( aBuffer, aCount, aObjectId ) > 0 )
+		{
+		buffer.BufferL().Format( KMdSUpdateFreeTextObjectFlagSet, iNamespaceDef->GetId() );
+		}
+	else
+		{
+		buffer.BufferL().Format( KMdSUpdateFreeTextObjectFlagReset, iNamespaceDef->GetId() );
+		delRow.Column(0).Set( ~EMdEObjectFlagFreetexts );
+		}
+	connection.ExecuteL( buffer.ConstBufferL(), delRow );
+
+	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // delRow, commonClauseOne
+	}
+
+TItemId CMdSSqlObjectManipulate::AddEventL( CMdSSqLiteConnection& aConnection, 
+		CMdCSerializationBuffer& aBuffer )
+	{
+	_LIT( KAddEvent, "INSERT INTO Event%u(EventId,ObjectId,EventDefId,Timestamp,Source,Participant) VALUES(?,?,?,?,?,?);" );
+
+	if ( !iNamespaceDef )
+		{
+		User::Leave( KErrMdEUnknownNamespaceDef );
+		}
+	
+	RClauseBuffer commonClauseOne(*this, KAddEvent().Length() + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& sqlBuf = commonClauseOne.BufferL();
+	sqlBuf.BufferL().Format( KAddEvent, iNamespaceDef->GetId() );
+
+   	RRowData var;
+    CleanupClosePushL( var );
+
+    const TMdCEvent& event = TMdCEvent::GetFromBufferL( aBuffer );
+
+    TItemId eventId = event.iId;
+	if ( eventId != KNoId )
+		{
+		User::Leave( KErrArgument );
+		}
+	
+	RSQLIndex sqlIndex;
+	CleanupClosePushL( sqlIndex );
+	eventId = sqlIndex.GetId();
+
+	if ( !iNamespaceDef->GetEventByIdL( event.iDefId ) )
+		{
+		User::Leave( KErrMdEUnknownEventDef );
+		}
+
+    if ( event.iObjectId == KNoId )
+    	{
+    	User::Leave( KErrCorrupt );
+    	}
+
+    var.AppendL( TColumn( eventId ) );
+    var.AppendL( TColumn( event.iObjectId ) );
+    var.AppendL( TColumn( event.iDefId ) );
+    var.AppendL( TColumn( event.iTime.Int64() ) );
+
+    TPtrC16 source;
+    if ( event.iSourceText.iPtr.iCount > 0 )
+    	{
+    	aBuffer.PositionL( event.iSourceText.iPtr.iOffset );
+        source.Set( aBuffer.ReceivePtr16L() );
+    	}
+    else
+    	{
+    	source.Set( TPtr16((TUint16*)0, 0) );
+    	}
+    var.AppendL( TColumn( source ) );
+
+	TPtrC16 participant;
+    if ( event.iParticipantText.iPtr.iCount > 0 )
+    	{
+    	aBuffer.PositionL( event.iParticipantText.iPtr.iOffset );
+    	participant.Set( aBuffer.ReceivePtr16L() );
+    	}
+    else
+    	{
+    	participant.Set( TPtr16((TUint16*)0, 0) );
+    	}
+    var.AppendL( TColumn( participant ) );
+
+    aConnection.ExecuteL( sqlBuf.ConstBufferL(), var );
+
+	sqlIndex.Commit();
+	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // sqlIndex, var, commonClauseOne
+	return eventId;
+	}
+        
+TItemId CMdSSqlObjectManipulate::AddRelationL( 
+		CMdSSqLiteConnection& aConnection, CMdCSerializationBuffer& aBuffer )
+	{
+	_LIT( KAddRelation, "INSERT INTO Relations%u(RelationId,Flags,RelationDefId,LeftObjectId,RightObjectId,Parameter,GuidHigh,GuidLow,LastModifiedDate) VALUES(?,?,?,?,?,?,?,?,?);" );
+
+	if ( !iNamespaceDef )
+		{
+		User::Leave( KErrMdEUnknownNamespaceDef );
+		}
+	
+	RClauseBuffer commonClauseOne(*this, KAddRelation().Length() + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& buffer = commonClauseOne.BufferL();
+	buffer.BufferL().Format( KAddRelation, iNamespaceDef->GetId() );
+
+    RRowData var;
+	CleanupClosePushL( var );
+
+	const TMdCRelation& relation = TMdCRelation::GetFromBufferL( aBuffer );
+	TItemId relationId = relation.iId;
+
+	if ( relationId != KNoId )
+		{
+		User::Leave( KErrArgument );
+		}
+	
+	RSQLIndex sqlIndex;
+	CleanupClosePushL( sqlIndex );
+	relationId = sqlIndex.GetId();
+
+	if ( !iNamespaceDef->GetRelationByIdL( relation.iDefId ) )
+		{
+		User::Leave( KErrMdEUnknownRelationDef );
+		}
+
+    if ( relation.iLeftObjectId == KNoId || relation.iRightObjectId == KNoId )
+    	{
+    	User::Leave( KErrCorrupt );
+    	}
+
+	TInt64 guidHigh = relation.iGuidHigh;
+	TInt64 guidLow = relation.iGuidLow;
+	if ( guidHigh == 0 && guidLow == 0 )
+		{
+		iGenerator->GenerateGuid( guidHigh, guidLow );
+		}
+
+	// if last modified date is 0, set it to current universal time
+	TInt64 lastModifiedDate = relation.iLastModifiedDate.Int64();
+	if( lastModifiedDate == 0 )
+		{
+		TTime currentTime;
+		currentTime.UniversalTime();
+		lastModifiedDate = currentTime.Int64();
+		}
+
+    var.AppendL( TColumn( relationId ) );
+    var.AppendL( TColumn( TUint32(0) ) ); // no flags
+    var.AppendL( TColumn( relation.iDefId) );
+    var.AppendL( TColumn( relation.iLeftObjectId ) );
+    var.AppendL( TColumn( relation.iRightObjectId ) );
+    var.AppendL( TColumn( relation.iParameter ) );
+    var.AppendL( TColumn( guidHigh ) );
+    var.AppendL( TColumn( guidLow ) );
+    var.AppendL( TColumn( lastModifiedDate ) );
+
+    aConnection.ExecuteL( buffer.ConstBufferL(), var );
+
+	sqlIndex.Commit();
+	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // sqlIndex, var, commonClauseOne
+	return relationId;
+	}
+
+void CMdSSqlObjectManipulate::RemoveRelationsL( CMdCSerializationBuffer& aBuffer,
+		TInt aCount, RArray<TItemId>& aIdArray )
+    {	
+	_LIT( KRemoveRelation, "UPDATE Relations%u SET Flags=Flags|? WHERE RelationId=? AND NOT Flags&?;" );
+    CMdSSqLiteConnection& db = MMdSDbConnectionPool::GetDefaultDBL();
+    
+	RClauseBuffer commonClauseOne(*this, KRemoveRelation().Length() + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& buf = commonClauseOne.BufferL();
+    buf.BufferL().Format( KRemoveRelation, iNamespaceDef->GetId() );
+
+	TInt queryResult = 0;
+	TItemId relationId = KNoId;
+
+    RRowData varRemove;
+    CleanupClosePushL( varRemove );
+    varRemove.AppendL( TColumn( 
+    		EMdERelationFlagDeleted | EMdERelationFlagGarbageDeleted ) );
+    varRemove.AppendL( TColumn( relationId ) );
+    varRemove.AppendL( TColumn( 
+    		EMdERelationFlagDeleted | EMdERelationFlagNotPresent ) );
+
+	for ( TUint32 i = 0; i < aCount; ++i )
+		{
+		aBuffer.ReceiveL( relationId );
+		varRemove.Column( 1 ).Set( relationId );
+		TRAPD( err, queryResult = db.ExecuteL( buf.ConstBufferL(), varRemove ) );
+		if ( err == KErrNone && queryResult == 1 )
+			{
+			aIdArray.AppendL( relationId );
+			}
+		else
+			{
+			aIdArray.AppendL( KNoId );
+			}
+		}
+	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // varRemove, commonClauseOne
+    }
+
+void CMdSSqlObjectManipulate::RemoveEventsL( CMdCSerializationBuffer& aBuffer, 
+		TInt aCount, RArray<TItemId>& aIdArray )
+    {
+	_LIT( KRemoveEvent, "DELETE FROM Event%u WHERE EventId=?;" );
+
+    CMdSSqLiteConnection& db = MMdSDbConnectionPool::GetDefaultDBL();
+
+	RClauseBuffer commonClauseOne(*this, KRemoveEvent().Length() + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& buf = commonClauseOne.BufferL();
+    buf.BufferL().Format( KRemoveEvent, iNamespaceDef->GetId() );
+
+	TInt queryResult = 0;
+	TItemId eventId = KNoId;
+
+    RRowData varRemove;
+    CleanupClosePushL( varRemove );
+    varRemove.AppendL( TColumn( eventId ) );
+
+	for ( TUint32 i = 0; i < aCount; ++i )
+		{
+		aBuffer.ReceiveL( eventId );
+		varRemove.Column( 0 ).Set( eventId );
+		TRAPD( err, queryResult = db.ExecuteL( buf.ConstBufferL(), varRemove ) );
+		if ( err == KErrNone && queryResult == 1 )
+			{
+			aIdArray.AppendL( eventId );
+			}
+		else
+			{
+			aIdArray.AppendL( KNoId );
+			}
+		}
+	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // varRemove, commonClauseOne
+    }
+
+TItemId CMdSSqlObjectManipulate::UpdateRelationsL(
+		CMdSSqLiteConnection& aConnection, CMdCSerializationBuffer& aBuffer )
+    {	
+	_LIT( KUpdateRelation, "UPDATE Relations%u SET RelationDefId=?,LeftObjectId=?,RightObjectId=?,Parameter=?,GuidHigh=?,GuidLow=?,LastModifiedDate=? WHERE NOT Flags&? AND NOT Flags&? AND RelationId=?;" );
+
+if ( !iNamespaceDef )
+		{
+		User::Leave( KErrMdEUnknownNamespaceDef );
+		}
+	
+	RClauseBuffer commonClauseOne(*this, KUpdateRelation().Length() + KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& sqlBuf = commonClauseOne.BufferL();
+    sqlBuf.BufferL().Format( KUpdateRelation, iNamespaceDef->GetId() );
+
+    RRowData var;
+    CleanupClosePushL( var );
+
+    const TMdCRelation& relation = TMdCRelation::GetFromBufferL( aBuffer );
+
+    if ( relation.iId == KNoId )
+    	{
+    	User::Leave( KErrArgument );
+    	}
+
+    if ( !iNamespaceDef->GetRelationByIdL( relation.iDefId ) )
+		{
+		User::Leave( KErrMdEUnknownRelationDef );
+		}
+
+	// leave if GUID high and low are 0
+	if( relation.iGuidHigh == 0 && relation.iGuidLow == 0 )
+		{
+		User::Leave( KErrCorrupt );
+		}
+
+	// if last modified date is 0, set it to current universal time
+	TInt64 lastModifiedDate = relation.iLastModifiedDate.Int64();
+	if( lastModifiedDate == 0 )
+		{
+		TTime currentTime;
+		currentTime.UniversalTime();
+		lastModifiedDate = currentTime.Int64();
+		}
+
+    var.AppendL( TColumn( relation.iDefId ) );
+    var.AppendL( TColumn( relation.iLeftObjectId ) );
+    var.AppendL( TColumn( relation.iRightObjectId ) );
+    var.AppendL( TColumn( relation.iParameter ) );
+    var.AppendL( TColumn( relation.iGuidHigh ) );
+    var.AppendL( TColumn( relation.iGuidLow ) );
+    var.AppendL( TColumn( lastModifiedDate ) );
+    var.AppendL( TColumn( EMdERelationFlagNotPresent ) );
+    var.AppendL( TColumn( EMdERelationFlagDeleted ) );
+	var.AppendL( TColumn( relation.iId ) );
+
+	aConnection.ExecuteL( sqlBuf.ConstBufferL(), var );
+
+	CleanupStack::PopAndDestroy( 2, &commonClauseOne ); // var, commonClauseOne
+
+	return relation.iId;
+    }
+
+void CMdSSqlObjectManipulate::GetRemovedRelationItemsL( CMdCSerializationBuffer& aBuffer,
+		const RArray<TItemId>& aRemovedRelations,
+		const RArray<TItemId>& aAdditionalRemovedRelations )
+	{
+	_LIT( KGetRelationItemsStart, "SELECT RelationId,RelationDefId,LeftObjectId,RightObjectId FROM Relations%u WHERE Flags&? AND RelationId IN(?" );
+	_LIT( KGetRelationItemsMiddle, ",?" );
+	_LIT( KGetRelationItemsEnd, ");" );
+
+	const TInt relationsCount = aRemovedRelations.Count() + aAdditionalRemovedRelations.Count();
+	
+	TMdCItems relationItems;
+	
+	relationItems.iNamespaceDefId = iNamespaceDef->GetId();
+	relationItems.iRelations.iPtr.iCount = 0; // will be updated later
+	relationItems.iRelations.iPtr.iOffset = sizeof( TMdCItems );
+
+	if ( relationsCount == 0 )
+		{
+		relationItems.SerializeL( aBuffer );
+
+		return;
+		}
+	
+	RClauseBuffer commonClauseOne(*this, KGetRelationItemsStart().Length() + KMaxUintValueLength
+			+ KGetRelationItemsMiddle().Length() * relationsCount 
+			+ KGetRelationItemsEnd().Length() );
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& sqlBuffer = commonClauseOne.BufferL();
+	sqlBuffer.BufferL().Format( KGetRelationItemsStart, iNamespaceDef->GetId() );
+
+    RRowData var;
+    CleanupClosePushL( var );
+    var.ReserveL( 1 + relationsCount );
+    var.AppendL( EMdERelationFlagDeleted );
+
+    const TInt removedRelationsCount = aRemovedRelations.Count();
+    for (TInt i = 0; i < removedRelationsCount-1; ++i)
+    	{
+    	sqlBuffer.AppendL( KGetRelationItemsMiddle );
+    	var.AppendL( aRemovedRelations[i] );
+    	}
+    if ( removedRelationsCount )
+    	{
+	    var.AppendL( aRemovedRelations[removedRelationsCount-1] );
+    	}
+
+    const TInt additionalRemovedRelationsCount = aAdditionalRemovedRelations.Count();
+    for (TInt i = 0; i < additionalRemovedRelationsCount-1; ++i)
+    	{
+    	sqlBuffer.AppendL( KGetRelationItemsMiddle );
+    	var.AppendL( aAdditionalRemovedRelations[i] );
+    	}
+    if ( removedRelationsCount == 0 /*&& additionalRemovedRelationsCount*/ )
+    	{
+    	// cannot be empty
+    	var.AppendL( aAdditionalRemovedRelations[additionalRemovedRelationsCount-1] );
+    	}
+    
+    sqlBuffer.AppendL( KGetRelationItemsEnd );
+    
+	RMdsStatement getQuery;
+    CleanupClosePushL( getQuery );
+
+	__LOGQUERY_16( _L("CMdSSqlObjectManipulate::GetRemovedRelationItemsL:"), 
+			sqlBuffer.ConstBufferL(), var);
+    CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+	
+    connection.ExecuteQueryL( sqlBuffer.ConstBufferL(), getQuery, var );
+
+	var.Free(); 
+	var.Reset();
+
+    var.ReserveL( 4 );
+    
+    TMdCRelation relation;
+	var.AppendL( relation.iId );
+	var.AppendL( relation.iDefId );
+	var.AppendL( relation.iLeftObjectId );
+	var.AppendL( relation.iRightObjectId );
+	
+    TUint32 resultCount = 0;
+    
+    // move position after items
+	aBuffer.PositionL( relationItems.iRelations.iPtr.iOffset );
+
+	while( connection.NextRowL( getQuery, var ) )
+		{
+		++resultCount;
+
+		var.Column( 0 ).Get( relation.iId );
+		var.Column( 1 ).Get( relation.iDefId );
+		var.Column( 2 ).Get( relation.iLeftObjectId );
+		var.Column( 3 ).Get( relation.iRightObjectId );
+
+		relation.SerializeL( aBuffer );
+		}
+
+	// update relation count
+	relationItems.iRelations.iPtr.iCount = resultCount;
+
+	// move position to begin of buffer and serialize items
+	aBuffer.PositionL( KNoOffset );
+	relationItems.SerializeL( aBuffer );
+
+	CleanupStack::PopAndDestroy( 3, &commonClauseOne ); // getQuery, var, commonClauseOne
+	}
+
+void CMdSSqlObjectManipulate::SetPendingL(const RArray<TItemId>& aObjectIds, 
+		TBool aReset)
+	{
+	_LIT( KUpdatePending,   "UPDATE Object%u SET Flags=Flags%c? WHERE ObjectId IN(?" );
+	_LIT( KUpdatePendingMiddle, ",?" );
+	_LIT( KUpdatePendingEnd, ");" );
+
+    CMdSSqLiteConnection& db = MMdSDbConnectionPool::GetDefaultDBL();
+
+    const TInt objectIdsCount = aObjectIds.Count();
+
+	RClauseBuffer commonClause(*this, KUpdatePending().Length() + KMaxUintValueLength + 
+			KUpdatePendingMiddle().Length() * (objectIdsCount - 1) + 
+			KUpdatePendingEnd().Length() );
+	CleanupClosePushL( commonClause );
+	CMdsClauseBuffer& buf = commonClause.BufferL();
+
+	const TChar KSetUpdateFlag = '|';
+	const TChar KResetUpdateFlag = '&';
+	
+	TChar flagUpdate = KSetUpdateFlag; // set flag
+	TUint32 objectFlag = EMdeObjectFlagPending;
+
+	if( aReset )
+		{
+		flagUpdate = KResetUpdateFlag; // reset flag
+		objectFlag = ~objectFlag; // not pending flag
+		}
+	
+    buf.BufferL().Format( KUpdatePending, KDefaultNamespaceDefId, (TUint)flagUpdate );
+
+    RRowData var;
+    CleanupClosePushL( var );
+
+    var.ReserveL( 1 + objectIdsCount );
+    
+    var.AppendL( TColumn( objectFlag ) );
+
+	var.AppendL( aObjectIds[0] );
+    for (TInt i = 1; i < objectIdsCount; ++i)
+    	{
+    	buf.AppendL( KUpdatePendingMiddle );
+    	var.AppendL( aObjectIds[i] );
+    	}
+    buf.AppendL( KUpdatePendingEnd );
+
+    db.ExecuteL( buf.ConstBufferL(), var );
+
+	CleanupStack::PopAndDestroy( 2, &commonClause ); // var, commonClause
+	}
+
+TInt CMdSSqlObjectManipulate::GetPendingCountL(TDefId aObjectDefId)
+	{
+	_LIT( KGetPendingCount,   "SELECT count(*) FROM Object%u WHERE Flags&? AND NOT Flags&?" );
+	_LIT( KGetPendingCountObjectDefId, " AND ObjectDefId=?" );
+	_LIT( KGetPendingCountEnd, ";" );
+
+    CMdSSqLiteConnection& db = MMdSDbConnectionPool::GetDefaultDBL();
+
+    TInt bufferSize = KGetPendingCount().Length() + KMaxUintValueLength + 
+    		KGetPendingCountEnd().Length();
+    
+	if( aObjectDefId != KNoDefId )	
+		{
+		bufferSize += KGetPendingCountObjectDefId().Length();
+		}
+    
+	RClauseBuffer commonClause( *this, bufferSize );
+	CleanupClosePushL( commonClause );
+	CMdsClauseBuffer& buf = commonClause.BufferL();
+    buf.BufferL().Format( KGetPendingCount, KDefaultNamespaceDefId );
+    
+    TInt varReservation = 2;
+    
+	if( aObjectDefId != KNoDefId )	
+		{
+		buf.AppendL( KGetPendingCountObjectDefId );
+		++varReservation;
+		}
+
+	buf.AppendL( KGetPendingCountEnd );
+	
+    RRowData var;
+    CleanupClosePushL( var );
+
+    var.ReserveL( varReservation );
+
+    var.AppendL( TColumn( EMdeObjectFlagPending ) );
+    var.AppendL( TColumn( EMdEObjectFlagNotPresent | EMdEObjectFlagRemoved | 
+    		EMdEObjectFlagPlaceholder | EMdEObjectFlagStartUpNotPresent ) );
+
+    if( aObjectDefId != KNoDefId )
+    	{
+    	var.AppendL( TColumn( aObjectDefId ) );
+    	}
+    
+	RMdsStatement getQuery;
+    CleanupClosePushL( getQuery );
+
+	db.ExecuteQueryL( buf.ConstBufferL(), getQuery, var );
+
+	var.Free();
+	var.Reset();
+
+	TUint32 count = 0;
+	
+	var.AppendL( TColumn( count ) );
+
+	if ( db.NextRowL( getQuery, var ) )
+		{
+		var.Column(0).Get( count );
+		}
+
+	CleanupStack::PopAndDestroy( 2, &var ); // getQuery, varSearch
+	CleanupStack::PopAndDestroy( &commonClause );
+	
+	return count;
+	}
+
+TInt CMdSSqlObjectManipulate::GetPendingL(TDefId aObjectDefId, 
+		TInt aBufferSize, RArray<TItemId>& aObjectIds)
+	{
+	_LIT( KGetPending,   "SELECT ObjectId FROM Object%u WHERE Flags&? AND NOT Flags&?" );
+	_LIT( KGetPendingObjectDefId, " AND ObjectDefId=?" );
+	_LIT( KGetPendingEnd, " LIMIT ?;" );
+
+    CMdSSqLiteConnection& db = MMdSDbConnectionPool::GetDefaultDBL();
+
+    TInt bufferSize = KGetPending().Length() + KMaxUintValueLength + 
+    		KGetPendingEnd().Length();
+
+	if( aObjectDefId != KNoDefId )	
+		{
+		bufferSize += KGetPendingObjectDefId().Length();
+		}
+
+	RClauseBuffer commonClause( *this, bufferSize );
+	CleanupClosePushL( commonClause );
+	CMdsClauseBuffer& buf = commonClause.BufferL();
+    buf.BufferL().Format( KGetPending, KDefaultNamespaceDefId );
+
+    TInt varReservation = 3;
+
+	if( aObjectDefId != KNoDefId )	
+		{
+		buf.AppendL( KGetPendingObjectDefId );
+		++varReservation;
+		}
+
+	buf.AppendL( KGetPendingEnd );
+
+    RRowData var;
+    CleanupClosePushL( var );
+
+    var.ReserveL( varReservation );
+
+    var.AppendL( TColumn( EMdeObjectFlagPending ) );
+    var.AppendL( TColumn( EMdEObjectFlagNotPresent | EMdEObjectFlagRemoved | 
+    		EMdEObjectFlagPlaceholder | EMdEObjectFlagStartUpNotPresent ) );
+
+    if( aObjectDefId != KNoDefId )
+    	{
+    	var.AppendL( TColumn( aObjectDefId ) );
+    	}
+
+    // get as much as possible to buffer and check if there is more than that
+    var.AppendL( TColumn( aBufferSize + 1 ) );
+
+	RMdsStatement getQuery;
+    CleanupClosePushL( getQuery );
+
+	db.ExecuteQueryL( buf.ConstBufferL(), getQuery, var );
+
+	var.Free();
+	var.Reset();
+
+	TItemId objectId = 0;
+
+	var.AppendL( TColumn( objectId ) );
+
+	TInt extraRows = 0;
+
+	while( db.NextRowL( getQuery, var ) )
+		{
+		var.Column(0).Get( objectId );
+		
+		if( aObjectIds.Count() < aBufferSize )
+			{
+			aObjectIds.Append( objectId );
+			}
+		else
+			{
+			extraRows = 1;
+			break;
+			}
+		}
+
+	CleanupStack::PopAndDestroy( 2, &var ); // getQuery, varSearch
+	CleanupStack::PopAndDestroy( &commonClause );
+
+	return extraRows;
+	}
+
+TBool CMdSSqlObjectManipulate::DoGarbageCollectionL()
+	{
+	_LIT( KDeleteObject,                 "DELETE FROM Object%u WHERE Flags&?;" );
+	_LIT( KUpdateDeleteObject,           "UPDATE Object%u SET Flags=Flags|? WHERE Flags&?;" );
+	_LIT( KDeleteRelations,              "DELETE FROM Relations%u WHERE Flags&?;" );
+	_LIT( KUpdateDeleteRelations,        "UPDATE Relations%u SET Flags=Flags|? WHERE Flags&?;" );
+	_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 );" );
+    _LIT( KDeleteWordFromTextSearchDict, "DELETE FROM TextSearchDictionary%u WHERE NOT EXISTS(SELECT WordId FROM TextSearch%u WHERE WordId = TextSearchDictionary%u.WordId);");
+
+
+	RClauseBuffer commonClauseOne(*this, KUpdateDeleteContextObjects().Length() + 3 * KMaxUintValueLength);
+	CleanupClosePushL( commonClauseOne );
+	CMdsClauseBuffer& buffer = commonClauseOne.BufferL();
+
+    RRowData rowDataDel;
+    CleanupClosePushL( rowDataDel );
+    rowDataDel.AppendL( TColumn( EMdEObjectFlagGarbage ) );
+
+    RRowData rowDataUpd;
+    CleanupClosePushL( rowDataUpd );
+    rowDataUpd.AppendL( TColumn( EMdEObjectFlagGarbage ) );
+    rowDataUpd.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+
+    RRowData rowDataDelRel;
+    CleanupClosePushL( rowDataDelRel );
+    rowDataDelRel.AppendL( TColumn( EMdERelationFlagGarbageDeleted ) );
+
+    RRowData rowDataUpdRel;
+    CleanupClosePushL( rowDataUpdRel );
+    rowDataUpdRel.AppendL( TColumn( EMdERelationFlagGarbageDeleted ) );
+    rowDataUpdRel.AppendL( TColumn( EMdERelationFlagDeleted ) );
+
+    RRowData rowDataDelContext;
+    CleanupClosePushL( rowDataDelContext );
+    rowDataDelContext.AppendL( TColumn( EMdEObjectFlagRemoved ) );
+    rowDataDelContext.AppendL( TColumn( EMdEObjectFlagContext ) );
+    rowDataDelContext.AppendL( TColumn( EMdERelationFlagDeleted ) );
+
+	RRowData emptyRow;
+	CleanupClosePushL( emptyRow );
+
+   	const RPointerArray<CMdsNamespaceDef>& namespaceDefs = 
+   		iSchema.NamespaceDefs();
+
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+	TInt deleteObjectResult;
+	TInt updateResult = 0;
+	
+	const TInt count = namespaceDefs.Count();
+	
+   	for( TInt i = 0; i < count; ++i )
+   	    {
+   	    const TDefId nmspId = namespaceDefs[i]->GetId();
+
+		// deleting objects
+		buffer.BufferL().Format( KDeleteObject, nmspId );
+   	    User::LeaveIfError( deleteObjectResult = connection.ExecuteL( 
+   	    		buffer.ConstBufferL(), rowDataDel ) );
+
+        buffer.BufferL().Format( KUpdateDeleteObject, nmspId );
+   	    User::LeaveIfError( updateResult += connection.ExecuteL(
+   	    		buffer.ConstBufferL(), rowDataUpd ) );
+
+		// deleting relations
+		buffer.BufferL().Format( KDeleteRelations, nmspId );
+   	    User::LeaveIfError( connection.ExecuteL( 
+   	    		buffer.ConstBufferL(), rowDataDelRel ) );
+
+		buffer.BufferL().Format( KUpdateDeleteRelations, nmspId );
+   	    User::LeaveIfError( updateResult += connection.ExecuteL( 
+   	    		buffer.ConstBufferL(), rowDataUpdRel ) );
+
+		// deleting context objects
+		buffer.BufferL().Format( KUpdateDeleteContextObjects, nmspId, nmspId, nmspId );
+   	    User::LeaveIfError( updateResult += connection.ExecuteL( 
+   	    		buffer.ConstBufferL(), rowDataDelContext ) );
+
+		// deleting words from text search dictionary
+		if ( deleteObjectResult > 0 )
+			{
+			buffer.BufferL().Format( KDeleteWordFromTextSearchDict, nmspId, nmspId, 
+					nmspId );
+	   	    User::LeaveIfError( connection.ExecuteL( 
+	   	    		buffer.ConstBufferL(), emptyRow ) );
+			}
+   	    }
+
+   	// empryRow, rowDataDelContext, rowDataUpdRel, rowDataDelRel, rowDataUpd, 
+   	// rowDataDel, commonClauseOne
+	CleanupStack::PopAndDestroy( 7, &commonClauseOne );
+
+	return updateResult != 0;
+	}
+
+CMdSSqlObjectManipulate::RClauseBuffer::RClauseBuffer( CMdSSqlObjectManipulate& aSOM, TInt aSize )
+	: iBuffers( aSOM.iBuffers ), iBuffer( NULL ), iNr( -1 ), iSize( aSize )
+	{
+	// search for available buffer
+	// or create new one
+	for (TInt i = 0; i < iBuffers.Count(); ++i)
+		{
+		if (!iBuffers[i].iLock)
+			{
+			iBuffers[i].iLock = ETrue;
+			iBuffer = iBuffers[i].iBuffer;
+			iNr = i;
+			TRAP_IGNORE( iBuffer->ReserveSpaceL(aSize) );
+			TRAP_IGNORE( iBuffer->BufferL().Zero() );
+			return;
+			}
+		}
+	}
+
+CMdsClauseBuffer& CMdSSqlObjectManipulate::RClauseBuffer::BufferL()
+	{
+	if ( iNr < 0 && !iBuffer )
+		{
+		iBuffer = CMdsClauseBuffer::NewL( iSize );
+		}
+	return *iBuffer;
+	}
+
+void CMdSSqlObjectManipulate::RClauseBuffer::Close()
+	{
+	if ( iNr < 0 )
+		{
+		__ASSERT_DEBUG( iBuffer, _L("RClauseBuffer::Close()") );
+		if ( iBuffer )
+			{
+			delete iBuffer;
+			iBuffer = NULL;
+			}
+		}
+	else
+		{
+		iBuffers[iNr].iLock = EFalse;
+		iBuffer = NULL;
+		}
+	}