diff -r 000000000000 -r 2014ca87e772 imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailstore.cpp --- /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 +#include +#include +#include +#include +#include + +#include +#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 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( 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