imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailstore.cpp
changeset 0 2014ca87e772
child 1 235a7fc86938
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailstore.cpp	Tue Jan 26 15:18:05 2010 +0200
@@ -0,0 +1,2370 @@
+/*
+* Copyright (c) 2006-2007 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:  Store for thumbnails.
+ *
+*/
+
+
+#include <s32mem.h>
+#include <e32cmn.h>
+#include <fbs.h>
+#include <imageconversion.h>
+#include <e32base.h>
+#include <exifread.h>
+
+#include <iclextjpegapi.h>
+#include "thumbnailstore.h"
+#include "thumbnailsql.h"
+#include "thumbnaillog.h"
+#include "thumbnailmanageruids.hrh"
+#include "thumbnailcenrep.h"
+#include "thumbnailpanic.h"
+#include "thumbnailmanagerconstants.h"
+#include "thumbnailserver.h"
+
+
+
+_LIT8( KThumbnailSqlConfig, "page_size=16384; cache_size=32;" );
+
+const TInt KStreamBufferSize = 1024 * 8;
+const TInt KMajor = 3;
+const TInt KMinor = 2;
+
+// Database path without drive letter
+_LIT( KThumbnailDatabaseName, ":[102830AB]thumbnail_v2.db" );
+
+// Allow access to database only for the server process
+const TSecurityPolicy KThumbnailDatabaseSecurityPolicy( TSecureId(
+    THUMBNAIL_MANAGER_SERVER_UID ));
+
+
+// ---------------------------------------------------------------------------
+// RThumbnailTransaction::RThumbnailTransaction::TThumbnailPersistentSize
+// ---------------------------------------------------------------------------
+//
+RThumbnailTransaction::RThumbnailTransaction( RSqlDatabase& aDatabase ):
+    iDatabase( aDatabase ), iState( EClosed )
+    {
+    // No implementation required
+    }
+
+
+// ---------------------------------------------------------------------------
+// RThumbnailTransaction::BeginL()
+// ---------------------------------------------------------------------------
+//
+void RThumbnailTransaction::BeginL()
+    {
+    const TInt err = iDatabase.Exec( KThumbnailBeginTransaction );
+    if ( err >= 0 )
+        {
+        iState = EOpen;
+        }
+    else
+        {
+        iState = EError;
+        User::Leave( err );
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// RThumbnailTransaction::Close()
+// ---------------------------------------------------------------------------
+//
+void RThumbnailTransaction::Close()
+    {
+    if ( iState != EClosed )
+        {
+        Rollback();
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// RThumbnailTransaction::CommitL()
+// ---------------------------------------------------------------------------
+//
+void RThumbnailTransaction::CommitL()
+    {
+    User::LeaveIfError( iDatabase.Exec( KThumbnailCommitTransaction ));
+    iState = EClosed;
+    }
+
+
+// ---------------------------------------------------------------------------
+// RThumbnailTransaction::Rollback()
+// ---------------------------------------------------------------------------
+//
+TInt RThumbnailTransaction::Rollback()
+    {
+    const TInt err = iDatabase.Exec( KThumbnailRollbackTransaction );
+    if ( err >= 0 )
+        {
+        iState = EClosed;
+        }
+    return err;
+    }
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CThumbnailStore::NewL()
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CThumbnailStore* CThumbnailStore::NewL( RFs& aFs, TInt aDrive, TDesC& aImei, CThumbnailServer* aServer )
+    {
+    CThumbnailStore* self = new( ELeave )CThumbnailStore( aFs, aDrive, aImei, aServer );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CThumbnailStore::~CThumbnailStore()
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CThumbnailStore::~CThumbnailStore()
+    {
+    TN_DEBUG1( "CThumbnailStore::~CThumbnailStore()" );
+
+    if(!iServer->IsFormatting())
+        {
+ 	    FlushCacheTable( ETrue );
+        }
+    if( iAutoFlushTimer )
+        {
+        iAutoFlushTimer->Cancel();
+        delete iAutoFlushTimer;
+        iAutoFlushTimer = NULL;
+        }
+    
+    iDatabase.Close();
+    TN_DEBUG1( "CThumbnailStore::~CThumbnailStore() - database closed" );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CThumbnailStore::CThumbnailStore()
+// C++ default constructor can NOT contain any code, that might leave.
+// ---------------------------------------------------------------------------
+//
+CThumbnailStore::CThumbnailStore( RFs& aFs, TInt aDrive, TDesC& aImei,  CThumbnailServer* aServer ): 
+    iFs( aFs ), iDrive( aDrive ), iBatchItemCount(0), iImei(aImei), iServer(aServer)
+    {
+    // no implementation required
+    }
+
+
+// ---------------------------------------------------------------------------
+// CThumbnailStore::ConstructL()
+// Symbian 2nd phase constructor can leave.
+// ---------------------------------------------------------------------------
+//
+void CThumbnailStore::ConstructL()
+    {
+    TN_DEBUG1( "CThumbnailStore::ConstructL()" );
+
+#ifdef _DEBUG
+    iThumbCounter = 0;
+#endif
+    
+    HBufC* databasePath = HBufC::NewLC( KMaxFileName );
+    TPtr pathPtr = databasePath->Des();
+    TChar driveChar = 0;
+    User::LeaveIfError( RFs::DriveToChar( iDrive, driveChar ));
+    pathPtr.Append( driveChar );
+    pathPtr.Append( KThumbnailDatabaseName );
+
+    TVolumeInfo volumeinfo;
+    iFs.Volume(volumeinfo, iDrive);
+    TUint id = volumeinfo.iUniqueID;
+    TBuf<50> mediaid;
+    mediaid.Num(id);
+    TBool newDatabase(EFalse);
+    
+    TInt error = KErrNone;
+    
+    TInt err = iDatabase.Open( pathPtr );
+    if ( err == KErrNotFound )
+        {
+        // db not found, create new
+        TN_DEBUG1( "CThumbnailStore::ConstructL() -- 1 creating database" );
+        const TDesC8& config = KThumbnailSqlConfig;
+
+        RSqlSecurityPolicy securityPolicy;
+        CleanupClosePushL( securityPolicy );
+        securityPolicy.Create( KThumbnailDatabaseSecurityPolicy );
+
+        iDatabase.CreateL( pathPtr, securityPolicy, &config );
+        CleanupStack::PopAndDestroy( &securityPolicy );
+
+        TN_DEBUG1( "CThumbnailStore::ConstructL() -- 1 database created ok" );
+                
+        RFile64 file;
+        file.Create(iFs, mediaid, EFileShareReadersOrWriters );
+        file.Close();
+        newDatabase = ETrue;
+        }
+    else if ( err == KErrNone)
+        {
+        // db found, check version and rowids
+        error = CheckVersionL();
+        if(error == KErrNone)
+            {
+            error = CheckRowIDsL();
+            }
+        
+        }
+    
+    // if wrong version, corrupted database or other error opening db
+    if ( error == KErrNotSupported || (err != KErrNone && err != KErrNotFound) )
+        {
+        TN_DEBUG1( "CThumbnailStore::ConstructL() -- delete databases" );
+        
+        // delete db and create new
+        iDatabase.Close();
+        iDatabase.Delete(pathPtr);
+        
+        TN_DEBUG1( "CThumbnailStore::ConstructL() -- 2 creating database" );
+        
+        const TDesC8& config = KThumbnailSqlConfig;
+
+        RSqlSecurityPolicy securityPolicy;
+        CleanupClosePushL( securityPolicy );
+        securityPolicy.Create( KThumbnailDatabaseSecurityPolicy );
+
+        iDatabase.CreateL( pathPtr, securityPolicy, &config );
+        CleanupStack::PopAndDestroy( &securityPolicy );
+
+        TN_DEBUG1( "CThumbnailStore::ConstructL() -- 2 database created ok" );
+        
+        RFile64 file;
+        file.Create(iFs, mediaid, EFileShareReadersOrWriters );
+        file.Close();
+        }
+    else if(!newDatabase)
+        {
+        //check ownership
+        if(CheckImeiL() != KErrNone)
+            {
+            ResetThumbnailIDs();
+            
+            //take ownership
+            UpdateImeiL();
+            
+            //Remove blacklist markings
+            TRAP_IGNORE( RemoveDbFlagL( KThumbnailDbFlagBlacklisted ) );
+            }
+        
+        //check is MMC known
+        if(CheckMediaIDL() != KErrNone )
+            {
+            ResetThumbnailIDs();
+            
+            //Remove blacklist markings
+            TRAP_IGNORE( RemoveDbFlagL( KThumbnailDbFlagBlacklisted ) );
+            }
+        }
+              
+    CleanupStack::PopAndDestroy( databasePath );
+    
+    // add tables
+    TRAPD(tableError, CreateTablesL() );
+    
+    if(!tableError)
+        {
+        AddVersionAndImeiL();
+        }
+    
+    err = iDatabase.Exec( KThumbnailCreateTempInfoTable );
+    TN_DEBUG2("CThumbnailStore::CreateTablesL() KThumbnailCreateTempInfoTable %d", err);
+    User::LeaveIfError( err );
+    err = iDatabase.Exec( KThumbnailCreateTempInfoDataTable );
+    TN_DEBUG2("CThumbnailStore::CreateTablesL() KThumbnailCreateTempInfoDataTable %d", err);
+    User::LeaveIfError( err );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CThumbnailStore::StoreThumbnailL()
+// Stores thumbnail image.
+// ---------------------------------------------------------------------------
+//
+void CThumbnailStore::StoreThumbnailL( const TDesC& aPath, const TDes8& aData,
+    const TSize& aSize, const TSize& aOriginalSize, const TThumbnailFormat& aFormat, TInt aFlags, 
+	const TThumbnailSize& aThumbnailSize, TThumbnailId aThumbnailId, const TBool aThumbFromPath )
+    {
+    TN_DEBUG1( "CThumbnailStore::StoreThumbnailL( const TDes8& ) in" );
+
+#ifdef _DEBUG
+    TTime aStart, aStop;
+    aStart.UniversalTime();
+#endif
+
+    //Encapsulate insert to Transaction
+    RThumbnailTransaction transaction( iDatabase );
+    CleanupClosePushL( transaction );
+    transaction.BeginL();
+    
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    // Insert into ThumbnailInfo
+    User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailInsertThumbnailInfoByPathAndId ));
+
+    TInt paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindText( paramIndex, aPath ));
+
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamWidth );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aSize.iWidth ));
+
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamHeight );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aSize.iHeight ));
+
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamOriginalWidth );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aOriginalSize.iWidth ));
+
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamOriginalHeight );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aOriginalSize.iHeight ));
+
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamFormat );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aFormat ));
+
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamFlags );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aFlags ));
+
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSize );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailSize ));
+    
+    if( aThumbnailId > 0 )
+        {
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailId ));
+        }
+    else
+        {
+        TN_DEBUG1( "CThumbnailStore::StoreThumbnailL( ) aThumbnailId == 0" );
+        }
+    
+    // orientation temporarily to 0
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamOrientation );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, 0 ));
+    
+    // thumb from associated path
+    TInt fromPath = aThumbFromPath;
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamThumbFromPath );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, fromPath ));
+    
+    // try getting modification time from file
+    TTime timeStamp;
+    
+    if (aPath.Length())
+        {
+        iFs.Modified(aPath, timeStamp);
+        }
+    else
+        {
+        // otherwise current time
+        timeStamp.UniversalTime();
+        }
+    
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamModified );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt64( paramIndex, timeStamp.Int64() ));
+    
+    User::LeaveIfError( stmt.Exec());
+    CleanupStack::PopAndDestroy( &stmt );
+    
+    RSqlStatement stmtData;
+    CleanupClosePushL( stmtData );
+    // Insert into ThumbnailInfoData
+    TInt err = stmtData.Prepare( iDatabase, KThumbnailInsertTempThumbnailInfoData );
+       
+#ifdef _DEBUG
+    TPtrC errorMsg = iDatabase.LastErrorMessage();
+    TN_DEBUG2( "CThumbnailStore::FetchThumbnailL() KThumbnailInsertTempThumbnailInfoData %S" , &errorMsg);
+#endif    
+    User::LeaveIfError( err );
+    
+    paramIndex = stmtData.ParameterIndex( KThumbnailSqlParamData );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmtData.BindBinary( paramIndex, aData ));
+
+    User::LeaveIfError( stmtData.Exec());
+    CleanupStack::PopAndDestroy( &stmtData );
+	
+    // Commit transaction
+    transaction.CommitL();
+    CleanupStack::PopAndDestroy( &transaction );
+
+    iBatchItemCount++;
+    
+    FlushCacheTable();
+
+#ifdef _DEBUG
+    iThumbCounter++;
+    TN_DEBUG2( "CThumbnailStore::THUMBSTORE-COUNTER----------, Thumbs = %d", iThumbCounter );
+    
+    aStop.UniversalTime();
+    TN_DEBUG2( "CThumbnailStore::StoreThumbnailL() insert to table %d ms", (TInt)aStop.MicroSecondsFrom(aStart).Int64()/1000);
+#endif 
+    TN_DEBUG1( "CThumbnailStore::StoreThumbnailL( const TDes8& ) out" );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CThumbnailStore::StoreThumbnailL()
+// Stores thumbnail image.
+// ---------------------------------------------------------------------------
+//
+void CThumbnailStore::StoreThumbnailL( const TDesC& aPath, CFbsBitmap*
+    aThumbnail, const TSize& aOriginalSize, TBool /*aCropped*/, const TThumbnailSize aThumbnailSize, 
+    const TThumbnailId aThumbnailId, const TBool aThumbFromPath, TBool aBlackListed )
+    {
+    TN_DEBUG1( "CThumbnailStore::StoreThumbnailL( CFbsBitmap* ) in" );
+
+    __ASSERT_DEBUG(( aThumbnail ), ThumbnailPanic( EThumbnailNullPointer ));
+
+    // check for duplicates
+    TBool exists = FindDuplicateL(aPath, aThumbnailId, aThumbnailSize);
+    
+    TSize thumbSize = aThumbnail->SizeInPixels();
+    for ( TInt i = iPersistentSizes.Count(); --i >= 0; )
+        {
+        TThumbnailPersistentSize & persistentSize = iPersistentSizes[i];
+        
+        // don't store duplicates or custom sizes
+        if ( !exists && (aThumbnailSize != ECustomThumbnailSize && 
+                         thumbSize.iWidth > 0 && thumbSize.iHeight > 0 ))
+            {
+            TInt flags = 0;
+            if ( persistentSize.iCrop )
+                {
+                flags |= KThumbnailDbFlagCropped;
+                }
+            
+            if( aBlackListed )
+                {
+                flags |= KThumbnailDbFlagBlacklisted;
+                }
+            
+            if( (aThumbnailSize == EImageFullScreenThumbnailSize || aThumbnailSize == EVideoFullScreenThumbnailSize ||
+                 aThumbnailSize == EAudioFullScreenThumbnailSize) && !aBlackListed )
+                {
+                HBufC8* data = NULL;
+                CImageEncoder* iEncoder = CImageEncoder::DataNewL( data,  KJpegMime(), CImageEncoder::EOptionAlwaysThread );
+                TJpegImageData* imageData = new (ELeave) TJpegImageData();
+             
+                // Set some format specific data
+                imageData->iSampleScheme = TJpegImageData::EColor444;
+                imageData->iQualityFactor = 75; //?
+             
+                CFrameImageData* iFrameImageData = CFrameImageData::NewL();
+             
+                // frameData - ownership passed to iFrameImageData after AppendImageData
+                User::LeaveIfError(iFrameImageData->AppendImageData(imageData));
+                
+#ifdef _DEBUG
+        TN_DEBUG4( "CThumbnailStore::StoreThumbnailL() size %d x %d displaymode %d ", 
+                aThumbnail->SizeInPixels().iWidth, 
+                aThumbnail->SizeInPixels().iHeight, 
+                aThumbnail->DisplayMode());
+#endif
+                
+                TRequestStatus request;
+                iEncoder->Convert( &request, *aThumbnail, iFrameImageData);
+                User::WaitForRequest( request);
+                  
+                if(request== KErrNone)
+                  {
+                  TPtr8 ptr  = data->Des(); 
+                  StoreThumbnailL( aPath, ptr, aThumbnail->SizeInPixels(), aOriginalSize,
+                          EThumbnailFormatJpeg, flags, aThumbnailSize, aThumbnailId, aThumbFromPath  );
+                  }
+             
+                delete iFrameImageData;
+                iFrameImageData = NULL;          
+                
+                delete iEncoder;
+                iEncoder = NULL;    
+                delete data;
+                data = NULL;                
+                }
+            else
+                {
+                CBufFlat* buf = CBufFlat::NewL( KStreamBufferSize );
+                CleanupStack::PushL( buf );
+                RBufWriteStream stream;
+                stream.Open( *buf );
+                aThumbnail->ExternalizeL( stream );
+            
+                StoreThumbnailL( aPath, buf->Ptr( 0 ), aThumbnail->SizeInPixels(),
+                    aOriginalSize, EThumbnailFormatFbsBitmap, flags, aThumbnailSize, aThumbnailId );
+  
+                CleanupStack::PopAndDestroy( buf );
+                }
+            
+            break;
+            }
+        }
+    
+    TN_DEBUG1( "CThumbnailStore::StoreThumbnailL( CFbsBitmap* ) out" );
+    }
+
+
+// ---------------------------------------------------------------------------
+// Finds possible existing duplicate thumbnail.
+// ---------------------------------------------------------------------------
+//
+TBool CThumbnailStore::FindDuplicateL( const TDesC& aPath, const TThumbnailId aThumbnailId,
+                                       const TThumbnailSize& aThumbnailSize )
+    {
+    TN_DEBUG1( "CThumbnailStore::FindDuplicateL()" );
+    
+    TInt rowStatus = 0;
+    TInt paramIndex = 0;
+    TInt found = EFalse;
+    
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );     
+    
+    User::LeaveIfError( stmt.Prepare( iDatabase, KTempFindDuplicate ));
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindText( paramIndex, aPath ));
+        
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailId ));
+    
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSize );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailSize ));
+    
+    rowStatus = stmt.Next();
+    
+    //if not found from temp table, look from real table
+    if(rowStatus != KSqlAtRow)
+        {
+        stmt.Close();
+        CleanupStack::PopAndDestroy( &stmt );
+        CleanupClosePushL( stmt );
+           
+        User::LeaveIfError( stmt.Prepare( iDatabase, KFindDuplicate ));
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindText( paramIndex, aPath ));
+            
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailId ));
+        
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSize );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailSize ));
+        
+        rowStatus = stmt.Next();
+        
+        if(rowStatus == KSqlAtRow)
+            {
+            TN_DEBUG1( "CThumbnailStore::FindDuplicateL() - duplicate in main table" );
+            
+            found = ETrue;
+            }
+        else
+            {
+            TN_DEBUG1( "CThumbnailStore::FindDuplicateL() - no duplicate" );
+            }
+        }
+    else
+        {
+        TN_DEBUG1( "CThumbnailStore::FindDuplicateL() - duplicate in temp table" );
+        
+        found = ETrue;
+        }
+    
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+    
+    return found;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Create database tables
+// ---------------------------------------------------------------------------
+//
+void CThumbnailStore::CreateTablesL()
+    {
+    TN_DEBUG1( "CThumbnailStore::CreateTablesL()" );
+    TInt err = 0;
+    err = iDatabase.Exec( KThumbnailCreateInfoTable );
+    TN_DEBUG2( "CThumbnailStore::CreateTablesL() KThumbnailCreateInfoTable err=%d", err );
+    err = iDatabase.Exec( KThumbnailCreateInfoDataTable );
+    TN_DEBUG2( "CThumbnailStore::CreateTablesL() KThumbnailCreateInfoDataTable err=%d", err );
+    err = iDatabase.Exec( KThumbnailCreateInfoTableIndex1 );
+    TN_DEBUG2( "CThumbnailStore::CreateTablesL() KThumbnailCreateInfoTableIndex1 err=%d", err );
+    err = iDatabase.Exec( KThumbnailCreateInfoTableIndex2 );
+    TN_DEBUG2( "CThumbnailStore::CreateTablesL() KThumbnailCreateInfoTableIndex2 err=%d", err );
+    err = iDatabase.Exec(KThumbnailVersionTable);
+    TN_DEBUG2( "CThumbnailStore::CreateTablesL() KThumbnailVersionTable err=%d", err );
+    User::LeaveIfError( err );
+    }
+
+
+// ---------------------------------------------------------------------------
+// Get missing sizes by Path
+// ---------------------------------------------------------------------------
+//     
+void CThumbnailStore::GetMissingSizesAndIDsL( const TDesC& aPath, TInt aSourceType, RArray <
+    TThumbnailPersistentSize > & aMissingSizes, TBool& aMissingIDs )
+    {
+    TN_DEBUG2( "CThumbnailStore::GetMissingSizesAndIDsL() aSourceType == %d", aSourceType );
+    // define sizes to be checked
+    const TInt count = iPersistentSizes.Count();
+    
+    for ( TInt i = 0 ; i < count; i++ )
+        {
+        if ( iPersistentSizes[ i ].iSourceType == aSourceType && iPersistentSizes[ i ].iAutoCreate)
+            {
+            aMissingSizes.Append( iPersistentSizes[ i ] );
+            }
+        }
+    
+    TInt missingSizeCount = aMissingSizes.Count();
+    aMissingIDs = EFalse;
+        
+    TN_DEBUG3( "CThumbnailStore::GetMissingSizesAndIDsL() missingSizeCount == %d, missingIDs == %d", missingSizeCount, aMissingIDs );
+    
+    // check temp table first
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectTempSizeByPath ));
+    TInt paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindText( paramIndex, aPath ));
+       
+    TInt rowStatus = stmt.Next();
+
+    TInt round = 1;
+    TInt size = 0;
+    TInt id = 0;
+    
+    while (round <= 2)
+        {
+        while ( rowStatus == KSqlAtRow && missingSizeCount > 0 )
+            {
+            size = stmt.ColumnInt( 0 );
+            id = stmt.ColumnInt( 1 );
+			
+			TN_DEBUG2( "CThumbnailStore::GetMissingSizesAndIDsL() id == %d", id );
+            
+			//if TNId is not valid mark that some are missing so that UpdateDb is run later
+            if ( id <= 0)
+                {
+                TN_DEBUG1( "CThumbnailStore::GetMissingSizesAndIDsL() missing ID");
+                aMissingIDs = ETrue;
+                }
+            
+            missingSizeCount = aMissingSizes.Count();
+            for ( TInt i = 0; i < missingSizeCount; i++ )
+                {
+                if ( aMissingSizes[ i ].iType == size )
+                    {
+                    TN_DEBUG1( "CThumbnailStore::GetMissingSizesL() -- thumbnail found" );
+                    aMissingSizes.Remove( i );
+                    missingSizeCount--;
+                    break;
+                    }
+                }
+                
+            rowStatus = stmt.Next();
+            }
+        stmt.Close();
+        CleanupStack::PopAndDestroy( &stmt );
+        
+        // all found
+        if (missingSizeCount == 0)
+            {
+            return;
+            }
+        else if (round == 1)
+            {
+            // change to real table
+            CleanupClosePushL( stmt );
+            User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectSizeByPath ));
+            paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+            User::LeaveIfError( paramIndex );
+            User::LeaveIfError( stmt.BindText( paramIndex, aPath ));
+            rowStatus = stmt.Next();    
+            }
+        
+        round++;
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CThumbnailStore::FetchThumbnailL()
+// Fetches thumbnail image.
+// ---------------------------------------------------------------------------
+//
+TInt CThumbnailStore::FetchThumbnailL( TThumbnailId aThumbnailId, 
+        CFbsBitmap*& aThumbnail, TDesC8* & aData, TThumbnailSize aThumbnailSize, TSize &aThumbnailRealSize )
+    {
+    TN_DEBUG3( "CThumbnailStore::FetchThumbnailL(%d) aThumbnailSize == %d", aThumbnailId, aThumbnailSize );
+     delete aThumbnail;
+     aThumbnail = NULL;
+
+     RSqlStatement stmt;
+     CleanupClosePushL( stmt );
+     
+     TInt paramIndex = 0;
+     TInt found = KErrNotFound;
+     TInt rowStatus = 0;
+     TInt column = 0;
+     TInt count = 0;
+     TThumbnailSize thumbnailImage = EUnknownThumbnailSize;
+     TThumbnailSize thumbnailVideo = EUnknownThumbnailSize;
+     TThumbnailSize thumbnailAudio = EUnknownThumbnailSize;
+     TBool inTempTable( ETrue );
+     
+     if(aThumbnailSize == EFullScreenThumbnailSize)
+         {
+         thumbnailImage = EImageFullScreenThumbnailSize;
+         thumbnailVideo = EVideoFullScreenThumbnailSize;
+         thumbnailAudio = EAudioFullScreenThumbnailSize;
+         }
+     else if(aThumbnailSize == EGridThumbnailSize)
+         {
+         thumbnailImage = EImageGridThumbnailSize;
+         thumbnailVideo = EVideoGridThumbnailSize;
+         thumbnailAudio = EAudioGridThumbnailSize;
+         }
+     else if(aThumbnailSize == EListThumbnailSize)
+         {
+         thumbnailImage = EImageListThumbnailSize;
+         thumbnailVideo = EVideoListThumbnailSize;
+         thumbnailAudio = EAudioListThumbnailSize;
+         }
+     
+     if(aThumbnailSize == EFullScreenThumbnailSize ||
+        aThumbnailSize == EGridThumbnailSize ||
+        aThumbnailSize == EListThumbnailSize )
+         {
+         TN_DEBUG1( "CThumbnailStore::FetchThumbnailL() -- No DataType -- TEMP TABLE lookup" );
+         User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectTempInfoByIdv2 ));
+         paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+         User::LeaveIfError( paramIndex );
+         User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailId ));
+             
+         paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSizeImage );
+         User::LeaveIfError( paramIndex );
+         User::LeaveIfError( stmt.BindInt( paramIndex, thumbnailImage ));
+         
+         paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSizeVideo );
+         User::LeaveIfError( paramIndex );
+         User::LeaveIfError( stmt.BindInt( paramIndex, thumbnailVideo ));
+         
+         paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSizeAudio );
+         User::LeaveIfError( paramIndex );
+         User::LeaveIfError( stmt.BindInt( paramIndex, thumbnailAudio ));
+             
+         rowStatus = stmt.Next();
+         //if not found from temp table, look from real table
+         if(rowStatus != KSqlAtRow)
+           {
+           TN_DEBUG1( "CThumbnailStore::FetchThumbnailL() -- No DataType -- MAIN TABLE lookup" );
+           inTempTable = EFalse;
+           stmt.Close();
+           CleanupStack::PopAndDestroy( &stmt );
+           CleanupClosePushL( stmt );
+                
+           User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectInfoByIdv2 ));
+             
+           paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+           User::LeaveIfError( paramIndex );
+           User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailId ));
+                 
+           paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSizeImage );
+           User::LeaveIfError( paramIndex );
+           User::LeaveIfError( stmt.BindInt( paramIndex, thumbnailImage ));
+                    
+           paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSizeVideo );
+           User::LeaveIfError( paramIndex );
+           User::LeaveIfError( stmt.BindInt( paramIndex, thumbnailVideo ));
+                    
+           paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSizeAudio );
+           User::LeaveIfError( paramIndex );
+           User::LeaveIfError( stmt.BindInt( paramIndex, thumbnailAudio ));
+             
+           rowStatus = stmt.Next();
+           }               
+         }
+     else
+         {
+         TN_DEBUG1( "CThumbnailStore::FetchThumbnailL() -- TEMP TABLE lookup" );
+         User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectTempInfoById ));
+         paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+         User::LeaveIfError( paramIndex );
+         User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailId ));
+     
+         paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSize );
+         User::LeaveIfError( paramIndex );
+         User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailSize ));
+     
+         rowStatus = stmt.Next();
+
+         //if not found from temp table, look from real table
+         if(rowStatus != KSqlAtRow)
+            {
+            TN_DEBUG1( "CThumbnailStore::FetchThumbnailL() -- MAIN TABLE lookup" );
+            inTempTable = EFalse;
+            stmt.Close();
+            CleanupStack::PopAndDestroy( &stmt );
+            CleanupClosePushL( stmt );
+        
+            User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectInfoById ));
+     
+            paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+            User::LeaveIfError( paramIndex );
+            User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailId ));
+         
+            paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSize );
+            User::LeaveIfError( paramIndex );
+            User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailSize ));
+     
+            rowStatus = stmt.Next();
+            }
+         }
+     if(rowStatus == KSqlAtRow)
+        {
+         TN_DEBUG1( "CThumbnailStore::FetchThumbnailL() -- thumbnail found" );
+         // Check whether blacklisted thumbnail entry modified. 
+         // If thumbnail is marked as blacklisted and timestamp has 
+         // changed, delete thumbnails from tables and leave with 
+         // KErrNotFound to get thumbnail regenerated.
+         column = 4;
+         TInt flags = stmt.ColumnInt( column );
+         if( flags & KThumbnailDbFlagBlacklisted )
+             {
+             TBool modified = EFalse;
+             CheckModifiedByIdL( aThumbnailId, inTempTable, modified );
+             if( modified )
+                 {
+                 // Close db to get deletion of thumbnails executed.
+                 stmt.Close();
+                 CleanupStack::PopAndDestroy( &stmt );
+                 DeleteThumbnailsL( aThumbnailId );
+                 User::Leave( KErrNotFound );
+                 }
+             else
+                 {
+                 User::Leave( KErrCompletion );
+                 }
+             }
+         
+         found = KErrNone;
+         count = 0;
+         count++;
+         column = 0;
+         TInt format = stmt.ColumnInt( column++ );  
+         if(format == 1 /*TThumbnailFormat::EThumbnailFormatJpeg */ )
+             {
+             TPtrC8 ptr = stmt.ColumnBinaryL( column++ );
+             HBufC8* data = ptr.AllocL() ;
+             aThumbnail = NULL;
+             aData = data;     
+             
+          } else {
+             TPtrC8 ptr = stmt.ColumnBinaryL( column );
+             RDesReadStream stream( ptr );
+             aThumbnail = new( ELeave )CFbsBitmap();
+             aThumbnail->InternalizeL( stream );
+             aData = NULL;
+          }
+         
+        //fetch real size of TN
+        column = 2;
+        aThumbnailRealSize.iWidth = stmt.ColumnInt( column++ );
+        aThumbnailRealSize.iHeight = stmt.ColumnInt( column );
+        }
+     else
+         {
+         TN_DEBUG1( "CThumbnailStore::FetchThumbnailL() -- thumbnail NOT found" );
+         }
+         
+     stmt.Close();
+     CleanupStack::PopAndDestroy( &stmt );
+
+     User::LeaveIfError( found );
+     return found;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CThumbnailStore::FetchThumbnailL()
+// Fetches thumbnail image.
+// ---------------------------------------------------------------------------
+//
+void CThumbnailStore::FetchThumbnailL( const TDesC& aPath, CFbsBitmap* &
+    aThumbnail, TDesC8* & aData, const TThumbnailSize aThumbnailSize, TSize &aThumbnailRealSize )
+    {
+    TN_DEBUG3( "CThumbnailStore::FetchThumbnailL(%S) aThumbnailSize==%d", &aPath, aThumbnailSize );
+    delete aThumbnail;
+    aThumbnail = NULL;
+
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    
+    TInt paramIndex = 0;
+    TInt found = KErrNotFound;
+    TInt rowStatus = 0;
+    TInt column = 0;
+    TBool inTempTable = ETrue;
+    
+    TN_DEBUG1( "CThumbnailStore::FetchThumbnailL() -- TEMP TABLE lookup" );
+    TInt err = stmt.Prepare( iDatabase, KThumbnailSelectTempInfoByPath );
+
+#ifdef _DEBUG
+    TPtrC errorMsg = iDatabase.LastErrorMessage();
+    TN_DEBUG2( "CThumbnailStore::FetchThumbnailL() %S" , &errorMsg);
+#endif
+    User::LeaveIfError( err );
+    
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindText( paramIndex, aPath ));
+    
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSize );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailSize ));
+    
+    rowStatus = stmt.Next();
+
+    //if not found from temp table, look from real table
+    if(rowStatus != KSqlAtRow)
+       {
+       TN_DEBUG1( "CThumbnailStore::FetchThumbnailL() -- MAIN TABLE lookup" );
+       inTempTable = EFalse;
+       stmt.Close();
+       CleanupStack::PopAndDestroy( &stmt );
+       CleanupClosePushL( stmt );
+       
+       User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectInfoByPath ));
+    
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindText( paramIndex, aPath ));
+        
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSize );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailSize ));
+    
+        rowStatus = stmt.Next();
+       }
+
+    if(rowStatus == KSqlAtRow)
+       {
+        TN_DEBUG1( "CThumbnailStore::FetchThumbnailL() -- thumbnail found" );
+        // Check whether blacklisted thumbnail entry modified. 
+        // If thumbnail is marked as blacklisted and timestamp has 
+        // changed, delete thumbnails from tables and leave with 
+        // KErrNotFound to get thumbnail regenerated.
+        column = 4;
+        TInt flags = stmt.ColumnInt( column );
+        if( flags & KThumbnailDbFlagBlacklisted && aPath.Length() )
+            {
+            TBool modified = EFalse;
+            CheckModifiedByPathL( aPath, inTempTable, modified );
+            if( modified )
+                {
+                // Close db to get deletion of thumbnails executed.
+                stmt.Close();
+                CleanupStack::PopAndDestroy( &stmt );
+                DeleteThumbnailsL( aPath );
+                User::Leave( KErrNotFound );
+                }
+            else
+                {
+                User::Leave( KErrCompletion );
+                }
+            }
+        else if( !(flags & KThumbnailDbFlagBlacklisted) )
+            {
+            found = KErrNone;
+            column = 0;
+            TInt format = stmt.ColumnInt( column++ );  
+            if(format == 1 /*TThumbnailFormat::EThumbnailFormatJpeg */ )
+               {
+               TPtrC8 ptr = stmt.ColumnBinaryL( column++ );
+               HBufC8* data = ptr.AllocL() ;
+               aThumbnail = NULL;
+               aData = data;
+               
+            } else {
+    
+               TPtrC8 ptr = stmt.ColumnBinaryL( column++ );
+               RDesReadStream stream( ptr );
+               aThumbnail = new( ELeave )CFbsBitmap();
+               aThumbnail->InternalizeL( stream );
+               aData = NULL;
+               }
+            
+            //fetch real size of TN
+            column = 2;
+            aThumbnailRealSize.iWidth = stmt.ColumnInt( column++ );
+            aThumbnailRealSize.iHeight = stmt.ColumnInt( column );
+            }
+        }
+    else
+        {
+        TN_DEBUG1( "CThumbnailStore::FetchThumbnailL() -- thumbnail NOT found" );
+        }
+        
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+
+    User::LeaveIfError( found );
+    }
+
+// -----------------------------------------------------------------------------
+// Delete thumbnails for given object file by Path
+// -----------------------------------------------------------------------------
+//
+void CThumbnailStore::DeleteThumbnailsL( const TDesC& aPath )
+    {
+    RThumbnailTransaction transaction( iDatabase );
+    CleanupClosePushL( transaction );
+    transaction.BeginL();
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    
+    TInt paramIndex = 0;
+    TInt paramIndex1 = 0;
+    TInt paramIndex2 = 0;
+    TInt rowStatus = 0;
+    TInt column = 0;
+    TInt rowid = 0;
+    TInt deleteCount = 0;
+    
+    TN_DEBUG1( "CThumbnailStore::DeleteThumbnailsByPathL() -- TEMP TABLE lookup" );
+    TInt err = stmt.Prepare( iDatabase, KTempThumbnailSqlSelectRowIDInfoByPath);
+    User::LeaveIfError( err );
+    
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindText( paramIndex, aPath ));
+    
+    rowStatus = stmt.Next();
+    RSqlStatement stmt_info;
+    CleanupClosePushL( stmt_info );
+    err = stmt_info.Prepare( iDatabase, KTempThumbnailSqlDeleteInfoByPath);
+    RSqlStatement stmt_infodata;
+    CleanupClosePushL( stmt_infodata );
+    err = stmt_infodata.Prepare( iDatabase, KTempThumbnailSqlDeleteInfoDataByPath);
+    
+    
+    while(rowStatus == KSqlAtRow)
+       {  
+       rowid = stmt.ColumnInt( column ); 
+       paramIndex1 = stmt_info.ParameterIndex( KThumbnailSqlParamRowID );
+       User::LeaveIfError( paramIndex1 );
+       User::LeaveIfError( stmt_info.BindInt( paramIndex1, rowid ));
+       
+       deleteCount = stmt_info.Exec();
+       stmt_info.Reset();
+       User::LeaveIfError( deleteCount );
+             
+       paramIndex2 = stmt_infodata.ParameterIndex( KThumbnailSqlParamRowID );
+       User::LeaveIfError( paramIndex2 );
+       User::LeaveIfError( stmt_infodata.BindInt( paramIndex2, rowid ));
+             
+       deleteCount = stmt_infodata.Exec();
+       stmt_infodata.Reset();
+       User::LeaveIfError( deleteCount );
+       
+       TN_DEBUG1( "CThumbnailStore::DeleteThumbnailsByPathL() -- TEMP TABLE lookup - thumbnail deleted" );
+       
+       // fetch another row (temp table rowIDs are updated immediately)
+       stmt.Reset();
+       
+       paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+       User::LeaveIfError( paramIndex );
+       User::LeaveIfError( stmt.BindText( paramIndex, aPath ));
+       
+       rowStatus = stmt.Next();   
+       }
+    stmt_infodata.Close();
+    stmt_info.Close();
+    CleanupStack::PopAndDestroy( &stmt_infodata );
+    CleanupStack::PopAndDestroy( &stmt_info );
+    
+
+    //look from real table 
+    TN_DEBUG1( "CThumbnailStore::DeleteThumbnailByPathL() -- MAIN TABLE lookup" );
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+    CleanupClosePushL( stmt );   
+    User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSqlSelectRowIDInfoByPath ));
+    
+    User::LeaveIfError( err );
+    
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindText( paramIndex, aPath ));
+         
+    rowStatus = stmt.Next();   
+    CleanupClosePushL( stmt_info );
+    err = stmt_info.Prepare( iDatabase, KThumbnailSqlDeleteInfoByPath);
+    CleanupClosePushL( stmt_infodata );
+    err = stmt_infodata.Prepare( iDatabase, KThumbnailSqlDeleteInfoDataByPath);
+       
+       
+    while(rowStatus == KSqlAtRow)
+       { 
+       rowid = stmt.ColumnInt( column ); 
+       paramIndex1 = stmt_info.ParameterIndex( KThumbnailSqlParamRowID );
+       User::LeaveIfError( paramIndex1 );
+       User::LeaveIfError( stmt_info.BindInt( paramIndex1, rowid ));
+          
+       deleteCount = stmt_info.Exec();
+       stmt_info.Reset();
+       User::LeaveIfError( deleteCount );
+                
+       paramIndex2 = stmt_infodata.ParameterIndex( KThumbnailSqlParamRowID );  
+       User::LeaveIfError( paramIndex2 );
+       User::LeaveIfError( stmt_infodata.BindInt( paramIndex2, rowid ));
+                
+       deleteCount = stmt_infodata.Exec();
+       stmt_infodata.Reset();
+       User::LeaveIfError( deleteCount );
+       
+       TN_DEBUG1( "CThumbnailStore::DeleteThumbnailByPathL() -- MAIN TABLE lookup - thumbnail deleted" );
+       
+       rowStatus = stmt.Next();
+       }
+    
+    stmt_infodata.Close();
+    stmt_info.Close();
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt_infodata );
+    CleanupStack::PopAndDestroy( &stmt_info );
+    CleanupStack::PopAndDestroy( &stmt );    
+    transaction.CommitL();
+    CleanupStack::PopAndDestroy( &transaction );
+    }
+
+// -----------------------------------------------------------------------------
+// Delete thumbnails for given object file by Id
+// -----------------------------------------------------------------------------
+//
+void CThumbnailStore::DeleteThumbnailsL( const TThumbnailId& aTNId )
+    {
+#ifdef _DEBUG
+    TTime aStart, aStop;
+    aStart.UniversalTime();
+#endif
+        
+    TInt paramIndex = 0;
+    TInt paramIndex1 = 0;
+    TInt paramIndex2 = 0;
+    TInt rowStatus = 0;
+    TInt column = 0;
+    TInt rowid = 0;
+    TInt deleteCount = 0;
+      
+    RThumbnailTransaction transaction( iDatabase );
+    CleanupClosePushL( transaction );
+    transaction.BeginL();
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    
+    TN_DEBUG1( "CThumbnailStore::DeleteThumbnailsByIdL() -- TEMP TABLE lookup" );
+    TInt err = stmt.Prepare( iDatabase, KTempThumbnailSqlSelectRowIDInfoByID);
+    User::LeaveIfError( err );
+        
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aTNId ));
+        
+    rowStatus = stmt.Next();
+    RSqlStatement stmt_info;
+    CleanupClosePushL( stmt_info );
+    err = stmt_info.Prepare( iDatabase, KTempThumbnailSqlDeleteInfoByID);
+    RSqlStatement stmt_infodata;
+    CleanupClosePushL( stmt_infodata );
+    err = stmt_infodata.Prepare( iDatabase, KTempThumbnailSqlDeleteInfoDataByID);
+        
+        
+    while(rowStatus == KSqlAtRow)
+       {  
+       rowid = stmt.ColumnInt( column ); 
+       paramIndex1 = stmt_info.ParameterIndex( KThumbnailSqlParamRowID );
+       User::LeaveIfError( paramIndex1 );
+       User::LeaveIfError( stmt_info.BindInt( paramIndex1, rowid ));
+           
+       err = stmt_info.Exec();
+       stmt_info.Reset();
+       User::LeaveIfError( err );
+                 
+       paramIndex2 = stmt_infodata.ParameterIndex( KThumbnailSqlParamRowID );
+       User::LeaveIfError( paramIndex2 );
+       User::LeaveIfError( stmt_infodata.BindInt( paramIndex2, rowid ));
+                 
+       err = stmt_infodata.Exec();
+       stmt_infodata.Reset();
+       User::LeaveIfError( err );
+       deleteCount++;
+       
+       TN_DEBUG1( "CThumbnailStore::DeleteThumbnailsByIdL() -- TEMP TABLE lookup - thumbnail deleted" );
+       
+       // fetch another row (temp table rowIDs are updated immediately)
+       stmt.Reset();
+       
+       paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+       User::LeaveIfError( paramIndex );
+       User::LeaveIfError( stmt.BindInt( paramIndex, aTNId ));
+       
+       rowStatus = stmt.Next();    
+       }
+    
+    stmt_infodata.Close();
+    stmt_info.Close();
+    CleanupStack::PopAndDestroy( &stmt_infodata );
+    CleanupStack::PopAndDestroy( &stmt_info );
+        
+    
+    //look from real table       
+    TN_DEBUG1( "CThumbnailStore::DeleteThumbnailByIdL() -- MAIN TABLE lookup" );
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+    CleanupClosePushL( stmt );   
+    User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSqlSelectRowIDInfoByID ));
+        
+    User::LeaveIfError( err );
+        
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aTNId ));
+             
+    rowStatus = stmt.Next();   
+    CleanupClosePushL( stmt_info );
+    err = stmt_info.Prepare( iDatabase, KThumbnailSqlDeleteInfoByID);
+    CleanupClosePushL( stmt_infodata );
+    err = stmt_infodata.Prepare( iDatabase, KThumbnailSqlDeleteInfoDataByID);
+           
+           
+    while(rowStatus == KSqlAtRow)
+       { 
+       rowid = stmt.ColumnInt( column ); 
+       paramIndex1 = stmt_info.ParameterIndex( KThumbnailSqlParamRowID );
+       User::LeaveIfError( paramIndex1 );
+       User::LeaveIfError( stmt_info.BindInt( paramIndex1, rowid ));
+              
+       err = stmt_info.Exec();
+       stmt_info.Reset();
+       User::LeaveIfError( err );
+                    
+       paramIndex2 = stmt_infodata.ParameterIndex( KThumbnailSqlParamRowID );  
+       User::LeaveIfError( paramIndex2 );
+       User::LeaveIfError( stmt_infodata.BindInt( paramIndex2, rowid ));
+                    
+       err = stmt_infodata.Exec();
+       stmt_infodata.Reset();
+       User::LeaveIfError( err );
+       deleteCount++;
+       
+       TN_DEBUG1( "CThumbnailStore::DeleteThumbnailByIdL() -- MAIN TABLE lookup - thumbnail deleted" );
+       
+       rowStatus = stmt.Next();
+       }
+        
+    stmt_infodata.Close();
+    stmt_info.Close();
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt_infodata );
+    CleanupStack::PopAndDestroy( &stmt_info );
+    CleanupStack::PopAndDestroy( &stmt );    
+    transaction.CommitL();
+    CleanupStack::PopAndDestroy( &transaction );
+    
+#ifdef _DEBUG
+    aStop.UniversalTime();
+    TN_DEBUG2( "CThumbnailStore::DeleteThumbnailsByIdL() took %d ms", (TInt)aStop.MicroSecondsFrom(aStart).Int64()/1000);
+#endif
+    
+    if(!deleteCount)
+        {
+        User::Leave(KErrNotFound);
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CThumbnailStore::PersistentSizes()
+// ---------------------------------------------------------------------------
+//
+void CThumbnailStore::SetPersistentSizes(const RArray < TThumbnailPersistentSize > &aSizes)
+    {
+    iPersistentSizes = aSizes;
+    }
+
+// ---------------------------------------------------------------------------
+// CThumbnailStore::FlushCacheTable()
+// ---------------------------------------------------------------------------
+//
+void CThumbnailStore::FlushCacheTable( TBool aForce )
+    {
+    TN_DEBUG1("CThumbnailStore::FlushCacheTable() in");
+    
+    StopAutoFlush();
+    
+    if(iBatchItemCount <= 0)
+        {
+        // cache empty
+        return;
+        }
+    
+    if(iBatchItemCount < KMaxBatchItems && !aForce)
+       {
+       //some items in cache
+       StartAutoFlush();
+       return;
+       }
+    
+    //cache full, flush now
+    iBatchItemCount = 0;
+    
+#ifdef _DEBUG
+    TTime aStart, aStop;
+    aStart.UniversalTime();
+#endif
+    
+    // Move data from temp table to main....
+    TInt err_begin = iDatabase.Exec( KThumbnailBeginTransaction );
+    TN_DEBUG2("CThumbnailStore::FlushCacheTable() KThumbnailBeginTransaction %d", err_begin);
+    
+    TInt err_tempinfo = iDatabase.Exec( KThumbnailMoveFromTempInfoToMainTable );
+    TN_DEBUG2("CThumbnailStore::FlushCacheTable() KThumbnailMoveFromTempInfoToMainTable %d", err_tempinfo);
+    
+    TInt err_tempdata = iDatabase.Exec( KThumbnailMoveFromTempDataToMainTable );
+    TN_DEBUG2("CThumbnailStore::FlushCacheTable() KThumbnailMoveFromTempDataToMainTable %d", err_tempdata);
+    
+    TInt err_delinfo = iDatabase.Exec( KThumbnailDeleteFromTempInfoTable );
+    TN_DEBUG2("CThumbnailStore::FlushCacheTable() KThumbnailDeleteFromTempInfoTable %d", err_delinfo);
+    
+    TInt err_deldata = iDatabase.Exec( KThumbnailDeleteFromTempDataTable );
+    TN_DEBUG2("CThumbnailStore::FlushCacheTable() KThumbnailDeleteFromTempDataTable %d", err_deldata);
+   
+    
+    if( err_tempinfo < 0 || err_tempdata < 0  || err_delinfo < 0  || err_deldata < 0 )
+        {
+        TInt err = iDatabase.Exec( KThumbnailRollbackTransaction );
+        TN_DEBUG2("CThumbnailStore::FlushCacheTable() KThumbnailRollbackTransaction %d", err);
+        }
+    else
+        {
+        TInt err_commit = iDatabase.Exec( KThumbnailCommitTransaction );
+        TN_DEBUG2("CThumbnailStore::FlushCacheTable() KThumbnailCommitTransaction %d", err_commit);
+        }
+    
+#ifdef _DEBUG
+    aStop.UniversalTime();
+    TN_DEBUG2( "CThumbnailStore::FlushCacheTable() took %d ms", (TInt)aStop.MicroSecondsFrom(aStart).Int64()/1000);
+#endif
+
+    TN_DEBUG1("CThumbnailStore::FlushCacheTable() out");
+    }
+
+
+// -----------------------------------------------------------------------------
+// Find store for thumbnails by Id
+// -----------------------------------------------------------------------------
+//
+void CThumbnailStore::FindStoreL(TThumbnailId aThumbnailId)
+    {
+    TN_DEBUG2( "CThumbnailStore::FindStore( %d )", aThumbnailId );
+     RSqlStatement stmt;
+     CleanupClosePushL( stmt );
+         
+     TInt paramIndex = 0;
+     TInt found = KErrNotFound;
+     TInt rowStatus = 0;
+         
+     TN_DEBUG1( "CThumbnailStore::FindStore() -- TEMP TABLE lookup" );
+     User::LeaveIfError( stmt.Prepare( iDatabase, KTempThumbnailSqlSelectRowIDInfoByID ));
+     paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+     User::LeaveIfError( paramIndex );
+     User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailId ));
+         
+     rowStatus = stmt.Next();
+
+    //if not found from temp table, look from real table
+    if(rowStatus != KSqlAtRow)
+        {
+        TN_DEBUG1( "CThumbnailStore::FindStore() -- MAIN TABLE lookup" );
+        stmt.Close();
+        CleanupStack::PopAndDestroy( &stmt );
+        CleanupClosePushL( stmt );
+            
+        User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSqlSelectRowIDInfoByID ));
+         
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnailId ));
+            
+        rowStatus = stmt.Next();
+        }
+
+    if( rowStatus == KSqlAtRow )
+        {
+        TN_DEBUG1( "CThumbnailStore::FindStore() -- thumbnail found" );
+        found = KErrNone;
+        }
+    else
+        {
+        TN_DEBUG1( "CThumbnailStore::FindStore() -- thumbnail NOT found" );
+        }
+             
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+
+    User::LeaveIfError( found );
+    }
+
+// -----------------------------------------------------------------------------
+// Updates path in current store by Id
+// -----------------------------------------------------------------------------
+//
+TBool CThumbnailStore::UpdateStoreL( TThumbnailId aItemId, const TDesC& aNewPath )
+    {
+    TN_DEBUG3( "CThumbnailStore::UpdateStore( %d, %S) by ID", aItemId, &aNewPath);
+
+    TBool doUpdate(EFalse);
+    TPath oldPath;
+    TInt column = 0;
+    
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+       
+    //check if path needs updating in temp table
+    User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectTempPathByID ));
+    
+    TInt paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aItemId ));
+     
+    TInt rowStatus = stmt.Next();
+
+     //if not found from temp table, look from real table
+     if(rowStatus != KSqlAtRow)
+         {
+         stmt.Close();
+         CleanupStack::PopAndDestroy( &stmt );
+         CleanupClosePushL( stmt );
+         
+         //check if path needs updating in main table
+         User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectPathByID ));
+         
+         paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+         User::LeaveIfError( paramIndex );
+         User::LeaveIfError( stmt.BindInt( paramIndex, aItemId ));
+          
+         rowStatus = stmt.Next();
+         }
+     
+     if(rowStatus == KSqlAtRow)
+         {
+           TN_DEBUG1( "CThumbnailStore::UpdateStore() -- matching TN ID found" );
+           oldPath = stmt.ColumnTextL(column);
+            
+            if(oldPath.CompareF(aNewPath) != 0)
+                {
+                TN_DEBUG1( "CThumbnailStore::UpdateStore() -- path no match" );
+                doUpdate = ETrue;
+                }
+            else
+                {
+                TN_DEBUG1( "CThumbnailStore::UpdateStore() -- path match, skip..." );
+                }
+         }
+     
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+        
+    if(!doUpdate)
+        {
+        TN_DEBUG2( "CThumbnailStore::UpdateStore() -- no need to update old path=%S", &oldPath );
+        return EFalse;
+        }
+    
+    //Encapsulate update to Transaction
+    RThumbnailTransaction transaction( iDatabase );
+    CleanupClosePushL( transaction );
+    transaction.BeginL();
+	
+    CleanupClosePushL( stmt );
+     
+    TN_DEBUG1( "CThumbnailStore::UpdateStore() -- do temp path update" );
+
+    User::LeaveIfError( stmt.Prepare( iDatabase, KTempThumbnailSqlUpdateById ));
+    
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindText( paramIndex, aNewPath ));
+       
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aItemId ));
+    User::LeaveIfError( stmt.Exec());
+    
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+    CleanupClosePushL( stmt );
+    
+    TN_DEBUG1( "CThumbnailStore::UpdateStore() -- do main table path update" );
+             
+    User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSqlUpdateById ));
+                
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindText( paramIndex, aNewPath ));
+
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aItemId ));  
+            
+    User::LeaveIfError( stmt.Exec());   
+    CleanupStack::PopAndDestroy( &stmt );
+    
+    // Commit transaction
+    transaction.CommitL();
+    CleanupStack::PopAndDestroy( &transaction );
+    
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// Update IDs by Path
+// -----------------------------------------------------------------------------
+//
+void CThumbnailStore::UpdateStoreL( const TDesC& aPath, TThumbnailId aNewId )
+    {
+    TN_DEBUG3( "CThumbnailStore::UpdateStore( %S, %d ) by Path", &aPath, aNewId);
+    
+#ifdef _DEBUG
+    TTime aStart, aStop;
+    aStart.UniversalTime();
+#endif
+    
+    //Encapsulate update to Transaction
+    RThumbnailTransaction transaction( iDatabase );
+    CleanupClosePushL( transaction );
+    transaction.BeginL();
+    
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+       
+    TN_DEBUG1( "CThumbnailStore::UpdateStoreL() -- do temp ID update" );
+    
+    TInt err = stmt.Prepare( iDatabase, KTempThumbnailUpdateIdByPath );
+    
+#ifdef _DEBUG
+    TPtrC errorMsg = iDatabase.LastErrorMessage();
+    TN_DEBUG2( "CThumbnailStore::UpdateStoreL() KTempThumbnailUpdateIdByPath %S" , &errorMsg);
+#endif
+    
+    User::LeaveIfError( err );
+    
+    TInt paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aNewId ));
+    
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindText( paramIndex, aPath ));
+    
+    err =  stmt.Exec();
+    
+    TN_DEBUG2( "CThumbnailStore::UpdateStoreL() err==%d", err );
+    
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+    CleanupClosePushL( stmt );
+    
+    TN_DEBUG1( "CThumbnailStore::UpdateStoreL() -- do main table ID update" );
+    
+    err = stmt.Prepare( iDatabase, KThumbnailUpdateIdByPath );
+    
+#ifdef _DEBUG
+    TPtrC errorMsg2 = iDatabase.LastErrorMessage();
+    TN_DEBUG2( "CThumbnailStore::UpdateStoreL() KThumbnailUpdateIdByPath %S" , &errorMsg2);
+#endif    
+    
+    User::LeaveIfError( err );
+    
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aNewId ));
+    
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindText( paramIndex, aPath ));
+    
+    err =  stmt.Exec();
+    
+    TN_DEBUG2( "CThumbnailStore::UpdateStoreL() err==%d", err );
+    
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt ); 
+    
+    // Commit transaction
+    transaction.CommitL();
+    CleanupStack::PopAndDestroy( &transaction );
+    
+#ifdef _DEBUG
+    aStop.UniversalTime();
+    TN_DEBUG2( "CThumbnailStore::UpdateStoreL() took %d ms", (TInt)aStop.MicroSecondsFrom(aStart).Int64()/1000);
+#endif
+    }
+
+// -----------------------------------------------------------------------------
+// Checks if given modification timestamp is newer than in DB
+// -----------------------------------------------------------------------------
+//
+TBool CThumbnailStore::CheckModifiedL( const TThumbnailId aItemId, const TInt64 aModified )
+    {
+    TN_DEBUG2( "CThumbnailStore::CheckModifiedL( %d )", aItemId);
+
+    TInt column = 0;
+    
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+       
+    User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectTempModifiedByID ));
+    
+    TInt paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aItemId ));
+     
+    TInt rowStatus = stmt.Next();
+
+     //if not found from temp table, look from real table
+     if(rowStatus != KSqlAtRow)
+         {
+         stmt.Close();
+         CleanupStack::PopAndDestroy( &stmt );
+         CleanupClosePushL( stmt );
+         
+         User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectModifiedByID ));
+         
+         paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+         User::LeaveIfError( paramIndex );
+         User::LeaveIfError( stmt.BindInt( paramIndex, aItemId ));
+          
+         rowStatus = stmt.Next();
+         }
+     
+     TBool modified = EFalse;
+     
+     if(rowStatus == KSqlAtRow)
+         {
+         TInt64 oldModified = stmt.ColumnInt64( column );
+         
+         if (oldModified < aModified)
+             {
+             TN_DEBUG1( "CThumbnailStore::CheckModifiedL() -- timestamp is newer than original" );
+             modified = ETrue;
+             }
+         else if (oldModified > aModified)
+             {
+             TN_DEBUG1( "CThumbnailStore::CheckModifiedL() -- timestamp is older than original" );
+             }
+         else if (oldModified == aModified)
+             {
+             TN_DEBUG1( "CThumbnailStore::CheckModifiedL() -- timestamp is the same as original" );
+             }
+         }
+     
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt ); 
+    
+    return modified;
+    }
+
+// -----------------------------------------------------------------------------
+// Fetches thumbnails from store by Id
+// -----------------------------------------------------------------------------
+//
+void CThumbnailStore::FetchThumbnailsL(TThumbnailId aItemId, RArray < TThumbnailDatabaseData* >& aThumbnails)
+    {
+    TN_DEBUG1( "CThumbnailStore::FetchThumbnails()" );
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    
+    // first temp table
+    User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectTempById ));
+
+    TInt paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aItemId ));
+
+    TInt rowStatus = stmt.Next();
+    
+    TPath path;
+    TPath tnPath;
+    while ( rowStatus == KSqlAtRow)
+        {
+        TN_DEBUG1( "CThumbnailStore::FetchThumbnails() -- thumbnail found from temp table" );
+        
+        TInt column = 0;
+            
+        TThumbnailDatabaseData* newRow = new(ELeave) TThumbnailDatabaseData;
+            
+        TInt err = stmt.ColumnText( column++, newRow->iPath );
+        newRow->iTnId = stmt.ColumnInt( column++ );
+        newRow->iSize = stmt.ColumnInt( column++ );
+        newRow->iFormat = stmt.ColumnInt( column++ );
+        err = stmt.ColumnText( column++, newRow->iTnPath);
+        newRow->iWidth = stmt.ColumnInt( column++ );
+        newRow->iHeight = stmt.ColumnInt( column++ );
+        newRow->iOrigWidth = stmt.ColumnInt( column++ );
+        newRow->iOrigHeight = stmt.ColumnInt( column++ );
+        newRow->iFlags = stmt.ColumnInt( column++ );
+        newRow->iVideoPosition = stmt.ColumnInt( column++ );
+        newRow->iOrientation = stmt.ColumnInt( column++ );
+        newRow->iThumbFromPath = stmt.ColumnInt( column++ );
+        newRow->iModified = stmt.ColumnInt64( column++ );
+        
+        if(newRow->iFormat == 0)
+            {
+            TPtrC8 ptr = stmt.ColumnBinaryL( column++ );
+            RDesReadStream stream( ptr );
+            newRow->iBlob = new( ELeave )CFbsBitmap();
+            newRow->iBlob->InternalizeL( stream );
+            }
+        else if(newRow->iFormat == 1)
+            {
+            TPtrC8 ptr = stmt.ColumnBinaryL( column++ );
+            HBufC8* data = ptr.AllocL() ;
+            newRow->iBlob = NULL;
+            newRow->iData = data;
+            }
+        
+        aThumbnails.Append( newRow );
+               
+        rowStatus = stmt.Next();
+        }
+    
+    // then real table
+    stmt.Close();
+    CleanupStack::PopAndDestroy(&stmt); 
+    CleanupClosePushL( stmt );
+    User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectById ));
+
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aItemId ));
+
+    rowStatus = stmt.Next();
+    while ( rowStatus == KSqlAtRow)
+        {
+        TN_DEBUG1( "CThumbnailStore::FetchThumbnails() -- thumbnail found from real table" );
+        
+        TInt column = 0;
+        
+        TThumbnailDatabaseData* newRow = new(ELeave) TThumbnailDatabaseData;
+        
+        TInt err = stmt.ColumnText( column++, newRow->iPath );
+        newRow->iTnId = stmt.ColumnInt( column++ );
+        newRow->iSize = stmt.ColumnInt( column++ );
+        newRow->iFormat = stmt.ColumnInt( column++ );
+        err = stmt.ColumnText( column++, newRow->iTnPath);
+        newRow->iWidth = stmt.ColumnInt( column++ );
+        newRow->iHeight = stmt.ColumnInt( column++ );
+        newRow->iOrigWidth = stmt.ColumnInt( column++ );
+        newRow->iOrigHeight = stmt.ColumnInt( column++ );
+        newRow->iFlags = stmt.ColumnInt( column++ );
+        newRow->iVideoPosition = stmt.ColumnInt( column++ );
+        newRow->iOrientation = stmt.ColumnInt( column++ );
+        newRow->iThumbFromPath = stmt.ColumnInt( column++ );
+        newRow->iModified = stmt.ColumnInt64( column++ );
+        
+        if(newRow->iFormat == 0)
+            {
+            TPtrC8 ptr = stmt.ColumnBinaryL( column++ );
+            RDesReadStream stream( ptr );
+            newRow->iBlob = new( ELeave )CFbsBitmap();
+            newRow->iBlob->InternalizeL( stream );
+            }
+        else if(newRow->iFormat == 1)
+            {
+            TPtrC8 ptr = stmt.ColumnBinaryL( column++ );
+            HBufC8* data = ptr.AllocL() ;
+            newRow->iBlob = NULL;
+            newRow->iData = data;
+            }
+        
+        aThumbnails.Append( newRow );
+              
+        rowStatus = stmt.Next();
+        }
+    
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+    }
+
+// -----------------------------------------------------------------------------
+// Stores thumbnails to store
+// -----------------------------------------------------------------------------
+//
+
+void CThumbnailStore::StoreThumbnailsL(const TDesC& aNewPath, RArray < TThumbnailDatabaseData* >& aThumbnails)
+    {
+    TN_DEBUG1( "CThumbnailStore::StoreThumbnails()" );
+    
+    TInt ThumbnailCount = aThumbnails.Count();
+    RSqlStatement stmt;
+    for ( TInt i = 0; i < ThumbnailCount; i++ )
+        {
+        RThumbnailTransaction transaction( iDatabase );
+        CleanupClosePushL( transaction );
+        transaction.BeginL();
+        
+        CleanupClosePushL( stmt );
+          
+        User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailInsertThumbnailInfoByPathAndId ));
+        
+        TInt paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindText( paramIndex, aNewPath ));
+        
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamWidth );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnails[ i ]->iWidth ));
+        
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamHeight );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnails[ i ]->iHeight ));
+        
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamOriginalWidth );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnails[ i ]->iOrigWidth ));
+        
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamOriginalHeight );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnails[ i ]->iOrigHeight ));
+        
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamFormat );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnails[ i ]->iFormat ));
+        
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamFlags );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnails[ i ]->iFlags ));
+        
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamSize );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnails[ i ]->iSize ));
+        
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnails[ i ]->iTnId ));
+        
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamOrientation );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnails[ i ]->iOrientation ));
+        
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamThumbFromPath );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt( paramIndex, aThumbnails[ i ]->iThumbFromPath ));
+        
+        paramIndex = stmt.ParameterIndex( KThumbnailSqlParamModified );
+        User::LeaveIfError( paramIndex );
+        User::LeaveIfError( stmt.BindInt64( paramIndex, aThumbnails[ i ]->iModified ));
+        
+        User::LeaveIfError( stmt.Exec());    
+        CleanupStack::PopAndDestroy( &stmt );
+        
+        RSqlStatement stmtData;
+        CleanupClosePushL( stmtData );
+        TInt err = stmtData.Prepare( iDatabase, KThumbnailInsertTempThumbnailInfoData );
+        
+        if(aThumbnails[ i ]->iFormat == 0)
+            {
+            CBufFlat* buf = CBufFlat::NewL( KStreamBufferSize );
+            CleanupStack::PushL( buf );
+            RBufWriteStream stream;
+            stream.Open( *buf );
+            aThumbnails[ i ]->iBlob->ExternalizeL( stream );
+            paramIndex = stmtData.ParameterIndex( KThumbnailSqlParamData );
+            User::LeaveIfError( paramIndex );
+            User::LeaveIfError( stmtData.BindBinary( paramIndex, buf->Ptr( 0 ) ));
+            CleanupStack::PopAndDestroy( buf );
+            delete aThumbnails[i]->iBlob;
+            aThumbnails[i]->iBlob = NULL;
+            }
+        else if(aThumbnails[ i ]->iFormat == 1)
+            {
+            paramIndex = stmtData.ParameterIndex( KThumbnailSqlParamData );
+            User::LeaveIfError( paramIndex );
+            User::LeaveIfError( stmtData.BindBinary( paramIndex, *aThumbnails[ i ]->iData ));
+            delete aThumbnails[i]->iData;
+            aThumbnails[i]->iData = NULL;
+            }
+        
+        User::LeaveIfError( stmtData.Exec());
+        CleanupStack::PopAndDestroy( &stmtData );
+        
+        // Commit transaction
+        transaction.CommitL();
+        CleanupStack::PopAndDestroy( &transaction );
+        
+        delete aThumbnails[i];
+        aThumbnails[i] = NULL;
+        iBatchItemCount++;                          
+        }
+    
+    FlushCacheTable();
+    }
+
+// -----------------------------------------------------------------------------
+// CheckVersionAndImeiL()
+// -----------------------------------------------------------------------------
+//
+TInt CThumbnailStore::CheckImeiL()
+    {
+    TN_DEBUG1( "CThumbnailStore::CheckImeiL()" );
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+         
+    TInt rowStatus = 0;
+    TInt column = 0;
+    TBuf<KImeiBufferSize> imei;
+      
+    TInt ret = stmt.Prepare( iDatabase, KThumbnailSelectFromVersion );
+    if(ret < 0 )
+       {  
+       stmt.Close();
+       CleanupStack::PopAndDestroy( &stmt ); 
+       return KErrNotSupported;
+       }
+              
+    rowStatus = stmt.Next();
+    
+    if ( rowStatus == KSqlAtRow)    
+       {        
+       column=2;
+       stmt.ColumnText( column++, imei);  
+       }
+    
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt ); 
+    
+    if( imei == iImei )
+      {
+      return KErrNone;  
+      }
+    else
+      {
+      return KErrNotSupported;  
+      }
+    }
+
+// -----------------------------------------------------------------------------
+// CheckVersionAndImeiL()
+// -----------------------------------------------------------------------------
+//
+TInt CThumbnailStore::CheckVersionL()
+    {
+    TN_DEBUG1( "CThumbnailStore::CheckVersionL()" );
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+         
+    TInt rowStatus = 0;
+    TInt column = 0;
+    TInt minor = 0;
+    TInt major = 0;
+
+      
+    TInt ret = stmt.Prepare( iDatabase, KThumbnailSelectFromVersion );
+    if(ret < 0 )
+       {  
+       stmt.Close();
+       CleanupStack::PopAndDestroy( &stmt ); 
+       return KErrNotSupported;
+       }
+              
+    rowStatus = stmt.Next();
+    
+    if ( rowStatus == KSqlAtRow)    
+       {        
+       major = stmt.ColumnInt( column++);
+       minor = stmt.ColumnInt( column++);
+       }
+    
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt ); 
+    
+    if(major == KMajor && minor == KMinor )
+      {
+      return KErrNone;  
+      }
+    else
+      {
+      return KErrNotSupported;  
+      }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CheckVersionAndImeiL()
+// -----------------------------------------------------------------------------
+//
+TInt CThumbnailStore::CheckMediaIDL()
+    {
+    
+    TN_DEBUG1( "CThumbnailStore::CheckMediaIDL()" );
+    TInt err = 0;
+    
+    TVolumeInfo volumeinfo;
+    err = iFs.Volume(volumeinfo, iDrive);
+    TUint id = volumeinfo.iUniqueID;
+    TBuf<50> mediaid;
+    mediaid.Num(id);
+    
+    RFile64 file;
+    err = file.Open(iFs, mediaid, EFileShareReadersOrWriters);
+    if(err)
+       {
+       file.Create(iFs, mediaid, EFileShareReadersOrWriters );
+       file.Close();
+       return KErrNotSupported;
+       } 
+    file.Close();
+    return KErrNone;  
+    }
+     
+// -----------------------------------------------------------------------------
+// AddVersionAndImeiL()
+// -----------------------------------------------------------------------------
+//
+void CThumbnailStore::AddVersionAndImeiL()
+    {
+    
+    TN_DEBUG1( "CThumbnailStore::AddVersionAndImei()" );
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+            
+    TInt paramIndex = 0;
+            
+    User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailInsertToVersion ));
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamImei );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindText( paramIndex, iImei ));  
+    
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamMinor );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, KMinor )); 
+    
+    paramIndex = stmt.ParameterIndex( KThumbnailSqlParamMajor );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, KMajor )); 
+    
+    User::LeaveIfError( stmt.Exec());
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+    
+    }
+
+// -----------------------------------------------------------------------------
+// ResetThumbnailIDs()
+// -----------------------------------------------------------------------------
+//
+void CThumbnailStore::ResetThumbnailIDs()
+    {
+    TN_DEBUG1( "CThumbnailStore::ResetThumbnailIDs()" );
+
+    TInt err = iDatabase.Exec( KTempThumbnailResetIDs );
+    TN_DEBUG2( "CThumbnailStore::ResetThumbnailIDs() KThumbnailResetIDs - temp table, err=%d", err );
+    
+    err = iDatabase.Exec( KThumbnailResetIDs );
+    TN_DEBUG2( "CThumbnailStore::ResetThumbnailIDs() KThumbnailResetIDs - main table, err=%d", err );
+    }
+
+
+// -----------------------------------------------------------------------------
+// UpdateImeiL()
+// -----------------------------------------------------------------------------
+//
+void CThumbnailStore::UpdateImeiL()
+    {
+    TN_DEBUG1( "CThumbnailStore::UpdateImeiL()" );
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+         
+      
+    TInt ret = stmt.Prepare( iDatabase, KThumbnailUpdateIMEI );
+    
+    TInt paramIndex = stmt.ParameterIndex( KThumbnailSqlParamImei );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindText( paramIndex, iImei ));
+    
+    TInt err =  stmt.Exec();
+    
+    TN_DEBUG2( "CThumbnailStore::UpdateImeiL() err==%d", err );
+    
+    User::LeaveIfError( err );
+    
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt ); 
+    }
+
+// -----------------------------------------------------------------------------
+// StartAutoFlush()
+// -----------------------------------------------------------------------------
+//
+void CThumbnailStore::StartAutoFlush()
+    {
+    TN_DEBUG1( "CThumbnailStore::StartAutoFlush()" );
+    
+    TInt err = KErrNone;
+    
+    if( iAutoFlushTimer )
+        {
+        iAutoFlushTimer->Cancel();
+        }
+    else
+        {
+        TRAP(err, iAutoFlushTimer = CPeriodic::NewL(CActive::EPriorityIdle) );
+        }
+    
+    if (err != KErrNone)
+        {
+        TN_DEBUG2( "CThumbnailStore::StartAutoFlush() - Error creating timer (%d)", err );
+        }
+    else
+        {
+        iAutoFlushTimer->Start( KAutoFlushTimeout, KAutoFlushTimeout, 
+                                TCallBack(AutoFlushTimerCallBack, this));
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// StopAutoFlush()
+// -----------------------------------------------------------------------------
+//
+void CThumbnailStore::StopAutoFlush()
+    {
+    TN_DEBUG1( "CThumbnailStore::StopAutoFlush()" );
+    if( iAutoFlushTimer )
+        {
+        iAutoFlushTimer->Cancel();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CThumbnailStore::AutoFlushTimerCallBack()
+// ---------------------------------------------------------------------------
+//
+TInt CThumbnailStore::AutoFlushTimerCallBack(TAny* aAny)
+    {
+    TN_DEBUG1( "CThumbnailStore::AutoFlushTimerCallBack()");
+    CThumbnailStore* self = static_cast<CThumbnailStore*>( aAny );
+    
+    self->FlushCacheTable(ETrue);
+
+    return KErrNone; // Return value ignored by CPeriodic
+    }
+
+TInt CThumbnailStore::CheckRowIDsL()
+    {
+    TN_DEBUG1( "CThumbnailStore::CheckRowIDs()");
+    
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    TInt column = 0;   
+    TInt rowStatus = 0;
+    TInt64 inforows = 0;
+    TInt64 datarows = 0;
+    
+    TInt ret = stmt.Prepare( iDatabase, KGetInfoRowID );
+    if(ret < 0)
+        {
+        stmt.Close();
+        CleanupStack::PopAndDestroy( &stmt );
+        return KErrNotSupported;
+        }
+    rowStatus = stmt.Next();
+                
+    if ( rowStatus == KSqlAtRow)    
+        {        
+        inforows = stmt.ColumnInt64( column );  
+        }
+            
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+            
+    CleanupClosePushL( stmt );
+    ret = stmt.Prepare( iDatabase, KGetDataRowID );
+    if(ret < 0)
+        {
+        stmt.Close();
+        CleanupStack::PopAndDestroy( &stmt );
+        return KErrNotSupported;
+        }
+    rowStatus = stmt.Next();
+                       
+    if ( rowStatus == KSqlAtRow)    
+        {        
+        datarows = stmt.ColumnInt64( column );  
+        }
+            
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+            
+    if( inforows != datarows)
+        {
+        return KErrNotSupported;
+        }  
+    else
+        {
+        return KErrNone;
+        }
+    }
+
+void CThumbnailStore::CheckModifiedByIdL( TUint32 aId, TBool aTempTable,
+    TBool& aModified )
+    {
+    TN_DEBUG1( "CThumbnailStore::CheckModifiedByIdL()");
+    
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    TInt column( 0 );
+    
+    if( aTempTable )
+        {
+        User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectTempPathModifiedByID ) );
+        }
+    else
+        {
+        User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectPathModifiedByID ) );
+        }
+    TInt paramIndex = stmt.ParameterIndex( KThumbnailSqlParamId );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aId ));
+     
+    TInt rowStatus = stmt.Next();
+    
+    if(rowStatus == KSqlAtRow)
+        {
+        TPath path = stmt.ColumnTextL(column++);
+           
+        if (path.Length())
+            {
+            TInt64 modified = stmt.ColumnInt64( column );
+            TTime timeStamp;
+            iFs.Modified( path, timeStamp );
+            
+            if( modified != timeStamp.Int64() )
+                {
+                aModified = ETrue;
+                }
+            }
+        }
+    
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+    }
+
+void CThumbnailStore::CheckModifiedByPathL( const TDesC& aPath, TBool aTempTable,
+    TBool& aModified )
+    {
+    TN_DEBUG1( "CThumbnailStore::CheckModifiedByPathL()");
+    
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    TInt column( 0 );
+    
+    if( aTempTable )
+        {
+        User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectTempModifiedByPath ) );
+        }
+    else
+        {
+        User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailSelectModifiedByPath ) );
+        }
+    TInt paramIndex = stmt.ParameterIndex( KThumbnailSqlParamPath );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindText( paramIndex, aPath ));
+     
+    TInt rowStatus = stmt.Next();
+    
+    if(rowStatus == KSqlAtRow)
+        {
+        TInt64 modified = stmt.ColumnInt64( column );
+        TTime timeStamp;
+        iFs.Modified( aPath, timeStamp );
+        
+        if( modified != timeStamp.Int64() )
+            {
+            aModified = ETrue;
+            }
+        }
+    
+    stmt.Close();
+    CleanupStack::PopAndDestroy( &stmt );
+    }
+
+// -----------------------------------------------------------------------------
+// RemoveDbFlagL()
+// -----------------------------------------------------------------------------
+//
+void CThumbnailStore::RemoveDbFlagL(TThumbnailDbFlags aFlag)
+    {
+    TN_DEBUG1( "CThumbnailStore::RemoveBlacklistedFlag()" );
+    
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+
+    User::LeaveIfError( stmt.Prepare( iDatabase, KThumbnailRemoveBlacklistedFlag ));
+    
+    TInt paramIndex = stmt.ParameterIndex( KThumbnailSqlParamFlag );
+    User::LeaveIfError( paramIndex );
+    User::LeaveIfError( stmt.BindInt( paramIndex, aFlag ));
+
+    TInt err = stmt.Exec();
+   
+    TN_DEBUG2( "CThumbnailStore::RemoveBlacklistedFlag() - main table, err=%d", err );
+    
+    CleanupStack::PopAndDestroy( &stmt );
+    }
+
+// End of file