mpserviceplugins/mpxsqlitedbcommon/src/mpxdbmanager.cpp
branchRCL_3
changeset 52 14979e23cb5e
equal deleted inserted replaced
50:26a1709b9fec 52:14979e23cb5e
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This class is responsible for managing all database access
       
    15 *                databases.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 
       
    22 #include <sqldb.h>
       
    23 #include <badesca.h>
       
    24 #include <f32file.h>
       
    25 // PREQ2536 the files sqlrowsetutil.h and sqlrowsetutil.cpp has been removed
       
    26 //#ifdef __WINSCW__    
       
    27 //#include <sqlrowsetutil.h>
       
    28 //#endif
       
    29 #include <sysutil.h>
       
    30 #ifdef __RAMDISK_PERF_ENABLE
       
    31 #include <centralrepository.h>
       
    32 #include <bautils.h>  
       
    33 #endif //__RAMDISK_PERF_ENABLE
       
    34 
       
    35 #include <mpxlog.h>
       
    36 
       
    37 #include "mpxdbcommondef.h"
       
    38 #include "mpxtable.h"
       
    39 #include "mpxdbmanager.h"
       
    40 
       
    41 // CONSTANTS
       
    42 
       
    43 // Version of   Database
       
    44 const   TInt KMPXDbVersion[] = {6,0,0};
       
    45 
       
    46 _LIT8( KMCSqlConfig, "cache_size=1024; page_size=16384; " );
       
    47 
       
    48 _LIT(KSecureFilePath,   "%S[%x]%S");
       
    49 _LIT(KRootDrive, "C:");
       
    50 _LIT(KAliasName, "%1SDrive");
       
    51 _LIT(KBeginTransaction, "BEGIN TRANSACTION");
       
    52 _LIT(KCommitTransaction, "COMMIT TRANSACTION");
       
    53 _LIT(KRollbackTransaction, "ROLLBACK TRANSACTION");
       
    54 _LIT(KOrderByToken, "ORDER BY");
       
    55 _LIT(KDBNameToken, ":dbname");
       
    56 _LIT(KPlDBNameToken, ":pldbname");
       
    57 _LIT(KUnionAllToken, " UNION ALL ");
       
    58 _LIT(KSelectToken, "SELECT");
       
    59 
       
    60 //for database deletion
       
    61 _LIT( KDBFilePath, "\\private\\10281e17\\" );
       
    62 _LIT( KDBFilePattern, "*.db*" );    
       
    63 
       
    64 #ifdef _DEBUG
       
    65 _LIT(KTableQuery, "SELECT * FROM %S");
       
    66 _LIT(KAttachedTableQuery, "SELECT * FROM :dbname.%S");
       
    67 _LIT(KFindAllCDriveTablesQuery, "SELECT name FROM   sqlite_master WHERE type = 'table' ORDER BY name");
       
    68 _LIT(KFindAllAttachedTablesQuery, "SELECT name FROM :dbname.sqlite_master WHERE type = 'table' ORDER BY name");
       
    69 _LIT(KNameColumn, "name");
       
    70 #endif
       
    71 
       
    72 const TInt KMaxLogQuery = 248;
       
    73 const TInt KBufIncrement = 10;
       
    74 
       
    75 #ifdef __RAMDISK_PERF_ENABLE
       
    76 _LIT(KSecurePath,   "[%x]%S");
       
    77 _LIT(KRAMAliasName, "%S");
       
    78 _LIT( KDummyDbFile, "%c:\\private\\10281e17\\dummydb.dat" );
       
    79 const TInt64 KMPMegaByte = 1048576;
       
    80 const TInt64 KMPEstimatedSongInBytes = KMPMegaByte * 2; 
       
    81 const TInt KMPEstimatedSizePerDBEntry = 3000; // worst scenario, can be lower if needed
       
    82 const TInt KMPMinimumRAMSizeToRun = 6 * KMPMegaByte; 
       
    83 // if RAM is lower than 5MB, doesn't seem enough for SQL as well.
       
    84 // so we set this number to move back DBs before being kicked out
       
    85 
       
    86 // Cenrep key defs -- Only temporary:  Need to find a better place for these
       
    87 const TUid KMPCenRepSettingsFeature               = { 0x10207C92 };
       
    88 const TUint32 KMPCenRepSettingRamdiskEnabled      = { 0x00000005 };
       
    89 const TUint32 KMPCenRepSettingRamdiskMaxDiskSpace = { 0x00000006 };
       
    90 
       
    91 #endif //__RAMDISK_PERF_ENABLE
       
    92 
       
    93 // Used to suppress overflow when appending formatted text to a buffer.
       
    94 class TOverflowHandle :
       
    95     public TDesOverflow
       
    96     {
       
    97     public:
       
    98         TOverflowHandle() :
       
    99             iFlag(EFalse)
       
   100             {
       
   101             }
       
   102 
       
   103         virtual void Overflow(TDes& /* aDes */)
       
   104             {
       
   105             iFlag = ETrue;
       
   106             return;
       
   107             }
       
   108 
       
   109         TBool GetOverflowFlag()
       
   110             {
       
   111             TBool flag(iFlag);
       
   112             iFlag = EFalse;
       
   113             return flag;
       
   114             }
       
   115     protected:
       
   116         TBool iFlag;
       
   117     };
       
   118 
       
   119 // ============================ MEMBER FUNCTIONS ==============================
       
   120 
       
   121 // ----------------------------------------------------------------------------
       
   122 // Constructor
       
   123 // ----------------------------------------------------------------------------
       
   124 //
       
   125 EXPORT_C CMPXDbManager::CMPXDbManager(
       
   126     RFs& aFs) :
       
   127     iFs(aFs), 
       
   128     iRAMDiskPerfEnabled(EFalse),
       
   129     iMaximumAllowedRAMDiskSpaceToCopy(0),
       
   130     iRAMInUse(EFalse)
       
   131     {
       
   132     MPX_FUNC("CMPXDbManager::CMPXDbManager");
       
   133     }
       
   134 
       
   135 // ----------------------------------------------------------------------------
       
   136 // Second phase constructor.
       
   137 // ----------------------------------------------------------------------------
       
   138 //
       
   139 EXPORT_C void CMPXDbManager::ConstructL(
       
   140     const TFileName& aDatabaseFile)
       
   141     {
       
   142     MPX_FUNC("CMPXDbManager::ConstructL");
       
   143     iDbFile = aDatabaseFile.AllocL();
       
   144     
       
   145 #ifdef __RAMDISK_PERF_ENABLE
       
   146     TInt temp;
       
   147     CRepository* repository = CRepository::NewLC( KMPCenRepSettingsFeature );
       
   148     User::LeaveIfError( repository->Get( KMPCenRepSettingRamdiskEnabled, temp ));
       
   149     iRAMDiskPerfEnabled = temp;
       
   150     
       
   151     User::LeaveIfError( repository->Get( KMPCenRepSettingRamdiskMaxDiskSpace, temp) );
       
   152     iMaximumAllowedRAMDiskSpaceToCopy = temp * KMPMegaByte;
       
   153     CleanupStack::PopAndDestroy(repository);
       
   154             
       
   155     if ( iRAMDiskPerfEnabled )
       
   156         {
       
   157         MPX_DEBUG1("CMPXDbManager::ConstructL RAMDisk performance is enabled.");
       
   158         MPX_DEBUG2("CMPXDbManager::ConstructL RAMDisk iMaximumAllowedRAMDiskSpaceToCopy=%Lu", iMaximumAllowedRAMDiskSpaceToCopy);
       
   159         if ( GetRAMDiskPath() != KErrNone )
       
   160             {
       
   161             // Error finding ram drive, disable ram disk
       
   162             iRAMDiskPerfEnabled = EFalse;
       
   163             }
       
   164         }
       
   165     else
       
   166         {
       
   167         MPX_DEBUG2("CMPXDbManager::ConstructL RAMDisk iRAMDiskPerfEnabled=%d", iRAMDiskPerfEnabled);
       
   168         MPX_DEBUG2("CMPXDbManager::ConstructL RAMDisk iMaximumAllowedRAMDiskSpaceToCopy=%Lu", iMaximumAllowedRAMDiskSpaceToCopy);
       
   169         }
       
   170 #endif //__RAMDISK_PERF_ENABLE
       
   171     }
       
   172 
       
   173 // ----------------------------------------------------------------------------
       
   174 // Destructor
       
   175 // ----------------------------------------------------------------------------
       
   176 //
       
   177 EXPORT_C CMPXDbManager::~CMPXDbManager()
       
   178     {
       
   179     MPX_FUNC("CMPXDbManager::~CMPXDbManager");
       
   180 
       
   181     // Close the state array
       
   182     iPreparedStatements.Close();
       
   183 
       
   184     // Close and destroy all RSQLStatements
       
   185     TInt c( iStatements.Count() );
       
   186     for( TInt i=0; i<c; ++i )
       
   187         {
       
   188         iStatements[i]->Close();
       
   189         }
       
   190     iStatements.ResetAndDestroy();
       
   191 
       
   192     iTables.Close();
       
   193     CloseAllDatabases();
       
   194 
       
   195     delete iDbFile;
       
   196     iDatabaseHandles.Close();
       
   197     }
       
   198 
       
   199 // ----------------------------------------------------------------------------
       
   200 // Checks if all databases have been initialized.
       
   201 // ----------------------------------------------------------------------------
       
   202 //
       
   203 EXPORT_C TBool CMPXDbManager::IsInitialized()
       
   204     {
       
   205     MPX_FUNC("CMPXDbManager::IsInitialized");
       
   206     return iInitialized;
       
   207     }
       
   208 
       
   209 // ----------------------------------------------------------------------------
       
   210 // Begins a transaction on all databases.
       
   211 // ----------------------------------------------------------------------------
       
   212 //
       
   213 EXPORT_C void CMPXDbManager::BeginL()
       
   214     {
       
   215     MPX_FUNC("CMPXDbManager::BeginL");
       
   216 
       
   217     ASSERT(iTransactionCount >= 0);
       
   218 
       
   219     if (++iTransactionCount == 1)
       
   220         {
       
   221         DoBeginL();
       
   222         }
       
   223     }
       
   224 
       
   225 void CMPXDbManager::DoBeginL()
       
   226     {
       
   227     MPX_FUNC("CMPXDbManager::DoBeginL");
       
   228 
       
   229     TInt err = iDatabase.Exec(KBeginTransaction);
       
   230         
       
   231     // transforms SQL error to KErrNotReady
       
   232     if( (err <= KSqlErrGeneral && err >= KSqlErrNotDb) || err == KSqlErrStmtExpired )
       
   233         {
       
   234         User::Leave(KErrNotReady);
       
   235         }
       
   236     else
       
   237         {
       
   238         User::LeaveIfError(err);
       
   239         }
       
   240     }
       
   241 
       
   242 // ----------------------------------------------------------------------------
       
   243 // Copy all DBs to RAM disk
       
   244 // ----------------------------------------------------------------------------
       
   245 //
       
   246 EXPORT_C void CMPXDbManager::CopyDBsToRamL( TBool aIsMTPInUse )
       
   247     {
       
   248 #ifdef __RAMDISK_PERF_ENABLE
       
   249     MPX_DEBUG1("-->CMPXDbManager::CopyDBsToRamL");
       
   250     if( iRAMDiskPerfEnabled )
       
   251         {
       
   252         if ( !IsRamDiskSpaceAvailable() )
       
   253             {
       
   254             return;
       
   255             }
       
   256         
       
   257         // Check if we are over the allowed ram space.
       
   258         TInt dbSize=0;
       
   259         TInt err = GetTotalDatabasesSize(dbSize);
       
   260         if ( err || (dbSize > iMaximumAllowedRAMDiskSpaceToCopy) )
       
   261             {
       
   262             MPX_DEBUG2("<--CMPXDbManager::CopyDBsToRamL Over the allowed Ram disk limit %Lu", iMaximumAllowedRAMDiskSpaceToCopy );
       
   263             return;
       
   264             }
       
   265         
       
   266         TInt transactionCount = iTransactionCount;
       
   267         if (iTransactionCount > 0) 
       
   268             {
       
   269             iTransactionCount = 0;
       
   270             DoCommitL();
       
   271             }
       
   272 
       
   273         TInt count(iDatabaseHandles.Count());
       
   274         for ( TInt i = 0; i < count ; ++i )
       
   275             {
       
   276             if ( ! iDatabaseHandles[i].iOpen )
       
   277                 {
       
   278                 MPX_DEBUG1("CMPXDbManager::CopyDBsToRamL DB not open (assuming drive is not present)");
       
   279                 continue;
       
   280                 }
       
   281             if ( iDatabaseHandles[i].iUseRAMdb )
       
   282                 {
       
   283                 // already used
       
   284                 MPX_DEBUG1("CMPXDbManager::CopyDBsToRamL iUseRAMdb already ETrue");
       
   285                 continue;
       
   286                 }
       
   287             CloseDatabaseAtIndexL( i ); // let leave: not much we can do if we can't close the original DB
       
   288             DoCopyDBToRam( i, aIsMTPInUse ); // copies if it can
       
   289             TRAPD( err, OpenDatabaseAtIndexL( i ) );
       
   290             if ( err != KErrNone )
       
   291                 {
       
   292                 MPX_DEBUG2("CMPXDbManager::CopyDBsToRamL OpenDatabaseAtIndexL leave=%d", err);
       
   293                 RemoveDummyFile(i);
       
   294                 if ( iDatabaseHandles[i].iUseRAMdb ) 
       
   295                     {
       
   296                     // go back to disk DB
       
   297                     TRAP_IGNORE(CloseDatabaseAtIndexL( i ));
       
   298                     iDatabaseHandles[i].iUseRAMdb = EFalse;
       
   299                     OpenDatabaseAtIndexL( i );
       
   300                     continue;
       
   301                     }
       
   302                 else
       
   303                     {
       
   304                     User::Leave( err );
       
   305                     }
       
   306                 }
       
   307             }
       
   308             
       
   309         if (transactionCount > 0) 
       
   310             {
       
   311             DoBeginL();
       
   312             iTransactionCount = transactionCount;
       
   313             }
       
   314         }
       
   315     iRAMInUse = ETrue;
       
   316 	
       
   317     MPX_DEBUG1("<--CMPXDbManager::CopyDBsToRamL");
       
   318 #endif //__RAMDISK_PERF_ENABLE
       
   319 
       
   320     }
       
   321 
       
   322 
       
   323 // ----------------------------------------------------------------------------
       
   324 // CMPXDbManager::DoCopyDBToRam
       
   325 // ----------------------------------------------------------------------------
       
   326 //
       
   327 TBool CMPXDbManager::DoCopyDBToRam( TInt aIndex, TBool aIsMTPInUse )
       
   328     {
       
   329 #ifdef __RAMDISK_PERF_ENABLE
       
   330     MPX_DEBUG2("-->CMPXDbManager::DoCopyDBsToRam drive=%d", (TInt)iDatabaseHandles[aIndex].iDrive);
       
   331     DatabaseHandle& database = iDatabaseHandles[aIndex];
       
   332     TInt err = KErrNone;
       
   333 
       
   334     delete database.iOrigFullFilePath;
       
   335     database.iOrigFullFilePath = 0;
       
   336     delete database.iTargetFullFilePath;
       
   337     database.iTargetFullFilePath = 0;
       
   338     TRAP (err, 
       
   339 	      database.iOrigFullFilePath = CreateFullFilenameL( database.iDrive );
       
   340           database.iUseRAMdb = ETrue; // must turn this on to create RAM filename
       
   341           database.iTargetFullFilePath = CreateFullFilenameL( database.iDrive );
       
   342           BaflUtils::EnsurePathExistsL( iFs, *database.iTargetFullFilePath ));
       
   343     database.iUseRAMdb = EFalse;
       
   344     if (err != KErrNone)
       
   345         {
       
   346         MPX_DEBUG1("CMPXDbManager::DoCopyDBsToRamL() CreateFilenameL or EnsurePathExistsL failed");
       
   347         return EFalse;
       
   348         }
       
   349     MPX_DEBUG2("RAMDisk src path=%S", database.iOrigFullFilePath);
       
   350     MPX_DEBUG2("RAMDisk dst path=%S", database.iTargetFullFilePath);
       
   351 
       
   352     if (!BlockDiskSpace( aIndex, aIsMTPInUse ) )
       
   353         {
       
   354         MPX_DEBUG1("CMPXDbManager::DoCopyDBsToRamL() BlockDiskSpace failed");
       
   355         return EFalse; // continue for next drive
       
   356         }
       
   357 
       
   358     if ( BaflUtils::CopyFile(iFs, *database.iOrigFullFilePath, *database.iTargetFullFilePath ) != KErrNone )
       
   359         {
       
   360         RemoveDummyFile( aIndex );
       
   361         return EFalse;
       
   362         }
       
   363     MPX_DEBUG2("RAMDisk Database copied=%d", (TInt)database.iDrive);
       
   364     database.iUseRAMdb = ETrue; // succeeded moving DB to RAM
       
   365     MPX_DEBUG1("<--CMPXDbManager::DoCopyDBsToRamL");
       
   366     return ETrue;
       
   367 #else
       
   368     return EFalse;
       
   369 #endif //__RAMDISK_PERF_ENABLE
       
   370     }
       
   371 
       
   372 // ----------------------------------------------------------------------------
       
   373 // Copy all DBs from RAM disk back to normal drives
       
   374 // ----------------------------------------------------------------------------
       
   375 //
       
   376 EXPORT_C void CMPXDbManager::CopyDBsFromRamL()
       
   377     {
       
   378     MPX_FUNC("CMPXDbManager::CopyDBsFromRamL");
       
   379 #ifdef __RAMDISK_PERF_ENABLE
       
   380     if( iRAMDiskPerfEnabled )
       
   381        {
       
   382         TInt transactionCount = iTransactionCount;
       
   383         if (iTransactionCount > 0) 
       
   384             {
       
   385             iTransactionCount = 0;
       
   386             TRAP_IGNORE( DoCommitL() );
       
   387             }
       
   388 
       
   389         TInt count(iDatabaseHandles.Count());
       
   390         TInt leaveError = KErrNone;
       
   391         iRAMInUse = EFalse;
       
   392         // Should not leave until all the databases have been copied from RAM drive. 
       
   393         for (TInt i = 0; i < count; ++i)
       
   394             {
       
   395             if ( !iDatabaseHandles[i].iUseRAMdb )
       
   396                 {
       
   397                 continue;
       
   398                 }
       
   399             TRAPD( error, CloseDatabaseAtIndexL( i ) );
       
   400             if ( error )
       
   401                 {
       
   402                 // Can't close db on RAM drive, so cleanup.
       
   403                 MPX_DEBUG2("CMPXDbManager::CopyDBsFromRamL CloseDatabaseAtIndexL fail: error = %d", error);
       
   404                 // Delete database on RAM drive.
       
   405                 BaflUtils::DeleteFile(iFs, *iDatabaseHandles[i].iTargetFullFilePath);
       
   406                 // Delete dummy file
       
   407                 RemoveDummyFile(i);
       
   408                 }
       
   409             else
       
   410                 {
       
   411                 DoCopyDBFromRam(i);
       
   412                 }
       
   413             iDatabaseHandles[i].iUseRAMdb = EFalse;
       
   414             // open db from drive
       
   415             TRAP( error, OpenDatabaseAtIndexL( i ) );      
       
   416             if ( error && !leaveError )
       
   417                 {
       
   418                 leaveError = error;
       
   419                 }
       
   420             }
       
   421         
       
   422         // leave if error
       
   423         User::LeaveIfError(leaveError);
       
   424 
       
   425         if (transactionCount > 0) 
       
   426             {
       
   427             DoBeginL();
       
   428             iTransactionCount = transactionCount;
       
   429             }
       
   430         }
       
   431 #endif //__RAMDISK_PERF_ENABLE
       
   432     }
       
   433 
       
   434 
       
   435 // ----------------------------------------------------------------------------
       
   436 // CMPXDbManager::DoCopyDBsToRam
       
   437 // ----------------------------------------------------------------------------
       
   438 //
       
   439 void CMPXDbManager::DoCopyDBFromRam( TInt aIndex )
       
   440     {
       
   441 #ifdef __RAMDISK_PERF_ENABLE
       
   442     MPX_DEBUG1("-->CMPXDbManager::DoCopyDBsFromRam");    
       
   443     DatabaseHandle& database = iDatabaseHandles[aIndex];
       
   444 
       
   445     //Copy Db from RAM to replace dummy file
       
   446     TRAPD(error, ReplaceFileL( *database.iTargetFullFilePath, database.iDummyFilePath));
       
   447     MPX_DEBUG2("CMPXDbManager::CopyDBsFromRam RAMDisk copied over dummy, error=%d", error);
       
   448 
       
   449     // done with RAM DB (whether copying succeeded or not) so can delete it
       
   450     // can ignore errors since we cannot do anything if this fails
       
   451     BaflUtils::DeleteFile(iFs, *database.iTargetFullFilePath);
       
   452     MPX_DEBUG1("CMPXDbManager::DoCopyDBsFromRam RAM DB deleted");
       
   453         
       
   454     if ( error == KErrNone )
       
   455         {
       
   456         // Delete old DB on drive
       
   457         // Can ignore error: either original does not exist or something is wrong and can't help it
       
   458         BaflUtils::DeleteFile(iFs, *database.iOrigFullFilePath);
       
   459         MPX_DEBUG1("CMPXDbManager::DoCopyDBsFromRam old DB on drive deleted");
       
   460 
       
   461         // Rename dummy file to be original file name
       
   462         error = BaflUtils::RenameFile(iFs, database.iDummyFilePath, *database.iOrigFullFilePath);
       
   463         MPX_DEBUG2("CMPXDbManager::CopyDBsFromRam dummy file renamed, error=%d", error);
       
   464         if ( error )
       
   465             {
       
   466             // Error renaming dummy file, delete dummy file.
       
   467             RemoveDummyFile(aIndex);
       
   468             }
       
   469         }
       
   470     else
       
   471         {
       
   472         RemoveDummyFile(aIndex);
       
   473         MPX_DEBUG1("CMPXDbManager::DoCopyDBsFromRam dummy file deleted");
       
   474         }
       
   475 
       
   476     MPX_DEBUG1("<--CMPXDbManager::DoCopyDBsFromRam");
       
   477 #endif //__RAMDISK_PERF_ENABLE
       
   478     } 
       
   479 
       
   480 // ----------------------------------------------------------------------------
       
   481 // CMPXDbManager::ReplaceFileL
       
   482 //
       
   483 // Replaces a file with another writing over the destination file.
       
   484 // Leaves on error.
       
   485 // Implementation follows CFileMan::Copy except that 
       
   486 //  - we don't resize target file to zero
       
   487 //  - we can assume that source file already exists
       
   488 //  - we don't copy file attributes & timestamp
       
   489 // ----------------------------------------------------------------------------
       
   490 //
       
   491 void CMPXDbManager::ReplaceFileL( const TDesC& aSrcName, const TDesC& aDstName )
       
   492     {
       
   493     // open files
       
   494     RFile srcFile;
       
   495     User::LeaveIfError( srcFile.Open(iFs, aSrcName, EFileRead|EFileShareReadersOnly) );
       
   496     CleanupClosePushL( srcFile );
       
   497     
       
   498     RFile dstFile;
       
   499 	TInt error = dstFile.Open(iFs, aDstName, EFileWrite|EFileWriteDirectIO|EFileShareExclusive);
       
   500 	if (error == KErrNotFound)
       
   501 	   {
       
   502 	   error = dstFile.Create(iFs, aDstName, EFileWrite|EFileWriteDirectIO|EFileShareExclusive);
       
   503 	   }
       
   504 	User::LeaveIfError ( error );
       
   505     CleanupClosePushL( dstFile );
       
   506     
       
   507     // resize destination file
       
   508     TInt remainingBytes = 0;
       
   509     User::LeaveIfError( srcFile.Size(remainingBytes) );
       
   510     User::LeaveIfError( dstFile.SetSize(remainingBytes) );
       
   511 
       
   512     // allocate buffer
       
   513    	const TInt KBigBufSize = 512 * 1024;
       
   514     const TInt KMediumBufSize = 32 * 1024;
       
   515     const TInt KSmallBufSize = 4 * 1024;
       
   516     HBufC8* bufPtr=HBufC8::New( Min(KBigBufSize, remainingBytes) );
       
   517     if (bufPtr==NULL)
       
   518         bufPtr=HBufC8::New(KMediumBufSize);
       
   519     if (bufPtr==NULL)
       
   520         bufPtr=HBufC8::New(KSmallBufSize);
       
   521     if (bufPtr == NULL)
       
   522         User::Leave(KErrNoMemory);
       
   523     CleanupStack::PushL(bufPtr);
       
   524 
       
   525     // copy
       
   526     TPtr8 copyBuf=bufPtr->Des();
       
   527     TInt pos=0;
       
   528     while( remainingBytes > 0 )
       
   529         {
       
   530         TInt s = Min( remainingBytes, copyBuf.MaxSize() );
       
   531         TInt ret = srcFile.Read(pos, copyBuf, s);
       
   532         if (ret == KErrNone && copyBuf.Length()!= s )
       
   533             {
       
   534             ret = KErrCorrupt;
       
   535             }
       
   536         if (ret == KErrNone)
       
   537             {
       
   538             ret = dstFile.Write(pos, copyBuf, s);
       
   539             }
       
   540         User::LeaveIfError (ret);
       
   541         pos += s;
       
   542         remainingBytes -= s;
       
   543         }
       
   544     User::LeaveIfError( dstFile.Flush() );
       
   545     CleanupStack::PopAndDestroy(3); // bufPtr, dstFile, srcFile
       
   546     }
       
   547 
       
   548 // ----------------------------------------------------------------------------
       
   549 // CMPXDbManager::RemoveDummyFile
       
   550 // ----------------------------------------------------------------------------
       
   551 //
       
   552 void CMPXDbManager::RemoveDummyFile( TInt index )
       
   553     {
       
   554 #ifdef __RAMDISK_PERF_ENABLE
       
   555     MPX_DEBUG1("-->CMPXDbManager::RemoveDummyFile");
       
   556        
       
   557     if ( iDatabaseHandles[index].iDummyFilePath.Length() )
       
   558         {
       
   559         BaflUtils::DeleteFile(iFs, iDatabaseHandles[index].iDummyFilePath);
       
   560         iDatabaseHandles[index].iDummyFilePath.Zero();
       
   561         }
       
   562     MPX_DEBUG1("<--CMPXDbManager::RemoveDummyFile");
       
   563 #endif //__RAMDISK_PERF_ENABLE
       
   564 
       
   565     }
       
   566 
       
   567 
       
   568 // ----------------------------------------------------------------------------
       
   569 // Commits a transaction on all databases.
       
   570 // ----------------------------------------------------------------------------
       
   571 //
       
   572 EXPORT_C void CMPXDbManager::CommitL()
       
   573     {
       
   574     MPX_FUNC("CMPXDbManager::CommitL");
       
   575 
       
   576     if(iTransactionCount > 0)
       
   577         {
       
   578         if (--iTransactionCount == 0)
       
   579             {
       
   580             DoCommitL();
       
   581             }
       
   582         }
       
   583     }
       
   584     
       
   585 // ----------------------------------------------------------------------------
       
   586 // Commits a transaction on all databases.
       
   587 // ----------------------------------------------------------------------------
       
   588 //
       
   589 void CMPXDbManager::DoCommitL()
       
   590     {
       
   591     MPX_FUNC("CMPXDbManager::DoCommitL");
       
   592     TInt err = iDatabase.Exec(KCommitTransaction);
       
   593     
       
   594     // transforms SQL error to KErrNotReady
       
   595     if( (err <= KSqlErrGeneral && err >= KSqlErrNotDb) || err == KSqlErrStmtExpired )
       
   596         {
       
   597         MPX_DEBUG2("CMPXDbManager::CommitL failed err=%d", err);
       
   598         User::Leave(KErrNotReady);
       
   599         }
       
   600     else
       
   601         {
       
   602         User::LeaveIfError(err);
       
   603         }
       
   604     }
       
   605 
       
   606 // ----------------------------------------------------------------------------
       
   607 // Rolls back a transaction on all databases.
       
   608 // ----------------------------------------------------------------------------
       
   609 //
       
   610 EXPORT_C void CMPXDbManager::RollbackL()
       
   611     {
       
   612     MPX_FUNC("CMPXDbManager::RollbackL");
       
   613 
       
   614     if(iTransactionCount > 0)
       
   615         {
       
   616         if (--iTransactionCount == 0)
       
   617             {
       
   618             TInt err = iDatabase.Exec(KRollbackTransaction);
       
   619             
       
   620             // transforms SQL error to KErrNotReady
       
   621             if( (err <= KSqlErrGeneral && err >= KSqlErrNotDb) || err == KSqlErrStmtExpired )
       
   622                 {
       
   623                 User::Leave(KErrNotReady);  
       
   624                 }
       
   625             else
       
   626                 {
       
   627                 User::LeaveIfError(err);
       
   628                 }
       
   629             }
       
   630     	}
       
   631     }
       
   632 
       
   633 // ----------------------------------------------------------------------------
       
   634 // Rolls back a transaction on all databases.
       
   635 // ----------------------------------------------------------------------------
       
   636 //
       
   637 EXPORT_C TBool CMPXDbManager::InTransaction()
       
   638     {
       
   639     MPX_FUNC("CMPXDbManager::InTransaction");
       
   640     return iDatabase.InTransaction();
       
   641     }
       
   642 
       
   643 // ----------------------------------------------------------------------------
       
   644 // Tries to create and open the databases on all specified drives.
       
   645 // ----------------------------------------------------------------------------
       
   646 //
       
   647 EXPORT_C void CMPXDbManager::InitDatabasesL(
       
   648     RArray<TInt> aDrives)
       
   649     {
       
   650     MPX_FUNC("CMPXDbManager::InitDatabasesL");
       
   651 
       
   652     CloseAllDatabases();
       
   653 
       
   654     TDriveUnit cdrive(KRootDrive());
       
   655 
       
   656     CreateDatabaseL(cdrive);
       
   657     OpenRootDatabaseL();
       
   658 
       
   659     TInt count(aDrives.Count());
       
   660     for (TInt i = 0; i < count; ++i)
       
   661         {
       
   662         TDriveUnit drive(aDrives[i]);
       
   663         if ((drive != cdrive) && !IsRemoteDrive(static_cast<TDriveNumber>(aDrives[i])))
       
   664             {
       
   665             const TDesC& driveName = drive.Name();
       
   666 
       
   667             DatabaseHandle handle;
       
   668 
       
   669             handle.iDrive = aDrives[i];
       
   670             handle.iAliasname = HBufC::NewL(KAliasName().Length());
       
   671             handle.iAliasname->Des().Format(KAliasName, &driveName);
       
   672             handle.iOpen = EFalse;
       
   673 #ifdef __RAMDISK_PERF_ENABLE
       
   674             handle.iOrigFullFilePath = HBufC::NewL(0);
       
   675             handle.iTargetFullFilePath = HBufC::NewL(0);
       
   676             handle.iDummyFilePath.Zero();
       
   677             handle.iUseRAMdb = EFalse;
       
   678 #endif //__RAMDISK_PERF_ENABLE
       
   679 
       
   680             TInt index = iDatabaseHandles.Count();
       
   681             iDatabaseHandles.AppendL(handle);
       
   682 
       
   683             TVolumeInfo vol;
       
   684             if (iFs.Volume(vol, drive) == KErrNone)
       
   685                 {
       
   686                 CreateDatabaseL(drive);
       
   687                 AttachDatabaseL( index );
       
   688                 }
       
   689             }
       
   690         }
       
   691 
       
   692     iInitialized = ETrue;
       
   693     }
       
   694 
       
   695 // ----------------------------------------------------------------------------
       
   696 // Opens a specified database.
       
   697 // ----------------------------------------------------------------------------
       
   698 //
       
   699 EXPORT_C void CMPXDbManager::OpenDatabaseL(
       
   700     TInt aDrive)
       
   701     {
       
   702     MPX_FUNC("CMPXDbManager::OpenDatabaseL");
       
   703 
       
   704     if (iInitialized == EFalse)
       
   705         {
       
   706         User::Leave(KErrNotReady);
       
   707         }
       
   708 
       
   709     TDriveUnit drive(aDrive);
       
   710     TDriveUnit cdrive(KRootDrive());
       
   711     TBool found(EFalse);
       
   712 
       
   713     if ((drive != cdrive) && !IsRemoteDrive(static_cast<TDriveNumber>(aDrive)))
       
   714         {
       
   715         TInt count(iDatabaseHandles.Count());
       
   716         for (TInt i = 0; i < count; ++i)
       
   717             {
       
   718             if (iDatabaseHandles[i].iDrive == aDrive)
       
   719                 {
       
   720                 MPX_DEBUG2("CMPXDbManager::OpenDatabaseL found %d", aDrive);
       
   721                 TInt transactionCount = iTransactionCount;
       
   722                 if (iTransactionCount > 0) 
       
   723                     {
       
   724                     iTransactionCount = 0;
       
   725                     DoCommitL();
       
   726                     }
       
   727                 OpenDatabaseAtIndexL( i );
       
   728                 if (transactionCount > 0) 
       
   729                     {
       
   730                     DoBeginL();
       
   731                     iTransactionCount = transactionCount;
       
   732                     }
       
   733                 found = ETrue;
       
   734                 break;
       
   735                 }
       
   736             }
       
   737         }
       
   738     if (!found)
       
   739         {
       
   740         MPX_DEBUG1("CMPXDbManager::OpenDatabaseL not found");
       
   741         User::Leave(KErrArgument);
       
   742         }
       
   743 
       
   744     // Close all prepared statements if a db is opened
       
   745     //
       
   746     ResetPreparedQueries();
       
   747     }
       
   748     
       
   749 void CMPXDbManager::OpenDatabaseAtIndexL( TInt aIndex )
       
   750     {
       
   751     	  DatabaseHandle & database = iDatabaseHandles[aIndex];
       
   752         if (!database.iOpen)
       
   753             {
       
   754             MPX_DEBUG1("CMPXDbManager::OpenDatabaseAtIndexL not open");
       
   755             // make sure the database is created
       
   756             CreateDatabaseL( TDriveUnit(database.iDrive) );
       
   757             AttachDatabaseL( aIndex );
       
   758             }
       
   759     }
       
   760 
       
   761 // ----------------------------------------------------------------------------
       
   762 // Closes a specified database.
       
   763 // ----------------------------------------------------------------------------
       
   764 //
       
   765 EXPORT_C void CMPXDbManager::CloseDatabaseL(
       
   766     TInt aDrive)
       
   767     {
       
   768     MPX_FUNC("CMPXDbManager::CloseDatabaseL");
       
   769 
       
   770     if (iInitialized == EFalse)
       
   771         {
       
   772         User::Leave(KErrNotReady);
       
   773         }
       
   774     
       
   775     TDriveUnit drive(aDrive);
       
   776     TDriveUnit cdrive(KRootDrive());
       
   777     TBool found(EFalse);
       
   778 
       
   779     if ((drive != cdrive) && !IsRemoteDrive(static_cast<TDriveNumber>(aDrive)))
       
   780         {
       
   781         TInt count(iDatabaseHandles.Count());
       
   782         for (TInt i = 0; i < count; ++i)
       
   783             {
       
   784             if (iDatabaseHandles[i].iDrive == aDrive)
       
   785                 {
       
   786                 TBool inTransaction = InTransaction();
       
   787                 TInt transactionCount = iTransactionCount;
       
   788                 iTransactionCount = 0;								
       
   789 								
       
   790                 if (inTransaction) //if the transaction is ongoing, try committing
       
   791                     {
       
   792                     //if transaction committing fails, try roll-back	
       
   793                     TInt error = iDatabase.Exec( KCommitTransaction );
       
   794                     if ( error != KErrNone )
       
   795                         {
       
   796                         //The error is ignored since we can't do nothing about it
       
   797                         iDatabase.Exec( KRollbackTransaction ); 
       
   798                         }
       
   799                     }
       
   800                 	
       
   801 #ifdef __RAMDISK_PERF_ENABLE                	
       
   802                 if ( iRAMDiskPerfEnabled && iDatabaseHandles[i].iUseRAMdb )
       
   803             	      {
       
   804                     MPX_DEBUG2("CMPXDbManager::CloseDatabaseL found %d at RAM", aDrive);
       
   805                     TRAPD( err, CloseDatabaseAtIndexL( i ) );
       
   806                     if ( err != KErrNone )
       
   807                         {
       
   808                         // Can't close db on RAM drive, so cleanup.
       
   809                         MPX_DEBUG2("CMPXDbManager::CloseDatabaseL CloseDatabaseAtIndexL fail: error = %d", err);
       
   810                         // Delete dummy file
       
   811                         RemoveDummyFile(i);
       
   812                         iDatabaseHandles[i].iUseRAMdb = EFalse;
       
   813                         // Delete database on RAM drive.
       
   814                         User::LeaveIfError( BaflUtils::DeleteFile(iFs, *iDatabaseHandles[i].iTargetFullFilePath) );
       
   815                         }
       
   816                     else
       
   817                         {
       
   818                         DoCopyDBFromRam(i);
       
   819                         }
       
   820                     iDatabaseHandles[i].iUseRAMdb = EFalse;
       
   821                     }
       
   822                 else
       
   823 #endif
       
   824                     {
       
   825                     MPX_DEBUG2("CMPXDbManager::CloseDatabaseL found %d", aDrive);
       
   826                     CloseDatabaseAtIndexL( i );
       
   827                     }
       
   828                 
       
   829                 //Let MTP handle the transcation if there is any 
       
   830                 if ( inTransaction ) 
       
   831                     {
       
   832                     DoBeginL();
       
   833                     iTransactionCount = transactionCount;
       
   834                     }
       
   835 
       
   836                 found = ETrue;
       
   837                 break;
       
   838                 }
       
   839             }
       
   840         }
       
   841     if (!found)
       
   842         {
       
   843         MPX_DEBUG1("CMPXDbManager::CloseDatabaseL not found");
       
   844         User::Leave(KErrArgument);
       
   845         }
       
   846 
       
   847     }
       
   848 
       
   849 void CMPXDbManager::CloseDatabaseAtIndexL( TInt aIndex )
       
   850     {
       
   851     // Close all prepared statements if a db is closed
       
   852     //
       
   853     ResetPreparedQueries();
       
   854 
       
   855     if (iDatabaseHandles[aIndex].iOpen)
       
   856         {
       
   857         MPX_DEBUG1("CMPXDbManager::CloseDatabaseAtIndexL found open");
       
   858         DetachDatabaseL( aIndex );
       
   859         }
       
   860 }
       
   861 
       
   862 // ----------------------------------------------------------------------------
       
   863 // Closes all databases.
       
   864 // ----------------------------------------------------------------------------
       
   865 //
       
   866 EXPORT_C void CMPXDbManager::CloseAllDatabases()
       
   867     {
       
   868     MPX_FUNC("CMPXDbManager::CloseAllDatabases");
       
   869 
       
   870     // Close all prepared statements if a db is closed
       
   871     //
       
   872     ResetPreparedQueries();
       
   873 
       
   874     TInt count(iDatabaseHandles.Count());
       
   875     for (TInt i = 0; i < count; ++i)
       
   876         {
       
   877         delete iDatabaseHandles[i].iAliasname;
       
   878         iDatabaseHandles[i].iAliasname = 0;
       
   879 #ifdef __RAMDISK_PERF_ENABLE 
       
   880         RemoveDummyFile(i);            	
       
   881         delete iDatabaseHandles[i].iOrigFullFilePath;
       
   882         iDatabaseHandles[i].iOrigFullFilePath = 0;
       
   883         delete iDatabaseHandles[i].iTargetFullFilePath;
       
   884         iDatabaseHandles[i].iTargetFullFilePath = 0;
       
   885 #endif //__RAMDISK_PERF_ENABLE 
       
   886         }
       
   887 
       
   888     iDatabaseHandles.Reset();
       
   889     iDatabase.Close();
       
   890     iInitialized = EFalse;
       
   891     }
       
   892 
       
   893 // ----------------------------------------------------------------------------
       
   894 // Open all databases.
       
   895 // ----------------------------------------------------------------------------
       
   896 //
       
   897 EXPORT_C void CMPXDbManager::OpenAllDatabasesL()
       
   898     {
       
   899     MPX_FUNC("CMPXDbManager::OpenAllDatabasesL");
       
   900 
       
   901     if (!iInitialized)
       
   902         {
       
   903         OpenRootDatabaseL();
       
   904         }
       
   905 
       
   906     TInt count(iDatabaseHandles.Count());
       
   907     for (TInt i = 0; i < count; ++i)
       
   908         {
       
   909         TVolumeInfo vol;
       
   910         if (iFs.Volume(vol, iDatabaseHandles[i].iDrive) == KErrNone)
       
   911             {
       
   912             AttachDatabaseL( i );
       
   913             }
       
   914         }
       
   915     iInitialized = ETrue;
       
   916 
       
   917     // Close all prepared statements if a db is closed
       
   918     //
       
   919     ResetPreparedQueries();
       
   920     }
       
   921 
       
   922 // ----------------------------------------------------------------------------
       
   923 // Checks if the database on a specified drive is open.
       
   924 // ----------------------------------------------------------------------------
       
   925 //
       
   926 EXPORT_C TBool CMPXDbManager::IsOpen(
       
   927     TInt aDrive) const
       
   928     {
       
   929     MPX_FUNC("CMPXDbManager::IsOpen");
       
   930 
       
   931     TDriveUnit drive(aDrive);
       
   932     TDriveUnit cdrive(KRootDrive());
       
   933 
       
   934     if (!iInitialized)
       
   935         {
       
   936         return EFalse;
       
   937         }
       
   938     else if (drive == cdrive)
       
   939         {
       
   940         return ETrue;
       
   941         }
       
   942     else
       
   943         {
       
   944         TInt count(iDatabaseHandles.Count());
       
   945         for (TInt i = 0; i < count; ++i)
       
   946             {
       
   947             if (iDatabaseHandles[i].iDrive == aDrive)
       
   948                 {
       
   949                 return iDatabaseHandles[i].iOpen;
       
   950                 }
       
   951             }
       
   952         }
       
   953 
       
   954     return EFalse;
       
   955     }
       
   956 
       
   957 // ----------------------------------------------------------------------------
       
   958 // Returns the number of currently open databases.
       
   959 // ----------------------------------------------------------------------------
       
   960 //
       
   961 EXPORT_C TInt CMPXDbManager::DatabaseCount() const
       
   962     {
       
   963     MPX_FUNC("CMPXDbManager::DatabaseCount");
       
   964 
       
   965     TInt openCount(0);
       
   966     if (iInitialized)
       
   967         {
       
   968         ++openCount;
       
   969 
       
   970         TInt count(iDatabaseHandles.Count());
       
   971         for (TInt i = 0; i < count; ++i)
       
   972             {
       
   973             if (iDatabaseHandles[i].iOpen)
       
   974                 {
       
   975                 ++openCount;
       
   976                 }
       
   977             }
       
   978         }
       
   979 
       
   980     return openCount;
       
   981     }
       
   982 
       
   983 // ----------------------------------------------------------------------------
       
   984 // Returns the drive corresponding to a given index.
       
   985 // ----------------------------------------------------------------------------
       
   986 //
       
   987 EXPORT_C TInt CMPXDbManager::DbDrive(
       
   988     TInt aIndex) const
       
   989     {
       
   990     MPX_FUNC("CMPXDbManager::DbDrive");
       
   991 
       
   992     ASSERT((aIndex >= 0) || (aIndex < iDatabaseHandles.Count()));
       
   993     return iDatabaseHandles[aIndex].iDrive;
       
   994     }
       
   995 
       
   996 // ----------------------------------------------------------------------------
       
   997 // Recreate a specified database.
       
   998 // ----------------------------------------------------------------------------
       
   999 //
       
  1000 EXPORT_C void CMPXDbManager::RecreateDatabaseL(
       
  1001     TInt aDrive)
       
  1002     {
       
  1003     MPX_FUNC("CMPXDbManager::RecreateDatabaseL");
       
  1004 
       
  1005     if (iInitialized == EFalse)
       
  1006         {
       
  1007         User::Leave(KErrNotReady);
       
  1008         }
       
  1009 
       
  1010     TInt index = KErrNotFound;
       
  1011 
       
  1012     if (aDrive == EDriveC)
       
  1013         {
       
  1014         index = iDatabaseHandles.Count();
       
  1015         }
       
  1016     else
       
  1017         {
       
  1018         TInt count(iDatabaseHandles.Count());
       
  1019         for (TInt i = 0; i < count; ++i)
       
  1020             {
       
  1021             if ((iDatabaseHandles[i].iDrive == aDrive) && (iDatabaseHandles[i].iOpen))
       
  1022                 {
       
  1023                 index = i;
       
  1024                 break;
       
  1025                 }
       
  1026             }
       
  1027         }
       
  1028     if ( index >= 0 )
       
  1029         {
       
  1030         HBufC * filename = CreateFilenameL(aDrive);
       
  1031         CleanupStack::PushL(filename);
       
  1032 
       
  1033         TRAPD(err, DoRecreateDatabaseL(filename));
       
  1034         if(err < 0)
       
  1035             {
       
  1036             TDriveUnit drive_unit(aDrive);
       
  1037 
       
  1038             if(aDrive == EDriveC)
       
  1039                 {
       
  1040                 iDatabase.Close();
       
  1041                 iInitialized = EFalse;
       
  1042 
       
  1043                 RSqlDatabase::Delete(*filename);
       
  1044                 CreateDatabaseL(drive_unit);
       
  1045 
       
  1046                 User::LeaveIfError(iDatabase.Open(*filename));
       
  1047                 iInitialized = ETrue;
       
  1048                 }
       
  1049             else
       
  1050                 {
       
  1051                 DetachDatabaseL( index );
       
  1052 
       
  1053                 RSqlDatabase::Delete(*filename);
       
  1054                 CreateDatabaseL(drive_unit);
       
  1055 
       
  1056                 AttachDatabaseL( index );
       
  1057                 }
       
  1058             }
       
  1059 
       
  1060         CleanupStack::PopAndDestroy(filename);
       
  1061         }
       
  1062     else
       
  1063         {
       
  1064         User::Leave(KErrNotFound);
       
  1065         }
       
  1066     }
       
  1067 
       
  1068 // ----------------------------------------------------------------------------
       
  1069 // Recreate all databases.
       
  1070 // ----------------------------------------------------------------------------
       
  1071 //
       
  1072 EXPORT_C void CMPXDbManager::RecreateAllDatabasesL()
       
  1073     {
       
  1074     MPX_FUNC("CMPXDbManager::RecreateAllDatabasesL");
       
  1075 
       
  1076     if (iInitialized == EFalse)
       
  1077         {
       
  1078         User::Leave(KErrNotReady);
       
  1079         }
       
  1080 
       
  1081     // Recreate on drive C
       
  1082     RecreateDatabaseL(EDriveC);
       
  1083 
       
  1084     // Recreate all attached drives
       
  1085     TInt count(iDatabaseHandles.Count());
       
  1086     for (TInt i = 0; i < count; ++i)
       
  1087         {
       
  1088         if (iDatabaseHandles[i].iOpen)
       
  1089             {
       
  1090             RecreateDatabaseL(iDatabaseHandles[i].iDrive);
       
  1091             }
       
  1092         }
       
  1093     }
       
  1094 
       
  1095 // ----------------------------------------------------------------------------
       
  1096 // Returns current DB version
       
  1097 // ----------------------------------------------------------------------------
       
  1098 //
       
  1099 EXPORT_C TVersion CMPXDbManager::Version() const
       
  1100     {
       
  1101     MPX_FUNC("CMPXDbManager::Version");
       
  1102     return TVersion(KMPXDbVersion[0], KMPXDbVersion[1], KMPXDbVersion[2]);
       
  1103     }
       
  1104 
       
  1105 // ----------------------------------------------------------------------------
       
  1106 // Registes a table with the database
       
  1107 // ----------------------------------------------------------------------------
       
  1108 //
       
  1109 EXPORT_C void CMPXDbManager::RegisterTableL(
       
  1110     MMPXTable& aTable)
       
  1111     {
       
  1112     MPX_FUNC("CMPXDbManager::RegisterTableL");
       
  1113     iTables.AppendL(&aTable);
       
  1114     }
       
  1115 
       
  1116 // ----------------------------------------------------------------------------
       
  1117 // Executes a select query with variable number of parameters
       
  1118 // The query is executed on all available databases with a format like:
       
  1119 //
       
  1120 //      <query on database1> UNION ALL <query on database2> ...
       
  1121 //
       
  1122 // The query string passed in by the caller must have the ":dbname" prefix for all
       
  1123 // the tables in the FROM clause. This will be replaced with the right alias for
       
  1124 // attached databases or with no alias for the C database.
       
  1125 //
       
  1126 // In case the original query contains an ORDER BY clause, this will be extracted
       
  1127 // and added at the end of the union query.
       
  1128 //
       
  1129 // Note: Running the union query seems to be similar in speed even if one of the
       
  1130 // databases is empty and therefore no optimization was done for this case.
       
  1131 // ----------------------------------------------------------------------------
       
  1132 //
       
  1133 EXPORT_C RSqlStatement CMPXDbManager::ExecuteSelectQueryL(
       
  1134     TRefByValue<const TDesC> aFmt,
       
  1135     ...)
       
  1136     {
       
  1137     MPX_FUNC("CMPXDatabase::ExecuteSelectQueryL");
       
  1138 
       
  1139     VA_LIST list;
       
  1140     VA_START(list, aFmt);
       
  1141 
       
  1142     // Will reallocate
       
  1143     HBufC* selectBuf = FormatQueryLC(aFmt, list);
       
  1144     RSqlStatement statement = ExecuteSelectQueryOnAllDrivesL(selectBuf->Des());
       
  1145     CleanupStack::PopAndDestroy(selectBuf);
       
  1146 
       
  1147     VA_END(list);
       
  1148 
       
  1149     return statement;
       
  1150     }
       
  1151 
       
  1152 // ----------------------------------------------------------------------------
       
  1153 // Executes a select query against a specified drive
       
  1154 // ----------------------------------------------------------------------------
       
  1155 //
       
  1156 EXPORT_C RSqlStatement CMPXDbManager::ExecuteSelectQueryL(
       
  1157     TInt aDrive,
       
  1158     TRefByValue<const TDesC> aFmt,
       
  1159     ...)
       
  1160     {
       
  1161     MPX_FUNC("CMPXDatabase::ExecuteSelectQueryL");
       
  1162 
       
  1163     VA_LIST list;
       
  1164     VA_START(list, aFmt);
       
  1165 
       
  1166     // Will reallocate
       
  1167     HBufC* selectBuf = FormatQueryLC(aFmt, list);
       
  1168     RSqlStatement statement = ExecuteSelectQueryOnDriveL(aDrive, selectBuf->Des());
       
  1169     CleanupStack::PopAndDestroy(selectBuf);
       
  1170 
       
  1171     VA_END(list);
       
  1172 
       
  1173     return statement;
       
  1174     }
       
  1175 
       
  1176 // ----------------------------------------------------------------------------
       
  1177 // CMPXDbManager::ExecuteSelectQueryL
       
  1178 // ----------------------------------------------------------------------------
       
  1179 //
       
  1180 EXPORT_C RSqlStatement& CMPXDbManager::ExecuteSelectQueryL(
       
  1181     TUint aStatementId,
       
  1182     TInt aFirstValue,
       
  1183     TInt aSecondValue,
       
  1184     TRefByValue<const TDesC> aFmt,
       
  1185     ...)
       
  1186     {
       
  1187     MPX_FUNC("CMPXDatabase::ExecuteOffsetSelectQueryL");
       
  1188 
       
  1189     // Prepare the Query first
       
  1190     VA_LIST list;
       
  1191     VA_START(list, aFmt);
       
  1192     RSqlStatement& statement = PrepareQueryL( aStatementId, aFmt, list );
       
  1193     VA_END(list);
       
  1194 
       
  1195     // Bind the Limit and Offset variables
       
  1196     User::LeaveIfError(statement.BindInt(0, aFirstValue));
       
  1197     User::LeaveIfError(statement.BindInt(1, aSecondValue));
       
  1198 
       
  1199     return statement;
       
  1200     }
       
  1201 
       
  1202 // ----------------------------------------------------------------------------
       
  1203 // CMPXDbManager::ExecuteSelectQueryL
       
  1204 // ----------------------------------------------------------------------------
       
  1205 //
       
  1206 EXPORT_C RSqlStatement& CMPXDbManager::ExecuteSelectQueryL( TUint aStatementId,
       
  1207                                                             const TDesC& aFirstValue,
       
  1208                                                             TInt aSecondValue,
       
  1209                                                             TRefByValue<const TDesC> aFmt, ...)
       
  1210     {
       
  1211     MPX_FUNC("CMPXDbManager::ExecuteMediaAscQueryL");
       
  1212 
       
  1213     // Prepare the Query first
       
  1214     VA_LIST list;
       
  1215     VA_START(list, aFmt);
       
  1216     RSqlStatement& statement = PrepareQueryL( aStatementId, aFmt, list );
       
  1217     VA_END(list);
       
  1218 
       
  1219     // bind the title and limit values
       
  1220     User::LeaveIfError(statement.BindText(0, aFirstValue));
       
  1221     User::LeaveIfError(statement.BindInt(1, aSecondValue));
       
  1222 
       
  1223     return statement;
       
  1224     }
       
  1225 
       
  1226 // ----------------------------------------------------------------------------
       
  1227 // Executes a query that does not return a record set (INSERT, UPDATE, DELETE,
       
  1228 // CREATE, DROP, etc).
       
  1229 //
       
  1230 // If a valid drive is specified then the query is only executed only on
       
  1231 // that drive. If KDbManagerAllDrives is specified then the query is executed
       
  1232 // separately on each available drive.
       
  1233 // ----------------------------------------------------------------------------
       
  1234 //
       
  1235 EXPORT_C void CMPXDbManager::ExecuteQueryL(
       
  1236     TInt aDrive,
       
  1237     TRefByValue<const TDesC> aFmt,
       
  1238     ...)
       
  1239     {
       
  1240     MPX_FUNC("CMPXDatabase::ExecuteQueryL");
       
  1241 
       
  1242     // make sure there is enough space on all drives affected
       
  1243     CheckDiskSpaceL(aDrive);
       
  1244 
       
  1245     VA_LIST list;
       
  1246     VA_START(list, aFmt);
       
  1247 
       
  1248     HBufC* selectBuf = FormatQueryLC(aFmt, list);
       
  1249     TPtr selectBufPtr = selectBuf->Des();
       
  1250     TInt dbCount(iDatabaseHandles.Count());
       
  1251 
       
  1252     // a specified drive or all drives
       
  1253     TInt loopCount = (aDrive == KDbManagerAllDrives) ? (dbCount + 1) : 1;
       
  1254     TBool queryExecuted(EFalse); // flag to check if the query was executed at least once
       
  1255     for (TInt j = 0; j < loopCount; ++j)
       
  1256         {
       
  1257         HBufC* query = HBufC::NewLC(selectBufPtr.Length() + KBufIncrement);
       
  1258         TPtr queryPtr = query->Des();
       
  1259         queryPtr.Copy(selectBufPtr);
       
  1260         if (aDrive == EDriveC) // if C drive only
       
  1261             {
       
  1262             RemoveDriveAlias(queryPtr);
       
  1263             }
       
  1264         else // all drives or a particular drive other than C drive
       
  1265             {
       
  1266             if (aDrive == 0) // all drives
       
  1267                 {
       
  1268                 if (j == dbCount) // C drive
       
  1269                     {
       
  1270                     RemoveDriveAlias(queryPtr);
       
  1271                     }
       
  1272                 else //all other drives, except C drive
       
  1273                     {
       
  1274                     if (iDatabaseHandles[j].iOpen)
       
  1275                         {
       
  1276                         ReplaceDriveAlias(queryPtr, *(iDatabaseHandles[j].iAliasname));
       
  1277                         }
       
  1278                     }
       
  1279                 }
       
  1280             else //a particular drive, other than C drive
       
  1281                 {
       
  1282                 for (TInt i = 0; i < dbCount; ++i)
       
  1283                     {
       
  1284                     if (iDatabaseHandles[i].iOpen && iDatabaseHandles[i].iDrive == aDrive)
       
  1285                         {
       
  1286                         ReplaceDriveAlias(queryPtr, *(iDatabaseHandles[i].iAliasname));
       
  1287                         break;
       
  1288                         }
       
  1289                     }
       
  1290                 }
       
  1291             }
       
  1292         TInt dbnamePos = queryPtr.Find(KDBNameToken);// check if the query was created correctly
       
  1293         if (dbnamePos == KErrNotFound)
       
  1294             {
       
  1295             // log the query
       
  1296             TPtrC ptr(query->Left(KMaxLogQuery));
       
  1297             MPX_DEBUG2("Query: %S", &ptr);
       
  1298 
       
  1299             User::LeaveIfError(ExecuteSqlStatement(iDatabase, queryPtr));
       
  1300             queryExecuted = ETrue;
       
  1301             }
       
  1302         CleanupStack::PopAndDestroy(query);
       
  1303         }   //for (TInt j = 0; j < loopCount; ++j)
       
  1304     CleanupStack::PopAndDestroy(selectBuf);
       
  1305     VA_END(list);
       
  1306     if (!queryExecuted && aDrive !=   0)
       
  1307         {
       
  1308         // the requested drive(s) is not open
       
  1309         User::Leave(KErrNotFound);
       
  1310         }
       
  1311     }
       
  1312 
       
  1313 // ----------------------------------------------------------------------------
       
  1314 // CMPXDbManager::FormatQueryLC
       
  1315 // ----------------------------------------------------------------------------
       
  1316 //
       
  1317 HBufC* CMPXDbManager::FormatQueryLC(
       
  1318     TRefByValue<const TDesC> aFmt,
       
  1319     VA_LIST aList)
       
  1320     {
       
  1321     MPX_FUNC("CMPXDatabase::FormatQueryLC");
       
  1322 
       
  1323     TOverflowHandle overflow;
       
  1324 
       
  1325     HBufC* selectBuf = HBufC::NewLC(TDesC(aFmt).Length());//will reallocate
       
  1326     selectBuf->Des().AppendFormatList(aFmt, aList, &overflow);
       
  1327     while (overflow.GetOverflowFlag())
       
  1328         {
       
  1329         TInt len = selectBuf->Des().MaxLength() + KBufIncrement;
       
  1330         CleanupStack::PopAndDestroy(selectBuf);
       
  1331         selectBuf = HBufC::NewLC(len);
       
  1332         selectBuf->Des().AppendFormatList(aFmt, aList, &overflow);
       
  1333         }
       
  1334 
       
  1335     return selectBuf;
       
  1336     }
       
  1337 
       
  1338 // ----------------------------------------------------------------------------
       
  1339 // Executes a select query against a specified drive
       
  1340 // ----------------------------------------------------------------------------
       
  1341 //
       
  1342 EXPORT_C RSqlStatement CMPXDbManager::ExecuteSelectQueryOnAllDrivesL(
       
  1343     TInt aDrive,
       
  1344     TRefByValue<const TDesC> aFmt,
       
  1345     ...)
       
  1346     {
       
  1347     MPX_FUNC("CMPXDatabase::ExecuteSelectQueryL");
       
  1348 
       
  1349     VA_LIST list;
       
  1350     VA_START(list, aFmt);
       
  1351 
       
  1352     // Will reallocate
       
  1353     HBufC* selectBuf = FormatQueryLC(aFmt, list);
       
  1354     RSqlStatement statement = ExecuteSelectQueryOnAllDrivesL(aDrive, selectBuf->Des());
       
  1355     CleanupStack::PopAndDestroy(selectBuf);
       
  1356 
       
  1357     VA_END(list);
       
  1358 
       
  1359     return statement;
       
  1360     }
       
  1361 
       
  1362 // ----------------------------------------------------------------------------
       
  1363 // CMPXDbManager::ExecuteSelectQueryOnAllDrivesL
       
  1364 // ----------------------------------------------------------------------------
       
  1365 //
       
  1366 RSqlStatement CMPXDbManager::ExecuteSelectQueryOnAllDrivesL(
       
  1367     TPtr aQuery)
       
  1368     {
       
  1369     MPX_FUNC("CMPXDatabase::ExecuteSelectQueryOnAllDrivesL");
       
  1370 
       
  1371     TInt dbCount = iDatabaseHandles.Count();
       
  1372     HBufC* query = HBufC::NewLC(aQuery.Length() * (dbCount + 1) +
       
  1373         KUnionAllToken().Length() * dbCount);
       
  1374     TPtr queryPtr = query->Des();
       
  1375     HBufC* selectOutBuf = NULL;
       
  1376     TInt enclosed = aQuery.Mid(1, aQuery.Length() - 1).Find(KSelectToken);
       
  1377     if (enclosed != KErrNotFound)
       
  1378         {
       
  1379         enclosed++;//to compensate the indent
       
  1380         selectOutBuf = HBufC::NewLC(aQuery.Length() * (dbCount + 1) +
       
  1381             KUnionAllToken().Length() * dbCount);
       
  1382         selectOutBuf->Des().Copy(aQuery.Left(enclosed));
       
  1383         selectOutBuf->Des().Append(aQuery.Right(1));//the closing bracket
       
  1384         aQuery.Delete(0, enclosed);
       
  1385         aQuery.Delete(aQuery.Length() - 1, 1);
       
  1386         }
       
  1387 
       
  1388     HBufC* orderBuf = NULL;
       
  1389     TInt orderPos = aQuery.Find(KOrderByToken);
       
  1390     if (orderPos != KErrNotFound)
       
  1391         {
       
  1392         orderBuf = aQuery.Right(aQuery.Length() - orderPos).AllocL();
       
  1393         aQuery.Delete(orderPos, aQuery.Length() - orderPos);
       
  1394         }
       
  1395     queryPtr.Append(aQuery);// for cdrive
       
  1396     RemoveDriveAlias(queryPtr);
       
  1397     for (TInt i = 0; i < dbCount; ++i)//for other drives
       
  1398         {
       
  1399         if (iDatabaseHandles[i].iOpen)
       
  1400             {
       
  1401             queryPtr.Append(KUnionAllToken);
       
  1402             queryPtr.Append(aQuery);
       
  1403             ReplaceDriveAlias(queryPtr, *(iDatabaseHandles[i].iAliasname));
       
  1404             }
       
  1405         }
       
  1406     if (orderBuf)
       
  1407         {
       
  1408         queryPtr.Append(orderBuf->Des());
       
  1409         }
       
  1410     delete orderBuf;
       
  1411     if (enclosed != KErrNotFound)
       
  1412         {
       
  1413         selectOutBuf->Des().Insert(enclosed, query->Des());
       
  1414         queryPtr.Copy(selectOutBuf->Des());
       
  1415         CleanupStack::PopAndDestroy(selectOutBuf);
       
  1416         }
       
  1417 
       
  1418     // Log the query string before execution
       
  1419     TPtrC ptr(query->Left(KMaxLogQuery));
       
  1420     MPX_DEBUG2("Query: %S", &ptr);
       
  1421 
       
  1422     // Return a temporary statement and not a member variable.
       
  1423     // This ensures that a copy is done and a second embedded query can be
       
  1424     // executed while the first result set is processed.
       
  1425     RSqlStatement statement;
       
  1426     User::LeaveIfError(statement.Prepare(iDatabase, queryPtr));
       
  1427     CleanupStack::PopAndDestroy(query);
       
  1428 
       
  1429     return statement;
       
  1430     }
       
  1431 
       
  1432 // ----------------------------------------------------------------------------
       
  1433 // CMPXDbManager::ExecuteSelectQueryOnAllDrivesL
       
  1434 // ----------------------------------------------------------------------------
       
  1435 //
       
  1436 RSqlStatement CMPXDbManager::ExecuteSelectQueryOnAllDrivesL( TInt aDrive,
       
  1437     TPtr aQuery)
       
  1438     {
       
  1439     MPX_FUNC("CMPXDatabase::ExecuteSelectQueryOnAllDrivesL");
       
  1440 
       
  1441     TInt dbCount = iDatabaseHandles.Count();
       
  1442     HBufC* query = HBufC::NewLC(aQuery.Length() * (dbCount + 1) +
       
  1443         KUnionAllToken().Length() * dbCount);
       
  1444     TPtr queryPtr = query->Des();
       
  1445     HBufC* selectOutBuf = NULL;
       
  1446     TInt enclosed = aQuery.Mid(1, aQuery.Length() - 1).Find(KSelectToken);
       
  1447     if (enclosed != KErrNotFound)
       
  1448         {
       
  1449         enclosed++;//to compensate the indent
       
  1450         selectOutBuf = HBufC::NewLC(aQuery.Length() * (dbCount + 1) +
       
  1451             KUnionAllToken().Length() * dbCount);
       
  1452         selectOutBuf->Des().Copy(aQuery.Left(enclosed));
       
  1453         selectOutBuf->Des().Append(aQuery.Right(1));//the closing bracket
       
  1454         aQuery.Delete(0, enclosed);
       
  1455         aQuery.Delete(aQuery.Length() - 1, 1);
       
  1456         }
       
  1457 
       
  1458     HBufC* orderBuf = NULL;
       
  1459     TInt orderPos = aQuery.Find(KOrderByToken);
       
  1460     if (orderPos != KErrNotFound)
       
  1461         {
       
  1462         orderBuf = aQuery.Right(aQuery.Length() - orderPos).AllocL();
       
  1463         aQuery.Delete(orderPos, aQuery.Length() - orderPos);
       
  1464         }
       
  1465     
       
  1466     //remove KPlDBNameToken
       
  1467     if ( aDrive == EDriveC )//if playlist on c drive
       
  1468     	{
       
  1469     	RemoveDriveAlias(aQuery,KPlDBNameToken);
       
  1470     	}
       
  1471     else
       
  1472     	{//for other drives
       
  1473 	    for (TInt i = 0; i < dbCount; ++i)
       
  1474 	        {
       
  1475 	        if (iDatabaseHandles[i].iOpen && (iDatabaseHandles[i].iDrive == aDrive))
       
  1476 	            {
       
  1477 	            ReplaceDriveAlias(aQuery, *(iDatabaseHandles[i].iAliasname),
       
  1478 	            		KPlDBNameToken);
       
  1479 	            break;
       
  1480 	            }
       
  1481 	        }
       
  1482     	}
       
  1483     
       
  1484     queryPtr.Append(aQuery);// for cdrive
       
  1485     RemoveDriveAlias(queryPtr);
       
  1486     for (TInt i = 0; i < dbCount; ++i)//for other drives
       
  1487         {
       
  1488         if (iDatabaseHandles[i].iOpen)
       
  1489             {
       
  1490             queryPtr.Append(KUnionAllToken);
       
  1491             queryPtr.Append(aQuery);
       
  1492             ReplaceDriveAlias(queryPtr, *(iDatabaseHandles[i].iAliasname));
       
  1493             }
       
  1494         }
       
  1495    
       
  1496     if (orderBuf)
       
  1497         {
       
  1498         queryPtr.Append(orderBuf->Des());
       
  1499         }
       
  1500     delete orderBuf;
       
  1501     if (enclosed != KErrNotFound)
       
  1502         {
       
  1503         selectOutBuf->Des().Insert(enclosed, query->Des());
       
  1504         queryPtr.Copy(selectOutBuf->Des());
       
  1505         CleanupStack::PopAndDestroy(selectOutBuf);
       
  1506         }
       
  1507 
       
  1508     // Log the query string before execution
       
  1509     TPtrC ptr(query->Left(KMaxLogQuery));
       
  1510     MPX_DEBUG2("Query: %S", &ptr);
       
  1511 
       
  1512     // Return a temporary statement and not a member variable.
       
  1513     // This ensures that a copy is done and a second embedded query can be
       
  1514     // executed while the first result set is processed.
       
  1515     RSqlStatement statement;
       
  1516     TInt err(statement.Prepare(iDatabase, queryPtr));
       
  1517     User::LeaveIfError(err);
       
  1518     CleanupStack::PopAndDestroy(query);
       
  1519 
       
  1520     return statement;
       
  1521     }
       
  1522 
       
  1523 // ----------------------------------------------------------------------------
       
  1524 // CMPXDbManager::ExecuteSelectQueryOnDriveLryLC
       
  1525 // ----------------------------------------------------------------------------
       
  1526 //
       
  1527 RSqlStatement CMPXDbManager::ExecuteSelectQueryOnDriveL(
       
  1528     TInt aDrive,
       
  1529     TPtr aQuery)
       
  1530     {
       
  1531     MPX_FUNC("CMPXDatabase::ExecuteSelectQueryOnDriveL");
       
  1532 
       
  1533     RSqlStatement statement;
       
  1534     if (KDbManagerAllDrives == aDrive)
       
  1535         {
       
  1536         statement = ExecuteSelectQueryOnAllDrivesL(aQuery);
       
  1537         }
       
  1538     else
       
  1539         {
       
  1540         TInt dbCount(iDatabaseHandles.Count());
       
  1541 
       
  1542         // flag to check if the query was executed at least once
       
  1543         TBool queryExecuted = EFalse;
       
  1544 
       
  1545         HBufC* query = HBufC::NewLC(aQuery.Length() + KBufIncrement);
       
  1546         TPtr queryPtr = query->Des();
       
  1547         queryPtr.Copy(aQuery);
       
  1548         if (aDrive == EDriveC) //if C drive
       
  1549             {
       
  1550             RemoveDriveAlias(queryPtr);
       
  1551             }
       
  1552         else // drive other than C drive
       
  1553             {
       
  1554             for (TInt i = 0; i < dbCount; ++i)
       
  1555                 {
       
  1556                 if (iDatabaseHandles[i].iOpen && (iDatabaseHandles[i].iDrive == aDrive))
       
  1557                     {
       
  1558                     ReplaceDriveAlias(queryPtr, *(iDatabaseHandles[i].iAliasname));
       
  1559                     break;
       
  1560                     }
       
  1561                 }
       
  1562             }
       
  1563 
       
  1564         TInt dbnamePos = queryPtr.Find(KDBNameToken);// check if the query was created correctly
       
  1565         if (dbnamePos == KErrNotFound)
       
  1566             {
       
  1567             // Log the query string before execution
       
  1568             TPtrC ptr(query->Left(KMaxLogQuery));
       
  1569             MPX_DEBUG2("Query: %S", &ptr);
       
  1570 
       
  1571             User::LeaveIfError(statement.Prepare(iDatabase, queryPtr));
       
  1572             queryExecuted = ETrue;
       
  1573             }
       
  1574         CleanupStack::PopAndDestroy(query);
       
  1575 
       
  1576         if (!queryExecuted)
       
  1577             {
       
  1578             // the requested drive(s) is not open
       
  1579             User::Leave(KErrNotFound);
       
  1580             }
       
  1581         }
       
  1582 
       
  1583     return statement;
       
  1584     }
       
  1585 
       
  1586 // ----------------------------------------------------------------------------
       
  1587 // Prepare a query for execution on all open database. This query's lifetime
       
  1588 // is owned by the dbmanager
       
  1589 // ----------------------------------------------------------------------------
       
  1590 //
       
  1591 RSqlStatement& CMPXDbManager::PrepareQueryL( TUint aStatementId,
       
  1592                                              TRefByValue<const TDesC> aFmt,
       
  1593                                              VA_LIST aList )
       
  1594     {
       
  1595     // Try to find the query first if it has been created
       
  1596     TInt index(KErrNotFound);
       
  1597     TInt c(iPreparedStatements.Count());
       
  1598 
       
  1599     for( TInt i=0; i<c; ++i )
       
  1600         {
       
  1601         if( iPreparedStatements[i].iId == aStatementId )
       
  1602             {
       
  1603             index = i;
       
  1604             break;
       
  1605             }
       
  1606         }
       
  1607 
       
  1608     // If the index isn't found we create a new query statement
       
  1609     //
       
  1610     if( index == KErrNotFound )
       
  1611         {
       
  1612         RSqlStatement* newStatement = new(ELeave) RSqlStatement();
       
  1613         CleanupStack::PushL(newStatement);
       
  1614 
       
  1615         TSqlStatementState newState;
       
  1616         newState.iId = aStatementId;
       
  1617         newState.iPrepared = EFalse;
       
  1618         iPreparedStatements.AppendL( newState );
       
  1619 
       
  1620         TInt err = iStatements.Append( newStatement ); // ownership x-fer
       
  1621         if (err != KErrNone)
       
  1622             {
       
  1623             iPreparedStatements.Remove(c);
       
  1624             User::Leave(err);
       
  1625             }
       
  1626         CleanupStack::Pop(newStatement);
       
  1627         index = c;
       
  1628         }
       
  1629 
       
  1630     // Finally create the statement
       
  1631     if ( !iPreparedStatements[index].iPrepared )
       
  1632         {
       
  1633 
       
  1634         // Will reallocate
       
  1635         HBufC* selectBuf = FormatQueryLC(aFmt, aList);
       
  1636         TPtr selectBufPtr = selectBuf->Des();
       
  1637         TInt dbCount = iDatabaseHandles.Count();
       
  1638         HBufC* query = HBufC::NewLC(selectBufPtr.Length() * (dbCount + 1) +
       
  1639             KUnionAllToken().Length() * dbCount);
       
  1640         TPtr queryPtr = query->Des();
       
  1641         HBufC* selectOutBuf = NULL;
       
  1642         TInt enclosed = selectBufPtr.Mid(1,selectBufPtr.Length() - 1).Find(KSelectToken);
       
  1643         if (enclosed != KErrNotFound)
       
  1644             {
       
  1645             enclosed++;//to compensate the indent
       
  1646             selectOutBuf = HBufC::NewLC(selectBufPtr.Length() * (dbCount + 1) +
       
  1647                 KUnionAllToken().Length() * dbCount);
       
  1648             selectOutBuf->Des().Copy(selectBufPtr.Left(enclosed));
       
  1649             selectOutBuf->Des().Append(selectBufPtr.Right(1));//the closing bracket
       
  1650             selectBufPtr.Delete(0, enclosed);
       
  1651             selectBufPtr.Delete(selectBufPtr.Length()   -   1, 1);
       
  1652             }
       
  1653 
       
  1654         HBufC* orderBuf = NULL;
       
  1655         TInt orderPos = selectBufPtr.Find(KOrderByToken);
       
  1656         if (orderPos != KErrNotFound)
       
  1657             {
       
  1658             orderBuf = selectBufPtr.Right(selectBufPtr.Length() - orderPos).AllocL();
       
  1659             selectBufPtr.Delete(orderPos,   selectBufPtr.Length() - orderPos);
       
  1660             }
       
  1661         queryPtr.Append(selectBufPtr);// for cdrive
       
  1662         RemoveDriveAlias(queryPtr);
       
  1663         for (TInt i = 0; i < dbCount; ++i)//for other drives
       
  1664             {
       
  1665             if (iDatabaseHandles[i].iOpen)
       
  1666                 {
       
  1667                 queryPtr.Append(KUnionAllToken);
       
  1668                 queryPtr.Append(selectBufPtr);
       
  1669                 ReplaceDriveAlias(queryPtr, *(iDatabaseHandles[i].iAliasname));
       
  1670                 }
       
  1671             }
       
  1672         if (orderBuf)
       
  1673             {
       
  1674             queryPtr.Append(orderBuf->Des());
       
  1675             }
       
  1676         delete orderBuf;
       
  1677         if (enclosed != KErrNotFound)
       
  1678             {
       
  1679             selectOutBuf->Des().Insert(enclosed, query->Des());
       
  1680             queryPtr.Copy(selectOutBuf->Des());
       
  1681             CleanupStack::PopAndDestroy(selectOutBuf);
       
  1682             }
       
  1683 
       
  1684         // Log the query string before execution
       
  1685         TPtrC ptr(query->Left(KMaxLogQuery));
       
  1686         MPX_DEBUG2("Query: %S", &ptr);
       
  1687 
       
  1688         // use the member variable statement
       
  1689         User::LeaveIfError(iStatements[index]->Prepare(iDatabase, queryPtr));
       
  1690         CleanupStack::PopAndDestroy(2, selectBuf); //query
       
  1691 
       
  1692         iPreparedStatements[index].iPrepared = ETrue;
       
  1693         }
       
  1694     else
       
  1695         {
       
  1696         iStatements[index]->Reset();
       
  1697         }
       
  1698 
       
  1699     return *iStatements[index];
       
  1700     }
       
  1701 
       
  1702 // ----------------------------------------------------------------------------
       
  1703 // Resets all prepared queries
       
  1704 // ----------------------------------------------------------------------------
       
  1705 //
       
  1706 void CMPXDbManager::ResetPreparedQueries()
       
  1707     {
       
  1708     MPX_FUNC("CMPXDbManager::ResetPreparedQueries");
       
  1709     iPreparedStatements.Reset();
       
  1710 
       
  1711     TInt c( iStatements.Count() );
       
  1712     for( TInt i=0; i<c; ++i )
       
  1713         {
       
  1714         iStatements[i]->Close();
       
  1715         }
       
  1716     iStatements.ResetAndDestroy();
       
  1717     }
       
  1718 
       
  1719 // ----------------------------------------------------------------------------
       
  1720 // Asks all registered tables to create themselves
       
  1721 // ----------------------------------------------------------------------------
       
  1722 //
       
  1723 EXPORT_C void CMPXDbManager::CreateTablesL(
       
  1724     RSqlDatabase& aDatabase)
       
  1725     {
       
  1726     MPX_FUNC("CMPXDbManager::CreateTablesL");
       
  1727 
       
  1728 	CreateTablesL(aDatabase, EFalse);
       
  1729     }
       
  1730 
       
  1731 // ----------------------------------------------------------------------------
       
  1732 // CleanupTransaction: close transaction when creating DB
       
  1733 // ----------------------------------------------------------------------------
       
  1734 //
       
  1735 static void CleanupTransaction(TAny * aDatabase)
       
  1736     {
       
  1737     TInt err = ((RSqlDatabase*)aDatabase)->Exec(KRollbackTransaction);
       
  1738     MPX_DEBUG2("CMPXDbManager CleanupTransaction rollback, error %d", err);
       
  1739     }
       
  1740     
       
  1741 // ----------------------------------------------------------------------------
       
  1742 // CMPXDbManager::CreateTablesL
       
  1743 // ----------------------------------------------------------------------------
       
  1744 //
       
  1745 void CMPXDbManager::CreateTablesL(
       
  1746 	RSqlDatabase& aDatabase,
       
  1747 	TBool aCorrupt)
       
  1748 	{
       
  1749 	MPX_FUNC("CMPXDbManager::CreateTablesL");
       
  1750     TInt err = aDatabase.Exec(KBeginTransaction);
       
  1751     if (err < 0)
       
  1752        {
       
  1753        MPX_DEBUG2("SQL BEGIN TRANSACTION error %d", err);
       
  1754        User::Leave (err);
       
  1755        }
       
  1756     CleanupStack::PushL(TCleanupItem(&CleanupTransaction, &aDatabase));
       
  1757     TInt count(iTables.Count());
       
  1758     for (TInt i = 0; i < count; ++i)
       
  1759         {
       
  1760         iTables[i]->CreateTableL(aDatabase, aCorrupt);
       
  1761         }
       
  1762     err = aDatabase.Exec(KCommitTransaction);
       
  1763     if (err < 0)
       
  1764         {
       
  1765         MPX_DEBUG2("SQL COMMIT TRANSACTION error %d", err);
       
  1766         User::Leave (err);
       
  1767         }
       
  1768     CleanupStack::Pop();
       
  1769 	}
       
  1770 
       
  1771 // ----------------------------------------------------------------------------
       
  1772 // Opens root database on C-drive
       
  1773 // ----------------------------------------------------------------------------
       
  1774 //
       
  1775 void CMPXDbManager::OpenRootDatabaseL()
       
  1776     {
       
  1777     MPX_FUNC("CMPXDbManager::OpenRootDatabaseL");
       
  1778         TDriveUnit cdrive(KRootDrive());
       
  1779     HBufC * filename = CreateFilenameL(cdrive);
       
  1780     CleanupStack::PushL(filename);
       
  1781     User::LeaveIfError(iDatabase.Open(*filename));
       
  1782 
       
  1783     CleanupStack::PopAndDestroy(filename);
       
  1784     }
       
  1785 
       
  1786 // ----------------------------------------------------------------------------
       
  1787 // Creates a specified database.
       
  1788 // ----------------------------------------------------------------------------
       
  1789 //
       
  1790 void CMPXDbManager::CreateDatabaseL(
       
  1791     TDriveUnit aDrive)
       
  1792     {
       
  1793     MPX_FUNC("CMPXDbManager::CreateDatabaseL");
       
  1794 
       
  1795     RSqlDatabase database;
       
  1796     CleanupClosePushL(database);
       
  1797 
       
  1798     HBufC* filename = CreateFilenameL(aDrive);
       
  1799     CleanupStack::PushL(filename);
       
  1800 
       
  1801     if (database.Open(filename->Des()) != KErrNone)
       
  1802         {
       
  1803         MPX_DEBUG3("CMPXDbManager::CreateDatabaseL - cannot open db on drive %d %S", TInt(aDrive), filename);
       
  1804 
       
  1805         // close the database first
       
  1806         database.Close();
       
  1807         DoCreateDatabaseL( aDrive );
       
  1808         }
       
  1809     else
       
  1810         {
       
  1811         TBool tableOK(ETrue);
       
  1812 
       
  1813         // try to detect any corrupt tables
       
  1814         TInt count(iTables.Count());
       
  1815         for (TInt i = 0; i < count; ++i)
       
  1816             {
       
  1817             // ask the table to check its structure
       
  1818             if (!iTables[i]->CheckTableL(database))
       
  1819                 {
       
  1820                 tableOK = EFalse;
       
  1821                 break;
       
  1822                 }
       
  1823             }
       
  1824 
       
  1825         if (!tableOK)
       
  1826             {
       
  1827             // close the database first
       
  1828             database.Close();
       
  1829 			
       
  1830 			// delete database and create database
       
  1831             DoCreateDatabaseL( aDrive );
       
  1832             }
       
  1833         }
       
  1834     CleanupStack::PopAndDestroy(filename);
       
  1835     CleanupStack::PopAndDestroy(&database);
       
  1836     }
       
  1837 
       
  1838 // ----------------------------------------------------------------------------
       
  1839 // Attaches a specified database.
       
  1840 // ----------------------------------------------------------------------------
       
  1841 //
       
  1842 void CMPXDbManager::AttachDatabaseL( TInt aIndex )
       
  1843     {
       
  1844     MPX_FUNC("CMPXDbManager::AttachDatabaseL");
       
  1845     ASSERT( aIndex < iDatabaseHandles.Count() );
       
  1846     DatabaseHandle & database = iDatabaseHandles[ aIndex ];
       
  1847     if (!database.iOpen)
       
  1848         {
       
  1849         HBufC* filename = CreateFilenameL( database.iDrive );
       
  1850         CleanupStack::PushL(filename);
       
  1851                 
       
  1852 #ifdef __RAMDISK_PERF_ENABLE
       
  1853         if( database.iUseRAMdb )
       
  1854             {
       
  1855             delete database.iAliasname;
       
  1856             database.iAliasname = HBufC::NewL(KAliasName().Length());
       
  1857             // coverity[size_error]
       
  1858             // coverity[buffer_alloc]
       
  1859             HBufC* temp = HBufC::NewLC(2); // form of DE, DF, DX,...
       
  1860             temp->Des().Append(iRAMDrive); // length == 2
       
  1861             TDriveUnit pdrive( database.iDrive );
       
  1862             temp->Des().Append(pdrive.Name().Left(1)); //length == 2+ 1
       
  1863             database.iAliasname->Des().Format(KRAMAliasName, temp);
       
  1864             MPX_DEBUG2("CMPXDbManager::AttachDatabaseL - RAM change aliasname of %S", database.iAliasname );
       
  1865             CleanupStack::PopAndDestroy(temp);
       
  1866             }
       
  1867         else
       
  1868 #endif //__RAMDISK_PERF_ENABLE
       
  1869             {
       
  1870             delete database.iAliasname;
       
  1871             TDriveUnit drive( database.iDrive );
       
  1872             const TDesC& driveName = drive.Name();
       
  1873             database.iAliasname = HBufC::NewL(KAliasName().Length());
       
  1874             database.iAliasname->Des().Format(KAliasName, &driveName);
       
  1875             MPX_DEBUG2("CMPXDbManager::AttachDatabaseL - normal change aliasname of %S", database.iAliasname);
       
  1876             }
       
  1877 
       
  1878         TInt err = iDatabase.Attach( *filename, *database.iAliasname );
       
  1879         MPX_DEBUG2("CMPXDbManager::AttachDatabaseL - Attach Error =%d", err);
       
  1880         User::LeaveIfError(err);
       
  1881         database.iOpen = ETrue;
       
  1882 
       
  1883         CleanupStack::PopAndDestroy(filename);
       
  1884         }
       
  1885     else
       
  1886         {
       
  1887         MPX_DEBUG1("CMPXDbManager::AttachDatabaseL - found already open");    
       
  1888         }
       
  1889     }
       
  1890 
       
  1891 // ----------------------------------------------------------------------------
       
  1892 // Detaches a specified database.
       
  1893 // ----------------------------------------------------------------------------
       
  1894 //
       
  1895 void CMPXDbManager::DetachDatabaseL( TInt aIndex )
       
  1896     {
       
  1897     MPX_FUNC("CMPXDbManager::DetachDatabaseL");
       
  1898 
       
  1899     ASSERT( iInitialized && aIndex < iDatabaseHandles.Count() );
       
  1900     DatabaseHandle & database = iDatabaseHandles[ aIndex ];
       
  1901     if ( database.iOpen )
       
  1902         {
       
  1903         MPX_DEBUG2("CMPXDbManager::DetachDatabaseL iAliasname=%S is open",database.iAliasname );
       
  1904         TInt err = iDatabase.Detach(*(database.iAliasname));
       
  1905         if ( err )
       
  1906             {
       
  1907             MPX_DEBUG2("CMPXDbManager::DetachDatabaseL detach failed Error=%d", err);
       
  1908             }
       
  1909         User::LeaveIfError(err);
       
  1910         database.iOpen = EFalse;
       
  1911         }
       
  1912     }
       
  1913 
       
  1914 // ----------------------------------------------------------------------------
       
  1915 // Creates the absolute database filename on a specified drive.
       
  1916 // ----------------------------------------------------------------------------
       
  1917 //
       
  1918 HBufC* CMPXDbManager::CreateFilenameL(
       
  1919     TDriveUnit aDrive)
       
  1920     {
       
  1921     MPX_FUNC("CMPXDbManager::CreateFilenameL");
       
  1922 
       
  1923     HBufC* filename = HBufC::NewL(KMaxFileName);
       
  1924 
       
  1925     const TDesC& securefilePath = KSecureFilePath;
       
  1926     TDriveUnit cdrive(KRootDrive());
       
  1927 
       
  1928 #ifdef __RAMDISK_PERF_ENABLE
       
  1929     TInt index(GetDatabaseIndex((TInt)aDrive));    
       
  1930     if ( index >=0 && iDatabaseHandles[index].iUseRAMdb && aDrive != cdrive )
       
  1931         {
       
  1932         MPX_DEBUG1("CMPXDbManager::CreateFilenameL - use RAMDisk");
       
  1933         TFileName path;
       
  1934         path.Append(iRAMDrive);
       
  1935         path.Append(_L(":"));
       
  1936         TBuf<2> d;
       
  1937         d.Append(aDrive.Name());
       
  1938         TFileName temp;
       
  1939         temp.Append(d.Left(1)); // attach original drive name
       
  1940         temp.Append(iDbFile->Des()); 
       
  1941         filename->Des().Format(securefilePath, &path, User::Identity().iUid, &temp);
       
  1942         MPX_DEBUG3("CMPXDbManager::CreateFilenameL - path=%S filename=%S", &path, filename);
       
  1943         }
       
  1944     else
       
  1945 #endif //__RAMDISK_PERF_ENABLE
       
  1946         {
       
  1947         MPX_DEBUG1("CMPXDbManager::CreateFilenameL - use normal drive");
       
  1948         const TDesC& driveName = aDrive.Name();
       
  1949         filename->Des().Format(securefilePath, &driveName, User::Identity().iUid, iDbFile);
       
  1950         }
       
  1951     
       
  1952     MPX_DEBUG2("CMPXDbManager::CreateFilenameL filename = %S", filename); 
       
  1953     return filename;
       
  1954     }
       
  1955 
       
  1956 // ----------------------------------------------------------------------------
       
  1957 // Replaces :dbname with a drive alias
       
  1958 // ----------------------------------------------------------------------------
       
  1959 //
       
  1960 void CMPXDbManager::ReplaceDriveAlias(
       
  1961     TDes& aQuery,
       
  1962     const TDesC& aAlias)
       
  1963     {
       
  1964 //  MPX_FUNC("CMPXDbManager::ReplaceDriveAlias");
       
  1965 
       
  1966     TInt dbnamePos(aQuery.Find(KDBNameToken));
       
  1967     while (dbnamePos != KErrNotFound)
       
  1968         {
       
  1969         aQuery.Delete(dbnamePos, KDBNameToken().Length());
       
  1970         aQuery.Insert(dbnamePos, aAlias);
       
  1971         dbnamePos = aQuery.Find(KDBNameToken);
       
  1972         }
       
  1973     }
       
  1974 
       
  1975 // ----------------------------------------------------------------------------
       
  1976 // Replaces :dbname with a drive alias
       
  1977 // ----------------------------------------------------------------------------
       
  1978 //
       
  1979 void CMPXDbManager::ReplaceDriveAlias(
       
  1980     TDes& aQuery,
       
  1981     const TDesC& aAlias,
       
  1982     const TDesC& aToKen)
       
  1983     {
       
  1984     
       
  1985     TInt dbnamePos(aQuery.Find(aToKen));
       
  1986     while (dbnamePos != KErrNotFound)
       
  1987         {
       
  1988         aQuery.Delete(dbnamePos, aToKen.Length());
       
  1989         aQuery.Insert(dbnamePos, aAlias);
       
  1990         dbnamePos = aQuery.Find(aToKen);
       
  1991         }
       
  1992     }
       
  1993 
       
  1994 // ----------------------------------------------------------------------------
       
  1995 // Removes :dbname
       
  1996 // ----------------------------------------------------------------------------
       
  1997 //
       
  1998 void CMPXDbManager::RemoveDriveAlias(
       
  1999     TDes& aQuery)
       
  2000     {
       
  2001     MPX_FUNC("CMPXDbManager::RemoveDriveAlias");
       
  2002 
       
  2003     TInt dbnamePos(aQuery.Find(KDBNameToken));
       
  2004     while (dbnamePos != KErrNotFound)
       
  2005         {
       
  2006         aQuery.Delete(dbnamePos, KDBNameToken().Length() + 1);
       
  2007         dbnamePos = aQuery.Find(KDBNameToken);
       
  2008         }
       
  2009     }
       
  2010 
       
  2011 
       
  2012 // ----------------------------------------------------------------------------
       
  2013 // Removes :dbname
       
  2014 // ----------------------------------------------------------------------------
       
  2015 //
       
  2016 void CMPXDbManager::RemoveDriveAlias(
       
  2017     TDes& aQuery,const TDesC& aToKen)
       
  2018     {
       
  2019     MPX_FUNC("CMPXDbManager::RemoveDriveAlias");
       
  2020 
       
  2021     TInt dbnamePos(aQuery.Find(aToKen));
       
  2022     while (dbnamePos != KErrNotFound)
       
  2023         {
       
  2024         aQuery.Delete(dbnamePos, aToKen.Length() + 1);
       
  2025         dbnamePos = aQuery.Find(aToKen);
       
  2026         }
       
  2027     }
       
  2028 
       
  2029 
       
  2030 // ----------------------------------------------------------------------------
       
  2031 // CMPXDbManager::CheckDiskSpaceL
       
  2032 // ----------------------------------------------------------------------------
       
  2033 //
       
  2034 EXPORT_C void CMPXDbManager::CheckDiskSpaceL(
       
  2035     TInt aDrive)
       
  2036     {
       
  2037     MPX_FUNC("CMPXDbManager::CheckDiskSpaceL");
       
  2038     
       
  2039     // LTAN-7GH6BZ, crash if eject memory card when adding song to existing playlist
       
  2040     // due to special timing issue, it is possible drive number is -1 and create a
       
  2041     // panic when use for TDriveUnit
       
  2042     MPX_DEBUG2("aDrive = %d", aDrive);
       
  2043     
       
  2044     if (aDrive < 0)
       
  2045         {
       
  2046         MPX_DEBUG1("invalid driveId, leave with KErrNotReady");
       
  2047         User::Leave(KErrNotReady);
       
  2048         }
       
  2049     
       
  2050     EnsureDiskSpaceL(aDrive);
       
  2051     }
       
  2052     
       
  2053 // ----------------------------------------------------------------------------
       
  2054 // Regenerate all databases.
       
  2055 // ----------------------------------------------------------------------------
       
  2056 //
       
  2057 EXPORT_C void CMPXDbManager::RegenerateAllDatabasesL()
       
  2058     {
       
  2059     MPX_DEBUG1("CMPXDbManager::RegenerateAllDatabasesL Enter");
       
  2060     ResetPreparedQueries(); //just in case ...
       
  2061     TInt handles(iDatabaseHandles.Count());
       
  2062     for (TInt i = 0; i < handles; ++i)
       
  2063         {
       
  2064         iDatabaseHandles[i].iOpen = EFalse; //attach will open them again
       
  2065         }    
       
  2066     iDatabase.Close(); //close the database before deleting the file
       
  2067     iInitialized = EFalse;
       
  2068 
       
  2069     MPX_DEBUG1("RegenerateAllDatabasesL: Regenerating main DB on C:");
       
  2070     HBufC * filename = CreateFilenameL(EDriveC);
       
  2071     CleanupStack::PushL(filename);
       
  2072     RSqlDatabase::Delete(*filename);
       
  2073     TDriveUnit cdrive(KRootDrive());
       
  2074     CreateDatabaseL(cdrive);
       
  2075     User::LeaveIfError(iDatabase.Open(*filename)); // will set handle status later
       
  2076     CleanupStack::PopAndDestroy(filename);
       
  2077     MPX_DEBUG1("RegenerateAllDatabasesL: DB regeneration complete");
       
  2078     
       
  2079     // Recreate all attached drives
       
  2080     TInt count(iDatabaseHandles.Count());
       
  2081     for (TInt i = 0; i < count; ++i)
       
  2082         {
       
  2083         if (iDatabaseHandles[i].iDrive != EDriveC)
       
  2084             {
       
  2085             MPX_DEBUG2("RegenerateAllDatabasesL: Regenerating DB on %d",iDatabaseHandles[i].iDrive);
       
  2086             TVolumeInfo volumeInfo; 
       
  2087             TInt err = iFs.Volume(volumeInfo,iDatabaseHandles[i].iDrive);
       
  2088             if(err != KErrNone)
       
  2089                 {
       
  2090                 continue; //if drive is not currently accessible, skip
       
  2091                 }
       
  2092             filename = CreateFilenameL(iDatabaseHandles[i].iDrive);
       
  2093             CleanupStack::PushL(filename);
       
  2094             MPX_DEBUG1("RegenerateAllDatabasesL: Detaching DB");
       
  2095             err = iDatabase.Detach(*(iDatabaseHandles[i].iAliasname)); //ignore the error if any
       
  2096             MPX_DEBUG2("RegenerateAllDatabasesL: Detached[err=%d]; Deleting DB",err);
       
  2097             err = RSqlDatabase::Delete(*filename);
       
  2098             MPX_DEBUG2("RegenerateAllDatabasesL: Deleted[err=%d]; Creating new DB",err);
       
  2099             TDriveUnit drive(iDatabaseHandles[i].iDrive);
       
  2100             CreateDatabaseL(drive);
       
  2101             MPX_DEBUG1("RegenerateAllDatabasesL: Attaching new DB");
       
  2102             AttachDatabaseL( i );    
       
  2103             MPX_DEBUG1("RegenerateAllDatabasesL: DB regeneration complete");
       
  2104             CleanupStack::PopAndDestroy(filename);
       
  2105             }
       
  2106         else
       
  2107             {
       
  2108             iDatabaseHandles[i].iOpen = ETrue; //if we got here it is opened
       
  2109             }
       
  2110         }
       
  2111     iInitialized = ETrue;
       
  2112     MPX_DEBUG1("CMPXDbManager::RegenerateAllDatabasesL Exit");
       
  2113     }    
       
  2114 
       
  2115 // ----------------------------------------------------------------------------
       
  2116 // CMPXDbManager::DoRecreateDatabaseL
       
  2117 // ----------------------------------------------------------------------------
       
  2118 //
       
  2119 void CMPXDbManager::DoRecreateDatabaseL(HBufC * aFilename)
       
  2120     {
       
  2121     RSqlDatabase database;
       
  2122     CleanupClosePushL(database);
       
  2123 
       
  2124     User::LeaveIfError(database.Open(aFilename->Des()));
       
  2125 
       
  2126     TInt count(iTables.Count());
       
  2127     for (TInt i = 0; i < count; ++i)
       
  2128         {
       
  2129         iTables[i]->DropTableL(database);
       
  2130         iTables[i]->CreateTableL(database, EFalse);
       
  2131         }
       
  2132     CleanupStack::PopAndDestroy(&database);
       
  2133     }
       
  2134 
       
  2135 // ----------------------------------------------------------------------------
       
  2136 // CMPXDbManager::ExecuteSqlStatement
       
  2137 // ----------------------------------------------------------------------------
       
  2138 //
       
  2139 TInt CMPXDbManager::ExecuteSqlStatement(RSqlDatabase& aDatabase,const TDesC& aStatement)
       
  2140     {
       
  2141     MPX_FUNC("CMPXDbManager::ExecuteSqlStatement");
       
  2142     TInt result( KErrNone );
       
  2143     RSqlStatement sqlStatement;
       
  2144     //Prepare and execute SQL statement
       
  2145     result = sqlStatement.Prepare(aDatabase, aStatement);
       
  2146     if (result == KErrNone)
       
  2147         {
       
  2148         result = sqlStatement.Exec();
       
  2149         //If the database schema was changed or the session expired repeat all the steps
       
  2150         if((result == KSqlErrStmtExpired) || (result == KSqlErrSchema))
       
  2151             {
       
  2152             sqlStatement.Close();
       
  2153             result = sqlStatement.Prepare(aDatabase, aStatement);
       
  2154             if (result == KErrNone)
       
  2155                 {
       
  2156                 result = sqlStatement.Exec();
       
  2157                 }
       
  2158             }
       
  2159         sqlStatement.Close();
       
  2160         }
       
  2161     return result;
       
  2162     }
       
  2163 
       
  2164 #ifdef _DEBUG
       
  2165 
       
  2166 // ----------------------------------------------------------------------------
       
  2167 // Returns the number of columns from a specified SQL statement
       
  2168 // ----------------------------------------------------------------------------
       
  2169 //
       
  2170 TInt CMPXDbManager::GetColumnCountL(
       
  2171     RSqlStatement& aStatement)
       
  2172     {
       
  2173     TInt columnCount(0);
       
  2174 
       
  2175 // Using TSqlRowSetUtil causes linker errors on ARMv5 UDEB
       
  2176 // Enabling this functionality for WINSCW UDEB only
       
  2177 // PREQ2536 the files sqlrowsetutil.h and sqlrowsetutil.cpp has been removed
       
  2178 //#ifdef __WINSCW__
       
  2179 //
       
  2180 //    HBufC* headers = TSqlRowSetUtil::GetDeclColumnTypesL(aStatement);
       
  2181 //    CleanupStack::PushL(headers);
       
  2182 //
       
  2183 //    // Count the number of semicolons to get the number of columns
       
  2184 //    TPtr headerPtr = headers->Des();
       
  2185 //    TInt location(headerPtr.Locate(';'));
       
  2186 //    while ((location != KErrNotFound) && (location < headers->Length()))
       
  2187 //        {
       
  2188 //        ++columnCount;
       
  2189 //        if (++location < headers->Length())
       
  2190 //            {
       
  2191 //            headerPtr = headers->Des().Mid(location);
       
  2192 //            location = headerPtr.Locate(';');
       
  2193 //            }
       
  2194 //        }
       
  2195 //    CleanupStack::PopAndDestroy(headers);
       
  2196 //
       
  2197 //#else
       
  2198 	(void)aStatement;
       
  2199 //#endif
       
  2200 
       
  2201     return columnCount;
       
  2202     }
       
  2203 
       
  2204 // ----------------------------------------------------------------------------
       
  2205 // Prints the table values from a specified SQL query
       
  2206 // ----------------------------------------------------------------------------
       
  2207 //
       
  2208 void CMPXDbManager::PrintTableValuesL(
       
  2209     RSqlStatement& aStatement)
       
  2210     {
       
  2211     TInt columnCount(GetColumnCountL(aStatement));
       
  2212     TInt err(KErrNone);
       
  2213     // coverity[incorrect_multiplication]
       
  2214     // coverity[buffer_alloc]
       
  2215     HBufC* tableRow = HBufC::NewLC(255 * columnCount);
       
  2216     TPtr tableRowPtr = tableRow->Des();
       
  2217 
       
  2218     while ((err = aStatement.Next()) == KSqlAtRow)
       
  2219         {
       
  2220         tableRowPtr.Zero();
       
  2221         TInt error(KErrNone);
       
  2222         for (TInt index = 0; (error == KErrNone) && (index < columnCount); ++index)
       
  2223             {
       
  2224             if (index !=0)
       
  2225                 {
       
  2226                 tableRowPtr.Append(',');
       
  2227                 }
       
  2228             switch (aStatement.ColumnType(index))
       
  2229                 {
       
  2230                 case ESqlNull:
       
  2231                     tableRowPtr.Append(_L("<NULL>"));
       
  2232                     break;
       
  2233 
       
  2234                 case ESqlInt:
       
  2235                     {
       
  2236                     tableRowPtr.AppendFormat(_L("%u"), aStatement.ColumnInt(index));
       
  2237                     }
       
  2238                     break;
       
  2239 
       
  2240                 case ESqlInt64:
       
  2241                     {
       
  2242                     tableRowPtr.AppendFormat(_L("%lu"), aStatement.ColumnInt64(index));
       
  2243                     }
       
  2244                     break;
       
  2245 
       
  2246                 case ESqlReal:
       
  2247                     {
       
  2248                     tableRowPtr.AppendFormat(_L("%f"), aStatement.ColumnReal(index));
       
  2249                     }
       
  2250                     break;
       
  2251 
       
  2252                 case ESqlText:
       
  2253                     {
       
  2254                     TPtrC columnValue;
       
  2255                     error = aStatement.ColumnText(index, columnValue);
       
  2256                     if (error == KErrNone)
       
  2257                         {
       
  2258                         tableRowPtr.AppendFormat(_L("%S"), &columnValue);
       
  2259                         }
       
  2260                     }
       
  2261                     break;
       
  2262 
       
  2263                 case ESqlBinary:
       
  2264                     {
       
  2265                     TPtrC8 columnValue;
       
  2266                     error = aStatement.ColumnBinary(index, columnValue);
       
  2267                     if (error == KErrNone)
       
  2268                         {
       
  2269                         tableRowPtr.AppendFormat(_L("%S"), &columnValue);
       
  2270                         }
       
  2271                     }
       
  2272                     break;
       
  2273 
       
  2274                 default :
       
  2275                     ASSERT(EFalse);
       
  2276                 }
       
  2277 
       
  2278             if (tableRowPtr.Length() > 255)
       
  2279                 {
       
  2280                 tableRowPtr.SetLength(255);
       
  2281                 MPX_DEBUG2("%S", tableRow);
       
  2282                 tableRowPtr.Zero();
       
  2283                 }
       
  2284             }
       
  2285         if (tableRowPtr.Length() > 0)
       
  2286             {
       
  2287             tableRowPtr.SetLength(Min(tableRowPtr.Length(), 255));
       
  2288             MPX_DEBUG2("%S", tableRow);
       
  2289             }
       
  2290         }
       
  2291     CleanupStack::PopAndDestroy(tableRow);
       
  2292     if (err != KSqlAtEnd)
       
  2293         {
       
  2294         User::Leave(err);
       
  2295         }
       
  2296     }
       
  2297 
       
  2298 // ----------------------------------------------------------------------------
       
  2299 // Finds all the tables on the main or attached drives
       
  2300 // ----------------------------------------------------------------------------
       
  2301 //
       
  2302 void CMPXDbManager::FindAllTablesL(
       
  2303     const TDesC& aAlias,
       
  2304     RArray<HBufC*>& aTableName)
       
  2305     {
       
  2306     CleanupClosePushL(aTableName);
       
  2307     RSqlStatement statement;
       
  2308     CleanupClosePushL(statement);
       
  2309 
       
  2310     if (aAlias == KNullDesC)
       
  2311         {
       
  2312         statement.Prepare(iDatabase, KFindAllCDriveTablesQuery);
       
  2313         }
       
  2314     else
       
  2315         {
       
  2316         HBufC* query = KFindAllAttachedTablesQuery().AllocL();
       
  2317         CleanupStack::PushL(query);
       
  2318         TPtr queryPtr = query->Des();
       
  2319         ReplaceDriveAlias(queryPtr, aAlias);
       
  2320         statement.Prepare(iDatabase, queryPtr);
       
  2321         CleanupStack::PopAndDestroy(query);
       
  2322         }
       
  2323 
       
  2324     TInt err(KErrNone);
       
  2325 
       
  2326     while ((err = statement.Next()) == KSqlAtRow)
       
  2327         {
       
  2328         TPtrC val = statement.ColumnTextL(statement.ColumnIndex(KNameColumn));
       
  2329         aTableName.AppendL(val.AllocL());
       
  2330         }
       
  2331     if (err != KSqlAtEnd)
       
  2332         {
       
  2333         User::Leave(err);
       
  2334         }
       
  2335 
       
  2336     CleanupStack::PopAndDestroy(&statement);
       
  2337     CleanupStack::Pop();
       
  2338     }
       
  2339 
       
  2340 // ----------------------------------------------------------------------------
       
  2341 // Prints the tables on the main or attached drives
       
  2342 // ----------------------------------------------------------------------------
       
  2343 //
       
  2344 void CMPXDbManager::PrintTableL(
       
  2345     const TDesC& aAlias,
       
  2346     const TDesC& aTableName)
       
  2347     {
       
  2348     RSqlStatement statement;
       
  2349     CleanupClosePushL(statement);
       
  2350 
       
  2351     if (aAlias == KNullDesC)
       
  2352         {
       
  2353         HBufC* selectQuery = HBufC::NewLC(KTableQuery().Length() + aTableName.Length());
       
  2354         selectQuery->Des().Format(KTableQuery, &aTableName);
       
  2355         User::LeaveIfError(statement.Prepare(iDatabase, *selectQuery));
       
  2356         CleanupStack::PopAndDestroy(selectQuery);
       
  2357         }
       
  2358     else
       
  2359         {
       
  2360         HBufC* selectQuery = HBufC::NewLC(KAttachedTableQuery().Length() + aTableName.Length());
       
  2361         selectQuery->Des().Format(KAttachedTableQuery, &aTableName);
       
  2362 
       
  2363         TPtr selectQueryPtr(selectQuery->Des());
       
  2364         ReplaceDriveAlias(selectQueryPtr, aAlias);
       
  2365         User::LeaveIfError(statement.Prepare(iDatabase, *selectQuery));
       
  2366 
       
  2367         CleanupStack::PopAndDestroy(selectQuery);
       
  2368         }
       
  2369 
       
  2370     PrintTableValuesL(statement);
       
  2371     CleanupStack::PopAndDestroy(&statement);
       
  2372     }
       
  2373 
       
  2374 #endif
       
  2375 
       
  2376 // ----------------------------------------------------------------------------
       
  2377 // Prints all the tables on the main and attached drives
       
  2378 // ----------------------------------------------------------------------------
       
  2379 //
       
  2380 EXPORT_C void CMPXDbManager::PrintDatabaseL()
       
  2381     {
       
  2382 #ifdef _DEBUG
       
  2383     if (iInitialized)
       
  2384         {
       
  2385         // C-Drive
       
  2386         RArray<HBufC*> tableNames;
       
  2387         FindAllTablesL(KNullDesC(), tableNames);
       
  2388 
       
  2389         MPX_DEBUG1("### Drive C ###");
       
  2390 
       
  2391         TInt tableCount(tableNames.Count());
       
  2392         for (TInt i = 0; i < tableCount; ++i)
       
  2393             {
       
  2394             MPX_DEBUG2("# %S #", tableNames[i]);
       
  2395             MPX_TRAPD(error, PrintTableL(KNullDesC, *tableNames[i]));
       
  2396             delete tableNames[i];
       
  2397             if (error != KErrNone)
       
  2398                 {
       
  2399                 if (error != KErrPermissionDenied)
       
  2400                     {
       
  2401                     User::Leave(error);
       
  2402                     }
       
  2403                 else
       
  2404                     {
       
  2405                     MPX_DEBUG1("Unable to print table");
       
  2406                     }
       
  2407                 }
       
  2408             }
       
  2409         tableNames.Close();
       
  2410 
       
  2411         // Each attached drive
       
  2412         TInt count(iDatabaseHandles.Count());
       
  2413         for (TInt i = 0; i < count; ++i)
       
  2414             {
       
  2415             if (iDatabaseHandles[i].iOpen)
       
  2416                 {
       
  2417                 FindAllTablesL(iDatabaseHandles[i].iAliasname->Des(), tableNames);
       
  2418 
       
  2419                 TDriveUnit driveUnit(iDatabaseHandles[i].iDrive);
       
  2420                 const   TDesC& name = driveUnit.Name();
       
  2421                 MPX_DEBUG2("### Drive %S ###", &name);
       
  2422 
       
  2423                 for (TInt j = 0; j < tableCount; ++j)
       
  2424                     {
       
  2425                     MPX_DEBUG2("# %S #", tableNames[j]);
       
  2426                     MPX_TRAPD(error, PrintTableL(iDatabaseHandles[i].iAliasname->Des(), *tableNames[j]));
       
  2427                     delete tableNames[j];
       
  2428                     if (error != KErrNone)
       
  2429                         {
       
  2430                         if (error != KErrPermissionDenied)
       
  2431                             {
       
  2432                             User::Leave(error);
       
  2433                             }
       
  2434                         else
       
  2435                             {
       
  2436                             MPX_DEBUG1("Unable to print table");
       
  2437                             }
       
  2438                         }
       
  2439                     }
       
  2440                 tableNames.Close();
       
  2441                 }
       
  2442             }
       
  2443         }
       
  2444 #endif
       
  2445     }
       
  2446 
       
  2447 // ----------------------------------------------------------------------------
       
  2448 // Prints all the tables on the main and attached drives
       
  2449 // ----------------------------------------------------------------------------
       
  2450 //
       
  2451 EXPORT_C RFs& CMPXDbManager::Fs()
       
  2452     {
       
  2453     return iFs;
       
  2454     }
       
  2455 
       
  2456 
       
  2457 
       
  2458 // ---------------------------------------------------------------------------
       
  2459 // CMPXDbManager::IsRemoteDrive
       
  2460 // ---------------------------------------------------------------------------
       
  2461 //
       
  2462 EXPORT_C TBool CMPXDbManager::IsRemoteDrive(TDriveNumber aDrive)
       
  2463     {
       
  2464     TDriveInfo driveInfo;
       
  2465     TBool isRemoteDrive(EFalse);
       
  2466     if (iFs.Drive(driveInfo, aDrive) == KErrNone)
       
  2467         {
       
  2468         isRemoteDrive = driveInfo.iDriveAtt & KDriveAttRemote;
       
  2469         }
       
  2470     return isRemoteDrive;
       
  2471     }
       
  2472 
       
  2473 // ---------------------------------------------------------------------------
       
  2474 // CMPXDbManager::DoCreateDatabaseL
       
  2475 // ---------------------------------------------------------------------------
       
  2476 //
       
  2477 void CMPXDbManager::DoCreateDatabaseL( TDriveUnit aDrive )
       
  2478     {
       
  2479 	MPX_FUNC( "CMPXDbManager::DoCreateDatabaseL" );
       
  2480 	
       
  2481     RSqlDatabase database;
       
  2482     CleanupClosePushL(database);
       
  2483 
       
  2484     HBufC* filename = CreateFilenameL(aDrive);
       
  2485     CleanupStack::PushL(filename);
       
  2486     
       
  2487     // remove old databases before creating/replacing new database
       
  2488     TInt driveNameLen = aDrive.Name().Length();
       
  2489     
       
  2490     TFileName dbFileName;
       
  2491 
       
  2492 #ifdef __RAMDISK_PERF_ENABLE
       
  2493     TInt index(GetDatabaseIndex((TInt)aDrive));
       
  2494     if( index >= 0 && iDatabaseHandles[index].iUseRAMdb )
       
  2495         {
       
  2496         dbFileName.Append(iRAMDrive); // RAM
       
  2497         dbFileName.Append(_L(":")); // RAM
       
  2498         }
       
  2499     else 
       
  2500 #endif //__RAMDISK_PERF_ENABLE
       
  2501         {
       
  2502         MPX_DEBUG1("CMPXDbManager::CreateDatabaseL - E:");
       
  2503         dbFileName.Append(aDrive.Name()); //initialise with drive name
       
  2504         }
       
  2505         
       
  2506 
       
  2507     MPX_DEBUG2("CMPXDbManager::CreateDatabaseL - dbFileName=%S", &dbFileName);
       
  2508     dbFileName.Append(KDBFilePath);  // append private path
       
  2509     
       
  2510     //append file name
       
  2511     dbFileName.Append(filename->Right((filename->Length())- driveNameLen));     
       
  2512     
       
  2513     // locate the offset position where version info starts in file name
       
  2514     TInt pos = dbFileName.LocateReverse('v');
       
  2515 
       
  2516     //replace version info with wildcards 
       
  2517     dbFileName.Replace(pos, (dbFileName.Length()- pos), KDBFilePattern);
       
  2518 
       
  2519     CFileMan* fileManager = CFileMan::NewL(iFs);
       
  2520     TInt ret = fileManager->Delete(dbFileName);
       
  2521     delete fileManager;
       
  2522     fileManager = NULL;
       
  2523     
       
  2524     // create the database now
       
  2525     RSqlSecurityPolicy securityPolicy;
       
  2526     CleanupClosePushL(securityPolicy);
       
  2527 
       
  2528     TSecurityPolicy policy(TSecurityPolicy::EAlwaysPass);
       
  2529     securityPolicy.Create(policy);
       
  2530 
       
  2531     TSecurityPolicy schemaPolicy(TSecurityPolicy::EAlwaysPass);
       
  2532     TSecurityPolicy readPolicy(TSecurityPolicy::EAlwaysPass);
       
  2533     TSecurityPolicy writePolicy(TSecurityPolicy::EAlwaysPass);
       
  2534 
       
  2535     User::LeaveIfError(securityPolicy.SetDbPolicy(RSqlSecurityPolicy::ESchemaPolicy, schemaPolicy));
       
  2536     User::LeaveIfError(securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EReadPolicy, readPolicy));
       
  2537     User::LeaveIfError(securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EWritePolicy, writePolicy));
       
  2538 
       
  2539     
       
  2540     const TDesC8& config = KMCSqlConfig;
       
  2541     
       
  2542     TBool corrupt(EFalse);
       
  2543     TInt err = database.Create(filename->Des(), securityPolicy, &config);
       
  2544     if (KErrAlreadyExists == err)
       
  2545         {
       
  2546         MPX_DEBUG1("CMPXDbManager::DoCreateDatabaseL - could not create the database");
       
  2547 
       
  2548         // the file already exists and it is corrupted
       
  2549         // make sure we delete the file
       
  2550         User::LeaveIfError(database.Delete(*filename));
       
  2551 
       
  2552         MPX_DEBUG1("CMPXDbManager::DoCreateDatabaseL - deleted the database");
       
  2553 
       
  2554         // try again
       
  2555         err = database.Create(filename->Des(), securityPolicy, &config);
       
  2556 
       
  2557         // the database could not be opened but the file exists
       
  2558         corrupt = ETrue;
       
  2559         }
       
  2560     User::LeaveIfError(err);
       
  2561 
       
  2562     MPX_DEBUG1("CMPXDbManager::DoCreateDatabaseL - created the database");
       
  2563 
       
  2564     CleanupStack::PopAndDestroy(&securityPolicy);
       
  2565 
       
  2566     CreateTablesL(database, corrupt);
       
  2567 
       
  2568     CleanupStack::PopAndDestroy(filename);
       
  2569     CleanupStack::PopAndDestroy(&database);
       
  2570     }
       
  2571 	
       
  2572 // ---------------------------------------------------------------------------
       
  2573 // CMPXDbManager::GetRAMDiskPath
       
  2574 // ---------------------------------------------------------------------------
       
  2575 //
       
  2576 TInt CMPXDbManager::GetRAMDiskPath()
       
  2577     {
       
  2578     TInt error = KErrNotSupported;
       
  2579 #ifdef __RAMDISK_PERF_ENABLE
       
  2580     MPX_DEBUG1("-->CMPXDbManager::GetRAMDiskPath");
       
  2581     TDriveList driveList;
       
  2582     TBool ramDriveFound = EFalse;
       
  2583     TInt driveOffset = 'A';
       
  2584     iRAMFolder.Zero();
       
  2585     
       
  2586     error = iFs.DriveList( driveList );
       
  2587     if ( error == KErrNone )
       
  2588         {
       
  2589         for ( TInt i = 0; i < driveList.Length(); i++ )
       
  2590             {
       
  2591             if ( driveList[i] != 0 )
       
  2592                 {
       
  2593                 TDriveInfo info;
       
  2594                 TInt err = iFs.Drive( info, i );
       
  2595                 if ( !err && info.iType == EMediaRam )
       
  2596                     {
       
  2597                     iRAMDrive = driveOffset + i;
       
  2598                     iRAMFolder.Append(iRAMDrive);
       
  2599                     iRAMFolder.Append(_L(":"));
       
  2600                     iRAMFolder.Append(KDBFilePath);
       
  2601                     ramDriveFound = ETrue;
       
  2602                     MPX_DEBUG2("RAMDisk path=%S", &iRAMFolder);
       
  2603                     break;
       
  2604                     }
       
  2605                 }
       
  2606             }
       
  2607         
       
  2608         // Check if ram drive is found.
       
  2609         if ( !ramDriveFound )
       
  2610             {
       
  2611             error = KErrNotFound;
       
  2612             }
       
  2613         }
       
  2614     MPX_DEBUG2("CMPXDbManager::GetRAMDiskPath Get DriveList error=%d", error);
       
  2615     MPX_DEBUG1("<--CMPXDbManager::GetRAMDiskPath");
       
  2616 #endif //__RAMDISK_PERF_ENABLE
       
  2617     return error;
       
  2618     }
       
  2619 
       
  2620 // ---------------------------------------------------------------------------
       
  2621 // CMPXDbManager::IsRamDiskSpaceAvailable
       
  2622 // ---------------------------------------------------------------------------
       
  2623 //
       
  2624 TBool CMPXDbManager::IsRamDiskSpaceAvailable()
       
  2625     {
       
  2626 
       
  2627 #ifdef __RAMDISK_PERF_ENABLE
       
  2628 
       
  2629     MPX_DEBUG1("-->CMPXDbManager::IsDiskSpaceAvailable" );
       
  2630     TInt driveIndex;
       
  2631     RFs::CharToDrive(iRAMDrive, driveIndex);
       
  2632     TVolumeInfo vol;
       
  2633     TInt err = iFs.Volume( vol, driveIndex );
       
  2634     if ( err == KErrNone )
       
  2635         {
       
  2636         MPX_DEBUG2("CMPXDbManager::IsRamDiskSpaceAvailable Free in bytes =%Lu", vol.iFree);
       
  2637         if ( vol.iFree > KMPMinimumRAMSizeToRun )
       
  2638             {
       
  2639             MPX_DEBUG1("CMPXDbManager::IsRamDiskSpaceAvailable Ok to copy");
       
  2640             return ETrue;
       
  2641             }
       
  2642         MPX_DEBUG1("CMPXDbManager::IsRamDiskSpaceAvailable NOT Ok to copy");
       
  2643         return EFalse;
       
  2644         }
       
  2645     
       
  2646     MPX_DEBUG2("CMPXDbManager::IsRamDiskSpaceAvailable Disk Not available to use. %d", err);
       
  2647     MPX_DEBUG1("<--CMPXDbManager::IsDiskSpaceAvailable");
       
  2648 
       
  2649 #endif //__RAMDISK_PERF_ENABLE
       
  2650 
       
  2651     return EFalse;
       
  2652     }
       
  2653 
       
  2654 
       
  2655 // ---------------------------------------------------------------------------
       
  2656 // CMPXDbManager::BlockDiskSpaceL
       
  2657 // ---------------------------------------------------------------------------
       
  2658 //
       
  2659 TBool CMPXDbManager::BlockDiskSpace( TInt aIndex, TBool aIsMTPInUse )
       
  2660     {
       
  2661 #ifdef __RAMDISK_PERF_ENABLE
       
  2662 
       
  2663     MPX_DEBUG2("-->CMPXDbManager::BlockDiskSpaceL %d", aIndex );
       
  2664     DatabaseHandle & database = iDatabaseHandles[aIndex];    
       
  2665     // if current DB size can not fit in RAM, abort now
       
  2666     TInt ramDrive;
       
  2667     RFs::CharToDrive(iRAMDrive, ramDrive);
       
  2668     TVolumeInfo vol;
       
  2669     TInt err = iFs.Volume( vol, ramDrive );
       
  2670     TEntry origDb;
       
  2671     iFs.Entry( *database.iOrigFullFilePath, origDb );
       
  2672     if ( vol.iFree <= origDb.iSize + KMPMinimumRAMSizeToRun )
       
  2673         {
       
  2674         MPX_DEBUG1("-->CMPXDbManager::BlockDiskSpaceL Not enough even for copy original DB file, leave" );
       
  2675         return EFalse;
       
  2676         }
       
  2677 
       
  2678     // ensure you have the disk volume and database
       
  2679     err = iFs.Volume( vol, database.iDrive );
       
  2680     if (err != KErrNone) 
       
  2681         {
       
  2682         MPX_DEBUG2("CMPXDbManager::BlockDiskSpaceL Volume not available on drive %d", database.iDrive);
       
  2683         return EFalse;
       
  2684         }
       
  2685 
       
  2686     // Check if the drive has enough space to block
       
  2687     MPX_DEBUG2("CMPXDbManager::BlockDiskSpaceL Disk total free space in bytes =%Lu", vol.iFree);
       
  2688     TInt64 blockingSize( CalculateInitalDummyDBSize( vol, origDb.iSize, aIsMTPInUse ));
       
  2689     MPX_DEBUG2("CMPXDbManager::BlockDiskSpaceL Disk blocking size =%Lu", blockingSize);
       
  2690     if ( vol.iFree <= blockingSize + 1*KMPMegaByte )
       
  2691         {
       
  2692         MPX_DEBUG1("CMPXDbManager::BlockDiskSpaceL NOk to block");
       
  2693         return EFalse;
       
  2694         }
       
  2695 
       
  2696     // Create and resize the dummy file
       
  2697     TChar ch;
       
  2698     RFs::DriveToChar(database.iDrive, ch );
       
  2699     database.iDummyFilePath.Format( KDummyDbFile, (TUint)ch);
       
  2700     RFile dummyDb;
       
  2701     err = dummyDb.Replace( iFs, database.iDummyFilePath, EFileWrite );
       
  2702     if (err != KErrNone) 
       
  2703         {
       
  2704         MPX_DEBUG2("CMPXDbManager::BlockDiskSpaceL Can't open dummy file %d", err);
       
  2705         database.iDummyFilePath.Zero();
       
  2706         return EFalse;
       
  2707         }
       
  2708     err = dummyDb.SetSize( blockingSize );
       
  2709     if ( err )
       
  2710         {
       
  2711         MPX_DEBUG2("CMPXDbManager::BlockDiskSpaceL Can't resize dummy file %d", err);
       
  2712         dummyDb.Close();
       
  2713         RemoveDummyFile(aIndex);
       
  2714         return EFalse;
       
  2715         }
       
  2716 
       
  2717     dummyDb.Close();
       
  2718     MPX_DEBUG1("CMPXDbManager::BlockDiskSpaceL Ok to block");
       
  2719     MPX_DEBUG1("<--CMPXDbManager::BlockDiskSpace");
       
  2720 
       
  2721     return ETrue;
       
  2722 #else
       
  2723     return EFalse;
       
  2724 #endif //__RAMDISK_PERF_ENABLE
       
  2725     }
       
  2726 
       
  2727 
       
  2728 // ---------------------------------------------------------------------------
       
  2729 // CMPXDbManager::CalculateInitalDummyDBSizeL
       
  2730 //
       
  2731 //a) MTP case
       
  2732 //-------------
       
  2733 //        totalNumOfSongsCanFit = <disk free space> / 2 MB;
       
  2734 //        metadataSize = totalNumOfSongsCanFit * 3000B 
       
  2735 //        estimatedDBSize = metadataSize + <orig DB size>;
       
  2736 //        dummyDBSize = MIN (iMaximumAllowedRAMDiskSpaceToCopy , estimatedDBSize )
       
  2737 
       
  2738 //b) Harvesting case
       
  2739 //-------------------
       
  2740 //        totalNumOfSongsCanFit = <disk total size>/ 2 MB
       
  2741 //        metadataSize = totalNumOfSongsCanFit * 3000B 
       
  2742 //        estimatedSize = metadataSize+ <orig DB size>
       
  2743 //        freeDiskSpace = <disk free space> - 1 MB
       
  2744 //        dummyDBSize = MIN (freeDiskSpace, iMaximumAllowedRAMDiskSpaceToCopy , estimatedSize);
       
  2745 //
       
  2746 // ---------------------------------------------------------------------------
       
  2747 //
       
  2748 TInt64 CMPXDbManager::CalculateInitalDummyDBSize( const TVolumeInfo& aVol, TInt aOrigDbSize, TBool aIsMTPInUse )
       
  2749     {
       
  2750 #ifdef __RAMDISK_PERF_ENABLE
       
  2751     MPX_DEBUG1("-->CMPXDbManager::CalculateInitalDummyDBSize");
       
  2752 
       
  2753     if ( aIsMTPInUse )
       
  2754         {
       
  2755         TInt64 totalNumOfSongsCanFit = aVol.iFree / KMPEstimatedSongInBytes;
       
  2756         MPX_DEBUG2("-->CMPXDbManager::CalculateInitalDummyDBSize aVol.iFree=%Lu", aVol.iFree );
       
  2757         MPX_DEBUG2("-->CMPXDbManager::CalculateInitalDummyDBSize totalNumOfSongsCanFit=%Lu", totalNumOfSongsCanFit );
       
  2758         TInt64 estimatedSize = totalNumOfSongsCanFit * (TInt64) KMPEstimatedSizePerDBEntry + aOrigDbSize;
       
  2759         MPX_DEBUG2("-->CMPXDbManager::CalculateInitalDummyDBSize (MTP case) estimated DB size from calculation=%Lu", estimatedSize );
       
  2760         if ( estimatedSize > iMaximumAllowedRAMDiskSpaceToCopy )
       
  2761             {
       
  2762             MPX_DEBUG2("<--CMPXDbManager::CalculateInitalDummyDBSize returned iMaximumAllowedRAMDiskSpaceToCopy %d", iMaximumAllowedRAMDiskSpaceToCopy);
       
  2763             return iMaximumAllowedRAMDiskSpaceToCopy;
       
  2764             }
       
  2765         else
       
  2766             {
       
  2767             MPX_DEBUG2("<--CMPXDbManager::CalculateInitalDummyDBSize returned %Lu", estimatedSize );
       
  2768             return estimatedSize;
       
  2769             }
       
  2770         }
       
  2771     else
       
  2772         {
       
  2773         TInt64 totalNumOfSongsCanFit = aVol.iSize / KMPEstimatedSongInBytes;
       
  2774         TInt64 estimatedSize = totalNumOfSongsCanFit * (TInt64) KMPEstimatedSizePerDBEntry + aOrigDbSize;
       
  2775         MPX_DEBUG2("-->CMPXDbManager::CalculateInitalDummyDBSize estimated DB size from calculation=%Lu", estimatedSize );
       
  2776         if ( estimatedSize > iMaximumAllowedRAMDiskSpaceToCopy )
       
  2777             {
       
  2778             MPX_DEBUG1("<--CMPXDbManager::CalculateInitalDummyDBSize");
       
  2779             // If estimated size is larger than expected free RAM size, 
       
  2780             // and if the RAM size is larger than free disk space,
       
  2781             // then use free disk space. 1*KMPMegaByte prevent MP to use up all diskspace
       
  2782             //return iMaximumAllowedRAMDiskSpaceToCopy > aVol.iFree - 1*KMPMegaByte  
       
  2783             //    ? aVol.iFree - 1*KMPMegaByte : iMaximumAllowedRAMDiskSpaceToCopy;
       
  2784             return iMaximumAllowedRAMDiskSpaceToCopy;
       
  2785             }
       
  2786         else
       
  2787             {
       
  2788             MPX_DEBUG1("<--CMPXDbManager::CalculateInitalDummyDBSize");
       
  2789             // If estimated size is larger than disk free size, use free diskspace size,            
       
  2790             //return estimatedSize > aVol.iFree - 1*KMPMegaByte
       
  2791             //    ? aVol.iFree - 1*KMPMegaByte : estimatedSize;
       
  2792             return estimatedSize;
       
  2793             }
       
  2794         }
       
  2795     
       
  2796 #endif //__RAMDISK_PERF_ENABLE    
       
  2797     }
       
  2798     
       
  2799 
       
  2800 // ---------------------------------------------------------------------------
       
  2801 // CMPXDbManager::GetDatabaseIndex
       
  2802 // ---------------------------------------------------------------------------
       
  2803 //
       
  2804 TInt CMPXDbManager::GetDatabaseIndex(TInt aDrive) 
       
  2805     {
       
  2806 #ifdef __RAMDISK_PERF_ENABLE
       
  2807     MPX_DEBUG2("-->CMPXDbManager::GetDatabaseIndex %d", aDrive );
       
  2808     TInt count(iDatabaseHandles.Count());
       
  2809     for (TInt i = 0; i < count; ++i)
       
  2810         {
       
  2811         if ( iDatabaseHandles[i].iDrive == aDrive )
       
  2812             {
       
  2813             return i;
       
  2814             }
       
  2815         }    
       
  2816 #endif //__RAMDISK_PERF_ENABLE    
       
  2817     MPX_DEBUG1("<--CMPXDbManager::GetDatabaseIndex returned -1");
       
  2818     return -1;
       
  2819     }
       
  2820 
       
  2821 
       
  2822 // ---------------------------------------------------------------------------
       
  2823 // CMPXDbManager::EnsureRamSpaceL
       
  2824 // ---------------------------------------------------------------------------
       
  2825 //
       
  2826 EXPORT_C void CMPXDbManager::EnsureRamSpaceL() 
       
  2827     {
       
  2828 #ifdef __RAMDISK_PERF_ENABLE
       
  2829     MPX_DEBUG1("-->CMPXDbManager::EnsureRamSpaceL");
       
  2830 
       
  2831     if ( iRAMInUse )
       
  2832         {
       
  2833         TVolumeInfo vol;
       
  2834         TInt driveIndex;
       
  2835         RFs::CharToDrive( iRAMDrive, driveIndex );
       
  2836 
       
  2837         TInt errRAM = iFs.Volume( vol, driveIndex );
       
  2838         if ( errRAM == KErrNone && vol.iFree < KMPMinimumRAMSizeToRun )
       
  2839             {
       
  2840             // RAM not enough, copy back to normal drive and continue to harvest.
       
  2841             MPX_DEBUG1("CMPXDbManager::EnsureRamSpaceL RAM diskspace is full, copy dbs back");
       
  2842             CopyDBsFromRamL();
       
  2843             }
       
  2844         else
       
  2845             {
       
  2846             TInt size=0;
       
  2847             TInt err = GetTotalRamDatabasesSizeL(size);
       
  2848             if ( err || (size > iMaximumAllowedRAMDiskSpaceToCopy) )
       
  2849                 {
       
  2850                 // Databases using too much RAM space, copy back to normal drive and continue to harvest.
       
  2851                 if ( err )
       
  2852                     {
       
  2853                     MPX_DEBUG2("CMPXDbManager::EnsureRamSpaceL Get DBs Size Err = %d, copy dbs back", err);
       
  2854                     }
       
  2855                 else
       
  2856                     {
       
  2857                     MPX_DEBUG2("CMPXDbManager::EnsureRamSpaceL DBs using too much RAM space size = %d, copy dbs back", size);
       
  2858                     }
       
  2859                 CopyDBsFromRamL();
       
  2860                 }
       
  2861             }
       
  2862         }
       
  2863     MPX_DEBUG1("<--CMPXDbManager::EnsureRamSpaceL");
       
  2864 #endif //__RAMDISK_PERF_ENABLE    
       
  2865     }
       
  2866 
       
  2867 
       
  2868 // ---------------------------------------------------------------------------
       
  2869 // CMPXDbManager::EnsureDiskSpaceL
       
  2870 // ---------------------------------------------------------------------------
       
  2871 //
       
  2872 void CMPXDbManager::EnsureDiskSpaceL(TInt aDrive) 
       
  2873     {
       
  2874     MPX_DEBUG2("-->CMPXDbManager::EnsureDiskSpaceL for drive %d", aDrive);
       
  2875     // handle the case of C drive
       
  2876     TDriveUnit drive(aDrive);
       
  2877     TDriveUnit cdrive(KRootDrive());
       
  2878 
       
  2879     if(drive == cdrive)
       
  2880         {
       
  2881         if (SysUtil::DiskSpaceBelowCriticalLevelL(&iFs, 0, aDrive))
       
  2882             {
       
  2883             MPX_DEBUG1("CMPXDbManager::EnsureDiskSpaceL Error diskspace full");
       
  2884             User::Leave(KErrDiskFull);
       
  2885             }
       
  2886 
       
  2887         return;
       
  2888         }
       
  2889 
       
  2890     // handle other drives (eg. removable EDriveE)
       
  2891     TInt count(iDatabaseHandles.Count());
       
  2892     for (TInt i = 0; i < count; ++i)
       
  2893         {
       
  2894         DatabaseHandle& database = iDatabaseHandles[i];
       
  2895         if (((KDbManagerAllDrives == aDrive) ||
       
  2896             (aDrive == database.iDrive)) &&
       
  2897             database.iOpen
       
  2898 #ifdef __RAMDISK_PERF_ENABLE
       
  2899             && !database.iUseRAMdb
       
  2900 #endif
       
  2901             )
       
  2902             {
       
  2903             if (SysUtil::DiskSpaceBelowCriticalLevelL(&iFs, 0,
       
  2904                 database.iDrive))
       
  2905                 {
       
  2906                 MPX_DEBUG1("CMPXDbManager::EnsureDiskSpaceL Error diskspace full");
       
  2907                 User::Leave(KErrDiskFull);
       
  2908                 }
       
  2909             }
       
  2910 
       
  2911         if (aDrive == database.iDrive)
       
  2912             {
       
  2913             // exit if just one drive to check
       
  2914             break;
       
  2915             }
       
  2916         }
       
  2917     MPX_DEBUG1("<--CMPXDbManager::EnsureDiskSpaceL");
       
  2918     }
       
  2919 
       
  2920 
       
  2921 // ---------------------------------------------------------------------------
       
  2922 // CMPXDbManager::DoBackupDBs
       
  2923 // ---------------------------------------------------------------------------
       
  2924 //
       
  2925 /*EXPORT_C void CMPXDbManager::BackupDBsL()
       
  2926     {
       
  2927 #ifdef __RAMDISK_PERF_ENABLE
       
  2928     MPX_DEBUG1("-->CMPXDbManager::BackupDBsL");
       
  2929 
       
  2930     TInt transactionCount = iTransactionCount;
       
  2931     if (iTransactionCount > 0) 
       
  2932         {
       
  2933         iTransactionCount = 0;
       
  2934         DoCommitL();
       
  2935         }
       
  2936     
       
  2937     TInt count(iDatabaseHandles.Count());
       
  2938     for (TInt i = 0; i < count && iDatabaseHandles[i].iUseRAMdb ; ++i)
       
  2939         {
       
  2940         CloseDatabaseAtIndexL( i );            
       
  2941 
       
  2942         TInt err= BaflUtils::CopyFile(iFs, 
       
  2943             iDatabaseHandles[i].iTargetFullFilePath->Des(), 
       
  2944             iDatabaseHandles[i].iOrigFullFilePath->Des());
       
  2945 
       
  2946         MPX_DEBUG2("CMPXDbManager::BackupDBsL err = %d", err);     
       
  2947 
       
  2948         OpenDatabaseAtIndexL( i );      
       
  2949         }
       
  2950         
       
  2951     if (transactionCount > 0) 
       
  2952         {
       
  2953         DoBeginL();
       
  2954         iTransactionCount = transactionCount;
       
  2955         }
       
  2956     MPX_DEBUG1("<--CMPXDbManager::BackupDBsL");
       
  2957 #endif //__RAMDISK_PERF_ENABLE    
       
  2958     }*/
       
  2959     
       
  2960 // ---------------------------------------------------------------------------
       
  2961 // CMPXDbManager::GetTotalDatabasesSize
       
  2962 // ---------------------------------------------------------------------------
       
  2963 //
       
  2964 TInt CMPXDbManager::GetTotalDatabasesSize(TInt& aSize)
       
  2965     {
       
  2966     MPX_FUNC("CMPXDbManager::GetTotalDatabasesSize");
       
  2967     TInt err = KErrNotSupported;
       
  2968 #ifdef __RAMDISK_PERF_ENABLE
       
  2969     TInt size=0;
       
  2970     TInt count(iDatabaseHandles.Count());
       
  2971     err = KErrNone;
       
  2972     for ( TInt i = 0; i < count ; ++i )
       
  2973         {
       
  2974         // Generate database name.
       
  2975         TFileName dbFilename;
       
  2976         TDriveUnit drive(iDatabaseHandles[i].iDrive);
       
  2977         dbFilename.Append(drive.Name());
       
  2978         dbFilename.Append(KDBFilePath);
       
  2979         TFileName filename;            
       
  2980         filename.Format(KSecurePath, User::Identity().iUid, iDbFile); //x:\private\10281e17\[sldfdsf]mpxv2_5.db
       
  2981         dbFilename.Append(filename);
       
  2982         MPX_DEBUG2("CMPXDbManager::GetTotalDatabasesSize - Database name = %S", &dbFilename);
       
  2983         TEntry entry;
       
  2984         err = iFs.Entry( dbFilename, entry );
       
  2985         if (err == KErrNotFound || err == KErrNotReady )
       
  2986             {
       
  2987             MPX_DEBUG3("CMPXDbManager::GetTotalDatabasesSize - Ignored %S, error = %d", &dbFilename, err);
       
  2988             err = KErrNone;
       
  2989             continue;
       
  2990             }
       
  2991         if ( err != KErrNone )
       
  2992             {
       
  2993             break;
       
  2994             }
       
  2995         MPX_DEBUG3("CMPXDbManager::GetTotalDatabasesSize - Size of Db %S = %d", &dbFilename, entry.iSize);
       
  2996         // sum up size
       
  2997         size += entry.iSize;
       
  2998         }
       
  2999     aSize = size;
       
  3000     MPX_DEBUG2("CMPXDbManager::GetTotalDatabasesSize - Total Size of Dbs = %d", size);
       
  3001     
       
  3002 #endif //__RAMDISK_PERF_ENABLE    
       
  3003     MPX_DEBUG2("CMPXDbManager::GetTotalDatabasesSize - Return err = %d", err);
       
  3004     return err;
       
  3005     }
       
  3006     
       
  3007 // ---------------------------------------------------------------------------
       
  3008 // CMPXDbManager::GetTotalRamDatabasesSize
       
  3009 // ---------------------------------------------------------------------------
       
  3010 //
       
  3011 TInt CMPXDbManager::GetTotalRamDatabasesSizeL(TInt& aSize)
       
  3012     {
       
  3013     MPX_FUNC("CMPXDbManager::GetTotalRamDatabasesSize");
       
  3014     TInt err = KErrNotSupported;
       
  3015 #ifdef __RAMDISK_PERF_ENABLE
       
  3016     TInt size=0;
       
  3017     TInt count(iDatabaseHandles.Count());
       
  3018     err = KErrNone;
       
  3019     for ( TInt i = 0; i < count ; ++i )
       
  3020         {
       
  3021         // make sure this db is in ram drive.
       
  3022         if ( !iDatabaseHandles[i].iUseRAMdb )
       
  3023             {
       
  3024             continue;
       
  3025             }
       
  3026         // Generate database name.
       
  3027         TFileName dbFilename;
       
  3028         dbFilename.Append(iRAMFolder);
       
  3029         TBuf<2> d;
       
  3030         TDriveUnit drive(iDatabaseHandles[i].iDrive);
       
  3031         d.Append(drive.Name());
       
  3032         HBufC* temp = HBufC::NewLC(KMaxFileName);
       
  3033         temp->Des().Append(d.Left(1));
       
  3034         temp->Des().Append(iDbFile->Des());
       
  3035         TFileName filename;            
       
  3036         filename.Format(KSecurePath, User::Identity().iUid, temp);
       
  3037         CleanupStack::PopAndDestroy(temp);
       
  3038         dbFilename.Append(filename);
       
  3039         MPX_DEBUG2("CMPXDbManager::GetTotalRamDatabasesSizeL - Database name = %S", &dbFilename);
       
  3040         TEntry entry;
       
  3041         err = iFs.Entry( dbFilename, entry );
       
  3042         if ( (err != KErrNone) && (err != KErrNotFound) )
       
  3043             {
       
  3044             break;
       
  3045             }
       
  3046         MPX_DEBUG3("CMPXDbManager::GetTotalRamDatabasesSizeL - Size of Db %S = %d", &dbFilename, entry.iSize);
       
  3047         // sum up size
       
  3048         size += entry.iSize;
       
  3049         }
       
  3050     aSize = size;
       
  3051     MPX_DEBUG2("CMPXDbManager::GetTotalRamDatabasesSizeL - Total Size of Dbs = %d", size);
       
  3052 #endif //__RAMDISK_PERF_ENABLE    
       
  3053     MPX_DEBUG2("CMPXDbManager::GetTotalRamDatabasesSizeL - Return err = %d", err);
       
  3054     return err;
       
  3055     }
       
  3056 
       
  3057 // ----------------------------------------------------------------------------
       
  3058 // Creates the absolute database filename on a specified drive.
       
  3059 // ----------------------------------------------------------------------------
       
  3060 //
       
  3061 HBufC* CMPXDbManager::CreateFullFilenameL(TDriveUnit aDrive)
       
  3062     {
       
  3063     MPX_FUNC("CMPXDbManager::CreateFullFilenameL");
       
  3064 
       
  3065     HBufC* filename = HBufC::NewL(KMaxFileName);
       
  3066     const TDesC& securefilePath = KSecureFilePath;
       
  3067     TDriveUnit cdrive(KRootDrive());
       
  3068 
       
  3069 #ifdef __RAMDISK_PERF_ENABLE
       
  3070     TInt index(GetDatabaseIndex((TInt)aDrive));    
       
  3071     if ( index >=0 && iDatabaseHandles[index].iUseRAMdb && aDrive != cdrive )
       
  3072         {
       
  3073         MPX_DEBUG1("CMPXDbManager::CreateFullFilenameL - use RAMDisk");
       
  3074         TFileName path;
       
  3075         path.Append(iRAMDrive);
       
  3076         path.Append(_L(":"));
       
  3077         path.Append(KDBFilePath);
       
  3078         TBuf<2> d;
       
  3079         d.Append(aDrive.Name());
       
  3080         TFileName temp;
       
  3081         temp.Append(d.Left(1)); // attach original drive name
       
  3082         temp.Append(iDbFile->Des()); 
       
  3083         filename->Des().Format(securefilePath, &path, User::Identity().iUid, &temp);
       
  3084         MPX_DEBUG3("CMPXDbManager::CreateFullFilenameL - path=%S filename=%S", &path, filename);
       
  3085         }
       
  3086     else
       
  3087 #endif //__RAMDISK_PERF_ENABLE
       
  3088         {
       
  3089         MPX_DEBUG1("CMPXDbManager::CreateFullFilenameL - use normal drive");
       
  3090         TFileName dbPath;
       
  3091         dbPath.Append(aDrive.Name());
       
  3092         dbPath.Append(KDBFilePath);
       
  3093         filename->Des().Format(securefilePath, &dbPath, User::Identity().iUid, iDbFile);
       
  3094         }
       
  3095     
       
  3096     MPX_DEBUG2("CMPXDbManager::CreateFullFilenameL filename = %S", filename); 
       
  3097     return filename;
       
  3098     }
       
  3099 
       
  3100 // End of File