mmappcomponents/harvester/filehandler/src/mpxharvesterdb.cpp
changeset 0 a2952bb97e68
child 9 bee149131e4b
equal deleted inserted replaced
-1:000000000000 0:a2952bb97e68
       
     1 /*
       
     2 * Copyright (c) 2006 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:  Database Class to the harvester db
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32base.h>
       
    20 #include <mpxlog.h>
       
    21 #include <bautils.h>
       
    22 #include "mpxharvesterdb.h"
       
    23 #include "mpxdbcommon.h"
       
    24 #include "mpxharvesterdbtable.h"
       
    25 
       
    26 // unlikely to have 50 quotes in a string
       
    27 const TInt KAdditionalStringLength = 50;
       
    28 
       
    29 // ---------------------------------------------------------------------------
       
    30 // C++ Constructor
       
    31 // ---------------------------------------------------------------------------
       
    32 //
       
    33 CMPXHarvesterDB::CMPXHarvesterDB( TDriveNumber aDrive, RFs& aFs  ) :
       
    34                                                              iDrive( aDrive),
       
    35                                                              iFs( aFs )
       
    36     {
       
    37     }
       
    38 
       
    39 
       
    40 // ---------------------------------------------------------------------------
       
    41 // 2nd Phase constructor
       
    42 // ---------------------------------------------------------------------------
       
    43 //
       
    44 void CMPXHarvesterDB::ConstructL()
       
    45     {
       
    46     // Nothing, have to call "OpenL()"
       
    47     }
       
    48 
       
    49 // ---------------------------------------------------------------------------
       
    50 // Two-Phased Constructor
       
    51 // ---------------------------------------------------------------------------
       
    52 //
       
    53 CMPXHarvesterDB* CMPXHarvesterDB::NewL( TDriveNumber aDrive, RFs& aFs   )
       
    54     {
       
    55     CMPXHarvesterDB* self = new( ELeave ) CMPXHarvesterDB( aDrive, aFs );
       
    56     CleanupStack::PushL( self );
       
    57     self->ConstructL();
       
    58     CleanupStack::Pop( self );
       
    59     return self;
       
    60     }
       
    61 
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // Destructor
       
    65 // ---------------------------------------------------------------------------
       
    66 //
       
    67 CMPXHarvesterDB::~CMPXHarvesterDB()
       
    68     {
       
    69     Close();
       
    70     }
       
    71 
       
    72 // ---------------------------------------------------------------------------
       
    73 // Open a database
       
    74 // ---------------------------------------------------------------------------
       
    75 //
       
    76 TInt CMPXHarvesterDB::OpenL()
       
    77     {
       
    78     MPX_DEBUG1("CMPXHarvesterDB::OpenL <---");
       
    79 
       
    80     // There is no need to re-open if it was already open
       
    81     if( iDBOpen )
       
    82         {
       
    83         return KErrNone;
       
    84         }
       
    85 
       
    86     TInt rtn( KErrNone );
       
    87     TDriveUnit drive( iDrive );
       
    88     TFileName fileName;
       
    89     fileName.Append( drive.Name() );
       
    90     fileName.Append( KHarvesterDBPath );
       
    91 
       
    92     // Make sure Path exists
       
    93     if (!BaflUtils::PathExists(iFs, fileName))
       
    94         {
       
    95         iFs.MkDirAll(fileName);
       
    96         }
       
    97 
       
    98     fileName.Append( KHarvesterDBName );
       
    99 
       
   100     // Try to open the stream
       
   101     TRAPD( err,
       
   102         iStore = CPermanentFileStore::OpenL(iFs, fileName ,EFileRead|EFileWrite);
       
   103         );
       
   104 
       
   105     // DB doesn't exist or error, replace it and recreate DB
       
   106     //
       
   107     if( err )
       
   108         {
       
   109         MPX_DEBUG2("CMPXHarvesterDB::OpenL -- New database %i", err);
       
   110 
       
   111         TRAPD( openErr,
       
   112             iStore = CPermanentFileStore::ReplaceL(iFs, fileName ,EFileRead|EFileWrite);
       
   113         	iStore->SetTypeL(iStore->Layout());
       
   114             CreateDBL();
       
   115             iDBOpen = ETrue;
       
   116             );
       
   117 
       
   118         if( KErrNone != openErr )
       
   119             {
       
   120             iDBOpen = EFalse;
       
   121             User::Leave( openErr );
       
   122             }
       
   123 
       
   124         // If the open stream error was not found, that is fine
       
   125         // because it is a new db, other errors means the stream
       
   126         // is corrupted
       
   127         //
       
   128         rtn = err!=KErrNotFound ? KErrCorrupt : KErrNone;
       
   129         }
       
   130     else
       
   131         {
       
   132         MPX_DEBUG1("CMPXHarvesterDB::OpenL -- Opening database" );
       
   133         rtn = OpenDBL();
       
   134         iDBOpen = ETrue;
       
   135         }
       
   136 
       
   137 
       
   138     // Check volume Id
       
   139     //
       
   140     TVolumeInfo volInfo;
       
   141     iFs.Volume(volInfo, iDrive);
       
   142     TUint volId(volInfo.iUniqueID);
       
   143 
       
   144     TUint uniqueId(0);
       
   145     TRAPD( idErr, uniqueId = UniqueIdL() );
       
   146     if( idErr != KErrNone )
       
   147         {
       
   148         // Delete the database because this is not readable
       
   149         Close();
       
   150         User::LeaveIfError(DeleteDatabase());
       
   151         rtn = KErrCorrupt;
       
   152         }
       
   153     else if( volId != uniqueId )
       
   154         {
       
   155         // Recreate if volId doesn't match
       
   156         //
       
   157         MPX_DEBUG1("CMPXHarvesterDB::OpenL unmatched unique ID");
       
   158         Close();
       
   159         User::LeaveIfError(DeleteDatabase());
       
   160         rtn = OpenL();
       
   161         }
       
   162 
       
   163     MPX_DEBUG1("CMPXHarvesterDB::OpenL --->");
       
   164     return rtn;
       
   165     }
       
   166 
       
   167 // ---------------------------------------------------------------------------
       
   168 // Close a database
       
   169 // ---------------------------------------------------------------------------
       
   170 //
       
   171 void CMPXHarvesterDB::Close()
       
   172     {
       
   173     MPX_DEBUG1("CMPXHarvesterDB::Close <---");
       
   174 
       
   175     // Close the database and close the stream
       
   176     if( iDatabase )
       
   177         {
       
   178         iDatabase->Close();
       
   179         delete iDatabase;
       
   180         iDatabase = NULL;
       
   181         }
       
   182 
       
   183     delete iStore;
       
   184     iStore = NULL;
       
   185 
       
   186     iDBOpen = EFalse;
       
   187     MPX_DEBUG1("CMPXHarvesterDB::Close --->");
       
   188     }
       
   189 
       
   190 // ---------------------------------------------------------------------------
       
   191 // Create a new database
       
   192 // ---------------------------------------------------------------------------
       
   193 //
       
   194 void CMPXHarvesterDB::CreateDBL()
       
   195     {
       
   196     MPX_DEBUG1("CMPXHarvesterDB::CreateDBL <---");
       
   197 
       
   198     // remove old databases before creating/replacing new database
       
   199 
       
   200     TFileName dbFileName;
       
   201     TDriveUnit drive( iDrive );
       
   202     dbFileName.Append( drive.Name() );
       
   203     dbFileName.Append( KHarvesterDBPath );
       
   204     dbFileName.Append( KHarvesterDBPattern );
       
   205     
       
   206     CFileMan* fileManager = CFileMan::NewL(iFs);
       
   207     TInt ret = fileManager->Delete(dbFileName);	
       
   208     delete fileManager;
       
   209     fileManager = NULL;
       
   210 
       
   211 
       
   212     //Create the database
       
   213     //
       
   214     iDatabase = new( ELeave ) RDbStoreDatabase();
       
   215     TStreamId id(0);
       
   216     id = iDatabase->CreateL( iStore );
       
   217 
       
   218     iStore->SetRootL(id);
       
   219     iStore->CommitL();
       
   220 
       
   221     // Define the columns
       
   222     // "Create table files ( PathName, FileName, LastModTime, Col ID )"
       
   223     //
       
   224     TBuf<KDbMaxTableCreationSQLLength> query;
       
   225     query.Append( KStartCreateTable );
       
   226     query.Append( KHarvesterMainTable );
       
   227 
       
   228     query.Append(KOpenBracket);
       
   229 
       
   230     query.Append(KHarPathName);
       
   231     query.Append(KHarPathNameType);
       
   232     query.Append(KCommaSign);
       
   233 
       
   234     query.Append(KHarFileName);
       
   235     query.Append(KHarFileNameType);
       
   236     query.Append(KCommaSign);
       
   237 
       
   238     query.Append(KHarLastModTime);
       
   239     query.Append(KHarLastModTimeType);
       
   240     query.Append(KCommaSign);
       
   241 
       
   242     query.Append(KHarCollectionDB);
       
   243     query.Append(KHarColDBIDType);
       
   244     query.Append(KCommaSign);
       
   245 
       
   246     query.Append(KHarItemDRM);
       
   247     query.Append(KHarItemDRMType);
       
   248 
       
   249     query.Append(KCloseBracket);
       
   250 
       
   251     // Execute the query
       
   252     User::LeaveIfError( iDatabase->Execute( query ) );
       
   253 
       
   254     // Add an auxiliary table with the volume id
       
   255     // This is to make sure the user doesn't copy a db from another phone
       
   256     // "Create table aux { volumeid }"
       
   257     //
       
   258     query = KNullDesC;
       
   259     query.Append( KStartCreateTable );
       
   260     query.Append( KHarvesterAuxTable);
       
   261 
       
   262     query.Append(KOpenBracket);
       
   263     query.Append(KAuxVolumeId);
       
   264     query.Append(KAuxVolumeIdType);
       
   265     query.Append(KCloseBracket);
       
   266 
       
   267     User::LeaveIfError( iDatabase->Execute( query ) );
       
   268 
       
   269     // Default aux volume id entry
       
   270     //
       
   271     TVolumeInfo volInfo;
       
   272     iFs.Volume(volInfo, iDrive);
       
   273     TUint volId(volInfo.iUniqueID);
       
   274 
       
   275     query = KNullDesC;
       
   276     query.AppendFormat(KAuxVolumeIdQuery, volId);
       
   277     User::LeaveIfError( iDatabase->Execute( query ) );
       
   278     MPX_DEBUG2("CMPXHarvesterDB::CreateDBL 4a %S", &query);
       
   279 
       
   280     MPX_DEBUG1("CMPXHarvesterDB::CreateDBL --->");
       
   281     }
       
   282 
       
   283 // ---------------------------------------------------------------------------
       
   284 // Open an existing database
       
   285 // ---------------------------------------------------------------------------
       
   286 //
       
   287 TInt CMPXHarvesterDB::OpenDBL()
       
   288     {
       
   289     MPX_DEBUG1("CMPXHarvesterDB::OpenDBL <---");
       
   290     TInt rtn( KErrNone );
       
   291 
       
   292     // Open the database
       
   293     if( !iDBOpen )
       
   294         {
       
   295         iDatabase = new( ELeave ) RDbStoreDatabase(); //lint !e423
       
   296 
       
   297         // Unable to open db, so try to re-create
       
   298         //
       
   299         TRAPD(err, iDatabase->OpenL( iStore, iStore->Root() ) );
       
   300         if( err != KErrNone )
       
   301             {
       
   302             delete iDatabase;
       
   303             iDatabase = NULL;
       
   304             CreateDBL();
       
   305             rtn = KErrCorrupt;
       
   306             }
       
   307         }
       
   308 
       
   309     MPX_DEBUG1("CMPXHarvesterDB::OpenDBL --->");
       
   310     return rtn;
       
   311     }
       
   312 
       
   313 // ---------------------------------------------------------------------------
       
   314 // Get the current drive
       
   315 // ---------------------------------------------------------------------------
       
   316 //
       
   317 TDriveNumber CMPXHarvesterDB::GetDbDrive()
       
   318     {
       
   319     return iDrive;
       
   320     }
       
   321 
       
   322 // ---------------------------------------------------------------------------
       
   323 // Creates a table to all items
       
   324 // ---------------------------------------------------------------------------
       
   325 //
       
   326 CMPXHarvesterDatabaseTable* CMPXHarvesterDB::OpenAllFilesTableL()
       
   327     {
       
   328     // Database isn't opened, leave
       
   329     if( iDBOpen == EFalse )
       
   330         {
       
   331         User::Leave(KErrNotReady);
       
   332         }
       
   333 
       
   334     // Open the table
       
   335     CMPXHarvesterDatabaseTable* table =
       
   336                                CMPXHarvesterDatabaseTable::NewLC( *iDatabase );
       
   337     table->OpenAllFilesTableL();
       
   338     CleanupStack::Pop( table );
       
   339     return table;
       
   340     }
       
   341 
       
   342 // ---------------------------------------------------------------------------
       
   343 // Creates a table to a directory
       
   344 // ---------------------------------------------------------------------------
       
   345 //
       
   346 CMPXHarvesterDatabaseTable* CMPXHarvesterDB::OpenDirectoryL( const TDesC& aDir )
       
   347     {
       
   348     // Database isn't opened, leave
       
   349     if( iDBOpen == EFalse )
       
   350         {
       
   351         User::Leave(KErrNotReady);
       
   352         }
       
   353 
       
   354     // Open the table
       
   355     CMPXHarvesterDatabaseTable* table =
       
   356                                CMPXHarvesterDatabaseTable::NewLC( *iDatabase );
       
   357     table->OpenDirectoryL( aDir );
       
   358     CleanupStack::Pop( table );
       
   359     return table;
       
   360     }
       
   361 
       
   362 // ---------------------------------------------------------------------------
       
   363 // Creates a table to a specific song
       
   364 // ---------------------------------------------------------------------------
       
   365 //
       
   366 CMPXHarvesterDatabaseTable* CMPXHarvesterDB::OpenFileL( const TDesC& aFile )
       
   367     {
       
   368     // Database isn't opened, leave
       
   369     if( iDBOpen == EFalse )
       
   370         {
       
   371         User::Leave(KErrNotReady);
       
   372         }
       
   373 
       
   374     // Open the table
       
   375     CMPXHarvesterDatabaseTable* table =
       
   376                                CMPXHarvesterDatabaseTable::NewLC( *iDatabase );
       
   377     table->OpenItemL( aFile );
       
   378     CleanupStack::Pop( table );
       
   379     return table;
       
   380     }
       
   381 
       
   382 // ---------------------------------------------------------------------------
       
   383 // Creates a table to open to all files with DRM flag set
       
   384 // ---------------------------------------------------------------------------
       
   385 //    
       
   386 CMPXHarvesterDatabaseTable* CMPXHarvesterDB::OpenDrmFileL()
       
   387     {
       
   388     // Database isn't opened, leave 
       
   389     if( iDBOpen == EFalse )
       
   390         {
       
   391         User::Leave(KErrNotReady);
       
   392         }
       
   393     
       
   394     // Open the table    
       
   395     CMPXHarvesterDatabaseTable* table = 
       
   396                                CMPXHarvesterDatabaseTable::NewLC( *iDatabase );
       
   397     table->OpenDrmL();                            
       
   398     CleanupStack::Pop( table );
       
   399     return table;
       
   400     }
       
   401 
       
   402 // ---------------------------------------------------------------------------
       
   403 // Delete a particular file from the database
       
   404 // ---------------------------------------------------------------------------
       
   405 //
       
   406 void CMPXHarvesterDB::DeleteFileL( const TDesC& aFile )
       
   407     {
       
   408     HBufC* buf = HBufC::NewLC( aFile.Length() + KAdditionalStringLength );
       
   409     TPtr ptr = buf->Des();
       
   410 
       
   411     TParsePtrC parse( aFile );
       
   412     TBuf<KDbMaxTableCreationSQLLength> query;
       
   413     query += KDelete;
       
   414     query += KFrom;
       
   415     query += KHarvesterMainTable;
       
   416     query += KWhere;
       
   417     query += KHarFileName;
       
   418     query += KEquals;
       
   419     query += KItemBracket;
       
   420     ptr.Copy( KNullDesC );
       
   421     FindAndReplaceSingleQuote( parse.NameAndExt(), ptr );
       
   422     query += ptr;
       
   423     query += KItemBracket;
       
   424     query += KAnd;
       
   425     query += KHarPathName;
       
   426     query += KEquals;
       
   427     query += KItemBracket;
       
   428     ptr.Copy( KNullDesC );
       
   429     FindAndReplaceSingleQuote( parse.DriveAndPath(), ptr );
       
   430     query += ptr;
       
   431     query += KItemBracket;
       
   432 
       
   433     // Execute
       
   434     User::LeaveIfError( iDatabase->Execute( query, EDbCompareFolded ) );
       
   435 
       
   436     CleanupStack::PopAndDestroy( buf );
       
   437     }
       
   438 
       
   439 // ---------------------------------------------------------------------------
       
   440 // Removes all files from this database
       
   441 // ---------------------------------------------------------------------------
       
   442 //
       
   443 void CMPXHarvesterDB::RemoveAllFilesL()
       
   444     {
       
   445 
       
   446     // Only delete all if db is opened (ie media present)
       
   447     //
       
   448     if( iDBOpen )
       
   449         {
       
   450         // SQL Statement is "DELETE FROM 'tablename'"
       
   451         //
       
   452         TBuf<KDbMaxTableCreationSQLLength> query;
       
   453         query += KDelete;
       
   454         query += KFrom;
       
   455         query += KHarvesterMainTable;
       
   456         User::LeaveIfError( iDatabase->Execute( query ) );
       
   457 
       
   458     #ifdef __PRINTDB__
       
   459         CMPXHarvesterDatabaseTable* curTable = OpenAllFilesTableL();
       
   460         if( curTable )
       
   461             {
       
   462             CleanupStack::PushL( curTable );
       
   463             curTable->PrintItemsInTableL();
       
   464             CleanupStack::PopAndDestroy( curTable );
       
   465             }
       
   466     #endif //__PRINTDB__
       
   467 
       
   468         }
       
   469     }
       
   470 
       
   471 // ---------------------------------------------------------------------------
       
   472 // Deletes the database file, the user should call Close() before hand
       
   473 // ---------------------------------------------------------------------------
       
   474 //
       
   475 TInt CMPXHarvesterDB::DeleteDatabase()
       
   476     {
       
   477     TDriveUnit drive( iDrive );
       
   478     TFileName fileName;
       
   479     fileName.Append( drive.Name() );
       
   480     fileName.Append( KHarvesterDBPath );
       
   481     fileName.Append( KHarvesterDBName );
       
   482 
       
   483     return iFs.Delete( fileName );
       
   484     }
       
   485 
       
   486 // ---------------------------------------------------------------------------
       
   487 // Read the unique id of the database file
       
   488 // ---------------------------------------------------------------------------
       
   489 //
       
   490 TUint CMPXHarvesterDB::UniqueIdL()
       
   491     {
       
   492     TBuf<KDbMaxTableCreationSQLLength> query;
       
   493     query.Append( KSelectAll );
       
   494     query.Append( KHarvesterAuxTable );
       
   495 
       
   496     RDbView view;
       
   497     User::LeaveIfError( view.Prepare( *iDatabase, query ) );
       
   498     User::LeaveIfError( view.Evaluate() );
       
   499 
       
   500     TBool found = view.FirstL();
       
   501     if( !found )
       
   502         {
       
   503         User::Leave( KErrCorrupt );
       
   504         }
       
   505 
       
   506     view.GetL();
       
   507     TUint id = view.ColUint(KHarAuxVolumeIdColumn);
       
   508     view.Close();
       
   509     return id;
       
   510     }
       
   511 
       
   512 // ---------------------------------------------------------------------------
       
   513 // Counts all files from this database
       
   514 // ---------------------------------------------------------------------------
       
   515 //
       
   516 TInt CMPXHarvesterDB::CountAllFilesL()
       
   517     {
       
   518     TInt count = 0;
       
   519     // Only count if db is opened (ie media present)
       
   520     if( iDBOpen )
       
   521         {
       
   522         // Open the table
       
   523         CMPXHarvesterDatabaseTable* table = CMPXHarvesterDatabaseTable::NewLC( *iDatabase );
       
   524         table->OpenAllFilesTableL();
       
   525         count = table->CountL();
       
   526         CleanupStack::PopAndDestroy(table);
       
   527         }
       
   528     return count;
       
   529     }
       
   530 
       
   531 // ---------------------------------------------------------------------------
       
   532 // Fixes single quote query issues
       
   533 // ---------------------------------------------------------------------------
       
   534 //
       
   535 void CMPXHarvesterDB::FindAndReplaceSingleQuote(const TDesC& aSrc,
       
   536                                                 TDes& aTrg)
       
   537     {
       
   538     TPtrC ch;
       
   539 
       
   540     TInt srcLen = aSrc.Length();
       
   541 
       
   542     for (TInt i = 0; i < srcLen; ++i)
       
   543         {
       
   544         ch.Set(&aSrc[i], 1);
       
   545         aTrg.Append(ch);
       
   546         if ( ch.CompareF(_L("'")) == 0)
       
   547             {
       
   548             aTrg.Append(ch);
       
   549             }
       
   550         }
       
   551     }
       
   552 
       
   553 // ---------------------------------------------------------------------------
       
   554 // Begin transaction on this database
       
   555 // ---------------------------------------------------------------------------
       
   556 //
       
   557 void CMPXHarvesterDB::BeginL()
       
   558     {
       
   559     TInt err = iDatabase->Begin();
       
   560     
       
   561     if(err != KErrNone)
       
   562         {
       
   563         User::Leave(err);
       
   564         }
       
   565     }
       
   566 
       
   567 // ---------------------------------------------------------------------------
       
   568 // Check if the database is in transaction
       
   569 // ---------------------------------------------------------------------------
       
   570 //
       
   571 TBool CMPXHarvesterDB::InTransaction()
       
   572     {
       
   573     MPX_DEBUG1("CMPXHarvesterDB::InTransaction <---");
       
   574     TBool inTrans = EFalse;
       
   575     if ( iDatabase != NULL )
       
   576         {
       
   577         inTrans = iDatabase->InTransaction();
       
   578         }
       
   579     MPX_DEBUG1("CMPXHarvesterDB::InTransaction --->");
       
   580     return inTrans;
       
   581     }
       
   582 
       
   583 // ---------------------------------------------------------------------------
       
   584 // Commit all changes in the transaction on this database
       
   585 // ---------------------------------------------------------------------------
       
   586 //
       
   587 void CMPXHarvesterDB::CommitL()
       
   588     {
       
   589     MPX_DEBUG1("CMPXHarvesterDB::CommitL <---");
       
   590     if ( iDatabase != NULL )
       
   591         {
       
   592         TInt err = iDatabase->Commit();
       
   593         
       
   594         if(err != KErrNone)
       
   595             {
       
   596             User::Leave(err);
       
   597             }
       
   598         }
       
   599     }
       
   600 
       
   601 // ---------------------------------------------------------------------------
       
   602 // Rollbacks the current transaction
       
   603 // ---------------------------------------------------------------------------
       
   604 //
       
   605 void CMPXHarvesterDB::Rollback()
       
   606     {
       
   607     iDatabase->Rollback();
       
   608     }
       
   609 
       
   610 // End of file