mpxplugins/serviceplugins/collectionplugins/mpxsqlitedbplugin/src/mpxdbhandler.cpp
changeset 0 ff3acec5bc43
child 2 b70d77332e66
equal deleted inserted replaced
-1:000000000000 0:ff3acec5bc43
       
     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 used by db plugin for all database related
       
    15 *                functionality. The main responsibilities are:
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <bautils.h>
       
    22 #ifdef RD_MULTIPLE_DRIVE
       
    23 #include <driveinfo.h>
       
    24 #include <pathinfo.h>
       
    25 #endif //RD_MULTIPLE_DRIVE
       
    26 
       
    27 #include <mpxcollectiondbres.rsg>
       
    28 #include <mpxmediageneraldefs.h>
       
    29 #include <mpxmediacontainerdefs.h>
       
    30 #include <mpxmediamusicdefs.h>
       
    31 #include <mpxmediaaudiodefs.h>
       
    32 #include <mpxmedia.h>
       
    33 #include <mpxmediaarray.h>
       
    34 #include <mpxcollectionpath.h>
       
    35 #include <mpxlog.h>
       
    36 
       
    37 #include "mpxresource.h"
       
    38 #include "mpxdbcommonutil.h"
       
    39 
       
    40 #include "mpxdbutil.h"
       
    41 #include "mpxcollectiondbdef.h"
       
    42 #include "mpxdbpluginqueries.h"
       
    43 #include "mpxcollectiondbmanager.h"
       
    44 #include "mpxdbplaylist.h"
       
    45 #include "mpxdbplaylistsongs.h"
       
    46 #include "mpxdbcategory.h"
       
    47 #include "mpxdbauxiliary.h"
       
    48 #include "mpxdbautoplaylist.h"
       
    49 #include "mpxdbhandler.h"
       
    50 #include "mpxdbartist.h"
       
    51 #include "mpxdbalbum.h"
       
    52 #include "mpxdbgenre.h"
       
    53 #include "mpxdbcomposer.h"
       
    54 
       
    55 // CONSTANTS
       
    56 _LIT(KMPXVirtualPlaylistExt, ".vir");
       
    57 static const TInt KMaxOpInTransaction = 100;
       
    58 
       
    59 const TInt KSqlDbCorrupted = -321;
       
    60 
       
    61 #if defined (__MTP_PROTOCOL_SUPPORT)
       
    62 
       
    63 #include <centralrepository.h>
       
    64 
       
    65 // MTP CenRep Key UID
       
    66 const TUid KMPXMtpSettings = {0x101FFC53};
       
    67 // MTP CenRep Key for Delete contents
       
    68 const TUint32 KMPXMtpSaveDeletedRecordFlag = 0x00000001;
       
    69 
       
    70 #endif
       
    71 
       
    72 // ============================ MEMBER FUNCTIONS ==============================
       
    73 
       
    74 // ----------------------------------------------------------------------------
       
    75 // Two-phased constructor.
       
    76 // ----------------------------------------------------------------------------
       
    77 //
       
    78 CMPXDbHandler* CMPXDbHandler::NewL(
       
    79     RFs& aFs,
       
    80     CMPXResource& aResource)
       
    81     {
       
    82     MPX_FUNC("CMPXDbHandler::NewL");
       
    83     CMPXDbHandler* self = CMPXDbHandler::NewLC(aFs, aResource);
       
    84     CleanupStack::Pop(self);
       
    85     return self;
       
    86     }
       
    87 
       
    88 // ----------------------------------------------------------------------------
       
    89 // Two-phased constructor.
       
    90 // ----------------------------------------------------------------------------
       
    91 //
       
    92 CMPXDbHandler* CMPXDbHandler::NewLC(
       
    93     RFs& aFs,
       
    94     CMPXResource& aResource)
       
    95     {
       
    96     MPX_FUNC("CMPXDbHandler::NewLC");
       
    97     CMPXDbHandler* self = new (ELeave) CMPXDbHandler(aFs, aResource);
       
    98     CleanupStack::PushL(self);
       
    99     self->ConstructL();
       
   100     return self;
       
   101     }
       
   102 
       
   103 // ----------------------------------------------------------------------------
       
   104 // Destructor
       
   105 // ----------------------------------------------------------------------------
       
   106 //
       
   107 CMPXDbHandler::~CMPXDbHandler()
       
   108     {
       
   109     MPX_FUNC("CMPXDbHandler::~CMPXDbHandler");
       
   110 
       
   111     delete iAutoPlaylist;
       
   112 
       
   113     delete iDbMusic;
       
   114     delete iDbPlaylist;
       
   115     delete iDbArtist;
       
   116     delete iDbAlbum;
       
   117     delete iDbGenre;
       
   118     delete iDbComposer;
       
   119     delete iDbAuxiliary;
       
   120     delete iDbManager;
       
   121 
       
   122     delete iMimeTypes;
       
   123     delete iExtensions;
       
   124     delete iExtensionsMime;
       
   125     delete iExtensionsDrm;
       
   126 
       
   127     iDbDrives.Close();
       
   128     }
       
   129 
       
   130 // ----------------------------------------------------------------------------
       
   131 // C++ default constructor can NOT contain any code, that might leave
       
   132 // ----------------------------------------------------------------------------
       
   133 //
       
   134 CMPXDbHandler::CMPXDbHandler(
       
   135     RFs& aFs,
       
   136     CMPXResource& aResource) :
       
   137     iFs(aFs),
       
   138     iResource(aResource)
       
   139     {
       
   140     MPX_FUNC("CMPXDbHandler::CMPXDbHandler");
       
   141     }
       
   142 
       
   143 // ----------------------------------------------------------------------------
       
   144 // Symbian 2nd phase constructor can leave.
       
   145 // ----------------------------------------------------------------------------
       
   146 //
       
   147 void CMPXDbHandler::ConstructL()
       
   148     {
       
   149     MPX_FUNC("CMPXDbHandler::ConstructL");
       
   150 
       
   151     iMimeTypes = iResource.ReadDesCArrayL(R_MC_MIME_TYPES);
       
   152     iExtensions = iResource.ReadDesCArrayL(R_MC_MUSIC_FILE_EXTENSIONS);
       
   153     iExtensionsMime = iResource.ReadDesCArrayL(R_MC_FILE_EXTENSIONS_MIME);
       
   154     iExtensionsDrm = iResource.ReadDesCArrayL(R_MC_FILE_EXTENSIONS_DRM);
       
   155     
       
   156     // make sure all databases are created and valid
       
   157     iDbManager = CMPXCollectionDbManager::NewL(iFs);
       
   158     
       
   159     CDesCArrayFlat* musicFolders =
       
   160 #ifdef RD_MULTIPLE_DRIVE
       
   161         GetMusicFoldersL();
       
   162 #else
       
   163         iResource.ReadDesCArrayL(R_MC_DEFAULT_MUSIC_FOLDERS);
       
   164 #endif
       
   165 
       
   166     // create the music folders and initialize iDbDrives
       
   167     CleanupStack::PushL(musicFolders);
       
   168     ProcessMusicFoldersL(*musicFolders);
       
   169     CleanupStack::PopAndDestroy(musicFolders);
       
   170 
       
   171     // Create the db infrastructure, 
       
   172     //
       
   173     iDbMusic = CMPXDbMusic::NewL(*iDbManager, iResource, *this);
       
   174     iDbPlaylist = CMPXDbPlaylist::NewL(*iDbManager, *this);
       
   175     iDbArtist = CMPXDbArtist::NewL(*iDbManager, EMPXArtist, *this);
       
   176 	iDbAlbum = CMPXDbAlbum::NewL(*iDbManager, EMPXAlbum, *this);
       
   177     iDbGenre = CMPXDbGenre::NewL(*iDbManager, EMPXGenre);
       
   178     iDbComposer = CMPXDbComposer::NewL(*iDbManager, EMPXComposer);
       
   179     iAutoPlaylist = CMPXDbAutoPlaylist::NewL(*iDbManager, iFs, iResource);
       
   180     iDbAuxiliary = CMPXDbAuxiliary::NewL(*iDbManager);
       
   181 
       
   182     MPX_TRAPD(err, iDbManager->InitDatabasesL(iDbDrives));
       
   183     iCollectionOpen = ETrue;
       
   184 
       
   185     // If KErrCorrupt is returned, a database file was found to be corrupted
       
   186     // and was replaced with a new one.  The db plugin can ignore this error and continue
       
   187     // because a new db file was successfully created in a subsequent retry.
       
   188     if ((err != KErrNone) && (err != KErrCorrupt) && (err != KErrDiskFull))
       
   189         {
       
   190         // leave to signal the caller that there was an error why creating and opening
       
   191         // one or more of the databases
       
   192         User::Leave(err);
       
   193         }
       
   194     else if (err == KErrDiskFull)
       
   195         {
       
   196         iOutOfDisk = ETrue;
       
   197         }
       
   198     else
       
   199         {
       
   200         // do nothing
       
   201         }
       
   202 
       
   203     // Verify the volume ids of each drive matches the database
       
   204     MPX_TRAP(err,VerifyVolumeIdL());
       
   205     if ((err != KErrNone) && (err != KErrDiskFull))
       
   206         {
       
   207         // leave to signal the caller that there was an error why creating and opening
       
   208         // one or more of the databases
       
   209         User::Leave(err);
       
   210         }
       
   211     else if (err == KErrDiskFull)
       
   212         {
       
   213         iOutOfDisk = ETrue;
       
   214         }
       
   215 
       
   216 //#ifdef _DEBUG
       
   217 //    iDbManager->PrintDatabaseL();    // PREQ2536 the files sqlrowsetutil.h and sqlrowsetutil.cpp has been removed
       
   218 //#endif
       
   219 
       
   220     MPX_DEBUG2("CMPXDbHandler::ConstructL DbCount[%d]", iDbManager->DatabaseCount());
       
   221     }
       
   222 
       
   223 // ----------------------------------------------------------------------------
       
   224 // Add song to collection
       
   225 // ----------------------------------------------------------------------------
       
   226 //
       
   227 TUint32 CMPXDbHandler::AddSongL(
       
   228     const CMPXMedia& aMedia,
       
   229     CMPXMessageArray* aMessageArray)
       
   230     {
       
   231     MPX_FUNC("CMPXDbHandler::AddSongL");
       
   232 
       
   233     BeginTransactionL();
       
   234     TUint32 songId(0);
       
   235     MPX_TRAPD(err, songId = DoAddSongL(aMedia,aMessageArray));
       
   236 
       
   237     if (iOutOfDisk && (err == KErrNotFound))
       
   238         {
       
   239         err = KErrDiskFull;
       
   240         }
       
   241     EndTransactionL(err);
       
   242 
       
   243     return songId;
       
   244     }
       
   245 
       
   246 // ----------------------------------------------------------------------------
       
   247 // Add song to collection with no database transaction
       
   248 // ----------------------------------------------------------------------------
       
   249 //
       
   250 TUint32 CMPXDbHandler::AddSongWithNoTransactionL(
       
   251     const CMPXMedia& aMedia,
       
   252     CMPXMessageArray* aMessageArray)
       
   253     {
       
   254     MPX_FUNC("CMPXDbHandler::AddSongWithNoTransactionL");
       
   255 
       
   256     TUint32 songId(0);
       
   257     MPX_TRAPD(err, songId = DoAddSongL(aMedia,aMessageArray));
       
   258 
       
   259     if (iOutOfDisk && (err == KErrNotFound))
       
   260         {
       
   261         err = KErrDiskFull;
       
   262         }
       
   263     User::LeaveIfError(err);
       
   264 
       
   265     return songId;
       
   266     }
       
   267 
       
   268 // ----------------------------------------------------------------------------
       
   269 // Add playlist to collection
       
   270 // ----------------------------------------------------------------------------
       
   271 //
       
   272 TUint32 CMPXDbHandler::AddPlaylistL(
       
   273     const CMPXMedia& aMedia)
       
   274     {
       
   275     MPX_FUNC("CMPXDbHandler::AddPlaylistL");
       
   276 
       
   277     BeginTransactionL();
       
   278     TUint32 playlistId(0);
       
   279     MPX_TRAPD(err, playlistId = DoAddPlaylistL(aMedia));
       
   280     EndTransactionL(err);
       
   281 
       
   282     return playlistId;
       
   283     }
       
   284 
       
   285 // ----------------------------------------------------------------------------
       
   286 // Add song to playlist
       
   287 // ----------------------------------------------------------------------------
       
   288 //
       
   289 TUint32 CMPXDbHandler::AddSongToPlaylistL(
       
   290     const CMPXMedia& aMedia)
       
   291     {
       
   292     MPX_FUNC("CMPXDbHandler::AddSongToPlaylistL");
       
   293 
       
   294     BeginTransactionL();
       
   295     TUint32 playlistId(0);
       
   296     MPX_TRAPD(err, playlistId = DoAddSongToPlaylistL(aMedia));
       
   297     EndTransactionL(err);
       
   298 
       
   299     return playlistId;
       
   300     }
       
   301 
       
   302 // ----------------------------------------------------------------------------
       
   303 // Update a song in the collection
       
   304 // ----------------------------------------------------------------------------
       
   305 //
       
   306 CMPXDbActiveTask::TChangeVisibility CMPXDbHandler::UpdateSongL(
       
   307     const CMPXMedia& aMedia,
       
   308     CMPXMessageArray& aItemChangedMessages)
       
   309     {
       
   310     MPX_FUNC("CMPXDbHandler::UpdateSongL");
       
   311 
       
   312     BeginTransactionL();
       
   313     CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
       
   314     MPX_TRAPD(err, visibleChange = DoUpdateSongL(aMedia, aItemChangedMessages));
       
   315     EndTransactionL(err);
       
   316     return visibleChange;
       
   317     }
       
   318 
       
   319 // ----------------------------------------------------------------------------
       
   320 // Update a playlist in the collection
       
   321 // ----------------------------------------------------------------------------
       
   322 //
       
   323 void CMPXDbHandler::UpdatePlaylistL(
       
   324     const CMPXMedia& aMedia,
       
   325     CMPXMessageArray& aMessageArray)
       
   326     {
       
   327     MPX_FUNC("CMPXDbHandler::UpdatePlaylistL");
       
   328 
       
   329     BeginTransactionL();
       
   330     MPX_TRAPD(err, DoUpdatePlaylistL(aMedia, aMessageArray));
       
   331     EndTransactionL(err);
       
   332     }
       
   333 
       
   334 // ----------------------------------------------------------------------------
       
   335 // Updates the playlist songs
       
   336 // ----------------------------------------------------------------------------
       
   337 //
       
   338 void CMPXDbHandler::UpdatePlaylistSongsL(
       
   339     const CMPXMedia& aMedia,
       
   340     CMPXMessage& aMessage)
       
   341     {
       
   342     MPX_FUNC("CMPXDbHandler::UpdatePlaylistSongsL");
       
   343 
       
   344     BeginTransactionL();
       
   345     MPX_TRAPD(err, DoUpdatePlaylistSongsL(aMedia, aMessage));
       
   346     EndTransactionL(err);
       
   347     }
       
   348 
       
   349 // ----------------------------------------------------------------------------
       
   350 // Reorder a song in a playlist
       
   351 // ----------------------------------------------------------------------------
       
   352 //
       
   353 void CMPXDbHandler::ReorderPlaylistL(
       
   354     const TMPXItemId& aPlaylistId,
       
   355     const TMPXItemId& aSongId,
       
   356     TUint aOriginalOrdinal,
       
   357     TUint aNewOrdinal,
       
   358     CMPXMessage& aMessage)
       
   359     {
       
   360     MPX_DEBUG5("-->CMPXDbHandler::ReorderPlaylistL(0x%x, 0x%x, %d, %d)",
       
   361                aPlaylistId.iId2, aSongId.iId2, aOriginalOrdinal, aNewOrdinal);
       
   362 
       
   363     BeginTransactionL();
       
   364     MPX_TRAPD(err, DoReorderPlaylistL(aPlaylistId, aSongId, aOriginalOrdinal, aNewOrdinal, aMessage));
       
   365     EndTransactionL(err);
       
   366     MPX_DEBUG2("<--CMPXDbHandler::ReorderPlaylistL() error=%d", err);
       
   367     }
       
   368 
       
   369 // ----------------------------------------------------------------------------
       
   370 // Remove the entire music collection database
       
   371 // ----------------------------------------------------------------------------
       
   372 //
       
   373 void CMPXDbHandler::RemoveEntireCollectionL()
       
   374     {
       
   375     MPX_FUNC("CMPXDbHandler::RemoveEntireCollectionL");
       
   376     BeginTransactionL();
       
   377     MPX_TRAPD(err, iDbManager->RecreateAllDatabasesL());
       
   378     EndTransactionL(err);
       
   379     }
       
   380 
       
   381 // ----------------------------------------------------------------------------
       
   382 // Delete a song from collection
       
   383 // The function notifies collection model to perform deletion
       
   384 // ----------------------------------------------------------------------------
       
   385 //
       
   386 void CMPXDbHandler::RemoveSongL(
       
   387     TUint32 aSongId,
       
   388     CDesCArray& aUriArray,
       
   389     CMPXMessageArray& aItemChangedMessages,
       
   390     TBool aDeleteRecord)
       
   391     {
       
   392     MPX_FUNC("CMPXDbHandler::RemoveSongL");
       
   393 
       
   394     MPX_TRAPD(err, DoRemoveSongL(aSongId, aUriArray, aItemChangedMessages, aDeleteRecord));
       
   395 
       
   396     MPX_TRAP(err, DoRemoveSongFromPlaylistL(aSongId,aItemChangedMessages));
       
   397 
       
   398     }
       
   399 
       
   400 // ----------------------------------------------------------------------------
       
   401 // Removes a category of songs from the music collection,
       
   402 // and its corresponding category in the lookup table
       
   403 // ----------------------------------------------------------------------------
       
   404 //
       
   405 void CMPXDbHandler::RemoveSongsMatchingCategoryL(
       
   406     TMPXGeneralCategory aCategory,
       
   407     TUint32 aCategoryId,
       
   408     CDesCArray& aUriArray,
       
   409     CMPXMessageArray& aItemChangedMessages)
       
   410     {
       
   411     MPX_FUNC("CMPXDbHandler::RemoveSongsMatchingCategoryL");
       
   412 
       
   413     BeginTransactionL();
       
   414     MPX_TRAPD(err, DoRemoveSongsMatchingCategoryL(aCategory, aCategoryId, aUriArray, aItemChangedMessages));
       
   415     EndTransactionL(err);
       
   416     }
       
   417 
       
   418 // ----------------------------------------------------------------------------------------------------------
       
   419 // Delete songs for the specified artist and album from collection
       
   420 // The function notifies collection model to perform deletion
       
   421 // ----------------------------------------------------------------------------------------------------------
       
   422 //
       
   423 void CMPXDbHandler::RemoveSongsMatchingArtistAndAlbumL(
       
   424     TUint32 aArtistId,
       
   425     TUint32 aAlbumId,
       
   426     CDesCArray& aUriArray,
       
   427     CMPXMessageArray& aItemChangedMessages)
       
   428     {
       
   429     MPX_FUNC("CMPXDbHandler::RemoveSongsMatchingArtistAndAlbumL");
       
   430 
       
   431     BeginTransactionL();
       
   432     MPX_TRAPD(err, DoRemoveSongsMatchingArtistAndAlbumL(aArtistId, aAlbumId, aUriArray,
       
   433         aItemChangedMessages));
       
   434     EndTransactionL(err);
       
   435     }
       
   436 
       
   437 // ----------------------------------------------------------------------------
       
   438 // Remove all playlists from collection
       
   439 // ----------------------------------------------------------------------------
       
   440 //
       
   441 void CMPXDbHandler::RemoveAllPlaylistsL()
       
   442     {
       
   443     MPX_FUNC("CMPXDbHandler::RemoveAllPlaylistsL");
       
   444 
       
   445     BeginTransactionL();
       
   446     MPX_TRAPD(err, DoRemoveAllPlaylistsL());
       
   447     EndTransactionL(err);
       
   448     }
       
   449 
       
   450 // ----------------------------------------------------------------------------
       
   451 // Remove specified playlist
       
   452 // ----------------------------------------------------------------------------
       
   453 //
       
   454 void CMPXDbHandler::RemovePlaylistL(
       
   455     TUint32 aPlaylistId,
       
   456     CDesCArray& aUriArray,
       
   457     CMPXMessageArray& aItemChangedMessages)
       
   458     {
       
   459     MPX_FUNC("CMPXDbHandler::RemovePlaylistL");
       
   460 
       
   461     BeginTransactionL();
       
   462     MPX_TRAPD(err, DoRemovePlaylistL(aPlaylistId, aUriArray, aItemChangedMessages));
       
   463     EndTransactionL(err);
       
   464     }
       
   465 
       
   466 // ----------------------------------------------------------------------------
       
   467 // Remove song from playlist songs table
       
   468 // ----------------------------------------------------------------------------
       
   469 //
       
   470 void CMPXDbHandler::RemoveSongFromPlaylistL(
       
   471     TUint32 aPlaylistId,
       
   472     const TMPXItemId& aSongId,
       
   473     TInt aOrdinal,
       
   474     CMPXMessageArray& aItemChangedMessages)
       
   475     {
       
   476     MPX_FUNC("CMPXDbHandler::RemoveSongFromPlaylistL");
       
   477     MPX_DEBUG5("CMPXDbHandler::RemoveSongFromPlaylistL(playlist 0x%x, songId [0x%x,0x%x], ordinal %d)",
       
   478         aPlaylistId, aSongId.iId1, aSongId.iId2, aOrdinal);
       
   479 
       
   480     MPX_TRAPD(err, DoRemoveSongFromPlaylistL(aPlaylistId, aSongId, aOrdinal, aItemChangedMessages));
       
   481     if ( err && InTransaction() )
       
   482         {
       
   483         // only end transaction if there's an error
       
   484         EndTransactionL( err );
       
   485         }
       
   486     }
       
   487 
       
   488 // ----------------------------------------------------------------------------
       
   489 // Cleanup records marked as deleted. This is designated for MTP to clean up records marked as deleted
       
   490 // at the end of its session.
       
   491 // ----------------------------------------------------------------------------
       
   492 //
       
   493 void CMPXDbHandler::CleanupDeletedRecordsL()
       
   494     {
       
   495     MPX_FUNC("CMPXDbHandler::CleanupDeletedRecordsL");
       
   496 
       
   497     BeginTransactionL();
       
   498     MPX_TRAPD(err, DoCleanupDeletedRecordsL());
       
   499     EndTransactionL(err);
       
   500     }
       
   501 
       
   502 // ----------------------------------------------------------------------------
       
   503 //  Read all songs and cache them into an array ordered by song name
       
   504 // ----------------------------------------------------------------------------
       
   505 //
       
   506 void CMPXDbHandler::GetAllSongsL(
       
   507     CMPXMediaArray* aMediaArray,
       
   508     const TArray<TMPXAttribute>& aAttrs)
       
   509     {
       
   510     MPX_FUNC("CMPXDbHandler::GetAllSongsL");
       
   511     iDbMusic->GetAllSongsL(aAttrs, *aMediaArray);
       
   512     }
       
   513 
       
   514 // ----------------------------------------------------------------------------
       
   515 //  Read a limited # of songs and cache them into an array ordered by song name
       
   516 // ----------------------------------------------------------------------------
       
   517 //
       
   518 void CMPXDbHandler::GetAllSongsLimitedL(const TArray<TMPXAttribute>& aAttrs,
       
   519                                         CMPXMediaArray& aMediaArray, TInt aLimit)
       
   520     {
       
   521     MPX_FUNC("CMPXDbHandler::GetAllSongsLimitedL");
       
   522     iDbMusic->GetAllSongsLimitedL( aAttrs, aMediaArray, aLimit );
       
   523     }
       
   524 
       
   525 // ----------------------------------------------------------------------------
       
   526 //  Read all songs and cache them into an array ordered by song name
       
   527 // ----------------------------------------------------------------------------
       
   528 //
       
   529 void CMPXDbHandler::GetSongsInBlockL(
       
   530     CMPXMediaArray* aMediaArray,
       
   531     const TArray<TMPXAttribute>& aAttrs,
       
   532     TPtrC aTitle,
       
   533     TUint aNumOfSongs,
       
   534     TBool aAsc)
       
   535     {
       
   536     MPX_FUNC("CMPXDbHandler::GetSongsInBlockL");
       
   537     iDbMusic->GetSongsInBlockL(aAttrs, *aMediaArray, aTitle, aNumOfSongs, aAsc);
       
   538     }
       
   539 
       
   540 // ----------------------------------------------------------------------------
       
   541 //  Read songs at a particular offset
       
   542 // ----------------------------------------------------------------------------
       
   543 //
       
   544 void CMPXDbHandler::GetSongsAtOffsetL( CMPXMediaArray* aMediaArray,
       
   545                                        const TArray<TMPXAttribute>& aAttrs,
       
   546                                        TInt aOffset,
       
   547                                        TInt aCount )
       
   548     {
       
   549     MPX_DEBUG1("CMPXDbHandler::GetSongsAtOffsetL <--");
       
   550     iDbMusic->GetSongsAtOffsetL( *aMediaArray, aAttrs, aOffset, aCount );
       
   551     }
       
   552 
       
   553 // ----------------------------------------------------------------------------
       
   554 // Get all songs matching the given artist ID
       
   555 // ----------------------------------------------------------------------------
       
   556 //
       
   557 void CMPXDbHandler::GetSongsMatchingArtistL(
       
   558     TUint aArtistId,
       
   559     const TArray<TMPXAttribute>& aAttrs,
       
   560     CMPXMediaArray* aMediaArray)
       
   561     {
       
   562     MPX_FUNC("CMPXDbHandler::GetSongsMatchingArtistL");
       
   563     iDbMusic->GetSongsForArtistL(aArtistId, aAttrs, *aMediaArray);
       
   564     }
       
   565 
       
   566 // ----------------------------------------------------------------------------
       
   567 // Get all songs matching the given album ID
       
   568 // ----------------------------------------------------------------------------
       
   569 //
       
   570 void CMPXDbHandler::GetSongsMatchingAlbumL(
       
   571     TUint aAlbumId,
       
   572     const TArray<TMPXAttribute>& aAttrs,
       
   573     CMPXMediaArray* aMediaArray)
       
   574     {
       
   575     MPX_FUNC("CMPXDbHandler::GetSongsMatchingAlbumL");
       
   576     iDbMusic->GetSongsForAlbumL(aAlbumId, aAttrs, *aMediaArray);
       
   577     }
       
   578 
       
   579 // ----------------------------------------------------------------------------------------------------------
       
   580 // Get all songs matching the given artist and album ID
       
   581 // ----------------------------------------------------------------------------------------------------------
       
   582 //
       
   583 void CMPXDbHandler::GetSongsMatchingArtistAndAlbumL(
       
   584     TUint aArtistId,
       
   585     TUint aAlbumId,
       
   586     const TArray<TMPXAttribute>& aAttrs,
       
   587     CMPXMediaArray* aMediaArray)
       
   588     {
       
   589     MPX_FUNC("CMPXDbHandler::GetSongsMatchingArtistAndAlbumL");
       
   590     iDbMusic->GetSongsForArtistAndAlbumL(aArtistId, aAlbumId, aAttrs, *aMediaArray);
       
   591     }
       
   592 
       
   593 // ----------------------------------------------------------------------------
       
   594 // Get all songs matching the given genre ID
       
   595 // ----------------------------------------------------------------------------
       
   596 //
       
   597 void CMPXDbHandler::GetSongsMatchingGenreL(
       
   598     TUint aGenreId,
       
   599     const TArray<TMPXAttribute>& aAttrs,
       
   600     CMPXMediaArray* aMediaArray)
       
   601     {
       
   602     MPX_FUNC("CMPXDbHandler::GetSongsMatchingGenreL");
       
   603     iDbMusic->GetSongsForGenreL(aGenreId, aAttrs, *aMediaArray);
       
   604     }
       
   605 
       
   606 // ----------------------------------------------------------------------------
       
   607 // Get all songs matching the given composer ID
       
   608 // ----------------------------------------------------------------------------
       
   609 //
       
   610 void CMPXDbHandler::GetSongsMatchingComposerL(
       
   611     TUint aComposerId,
       
   612     const TArray<TMPXAttribute>& aAttrs,
       
   613     CMPXMediaArray* aMediaArray)
       
   614     {
       
   615     MPX_FUNC("CMPXDbHandler::GetSongsMatchingComposerL");
       
   616     iDbMusic->GetSongsForComposerL(aComposerId, aAttrs, *aMediaArray);
       
   617     }
       
   618 
       
   619 // ----------------------------------------------------------------------------
       
   620 // Get all songs that belong to the given playlist
       
   621 // ----------------------------------------------------------------------------
       
   622 //
       
   623 void CMPXDbHandler::GetSongsMatchingPlaylistL(
       
   624     TUint aPlaylistId,
       
   625     const TArray<TMPXAttribute>& aAttrs,
       
   626     CMPXMediaArray* aMediaArray)
       
   627     {
       
   628     MPX_FUNC("CMPXDbHandler::GetSongsMatchingPlaylistL");
       
   629     GetPlaylistSongsL(aPlaylistId, aAttrs, *aMediaArray);
       
   630     }
       
   631 
       
   632 // ----------------------------------------------------------------------------
       
   633 // Get song matching the given song ID
       
   634 // ----------------------------------------------------------------------------
       
   635 //
       
   636 void CMPXDbHandler::GetSongL(
       
   637     TUint32 aSongId,
       
   638     const TArray<TMPXAttribute>& aAttrs,
       
   639     CMPXMedia& aMedia)
       
   640     {
       
   641     MPX_FUNC("CMPXDbHandler::GetSongL");
       
   642     iDbMusic->GetSongL(aSongId, aAttrs, aMedia);
       
   643     }
       
   644 
       
   645 // ----------------------------------------------------------------------------
       
   646 // GetSongL
       
   647 // ----------------------------------------------------------------------------
       
   648 //
       
   649 void CMPXDbHandler::GetSongL(
       
   650     TUint32 aSongId,
       
   651     const TArray<TMPXAttribute>& aAttrs,
       
   652     CMPXMediaArray& aMediaArray)
       
   653     {
       
   654     MPX_FUNC("CMPXDbHandler::GetSongL");
       
   655 
       
   656     CMPXMedia* media = CMPXMedia::NewL();
       
   657     CleanupStack::PushL(media);
       
   658 
       
   659     GetSongL(aSongId, aAttrs, *media);
       
   660     aMediaArray.AppendL(*media);
       
   661 
       
   662     CleanupStack::PopAndDestroy(media);
       
   663     }
       
   664 
       
   665 // ----------------------------------------------------------------------------
       
   666 // Get song matching the given song ID and playlist ID
       
   667 // ----------------------------------------------------------------------------
       
   668 //
       
   669 void CMPXDbHandler::GetPlaylistSongL(
       
   670     TUint32 aSongId,
       
   671     TUint32 aPlaylistId,
       
   672     const TArray<TMPXAttribute>& aAttrs,
       
   673     CMPXMedia& aMedia)
       
   674     {
       
   675     MPX_DEBUG3("-->CMPXDbHandler::GetPlaylistSongL songId[0x%x] playlistId[0x%x]", aSongId, aPlaylistId);
       
   676 
       
   677     // complete the song information from the Music table
       
   678     MPX_TRAPD(err, iDbMusic->GetSongL(aSongId, aAttrs, aMedia));
       
   679 
       
   680     //
       
   681     // song not found in Music table
       
   682     //
       
   683     if (err == KErrNotFound)
       
   684         {
       
   685         //
       
   686         // Leave with KErrNotFound if one of the following is true:
       
   687         // 1) the requested song is in an auto playlist. Since auto-playlist isn't
       
   688         //    stored in playlist tables, we won't be able to retrieve info elsewhere
       
   689         // 2) the requested song is in a user playlist but we cannot find the song
       
   690         //    info from playlist tables either
       
   691         //
       
   692         if (EMPXNoAutoPlaylist != iAutoPlaylist->AutoPlaylistTypeL(aPlaylistId) ||
       
   693             !iDbPlaylist->Songs().GetSongL(aPlaylistId, aSongId, aAttrs, aMedia))
       
   694             {
       
   695             User::Leave(KErrNotFound);
       
   696             }
       
   697         }
       
   698 
       
   699     //
       
   700     // Unable to read information from Music table
       
   701     //
       
   702     else
       
   703         {
       
   704         // ignore the error if KErrNotFound
       
   705         User::LeaveIfError(err);
       
   706         }
       
   707     MPX_DEBUG1("<--CMPXDbHandler::GetPlaylistSongL");
       
   708     }
       
   709 
       
   710 // ----------------------------------------------------------------------------
       
   711 // GetPlaylistSongL
       
   712 // ----------------------------------------------------------------------------
       
   713 //
       
   714 void CMPXDbHandler::GetPlaylistSongL(
       
   715     TUint32 aSongId,
       
   716     TUint32 aPlaylistId,
       
   717     const TArray<TMPXAttribute>& aAttrs,
       
   718     CMPXMediaArray& aMediaArray)
       
   719     {
       
   720     MPX_FUNC("CMPXDbHandler::GetPlaylistSongL");
       
   721 
       
   722     CMPXMedia* media = CMPXMedia::NewL();
       
   723     CleanupStack::PushL(media);
       
   724 
       
   725     GetPlaylistSongL(aSongId, aPlaylistId, aAttrs, *media);
       
   726     aMediaArray.AppendL(*media);
       
   727 
       
   728     CleanupStack::PopAndDestroy(media);
       
   729     }
       
   730 
       
   731 // ----------------------------------------------------------------------------
       
   732 // Get song matching the given URI
       
   733 // ----------------------------------------------------------------------------
       
   734 //
       
   735 TUint32 CMPXDbHandler::GetSongIdMatchingUriL(
       
   736     const TDesC& aUri)
       
   737     {
       
   738     MPX_FUNC("CMPXDbHandler::GetSongIdMatchingUriL");
       
   739     return MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, aUri, EFalse);
       
   740     }
       
   741 
       
   742 // ----------------------------------------------------------------------------
       
   743 // Get all artists
       
   744 // ----------------------------------------------------------------------------
       
   745 //
       
   746 void CMPXDbHandler::GetAllArtistsL(
       
   747     const TArray<TMPXAttribute>& aAttrs,
       
   748     CMPXMediaArray* aMediaArray)
       
   749     {
       
   750     MPX_FUNC("CMPXDbHandler::GetAllArtistsL");
       
   751     iDbArtist->GetAllCategoryItemsL(aAttrs, *aMediaArray);
       
   752     }
       
   753 
       
   754 // ----------------------------------------------------------------------------
       
   755 // Get all albums
       
   756 // ----------------------------------------------------------------------------
       
   757 //
       
   758 void CMPXDbHandler::GetAllAlbumsL(
       
   759     const TArray<TMPXAttribute>& aAttrs,
       
   760     CMPXMediaArray* aMediaArray)
       
   761     {
       
   762     MPX_FUNC("CMPXDbHandler::GetAllAlbumsL");
       
   763     iDbAlbum->GetAllCategoryItemsL(aAttrs, *aMediaArray);
       
   764     }
       
   765 
       
   766 // ----------------------------------------------------------------------------
       
   767 // Get all albums for the given artist ID
       
   768 // ----------------------------------------------------------------------------
       
   769 //
       
   770 void CMPXDbHandler::GetAlbumsMatchingArtistL(
       
   771     TUint aArtistId,
       
   772     const TArray<TMPXAttribute>& aAttrs,
       
   773     CMPXMediaArray& aMediaArray)
       
   774     {
       
   775     MPX_FUNC("CMPXDbHandler::GetAlbumsMatchingArtistL");
       
   776     RArray<TMPXAttribute> attributes;
       
   777     CleanupClosePushL( attributes );
       
   778         
       
   779     TBool tryGetSongCount = EFalse;
       
   780     TInt attrCount(aAttrs.Count());
       
   781     TInt i = 0;
       
   782     for (i = 0; i < attrCount; i++)
       
   783         {
       
   784         TInt contentId(aAttrs[i].ContentId());
       
   785         TUint attributeId(aAttrs[i].AttributeId());
       
   786 
       
   787         if (contentId == KMPXMediaIdGeneral && attributeId & EMPXMediaGeneralCount)
       
   788             {
       
   789             MPX_DEBUG1("    EMPXMediaGeneralCount");
       
   790             
       
   791             attributes.Append(TMPXAttribute(KMPXMediaIdGeneral, attributeId & !EMPXMediaGeneralCount));
       
   792                        
       
   793             tryGetSongCount = ETrue;
       
   794             break;
       
   795             }
       
   796         
       
   797         attributes.Append(aAttrs[i]);
       
   798         }
       
   799     
       
   800     for (TInt j = i+1; j < attrCount; j++)
       
   801         {
       
   802         attributes.Append(aAttrs[j]);
       
   803         }
       
   804     iDbAlbum->GetSubCategoryItemsL(EMPXArtist, aArtistId, attributes.Array(), aMediaArray);
       
   805     CleanupStack::PopAndDestroy(&attributes);
       
   806     
       
   807     TInt pPath(0);
       
   808     if (aMediaArray.Count())
       
   809         {
       
   810         CMPXMedia* pMedia = aMediaArray[0];
       
   811         if (pMedia->IsSupported(KMPXMediaGeneralValue))
       
   812             {
       
   813             pPath = pMedia->ValueTObjectL<TInt>(KMPXMediaGeneralValue);
       
   814             MPX_ASSERT(pPath);
       
   815             }
       
   816         }
       
   817     
       
   818     TInt albumCount(aMediaArray.Count());
       
   819     if (albumCount)
       
   820         {
       
   821         if ( tryGetSongCount )
       
   822             {
       
   823             TInt startIndex = pPath ? 1 : 0;
       
   824             
       
   825             for (TInt i = startIndex; i < albumCount; i++)
       
   826                 {
       
   827                 CMPXMedia* media = aMediaArray[i];
       
   828                 TUint32 albumId((media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)));
       
   829 
       
   830 				TInt songCount = iDbAlbum->GetSongsCountInAlbumMatchingArtistL(aArtistId, albumId);
       
   831 
       
   832                 media->SetTObjectValueL<TInt>(KMPXMediaGeneralCount, songCount );
       
   833 				MPX_DEBUG2("	SongCount[%d]", songCount );				
       
   834                 }
       
   835             }
       
   836         }
       
   837     }
       
   838 
       
   839 // ----------------------------------------------------------------------------
       
   840 // Get all genres
       
   841 // ----------------------------------------------------------------------------
       
   842 //
       
   843 void CMPXDbHandler::GetAllGenresL(
       
   844     const TArray<TMPXAttribute>& aAttrs,
       
   845     CMPXMediaArray* aMediaArray)
       
   846     {
       
   847     MPX_FUNC("CMPXDbHandler::GetAllGenresL");
       
   848     iDbGenre->GetAllCategoryItemsL(aAttrs, *aMediaArray);
       
   849     }
       
   850 
       
   851 // ----------------------------------------------------------------------------
       
   852 // Get all composers
       
   853 // ----------------------------------------------------------------------------
       
   854 //
       
   855 void CMPXDbHandler::GetAllComposersL(
       
   856     const TArray<TMPXAttribute>& aAttrs,
       
   857     CMPXMediaArray* aMediaArray)
       
   858     {
       
   859     MPX_FUNC("CMPXDbHandler::GetAllComposersL");
       
   860     iDbComposer->GetAllCategoryItemsL(aAttrs, *aMediaArray);
       
   861     }
       
   862 
       
   863 // ----------------------------------------------------------------------------
       
   864 // Get the playlist ID of the playlist that matches the given URI
       
   865 // ----------------------------------------------------------------------------
       
   866 //
       
   867 TUint32 CMPXDbHandler::GetPlaylistIdMatchingUriL(
       
   868     const TDesC& aUri)
       
   869     {
       
   870     MPX_FUNC("CMPXDbHandler::GetPlaylistIdMatchingUriL");
       
   871     return iDbPlaylist->GetIdL(aUri);
       
   872     }
       
   873 
       
   874 // ----------------------------------------------------------------------------
       
   875 // CMPXDbHandler::IsAutoPlaylistL
       
   876 // ----------------------------------------------------------------------------
       
   877 //
       
   878 TBool CMPXDbHandler::IsAutoPlaylistL(
       
   879     TUint32 aPlaylistId)
       
   880     {
       
   881     MPX_FUNC("CMPXDbHandler::IsAutoPlaylistL");
       
   882     return (iAutoPlaylist->AutoPlaylistTypeL(aPlaylistId) != EMPXNoAutoPlaylist);
       
   883     }
       
   884 
       
   885 // ----------------------------------------------------------------------------
       
   886 // Get all user playlist names
       
   887 // ----------------------------------------------------------------------------
       
   888 //
       
   889 void CMPXDbHandler::GetAllPlaylistsL(
       
   890     CMPXMediaArray* aMediaArray,
       
   891     const TArray<TMPXAttribute>& aAttrs)
       
   892     {
       
   893     MPX_FUNC("CMPXDbHandler::GetAllPlaylistsL");
       
   894     iDbPlaylist->GetAllPlaylistsL(aAttrs, *aMediaArray);
       
   895     }
       
   896 
       
   897 // ----------------------------------------------------------------------------
       
   898 // Get all system playlist names
       
   899 // ----------------------------------------------------------------------------
       
   900 //
       
   901 void CMPXDbHandler::GetAllSystemPlaylistNamesL(
       
   902     CMPXMediaArray* aMediaArray)
       
   903     {
       
   904     MPX_FUNC("CMPXDbHandler::GetAllSystemPlaylistNamesL()");
       
   905     iAutoPlaylist->GetAllPlaylistsL(*aMediaArray);
       
   906     }
       
   907 
       
   908 // ----------------------------------------------------------------------------
       
   909 // Get the name of the row matching the given ID
       
   910 // ----------------------------------------------------------------------------
       
   911 //
       
   912 HBufC* CMPXDbHandler::GetNameMatchingIdL(
       
   913     const TUint32 aId) const
       
   914     {
       
   915     MPX_FUNC("CMPXDbHandler::GetNameMatchingIdL()");
       
   916 
       
   917     HBufC* name(NULL);
       
   918     TMPXGeneralCategory category(MPX_ITEM_CATEGORY(aId));
       
   919     switch (category)
       
   920         {
       
   921         case EMPXCollection:
       
   922             {
       
   923             // song name
       
   924             name = iDbMusic->GetNameL(aId);
       
   925             break;
       
   926             }
       
   927         case EMPXPlaylist:
       
   928             {
       
   929             // playlist name
       
   930             if (iAutoPlaylist->AutoPlaylistTypeL(aId) != EMPXNoAutoPlaylist)
       
   931                 {
       
   932                 name = iAutoPlaylist->AutoPlaylistNameL(aId).AllocL();
       
   933                 }
       
   934             else
       
   935                 {
       
   936                 name = iDbPlaylist->GetNameL(aId);
       
   937                 }
       
   938             break;
       
   939             }
       
   940         default:
       
   941             {
       
   942             // category name
       
   943             name = DbCategoryL(category)->GetNameL(aId);
       
   944             break;
       
   945             }
       
   946         }
       
   947 
       
   948     return name;
       
   949     }
       
   950 
       
   951 // ----------------------------------------------------------------------------
       
   952 // Get the URI of the row matching the given ID
       
   953 // ----------------------------------------------------------------------------
       
   954 //
       
   955 HBufC* CMPXDbHandler::GetUriMatchingIdL(
       
   956     const TUint32 aId) const
       
   957     {
       
   958     MPX_FUNC("CMPXDbHandler::GetUriMatchingIdL");
       
   959 
       
   960     HBufC* uri(NULL);
       
   961     switch (MPX_ITEM_CATEGORY(aId))
       
   962         {
       
   963         case EMPXCollection:
       
   964             {
       
   965             // song URI
       
   966             uri = iDbMusic->GetUriL(aId);
       
   967             break;
       
   968             }
       
   969         case EMPXPlaylist:
       
   970             {
       
   971             // playlist URI
       
   972             uri = iDbPlaylist->GetUriL(aId);
       
   973             break;
       
   974             }
       
   975         default:
       
   976             User::Leave(KErrNotSupported);
       
   977         }
       
   978 
       
   979     return uri;
       
   980     }
       
   981 
       
   982 // ----------------------------------------------------------------------------
       
   983 // Get category
       
   984 // ----------------------------------------------------------------------------
       
   985 //
       
   986 void CMPXDbHandler::GetCategoryL(
       
   987     const TUint32 aCategoryId,
       
   988     TMPXGeneralCategory aCategory,
       
   989     const TArray<TMPXAttribute>& aAttrs,
       
   990     CMPXMedia* aMedia)
       
   991     {
       
   992     MPX_FUNC("CMPXDbHandler::GetCategoryL");
       
   993 
       
   994     switch (aCategory)
       
   995         {
       
   996         case EMPXPlaylist:
       
   997             {
       
   998             if (iAutoPlaylist->AutoPlaylistTypeL(aCategoryId) != EMPXNoAutoPlaylist)
       
   999                 {
       
  1000                 iAutoPlaylist->GetPlaylistL(aCategoryId, aAttrs, *aMedia);
       
  1001                 }
       
  1002             else
       
  1003                 {
       
  1004                 iDbPlaylist->GetPlaylistL(aCategoryId, aAttrs, *aMedia);
       
  1005                 }
       
  1006             break;
       
  1007             }
       
  1008         default:
       
  1009             {
       
  1010             DbCategoryL(aCategory)->GetCategoryItemL(aCategoryId, aAttrs, *aMedia);
       
  1011             break;
       
  1012             }
       
  1013         }
       
  1014     }
       
  1015 
       
  1016 // ----------------------------------------------------------------------------
       
  1017 //  Get the duration for all songs
       
  1018 // ----------------------------------------------------------------------------
       
  1019 //
       
  1020 TInt CMPXDbHandler::GetAllSongsDurationL()
       
  1021     {
       
  1022     MPX_FUNC("CMPXDbHandler::GetAllSongsDurationL");
       
  1023     return iDbMusic->AllSongsDurationL();
       
  1024     }
       
  1025 
       
  1026 // ----------------------------------------------------------------------------
       
  1027 //  Get the duration for an artist
       
  1028 // ----------------------------------------------------------------------------
       
  1029 //
       
  1030 TInt CMPXDbHandler::GetArtistDurationL(
       
  1031     TInt aArtistId)
       
  1032     {
       
  1033     MPX_FUNC("CMPXDbHandler::GetArtistDurationL");
       
  1034     return iDbMusic->ArtistDurationL(aArtistId);
       
  1035     }
       
  1036 
       
  1037 // ----------------------------------------------------------------------------
       
  1038 //  Get the duration for an album
       
  1039 // ----------------------------------------------------------------------------
       
  1040 //
       
  1041 TInt CMPXDbHandler::GetAlbumDurationL(
       
  1042     TInt aAlbumId)
       
  1043     {
       
  1044     MPX_FUNC("CMPXDbHandler::GetAlbumDurationL");
       
  1045     return iDbMusic->AlbumDurationL(aAlbumId);
       
  1046     }
       
  1047 
       
  1048 // ----------------------------------------------------------------------------
       
  1049 //  Get the duration for an artist/album combination
       
  1050 // ----------------------------------------------------------------------------
       
  1051 //
       
  1052 TInt CMPXDbHandler::GetArtistAlbumDurationL(
       
  1053     TInt aArtistId,
       
  1054     TInt aAlbumId)
       
  1055     {
       
  1056     MPX_FUNC("CMPXDbHandler::GetArtistAlbumDurationL");
       
  1057     return iDbMusic->ArtistAlbumDurationL(aArtistId, aAlbumId);
       
  1058     }
       
  1059 
       
  1060 // ----------------------------------------------------------------------------
       
  1061 //  Get the duration for a composer
       
  1062 // ----------------------------------------------------------------------------
       
  1063 //
       
  1064 TInt CMPXDbHandler::GetComposerDurationL(
       
  1065     TInt aComposerId)
       
  1066     {
       
  1067     MPX_FUNC("CMPXDbHandler::GetComposerDurationL");
       
  1068     return iDbMusic->ComposerDurationL(aComposerId);
       
  1069     }
       
  1070 
       
  1071 // ----------------------------------------------------------------------------
       
  1072 //  Get the duration for a genre
       
  1073 // ----------------------------------------------------------------------------
       
  1074 //
       
  1075 TInt CMPXDbHandler::GetGenreDurationL(
       
  1076     TInt aGenreId)
       
  1077     {
       
  1078     MPX_FUNC("CMPXDbHandler::GetGenreDurationL");
       
  1079     return iDbMusic->GenreDurationL(aGenreId);
       
  1080     }
       
  1081 
       
  1082 // ----------------------------------------------------------------------------
       
  1083 //  Get the duration for a user playlist
       
  1084 // ----------------------------------------------------------------------------
       
  1085 //
       
  1086 TInt CMPXDbHandler::GetUserPlaylistDurationL(
       
  1087     TInt aPlaylistId)
       
  1088     {
       
  1089     MPX_FUNC("CMPXDbHandler::GetUserPlaylistDurationL");
       
  1090 
       
  1091     RArray<TMPXAttribute> attributes;
       
  1092     CleanupClosePushL(attributes);
       
  1093     attributes.AppendL(KMPXMediaGeneralId);
       
  1094     attributes.AppendL(TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralDuration));
       
  1095 
       
  1096     CMPXMediaArray* mediaArray = CMPXMediaArray::NewL();
       
  1097     CleanupStack::PushL(mediaArray);
       
  1098 
       
  1099     GetPlaylistSongsL(aPlaylistId, attributes.Array(), *mediaArray);
       
  1100 
       
  1101     TInt duration(0);
       
  1102     TInt count(mediaArray->Count());
       
  1103     for (TInt index = 0; index < count; ++index)
       
  1104         {
       
  1105         CMPXMedia* media((*mediaArray)[index]);
       
  1106         if (media->IsSupported(KMPXMediaGeneralDuration))
       
  1107             {
       
  1108             duration += media->ValueTObjectL<TInt>(KMPXMediaGeneralDuration);
       
  1109             }
       
  1110         }
       
  1111 
       
  1112     CleanupStack::PopAndDestroy(mediaArray);
       
  1113     CleanupStack::PopAndDestroy(&attributes);
       
  1114 
       
  1115     return duration;
       
  1116     }
       
  1117 
       
  1118 // ----------------------------------------------------------------------------
       
  1119 //  Get the duration for a playlist
       
  1120 // ----------------------------------------------------------------------------
       
  1121 //
       
  1122 TInt CMPXDbHandler::GetPlaylistDurationL(
       
  1123     TInt aPlaylistId)
       
  1124     {
       
  1125     MPX_FUNC("CMPXDbHandler::GetPlaylistDurationL");
       
  1126 
       
  1127     TInt duration(0);
       
  1128 
       
  1129     if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyPlayedPlaylist))
       
  1130         {
       
  1131         duration = iDbMusic->RecentlyPlayedDurationL();
       
  1132         }
       
  1133     else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXMostPlayedPlaylist))
       
  1134         {
       
  1135         duration = iDbMusic->MostPlayedDurationL();
       
  1136         }
       
  1137     else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyAddedPlaylist))
       
  1138         {
       
  1139         duration = iDbMusic->RecentlyAddedDurationL();
       
  1140         }
       
  1141     else
       
  1142         {
       
  1143         duration = GetUserPlaylistDurationL(aPlaylistId);
       
  1144         }
       
  1145 
       
  1146     return duration;
       
  1147     }
       
  1148 
       
  1149 // ----------------------------------------------------------------------------
       
  1150 // Find the number of items of a specified type
       
  1151 // ----------------------------------------------------------------------------
       
  1152 //
       
  1153 TInt CMPXDbHandler::NumberOfItemsL(
       
  1154     TMPXGeneralCategory aCategory)
       
  1155     {
       
  1156     MPX_FUNC("CMPXDbHandler::NumberOfItemsL");
       
  1157 
       
  1158     TInt count(0);
       
  1159     switch(aCategory)
       
  1160         {
       
  1161         case EMPXSong:
       
  1162             {
       
  1163             count = iDbMusic->CountL();
       
  1164             break;
       
  1165             }
       
  1166         case EMPXPlaylist:
       
  1167             {
       
  1168             // return the total number of playlists, including the system ones
       
  1169             count = iDbPlaylist->CountL() + EMPXAutoPlaylistCount;
       
  1170             break;
       
  1171             }
       
  1172         default:
       
  1173             {
       
  1174             count = DbCategoryL(aCategory)->CountL();
       
  1175             break;
       
  1176             }
       
  1177         }
       
  1178 
       
  1179     return count;
       
  1180     }
       
  1181 
       
  1182 // ----------------------------------------------------------------------------
       
  1183 // CMPXDbHandler::FindAllLC
       
  1184 // ----------------------------------------------------------------------------
       
  1185 //
       
  1186 CMPXMedia* CMPXDbHandler::FindAllLC(
       
  1187     const CMPXMedia& aCriteria,
       
  1188     const TArray<TMPXAttribute>& aAttrs)
       
  1189     {
       
  1190     MPX_FUNC("CMPXDbHandler::FindAllLC");
       
  1191 
       
  1192     // leave if the given media doesn't contain the following attributes
       
  1193     if (!aCriteria.IsSupported(KMPXMediaGeneralType) ||
       
  1194         !aCriteria.IsSupported(KMPXMediaGeneralCategory))
       
  1195         {
       
  1196         User::Leave(KErrArgument);
       
  1197         }
       
  1198 
       
  1199     RArray<TInt> supportedIds;
       
  1200     CleanupClosePushL(supportedIds);
       
  1201     supportedIds.AppendL(KMPXMediaIdContainer);
       
  1202     MPXDbCommonUtil::FillInSupportedUIDsL(aAttrs, supportedIds);
       
  1203 
       
  1204     CMPXMedia* entries = CMPXMedia::NewL(supportedIds.Array());
       
  1205     CleanupStack::PopAndDestroy(&supportedIds);
       
  1206     CleanupStack::PushL(entries);
       
  1207 
       
  1208     CMPXMediaArray* array = CMPXMediaArray::NewL();
       
  1209     CleanupStack::PushL(array);
       
  1210 
       
  1211     FindAllL(aCriteria, aAttrs, array);
       
  1212 
       
  1213     entries->SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType, EMPXGroup);
       
  1214     entries->SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory,
       
  1215         aCriteria.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory));
       
  1216     entries->SetCObjectValueL(KMPXMediaArrayContents, array);
       
  1217     entries->SetTObjectValueL<TInt>(KMPXMediaArrayCount, array->Count());
       
  1218 
       
  1219     CleanupStack::PopAndDestroy(array);
       
  1220     return entries;
       
  1221     }
       
  1222 
       
  1223 // ----------------------------------------------------------------------------
       
  1224 // Set the last refreshed time into the collection
       
  1225 // ----------------------------------------------------------------------------
       
  1226 //
       
  1227 void CMPXDbHandler::SetLastRefreshedTimeL(
       
  1228     TTime aTime)
       
  1229     {
       
  1230     MPX_FUNC("CMPXDbHandler::SetLastRefreshedTimeL");
       
  1231 
       
  1232     BeginTransactionL();
       
  1233     MPX_TRAPD(err, iDbAuxiliary->SetLastRefreshedTimeL(aTime));
       
  1234     EndTransactionL(err);
       
  1235     }
       
  1236 
       
  1237 // ----------------------------------------------------------------------------
       
  1238 // Get the last refreshed time from the collection
       
  1239 // ----------------------------------------------------------------------------
       
  1240 //
       
  1241 TTime CMPXDbHandler::GetLastRefreshedTimeL()
       
  1242     {
       
  1243     MPX_FUNC("CMPXDbHandler::GetLastRefreshedTimeL");
       
  1244     return iDbAuxiliary->LastRefreshedTimeL();
       
  1245     }
       
  1246 
       
  1247 // ----------------------------------------------------------------------------
       
  1248 // Set the db corrupted state for all drives
       
  1249 // ----------------------------------------------------------------------------
       
  1250 //
       
  1251 void CMPXDbHandler::SetDBCorruptedL(
       
  1252     TBool aCorrupted)
       
  1253     {
       
  1254     MPX_FUNC("CMPXDbHandler::SetDBCorruptedL");
       
  1255 
       
  1256     BeginTransactionL();
       
  1257     MPX_TRAPD(err, iDbAuxiliary->SetDBCorruptedL(aCorrupted));
       
  1258     EndTransactionL(err);
       
  1259     }
       
  1260 
       
  1261 // ----------------------------------------------------------------------------
       
  1262 // Gets the db corrupted state for all drives
       
  1263 // ----------------------------------------------------------------------------
       
  1264 //
       
  1265 TBool CMPXDbHandler::IsDBCorruptedL()
       
  1266     {
       
  1267     MPX_FUNC("CMPXDbHandler::IsDBCorruptedL");
       
  1268     return iDbAuxiliary->DBCorruptedL();
       
  1269     }
       
  1270 
       
  1271 // ----------------------------------------------------------------------------
       
  1272 // Have the databases been created?
       
  1273 // ----------------------------------------------------------------------------
       
  1274 //
       
  1275 TBool CMPXDbHandler::DatabaseCreated()
       
  1276     {
       
  1277     MPX_FUNC("CMPXDbHandler::DatabaseCreatedL");
       
  1278 
       
  1279     TBool AuxilaryDbIsRefreshed(EFalse);
       
  1280     TRAP_IGNORE(AuxilaryDbIsRefreshed = iDbAuxiliary->IsRefreshedL());
       
  1281     // If none of the databases were available, ie out of disk we return EFalse
       
  1282     return iDbManager->IsInitialized() && AuxilaryDbIsRefreshed;
       
  1283     }
       
  1284 
       
  1285 // ----------------------------------------------------------------------------
       
  1286 // Open a database
       
  1287 // ----------------------------------------------------------------------------
       
  1288 //
       
  1289 void CMPXDbHandler::OpenDatabaseL(
       
  1290     TInt aDrive)
       
  1291     {
       
  1292     MPX_FUNC("CMPXDbHandler::OpenDatabaseL");
       
  1293     MPX_DEBUG2( "CMPXDbHandler::OpenDatabaseL: %i", aDrive);
       
  1294     iDbManager->OpenDatabaseL(aDrive);
       
  1295 
       
  1296     // Verify the volume ID after a remount event
       
  1297     VerifyVolumeIdL();
       
  1298     }
       
  1299 
       
  1300 // ----------------------------------------------------------------------------
       
  1301 // Close a database
       
  1302 // ----------------------------------------------------------------------------
       
  1303 //
       
  1304 void CMPXDbHandler::CloseDatabaseL(
       
  1305     TInt aDrive)
       
  1306     {
       
  1307     MPX_FUNC("CMPXDbHandler::CloseDatabaseL");
       
  1308     MPX_DEBUG2( "CMPXDbHandler::CloseDatabaseL drive: %i", aDrive );
       
  1309     iDbManager->CloseDatabaseL(aDrive);
       
  1310     }
       
  1311 
       
  1312 // ----------------------------------------------------------------------------
       
  1313 // Re-create all databases
       
  1314 // ----------------------------------------------------------------------------
       
  1315 //
       
  1316 void CMPXDbHandler::ReCreateDatabasesL()
       
  1317     {
       
  1318     MPX_FUNC("CMPXDbHandler::ReCreateDatabasesL");
       
  1319     iDbManager->RecreateAllDatabasesL();
       
  1320     }
       
  1321 
       
  1322 // ----------------------------------------------------------------------------
       
  1323 // Set handler refresh status
       
  1324 // ----------------------------------------------------------------------------
       
  1325 //
       
  1326 void CMPXDbHandler::RefreshStartL()
       
  1327     {
       
  1328     MPX_FUNC("CMPXDbHandler::RefreshStartL");
       
  1329 
       
  1330     iOutOfDisk = EFalse;
       
  1331     // Re-open databases
       
  1332     // This is needed for the case where we were OOD before, but user
       
  1333     // has cleared some space but now try to refresh
       
  1334     MPX_TRAPD(err, iDbManager->InitDatabasesL(iDbDrives));
       
  1335     iCollectionOpen = ETrue;
       
  1336     // Update (synchronize) music basic table if it's not
       
  1337     // in sync with music table
       
  1338     if(iSynchronizeBasicTable)
       
  1339         {
       
  1340         iDbMusic->RefreshEndL();
       
  1341         }
       
  1342     iSynchronizeBasicTable = ETrue;
       
  1343 
       
  1344     if(err == KErrDiskFull)
       
  1345         {
       
  1346             iOutOfDisk = ETrue;
       
  1347         }
       
  1348 
       
  1349     if(!iOutOfDisk)
       
  1350     {
       
  1351         MPX_TRAP(err,CheckDiskSpaceOnDrivesL());
       
  1352 
       
  1353         if(err == KErrDiskFull)
       
  1354             {
       
  1355             iOutOfDisk = ETrue;
       
  1356             }
       
  1357     }
       
  1358     
       
  1359     iDbMusic->RefreshStartL();
       
  1360 
       
  1361     BeginTransactionL();
       
  1362     iRefresh = ETrue;
       
  1363     }
       
  1364 
       
  1365 // ----------------------------------------------------------------------------
       
  1366 // Re-set handler refresh status
       
  1367 // ----------------------------------------------------------------------------
       
  1368 //
       
  1369 void CMPXDbHandler::RefreshEndL()
       
  1370     {
       
  1371     MPX_FUNC("CMPXDbHandler::RefreshEndL");
       
  1372     iRefresh = EFalse;
       
  1373     EndTransactionL(KErrNone);
       
  1374     if (!iOutOfDisk)
       
  1375         {
       
  1376         // Write last refreshed time as current time
       
  1377         // This also sets corrupt = 0
       
  1378         TTime curTime;
       
  1379         curTime.HomeTime();
       
  1380         SetLastRefreshedTimeL(curTime);
       
  1381         }
       
  1382     iDbMusic->RefreshEndL();
       
  1383     //Update of music basic table fails when the collection is not open
       
  1384     //Next time the collection is opened the music basic table must be updated
       
  1385     if (iCollectionOpen )
       
  1386         {
       
  1387         iSynchronizeBasicTable = EFalse;
       
  1388         }
       
  1389     }
       
  1390 
       
  1391 // ----------------------------------------------------------------------------
       
  1392 // Notification of Mtp status change
       
  1393 // ----------------------------------------------------------------------------
       
  1394 //
       
  1395 void CMPXDbHandler::MtpStartL()
       
  1396     {
       
  1397     iMtpInUse = ETrue;
       
  1398     iOpOnDbCount = 0;
       
  1399     iDbManager->BeginL();
       
  1400     }
       
  1401 
       
  1402 // ----------------------------------------------------------------------------
       
  1403 // Notification of Mtp status change
       
  1404 // ----------------------------------------------------------------------------
       
  1405 //
       
  1406 void CMPXDbHandler::MtpEndL()
       
  1407     {
       
  1408     iMtpInUse = EFalse;
       
  1409     iOpOnDbCount = 0;
       
  1410     iDbManager->CommitL();
       
  1411     }
       
  1412 
       
  1413 // ----------------------------------------------------------------------------
       
  1414 // Get all records count for music
       
  1415 // ----------------------------------------------------------------------------
       
  1416 //
       
  1417 TUint CMPXDbHandler::GetMusicCountL(TInt aDrive)
       
  1418     {
       
  1419     MPX_FUNC("CMPXDbHandler::GetMusicCountL");
       
  1420     TUint total(0);
       
  1421 
       
  1422     //music
       
  1423     total += iDbMusic->GetDriveTrackCountL(aDrive);
       
  1424 
       
  1425     return total;
       
  1426     }
       
  1427 
       
  1428 // ----------------------------------------------------------------------------
       
  1429 // Get all records count for playlists
       
  1430 // ----------------------------------------------------------------------------
       
  1431 //
       
  1432 TUint CMPXDbHandler::GetPlaylistCountL(TInt aDrive)
       
  1433     {
       
  1434     MPX_FUNC("CMPXDbHandler::GetPlaylistCountL");
       
  1435     TUint total(0);
       
  1436 
       
  1437     //playlist
       
  1438     total += iDbPlaylist->GetDrivePlaylistCountL(aDrive);
       
  1439 
       
  1440     return total;
       
  1441     }
       
  1442 
       
  1443 // ----------------------------------------------------------------------------
       
  1444 // Get all records count for music and playlists
       
  1445 // ----------------------------------------------------------------------------
       
  1446 //
       
  1447 TUint CMPXDbHandler::GetTotalCountL(TInt aDrive)
       
  1448     {
       
  1449     MPX_FUNC("CMPXDbHandler::GetTotalCountL");
       
  1450     TUint total(0);
       
  1451 
       
  1452     //music
       
  1453     total += iDbMusic->GetDriveTrackCountL(aDrive);
       
  1454     //playlist
       
  1455     total += iDbPlaylist->GetDrivePlaylistCountL(aDrive);
       
  1456 
       
  1457     return total;
       
  1458     }
       
  1459 
       
  1460 // ----------------------------------------------------------------------------
       
  1461 // Get all records count for music and playlists
       
  1462 // ----------------------------------------------------------------------------
       
  1463 //
       
  1464 void CMPXDbHandler::GetMusicUriArrayL(TInt aDrive, TInt aFromID, TInt aRecords,
       
  1465                                       CDesCArray& aUriArr, TInt& aLastID)
       
  1466     {
       
  1467     MPX_FUNC("CMPXDbHandler::GetMusicUriArrayL");
       
  1468 
       
  1469     iDbMusic->GetMusicUriArrayL(aDrive,aFromID,aRecords,aUriArr,aLastID);
       
  1470     }
       
  1471 
       
  1472 // ----------------------------------------------------------------------------
       
  1473 // Get all records count for music and playlists
       
  1474 // ----------------------------------------------------------------------------
       
  1475 //
       
  1476 void CMPXDbHandler::GetPlaylistUriArrayL(TInt aDrive, TInt aFromID, TInt aRecords,
       
  1477                                          CDesCArray& aUriArr, TInt& aLastID)
       
  1478     {
       
  1479     MPX_FUNC("CMPXDbHandler::GetPlaylistUriArrayL");
       
  1480 
       
  1481     iDbPlaylist->GetPlaylistUriArrayL(aDrive,aFromID,aRecords,aUriArr,aLastID);
       
  1482     }
       
  1483 
       
  1484 // ----------------------------------------------------------------------------
       
  1485 // Starts a transaction on all databases
       
  1486 // ----------------------------------------------------------------------------
       
  1487 //
       
  1488 void CMPXDbHandler::BeginTransactionL()
       
  1489     {
       
  1490     MPX_FUNC("CMPXDbHandler::BeginTransactionL");
       
  1491 
       
  1492     if(!iMtpInUse)
       
  1493         {
       
  1494         iDbManager->BeginL();
       
  1495         }
       
  1496     }
       
  1497 
       
  1498 // ----------------------------------------------------------------------------
       
  1499 // Ends a transaction on all databases
       
  1500 // ----------------------------------------------------------------------------
       
  1501 //
       
  1502 void CMPXDbHandler::EndTransactionL(
       
  1503     TInt aError)
       
  1504     {
       
  1505     MPX_FUNC("CMPXDbHandler::EndTransactionL");
       
  1506 
       
  1507     if(iMtpInUse)
       
  1508         {
       
  1509         if (aError)
       
  1510             {
       
  1511             iOpOnDbCount = 0;
       
  1512             iDbManager->RollbackL();
       
  1513             User::Leave(aError);
       
  1514             }
       
  1515         
       
  1516         if(iOpOnDbCount >= KMaxOpInTransaction)
       
  1517             {
       
  1518             MPX_DEBUG2("CMPXDbHandler::EndTransactionL - %d>KMaxOpInTransaction Commiting",iOpOnDbCount);
       
  1519             iOpOnDbCount = 0;
       
  1520             iDbManager->CommitL();
       
  1521             iDbManager->BeginL();
       
  1522             }        
       
  1523         }
       
  1524     else
       
  1525         {
       
  1526         if (aError)
       
  1527             {
       
  1528             MPX_DEBUG2("CMPXDbHandler::EndTransactionL - Rollback [%d]", aError);
       
  1529 
       
  1530             iDbManager->RollbackL();
       
  1531             
       
  1532             // KSqlDbCorrupted indicates DB corrupted, need to recreate.
       
  1533             if ( aError != KSqlDbCorrupted )
       
  1534                 {
       
  1535                 User::Leave(aError);
       
  1536                 }
       
  1537             }
       
  1538         else
       
  1539             {
       
  1540             iDbManager->CommitL();
       
  1541             }
       
  1542         }
       
  1543     }
       
  1544 
       
  1545 // ----------------------------------------------------------------------------
       
  1546 // Checks if the database is currently in a transaction
       
  1547 // ----------------------------------------------------------------------------
       
  1548 //
       
  1549 TBool CMPXDbHandler::InTransaction()
       
  1550     {
       
  1551     MPX_FUNC("CMPXDbHandler::InTransaction");
       
  1552     return iDbManager->InTransaction();
       
  1553     }
       
  1554 
       
  1555 // ----------------------------------------------------------------------------
       
  1556 // Notifies the handler that the collection will be closed.
       
  1557 // It is called before closing the collection.
       
  1558 // ----------------------------------------------------------------------------
       
  1559 //
       
  1560 void CMPXDbHandler::PreCloseCollectionL()
       
  1561     {
       
  1562     MPX_FUNC("CMPXDbHandler::PreCloseCollectionL");
       
  1563     // Complete pending transaction and set the latest refresh time
       
  1564     // before closing the databases if collection close event occurs
       
  1565     // before the end of the refresh operation
       
  1566     if(iRefresh)
       
  1567         {
       
  1568         EndTransactionL(KErrNone);
       
  1569         if (!iOutOfDisk)
       
  1570             {
       
  1571             // Write last refreshed time as current time
       
  1572             // This also sets corrupt = 0
       
  1573             TTime curTime;
       
  1574             curTime.HomeTime();
       
  1575             SetLastRefreshedTimeL(curTime);
       
  1576             }
       
  1577         }
       
  1578     }
       
  1579 
       
  1580 // ----------------------------------------------------------------------------
       
  1581 // Notifies the handler that the collection was closed.
       
  1582 // ----------------------------------------------------------------------------
       
  1583 //
       
  1584 void CMPXDbHandler::CollectionClosed()
       
  1585     {
       
  1586     MPX_FUNC("CMPXDbHandler::CollectionClosed");
       
  1587 
       
  1588     iCollectionOpen = EFalse;
       
  1589     }
       
  1590 
       
  1591 // ----------------------------------------------------------------------------
       
  1592 //Notifies the handler that the collection was opened.
       
  1593 // ----------------------------------------------------------------------------
       
  1594 //
       
  1595 void CMPXDbHandler::CollectionOpenedL()
       
  1596     {
       
  1597     MPX_FUNC("CMPXDbHandler::CollectionOpened");
       
  1598 
       
  1599     iCollectionOpen = ETrue;
       
  1600     // Update (synchronize) music basic table if it's not
       
  1601     // in sync with music table
       
  1602     if(iSynchronizeBasicTable)
       
  1603         {
       
  1604         iDbMusic->RefreshEndL();
       
  1605         iSynchronizeBasicTable = EFalse;
       
  1606         }
       
  1607     }
       
  1608 
       
  1609 // ----------------------------------------------------------------------------
       
  1610 // Add song to collection
       
  1611 // ----------------------------------------------------------------------------
       
  1612 //
       
  1613 TUint32 CMPXDbHandler::DoAddSongL(
       
  1614     const CMPXMedia& aMedia,
       
  1615     CMPXMessageArray* aMessageArray)
       
  1616     {
       
  1617     MPX_FUNC("CMPXDbHandler::DoAddSongL");
       
  1618 
       
  1619     if (!aMedia.IsSupported(KMPXMediaGeneralUri))
       
  1620         {
       
  1621         User::Leave(KErrArgument);
       
  1622         }
       
  1623 
       
  1624     // add the song to the Music table
       
  1625     TDriveUnit drive(aMedia.ValueText(KMPXMediaGeneralUri));
       
  1626     TUint32 songId(iDbMusic->AddSongL(aMedia, drive,
       
  1627                                       iRefresh?NULL:aMessageArray));
       
  1628 
       
  1629     // update the playlist tables
       
  1630     // make sure the song db flags are reset and not just updated
       
  1631     iDbPlaylist->UpdateSongL(aMedia, ETrue);
       
  1632     
       
  1633     if(iMtpInUse)
       
  1634         {
       
  1635         ++iOpOnDbCount;
       
  1636         }
       
  1637 
       
  1638     return songId;
       
  1639     }
       
  1640 
       
  1641 // ----------------------------------------------------------------------------
       
  1642 // Add playlist to collection
       
  1643 // ----------------------------------------------------------------------------
       
  1644 //
       
  1645 TUint32 CMPXDbHandler::DoAddPlaylistL(
       
  1646     const CMPXMedia& aMedia)
       
  1647     {
       
  1648     MPX_FUNC("CMPXDbHandler::DoAddPlaylistL");
       
  1649 
       
  1650     CMPXMedia* media = CMPXMedia::NewL(aMedia);
       
  1651     CleanupStack::PushL(media);
       
  1652 
       
  1653     const TDesC& playlistUri = media->ValueText(KMPXMediaGeneralUri);
       
  1654 
       
  1655     //
       
  1656     // client has asked to create a virtual playlist if file name is not specified
       
  1657     // in the URI. In this case, generate URI for virtual playlist specified as
       
  1658     // follows:
       
  1659     //          <dir path>\timestamp.vir
       
  1660     //
       
  1661     TParsePtrC parser(playlistUri);
       
  1662 
       
  1663     if (!parser.NameOrExtPresent() ||
       
  1664         parser.IsNameWild() ||
       
  1665         parser.IsExtWild())
       
  1666         {
       
  1667         HBufC* newUri = HBufC::NewLC(parser.DriveAndPath().Length() + KMCMaxTextLen +
       
  1668             KMPXVirtualPlaylistExt().Length());
       
  1669 
       
  1670         TPtr ptr = newUri->Des();
       
  1671         ptr.Append(parser.DriveAndPath());
       
  1672         TTime time;
       
  1673         time.HomeTime();
       
  1674         ptr.AppendNum(time.Int64());
       
  1675         ptr.Append(KMPXVirtualPlaylistExt);
       
  1676 
       
  1677         // overwrite the old uri with the new one with full path and playlist
       
  1678         // playlist filename
       
  1679         media->SetTextValueL(KMPXMediaGeneralUri, *newUri);
       
  1680 
       
  1681         CleanupStack::PopAndDestroy(newUri);
       
  1682 
       
  1683         // set DbFlags to indicate that this is a virtual playlist
       
  1684         media->SetTObjectValueL<TUint>(KMPXMediaGeneralFlags,
       
  1685             KMPXMediaGeneralFlagsSetOrUnsetBit | KMPXMediaGeneralFlagsIsVirtual);
       
  1686         }
       
  1687 
       
  1688     // complete the song attributes from the music table
       
  1689     UpdatePlaylistSongInfoL(*media);
       
  1690 
       
  1691     // add playlist to the database
       
  1692     TUint32 playlistId = iDbPlaylist->AddPlaylistL(*media);
       
  1693 
       
  1694     CleanupStack::PopAndDestroy(media);
       
  1695     return playlistId;
       
  1696     }
       
  1697 
       
  1698 // ----------------------------------------------------------------------------
       
  1699 // Add song to playlist
       
  1700 // ----------------------------------------------------------------------------
       
  1701 //
       
  1702 TUint32 CMPXDbHandler::DoAddSongToPlaylistL(
       
  1703     const CMPXMedia& aMedia)
       
  1704     {
       
  1705     MPX_FUNC("CMPXDbHandler::DoAddSongToPlaylistL");
       
  1706 
       
  1707     CMPXMedia* media = CMPXMedia::NewL(aMedia);
       
  1708     CleanupStack::PushL(media);
       
  1709 
       
  1710     // complete the song attributes from the music table
       
  1711     UpdatePlaylistSongInfoL(*media);
       
  1712 
       
  1713     // add the songs to the playlist
       
  1714     TUint32 playlistId((media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2);
       
  1715 
       
  1716     CMPXMediaArray* ary( aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents) );
       
  1717     User::LeaveIfNull( ary );
       
  1718     iDbPlaylist->AddSongsL(playlistId,*ary);
       
  1719 
       
  1720     CleanupStack::PopAndDestroy(media);
       
  1721     return playlistId;
       
  1722     }
       
  1723 
       
  1724 // ----------------------------------------------------------------------------
       
  1725 // Update a song in the collection
       
  1726 // ----------------------------------------------------------------------------
       
  1727 //
       
  1728 CMPXDbActiveTask::TChangeVisibility CMPXDbHandler::DoUpdateSongL(
       
  1729     const CMPXMedia& aMedia,
       
  1730     CMPXMessageArray& aItemChangedMessages)
       
  1731     {
       
  1732     MPX_FUNC("CMPXDbHandler::DoUpdateSongL");
       
  1733 
       
  1734     CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
       
  1735 
       
  1736     TUint32 songId(0);
       
  1737 
       
  1738     if (aMedia.IsSupported(KMPXMediaGeneralId))
       
  1739         {
       
  1740         songId = (aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
       
  1741         }
       
  1742     if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  1743         {
       
  1744         const TDesC& uri = aMedia.ValueText(KMPXMediaGeneralUri);
       
  1745         songId = MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, uri, EFalse);
       
  1746         }
       
  1747     if (!songId)
       
  1748         {
       
  1749         User::Leave(KErrNotSupported);
       
  1750         }
       
  1751 
       
  1752     // Update the Music table
       
  1753     TRAPD(err, visibleChange = iDbMusic->UpdateSongL(songId, aMedia, aItemChangedMessages));
       
  1754 
       
  1755     // do not leave if song is not found in Music table
       
  1756     // leave for other errors such as disk full
       
  1757     if(err != KErrNone && err != KErrNotFound)
       
  1758         {
       
  1759         User::Leave(err);
       
  1760         }
       
  1761 
       
  1762     // Update the Playlist table
       
  1763     TBool visible = EFalse;
       
  1764 
       
  1765     TRAP( err, visible = iDbPlaylist->UpdateSongL(aMedia, EFalse, &aItemChangedMessages));
       
  1766 
       
  1767     // do not leave if song is not found in Playlist table
       
  1768     // leave for other errors such as disk full
       
  1769     if(err != KErrNone && err != KErrNotFound)
       
  1770         {
       
  1771         User::Leave(err);
       
  1772         }
       
  1773 
       
  1774     // make it visible if either table is updated
       
  1775     if (visible)
       
  1776         {
       
  1777         visibleChange = CMPXDbActiveTask::EAllVisible;
       
  1778         }
       
  1779 
       
  1780     return visibleChange;
       
  1781     }
       
  1782 
       
  1783 // ----------------------------------------------------------------------------
       
  1784 // Update a playlist in the collection
       
  1785 // ----------------------------------------------------------------------------
       
  1786 //
       
  1787 void CMPXDbHandler::DoUpdatePlaylistL(
       
  1788     const CMPXMedia& aMedia,
       
  1789     CMPXMessageArray& aMessageArray)
       
  1790     {
       
  1791     MPX_FUNC("CMPXDbHandler::DoUpdatePlaylistL");
       
  1792 
       
  1793     TUint32 playlistId(0);
       
  1794     TInt drive(0);
       
  1795 
       
  1796     CMPXMedia* media = CMPXMedia::NewL(aMedia);
       
  1797     CleanupStack::PushL(media);
       
  1798 
       
  1799 
       
  1800     ProcessPlaylistMediaL(*media, playlistId, drive);
       
  1801 
       
  1802     CMPXMessage* m1 = CMPXMessage::NewL();
       
  1803     CleanupStack::PushL(m1);
       
  1804     CMPXMessage* m2 = CMPXMessage::NewL();
       
  1805     CleanupStack::PushL(m2);
       
  1806 
       
  1807     // send 2 messages to notify the playlist change & to refresh the display (update playlist name)
       
  1808     MPXDbCommonUtil::FillItemChangedMessageL(*m1, playlistId, EMPXItemModified,
       
  1809             EMPXPlaylist, KDBPluginUid);
       
  1810 
       
  1811     MPXDbCommonUtil::FillItemChangedMessageL(*m2, EBrowsePlaylist, EMPXItemModified,
       
  1812                 EMPXPlaylist, KDBPluginUid);
       
  1813 
       
  1814     iDbPlaylist->UpdatePlaylistL(*media, *m1, drive);
       
  1815 
       
  1816     aMessageArray.AppendL(*m1);
       
  1817     aMessageArray.AppendL(*m2);
       
  1818 
       
  1819 
       
  1820     CleanupStack::PopAndDestroy(m2);
       
  1821     CleanupStack::PopAndDestroy(m1);
       
  1822     CleanupStack::PopAndDestroy(media);
       
  1823     }
       
  1824 
       
  1825 // ----------------------------------------------------------------------------
       
  1826 // Update a playlist in the collection
       
  1827 // ----------------------------------------------------------------------------
       
  1828 //
       
  1829 void CMPXDbHandler::DoUpdatePlaylistSongsL(
       
  1830     const CMPXMedia& aMedia,
       
  1831     CMPXMessage& aMessage)
       
  1832     {
       
  1833     MPX_FUNC("CMPXDbHandler::DoUpdatePlaylistSongsL");
       
  1834 
       
  1835     CMPXMedia* media = CMPXMedia::NewL(aMedia);
       
  1836     CleanupStack::PushL(media);
       
  1837 
       
  1838     TUint32 playlistId(0);
       
  1839     TInt drive(0);
       
  1840 
       
  1841     // get the playlist ID and drive ID
       
  1842     ProcessPlaylistMediaL(*media, playlistId, drive);
       
  1843     MPXDbCommonUtil::FillItemChangedMessageL(aMessage, playlistId, EMPXItemModified,
       
  1844         EMPXPlaylist, KDBPluginUid);
       
  1845 
       
  1846     // complete the song attributes from the Music table
       
  1847     UpdatePlaylistSongInfoL(*media);
       
  1848 
       
  1849     // delete existing songs for the playlist first
       
  1850     iDbPlaylist->Songs().DeleteSongsL(playlistId, drive);
       
  1851 
       
  1852     // add new songs to the playlist
       
  1853     CMPXMediaArray* ary( media->Value<CMPXMediaArray>(KMPXMediaArrayContents ) );
       
  1854     User::LeaveIfNull( ary );
       
  1855     iDbPlaylist->AddSongsL(playlistId, *ary);
       
  1856 
       
  1857     CleanupStack::PopAndDestroy(media);
       
  1858     }
       
  1859 
       
  1860 // ----------------------------------------------------------------------------
       
  1861 // Reorder a song in a playlist
       
  1862 // ----------------------------------------------------------------------------
       
  1863 //
       
  1864 void CMPXDbHandler::DoReorderPlaylistL(
       
  1865     const TMPXItemId& aPlaylistId,
       
  1866     const TMPXItemId& aSongId,
       
  1867     TUint aOriginalOrdinal,
       
  1868     TUint aNewOrdinal,
       
  1869     CMPXMessage& aMessage)
       
  1870     {
       
  1871     MPX_DEBUG1("-->CMPXDbHandler::DoReorderPlaylistL()");
       
  1872 
       
  1873     if (aOriginalOrdinal != aNewOrdinal)
       
  1874         {
       
  1875         iDbPlaylist->Songs().ReorderSongL(aPlaylistId, aSongId, aOriginalOrdinal, aNewOrdinal);
       
  1876 
       
  1877         MPXDbCommonUtil::FillItemChangedMessageL(aMessage, aPlaylistId.iId2, EMPXItemModified,
       
  1878             EMPXPlaylist, KDBPluginUid);
       
  1879         }
       
  1880 
       
  1881     MPX_DEBUG1("<--CMPXDbHandler::DoReorderPlaylistL()");
       
  1882     }
       
  1883 
       
  1884 // ----------------------------------------------------------------------------
       
  1885 // Delete a song from collection
       
  1886 // The function notifies collection model to perform deletion
       
  1887 // ----------------------------------------------------------------------------
       
  1888 //
       
  1889 void CMPXDbHandler::DoRemoveSongL(
       
  1890     TUint32 aSongId,
       
  1891     CDesCArray& aUriArray,
       
  1892     CMPXMessageArray& aItemChangedMessages,
       
  1893     TBool aDeleteRecord)
       
  1894     {
       
  1895     MPX_FUNC("CMPXDbHandler::DoRemoveSongL");
       
  1896 
       
  1897     // Get the song drive
       
  1898     TUint32 artistID(0);
       
  1899     TUint32 albumID(0);
       
  1900     TUint32 genreID(0);
       
  1901     TUint32 composerID(0);
       
  1902     TInt drive(0);
       
  1903 
       
  1904     // Get information from the Music table first
       
  1905     HBufC* uri = iDbMusic->GetSongInfoL(aSongId, artistID, albumID, genreID, composerID, drive);
       
  1906 
       
  1907     // add the URI to the return array
       
  1908     CleanupStack::PushL(uri);
       
  1909     aUriArray.AppendL(*uri);
       
  1910     CleanupStack::PopAndDestroy(uri);
       
  1911 
       
  1912     // Update the category records
       
  1913     TBool categoryExist( EFalse );
       
  1914     iDbArtist->DecrementSongsForCategoryL(artistID, drive, &aItemChangedMessages, categoryExist);
       
  1915     iDbAlbum->DecrementSongsForCategoryL(albumID, drive, &aItemChangedMessages, categoryExist, artistID);
       
  1916     iDbGenre->DecrementSongsForCategoryL(genreID, drive, &aItemChangedMessages, categoryExist);
       
  1917     iDbComposer->DecrementSongsForCategoryL(composerID, drive, &aItemChangedMessages, categoryExist);
       
  1918 
       
  1919     // Update the music table
       
  1920     TBool deleteRecord(ETrue);
       
  1921 
       
  1922 #if defined (__MTP_PROTOCOL_SUPPORT)
       
  1923     // Mark the song record as deleted if the following is true; otherwise, delete the
       
  1924     // song record.
       
  1925     //
       
  1926     // A client other than MTP has initiated this song deletion (aDeleteRecord is EFalse)
       
  1927     // and MTP has turned on its cenrep key to save deleted records and current number of
       
  1928     // saved deleted records has not exceeded its maximum, KMCMaxSavedDeletedRecords.
       
  1929     //
       
  1930     // Songs are marked as deleted in order to support auto-sync. MTP will delete these
       
  1931     // marked records at the end of each session via CleanupDeletedRecordsL.
       
  1932     //
       
  1933     // For performance consideration, if the number of saved records exceeds its maximum,
       
  1934     // song record will be deleted.
       
  1935     if (!aDeleteRecord && SaveDeletedSongs())
       
  1936         {
       
  1937         TUint32 savedDeletedRecordCount(iDbAuxiliary->SaveDeletedRecordCountL());
       
  1938         MPX_DEBUG2("Current number of saved deleted record count is %d", savedDeletedRecordCount);
       
  1939 
       
  1940         if (savedDeletedRecordCount < KMCMaxSavedDeletedRecords)
       
  1941             {
       
  1942             deleteRecord = EFalse;
       
  1943             TUint32 savedDeletedDriveRecordCount(iDbAuxiliary->SaveDeletedRecordCountL(drive));
       
  1944             iDbAuxiliary->SetSaveDeletedRecordCountL(drive,++savedDeletedDriveRecordCount);
       
  1945             }
       
  1946         }
       
  1947 #endif
       
  1948 
       
  1949     // delete the song from the Music table
       
  1950     iDbMusic->DeleteSongL(aSongId, drive, deleteRecord);
       
  1951 
       
  1952     // add the item changed message
       
  1953     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aSongId, EMPXItemDeleted,
       
  1954         EMPXSong, KDBPluginUid);
       
  1955         
       
  1956 
       
  1957     if(iMtpInUse)
       
  1958         {
       
  1959         ++iOpOnDbCount;
       
  1960         }
       
  1961     }
       
  1962 
       
  1963 // ----------------------------------------------------------------------------
       
  1964 // Delete a song from playlist tables
       
  1965 // ----------------------------------------------------------------------------
       
  1966 //
       
  1967 void CMPXDbHandler::DoRemoveSongFromPlaylistL(TUint32 aSongId,CMPXMessageArray& aItemChangedMessages)
       
  1968     {
       
  1969     MPX_FUNC("CMPXDbHandler::DoRemoveSongFromPlaylistL");
       
  1970     // delete song from the playlist tables on all drives
       
  1971     iDbPlaylist->DeleteSongL(aSongId, aItemChangedMessages);
       
  1972     }
       
  1973 
       
  1974 // ----------------------------------------------------------------------------
       
  1975 // Removes a category of songs from the music collection,
       
  1976 // and its corresponding category in the lookup table
       
  1977 // ----------------------------------------------------------------------------
       
  1978 //
       
  1979 void CMPXDbHandler::DoRemoveSongsMatchingCategoryL(
       
  1980     TMPXGeneralCategory aCategory,
       
  1981     TUint32 aCategoryId,
       
  1982     CDesCArray& aUriArray,
       
  1983     CMPXMessageArray& aItemChangedMessages)
       
  1984     {
       
  1985     MPX_FUNC("CMPXDbHandler::DoRemoveSongsMatchingCategoryL");
       
  1986 
       
  1987     // get the songs for the specified category
       
  1988     CMPXMediaArray* songs = CMPXMediaArray::NewL();
       
  1989     CleanupStack::PushL(songs);
       
  1990 
       
  1991     RArray<TMPXAttribute> attributes;
       
  1992     CleanupClosePushL(attributes);
       
  1993     attributes.AppendL(KMPXMediaGeneralId);
       
  1994 
       
  1995     switch (aCategory)
       
  1996         {
       
  1997         case EMPXArtist:
       
  1998             {
       
  1999             iDbMusic->GetSongsForArtistL(aCategoryId, attributes.Array(), *songs);
       
  2000             break;
       
  2001             }
       
  2002         case EMPXAlbum:
       
  2003             {
       
  2004             iDbMusic->GetSongsForAlbumL(aCategoryId, attributes.Array(), *songs);
       
  2005             break;
       
  2006             }
       
  2007         case EMPXGenre:
       
  2008             {
       
  2009             iDbMusic->GetSongsForGenreL(aCategoryId, attributes.Array(), *songs);
       
  2010             break;
       
  2011             }
       
  2012         case EMPXComposer:
       
  2013             {
       
  2014             iDbMusic->GetSongsForComposerL(aCategoryId, attributes.Array(), *songs);
       
  2015             break;
       
  2016             }
       
  2017         default:
       
  2018             User::Leave(KErrNotSupported);
       
  2019         }
       
  2020 
       
  2021     CleanupStack::PopAndDestroy(&attributes);
       
  2022 
       
  2023     // iterate the songs and remove them one by one
       
  2024     // so records in the category tables can also be updated
       
  2025     TInt count(songs->Count());
       
  2026     for (TInt index = 0; index < count; ++index)
       
  2027         {
       
  2028         CMPXMedia* song = (*songs)[index];
       
  2029         if (song->IsSupported(KMPXMediaGeneralId))
       
  2030             {
       
  2031             DoRemoveSongL((song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2,
       
  2032                 aUriArray, aItemChangedMessages, EFalse);
       
  2033             DoRemoveSongFromPlaylistL((song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2,aItemChangedMessages);
       
  2034             }
       
  2035         }
       
  2036 
       
  2037     CleanupStack::PopAndDestroy(songs);
       
  2038     }
       
  2039 
       
  2040 // ----------------------------------------------------------------------------------------------------------
       
  2041 // Delete songs for the specified artist and album from collection
       
  2042 // ----------------------------------------------------------------------------------------------------------
       
  2043 //
       
  2044 void CMPXDbHandler::DoRemoveSongsMatchingArtistAndAlbumL(
       
  2045     TUint32 aArtistId,
       
  2046     TUint32 aAlbumId,
       
  2047     CDesCArray& aUriArray,
       
  2048     CMPXMessageArray& aItemChangedMessages)
       
  2049     {
       
  2050     MPX_FUNC("CMPXDbHandler::RemoveSongsMatchingArtistAndAlbumL");
       
  2051 
       
  2052     // get the songs for the specified artist and album
       
  2053     CMPXMediaArray* songs = CMPXMediaArray::NewL();
       
  2054     CleanupStack::PushL(songs);
       
  2055 
       
  2056     RArray<TMPXAttribute> attributes;
       
  2057     CleanupClosePushL (attributes);
       
  2058     attributes.AppendL(KMPXMediaGeneralId);
       
  2059 
       
  2060     iDbMusic->GetSongsForArtistAndAlbumL(aArtistId, aAlbumId, attributes.Array(), *songs);
       
  2061     CleanupStack::PopAndDestroy(&attributes);
       
  2062 
       
  2063     // iterate the songs and remove them one by one
       
  2064     // so records in the category tables can also be updated
       
  2065     TInt count(songs->Count());
       
  2066     for (TInt index = 0; index < count; ++index)
       
  2067         {
       
  2068         CMPXMedia* song = (*songs)[index];
       
  2069         if (song->IsSupported(KMPXMediaGeneralId))
       
  2070             {
       
  2071             DoRemoveSongL( song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId),
       
  2072                 aUriArray, aItemChangedMessages, EFalse);
       
  2073             DoRemoveSongFromPlaylistL(song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId),aItemChangedMessages);
       
  2074             }
       
  2075         }
       
  2076 
       
  2077     CleanupStack::PopAndDestroy(songs);
       
  2078     }
       
  2079 
       
  2080 // ----------------------------------------------------------------------------
       
  2081 // Remove all playlists from collection
       
  2082 // ----------------------------------------------------------------------------
       
  2083 //
       
  2084 void CMPXDbHandler::DoRemoveAllPlaylistsL()
       
  2085     {
       
  2086     MPX_FUNC("CMPXDbHandler::DoRemoveAllPlaylistsL");
       
  2087     iDbPlaylist->DeleteAllPlaylistsL();
       
  2088     }
       
  2089 
       
  2090 // ----------------------------------------------------------------------------
       
  2091 // Remove specified playlist
       
  2092 // ----------------------------------------------------------------------------
       
  2093 //
       
  2094 void CMPXDbHandler::DoRemovePlaylistL(
       
  2095     TUint32 aPlaylistId,
       
  2096     CDesCArray& aUriArray,
       
  2097     CMPXMessageArray& aItemChangedMessages)
       
  2098     {
       
  2099     MPX_FUNC("CMPXDbHandler::DoRemovePlaylistL");
       
  2100 
       
  2101     HBufC* uri(iDbPlaylist->DeletePlaylistL(aPlaylistId));
       
  2102     if (uri)
       
  2103         {
       
  2104         CleanupStack::PushL(uri);
       
  2105         aUriArray.AppendL(*uri);
       
  2106         CleanupStack::PopAndDestroy(uri);
       
  2107         }
       
  2108 
       
  2109     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aPlaylistId, EMPXItemDeleted,
       
  2110         EMPXPlaylist, KDBPluginUid);
       
  2111     }
       
  2112 
       
  2113 // ----------------------------------------------------------------------------
       
  2114 // Remove song from playlist songs table
       
  2115 // ----------------------------------------------------------------------------
       
  2116 //
       
  2117 void CMPXDbHandler::DoRemoveSongFromPlaylistL(
       
  2118     TUint32 aPlaylistId,
       
  2119     const TMPXItemId& aSongId,
       
  2120     TInt aOrdinal,
       
  2121     CMPXMessageArray& aItemChangedMessages)
       
  2122     {
       
  2123     MPX_FUNC("CMPXDbHandler::DoRemoveSongFromPlaylistL");
       
  2124     MPX_DEBUG5("CMPXDbHandler::DoRemoveSongFromPlaylistL(playlist 0x%x, songId [0x%x,0x%x], ordinal %d)",
       
  2125         aPlaylistId, aSongId.iId1, aSongId.iId2, aOrdinal);
       
  2126 
       
  2127     // delete the song
       
  2128     iDbPlaylist->DeleteSongL(aPlaylistId, aSongId.iId2, aOrdinal);
       
  2129 
       
  2130     // Send a playlist modified message
       
  2131     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aPlaylistId, EMPXItemModified,
       
  2132         EMPXPlaylist, KDBPluginUid);
       
  2133 
       
  2134     // Send a message on the song in the playlist that is deleted
       
  2135     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aSongId, EMPXItemDeleted,
       
  2136         EMPXSong, KDBPluginUid);
       
  2137     }
       
  2138 
       
  2139 // ----------------------------------------------------------------------------
       
  2140 // CMPXDbHandler::DoCleanupDeletedRecordsL
       
  2141 // ----------------------------------------------------------------------------
       
  2142 //
       
  2143 void CMPXDbHandler::DoCleanupDeletedRecordsL()
       
  2144     {
       
  2145     MPX_FUNC("CMPXDbHandler::DoCleanupDeletedRecordsL");
       
  2146 
       
  2147     // delete all marked records from the Music table
       
  2148     iDbMusic->CleanupL();
       
  2149 
       
  2150     // reset the count in the Auxiliary table
       
  2151     iDbAuxiliary->SetSaveDeletedRecordCountL(KDbManagerAllDrives,0);
       
  2152     }
       
  2153 
       
  2154 // ----------------------------------------------------------------------------
       
  2155 // FindAllL
       
  2156 // ----------------------------------------------------------------------------
       
  2157 //
       
  2158 void CMPXDbHandler::FindAllL(
       
  2159     const CMPXMedia& aCriteria,
       
  2160     const TArray<TMPXAttribute>& aAttrs,
       
  2161     CMPXMediaArray* aMediaArray)
       
  2162     {
       
  2163     MPX_FUNC("CMPXDbHandler::FindAllL");
       
  2164 
       
  2165     RArray<TMPXAttribute> attributes;
       
  2166     CleanupClosePushL(attributes);
       
  2167     MPXUser::MergeAttributeL(aAttrs, attributes);
       
  2168 
       
  2169     TMPXGeneralCategory category = aCriteria.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
  2170     switch (category)
       
  2171         {
       
  2172         case EMPXPlaylist:
       
  2173             {
       
  2174             TUint32 playlistId(0);
       
  2175             if (aCriteria.IsSupported(KMPXMediaGeneralId))
       
  2176                 {
       
  2177                 playlistId = (aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
       
  2178                 }
       
  2179 
       
  2180             if (iAutoPlaylist->AutoPlaylistTypeL(playlistId) != EMPXNoAutoPlaylist)
       
  2181                 {
       
  2182                 CMPXMedia* media = CMPXMedia::NewL();
       
  2183                 CleanupStack::PushL(media);
       
  2184 
       
  2185                 iAutoPlaylist->GetPlaylistL(playlistId, aAttrs, *media);
       
  2186 
       
  2187                 aMediaArray->AppendL(*media);
       
  2188                 CleanupStack::PopAndDestroy(media);
       
  2189                 }
       
  2190             else
       
  2191                 {
       
  2192                 iDbPlaylist->FindAllL(aCriteria, attributes.Array(), *aMediaArray);
       
  2193                 }
       
  2194 
       
  2195             break;
       
  2196             }
       
  2197         case EMPXSong:
       
  2198             {
       
  2199             FindSongL(aCriteria, attributes.Array(), *aMediaArray);
       
  2200             break;
       
  2201             }
       
  2202         default:
       
  2203             {
       
  2204             DbCategoryL(category)->FindAllL(aCriteria, attributes.Array(), *aMediaArray);
       
  2205             break;
       
  2206             }
       
  2207         }
       
  2208 
       
  2209     CleanupStack::PopAndDestroy(&attributes);
       
  2210     }
       
  2211 
       
  2212 // ----------------------------------------------------------------------------
       
  2213 // Get song(s) from the music table that match the given criteria
       
  2214 // ----------------------------------------------------------------------------
       
  2215 //
       
  2216 void CMPXDbHandler::FindSongL(
       
  2217     const CMPXMedia& aCriteria,
       
  2218     const TArray<TMPXAttribute>& aAttrs,
       
  2219     CMPXMediaArray& aMediaArray)
       
  2220     {
       
  2221     MPX_FUNC("CMPXDbCollection::FindSongL");
       
  2222 
       
  2223     TMPXGeneralType type = aCriteria.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
       
  2224 
       
  2225     TUint32 id(0);
       
  2226     if (aCriteria.IsSupported(KMPXMediaGeneralId))
       
  2227         {
       
  2228         id = (aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
       
  2229         }
       
  2230 
       
  2231     TUint32 containerId(0);
       
  2232     if (aCriteria.IsSupported(KMPXMediaGeneralContainerId))
       
  2233         {
       
  2234         containerId = aCriteria.ValueTObjectL<TUint32>(KMPXMediaGeneralContainerId);
       
  2235         }
       
  2236 
       
  2237     //////////////////////////////////////////////////////////////////////
       
  2238     // Find songs in the specified playlist
       
  2239     //////////////////////////////////////////////////////////////////////
       
  2240     TMPXGeneralCategory cat(MPX_ITEM_CATEGORY(id));
       
  2241 
       
  2242     if (type == EMPXGroup &&
       
  2243         (cat == EMPXPlaylist ||
       
  2244         MPX_ITEM_CATEGORY(containerId) == EMPXPlaylist))
       
  2245         {
       
  2246         TUint32 playlistId = (cat == EMPXPlaylist) ?
       
  2247             id : (containerId & KMCCategoryMask);
       
  2248 
       
  2249         GetPlaylistSongsL(playlistId, aAttrs, aMediaArray);
       
  2250         }
       
  2251 
       
  2252     //////////////////////////////////////////////////////////////////////
       
  2253     // Find a particular song in the specified playlist. This fills the
       
  2254     // song with info from Playlist table first then overwrites it with
       
  2255     // info from Songs table if Songs table where this song is located
       
  2256     // is present in order to support the display of song titles in a
       
  2257     // playlist when memory card is removed if the playlist refers to
       
  2258     // songs on the memory card. Caller of this scenario is OpenL/MediaL.
       
  2259     // When user attempts to play a track in an auto-playlist, we will
       
  2260     // find the song from Songs table directly since auto-playlists are
       
  2261     // not stored in the Playlist table. Auto-playlists are query-based,
       
  2262     // therefore, when memory card is removed, songs on the memory card
       
  2263     // will not be shown in the auto-playlist; hence they do not exhibit
       
  2264     // the same challenge as user created playlists.
       
  2265     //////////////////////////////////////////////////////////////////////
       
  2266     else if (type == EMPXItem &&
       
  2267         cat == EMPXCollection &&
       
  2268         MPX_ITEM_CATEGORY(containerId) == EMPXPlaylist)
       
  2269         {
       
  2270         if (iAutoPlaylist->AutoPlaylistTypeL(containerId) != EMPXNoAutoPlaylist)
       
  2271             {
       
  2272             // auto playlist song, get the song details from the music table
       
  2273             iDbMusic->FindSongsL(id, 0, type, aCriteria, aAttrs, aMediaArray);
       
  2274             }
       
  2275         else
       
  2276             {
       
  2277             GetPlaylistSongL(id, containerId, aAttrs, aMediaArray);
       
  2278             }
       
  2279         }
       
  2280 
       
  2281     //////////////////////////////////////////////////////////////////////
       
  2282     // Find all songs, all songs in a particular album and/or artist, or
       
  2283     // a particular song
       
  2284     //////////////////////////////////////////////////////////////////////
       
  2285     else
       
  2286         {
       
  2287         iDbMusic->FindSongsL(id, containerId, type, aCriteria, aAttrs, aMediaArray);
       
  2288         }
       
  2289     }
       
  2290 
       
  2291 // ----------------------------------------------------------------------------
       
  2292 // Get song(s) in the specified playlist
       
  2293 // ----------------------------------------------------------------------------
       
  2294 //
       
  2295 void CMPXDbHandler::GetPlaylistSongsL(
       
  2296     TUint32 aPlaylistId,
       
  2297     const TArray<TMPXAttribute>& aAttrs,
       
  2298     CMPXMediaArray& aMediaArray)
       
  2299     {
       
  2300     MPX_FUNC("CMPXDbHandler::GetPlaylistSongsL");
       
  2301     MPX_DEBUG2("CMPXDbHandler::GetPlaylistSongsL(0x%x)", aPlaylistId);
       
  2302 
       
  2303     // check the auto playlists first
       
  2304     if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyPlayedPlaylist))
       
  2305         {
       
  2306         iDbMusic->GetRecentlyPlayedSongsL(aAttrs, aMediaArray);
       
  2307         }
       
  2308     else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXMostPlayedPlaylist))
       
  2309         {
       
  2310         iDbMusic->GetMostPlayedSongsL(aAttrs, aMediaArray);
       
  2311         }
       
  2312     else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyAddedPlaylist))
       
  2313         {
       
  2314         iDbMusic->GetRecentlyAddedSongsL(aAttrs, aMediaArray);
       
  2315         }
       
  2316     else
       
  2317         {
       
  2318         TInt attrCount(aAttrs.Count());
       
  2319         if ( attrCount > 1 || (attrCount == 1 && !(aAttrs[0] == KMPXMediaGeneralId)) )
       
  2320             {
       
  2321 	        TInt plDrive(iDbPlaylist->GetDriveIdL(aPlaylistId));
       
  2322 	        MPX_TRAPD(err, iDbMusic->GetAllSongsL(plDrive, aPlaylistId, aAttrs, aMediaArray));
       
  2323 
       
  2324 	        // song not found in Music table
       
  2325 	        if (err == KErrNotFound)
       
  2326 	            {
       
  2327 	            //
       
  2328 	            // Leave with KErrNotFound if one of the following is true:
       
  2329 	            // 1) the requested song is in an auto playlist. Since auto-playlist isn't
       
  2330 	            //    stored in playlist tables, we won't be able to retrieve info elsewhere
       
  2331 	            // 2) the requested song is in a user playlist but we cannot find the song
       
  2332 	            //    info from playlist tables either
       
  2333 	            //
       
  2334 	           if (EMPXNoAutoPlaylist != iAutoPlaylist->AutoPlaylistTypeL(aPlaylistId) ||
       
  2335 	                !iDbPlaylist->Songs().GetSongsL(aPlaylistId, aAttrs, aMediaArray))
       
  2336 	               {
       
  2337 	               User::Leave(KErrNotFound);
       
  2338 	               }
       
  2339 	            }
       
  2340 	        else
       
  2341 	            {
       
  2342 	            // ignore the error if KErrNotFound
       
  2343 	            User::LeaveIfError(err);
       
  2344 	            }
       
  2345             }
       
  2346         else
       
  2347             {
       
  2348             // get ids of the songs in the playlist
       
  2349             iDbPlaylist->Songs().GetSongsL(aPlaylistId, aMediaArray);
       
  2350             }
       
  2351         }
       
  2352     }
       
  2353 
       
  2354 // ----------------------------------------------------------------------------
       
  2355 // Find all albums or the albums for a specified artist
       
  2356 // ----------------------------------------------------------------------------
       
  2357 //
       
  2358 void CMPXDbHandler::FindAlbumL(
       
  2359     const CMPXMedia& aCriteria,
       
  2360     const TArray<TMPXAttribute>& aAttrs,
       
  2361     CMPXMediaArray& aMediaArray)
       
  2362     {
       
  2363     MPX_FUNC("CMPXDbHandler::FindAlbumL");
       
  2364 
       
  2365     TMPXGeneralType type = aCriteria.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
       
  2366 
       
  2367     TUint32 id(0);
       
  2368     if (aCriteria.IsSupported(KMPXMediaGeneralId))
       
  2369         {
       
  2370         id = aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  2371         }
       
  2372 
       
  2373     if ((type == EMPXGroup) && (MPX_ITEM_CATEGORY(id) == EMPXArtist))
       
  2374         {
       
  2375         // get all the albums for the artist
       
  2376         GetAlbumsMatchingArtistL(id, aAttrs, aMediaArray);
       
  2377         }
       
  2378     else
       
  2379         {
       
  2380         // look up all albums from album table
       
  2381         iDbAlbum->FindAllL(aCriteria, aAttrs, aMediaArray);
       
  2382         }
       
  2383     }
       
  2384 
       
  2385 // ----------------------------------------------------------------------------
       
  2386 // Extracts the playlist ID and drive ID from a playlist media instance
       
  2387 // ----------------------------------------------------------------------------
       
  2388 //
       
  2389 void CMPXDbHandler::ProcessPlaylistMediaL(
       
  2390     CMPXMedia& aMedia,
       
  2391     TUint32& aPlaylistId,
       
  2392     TInt& aPlaylistDriveId)
       
  2393     {
       
  2394     MPX_FUNC("CMPXDbHandler::ProcessPlaylistMediaL");
       
  2395 
       
  2396     if (aMedia.IsSupported(KMPXMediaGeneralId))
       
  2397         {
       
  2398         aPlaylistId = aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  2399 
       
  2400         if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  2401             {
       
  2402             // find drive id of the playlist
       
  2403             aPlaylistDriveId = TDriveUnit(aMedia.ValueText(KMPXMediaGeneralUri));
       
  2404             }
       
  2405         else
       
  2406             {
       
  2407             // Find drive Id(s) of corresponding Playlist Id
       
  2408             aPlaylistDriveId = iDbPlaylist->GetDriveIdL(aPlaylistId);
       
  2409             }
       
  2410         }
       
  2411     else if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  2412         {
       
  2413         const TDesC& playlistUri = aMedia.ValueText(KMPXMediaGeneralUri);
       
  2414         // find drive id of the playlist
       
  2415         aPlaylistDriveId = TDriveUnit(playlistUri);
       
  2416 
       
  2417         // aMedia does not have an ID, make sure the add it
       
  2418         aPlaylistId = GetPlaylistIdMatchingUriL(playlistUri);
       
  2419         aMedia.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, aPlaylistId);
       
  2420         }
       
  2421     else
       
  2422         {
       
  2423         User::Leave(KErrArgument);
       
  2424         }
       
  2425     }
       
  2426 
       
  2427 // ----------------------------------------------------------------------------
       
  2428 // Makes sure that all songs in the specified playlist have the ID, title and URI attributes
       
  2429 // ----------------------------------------------------------------------------
       
  2430 //
       
  2431 void CMPXDbHandler::UpdatePlaylistSongInfoL(
       
  2432     CMPXMedia& aMedia)
       
  2433     {
       
  2434     MPX_FUNC("CMPXDbHandler::UpdatePlaylistSongInfoL");
       
  2435 
       
  2436     CMPXMediaArray* mediaArray = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  2437     User::LeaveIfNull(mediaArray);
       
  2438 
       
  2439     // make sure each song has Id, Uri, and Title before they can be added to playlist
       
  2440     TInt count(mediaArray->Count());
       
  2441     for (TInt i = 0; i < count; ++i)
       
  2442         {
       
  2443         CMPXMedia* element = mediaArray->AtL(i);
       
  2444 
       
  2445         // copy each song to deal w/ global heap issues
       
  2446         CMPXMedia* entry = CMPXMedia::NewL(*element);
       
  2447         CleanupStack::PushL(entry);
       
  2448 
       
  2449         // song has everything, go to next song
       
  2450         if (entry->IsSupported(KMPXMediaGeneralUri) &&
       
  2451             entry->IsSupported(KMPXMediaGeneralId) &&
       
  2452             entry->IsSupported(KMPXMediaGeneralTitle))
       
  2453             {
       
  2454             // pop entry to maintain CleanupStack
       
  2455             CleanupStack::PopAndDestroy(entry);
       
  2456             continue;
       
  2457             }
       
  2458 
       
  2459         // songs must contain (at minimum) an Uri or an Id
       
  2460         if (!entry->IsSupported(KMPXMediaGeneralUri) &&
       
  2461             !entry->IsSupported(KMPXMediaGeneralId))
       
  2462             {
       
  2463             User::Leave(KErrArgument);
       
  2464             }
       
  2465 
       
  2466         // get Id
       
  2467         if (!entry->IsSupported(KMPXMediaGeneralId))
       
  2468             {
       
  2469             // fill in the ID if not present
       
  2470             TParsePtrC parser(entry->ValueText(KMPXMediaGeneralUri));
       
  2471             entry->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId,
       
  2472                 MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, parser.FullName(), EFalse));
       
  2473             }
       
  2474 
       
  2475         CMPXMedia* song(NULL);
       
  2476 
       
  2477         // update songs info
       
  2478         TInt error(iDbMusic->GetSongL(*entry, song));
       
  2479         TBool result (ETrue);
       
  2480 
       
  2481         // error can only be KErrNone or KErrNotFound
       
  2482         // from CMPXDbMusic::GetSongL
       
  2483         // if not found in Music, get info from PlaylistSongs (PlaylistSongs & PlaylistSongInfo) DB
       
  2484         if (error == KErrNotFound)
       
  2485             {
       
  2486             RArray<TMPXAttribute> attributes;
       
  2487             CleanupClosePushL(attributes);
       
  2488             attributes.AppendL(TMPXAttribute(KMPXMediaIdGeneral,
       
  2489                 EMPXMediaGeneralId | EMPXMediaGeneralTitle | EMPXMediaGeneralUri | EMPXMediaGeneralFlags));
       
  2490 
       
  2491             // this song doesn't exist in Music table. This song is either a broken link or
       
  2492             // is of an unsupported song type that exists in the file system. Broken links
       
  2493             // have already been marked as such during playlist import.
       
  2494             result = iDbPlaylist->Songs().GetSongL(entry->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId), attributes.Array(), song);
       
  2495             if (!result)
       
  2496                 {
       
  2497                 // song is a broken link
       
  2498                 //TUint flags = KMPXMediaGeneralFlagsSetOrUnsetBit;
       
  2499                 //flags |= KMPXMediaGeneralFlagsIsInvalid; // set flag
       
  2500                 //t->SetTObjectValueL<TUint>( KMPXMediaGeneralFlags, flags );
       
  2501 
       
  2502                 if (entry->IsSupported(KMPXMediaGeneralUri))
       
  2503                     {
       
  2504                     // no valid Id but has Uri, just verify Title is present
       
  2505                     // this is the case if the song is a broken link or podcast
       
  2506                     if (!entry->IsSupported(KMPXMediaGeneralTitle))
       
  2507                         {
       
  2508                         // does not have Title, make up the Title from file name
       
  2509                         TParsePtrC parser(entry->ValueText(KMPXMediaGeneralUri));
       
  2510                         entry->SetTextValueL(KMPXMediaGeneralTitle, parser.Name());
       
  2511                         }
       
  2512                     }
       
  2513                 else
       
  2514                     {
       
  2515                     // no valid Id & no Uri, bad argument
       
  2516                     User::Leave(KErrArgument);
       
  2517                     }
       
  2518                 }
       
  2519             CleanupStack::PopAndDestroy(&attributes);
       
  2520             }
       
  2521 
       
  2522         // update attributes
       
  2523         CleanupStack::PushL(song);
       
  2524 
       
  2525         // song not found in Music or Playlist DB, update entry
       
  2526         if(error == KErrNotFound && !result)
       
  2527             {
       
  2528             mediaArray->InsertL(*entry,i);
       
  2529             }
       
  2530         else  // found in DB, replace entry
       
  2531             {
       
  2532             mediaArray->InsertL(*song,i);
       
  2533             }
       
  2534 
       
  2535         // replace element in the array
       
  2536         CleanupStack::PopAndDestroy(song);
       
  2537         CleanupStack::PopAndDestroy(entry);
       
  2538         mediaArray->Remove(i+1);
       
  2539         }
       
  2540     }
       
  2541 
       
  2542 // ----------------------------------------------------------------------------
       
  2543 // CMPXDbHandler::ProcessMusicFoldersL
       
  2544 // ----------------------------------------------------------------------------
       
  2545 //
       
  2546 void CMPXDbHandler::ProcessMusicFoldersL(
       
  2547     const CDesCArray& aFolders)
       
  2548     {
       
  2549     MPX_FUNC("CMPXDbHandler::ProcessMusicFoldersL");
       
  2550 
       
  2551     TInt count(aFolders.MdcaCount());
       
  2552     for (TInt i = 0; i < count; ++i)
       
  2553         {
       
  2554         TPtrC16 folder = aFolders.MdcaPoint(i);
       
  2555 
       
  2556         // check if disk is inserted and act accordingly
       
  2557         TDriveUnit driveUnit(folder);
       
  2558         if (!iFs.IsValidDrive(driveUnit))
       
  2559             {
       
  2560             User::Leave(KErrArgument);
       
  2561             }
       
  2562 
       
  2563         // append the drive to the drive list
       
  2564         iDbDrives.AppendL(driveUnit);
       
  2565 
       
  2566         // make sure the folder is created
       
  2567         TVolumeInfo info;
       
  2568         if (iFs.Volume(info, driveUnit) == KErrNone)
       
  2569            {
       
  2570             if (!BaflUtils::PathExists(iFs, folder))
       
  2571                 {
       
  2572                 // create music folder if necessary
       
  2573                 TInt err(iFs.MkDirAll(folder));
       
  2574                 MPX_DEBUG3("Try to create music folder %S return code %d", &folder, err);
       
  2575                 if (err != KErrAlreadyExists)
       
  2576                     {
       
  2577                     User::LeaveIfError(err);
       
  2578                     }
       
  2579                 }
       
  2580             }
       
  2581         }
       
  2582     }
       
  2583 
       
  2584 // ----------------------------------------------------------------------------
       
  2585 // CMPXDbHandler::DbCategoryL
       
  2586 // ----------------------------------------------------------------------------
       
  2587 //
       
  2588 CMPXDbCategory* CMPXDbHandler::DbCategoryL(
       
  2589     TMPXGeneralCategory aCategory) const
       
  2590     {
       
  2591     MPX_FUNC("CMPXDbHandler::DbCategoryL");
       
  2592 
       
  2593     CMPXDbCategory* dbCategory(NULL);
       
  2594     switch (aCategory)
       
  2595         {
       
  2596         case EMPXArtist:
       
  2597             {
       
  2598             dbCategory = (CMPXDbCategory*)iDbArtist;
       
  2599             break;
       
  2600             }
       
  2601         case EMPXAlbum:
       
  2602             {
       
  2603             dbCategory = (CMPXDbCategory*)iDbAlbum;
       
  2604             break;
       
  2605             }
       
  2606         case EMPXGenre:
       
  2607             {
       
  2608             dbCategory = (CMPXDbCategory*)iDbGenre;
       
  2609             break;
       
  2610             }
       
  2611         case EMPXComposer:
       
  2612             {
       
  2613             dbCategory = (CMPXDbCategory*)iDbComposer;
       
  2614             break;
       
  2615             }
       
  2616         default:
       
  2617             User::Leave(KErrNotSupported);
       
  2618         }
       
  2619 
       
  2620     return dbCategory;
       
  2621     }
       
  2622 
       
  2623 // ----------------------------------------------------------------------------
       
  2624 // Verifies that the volume ID of the database matches the drive
       
  2625 // ----------------------------------------------------------------------------
       
  2626 //
       
  2627 void CMPXDbHandler::VerifyVolumeIdL()
       
  2628     {
       
  2629     MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL <--");
       
  2630 
       
  2631     TInt count( iDbDrives.Count() );
       
  2632     for( TInt i=0; i<count; ++i )
       
  2633         {
       
  2634         if( iDbManager->IsOpen( iDbDrives[i] ) )
       
  2635             {
       
  2636             TVolumeInfo volInfo;
       
  2637             iFs.Volume(volInfo, iDbDrives[i] );
       
  2638             TUint curId(volInfo.iUniqueID);
       
  2639 
       
  2640             TInt volId = iDbAuxiliary->IdL( iDbDrives[i] );
       
  2641 
       
  2642             // New database, no volume id set, mask out top bit because this is an uint
       
  2643             //
       
  2644             MPX_DEBUG3("CMPXDBHandler::VerifyVolumeIdL drive:%i db:%i", curId, volId);
       
  2645             if( volId == 0 )
       
  2646                 {
       
  2647                 MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -- New ID");
       
  2648                 BeginTransactionL();
       
  2649                 TRAPD( err, iDbAuxiliary->SetIdL( iDbDrives[i], curId&0x7FFFFFFF ) );
       
  2650                 EndTransactionL( err );
       
  2651                 
       
  2652                 // KSqlDbCorrupted indicates DB corrupted, need to recreate.
       
  2653                 if ( err == KSqlDbCorrupted )
       
  2654                     {
       
  2655                     MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL -- Corrupted DB");     
       
  2656                     iDbManager->RecreateDatabaseL(iDbDrives[i]);
       
  2657                     BeginTransactionL();
       
  2658                     TRAPD(err, iDbAuxiliary->SetDBCorruptedL( ETrue ) );
       
  2659                     EndTransactionL( err );
       
  2660                     }
       
  2661                 }
       
  2662             // Unmatched volume id, mark db as corrupt and break
       
  2663             //
       
  2664             else if ( (curId&0x7FFFFFFF) != (volId&0x7FFFFFFFF) )
       
  2665                 {
       
  2666                 MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -- ID match FAILED");
       
  2667                 iDbManager->RecreateDatabaseL(iDbDrives[i]);
       
  2668                 BeginTransactionL();
       
  2669                 TRAPD(err, iDbAuxiliary->SetDBCorruptedL( ETrue ) );
       
  2670                 EndTransactionL( err );
       
  2671                 }
       
  2672             }
       
  2673         }
       
  2674     MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -->");
       
  2675     }
       
  2676 
       
  2677 
       
  2678 // ----------------------------------------------------------------------------
       
  2679 // Checks if there is a drive that has a low disk space
       
  2680 // ----------------------------------------------------------------------------
       
  2681 //
       
  2682 void CMPXDbHandler::CheckDiskSpaceOnDrivesL()
       
  2683     {
       
  2684     MPX_DEBUG1("CMPXDbHandler::CheckDiskSpaceOnDrivesL <--");
       
  2685 
       
  2686     TInt count( iDbDrives.Count() );
       
  2687     for( TInt index=0; index<count; ++index )
       
  2688         {
       
  2689         iDbManager->CheckDiskSpaceL(iDbDrives[index]);
       
  2690         }
       
  2691     MPX_DEBUG1("CMPXDbHandler::CheckDiskSpaceOnDrivesL -->");
       
  2692     }
       
  2693 
       
  2694 #if defined (__MTP_PROTOCOL_SUPPORT)
       
  2695 
       
  2696 // ----------------------------------------------------------------------------
       
  2697 // CMPXDbHandler::SaveDeletedSongs
       
  2698 // ----------------------------------------------------------------------------
       
  2699 //
       
  2700 TBool CMPXDbHandler::SaveDeletedSongs()
       
  2701     {
       
  2702     MPX_FUNC("CMPXDbHandler::SaveDeletedSongs");
       
  2703 
       
  2704     TBool saveDeletedSongs(ETrue);
       
  2705     CRepository* cenrep(NULL);
       
  2706     MPX_TRAPD(error, cenrep = CRepository::NewL(KMPXMtpSettings));
       
  2707     if (!error)
       
  2708         {
       
  2709         cenrep->Get(KMPXMtpSaveDeletedRecordFlag, saveDeletedSongs);
       
  2710         delete cenrep;
       
  2711         MPX_DEBUG2("MTP indicated to save deleted songs? %d", saveDeletedSongs);
       
  2712         }
       
  2713 
       
  2714     return saveDeletedSongs;
       
  2715     }
       
  2716 
       
  2717 #endif
       
  2718 
       
  2719 #ifdef RD_MULTIPLE_DRIVE
       
  2720 
       
  2721 // ----------------------------------------------------------------------------------------------------------
       
  2722 // Retrieve all visible music folder locations
       
  2723 // ----------------------------------------------------------------------------------------------------------
       
  2724 //
       
  2725 CDesCArrayFlat* CMPXDbHandler::GetMusicFoldersL()
       
  2726     {
       
  2727     MPX_FUNC("CMPXDbHandler::GetMusicFoldersL()");
       
  2728     TDriveList driveList;
       
  2729     TInt driveCount(0);
       
  2730     User::LeaveIfError(DriveInfo::GetUserVisibleDrives(iFs, driveList, driveCount));
       
  2731     MPX_DEBUG2 ("CMPXDbHandler::GetMusicFoldersL() - driveCount = %d", driveCount);
       
  2732 
       
  2733     CDesCArrayFlat* folders = new (ELeave) CDesCArrayFlat(1); // granularity
       
  2734     CleanupStack::PushL(folders);
       
  2735 
       
  2736     for (TInt i = EDriveA; i <= EDriveZ; i++)
       
  2737         {
       
  2738         if ((driveList[i]) && (!IsRemoteDrive(static_cast<TDriveNumber>(i))))
       
  2739             {
       
  2740             if (i == EDriveC)
       
  2741                 {
       
  2742                 // Append the default phone memory path to the list
       
  2743                 // of music folders
       
  2744                 TPtrC rootPath(PathInfo::PhoneMemoryRootPath());
       
  2745                 folders->AppendL(rootPath);
       
  2746                 MPX_DEBUG2("CMPXDbHandler::GetMusicFoldersL() - adding...%S", &rootPath);
       
  2747                 }
       
  2748             else
       
  2749                 {
       
  2750                 // Get drive letter
       
  2751                 TChar driveChar;
       
  2752                 User::LeaveIfError(iFs.DriveToChar(i, driveChar));
       
  2753 
       
  2754                 // Append visible drive to list of music folders
       
  2755                 TBuf<2> drive;
       
  2756                 drive.Append(driveChar);
       
  2757                 drive.Append(_L(":"));
       
  2758                 folders->AppendL(drive);
       
  2759                 MPX_DEBUG2 ("CMPXDbHandler::GetMusicFoldersL() - adding...%S", &drive);
       
  2760                 }
       
  2761             }
       
  2762         }
       
  2763 
       
  2764     CleanupStack::Pop(folders);
       
  2765     return folders;
       
  2766     }
       
  2767 
       
  2768 #endif // RD_MULTIPLE_DRIVE
       
  2769 
       
  2770 // ----------------------------------------------------------------------------
       
  2771 // CMPXDbHandler::AddCategoryItemL
       
  2772 // ----------------------------------------------------------------------------
       
  2773 //
       
  2774 TUint32 CMPXDbHandler::AddCategoryItemL(
       
  2775     TMPXGeneralCategory aCategory,
       
  2776     const TDesC& aName,
       
  2777     TInt aDriveId,
       
  2778     CMPXMessageArray* aItemChangedMessages,
       
  2779     TBool& aItemExist)
       
  2780     {
       
  2781     MPX_FUNC("CMPXDbHandler::AddCategoryItemL()");
       
  2782 
       
  2783     MPX_PERF_START(CMPXDbHandler_AddCategoryItemL);
       
  2784 
       
  2785     TBool newRecord(EFalse);
       
  2786     TUint32 id(DbCategoryL(aCategory)->AddItemL(aName, aDriveId, newRecord, (aCategory != EMPXGenre)));
       
  2787     if (newRecord && aItemChangedMessages)
       
  2788         {
       
  2789         MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id, EMPXItemInserted,
       
  2790             aCategory, KDBPluginUid);
       
  2791         }
       
  2792     aItemExist = !newRecord;
       
  2793     MPX_PERF_END(CMPXDbHandler_AddCategoryItemL);
       
  2794 
       
  2795     return id;
       
  2796     }
       
  2797 
       
  2798 TUint32 CMPXDbHandler::AddCategoryItemL(
       
  2799         TMPXGeneralCategory aCategory,
       
  2800         const TDesC& aName,
       
  2801         TUint32 aArtist,
       
  2802         const TDesC& aArt,
       
  2803         TInt aDriveId,
       
  2804         CMPXMessageArray* aItemChangedMessages,
       
  2805         TBool& aItemExist)
       
  2806 	{
       
  2807     MPX_FUNC("CMPXDbHandler::AddCategoryItemL()");
       
  2808 
       
  2809     MPX_PERF_START(CMPXDbHandler_AddCategoryItemL);
       
  2810 
       
  2811     TBool newRecord(EFalse);
       
  2812 
       
  2813     TUint32 id = 0;
       
  2814     if ( aArtist )
       
  2815         {
       
  2816         id = iDbAlbum->AddItemL(aName, aArtist, aArt, aDriveId, newRecord, (aCategory != EMPXGenre));
       
  2817         }
       
  2818     else
       
  2819         {
       
  2820         id = iDbArtist->AddItemL(aName, aArt, aDriveId, newRecord, (aCategory != EMPXGenre));
       
  2821         }
       
  2822         
       
  2823     if (newRecord && aItemChangedMessages)
       
  2824         {
       
  2825         MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id, EMPXItemInserted,
       
  2826             aCategory, KDBPluginUid);
       
  2827         }
       
  2828     aItemExist = !newRecord;
       
  2829     MPX_PERF_END(CMPXDbHandler_AddCategoryItemL);
       
  2830 
       
  2831     return id;
       
  2832 	}
       
  2833 
       
  2834 void CMPXDbHandler::UpdateCategoryItemL(
       
  2835 		TMPXGeneralCategory aCategory,
       
  2836 		TUint32 aCategoryId,
       
  2837 		const CMPXMedia& aMedia,
       
  2838 		TInt aDrive, 
       
  2839 		CMPXMessageArray* aItemChangedMessages)
       
  2840 	{
       
  2841 	switch(aCategory)
       
  2842 	    {
       
  2843 	    case EMPXAlbum:
       
  2844             iDbAlbum->UpdateItemL(aCategoryId, aMedia, aDrive, aItemChangedMessages);
       
  2845 	        break;
       
  2846 	        
       
  2847 	    case EMPXArtist:
       
  2848 	        iDbArtist->UpdateItemL(aCategoryId, aMedia, aDrive, aItemChangedMessages);
       
  2849 	        break;
       
  2850 
       
  2851 	    default:
       
  2852             DbCategoryL(aCategory)->UpdateItemL(aCategoryId, aMedia, aDrive, aItemChangedMessages);
       
  2853 	        break;
       
  2854 	    }
       
  2855 	}
       
  2856 // ----------------------------------------------------------------------------
       
  2857 // CMPXDbHandler::DeleteSongForCategoryL
       
  2858 // ----------------------------------------------------------------------------
       
  2859 //
       
  2860 void CMPXDbHandler::DeleteSongForCategoryL(
       
  2861     TMPXGeneralCategory aCategory,
       
  2862     TUint32 aCategoryId,
       
  2863     TInt aDriveId,
       
  2864     CMPXMessageArray* aItemChangedMessages,
       
  2865     TBool& aItemExist)
       
  2866     {
       
  2867     MPX_FUNC("CMPXDbHandler::DeleteSongForCategoryL");
       
  2868     DbCategoryL(aCategory)->DecrementSongsForCategoryL(aCategoryId, aDriveId,
       
  2869         aItemChangedMessages, aItemExist);
       
  2870     }
       
  2871 
       
  2872 // ----------------------------------------------------------------------------
       
  2873 // CMPXDbHandler::HandlePlayCountModifiedL
       
  2874 // ----------------------------------------------------------------------------
       
  2875 //
       
  2876 void CMPXDbHandler::HandlePlayCountModifiedL(
       
  2877     CMPXMessageArray& aItemChangedMessages)
       
  2878     {
       
  2879     MPX_FUNC("CMPXDbHandler::HandlePlayCountModifiedL");
       
  2880 
       
  2881     TUint32 plId(iAutoPlaylist->AutoPlaylistIdL(EMPXMostPlayedPlaylist));
       
  2882 
       
  2883     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, plId, EMPXItemModified,
       
  2884         EMPXSong, KDBPluginUid, plId);
       
  2885 
       
  2886     // Force the deprecated ID attribute
       
  2887     aItemChangedMessages[aItemChangedMessages.Count() - 1]->
       
  2888         SetTObjectValueL<TMPXItemId>(KMPXMessageMediaDeprecatedId, plId);
       
  2889     }
       
  2890 
       
  2891 // ----------------------------------------------------------------------------------------------------------
       
  2892 // CMPXDbHandler::HandlePlaybackTimeModifiedL
       
  2893 // ----------------------------------------------------------------------------------------------------------
       
  2894 //
       
  2895 void CMPXDbHandler::HandlePlaybackTimeModifiedL(
       
  2896     CMPXMessageArray& aItemChangedMessages)
       
  2897     {
       
  2898     MPX_FUNC("CMPXDbHandler::HandlePlaybackTimeModifiedL");
       
  2899 
       
  2900     TUint32 plId(iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyPlayedPlaylist));
       
  2901 
       
  2902     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, plId, EMPXItemModified,
       
  2903         EMPXSong, KDBPluginUid, plId);
       
  2904 
       
  2905     // Force the deprecated ID attribute
       
  2906     aItemChangedMessages[aItemChangedMessages.Count() - 1]->
       
  2907         SetTObjectValueL<TMPXItemId>(KMPXMessageMediaDeprecatedId, plId);
       
  2908     }
       
  2909 
       
  2910 
       
  2911 // ---------------------------------------------------------------------------
       
  2912 // CMPXDbHandler::IsRemoteDrive
       
  2913 // ---------------------------------------------------------------------------
       
  2914 //
       
  2915 TBool CMPXDbHandler::IsRemoteDrive(TDriveNumber aDrive)
       
  2916     {
       
  2917     return iDbManager->IsRemoteDrive(aDrive);
       
  2918     }
       
  2919 
       
  2920 TInt CMPXDbHandler::HandlePlaylistDurationL(TUint32 aPlaylistId)
       
  2921 	{
       
  2922 	return GetPlaylistDurationL(aPlaylistId);
       
  2923 	}
       
  2924 
       
  2925 TInt CMPXDbHandler::HandleGetAlbumsCountForArtistL(TUint32 aArtistId)
       
  2926 	{
       
  2927 	return iDbAlbum->GetAlbumsCountForArtistL(aArtistId);
       
  2928 	}
       
  2929 
       
  2930 TBool CMPXDbHandler::HandleIsUnknownArtistL(TUint32 aArtistId)
       
  2931     {
       
  2932     return iDbArtist->IsUnknownArtistL(aArtistId);
       
  2933     }
       
  2934 
       
  2935 TUint32 CMPXDbHandler::HandleArtistForAlbumL(const TUint32 aAlbumId)
       
  2936     {
       
  2937     return iDbMusic->ArtistForAlbumL(aAlbumId);
       
  2938     }
       
  2939 // End of file