mpserviceplugins/mpxsqlitedbhgplugin/src/mpxdbhandler.cpp
branchRCL_3
changeset 52 14979e23cb5e
equal deleted inserted replaced
50:26a1709b9fec 52:14979e23cb5e
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This class is 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);
       
   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 Media Wall
       
   967 // ----------------------------------------------------------------------------
       
   968 //
       
   969 void CMPXDbHandler::GetAllAlbumsMediaWallL(
       
   970     const TArray<TMPXAttribute>& aAttrs,
       
   971     CMPXMediaArray* aMediaArray)
       
   972     {
       
   973     MPX_FUNC("CMPXDbHandler::GetAllAlbumsL");
       
   974     iDbAlbum->GetAllCategoryItemsMediaWallL(aAttrs, *aMediaArray);
       
   975     }
       
   976 
       
   977 // ----------------------------------------------------------------------------
       
   978 // Get all albums for the given artist ID
       
   979 // ----------------------------------------------------------------------------
       
   980 //
       
   981 void CMPXDbHandler::GetAlbumsMatchingArtistL(
       
   982     TUint aArtistId,
       
   983     const TArray<TMPXAttribute>& aAttrs,
       
   984     CMPXMediaArray& aMediaArray)
       
   985     {
       
   986     MPX_FUNC("CMPXDbHandler::GetAlbumsMatchingArtistL");
       
   987     RArray<TMPXAttribute> attributes;
       
   988     CleanupClosePushL( attributes );
       
   989 
       
   990     TBool tryGetSongCount = EFalse;
       
   991     TInt attrCount(aAttrs.Count());
       
   992     TInt i = 0;
       
   993     for (i = 0; i < attrCount; i++)
       
   994         {
       
   995         TInt contentId(aAttrs[i].ContentId());
       
   996         TUint attributeId(aAttrs[i].AttributeId());
       
   997 
       
   998         if (contentId == KMPXMediaIdGeneral && attributeId & EMPXMediaGeneralCount)
       
   999             {
       
  1000             MPX_DEBUG1("    EMPXMediaGeneralCount");
       
  1001 
       
  1002             attributes.AppendL(TMPXAttribute(KMPXMediaIdGeneral, attributeId & ~EMPXMediaGeneralCount));
       
  1003 
       
  1004             tryGetSongCount = ETrue;
       
  1005             break;
       
  1006             }
       
  1007 
       
  1008         attributes.AppendL(aAttrs[i]);
       
  1009         }
       
  1010 
       
  1011     for (TInt j = i+1; j < attrCount; j++)
       
  1012         {
       
  1013         attributes.AppendL(aAttrs[j]);
       
  1014         }
       
  1015     iDbAlbum->GetSubCategoryItemsL(EMPXArtist, aArtistId, attributes.Array(), aMediaArray);
       
  1016     CleanupStack::PopAndDestroy(&attributes);
       
  1017 
       
  1018     TInt pPath(0);
       
  1019     if (aMediaArray.Count())
       
  1020         {
       
  1021         CMPXMedia* pMedia = aMediaArray[0];
       
  1022         if (pMedia->IsSupported(KMPXMediaGeneralValue))
       
  1023             {
       
  1024             pPath = pMedia->ValueTObjectL<TInt>(KMPXMediaGeneralValue);
       
  1025             MPX_ASSERT(pPath);
       
  1026             }
       
  1027         }
       
  1028 
       
  1029     TInt albumCount(aMediaArray.Count());
       
  1030     if (albumCount)
       
  1031         {
       
  1032         if ( tryGetSongCount )
       
  1033             {
       
  1034             TInt startIndex = pPath ? 1 : 0;
       
  1035 
       
  1036             for (TInt i = startIndex; i < albumCount; i++)
       
  1037                 {
       
  1038                 CMPXMedia* media = aMediaArray[i];
       
  1039                 TUint32 albumId((media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)));
       
  1040 
       
  1041                 TInt songCount = iDbAlbum->GetSongsCountInAlbumMatchingArtistL(aArtistId, albumId);
       
  1042 
       
  1043                 media->SetTObjectValueL<TInt>(KMPXMediaGeneralCount, songCount );
       
  1044                 MPX_DEBUG2("    SongCount[%d]", songCount );
       
  1045                 }
       
  1046             }
       
  1047         }
       
  1048     }
       
  1049 
       
  1050 // ----------------------------------------------------------------------------
       
  1051 // Get all genres
       
  1052 // ----------------------------------------------------------------------------
       
  1053 //
       
  1054 void CMPXDbHandler::GetAllGenresL(
       
  1055     const TArray<TMPXAttribute>& aAttrs,
       
  1056     CMPXMediaArray* aMediaArray)
       
  1057     {
       
  1058     MPX_FUNC("CMPXDbHandler::GetAllGenresL");
       
  1059     iDbGenre->GetAllCategoryItemsL(aAttrs, *aMediaArray);
       
  1060     }
       
  1061 
       
  1062 // ----------------------------------------------------------------------------
       
  1063 // Get all composers
       
  1064 // ----------------------------------------------------------------------------
       
  1065 //
       
  1066 void CMPXDbHandler::GetAllComposersL(
       
  1067     const TArray<TMPXAttribute>& aAttrs,
       
  1068     CMPXMediaArray* aMediaArray)
       
  1069     {
       
  1070     MPX_FUNC("CMPXDbHandler::GetAllComposersL");
       
  1071     iDbComposer->GetAllCategoryItemsL(aAttrs, *aMediaArray);
       
  1072     }
       
  1073 
       
  1074 // ----------------------------------------------------------------------------
       
  1075 // Get the playlist ID of the playlist that matches the given URI
       
  1076 // ----------------------------------------------------------------------------
       
  1077 //
       
  1078 TUint32 CMPXDbHandler::GetPlaylistIdMatchingUriL(
       
  1079     const TDesC& aUri)
       
  1080     {
       
  1081     MPX_FUNC("CMPXDbHandler::GetPlaylistIdMatchingUriL");
       
  1082     return iDbPlaylist->GetIdL(aUri);
       
  1083     }
       
  1084 
       
  1085 // ----------------------------------------------------------------------------
       
  1086 // CMPXDbHandler::IsAutoPlaylistL
       
  1087 // ----------------------------------------------------------------------------
       
  1088 //
       
  1089 TBool CMPXDbHandler::IsAutoPlaylistL(
       
  1090     TUint32 aPlaylistId)
       
  1091     {
       
  1092     MPX_FUNC("CMPXDbHandler::IsAutoPlaylistL");
       
  1093     return (iAutoPlaylist->AutoPlaylistTypeL(aPlaylistId) != EMPXNoAutoPlaylist);
       
  1094     }
       
  1095 
       
  1096 // ----------------------------------------------------------------------------
       
  1097 // Get all user playlist names
       
  1098 // ----------------------------------------------------------------------------
       
  1099 //
       
  1100 void CMPXDbHandler::GetAllPlaylistsL(
       
  1101     CMPXMediaArray* aMediaArray,
       
  1102     const TArray<TMPXAttribute>& aAttrs)
       
  1103     {
       
  1104     MPX_FUNC("CMPXDbHandler::GetAllPlaylistsL");
       
  1105     iDbPlaylist->GetAllPlaylistsL(aAttrs, *aMediaArray);
       
  1106     }
       
  1107 
       
  1108 // ----------------------------------------------------------------------------
       
  1109 // Get all system playlist names
       
  1110 // ----------------------------------------------------------------------------
       
  1111 //
       
  1112 void CMPXDbHandler::GetAllSystemPlaylistNamesL(
       
  1113     CMPXMediaArray* aMediaArray)
       
  1114     {
       
  1115     MPX_FUNC("CMPXDbHandler::GetAllSystemPlaylistNamesL()");
       
  1116     iAutoPlaylist->GetAllPlaylistsL(*aMediaArray);
       
  1117     }
       
  1118 
       
  1119 // ----------------------------------------------------------------------------
       
  1120 // Get the name of the row matching the given ID
       
  1121 // ----------------------------------------------------------------------------
       
  1122 //
       
  1123 HBufC* CMPXDbHandler::GetNameMatchingIdL(
       
  1124     const TUint32 aId) const
       
  1125     {
       
  1126     MPX_FUNC("CMPXDbHandler::GetNameMatchingIdL()");
       
  1127 
       
  1128     HBufC* name(NULL);
       
  1129     TMPXGeneralCategory category(MPX_ITEM_CATEGORY(aId));
       
  1130     switch (category)
       
  1131         {
       
  1132         case EMPXCollection:
       
  1133             {
       
  1134             // song name
       
  1135             name = iDbMusic->GetNameL(aId);
       
  1136             break;
       
  1137             }
       
  1138         case EMPXPlaylist:
       
  1139             {
       
  1140             // playlist name
       
  1141             if (iAutoPlaylist->AutoPlaylistTypeL(aId) != EMPXNoAutoPlaylist)
       
  1142                 {
       
  1143                 name = iAutoPlaylist->AutoPlaylistNameL(aId).AllocL();
       
  1144                 }
       
  1145             else
       
  1146                 {
       
  1147                 name = iDbPlaylist->GetNameL(aId);
       
  1148                 }
       
  1149             break;
       
  1150             }
       
  1151         default:
       
  1152             {
       
  1153             // category name
       
  1154             name = DbCategoryL(category)->GetNameL(aId);
       
  1155             break;
       
  1156             }
       
  1157         }
       
  1158 
       
  1159     return name;
       
  1160     }
       
  1161 
       
  1162 // ----------------------------------------------------------------------------
       
  1163 // Get the URI of the row matching the given ID
       
  1164 // ----------------------------------------------------------------------------
       
  1165 //
       
  1166 HBufC* CMPXDbHandler::GetUriMatchingIdL(
       
  1167     const TUint32 aId) const
       
  1168     {
       
  1169     MPX_FUNC("CMPXDbHandler::GetUriMatchingIdL");
       
  1170 
       
  1171     HBufC* uri(NULL);
       
  1172     switch (MPX_ITEM_CATEGORY(aId))
       
  1173         {
       
  1174         case EMPXCollection:
       
  1175             {
       
  1176             // song URI
       
  1177             uri = iDbMusic->GetUriL(aId);
       
  1178             break;
       
  1179             }
       
  1180         case EMPXPlaylist:
       
  1181             {
       
  1182             // playlist URI
       
  1183             uri = iDbPlaylist->GetUriL(aId);
       
  1184             break;
       
  1185             }
       
  1186         default:
       
  1187             User::Leave(KErrNotSupported);
       
  1188         }
       
  1189 
       
  1190     return uri;
       
  1191     }
       
  1192 
       
  1193 // ----------------------------------------------------------------------------
       
  1194 // Get category
       
  1195 // ----------------------------------------------------------------------------
       
  1196 //
       
  1197 void CMPXDbHandler::GetCategoryL(
       
  1198     const TUint32 aCategoryId,
       
  1199     TMPXGeneralCategory aCategory,
       
  1200     const TArray<TMPXAttribute>& aAttrs,
       
  1201     CMPXMedia* aMedia)
       
  1202     {
       
  1203     MPX_FUNC("CMPXDbHandler::GetCategoryL");
       
  1204 
       
  1205     switch (aCategory)
       
  1206         {
       
  1207         case EMPXPlaylist:
       
  1208             {
       
  1209             if (iAutoPlaylist->AutoPlaylistTypeL(aCategoryId) != EMPXNoAutoPlaylist)
       
  1210                 {
       
  1211                 iAutoPlaylist->GetPlaylistL(aCategoryId, aAttrs, *aMedia);
       
  1212                 }
       
  1213             else
       
  1214                 {
       
  1215                 iDbPlaylist->GetPlaylistL(aCategoryId, aAttrs, *aMedia);
       
  1216                 }
       
  1217             break;
       
  1218             }
       
  1219         default:
       
  1220             {
       
  1221             DbCategoryL(aCategory)->GetCategoryItemL(aCategoryId, aAttrs, *aMedia);
       
  1222             break;
       
  1223             }
       
  1224         }
       
  1225     }
       
  1226 
       
  1227 // ----------------------------------------------------------------------------
       
  1228 //  Get the duration for all songs
       
  1229 // ----------------------------------------------------------------------------
       
  1230 //
       
  1231 TInt CMPXDbHandler::GetAllSongsDurationL()
       
  1232     {
       
  1233     MPX_FUNC("CMPXDbHandler::GetAllSongsDurationL");
       
  1234     return iDbMusic->AllSongsDurationL();
       
  1235     }
       
  1236 
       
  1237 // ----------------------------------------------------------------------------
       
  1238 //  Get the duration for an artist
       
  1239 // ----------------------------------------------------------------------------
       
  1240 //
       
  1241 TInt CMPXDbHandler::GetArtistDurationL(
       
  1242     TInt aArtistId)
       
  1243     {
       
  1244     MPX_FUNC("CMPXDbHandler::GetArtistDurationL");
       
  1245     return iDbMusic->ArtistDurationL(aArtistId);
       
  1246     }
       
  1247 
       
  1248 // ----------------------------------------------------------------------------
       
  1249 //  Get the duration for an album
       
  1250 // ----------------------------------------------------------------------------
       
  1251 //
       
  1252 TInt CMPXDbHandler::GetAlbumDurationL(
       
  1253     TInt aAlbumId)
       
  1254     {
       
  1255     MPX_FUNC("CMPXDbHandler::GetAlbumDurationL");
       
  1256     return iDbMusic->AlbumDurationL(aAlbumId);
       
  1257     }
       
  1258 
       
  1259 // ----------------------------------------------------------------------------
       
  1260 //  Get the duration for an artist/album combination
       
  1261 // ----------------------------------------------------------------------------
       
  1262 //
       
  1263 TInt CMPXDbHandler::GetArtistAlbumDurationL(
       
  1264     TInt aArtistId,
       
  1265     TInt aAlbumId)
       
  1266     {
       
  1267     MPX_FUNC("CMPXDbHandler::GetArtistAlbumDurationL");
       
  1268     return iDbMusic->ArtistAlbumDurationL(aArtistId, aAlbumId);
       
  1269     }
       
  1270 
       
  1271 // ----------------------------------------------------------------------------
       
  1272 //  Get the duration for a composer
       
  1273 // ----------------------------------------------------------------------------
       
  1274 //
       
  1275 TInt CMPXDbHandler::GetComposerDurationL(
       
  1276     TInt aComposerId)
       
  1277     {
       
  1278     MPX_FUNC("CMPXDbHandler::GetComposerDurationL");
       
  1279     return iDbMusic->ComposerDurationL(aComposerId);
       
  1280     }
       
  1281 
       
  1282 // ----------------------------------------------------------------------------
       
  1283 //  Get the duration for a genre
       
  1284 // ----------------------------------------------------------------------------
       
  1285 //
       
  1286 TInt CMPXDbHandler::GetGenreDurationL(
       
  1287     TInt aGenreId)
       
  1288     {
       
  1289     MPX_FUNC("CMPXDbHandler::GetGenreDurationL");
       
  1290     return iDbMusic->GenreDurationL(aGenreId);
       
  1291     }
       
  1292 
       
  1293 // ----------------------------------------------------------------------------
       
  1294 //  Get the duration for a user playlist
       
  1295 // ----------------------------------------------------------------------------
       
  1296 //
       
  1297 TInt CMPXDbHandler::GetUserPlaylistDurationL(
       
  1298     TInt aPlaylistId)
       
  1299     {
       
  1300     MPX_FUNC("CMPXDbHandler::GetUserPlaylistDurationL");
       
  1301 
       
  1302     RArray<TMPXAttribute> attributes;
       
  1303     CleanupClosePushL(attributes);
       
  1304     attributes.AppendL(KMPXMediaGeneralId);
       
  1305     attributes.AppendL(TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralDuration));
       
  1306 
       
  1307     CMPXMediaArray* mediaArray = CMPXMediaArray::NewL();
       
  1308     CleanupStack::PushL(mediaArray);
       
  1309 
       
  1310     GetPlaylistSongsL(aPlaylistId, attributes.Array(), *mediaArray);
       
  1311 
       
  1312     TInt duration(0);
       
  1313     TInt count(mediaArray->Count());
       
  1314     for (TInt index = 0; index < count; ++index)
       
  1315         {
       
  1316         CMPXMedia* media((*mediaArray)[index]);
       
  1317         if (media->IsSupported(KMPXMediaGeneralDuration))
       
  1318             {
       
  1319             duration += media->ValueTObjectL<TInt>(KMPXMediaGeneralDuration);
       
  1320             }
       
  1321         }
       
  1322 
       
  1323     CleanupStack::PopAndDestroy(mediaArray);
       
  1324     CleanupStack::PopAndDestroy(&attributes);
       
  1325 
       
  1326     return duration;
       
  1327     }
       
  1328 
       
  1329 // ----------------------------------------------------------------------------
       
  1330 //  Get the duration for a playlist
       
  1331 // ----------------------------------------------------------------------------
       
  1332 //
       
  1333 TInt CMPXDbHandler::GetPlaylistDurationL(
       
  1334     TInt aPlaylistId)
       
  1335     {
       
  1336     MPX_FUNC("CMPXDbHandler::GetPlaylistDurationL");
       
  1337 
       
  1338     TInt duration(0);
       
  1339 
       
  1340     if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyPlayedPlaylist))
       
  1341         {
       
  1342         duration = iDbMusic->RecentlyPlayedDurationL();
       
  1343         }
       
  1344     else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXMostPlayedPlaylist))
       
  1345         {
       
  1346         duration = iDbMusic->MostPlayedDurationL();
       
  1347         }
       
  1348     else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyAddedPlaylist))
       
  1349         {
       
  1350         duration = iDbMusic->RecentlyAddedDurationL();
       
  1351         }
       
  1352     else
       
  1353         {
       
  1354         duration = GetUserPlaylistDurationL(aPlaylistId);
       
  1355         }
       
  1356 
       
  1357     return duration;
       
  1358     }
       
  1359 
       
  1360 // ----------------------------------------------------------------------------
       
  1361 // Find the number of items of a specified type
       
  1362 // ----------------------------------------------------------------------------
       
  1363 //
       
  1364 TInt CMPXDbHandler::NumberOfItemsL(
       
  1365     TMPXGeneralCategory aCategory)
       
  1366     {
       
  1367     MPX_FUNC("CMPXDbHandler::NumberOfItemsL");
       
  1368 
       
  1369     TInt count(0);
       
  1370     switch(aCategory)
       
  1371         {
       
  1372         case EMPXSong:
       
  1373             {
       
  1374             count = iDbMusic->CountL();
       
  1375             break;
       
  1376             }
       
  1377         case EMPXPlaylist:
       
  1378             {
       
  1379             // return the total number of playlists, including the system ones
       
  1380             count = iDbPlaylist->CountL() + EMPXAutoPlaylistCount;
       
  1381             break;
       
  1382             }
       
  1383         default:
       
  1384             {
       
  1385             count = DbCategoryL(aCategory)->CountL();
       
  1386             break;
       
  1387             }
       
  1388         }
       
  1389 
       
  1390     return count;
       
  1391     }
       
  1392 
       
  1393 // ----------------------------------------------------------------------------
       
  1394 // CMPXDbHandler::FindAllLC
       
  1395 // ----------------------------------------------------------------------------
       
  1396 //
       
  1397 CMPXMedia* CMPXDbHandler::FindAllLC(
       
  1398     const CMPXMedia& aCriteria,
       
  1399     const TArray<TMPXAttribute>& aAttrs)
       
  1400     {
       
  1401     MPX_FUNC("CMPXDbHandler::FindAllLC");
       
  1402 
       
  1403     // leave if the given media doesn't contain the following attributes
       
  1404     if (!aCriteria.IsSupported(KMPXMediaGeneralType) ||
       
  1405         !aCriteria.IsSupported(KMPXMediaGeneralCategory))
       
  1406         {
       
  1407         User::Leave(KErrArgument);
       
  1408         }
       
  1409 
       
  1410     RArray<TInt> supportedIds;
       
  1411     CleanupClosePushL(supportedIds);
       
  1412     supportedIds.AppendL(KMPXMediaIdContainer);
       
  1413     MPXDbCommonUtil::FillInSupportedUIDsL(aAttrs, supportedIds);
       
  1414 
       
  1415     CMPXMedia* entries = CMPXMedia::NewL(supportedIds.Array());
       
  1416     CleanupStack::PopAndDestroy(&supportedIds);
       
  1417     CleanupStack::PushL(entries);
       
  1418 
       
  1419     CMPXMediaArray* array = CMPXMediaArray::NewL();
       
  1420     CleanupStack::PushL(array);
       
  1421 
       
  1422     FindAllL(aCriteria, aAttrs, array);
       
  1423 
       
  1424     entries->SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType, EMPXGroup);
       
  1425     entries->SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory,
       
  1426         aCriteria.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory));
       
  1427     entries->SetCObjectValueL(KMPXMediaArrayContents, array);
       
  1428     entries->SetTObjectValueL<TInt>(KMPXMediaArrayCount, array->Count());
       
  1429 
       
  1430     CleanupStack::PopAndDestroy(array);
       
  1431     return entries;
       
  1432     }
       
  1433 
       
  1434 // ----------------------------------------------------------------------------
       
  1435 // Set the last refreshed time into the collection
       
  1436 // ----------------------------------------------------------------------------
       
  1437 //
       
  1438 void CMPXDbHandler::SetLastRefreshedTimeL(
       
  1439     TTime aTime)
       
  1440     {
       
  1441     MPX_FUNC("CMPXDbHandler::SetLastRefreshedTimeL");
       
  1442 
       
  1443     BeginTransactionL();
       
  1444     MPX_TRAPD(err, iDbAuxiliary->SetLastRefreshedTimeL(aTime));
       
  1445     EndTransactionL(err);
       
  1446     }
       
  1447 
       
  1448 // ----------------------------------------------------------------------------
       
  1449 // Get the last refreshed time from the collection
       
  1450 // ----------------------------------------------------------------------------
       
  1451 //
       
  1452 TTime CMPXDbHandler::GetLastRefreshedTimeL()
       
  1453     {
       
  1454     MPX_FUNC("CMPXDbHandler::GetLastRefreshedTimeL");
       
  1455     return iDbAuxiliary->LastRefreshedTimeL();
       
  1456     }
       
  1457 
       
  1458 // ----------------------------------------------------------------------------
       
  1459 // Set the db corrupted state for all drives
       
  1460 // ----------------------------------------------------------------------------
       
  1461 //
       
  1462 void CMPXDbHandler::SetDBCorruptedL(
       
  1463     TBool aCorrupted)
       
  1464     {
       
  1465     MPX_FUNC("CMPXDbHandler::SetDBCorruptedL");
       
  1466 
       
  1467     BeginTransactionL();
       
  1468     MPX_TRAPD(err, iDbAuxiliary->SetDBCorruptedL(aCorrupted));
       
  1469     EndTransactionL(err);
       
  1470     }
       
  1471 
       
  1472 // ----------------------------------------------------------------------------
       
  1473 // Gets the db corrupted state for all drives
       
  1474 // ----------------------------------------------------------------------------
       
  1475 //
       
  1476 TBool CMPXDbHandler::IsDBCorruptedL()
       
  1477     {
       
  1478     MPX_FUNC("CMPXDbHandler::IsDBCorruptedL");
       
  1479     return iDbAuxiliary->DBCorruptedL();
       
  1480     }
       
  1481 
       
  1482 // ----------------------------------------------------------------------------
       
  1483 // Have the databases been created?
       
  1484 // ----------------------------------------------------------------------------
       
  1485 //
       
  1486 TBool CMPXDbHandler::DatabaseCreated()
       
  1487     {
       
  1488     MPX_FUNC("CMPXDbHandler::DatabaseCreatedL");
       
  1489 
       
  1490     TBool AuxilaryDbIsRefreshed(EFalse);
       
  1491     TRAP_IGNORE(AuxilaryDbIsRefreshed = iDbAuxiliary->IsRefreshedL());
       
  1492     // If none of the databases were available, ie out of disk we return EFalse
       
  1493     return iDbManager->IsInitialized() && AuxilaryDbIsRefreshed;
       
  1494     }
       
  1495 
       
  1496 // ----------------------------------------------------------------------------
       
  1497 // Open a database
       
  1498 // ----------------------------------------------------------------------------
       
  1499 //
       
  1500 void CMPXDbHandler::OpenDatabaseL(
       
  1501     TInt aDrive)
       
  1502     {
       
  1503     MPX_FUNC("CMPXDbHandler::OpenDatabaseL");
       
  1504     MPX_DEBUG2( "CMPXDbHandler::OpenDatabaseL: %i", aDrive);
       
  1505     iDbManager->OpenDatabaseL(aDrive);
       
  1506 
       
  1507     // Verify the volume ID after a remount event
       
  1508     VerifyVolumeIdL( aDrive );
       
  1509     }
       
  1510 
       
  1511 // ----------------------------------------------------------------------------
       
  1512 // Close a database
       
  1513 // ----------------------------------------------------------------------------
       
  1514 //
       
  1515 void CMPXDbHandler::CloseDatabaseL(
       
  1516     TInt aDrive)
       
  1517     {
       
  1518     MPX_FUNC("CMPXDbHandler::CloseDatabaseL");
       
  1519     MPX_DEBUG2( "CMPXDbHandler::CloseDatabaseL drive: %i", aDrive );
       
  1520     iDbManager->CloseDatabaseL(aDrive);
       
  1521     }
       
  1522 
       
  1523 // ----------------------------------------------------------------------------
       
  1524 // Re-create all databases
       
  1525 // ----------------------------------------------------------------------------
       
  1526 //
       
  1527 void CMPXDbHandler::ReCreateDatabasesL()
       
  1528     {
       
  1529     MPX_FUNC("CMPXDbHandler::ReCreateDatabasesL");
       
  1530     iDbManager->RecreateAllDatabasesL();
       
  1531     }
       
  1532 
       
  1533 // ----------------------------------------------------------------------------
       
  1534 // Set handler refresh status
       
  1535 // ----------------------------------------------------------------------------
       
  1536 //
       
  1537 void CMPXDbHandler::RefreshStartL()
       
  1538     {
       
  1539     MPX_FUNC("CMPXDbHandler::RefreshStartL");
       
  1540 
       
  1541     iOutOfDisk = EFalse;
       
  1542     // Re-open databases
       
  1543     // This is needed for the case where we were OOD before, but user
       
  1544     // has cleared some space but now try to refresh
       
  1545     MPX_TRAPD(err, iDbManager->InitDatabasesL(iDbDrives));
       
  1546 
       
  1547     if(err == KErrDiskFull)
       
  1548         {
       
  1549             iOutOfDisk = ETrue;
       
  1550         }
       
  1551 
       
  1552     User::LeaveIfError( err );
       
  1553     	
       
  1554     if(!iOutOfDisk)
       
  1555     {
       
  1556         MPX_TRAP(err,CheckDiskSpaceOnDrivesL());
       
  1557 
       
  1558         if(err == KErrDiskFull)
       
  1559             {
       
  1560             iOutOfDisk = ETrue;
       
  1561             }
       
  1562     }
       
  1563 #ifdef __RAMDISK_PERF_ENABLE
       
  1564 	iDbManager->CopyDBsToRamL();
       
  1565 #endif //__RAMDISK_PERF_ENABLE
       
  1566 
       
  1567     BeginTransactionL();
       
  1568     iRefresh = ETrue;
       
  1569     }
       
  1570 
       
  1571 // ----------------------------------------------------------------------------
       
  1572 // Re-set handler refresh status
       
  1573 // ----------------------------------------------------------------------------
       
  1574 //
       
  1575 void CMPXDbHandler::RefreshEndL()
       
  1576     {
       
  1577     MPX_FUNC("CMPXDbHandler::RefreshEndL");
       
  1578     if ( iRefresh )
       
  1579         { 
       
  1580         iRefresh = EFalse;
       
  1581         EndTransactionL(KErrNone);
       
  1582         if (!iOutOfDisk)
       
  1583             {
       
  1584             // Write last refreshed time as current time
       
  1585             // This also sets corrupt = 0
       
  1586             TTime curTime;
       
  1587             curTime.HomeTime();
       
  1588             SetLastRefreshedTimeL(curTime);
       
  1589             }
       
  1590 
       
  1591 #ifdef ABSTRACTAUDIOALBUM_INCLUDED
       
  1592     //for AbstractAlbum garbage collection
       
  1593     TRAP_IGNORE( iDbAbstractAlbum->AbstractAlbumCleanUpL() );
       
  1594 #endif
       
  1595    
       
  1596 #ifdef __RAMDISK_PERF_ENABLE
       
  1597         iDbManager->CopyDBsFromRamL();
       
  1598 #endif //__RAMDISK_PERF_ENABLE
       
  1599         }
       
  1600     }
       
  1601 
       
  1602 // ----------------------------------------------------------------------------
       
  1603 // Notification of Mtp status change
       
  1604 // ----------------------------------------------------------------------------
       
  1605 //
       
  1606 void CMPXDbHandler::MtpStartL()
       
  1607     {
       
  1608     MPX_DEBUG1("-->CMPXDbHandler::MtpStartL");
       
  1609     if(!iMtpInUse)
       
  1610         {
       
  1611         iMtpInUse = ETrue;
       
  1612         iOpOnDbCount = 0;
       
  1613     
       
  1614     #ifdef __RAMDISK_PERF_ENABLE
       
  1615         TRAPD(err, iDbManager->CopyDBsToRamL(iMtpInUse));
       
  1616         if ( err != KErrNone )
       
  1617             {
       
  1618             MPX_DEBUG2("CMPXDbHandler::MtpStartL error=%d", err);
       
  1619             }
       
  1620     #endif //__RAMDISK_PERF_ENABLE
       
  1621     
       
  1622         iDbManager->BeginL();
       
  1623         }
       
  1624     //create Thumbnail manager session for cleanup for abstractalbum when MTP end.
       
  1625     //because when MTP end comes, in case of mode switching, we need to do it as fast as possible, 
       
  1626     //hence we don’t want the delay happens on that time.    
       
  1627 #ifdef RD_MPX_TNM_INTEGRATION           
       
  1628     iDbAbstractAlbum->CreateTNMSessionL();
       
  1629 #endif  //RD_MPX_TNM_INTEGRATION
       
  1630     MPX_DEBUG1("<--CMPXDbHandler::MtpStartL");
       
  1631     }
       
  1632 
       
  1633 // ----------------------------------------------------------------------------
       
  1634 // Notification of Mtp status change
       
  1635 // ----------------------------------------------------------------------------
       
  1636 //
       
  1637 void CMPXDbHandler::MtpEndL()
       
  1638     {
       
  1639     MPX_DEBUG1("-->CMPXDbHandler::MtpEndL");
       
  1640     iMtpInUse = EFalse;
       
  1641     iOpOnDbCount = 0;
       
  1642     iDbManager->CommitL();
       
  1643     TInt err = KErrNone;
       
  1644 
       
  1645 
       
  1646 #ifdef __RAMDISK_PERF_ENABLE
       
  1647     TRAP(err, iDbManager->CopyDBsFromRamL());
       
  1648     if ( err != KErrNone )
       
  1649         {
       
  1650         MPX_DEBUG2("CMPXDbHandler::MtpEndL error=%d", err);
       
  1651         }
       
  1652 #endif //__RAMDISK_PERF_ENABLE
       
  1653 
       
  1654 #ifdef ABSTRACTAUDIOALBUM_INCLUDED
       
  1655     BeginTransactionL();
       
  1656     TRAP(err, iDbAbstractAlbum->RemoveAbstractAlbumsWithNoSongL());
       
  1657     if ( err != KErrNone )
       
  1658         {
       
  1659         MPX_DEBUG2("CMPXDbHandler::MtpEndL error happened when cleanup albstractalbum with no songs association[%d]", err);
       
  1660         }
       
  1661     EndTransactionL(err);
       
  1662 #endif
       
  1663     MPX_DEBUG1("<--CMPXDbHandler::MtpEndL");
       
  1664     }
       
  1665 
       
  1666 // ----------------------------------------------------------------------------
       
  1667 // Get all records count for music
       
  1668 // ----------------------------------------------------------------------------
       
  1669 //
       
  1670 TUint CMPXDbHandler::GetMusicCountL(TInt aDrive)
       
  1671     {
       
  1672     MPX_FUNC("CMPXDbHandler::GetMusicCountL");
       
  1673     TUint total(0);
       
  1674 
       
  1675     //music
       
  1676     total += iDbMusic->GetDriveTrackCountL(aDrive);
       
  1677 
       
  1678     return total;
       
  1679     }
       
  1680 
       
  1681 // ----------------------------------------------------------------------------
       
  1682 // Get all records count for playlists
       
  1683 // ----------------------------------------------------------------------------
       
  1684 //
       
  1685 TUint CMPXDbHandler::GetPlaylistCountL(TInt aDrive)
       
  1686     {
       
  1687     MPX_FUNC("CMPXDbHandler::GetPlaylistCountL");
       
  1688     TUint total(0);
       
  1689 
       
  1690     //playlist
       
  1691     total += iDbPlaylist->GetDrivePlaylistCountL(aDrive);
       
  1692 
       
  1693     return total;
       
  1694     }
       
  1695 
       
  1696 // ----------------------------------------------------------------------------
       
  1697 // Get all records count for music and playlists
       
  1698 // ----------------------------------------------------------------------------
       
  1699 //
       
  1700 TUint CMPXDbHandler::GetTotalCountL(TInt aDrive)
       
  1701     {
       
  1702     MPX_FUNC("CMPXDbHandler::GetTotalCountL");
       
  1703     TUint total(0);
       
  1704 
       
  1705     //music
       
  1706     total += iDbMusic->GetDriveTrackCountL(aDrive);
       
  1707     //playlist
       
  1708     total += iDbPlaylist->GetDrivePlaylistCountL(aDrive);
       
  1709 
       
  1710     return total;
       
  1711     }
       
  1712 
       
  1713 // ----------------------------------------------------------------------------
       
  1714 // Get all records count for music and playlists
       
  1715 // ----------------------------------------------------------------------------
       
  1716 //
       
  1717 void CMPXDbHandler::GetMusicUriArrayL(TInt aDrive, TInt aFromID, TInt aRecords,
       
  1718                                       CDesCArray& aUriArr, TInt& aLastID)
       
  1719     {
       
  1720     MPX_FUNC("CMPXDbHandler::GetMusicUriArrayL");
       
  1721 
       
  1722     iDbMusic->GetMusicUriArrayL(aDrive,aFromID,aRecords,aUriArr,aLastID);
       
  1723     }
       
  1724 
       
  1725 // ----------------------------------------------------------------------------
       
  1726 // Get all records count for music and playlists
       
  1727 // ----------------------------------------------------------------------------
       
  1728 //
       
  1729 void CMPXDbHandler::GetPlaylistUriArrayL(TInt aDrive, TInt aFromID, TInt aRecords,
       
  1730                                          CDesCArray& aUriArr, TInt& aLastID)
       
  1731     {
       
  1732     MPX_FUNC("CMPXDbHandler::GetPlaylistUriArrayL");
       
  1733 
       
  1734     iDbPlaylist->GetPlaylistUriArrayL(aDrive,aFromID,aRecords,aUriArr,aLastID);
       
  1735     }
       
  1736 
       
  1737 // ----------------------------------------------------------------------------
       
  1738 // Starts a transaction on all databases
       
  1739 // ----------------------------------------------------------------------------
       
  1740 //
       
  1741 void CMPXDbHandler::BeginTransactionL()
       
  1742     {
       
  1743     MPX_FUNC("CMPXDbHandler::BeginTransactionL");
       
  1744 
       
  1745 #ifdef __RAMDISK_PERF_ENABLE
       
  1746     // EnsureRamSpaceL will copy dbs from ram if ram space is low or dbs exceeded
       
  1747     // max space.
       
  1748 	TRAPD(err, iDbManager->EnsureRamSpaceL());
       
  1749 	if (err)
       
  1750 		{
       
  1751 		//error but continue
       
  1752 		}
       
  1753 #endif //__RAMDISK_PERF_ENABLE
       
  1754 
       
  1755     if(!iMtpInUse)
       
  1756         {
       
  1757         iDbManager->BeginL();
       
  1758         }
       
  1759     }
       
  1760 
       
  1761 // ----------------------------------------------------------------------------
       
  1762 // Ends a transaction on all databases
       
  1763 // ----------------------------------------------------------------------------
       
  1764 //
       
  1765 void CMPXDbHandler::EndTransactionL(
       
  1766     TInt aError)
       
  1767     {
       
  1768     MPX_FUNC("CMPXDbHandler::EndTransactionL");
       
  1769 
       
  1770     if(iMtpInUse)
       
  1771         {
       
  1772         if (aError)
       
  1773             {
       
  1774             iOpOnDbCount = 0;
       
  1775             iDbManager->RollbackL();
       
  1776             User::Leave(aError);
       
  1777             }
       
  1778 
       
  1779         if(iOpOnDbCount >= KMaxOpInTransaction)
       
  1780             {
       
  1781             MPX_DEBUG2("CMPXDbHandler::EndTransactionL - %d>KMaxOpInTransaction Commiting",iOpOnDbCount);
       
  1782             iOpOnDbCount = 0;
       
  1783             iDbManager->CommitL();
       
  1784             iDbManager->BeginL();
       
  1785             }
       
  1786         }
       
  1787     else
       
  1788         {
       
  1789         if (aError)
       
  1790             {
       
  1791             MPX_DEBUG2("CMPXDbHandler::EndTransactionL - Rollback [%d]", aError);
       
  1792 
       
  1793             iDbManager->RollbackL();
       
  1794 
       
  1795             // KSqlDbCorrupted indicates DB corrupted, need to recreate.
       
  1796             if ( aError != KSqlDbCorrupted )
       
  1797                 {
       
  1798                 User::Leave(aError);
       
  1799                 }
       
  1800             }
       
  1801         else
       
  1802             {
       
  1803             iDbManager->CommitL();
       
  1804             }
       
  1805         }
       
  1806     }
       
  1807 
       
  1808 // ----------------------------------------------------------------------------
       
  1809 // Checks if the database is currently in a transaction
       
  1810 // ----------------------------------------------------------------------------
       
  1811 //
       
  1812 TBool CMPXDbHandler::InTransaction()
       
  1813     {
       
  1814     MPX_FUNC("CMPXDbHandler::InTransaction");
       
  1815     return iDbManager->InTransaction();
       
  1816     }
       
  1817 
       
  1818 // ----------------------------------------------------------------------------
       
  1819 // Notifies the handler that the collection will be closed.
       
  1820 // It is called before closing the collection.
       
  1821 // ----------------------------------------------------------------------------
       
  1822 //
       
  1823 void CMPXDbHandler::PreCloseCollectionL()
       
  1824     {
       
  1825     MPX_FUNC("CMPXDbHandler::PreCloseCollectionL");
       
  1826     // Complete pending transaction and set the latest refresh time
       
  1827     // before closing the databases if collection close event occurs
       
  1828     // before the end of the refresh operation
       
  1829     if(iRefresh)
       
  1830         {
       
  1831         EndTransactionL(KErrNone);
       
  1832         if (!iOutOfDisk)
       
  1833             {
       
  1834             // Write last refreshed time as current time
       
  1835             // This also sets corrupt = 0
       
  1836             TTime curTime;
       
  1837             curTime.HomeTime();
       
  1838             SetLastRefreshedTimeL(curTime);
       
  1839             }
       
  1840         }
       
  1841     }
       
  1842 
       
  1843 // ----------------------------------------------------------------------------
       
  1844 // Add song to collection
       
  1845 // ----------------------------------------------------------------------------
       
  1846 //
       
  1847 TUint32 CMPXDbHandler::DoAddSongL(
       
  1848     const CMPXMedia& aMedia,
       
  1849     CMPXMessageArray* aMessageArray)
       
  1850     {
       
  1851     MPX_FUNC("CMPXDbHandler::DoAddSongL");
       
  1852 
       
  1853     if (!aMedia.IsSupported(KMPXMediaGeneralUri))
       
  1854         {
       
  1855         User::Leave(KErrArgument);
       
  1856         }
       
  1857 
       
  1858     // add the song to the Music table
       
  1859     TDriveUnit drive(aMedia.ValueText(KMPXMediaGeneralUri));
       
  1860     TUint32 songId(iDbMusic->AddSongL(aMedia, drive,
       
  1861                                       iRefresh?NULL:aMessageArray));
       
  1862 
       
  1863     // update the playlist tables
       
  1864     // make sure the song db flags are reset and not just updated
       
  1865     iDbPlaylist->UpdateSongL(aMedia, ETrue);
       
  1866 
       
  1867     if(iMtpInUse)
       
  1868         {
       
  1869         ++iOpOnDbCount;
       
  1870         }
       
  1871 
       
  1872     return songId;
       
  1873     }
       
  1874 
       
  1875 // ----------------------------------------------------------------------------
       
  1876 // Add playlist to collection
       
  1877 // ----------------------------------------------------------------------------
       
  1878 //
       
  1879 TUint32 CMPXDbHandler::DoAddPlaylistL(
       
  1880     const CMPXMedia& aMedia)
       
  1881     {
       
  1882     MPX_FUNC("CMPXDbHandler::DoAddPlaylistL");
       
  1883 
       
  1884     CMPXMedia* media = CMPXMedia::NewL(aMedia);
       
  1885     CleanupStack::PushL(media);
       
  1886 
       
  1887     const TDesC& playlistUri = media->ValueText(KMPXMediaGeneralUri);
       
  1888 
       
  1889     //
       
  1890     // client has asked to create a virtual playlist if file name is not specified
       
  1891     // in the URI. In this case, generate URI for virtual playlist specified as
       
  1892     // follows:
       
  1893     //          <dir path>\timestamp.vir
       
  1894     //
       
  1895     TParsePtrC parser(playlistUri);
       
  1896 
       
  1897     if (!parser.NameOrExtPresent() ||
       
  1898         parser.IsNameWild() ||
       
  1899         parser.IsExtWild())
       
  1900         {
       
  1901         HBufC* newUri = HBufC::NewLC(parser.DriveAndPath().Length() + KMCMaxTextLen +
       
  1902             KMPXVirtualPlaylistExt().Length());
       
  1903 
       
  1904         TPtr ptr = newUri->Des();
       
  1905         ptr.Append(parser.DriveAndPath());
       
  1906         TTime time;
       
  1907         time.HomeTime();
       
  1908         ptr.AppendNum(time.Int64());
       
  1909         ptr.Append(KMPXVirtualPlaylistExt);
       
  1910 
       
  1911         // overwrite the old uri with the new one with full path and playlist
       
  1912         // playlist filename
       
  1913         media->SetTextValueL(KMPXMediaGeneralUri, *newUri);
       
  1914 
       
  1915         CleanupStack::PopAndDestroy(newUri);
       
  1916 
       
  1917         // set DbFlags to indicate that this is a virtual playlist
       
  1918         media->SetTObjectValueL<TUint>(KMPXMediaGeneralFlags,
       
  1919             KMPXMediaGeneralFlagsSetOrUnsetBit | KMPXMediaGeneralFlagsIsVirtual);
       
  1920         }
       
  1921 
       
  1922     // complete the song attributes from the music table
       
  1923     UpdatePlaylistSongInfoL(*media);
       
  1924 
       
  1925     // add playlist to the database
       
  1926     TUint32 playlistId = iDbPlaylist->AddPlaylistL(*media);
       
  1927 
       
  1928     CleanupStack::PopAndDestroy(media);
       
  1929     return playlistId;
       
  1930     }
       
  1931 
       
  1932 // ----------------------------------------------------------------------------
       
  1933 // Add song to playlist
       
  1934 // ----------------------------------------------------------------------------
       
  1935 //
       
  1936 TUint32 CMPXDbHandler::DoAddSongToPlaylistL(
       
  1937     const CMPXMedia& aMedia)
       
  1938     {
       
  1939     MPX_FUNC("CMPXDbHandler::DoAddSongToPlaylistL");
       
  1940 
       
  1941     CMPXMedia* media = CMPXMedia::NewL(aMedia);
       
  1942     CleanupStack::PushL(media);
       
  1943 
       
  1944     // complete the song attributes from the music table
       
  1945     UpdatePlaylistSongInfoL(*media);
       
  1946 
       
  1947     // add the songs to the playlist
       
  1948     TUint32 playlistId((media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2);
       
  1949 
       
  1950     CMPXMediaArray* ary( aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents) );
       
  1951     User::LeaveIfNull( ary );
       
  1952     iDbPlaylist->AddSongsL(playlistId,*ary);
       
  1953 
       
  1954     CleanupStack::PopAndDestroy(media);
       
  1955     return playlistId;
       
  1956     }
       
  1957 
       
  1958 // ----------------------------------------------------------------------------
       
  1959 // Update a song in the collection
       
  1960 // ----------------------------------------------------------------------------
       
  1961 //
       
  1962 CMPXDbActiveTask::TChangeVisibility CMPXDbHandler::DoUpdateSongL(
       
  1963     const CMPXMedia& aMedia,
       
  1964     CMPXMessageArray& aItemChangedMessages)
       
  1965     {
       
  1966     MPX_FUNC("CMPXDbHandler::DoUpdateSongL");
       
  1967 
       
  1968     CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
       
  1969 
       
  1970     TUint32 songId(0);
       
  1971 
       
  1972     if (aMedia.IsSupported(KMPXMediaGeneralId))
       
  1973         {
       
  1974         songId = (aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
       
  1975         }
       
  1976     if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  1977         {
       
  1978         const TDesC& uri = aMedia.ValueText(KMPXMediaGeneralUri);
       
  1979         songId = MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, uri, EFalse);
       
  1980         }
       
  1981     if (!songId)
       
  1982         {
       
  1983         User::Leave(KErrNotSupported);
       
  1984         }
       
  1985 
       
  1986     // Update the Music table
       
  1987     TRAPD(err, visibleChange = iDbMusic->UpdateSongL(songId, aMedia, aItemChangedMessages));
       
  1988 
       
  1989     // do not leave if song is not found in Music table
       
  1990     // leave for other errors such as disk full
       
  1991     if(err != KErrNone && err != KErrNotFound)
       
  1992         {
       
  1993         User::Leave(err);
       
  1994         }
       
  1995 
       
  1996     // Update the Playlist table
       
  1997     TBool visible = EFalse;
       
  1998 
       
  1999     TRAP( err, visible = iDbPlaylist->UpdateSongL(aMedia, EFalse, &aItemChangedMessages));
       
  2000 
       
  2001     // do not leave if song is not found in Playlist table
       
  2002     // leave for other errors such as disk full
       
  2003     if(err != KErrNone && err != KErrNotFound)
       
  2004         {
       
  2005         User::Leave(err);
       
  2006         }
       
  2007 
       
  2008     // make it visible if either table is updated
       
  2009     if (visible)
       
  2010         {
       
  2011         visibleChange = CMPXDbActiveTask::EAllVisible;
       
  2012         }
       
  2013     if ( aMedia.ValueTObjectL<TInt>( KMPXMediaMusicAlbumArtChanged )== 1 )
       
  2014         {
       
  2015         ( const_cast<CMPXMedia*>( &aMedia ) 
       
  2016         		)->SetTObjectValueL<TInt>( KMPXMediaMusicAlbumArtChanged, 0 );
       
  2017         }
       
  2018 
       
  2019     return visibleChange;
       
  2020     }
       
  2021 
       
  2022 // ----------------------------------------------------------------------------
       
  2023 // Update a playlist in the collection
       
  2024 // ----------------------------------------------------------------------------
       
  2025 //
       
  2026 void CMPXDbHandler::DoUpdatePlaylistL(
       
  2027     const CMPXMedia& aMedia,
       
  2028     CMPXMessageArray& aMessageArray)
       
  2029     {
       
  2030     MPX_FUNC("CMPXDbHandler::DoUpdatePlaylistL");
       
  2031 
       
  2032     TUint32 playlistId(0);
       
  2033     TInt drive(0);
       
  2034 
       
  2035     CMPXMedia* media = CMPXMedia::NewL(aMedia);
       
  2036     CleanupStack::PushL(media);
       
  2037 
       
  2038 
       
  2039     ProcessPlaylistMediaL(*media, playlistId, drive);
       
  2040 
       
  2041     CMPXMessage* m1 = CMPXMessage::NewL();
       
  2042     CleanupStack::PushL(m1);
       
  2043     CMPXMessage* m2 = CMPXMessage::NewL();
       
  2044     CleanupStack::PushL(m2);
       
  2045 
       
  2046     // send 2 messages to notify the playlist change & to refresh the display (update playlist name)
       
  2047     MPXDbCommonUtil::FillItemChangedMessageL(*m1, playlistId, EMPXItemModified,
       
  2048             EMPXPlaylist, KDBPluginUid);
       
  2049 
       
  2050     MPXDbCommonUtil::FillItemChangedMessageL(*m2, EBrowsePlaylist, EMPXItemModified,
       
  2051                 EMPXPlaylist, KDBPluginUid);
       
  2052 
       
  2053     iDbPlaylist->UpdatePlaylistL(*media, *m1, drive);
       
  2054 
       
  2055     aMessageArray.AppendL(*m1);
       
  2056     aMessageArray.AppendL(*m2);
       
  2057 
       
  2058 
       
  2059     CleanupStack::PopAndDestroy(m2);
       
  2060     CleanupStack::PopAndDestroy(m1);
       
  2061     CleanupStack::PopAndDestroy(media);
       
  2062     }
       
  2063 
       
  2064 // ----------------------------------------------------------------------------
       
  2065 // Update a playlist in the collection
       
  2066 // ----------------------------------------------------------------------------
       
  2067 //
       
  2068 void CMPXDbHandler::DoUpdatePlaylistSongsL(
       
  2069     const CMPXMedia& aMedia,
       
  2070     CMPXMessage& aMessage)
       
  2071     {
       
  2072     MPX_FUNC("CMPXDbHandler::DoUpdatePlaylistSongsL");
       
  2073 
       
  2074     CMPXMedia* media = CMPXMedia::NewL(aMedia);
       
  2075     CleanupStack::PushL(media);
       
  2076 
       
  2077     TUint32 playlistId(0);
       
  2078     TInt drive(0);
       
  2079 
       
  2080     // get the playlist ID and drive ID
       
  2081     ProcessPlaylistMediaL(*media, playlistId, drive);
       
  2082     MPXDbCommonUtil::FillItemChangedMessageL(aMessage, playlistId, EMPXItemModified,
       
  2083         EMPXPlaylist, KDBPluginUid);
       
  2084 
       
  2085     // complete the song attributes from the Music table
       
  2086     UpdatePlaylistSongInfoL(*media);
       
  2087 
       
  2088     // delete existing songs for the playlist first
       
  2089     iDbPlaylist->Songs().DeleteSongsL(playlistId, drive);
       
  2090 
       
  2091     // add new songs to the playlist
       
  2092     CMPXMediaArray* ary( media->Value<CMPXMediaArray>(KMPXMediaArrayContents ) );
       
  2093     User::LeaveIfNull( ary );
       
  2094     iDbPlaylist->AddSongsL(playlistId, *ary);
       
  2095 
       
  2096     CleanupStack::PopAndDestroy(media);
       
  2097     }
       
  2098 
       
  2099 // ----------------------------------------------------------------------------
       
  2100 // Reorder a song in a playlist
       
  2101 // ----------------------------------------------------------------------------
       
  2102 //
       
  2103 void CMPXDbHandler::DoReorderPlaylistL(
       
  2104     const TMPXItemId& aPlaylistId,
       
  2105     const TMPXItemId& aSongId,
       
  2106     TUint aOriginalOrdinal,
       
  2107     TUint aNewOrdinal,
       
  2108     CMPXMessage& aMessage)
       
  2109     {
       
  2110     MPX_DEBUG1("-->CMPXDbHandler::DoReorderPlaylistL()");
       
  2111 
       
  2112     if (aOriginalOrdinal != aNewOrdinal)
       
  2113         {
       
  2114         iDbPlaylist->Songs().ReorderSongL(aPlaylistId, aSongId, aOriginalOrdinal, aNewOrdinal);
       
  2115 
       
  2116         MPXDbCommonUtil::FillItemChangedMessageL(aMessage, aPlaylistId.iId2, EMPXItemModified,
       
  2117             EMPXPlaylist, KDBPluginUid);
       
  2118         }
       
  2119 
       
  2120     MPX_DEBUG1("<--CMPXDbHandler::DoReorderPlaylistL()");
       
  2121     }
       
  2122 
       
  2123 // ----------------------------------------------------------------------------
       
  2124 // Delete a song from collection
       
  2125 // The function notifies collection model to perform deletion
       
  2126 // ----------------------------------------------------------------------------
       
  2127 //
       
  2128 void CMPXDbHandler::DoRemoveSongL(
       
  2129     TUint32 aSongId,
       
  2130     CDesCArray& aUriArray,
       
  2131     CMPXMessageArray& aItemChangedMessages,
       
  2132     TBool aDeleteRecord)
       
  2133     {
       
  2134     MPX_FUNC("CMPXDbHandler::DoRemoveSongL");
       
  2135 
       
  2136     // Get the song drive
       
  2137     TUint32 artistID(0);
       
  2138     TUint32 albumID(0);
       
  2139     TUint32 genreID(0);
       
  2140     TUint32 composerID(0);
       
  2141     HBufC*  art(NULL);
       
  2142 #ifdef ABSTRACTAUDIOALBUM_INCLUDED
       
  2143     TUint32 abstractAlbumID(0);
       
  2144 #endif // ABSTRACTAUDIOALBUM_INCLUDED
       
  2145     TInt drive(0);
       
  2146 
       
  2147 // Get information from the Music table first
       
  2148 #ifdef ABSTRACTAUDIOALBUM_INCLUDED
       
  2149     HBufC* uri = iDbMusic->GetSongInfoL(aSongId, artistID, albumID, genreID, composerID, abstractAlbumID, drive, art);
       
  2150 #else
       
  2151     HBufC* uri = iDbMusic->GetSongInfoL(aSongId, artistID, albumID, genreID, composerID, drive, art);
       
  2152 #endif // ABSTRACTAUDIOALBUM_INCLUDED
       
  2153 
       
  2154     CleanupStack::PushL(art);
       
  2155     // add the URI to the return array
       
  2156     CleanupStack::PushL(uri);
       
  2157     aUriArray.AppendL(*uri);
       
  2158     CleanupStack::PopAndDestroy(uri);
       
  2159 
       
  2160     // Update the category records
       
  2161     TBool categoryExist( EFalse );
       
  2162     iDbArtist->DecrementSongsForCategoryL(artistID, drive, &aItemChangedMessages, categoryExist);
       
  2163     iDbAlbum->DecrementSongsForAlbumL(albumID, drive, &aItemChangedMessages, categoryExist, *art);
       
  2164     iDbGenre->DecrementSongsForCategoryL(genreID, drive, &aItemChangedMessages, categoryExist);
       
  2165     iDbComposer->DecrementSongsForCategoryL(composerID, drive, &aItemChangedMessages, categoryExist);
       
  2166     CleanupStack::PopAndDestroy(art);
       
  2167 #ifdef ABSTRACTAUDIOALBUM_INCLUDED
       
  2168     if (abstractAlbumID)
       
  2169         {
       
  2170         iDbAbstractAlbum->DecrementSongsForCategoryL(abstractAlbumID, drive, &aItemChangedMessages, categoryExist, iMtpInUse);
       
  2171         }
       
  2172 #endif // ABSTRACTAUDIOALBUM_INCLUDED
       
  2173     // Update the music table
       
  2174     TBool deleteRecord(ETrue);
       
  2175 
       
  2176 #if defined (__MTP_PROTOCOL_SUPPORT)
       
  2177     // Mark the song record as deleted if the following is true; otherwise, delete the
       
  2178     // song record.
       
  2179     //
       
  2180     // A client other than MTP has initiated this song deletion (aDeleteRecord is EFalse)
       
  2181     // and MTP has turned on its cenrep key to save deleted records and current number of
       
  2182     // saved deleted records has not exceeded its maximum, KMCMaxSavedDeletedRecords.
       
  2183     //
       
  2184     // Songs are marked as deleted in order to support auto-sync. MTP will delete these
       
  2185     // marked records at the end of each session via CleanupDeletedRecordsL.
       
  2186     //
       
  2187     // For performance consideration, if the number of saved records exceeds its maximum,
       
  2188     // song record will be deleted.
       
  2189     if (!aDeleteRecord && SaveDeletedSongs())
       
  2190         {
       
  2191         TUint32 savedDeletedRecordCount(iDbAuxiliary->SaveDeletedRecordCountL());
       
  2192         MPX_DEBUG2("Current number of saved deleted record count is %d", savedDeletedRecordCount);
       
  2193 
       
  2194         if (savedDeletedRecordCount < KMCMaxSavedDeletedRecords)
       
  2195             {
       
  2196             deleteRecord = EFalse;
       
  2197             TUint32 savedDeletedDriveRecordCount(iDbAuxiliary->SaveDeletedRecordCountL(drive));
       
  2198             iDbAuxiliary->SetSaveDeletedRecordCountL(drive,++savedDeletedDriveRecordCount);
       
  2199             }
       
  2200         }
       
  2201 #endif
       
  2202 
       
  2203     // delete the song from the Music table
       
  2204     iDbMusic->DeleteSongL(aSongId, drive, deleteRecord);
       
  2205 
       
  2206     // add the item changed message
       
  2207     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aSongId, EMPXItemDeleted,
       
  2208         EMPXSong, KDBPluginUid);
       
  2209 
       
  2210 
       
  2211     if(iMtpInUse)
       
  2212         {
       
  2213         ++iOpOnDbCount;
       
  2214         }
       
  2215     }
       
  2216 
       
  2217 // ----------------------------------------------------------------------------
       
  2218 // Delete a song from playlist tables
       
  2219 // ----------------------------------------------------------------------------
       
  2220 //
       
  2221 void CMPXDbHandler::DoRemoveSongFromPlaylistL(TUint32 aSongId,CMPXMessageArray& aItemChangedMessages)
       
  2222     {
       
  2223     MPX_FUNC("CMPXDbHandler::DoRemoveSongFromPlaylistL");
       
  2224     // delete song from the playlist tables on all drives
       
  2225     iDbPlaylist->DeleteSongL(aSongId, aItemChangedMessages);
       
  2226     }
       
  2227 
       
  2228 // ----------------------------------------------------------------------------
       
  2229 // Removes a category of songs from the music collection,
       
  2230 // and its corresponding category in the lookup table
       
  2231 // ----------------------------------------------------------------------------
       
  2232 //
       
  2233 void CMPXDbHandler::DoRemoveSongsMatchingCategoryL(
       
  2234     TMPXGeneralCategory aCategory,
       
  2235     TUint32 aCategoryId,
       
  2236     CDesCArray& aUriArray,
       
  2237     CMPXMessageArray& aItemChangedMessages)
       
  2238     {
       
  2239     MPX_FUNC("CMPXDbHandler::DoRemoveSongsMatchingCategoryL");
       
  2240 
       
  2241     // get the songs for the specified category
       
  2242     CMPXMediaArray* songs = CMPXMediaArray::NewL();
       
  2243     CleanupStack::PushL(songs);
       
  2244 
       
  2245     RArray<TMPXAttribute> attributes;
       
  2246     CleanupClosePushL(attributes);
       
  2247     attributes.AppendL(KMPXMediaGeneralId);
       
  2248 
       
  2249     switch (aCategory)
       
  2250         {
       
  2251         case EMPXArtist:
       
  2252             {
       
  2253             iDbMusic->GetSongsForArtistL(aCategoryId, attributes.Array(), *songs);
       
  2254             break;
       
  2255             }
       
  2256         case EMPXAlbum:
       
  2257             {
       
  2258             iDbMusic->GetSongsForAlbumL(aCategoryId, attributes.Array(), *songs);
       
  2259             break;
       
  2260             }
       
  2261         case EMPXGenre:
       
  2262             {
       
  2263             iDbMusic->GetSongsForGenreL(aCategoryId, attributes.Array(), *songs);
       
  2264             break;
       
  2265             }
       
  2266         case EMPXComposer:
       
  2267             {
       
  2268             iDbMusic->GetSongsForComposerL(aCategoryId, attributes.Array(), *songs);
       
  2269             break;
       
  2270             }
       
  2271         default:
       
  2272             User::Leave(KErrNotSupported);
       
  2273         }
       
  2274 
       
  2275     CleanupStack::PopAndDestroy(&attributes);
       
  2276 
       
  2277     // iterate the songs and remove them one by one
       
  2278     // so records in the category tables can also be updated
       
  2279     TInt count(songs->Count());
       
  2280     for (TInt index = 0; index < count; ++index)
       
  2281         {
       
  2282         CMPXMedia* song = (*songs)[index];
       
  2283         if (song->IsSupported(KMPXMediaGeneralId))
       
  2284             {
       
  2285             DoRemoveSongL((song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2,
       
  2286                 aUriArray, aItemChangedMessages, EFalse);
       
  2287             DoRemoveSongFromPlaylistL((song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2,aItemChangedMessages);
       
  2288             }
       
  2289         }
       
  2290 
       
  2291     CleanupStack::PopAndDestroy(songs);
       
  2292     }
       
  2293 
       
  2294 // ----------------------------------------------------------------------------------------------------------
       
  2295 // Delete songs for the specified artist and album from collection
       
  2296 // ----------------------------------------------------------------------------------------------------------
       
  2297 //
       
  2298 void CMPXDbHandler::DoRemoveSongsMatchingArtistAndAlbumL(
       
  2299     TUint32 aArtistId,
       
  2300     TUint32 aAlbumId,
       
  2301     CDesCArray& aUriArray,
       
  2302     CMPXMessageArray& aItemChangedMessages)
       
  2303     {
       
  2304     MPX_FUNC("CMPXDbHandler::RemoveSongsMatchingArtistAndAlbumL");
       
  2305 
       
  2306     // get the songs for the specified artist and album
       
  2307     CMPXMediaArray* songs = CMPXMediaArray::NewL();
       
  2308     CleanupStack::PushL(songs);
       
  2309 
       
  2310     RArray<TMPXAttribute> attributes;
       
  2311     CleanupClosePushL (attributes);
       
  2312     attributes.AppendL(KMPXMediaGeneralId);
       
  2313 
       
  2314     iDbMusic->GetSongsForArtistAndAlbumL(aArtistId, aAlbumId, attributes.Array(), *songs);
       
  2315     CleanupStack::PopAndDestroy(&attributes);
       
  2316 
       
  2317     // iterate the songs and remove them one by one
       
  2318     // so records in the category tables can also be updated
       
  2319     TInt count(songs->Count());
       
  2320     for (TInt index = 0; index < count; ++index)
       
  2321         {
       
  2322         CMPXMedia* song = (*songs)[index];
       
  2323         if (song->IsSupported(KMPXMediaGeneralId))
       
  2324             {
       
  2325             DoRemoveSongL( song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId),
       
  2326                 aUriArray, aItemChangedMessages, EFalse);
       
  2327             DoRemoveSongFromPlaylistL(song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId),aItemChangedMessages);
       
  2328             }
       
  2329         }
       
  2330 
       
  2331     CleanupStack::PopAndDestroy(songs);
       
  2332     }
       
  2333 
       
  2334 // ----------------------------------------------------------------------------
       
  2335 // Remove all playlists from collection
       
  2336 // ----------------------------------------------------------------------------
       
  2337 //
       
  2338 void CMPXDbHandler::DoRemoveAllPlaylistsL()
       
  2339     {
       
  2340     MPX_FUNC("CMPXDbHandler::DoRemoveAllPlaylistsL");
       
  2341     iDbPlaylist->DeleteAllPlaylistsL();
       
  2342     }
       
  2343 
       
  2344 // ----------------------------------------------------------------------------
       
  2345 // Remove specified playlist
       
  2346 // ----------------------------------------------------------------------------
       
  2347 //
       
  2348 void CMPXDbHandler::DoRemovePlaylistL(
       
  2349     TUint32 aPlaylistId,
       
  2350     CDesCArray& aUriArray,
       
  2351     CMPXMessageArray& aItemChangedMessages)
       
  2352     {
       
  2353     MPX_FUNC("CMPXDbHandler::DoRemovePlaylistL");
       
  2354 
       
  2355     HBufC* uri(iDbPlaylist->DeletePlaylistL(aPlaylistId));
       
  2356     if (uri)
       
  2357         {
       
  2358         CleanupStack::PushL(uri);
       
  2359         aUriArray.AppendL(*uri);
       
  2360         CleanupStack::PopAndDestroy(uri);
       
  2361         }
       
  2362 
       
  2363     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aPlaylistId, EMPXItemDeleted,
       
  2364         EMPXPlaylist, KDBPluginUid);
       
  2365     }
       
  2366 
       
  2367 // ----------------------------------------------------------------------------
       
  2368 // Remove song from playlist songs table
       
  2369 // ----------------------------------------------------------------------------
       
  2370 //
       
  2371 void CMPXDbHandler::DoRemoveSongFromPlaylistL(
       
  2372     TUint32 aPlaylistId,
       
  2373     const TMPXItemId& aSongId,
       
  2374     TInt aOrdinal,
       
  2375     CMPXMessageArray& aItemChangedMessages)
       
  2376     {
       
  2377     MPX_FUNC("CMPXDbHandler::DoRemoveSongFromPlaylistL");
       
  2378     MPX_DEBUG5("CMPXDbHandler::DoRemoveSongFromPlaylistL(playlist 0x%x, songId [0x%x,0x%x], ordinal %d)",
       
  2379         aPlaylistId, aSongId.iId1, aSongId.iId2, aOrdinal);
       
  2380 
       
  2381     // delete the song
       
  2382     iDbPlaylist->DeleteSongL(aPlaylistId, aSongId.iId2, aOrdinal);
       
  2383 
       
  2384     // Send a playlist modified message
       
  2385     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aPlaylistId, EMPXItemModified,
       
  2386         EMPXPlaylist, KDBPluginUid);
       
  2387 
       
  2388     // Send a message on the song in the playlist that is deleted
       
  2389     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aSongId, EMPXItemDeleted,
       
  2390         EMPXSong, KDBPluginUid);
       
  2391     }
       
  2392     
       
  2393 
       
  2394 // ----------------------------------------------------------------------------
       
  2395 // CMPXDbHandler::DoCleanupDeletedRecordsL
       
  2396 // ----------------------------------------------------------------------------
       
  2397 //
       
  2398 void CMPXDbHandler::DoCleanupDeletedRecordsL()
       
  2399     {
       
  2400     MPX_FUNC("CMPXDbHandler::DoCleanupDeletedRecordsL");
       
  2401 
       
  2402     // delete all marked records from the Music table
       
  2403     iDbMusic->CleanupL();
       
  2404 
       
  2405     // reset the count in the Auxiliary table
       
  2406     iDbAuxiliary->SetSaveDeletedRecordCountL(KDbManagerAllDrives,0);
       
  2407     }
       
  2408 
       
  2409 // ----------------------------------------------------------------------------
       
  2410 // FindAllL
       
  2411 // ----------------------------------------------------------------------------
       
  2412 //
       
  2413 void CMPXDbHandler::FindAllL(
       
  2414     const CMPXMedia& aCriteria,
       
  2415     const TArray<TMPXAttribute>& aAttrs,
       
  2416     CMPXMediaArray* aMediaArray)
       
  2417     {
       
  2418     MPX_FUNC("CMPXDbHandler::FindAllL");
       
  2419 
       
  2420     RArray<TMPXAttribute> attributes;
       
  2421     CleanupClosePushL(attributes);
       
  2422     MPXUser::MergeAttributeL(aAttrs, attributes);
       
  2423 
       
  2424     TMPXGeneralCategory category = aCriteria.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
  2425     switch (category)
       
  2426         {
       
  2427         case EMPXPlaylist:
       
  2428             {
       
  2429             TUint32 playlistId(0);
       
  2430             if (aCriteria.IsSupported(KMPXMediaGeneralId))
       
  2431                 {
       
  2432                 playlistId = (aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
       
  2433                 }
       
  2434 
       
  2435             if (iAutoPlaylist->AutoPlaylistTypeL(playlistId) != EMPXNoAutoPlaylist)
       
  2436                 {
       
  2437                 CMPXMedia* media = CMPXMedia::NewL();
       
  2438                 CleanupStack::PushL(media);
       
  2439 
       
  2440                 iAutoPlaylist->GetPlaylistL(playlistId, aAttrs, *media);
       
  2441 
       
  2442                 aMediaArray->AppendL(*media);
       
  2443                 CleanupStack::PopAndDestroy(media);
       
  2444                 }
       
  2445             else
       
  2446                 {
       
  2447                 iDbPlaylist->FindAllL(aCriteria, attributes.Array(), *aMediaArray);
       
  2448                 }
       
  2449 
       
  2450             break;
       
  2451             }
       
  2452         case EMPXSong:
       
  2453             {
       
  2454             FindSongL(aCriteria, attributes.Array(), *aMediaArray);
       
  2455             break;
       
  2456             }
       
  2457         default:
       
  2458             {
       
  2459             DbCategoryL(category)->FindAllL(aCriteria, attributes.Array(), *aMediaArray);
       
  2460             break;
       
  2461             }
       
  2462         }
       
  2463 
       
  2464     CleanupStack::PopAndDestroy(&attributes);
       
  2465     }
       
  2466 
       
  2467 // ----------------------------------------------------------------------------
       
  2468 // Get song(s) from the music table that match the given criteria
       
  2469 // ----------------------------------------------------------------------------
       
  2470 //
       
  2471 void CMPXDbHandler::FindSongL(
       
  2472     const CMPXMedia& aCriteria,
       
  2473     const TArray<TMPXAttribute>& aAttrs,
       
  2474     CMPXMediaArray& aMediaArray)
       
  2475     {
       
  2476     MPX_FUNC("CMPXDbCollection::FindSongL");
       
  2477 
       
  2478     TMPXGeneralType type = aCriteria.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
       
  2479 
       
  2480     TUint32 id(0);
       
  2481     if (aCriteria.IsSupported(KMPXMediaGeneralId))
       
  2482         {
       
  2483         id = (aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
       
  2484         }
       
  2485 
       
  2486     TUint32 containerId(0);
       
  2487     if (aCriteria.IsSupported(KMPXMediaGeneralContainerId))
       
  2488         {
       
  2489         containerId = aCriteria.ValueTObjectL<TUint32>(KMPXMediaGeneralContainerId);
       
  2490         }
       
  2491 
       
  2492     //////////////////////////////////////////////////////////////////////
       
  2493     // Find songs in the specified playlist
       
  2494     //////////////////////////////////////////////////////////////////////
       
  2495     TMPXGeneralCategory cat(MPX_ITEM_CATEGORY(id));
       
  2496 
       
  2497     if (type == EMPXGroup &&
       
  2498         (cat == EMPXPlaylist ||
       
  2499         MPX_ITEM_CATEGORY(containerId) == EMPXPlaylist))
       
  2500         {
       
  2501         TUint32 playlistId = (cat == EMPXPlaylist) ?
       
  2502             id : (containerId & KMCCategoryMask);
       
  2503 
       
  2504         GetPlaylistSongsL(playlistId, aAttrs, aMediaArray);
       
  2505         }
       
  2506 #ifdef ABSTRACTAUDIOALBUM_INCLUDED
       
  2507     else if (type == EMPXGroup &&
       
  2508         (cat == EMPXAbstractAlbum ||
       
  2509         MPX_ITEM_CATEGORY(containerId) == EMPXAbstractAlbum))
       
  2510         {
       
  2511         TUint32 abstractAlbumId = (cat == EMPXAbstractAlbum) ?
       
  2512             id : (containerId & KMCCategoryMask);
       
  2513         TInt attrCount(aAttrs.Count());
       
  2514         if ( attrCount > 1 || (attrCount == 1 && !(aAttrs[0] == KMPXMediaGeneralId)) )
       
  2515             {
       
  2516             MPX_TRAPD(err, iDbMusic->GetAllSongsForAbstractAlbumL( abstractAlbumId, aAttrs, aMediaArray));
       
  2517         if (err == KErrNotFound)
       
  2518             {
       
  2519             //
       
  2520             // Leave with KErrNotFound
       
  2521             User::Leave(KErrNotFound);
       
  2522             }
       
  2523         else
       
  2524             {
       
  2525             // Leave if error
       
  2526             User::LeaveIfError(err);
       
  2527             }
       
  2528         }
       
  2529     }
       
  2530 #endif // ABSTRACTAUDIOALBUM_INCLUDED
       
  2531     //////////////////////////////////////////////////////////////////////
       
  2532     // Find a particular song in the specified playlist. This fills the
       
  2533     // song with info from Playlist table first then overwrites it with
       
  2534     // info from Songs table if Songs table where this song is located
       
  2535     // is present in order to support the display of song titles in a
       
  2536     // playlist when memory card is removed if the playlist refers to
       
  2537     // songs on the memory card. Caller of this scenario is OpenL/MediaL.
       
  2538     // When user attempts to play a track in an auto-playlist, we will
       
  2539     // find the song from Songs table directly since auto-playlists are
       
  2540     // not stored in the Playlist table. Auto-playlists are query-based,
       
  2541     // therefore, when memory card is removed, songs on the memory card
       
  2542     // will not be shown in the auto-playlist; hence they do not exhibit
       
  2543     // the same challenge as user created playlists.
       
  2544     //////////////////////////////////////////////////////////////////////
       
  2545     else if (type == EMPXItem &&
       
  2546         cat == EMPXCollection &&
       
  2547         MPX_ITEM_CATEGORY(containerId) == EMPXPlaylist)
       
  2548         {
       
  2549         if (iAutoPlaylist->AutoPlaylistTypeL(containerId) != EMPXNoAutoPlaylist)
       
  2550             {
       
  2551             // auto playlist song, get the song details from the music table
       
  2552             iDbMusic->FindSongsL(id, 0, type, aCriteria, aAttrs, aMediaArray);
       
  2553             }
       
  2554         else
       
  2555             {
       
  2556             GetPlaylistSongL(id, containerId, aAttrs, aMediaArray);
       
  2557             }
       
  2558         }
       
  2559 
       
  2560     //////////////////////////////////////////////////////////////////////
       
  2561     // Find all songs, all songs in a particular album and/or artist, or
       
  2562     // a particular song
       
  2563     //////////////////////////////////////////////////////////////////////
       
  2564     else
       
  2565         {
       
  2566         TBool sortByTrackOrder = EFalse;
       
  2567 		
       
  2568         // construct the sort order depending on category. Albums are always sorted by track,
       
  2569         // then name, except for unknown album. Songs are sorted by name for unknown album.
       
  2570         // NULL track number is stored as KMaxTInt so that they will be sorted to the end
       
  2571         if ((type == EMPXGroup) && (MPX_ITEM_CATEGORY(id) == EMPXAlbum) && !iDbAlbum->IsUnknownAlbumL(id))
       
  2572             {
       
  2573             sortByTrackOrder = ETrue;
       
  2574             }
       
  2575         iDbMusic->FindSongsL(id, containerId, type, aCriteria, aAttrs, aMediaArray, sortByTrackOrder);
       
  2576         }
       
  2577     }
       
  2578 
       
  2579 // ----------------------------------------------------------------------------
       
  2580 // Get song(s) in the specified playlist
       
  2581 // ----------------------------------------------------------------------------
       
  2582 //
       
  2583 void CMPXDbHandler::GetPlaylistSongsL(
       
  2584     TUint32 aPlaylistId,
       
  2585     const TArray<TMPXAttribute>& aAttrs,
       
  2586     CMPXMediaArray& aMediaArray)
       
  2587     {
       
  2588     MPX_FUNC("CMPXDbHandler::GetPlaylistSongsL");
       
  2589     MPX_DEBUG2("CMPXDbHandler::GetPlaylistSongsL(0x%x)", aPlaylistId);
       
  2590 
       
  2591     // check the auto playlists first
       
  2592     if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyPlayedPlaylist))
       
  2593         {
       
  2594         iDbMusic->GetRecentlyPlayedSongsL(aAttrs, aMediaArray);
       
  2595         }
       
  2596     else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXMostPlayedPlaylist))
       
  2597         {
       
  2598         iDbMusic->GetMostPlayedSongsL(aAttrs, aMediaArray);
       
  2599         }
       
  2600     else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyAddedPlaylist))
       
  2601         {
       
  2602         iDbMusic->GetRecentlyAddedSongsL(aAttrs, aMediaArray);
       
  2603         }
       
  2604     else
       
  2605         {
       
  2606         TInt attrCount(aAttrs.Count());
       
  2607         if ( attrCount > 1 || (attrCount == 1 && !(aAttrs[0] == KMPXMediaGeneralId)) )
       
  2608             {
       
  2609 	        TInt plDrive(iDbPlaylist->GetDriveIdL(aPlaylistId));
       
  2610 	        MPX_TRAPD(err, iDbMusic->GetAllSongsL(plDrive, aPlaylistId, aAttrs, aMediaArray));
       
  2611 
       
  2612 	        // song not found in Music table
       
  2613 	        if (err == KErrNotFound)
       
  2614 	            {
       
  2615 	            //
       
  2616 	            // Leave with KErrNotFound if one of the following is true:
       
  2617 	            // 1) the requested song is in an auto playlist. Since auto-playlist isn't
       
  2618 	            //    stored in playlist tables, we won't be able to retrieve info elsewhere
       
  2619 	            // 2) the requested song is in a user playlist but we cannot find the song
       
  2620 	            //    info from playlist tables either
       
  2621 	            //
       
  2622 	           if (EMPXNoAutoPlaylist != iAutoPlaylist->AutoPlaylistTypeL(aPlaylistId) ||
       
  2623 	                !iDbPlaylist->Songs().GetSongsL(aPlaylistId, aAttrs, aMediaArray))
       
  2624 	               {
       
  2625 	               User::Leave(KErrNotFound);
       
  2626 	               }
       
  2627 	            }
       
  2628 	        else
       
  2629 	            {
       
  2630 	            // ignore the error if KErrNotFound
       
  2631 	            User::LeaveIfError(err);
       
  2632 	            }
       
  2633             }
       
  2634         else
       
  2635             {
       
  2636             // get ids of the songs in the playlist
       
  2637             iDbPlaylist->Songs().GetSongsL(aPlaylistId, aMediaArray);
       
  2638             }
       
  2639         }
       
  2640     }
       
  2641 
       
  2642 // ----------------------------------------------------------------------------
       
  2643 // Find all albums or the albums for a specified artist
       
  2644 // ----------------------------------------------------------------------------
       
  2645 //
       
  2646 void CMPXDbHandler::FindAlbumL(
       
  2647     const CMPXMedia& aCriteria,
       
  2648     const TArray<TMPXAttribute>& aAttrs,
       
  2649     CMPXMediaArray& aMediaArray)
       
  2650     {
       
  2651     MPX_FUNC("CMPXDbHandler::FindAlbumL");
       
  2652 
       
  2653     TMPXGeneralType type = aCriteria.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
       
  2654 
       
  2655     TUint32 id(0);
       
  2656     if (aCriteria.IsSupported(KMPXMediaGeneralId))
       
  2657         {
       
  2658         id = aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  2659         }
       
  2660 
       
  2661     if ((type == EMPXGroup) && (MPX_ITEM_CATEGORY(id) == EMPXArtist))
       
  2662         {
       
  2663         // get all the albums for the artist
       
  2664         GetAlbumsMatchingArtistL(id, aAttrs, aMediaArray);
       
  2665         }
       
  2666     else
       
  2667         {
       
  2668         // look up all albums from album table
       
  2669         iDbAlbum->FindAllL(aCriteria, aAttrs, aMediaArray);
       
  2670         }
       
  2671     }
       
  2672 
       
  2673 // ----------------------------------------------------------------------------
       
  2674 // Extracts the playlist ID and drive ID from a playlist media instance
       
  2675 // ----------------------------------------------------------------------------
       
  2676 //
       
  2677 void CMPXDbHandler::ProcessPlaylistMediaL(
       
  2678     CMPXMedia& aMedia,
       
  2679     TUint32& aPlaylistId,
       
  2680     TInt& aPlaylistDriveId)
       
  2681     {
       
  2682     MPX_FUNC("CMPXDbHandler::ProcessPlaylistMediaL");
       
  2683 
       
  2684     if (aMedia.IsSupported(KMPXMediaGeneralId))
       
  2685         {
       
  2686         aPlaylistId = aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  2687 
       
  2688         if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  2689             {
       
  2690             // find drive id of the playlist
       
  2691             aPlaylistDriveId = TDriveUnit(aMedia.ValueText(KMPXMediaGeneralUri));
       
  2692             }
       
  2693         else
       
  2694             {
       
  2695             // Find drive Id(s) of corresponding Playlist Id
       
  2696             aPlaylistDriveId = iDbPlaylist->GetDriveIdL(aPlaylistId);
       
  2697             }
       
  2698         }
       
  2699     else if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  2700         {
       
  2701         const TDesC& playlistUri = aMedia.ValueText(KMPXMediaGeneralUri);
       
  2702         // find drive id of the playlist
       
  2703         aPlaylistDriveId = TDriveUnit(playlistUri);
       
  2704 
       
  2705         // aMedia does not have an ID, make sure the add it
       
  2706         aPlaylistId = GetPlaylistIdMatchingUriL(playlistUri);
       
  2707         aMedia.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, aPlaylistId);
       
  2708         }
       
  2709     else
       
  2710         {
       
  2711         User::Leave(KErrArgument);
       
  2712         }
       
  2713     }
       
  2714 
       
  2715 // ----------------------------------------------------------------------------
       
  2716 // Makes sure that all songs in the specified playlist have the ID, title and URI attributes
       
  2717 // ----------------------------------------------------------------------------
       
  2718 //
       
  2719 void CMPXDbHandler::UpdatePlaylistSongInfoL(
       
  2720     CMPXMedia& aMedia)
       
  2721     {
       
  2722     MPX_FUNC("CMPXDbHandler::UpdatePlaylistSongInfoL");
       
  2723 
       
  2724     CMPXMediaArray* mediaArray = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  2725     User::LeaveIfNull(mediaArray);
       
  2726 
       
  2727     // make sure each song has Id, Uri, and Title before they can be added to playlist
       
  2728     TInt count(mediaArray->Count());
       
  2729     for (TInt i = 0; i < count; ++i)
       
  2730         {
       
  2731         CMPXMedia* element = mediaArray->AtL(i);
       
  2732 
       
  2733         // copy each song to deal w/ global heap issues
       
  2734         CMPXMedia* entry = CMPXMedia::NewL(*element);
       
  2735         CleanupStack::PushL(entry);
       
  2736 
       
  2737         // song has everything, go to next song
       
  2738         if (entry->IsSupported(KMPXMediaGeneralUri) &&
       
  2739             entry->IsSupported(KMPXMediaGeneralId) &&
       
  2740             entry->IsSupported(KMPXMediaGeneralTitle))
       
  2741             {
       
  2742             // pop entry to maintain CleanupStack
       
  2743             CleanupStack::PopAndDestroy(entry);
       
  2744             continue;
       
  2745             }
       
  2746 
       
  2747         // songs must contain (at minimum) an Uri or an Id
       
  2748         if (!entry->IsSupported(KMPXMediaGeneralUri) &&
       
  2749             !entry->IsSupported(KMPXMediaGeneralId))
       
  2750             {
       
  2751             User::Leave(KErrArgument);
       
  2752             }
       
  2753 
       
  2754         // get Id
       
  2755         if (!entry->IsSupported(KMPXMediaGeneralId))
       
  2756             {
       
  2757             // fill in the ID if not present
       
  2758             TParsePtrC parser(entry->ValueText(KMPXMediaGeneralUri));
       
  2759             entry->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId,
       
  2760                 MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, parser.FullName(), EFalse));
       
  2761             }
       
  2762 
       
  2763         CMPXMedia* song(NULL);
       
  2764 
       
  2765         // update songs info
       
  2766         TInt error(iDbMusic->GetSongL(*entry, song));
       
  2767         TBool result (ETrue);
       
  2768 
       
  2769         // error can only be KErrNone or KErrNotFound
       
  2770         // from CMPXDbMusic::GetSongL
       
  2771         // if not found in Music, get info from PlaylistSongs (PlaylistSongs & PlaylistSongInfo) DB
       
  2772         if (error == KErrNotFound)
       
  2773             {
       
  2774             RArray<TMPXAttribute> attributes;
       
  2775             CleanupClosePushL(attributes);
       
  2776             attributes.AppendL(TMPXAttribute(KMPXMediaIdGeneral,
       
  2777                 EMPXMediaGeneralId | EMPXMediaGeneralTitle | EMPXMediaGeneralUri | EMPXMediaGeneralFlags));
       
  2778 
       
  2779             // this song doesn't exist in Music table. This song is either a broken link or
       
  2780             // is of an unsupported song type that exists in the file system. Broken links
       
  2781             // have already been marked as such during playlist import.
       
  2782             result = iDbPlaylist->Songs().GetSongL(entry->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId), attributes.Array(), song);
       
  2783             if (!result)
       
  2784                 {
       
  2785                 // song is a broken link
       
  2786                 //TUint flags = KMPXMediaGeneralFlagsSetOrUnsetBit;
       
  2787                 //flags |= KMPXMediaGeneralFlagsIsInvalid; // set flag
       
  2788                 //t->SetTObjectValueL<TUint>( KMPXMediaGeneralFlags, flags );
       
  2789 
       
  2790                 if (entry->IsSupported(KMPXMediaGeneralUri))
       
  2791                     {
       
  2792                     // no valid Id but has Uri, just verify Title is present
       
  2793                     // this is the case if the song is a broken link or podcast
       
  2794                     if (!entry->IsSupported(KMPXMediaGeneralTitle))
       
  2795                         {
       
  2796                         // does not have Title, make up the Title from file name
       
  2797                         TParsePtrC parser(entry->ValueText(KMPXMediaGeneralUri));
       
  2798                         entry->SetTextValueL(KMPXMediaGeneralTitle, parser.Name());
       
  2799                         }
       
  2800                     }
       
  2801                 else
       
  2802                     {
       
  2803                     // no valid Id & no Uri, bad argument
       
  2804                     User::Leave(KErrArgument);
       
  2805                     }
       
  2806                 }
       
  2807             CleanupStack::PopAndDestroy(&attributes);
       
  2808             }
       
  2809 
       
  2810         // update attributes
       
  2811         CleanupStack::PushL(song);
       
  2812 
       
  2813         // song not found in Music or Playlist DB, update entry
       
  2814         if(error == KErrNotFound && !result)
       
  2815             {
       
  2816             mediaArray->InsertL(*entry,i);
       
  2817             }
       
  2818         else  // found in DB, replace entry
       
  2819             {
       
  2820             mediaArray->InsertL(*song,i);
       
  2821             }
       
  2822 
       
  2823         // replace element in the array
       
  2824         CleanupStack::PopAndDestroy(song);
       
  2825         CleanupStack::PopAndDestroy(entry);
       
  2826         mediaArray->Remove(i+1);
       
  2827         }
       
  2828     }
       
  2829 
       
  2830 // ----------------------------------------------------------------------------
       
  2831 // CMPXDbHandler::ProcessMusicFoldersL
       
  2832 // ----------------------------------------------------------------------------
       
  2833 //
       
  2834 void CMPXDbHandler::ProcessMusicFoldersL(
       
  2835     const CDesCArray& aFolders)
       
  2836     {
       
  2837     MPX_FUNC("CMPXDbHandler::ProcessMusicFoldersL");
       
  2838 
       
  2839     TInt count(aFolders.MdcaCount());
       
  2840     for (TInt i = 0; i < count; ++i)
       
  2841         {
       
  2842         TPtrC16 folder = aFolders.MdcaPoint(i);
       
  2843 
       
  2844         // check if disk is inserted and act accordingly
       
  2845         TDriveUnit driveUnit(folder);
       
  2846         if (!iFs.IsValidDrive(driveUnit))
       
  2847             {
       
  2848             User::Leave(KErrArgument);
       
  2849             }
       
  2850 
       
  2851         // append the drive to the drive list
       
  2852         iDbDrives.AppendL(driveUnit);
       
  2853         }
       
  2854     }
       
  2855 
       
  2856 // ----------------------------------------------------------------------------
       
  2857 // CMPXDbHandler::DbCategoryL
       
  2858 // ----------------------------------------------------------------------------
       
  2859 //
       
  2860 CMPXDbCategory* CMPXDbHandler::DbCategoryL(
       
  2861     TMPXGeneralCategory aCategory) const
       
  2862     {
       
  2863     MPX_FUNC("CMPXDbHandler::DbCategoryL");
       
  2864 
       
  2865     CMPXDbCategory* dbCategory(NULL);
       
  2866     switch (aCategory)
       
  2867         {
       
  2868         case EMPXArtist:
       
  2869             {
       
  2870             dbCategory = (CMPXDbCategory*)iDbArtist;
       
  2871             break;
       
  2872             }
       
  2873         case EMPXAlbum:
       
  2874             {
       
  2875             dbCategory = (CMPXDbCategory*)iDbAlbum;
       
  2876             break;
       
  2877             }
       
  2878         case EMPXGenre:
       
  2879             {
       
  2880             dbCategory = (CMPXDbCategory*)iDbGenre;
       
  2881             break;
       
  2882             }
       
  2883         case EMPXComposer:
       
  2884             {
       
  2885             dbCategory = (CMPXDbCategory*)iDbComposer;
       
  2886             break;
       
  2887             }
       
  2888 #ifdef ABSTRACTAUDIOALBUM_INCLUDED
       
  2889         case EMPXAbstractAlbum:
       
  2890             {
       
  2891             dbCategory = (CMPXDbCategory*)iDbAbstractAlbum;
       
  2892             break;
       
  2893             }
       
  2894 #endif // ABSTRACTAUDIOALBUM_INCLUDED
       
  2895         default:
       
  2896             User::Leave(KErrNotSupported);
       
  2897         }
       
  2898 
       
  2899     return dbCategory;
       
  2900     }
       
  2901 
       
  2902 // ----------------------------------------------------------------------------
       
  2903 // Verifies that the volume ID of the database matches the drive
       
  2904 // ----------------------------------------------------------------------------
       
  2905 //
       
  2906 void CMPXDbHandler::VerifyVolumeIdL( TInt aDrive )
       
  2907     {
       
  2908     MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL <--");
       
  2909         if( iDbManager->IsOpen( aDrive ) )
       
  2910             {
       
  2911             TVolumeInfo volInfo;
       
  2912             iFs.Volume(volInfo, aDrive );
       
  2913             TUint curId(volInfo.iUniqueID);
       
  2914 
       
  2915             TInt volId = iDbAuxiliary->IdL( aDrive );
       
  2916 
       
  2917             // New database, no volume id set, mask out top bit because this is an uint
       
  2918             //
       
  2919             MPX_DEBUG3("CMPXDBHandler::VerifyVolumeIdL drive:%i db:%i", curId, volId);
       
  2920             if( volId == 0 && (curId&0x7FFFFFFF) )
       
  2921                 {
       
  2922                 MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -- New ID");
       
  2923                 BeginTransactionL();
       
  2924                 TRAPD( err, iDbAuxiliary->SetIdL( aDrive, curId&0x7FFFFFFF ) );
       
  2925                 EndTransactionL( err );
       
  2926 
       
  2927                 // KSqlDbCorrupted indicates DB corrupted, need to recreate.
       
  2928                 if ( err == KSqlDbCorrupted )
       
  2929                     {
       
  2930                     MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL -- Corrupted DB");
       
  2931                     iDbManager->RecreateDatabaseL(aDrive);
       
  2932                     BeginTransactionL();
       
  2933                     TRAPD(err, iDbAuxiliary->SetDBCorruptedL( ETrue ) );
       
  2934                     EndTransactionL( err );
       
  2935                     }
       
  2936                 }
       
  2937             // Unmatched volume id, mark db as corrupt and break
       
  2938             //
       
  2939             else if ( (curId&0x7FFFFFFF) != (volId&0x7FFFFFFFF) )
       
  2940                 {
       
  2941                 MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -- ID match FAILED");
       
  2942                 iDbManager->RecreateDatabaseL(aDrive);
       
  2943                 BeginTransactionL();
       
  2944                 TRAPD(err, iDbAuxiliary->SetDBCorruptedL( ETrue ) );
       
  2945                 EndTransactionL( err );
       
  2946                 }
       
  2947             }
       
  2948 
       
  2949     MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -->");
       
  2950     }
       
  2951 
       
  2952 // ----------------------------------------------------------------------------
       
  2953 // Verifies that the volume ID of the database matches the drive
       
  2954 // ----------------------------------------------------------------------------
       
  2955 //
       
  2956 void CMPXDbHandler::VerifyVolumeIdL()
       
  2957     {
       
  2958     MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL <--");
       
  2959     TInt count( iDbDrives.Count() );
       
  2960     for( TInt i=0; i<count; ++i )
       
  2961         {
       
  2962         VerifyVolumeIdL(iDbDrives[i]);
       
  2963         }
       
  2964     MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -->");
       
  2965     }
       
  2966 
       
  2967 
       
  2968 // ----------------------------------------------------------------------------
       
  2969 // Checks if there is a drive that has a low disk space
       
  2970 // ----------------------------------------------------------------------------
       
  2971 //
       
  2972 void CMPXDbHandler::CheckDiskSpaceOnDrivesL()
       
  2973     {
       
  2974     MPX_DEBUG1("CMPXDbHandler::CheckDiskSpaceOnDrivesL <--");
       
  2975 
       
  2976     TInt count( iDbDrives.Count() );
       
  2977     for( TInt index=0; index<count; ++index )
       
  2978         {
       
  2979         iDbManager->CheckDiskSpaceL(iDbDrives[index]);
       
  2980         }
       
  2981     MPX_DEBUG1("CMPXDbHandler::CheckDiskSpaceOnDrivesL -->");
       
  2982     }
       
  2983 
       
  2984 #if defined (__MTP_PROTOCOL_SUPPORT)
       
  2985 
       
  2986 // ----------------------------------------------------------------------------
       
  2987 // CMPXDbHandler::SaveDeletedSongs
       
  2988 // ----------------------------------------------------------------------------
       
  2989 //
       
  2990 TBool CMPXDbHandler::SaveDeletedSongs()
       
  2991     {
       
  2992     MPX_FUNC("CMPXDbHandler::SaveDeletedSongs");
       
  2993 
       
  2994     TBool saveDeletedSongs(ETrue);
       
  2995     CRepository* cenrep(NULL);
       
  2996     MPX_TRAPD(error, cenrep = CRepository::NewL(KMPXMtpSettings));
       
  2997     if (!error)
       
  2998         {
       
  2999         cenrep->Get(KMPXMtpSaveDeletedRecordFlag, saveDeletedSongs);
       
  3000         delete cenrep;
       
  3001         MPX_DEBUG2("MTP indicated to save deleted songs? %d", saveDeletedSongs);
       
  3002         }
       
  3003 
       
  3004     return saveDeletedSongs;
       
  3005     }
       
  3006 
       
  3007 #endif
       
  3008 
       
  3009 #ifdef RD_MULTIPLE_DRIVE
       
  3010 
       
  3011 // ----------------------------------------------------------------------------------------------------------
       
  3012 // Retrieve all visible music folder locations
       
  3013 // ----------------------------------------------------------------------------------------------------------
       
  3014 //
       
  3015 CDesCArrayFlat* CMPXDbHandler::GetMusicFoldersL()
       
  3016     {
       
  3017     MPX_FUNC("CMPXDbHandler::GetMusicFoldersL()");
       
  3018     TDriveList driveList;
       
  3019     TInt driveCount(0);
       
  3020     User::LeaveIfError(DriveInfo::GetUserVisibleDrives(iFs, driveList, driveCount));
       
  3021     MPX_DEBUG2 ("CMPXDbHandler::GetMusicFoldersL() - driveCount = %d", driveCount);
       
  3022 
       
  3023     CDesCArrayFlat* folders = new (ELeave) CDesCArrayFlat(1); // granularity
       
  3024     CleanupStack::PushL(folders);
       
  3025 
       
  3026     for (TInt i = EDriveA; i <= EDriveZ; i++)
       
  3027         {
       
  3028         if ((driveList[i]) && (!IsRemoteDrive(static_cast<TDriveNumber>(i))))
       
  3029             {
       
  3030             if (i == EDriveC)
       
  3031                 {
       
  3032                 // Append the default phone memory path to the list
       
  3033                 // of music folders
       
  3034                 TPtrC rootPath(PathInfo::PhoneMemoryRootPath());
       
  3035                 folders->AppendL(rootPath);
       
  3036                 MPX_DEBUG2("CMPXDbHandler::GetMusicFoldersL() - adding...%S", &rootPath);
       
  3037                 }
       
  3038             else
       
  3039                 {
       
  3040                 // Get drive letter
       
  3041                 TChar driveChar;
       
  3042                 User::LeaveIfError(iFs.DriveToChar(i, driveChar));
       
  3043 
       
  3044                 // Append visible drive to list of music folders
       
  3045                 TBuf<2> drive;
       
  3046                 drive.Append(driveChar);
       
  3047                 drive.Append(_L(":"));
       
  3048                 folders->AppendL(drive);
       
  3049                 MPX_DEBUG2 ("CMPXDbHandler::GetMusicFoldersL() - adding...%S", &drive);
       
  3050                 }
       
  3051             }
       
  3052         }
       
  3053 
       
  3054     CleanupStack::Pop(folders);
       
  3055     return folders;
       
  3056     }
       
  3057 
       
  3058 #endif // RD_MULTIPLE_DRIVE
       
  3059 
       
  3060 // ----------------------------------------------------------------------------
       
  3061 // CMPXDbHandler::AddAbstractAlbumItemL
       
  3062 // ----------------------------------------------------------------------------
       
  3063 //
       
  3064 #ifdef ABSTRACTAUDIOALBUM_INCLUDED
       
  3065 TUint32 CMPXDbHandler::AddAbstractAlbumItemL(
       
  3066     const TDesC& aName,
       
  3067     TInt aDriveId,
       
  3068     CMPXMessageArray* aItemChangedMessages,
       
  3069     TBool& aItemExist,
       
  3070     const TDesC& aUri,
       
  3071     const TDesC& aAlbumArtist
       
  3072     )
       
  3073     {
       
  3074     MPX_FUNC("CMPXDbHandler::AddAbstractAlbumItemL()");
       
  3075 
       
  3076     MPX_PERF_START(CMPXDbHandler_AddAbstractAlbumItemL);
       
  3077     
       
  3078     TBool newRecord(EFalse);
       
  3079     TUint32 id(0);
       
  3080 
       
  3081     //AbstractAlbum is not case sensitive
       
  3082     id =  iDbAbstractAlbum->AddItemL(aUri, aName, aAlbumArtist, aDriveId, newRecord, EFalse);
       
  3083     MPX_PERF_END(CMPXDbHandler_AddAbstractAlbumItemL);
       
  3084     
       
  3085     return id;
       
  3086     }
       
  3087 #endif
       
  3088 
       
  3089 // ----------------------------------------------------------------------------
       
  3090 // CMPXDbHandler::AddCategoryItemL
       
  3091 // ----------------------------------------------------------------------------
       
  3092 //
       
  3093 TUint32 CMPXDbHandler::AddCategoryItemL(
       
  3094     TMPXGeneralCategory aCategory,
       
  3095     const CMPXMedia& aMedia,
       
  3096     TInt aDriveId,
       
  3097     CMPXMessageArray* aItemChangedMessages,
       
  3098     TBool& aItemExist)
       
  3099     {
       
  3100     MPX_FUNC("CMPXDbHandler::AddCategoryItemL()");
       
  3101     
       
  3102     MPX_PERF_START(CMPXDbHandler_AddCategoryItemL);
       
  3103 
       
  3104     ASSERT(aCategory != EMPXAbstractAlbum);
       
  3105 	
       
  3106     TBool newRecord(EFalse);
       
  3107 
       
  3108     TUint32 id = DbCategoryL(aCategory)->AddItemL(aCategory, aMedia, aDriveId, newRecord, aCategory != EMPXGenre);
       
  3109 
       
  3110     if (newRecord && aItemChangedMessages)
       
  3111         {
       
  3112         MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id, EMPXItemInserted,
       
  3113             aCategory, KDBPluginUid);
       
  3114         }
       
  3115     // when the added item's category is Genre, Composer or Artist, and it is NOT a new record,
       
  3116     // we should send the item number changed message
       
  3117     else if ( ( aCategory == EMPXGenre || aCategory == EMPXComposer || aCategory == EMPXArtist) &&
       
  3118             !newRecord && aItemChangedMessages )
       
  3119         {
       
  3120         MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id, EMPXItemModified,
       
  3121             aCategory, KDBPluginUid);
       
  3122         }
       
  3123     aItemExist = !newRecord;
       
  3124     MPX_PERF_END(CMPXDbHandler_AddCategoryItemL);
       
  3125 
       
  3126     return id;    
       
  3127     }
       
  3128 
       
  3129 // ----------------------------------------------------------------------------
       
  3130 // CMPXDbHandler::UpdateCategoryItemL
       
  3131 // ----------------------------------------------------------------------------
       
  3132 //
       
  3133 void CMPXDbHandler::UpdateCategoryItemL(
       
  3134     TMPXGeneralCategory aCategory,
       
  3135     TUint32 aCategoryId,
       
  3136     const CMPXMedia& aMedia,
       
  3137     TInt aDrive,
       
  3138     CMPXMessageArray* aItemChangedMessages)
       
  3139     {
       
  3140     DbCategoryL(aCategory)->UpdateItemL(aCategoryId, aMedia, aDrive, aItemChangedMessages);
       
  3141     }
       
  3142 
       
  3143 // ----------------------------------------------------------------------------
       
  3144 // CMPXDbHandler::DeleteSongForCategoryL
       
  3145 // ----------------------------------------------------------------------------
       
  3146 //
       
  3147 void CMPXDbHandler::DeleteSongForCategoryL(
       
  3148     TMPXGeneralCategory aCategory,
       
  3149     TUint32 aCategoryId,
       
  3150     TInt aDriveId,
       
  3151     CMPXMessageArray* aItemChangedMessages,
       
  3152     TBool& aItemExist,
       
  3153     const TDesC& aArt   
       
  3154     )
       
  3155     {
       
  3156     MPX_FUNC("CMPXDbHandler::DeleteSongForCategoryL");
       
  3157     switch(aCategory)
       
  3158         {
       
  3159         case EMPXAlbum:
       
  3160             iDbAlbum->DecrementSongsForAlbumL(aCategoryId, aDriveId, aItemChangedMessages, aItemExist, aArt);
       
  3161             break;
       
  3162         default:
       
  3163             DbCategoryL(aCategory)->DecrementSongsForCategoryL(aCategoryId, aDriveId,
       
  3164                     aItemChangedMessages, aItemExist);
       
  3165             break;
       
  3166         }
       
  3167     }
       
  3168 
       
  3169 // ----------------------------------------------------------------------------
       
  3170 // CMPXDbHandler::HandlePlayCountModifiedL
       
  3171 // ----------------------------------------------------------------------------
       
  3172 //
       
  3173 void CMPXDbHandler::HandlePlayCountModifiedL(
       
  3174     CMPXMessageArray& aItemChangedMessages)
       
  3175     {
       
  3176     MPX_FUNC("CMPXDbHandler::HandlePlayCountModifiedL");
       
  3177 
       
  3178     TUint32 plId(iAutoPlaylist->AutoPlaylistIdL(EMPXMostPlayedPlaylist));
       
  3179 
       
  3180     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, plId, EMPXItemModified,
       
  3181         EMPXSong, KDBPluginUid, plId);
       
  3182 
       
  3183     // Force the deprecated ID attribute
       
  3184     aItemChangedMessages[aItemChangedMessages.Count() - 1]->
       
  3185         SetTObjectValueL<TMPXItemId>(KMPXMessageMediaDeprecatedId, plId);
       
  3186     }
       
  3187 
       
  3188 // ----------------------------------------------------------------------------------------------------------
       
  3189 // CMPXDbHandler::HandlePlaybackTimeModifiedL
       
  3190 // ----------------------------------------------------------------------------------------------------------
       
  3191 //
       
  3192 void CMPXDbHandler::HandlePlaybackTimeModifiedL(
       
  3193     CMPXMessageArray& aItemChangedMessages)
       
  3194     {
       
  3195     MPX_FUNC("CMPXDbHandler::HandlePlaybackTimeModifiedL");
       
  3196 
       
  3197     TUint32 plId(iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyPlayedPlaylist));
       
  3198 
       
  3199     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, plId, EMPXItemModified,
       
  3200         EMPXSong, KDBPluginUid, plId);
       
  3201 
       
  3202     // Force the deprecated ID attribute
       
  3203     aItemChangedMessages[aItemChangedMessages.Count() - 1]->
       
  3204         SetTObjectValueL<TMPXItemId>(KMPXMessageMediaDeprecatedId, plId);
       
  3205     }
       
  3206 
       
  3207 // ---------------------------------------------------------------------------
       
  3208 // CMPXDbHandler::IsRemoteDrive
       
  3209 // ---------------------------------------------------------------------------
       
  3210 //
       
  3211 TBool CMPXDbHandler::IsRemoteDrive(TDriveNumber aDrive)
       
  3212     {
       
  3213     return iDbManager->IsRemoteDrive(aDrive);
       
  3214     }
       
  3215 
       
  3216 TInt CMPXDbHandler::HandlePlaylistDurationL(TUint32 aPlaylistId)
       
  3217     {
       
  3218     return GetPlaylistDurationL(aPlaylistId);
       
  3219     }
       
  3220 void CMPXDbHandler::HandlePlaylistInfoL(
       
  3221     TUint32 aPlaylistId, 
       
  3222     TInt& aCount, 
       
  3223     TInt& aDuration)
       
  3224     {
       
  3225     MPX_FUNC("CMPXDbHandler::HandlePlaylistInfoL");
       
  3226     MPX_DEBUG2("CMPXDbHandler::HandlePlaylistInfoL(0x%x)", aPlaylistId);
       
  3227 
       
  3228     RArray<TMPXAttribute> attributes;
       
  3229     CleanupClosePushL(attributes);
       
  3230     attributes.AppendL(KMPXMediaGeneralId);    
       
  3231     attributes.AppendL(TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralDuration));
       
  3232 
       
  3233     CMPXMediaArray* mediaArray = CMPXMediaArray::NewL();
       
  3234     CleanupStack::PushL(mediaArray);    
       
  3235     
       
  3236     GetPlaylistSongsL(aPlaylistId, attributes.Array(), *mediaArray);
       
  3237     
       
  3238     aCount = mediaArray->Count();
       
  3239     for (TInt index = 0; index < aCount; ++index)
       
  3240         {
       
  3241         CMPXMedia* media((*mediaArray)[index]);
       
  3242         if (media->IsSupported(KMPXMediaGeneralDuration))
       
  3243             {
       
  3244             aDuration += media->ValueTObjectL<TInt>(KMPXMediaGeneralDuration);
       
  3245             }
       
  3246         }
       
  3247 
       
  3248     CleanupStack::PopAndDestroy(mediaArray);
       
  3249     CleanupStack::PopAndDestroy(&attributes);        
       
  3250     }
       
  3251 
       
  3252 // ---------------------------------------------------------------------------
       
  3253 // CMPXDbHandler::HandleAlbumartForAlbumL
       
  3254 // ---------------------------------------------------------------------------
       
  3255 //
       
  3256 HBufC*  CMPXDbHandler::HandleAlbumartForAlbumL(const TUint32 aAlbumId, TPtrC aArt)
       
  3257     {
       
  3258     return iDbMusic->AlbumartForAlbumL(aAlbumId, aArt);
       
  3259     }
       
  3260 
       
  3261 #ifdef ABSTRACTAUDIOALBUM_INCLUDED   
       
  3262 // ----------------------------------------------------------------------------------------------------------
       
  3263 // CMPXDbHandler::HandleGetAlbumNameForSongL
       
  3264 // ----------------------------------------------------------------------------------------------------------
       
  3265 //
       
  3266 HBufC* CMPXDbHandler::HandleGetAlbumNameFromIdL(TUint32 aId)
       
  3267     {
       
  3268     return iDbAbstractAlbum->GetUriL(aId);
       
  3269     }
       
  3270 #endif // ABSTRACTAUDIOALBUM_INCLUDED
       
  3271 
       
  3272 // ----------------------------------------------------------------------------
       
  3273 // CMPXDbHandler::DeleteAlbumForArtistL
       
  3274 // ----------------------------------------------------------------------------
       
  3275 //
       
  3276 void CMPXDbHandler::DeleteAlbumForArtistL(TUint32 aCategoryId,
       
  3277     TInt aDrive, CMPXMessageArray* aItemChangedMessages)
       
  3278     {
       
  3279     MPX_FUNC("CMPXDbHandler::DeleteAlbumForArtistL");
       
  3280     iDbArtist->DecrementAlbumsForArtistL(aCategoryId, aDrive, aItemChangedMessages);
       
  3281     }
       
  3282 
       
  3283 // ----------------------------------------------------------------------------
       
  3284 // CMPXDbHandler::AddAlbumArtistL
       
  3285 // ----------------------------------------------------------------------------
       
  3286 //
       
  3287 TUint32 CMPXDbHandler::AddAlbumArtistL(const TDesC& aName, const TDesC& aArt, TInt aDriveId)
       
  3288     {
       
  3289     MPX_FUNC("CMPXDbHandler::AddAlbumArtistL");
       
  3290     return iDbArtist->AddAlbumArtistL(aName, aArt, aDriveId);
       
  3291     }
       
  3292 
       
  3293 // ----------------------------------------------------------------------------
       
  3294 // CMPXDbHandler::GenerateUniqueIdForAlbumL
       
  3295 // ----------------------------------------------------------------------------
       
  3296 //
       
  3297 TUint32 CMPXDbHandler::GenerateUniqueIdForAlbumL(const CMPXMedia& aMedia)
       
  3298     {
       
  3299     return iDbAlbum->GenerateUniqueIdL(aMedia);
       
  3300     }
       
  3301 
       
  3302 // ----------------------------------------------------------------------------
       
  3303 // CMPXDbHandler::IsUnknownAlbumL
       
  3304 // ----------------------------------------------------------------------------
       
  3305 //
       
  3306 TBool CMPXDbHandler::IsUnknownAlbumL(const TUint32 aId)
       
  3307     {
       
  3308     return iDbAlbum->IsUnknownAlbumL(aId);
       
  3309     }
       
  3310 // End of file