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