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