mpxplugins/serviceplugins/collectionplugins/mpxsqlitepodcastdbplugin/src/mpxpodcastdbhandler.cpp
changeset 0 ff3acec5bc43
child 15 171e07ac910f
equal deleted inserted replaced
-1:000000000000 0:ff3acec5bc43
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This class is used by db plugin to add episodes into DB or
       
    15 *                remove episodes from DB
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <PCRes.rsg>
       
    22 #include <bautils.h>
       
    23 #include <MetaDataUtility.h>
       
    24 #ifdef RD_MULTIPLE_DRIVE
       
    25 #include <driveinfo.h>
       
    26 #include <pathinfo.h>
       
    27 #endif //RD_MULTIPLE_DRIVE
       
    28 
       
    29 #include <mpxmediageneraldefs.h>
       
    30 #include <mpxmediacontainerdefs.h>
       
    31 #include <mpxmediamusicdefs.h>
       
    32 #include <mpxmediaaudiodefs.h>
       
    33 #include <mpxmedia.h>
       
    34 #include <mpxmediaarray.h>
       
    35 #include <mpxcollectionpath.h>
       
    36 #include <mpxlog.h>
       
    37 
       
    38 #include "mpxdbcommondef.h"
       
    39 #include "mpxresource.h"
       
    40 #include "mpxdbcommonutil.h"
       
    41 
       
    42 #include "mpxdbutil.h"
       
    43 #include "mpxpodcastcollectiondbdef.h"
       
    44 #include "mpxpodcastdbmanager.h"
       
    45 #include "mpxdbcategory.h"
       
    46 #include "mpxdbauxiliary.h"
       
    47 #include "mpxpodcastdbhandler.h"
       
    48 #include "mpxpodcastdbpluginqueries.h"
       
    49 
       
    50 // CONSTANTS
       
    51 #if defined (__MTP_PROTOCOL_SUPPORT)
       
    52 #include <centralrepository.h>
       
    53 
       
    54 const TUid KMPXMtpSettings = {0x101FFC53};    // MTP CenRep Key UID
       
    55 const TUint32 KMPXMtpSaveDeletedRecordFlag = 0x00000001;      // MTP CenRep Key for Delete contents
       
    56 #endif
       
    57 const TInt KSqlDbCorrupted = -321;
       
    58 
       
    59 // ============================ MEMBER FUNCTIONS ==============================
       
    60 
       
    61 // ----------------------------------------------------------------------------
       
    62 // Two-phased constructor.
       
    63 // ----------------------------------------------------------------------------
       
    64 //
       
    65 CMPXPodcastDbHandler* CMPXPodcastDbHandler::NewL(
       
    66     RFs& aFs,
       
    67     CMPXResource& aResource)
       
    68     {
       
    69     MPX_FUNC("CMPXPodcastDbHandler::NewL");
       
    70 
       
    71     CMPXPodcastDbHandler* self = CMPXPodcastDbHandler::NewLC(aFs, aResource);
       
    72     CleanupStack::Pop(self);
       
    73     return self;
       
    74     }
       
    75 
       
    76 // ----------------------------------------------------------------------------
       
    77 // Two-phased constructor.
       
    78 // ----------------------------------------------------------------------------
       
    79 //
       
    80 CMPXPodcastDbHandler* CMPXPodcastDbHandler::NewLC(
       
    81     RFs& aFs,
       
    82     CMPXResource& aResource)
       
    83     {
       
    84     MPX_FUNC("CMPXPodcastDbHandler::NewLC");
       
    85 
       
    86     CMPXPodcastDbHandler* self = new (ELeave) CMPXPodcastDbHandler(aFs, aResource);
       
    87     CleanupStack::PushL( self );
       
    88     self->ConstructL();
       
    89     return self;
       
    90     }
       
    91 
       
    92 // ----------------------------------------------------------------------------
       
    93 // Destructor
       
    94 // ----------------------------------------------------------------------------
       
    95 //
       
    96 CMPXPodcastDbHandler::~CMPXPodcastDbHandler()
       
    97     {
       
    98     MPX_FUNC("CMPXPodcastDbHandler::~CMPXPodcastDbHandler");
       
    99 
       
   100     delete iDbPodcast;
       
   101     delete iDbArtist;
       
   102     delete iDbAlbum;
       
   103     delete iDbGenre;
       
   104     delete iDbComposer;
       
   105     delete iDbAuxiliary;
       
   106     delete iDbManager;
       
   107 
       
   108     delete iPodcastPublishDateCat;
       
   109     iPodcastPublishDateIds.Close();
       
   110     iDbDrives.Close();
       
   111     }
       
   112 
       
   113 // ----------------------------------------------------------------------------
       
   114 // C++ default constructor can NOT contain any code, that might leave
       
   115 // ----------------------------------------------------------------------------
       
   116 //
       
   117 CMPXPodcastDbHandler::CMPXPodcastDbHandler(
       
   118     RFs& aFs,
       
   119     CMPXResource& aResource) :
       
   120     iFs(aFs),
       
   121     iResource(aResource)
       
   122     {
       
   123     MPX_FUNC("CMPXPodcastDbHandler::CMPXPodcastDbHandler");
       
   124     }
       
   125 
       
   126 // ----------------------------------------------------------------------------
       
   127 // Symbian 2nd phase constructor can leave.
       
   128 // ----------------------------------------------------------------------------
       
   129 //
       
   130 void CMPXPodcastDbHandler::ConstructL()
       
   131     {
       
   132     MPX_FUNC("CMPXPodcastDbHandler::ConstructL");
       
   133 
       
   134     iPodcastPublishDateCat = iResource.ReadMenuArrayL(R_MPX_QTN_NMP_PUBLISH_DATE_ARRAY,
       
   135         iPodcastPublishDateIds);
       
   136     
       
   137     //create db manager
       
   138     iDbManager = CMPXPodcastDbManager::NewL(iFs);
       
   139     CDesCArrayFlat* podcastFolders =
       
   140 #ifdef RD_MULTIPLE_DRIVE
       
   141 		GetPodcastFoldersL();
       
   142 #else
       
   143     	iResource.ReadDesCArrayL(R_MC_DEFAULT_MUSIC_FOLDERS);
       
   144 #endif
       
   145 
       
   146     // create the podcast folders and initialize iDbDrives
       
   147     CleanupStack::PushL(podcastFolders);
       
   148     ProcessPodcastFoldersL(*podcastFolders);
       
   149     CleanupStack::PopAndDestroy(podcastFolders);
       
   150 
       
   151     // create the db infrastructure
       
   152     iDbPodcast = CMPXDbPodcast::NewL(*iDbManager, iResource, *this);
       
   153     iDbArtist = CMPXDbCategory::NewL(*iDbManager, EMPXArtist);
       
   154     iDbAlbum = CMPXDbCategory::NewL(*iDbManager, EMPXAlbum);
       
   155     iDbGenre = CMPXDbCategory::NewL(*iDbManager, EMPXGenre);
       
   156     iDbComposer = CMPXDbCategory::NewL(*iDbManager, EMPXComposer);
       
   157     iDbAuxiliary = CMPXDbAuxiliary::NewL(*iDbManager);
       
   158 
       
   159     // make sure all databases are created and valid
       
   160     MPX_TRAPD(err, iDbManager->InitDatabasesL(iDbDrives));
       
   161 
       
   162     // If KErrCorrupt is returned, a database file was found to be corrupted
       
   163     // and was replaced with a new one.  The db plugin can ignore this error and continue
       
   164     // because a new db file was successfully created in a subsequent retry.
       
   165     if ((err != KErrNone) && (err != KErrCorrupt) && (err != KErrDiskFull))
       
   166         {
       
   167         // leave to signal the caller that there was an error why creating and opening
       
   168         // one or more of the databases
       
   169         User::Leave(err);
       
   170         }
       
   171     else if (err == KErrDiskFull)
       
   172         {
       
   173         iOutOfDisk = ETrue;
       
   174         }
       
   175     else
       
   176         {
       
   177         // do nothing
       
   178         }
       
   179     // Verify the volume ID Matches
       
   180     MPX_TRAP(err,VerifyVolumeIdL());
       
   181     if ((err != KErrNone) && (err != KErrDiskFull))
       
   182         {
       
   183         // leave to signal the caller that there was an error why creating and opening
       
   184         // one or more of the databases
       
   185         User::Leave(err);
       
   186         }
       
   187     else if (err == KErrDiskFull)
       
   188         {
       
   189         iOutOfDisk = ETrue;
       
   190         }
       
   191 
       
   192     // iDbManager->PrintDatabaseL();
       
   193 
       
   194     MPX_DEBUG2("CMPXDbHandler::ConstructL DbCount[%d]", iDbManager->DatabaseCount());
       
   195     }
       
   196 
       
   197 // ----------------------------------------------------------------------------
       
   198 // Add episode into collection
       
   199 // ----------------------------------------------------------------------------
       
   200 //
       
   201 TUint32 CMPXPodcastDbHandler::AddEpisodeL(
       
   202     const CMPXMedia& aMedia)
       
   203     {
       
   204     MPX_FUNC("CMPXPodcastDbHandler::AddEpisodeL");
       
   205 
       
   206     BeginTransactionL();
       
   207 
       
   208     TUint32 episodeId(0);
       
   209     MPX_TRAPD(err, episodeId = DoAddEpisodeL(aMedia));
       
   210 
       
   211     if (iOutOfDisk && (err == KErrNotFound))
       
   212         {
       
   213         err = KErrDiskFull;
       
   214         }
       
   215     EndTransactionL(err);
       
   216 
       
   217     return episodeId;
       
   218     }
       
   219 
       
   220 // ----------------------------------------------------------------------------
       
   221 // Update a episode in the collection
       
   222 // ----------------------------------------------------------------------------
       
   223 //
       
   224 CMPXDbActiveTask::TChangeVisibility CMPXPodcastDbHandler::UpdateEpisodeL(
       
   225     const CMPXMedia& aMedia,
       
   226     CMPXMessageArray& aItemChangedMessages)
       
   227     {
       
   228     MPX_FUNC("CMPXPodcastDbHandler::UpdateEpisodeL");
       
   229 
       
   230     BeginTransactionL();
       
   231     CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
       
   232     MPX_TRAPD(err, visibleChange = DoUpdateEpisodeL(aMedia, aItemChangedMessages));
       
   233     EndTransactionL(err);
       
   234     return visibleChange;
       
   235     }
       
   236 
       
   237 // ----------------------------------------------------------------------------
       
   238 // Remove the entire podcast collection database
       
   239 // ----------------------------------------------------------------------------
       
   240 //
       
   241 void CMPXPodcastDbHandler::RemoveEntireCollectionL()
       
   242     {
       
   243     MPX_FUNC("CMPXPodcastDbHandler::RemoveEntireCollectionL");
       
   244 
       
   245     BeginTransactionL();
       
   246     MPX_TRAPD(err, iDbManager->RecreateAllDatabasesL());
       
   247     EndTransactionL(err);
       
   248     }
       
   249 
       
   250 // ----------------------------------------------------------------------------
       
   251 // Delete a episode from collection
       
   252 // The function notifies collection model to perform deletion
       
   253 // ----------------------------------------------------------------------------
       
   254 //
       
   255 void CMPXPodcastDbHandler::RemoveEpisodeL(
       
   256     TUint32 aEpisodeId,
       
   257     CDesCArray& aUriArray,
       
   258     CMPXMessageArray& aItemChangedMessages,
       
   259     TBool aDeleteRecord)
       
   260     {
       
   261     MPX_FUNC("CMPXPodcastDbHandler::RemoveEpisodeL");
       
   262 
       
   263     BeginTransactionL();
       
   264     MPX_TRAPD(err, DoRemoveEpisodeL(aEpisodeId, aUriArray, aItemChangedMessages, aDeleteRecord));
       
   265     EndTransactionL(err);
       
   266     }
       
   267 
       
   268 // ----------------------------------------------------------------------------
       
   269 // Removes a category of episodes from the podcast collection, and its
       
   270 // corresponding category in the lookup table
       
   271 // ----------------------------------------------------------------------------
       
   272 //
       
   273 void CMPXPodcastDbHandler::RemoveEpisodesMatchingCategoryL(
       
   274     TMPXGeneralCategory aCategory,
       
   275     TUint32 aCategoryId,
       
   276     CDesCArray& aUriArray,
       
   277     CMPXMessageArray& aItemChangedMessages)
       
   278     {
       
   279     MPX_FUNC("CMPXPodcastDbHandler::RemoveEpisodesMatchingCategoryL");
       
   280 
       
   281     BeginTransactionL();
       
   282     MPX_TRAPD(err, DoRemoveEpisodesMatchingCategoryL(aCategory, aCategoryId,
       
   283         aUriArray, aItemChangedMessages));
       
   284     EndTransactionL(err);
       
   285     }
       
   286 
       
   287 // ----------------------------------------------------------------------------
       
   288 // Delete episode(s) from collection belonging to specified publish date category
       
   289 // The function notifies collection model to perform deletion
       
   290 // ----------------------------------------------------------------------------
       
   291 //
       
   292 void CMPXPodcastDbHandler::RemoveEpisodesMatchingPublishDateCategoryL(
       
   293     TUint32 aCategoryId,
       
   294     CDesCArray& aUriArray,
       
   295     CMPXMessageArray& aItemChangedMessages)
       
   296     {
       
   297     MPX_FUNC("CMPXPodcastDbHandler::RemoveEpisodesMatchingPublishDateCategoryL");
       
   298 
       
   299     BeginTransactionL();
       
   300     MPX_TRAPD(err, DoRemoveEpisodesMatchingPublishDateCategoryL(aCategoryId,
       
   301         aUriArray, aItemChangedMessages));
       
   302     EndTransactionL(err);
       
   303     }
       
   304 
       
   305 // ----------------------------------------------------------------------------
       
   306 // Cleanup records marked as deleted. This is designated for MTP to clean up
       
   307 // records marked as deleted at the end of its session.
       
   308 // ----------------------------------------------------------------------------
       
   309 //
       
   310 void CMPXPodcastDbHandler::CleanupDeletedRecordsL()
       
   311     {
       
   312     MPX_FUNC("CMPXPodcastDbHandler::CleanupDeletedRecordsL");
       
   313 
       
   314     BeginTransactionL();
       
   315     MPX_TRAPD(err, DoCleanupDeletedRecordsL());
       
   316     EndTransactionL(err);
       
   317     }
       
   318 
       
   319 // ----------------------------------------------------------------------------
       
   320 //  Read all episodes and cache them into an array ordered by episode name
       
   321 // ----------------------------------------------------------------------------
       
   322 //
       
   323 void CMPXPodcastDbHandler::GetAllEpisodesL(
       
   324     const TArray<TMPXAttribute>& aAttrs,
       
   325     CMPXMediaArray& aMediaArray)
       
   326     {
       
   327     MPX_FUNC("CMPXPodcastDbHandler::GetAllEpisodesL");
       
   328     iDbPodcast->GetAllEpisodesL(aAttrs, aMediaArray);
       
   329     }
       
   330 
       
   331 // ----------------------------------------------------------------------------
       
   332 // Retrieve the episode(s) with the specified title
       
   333 // ----------------------------------------------------------------------------
       
   334 //
       
   335 void CMPXPodcastDbHandler::GetEpisodesMatchingTitleL(
       
   336     TUint aTitleId,
       
   337     const TArray<TMPXAttribute>& aAttrs,
       
   338     CMPXMediaArray& aMediaArray)
       
   339     {
       
   340     MPX_FUNC("CMPXPodcastDbHandler::GetEpisodesMatchingTitleL");
       
   341     iDbPodcast->GetEpisodesForCategoryL(EMPXAlbum, aTitleId, aAttrs,
       
   342                                         aMediaArray, ETrue);
       
   343     }
       
   344 
       
   345 // ----------------------------------------------------------------------------
       
   346 // Retrieve the episode(s) belonging to the specified playlist
       
   347 // ----------------------------------------------------------------------------
       
   348 //
       
   349 void CMPXPodcastDbHandler::GetEpisodesMatchingPlaylistL(
       
   350     TUint aPlaylistId,
       
   351     const TArray<TMPXAttribute>& aAttrs,
       
   352     CMPXMediaArray& aMediaArray,
       
   353     TInt& aIndexOfCurrentlyPlayingItem)
       
   354     {
       
   355     MPX_FUNC("CMPXPodcastDbHandler::GetEpisodesMatchingPlaylistL");
       
   356 
       
   357     switch (aPlaylistId)
       
   358         {
       
   359         case KRecentlyAddedPlaylistUID:
       
   360             {
       
   361             iDbPodcast->GetRecentlyAddedPlaylistEpisodesL(aAttrs, aMediaArray,
       
   362                 aIndexOfCurrentlyPlayingItem);
       
   363             break;
       
   364             }
       
   365         case KNotPlayedPlaylistUID:
       
   366             {
       
   367             iDbPodcast->GetNotYetPlayedPlaylistEpisodesL(aAttrs, aMediaArray,
       
   368                 aIndexOfCurrentlyPlayingItem);
       
   369             break;
       
   370             }
       
   371         default:
       
   372             {
       
   373             User::Leave(KErrNotSupported);
       
   374             }
       
   375         }
       
   376     }
       
   377 
       
   378 // ----------------------------------------------------------------------------
       
   379 // Retrieve the episode with the specified ID
       
   380 // ----------------------------------------------------------------------------
       
   381 //
       
   382 void CMPXPodcastDbHandler::GetEpisodeL(
       
   383     TUint32 aEpisodeId,
       
   384     const TArray<TMPXAttribute>& aAttrs,
       
   385     CMPXMediaArray& aMediaArray)
       
   386     {
       
   387     MPX_FUNC("CMPXPodcastDbHandler::GetEpisodeL");
       
   388 
       
   389     CMPXMedia* media = CMPXMedia::NewL();
       
   390     CleanupStack::PushL(media);
       
   391 
       
   392     GetEpisodeL(aEpisodeId, aAttrs, *media);
       
   393     aMediaArray.AppendL(*media);
       
   394 
       
   395     CleanupStack::PopAndDestroy(media);
       
   396     }
       
   397 
       
   398 // ----------------------------------------------------------------------------
       
   399 // Retrieve the episode with the specified ID
       
   400 // ----------------------------------------------------------------------------
       
   401 //
       
   402 void CMPXPodcastDbHandler::GetEpisodeL(
       
   403     TUint32 aEpisodeId,
       
   404     const TArray<TMPXAttribute>& aAttrs,
       
   405     CMPXMedia& aMedia)
       
   406     {
       
   407     MPX_FUNC("CMPXPodcastDbHandler::GetEpisodeL");
       
   408     iDbPodcast->GetEpisodeL(aEpisodeId, aAttrs, aMedia);
       
   409     }
       
   410 
       
   411 // ----------------------------------------------------------------------------
       
   412 // Retrieve the episode with the specified URI
       
   413 // ----------------------------------------------------------------------------
       
   414 //
       
   415 TUint32 CMPXPodcastDbHandler::GetEpisodeIdMatchingUriL(
       
   416     const TDesC& aUri)
       
   417     {
       
   418     MPX_FUNC("CMPXPodcastDbHandler::GetEpisodeIdMatchingUriL");
       
   419     return MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, aUri, EFalse);
       
   420     }
       
   421 
       
   422 // ----------------------------------------------------------------------------
       
   423 // Return all podcast title names
       
   424 // ----------------------------------------------------------------------------
       
   425 //
       
   426 void CMPXPodcastDbHandler::GetAllPodcastTitlesL(
       
   427     const TArray<TMPXAttribute>& aAttrs,
       
   428     CMPXMediaArray& aMediaArray)
       
   429     {
       
   430     MPX_FUNC("CMPXPodcastDbHandler::GetAllPodcastTitlesL");
       
   431     iDbAlbum->GetAllCategoryItemsL(aAttrs, aMediaArray);
       
   432     }
       
   433 
       
   434 // ----------------------------------------------------------------------------
       
   435 // Retrieve episodes matching the specified publish playlist id
       
   436 // ----------------------------------------------------------------------------
       
   437 //
       
   438 TInt CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL(
       
   439     TUint aPlaylistId,
       
   440     const TArray<TMPXAttribute>& aAttrs,
       
   441     TBool aPendingCategoryDeletionFlag,
       
   442     CMPXMediaArray& aMediaArray)
       
   443     {
       
   444     MPX_FUNC("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL");
       
   445 
       
   446     TInt numEpisodes(0);
       
   447     TMPXItemId podcastPublishDateCatId = 0;
       
   448 
       
   449     // the deletion helper is retrieving all the media within this category
       
   450     // to delete it so need to record category id within last item so
       
   451     // that the HandleChangeL callback can cause OpenL to be called after the
       
   452     // last item within the category is deleted
       
   453     if (aPendingCategoryDeletionFlag)
       
   454         {
       
   455         TInt categoryID(EMPXOther);
       
   456 
       
   457         // pass in the category Id so that the helper method can add
       
   458         // the category Id to the last item in this category to aid
       
   459         // in deletion of a category
       
   460         podcastPublishDateCatId = (aPlaylistId - KPublishTodayPlaylistUID) | (categoryID << 28);
       
   461         }
       
   462 
       
   463     switch (aPlaylistId)
       
   464         {
       
   465         case KPublishAllPlaylistUID:
       
   466             {
       
   467             TInt itemCount(iPodcastPublishDateCat->Count());
       
   468             for (TInt i = 0; i < itemCount; ++i)
       
   469                 {
       
   470                 TMPXItemId itemId = iPodcastPublishDateIds[i];
       
   471                 TInt count(0);
       
   472 
       
   473                 switch (iPodcastPublishDateIds[i] + KPublishTodayPlaylistUID)
       
   474                     {
       
   475                     case KPublishTodayPlaylistUID:
       
   476                         count = iDbPodcast->GetTodayEpisodesCountL();
       
   477                         break;
       
   478                     case KPublishYesterdayPlaylistUID:
       
   479                         count = iDbPodcast->GetYesterdayEpisodesCountL();
       
   480                         break;
       
   481                     case KPublishThisWeekPlaylistUID:
       
   482                         count = iDbPodcast->GetThisWeekEpisodesCountL();
       
   483                         break;
       
   484                     case KPublishLastWeekPlaylistUID:
       
   485                         count = iDbPodcast->GetLastWeekEpisodesCountL();
       
   486                         break;
       
   487                     case KPublish2WeeksAgoPlaylistUID:
       
   488                         count = iDbPodcast->Get2WeeksAgoEpisodesCountL();
       
   489                         break;
       
   490                     case KPublish3WeeksAgoPlaylistUID:
       
   491                         count = iDbPodcast->Get3WeeksAgoEpisodesCountL();
       
   492                         break;
       
   493                     case KPublishLastMonthPlaylistUID:
       
   494                         count = iDbPodcast->GetLastMonthEpisodesCountL();
       
   495                         break;
       
   496                     case KPublishEarlierPlaylistUID:
       
   497                         count = iDbPodcast->GetEarlierEpisodesCountL();
       
   498                         break;
       
   499                     case KPublishUnknownPlaylistUID:
       
   500                         count = iDbPodcast->GetUnknownEpisodesCountL();
       
   501                         break;
       
   502                     default:
       
   503                         User::Leave(KErrNotFound);
       
   504                         break;
       
   505                     };
       
   506 
       
   507                 if (count > 0)
       
   508                     {
       
   509                     numEpisodes += count;
       
   510                     MPXDbUtil::AppendMediaL(aMediaArray, iPodcastPublishDateCat->MdcaPoint(i),
       
   511                         EMPXGroup, EMPXPlaylist, EMPXPodcastGroup, EMPXPubDate, itemId);
       
   512                     }
       
   513                 }
       
   514             break;
       
   515             }
       
   516 
       
   517         case KPublishTodayPlaylistUID:
       
   518             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published Today"));
       
   519             iDbPodcast->GetTodayEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray);
       
   520             break;
       
   521 
       
   522         case KPublishYesterdayPlaylistUID:
       
   523             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published Yesterday"));
       
   524             iDbPodcast->GetYesterdayEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray);
       
   525             break;
       
   526 
       
   527         case KPublishThisWeekPlaylistUID:
       
   528             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published This Week"));
       
   529             iDbPodcast->GetThisWeekEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray);
       
   530             break;
       
   531 
       
   532         case KPublishLastWeekPlaylistUID:
       
   533             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published Last Week"));
       
   534             iDbPodcast->GetLastWeekEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray);
       
   535             break;
       
   536 
       
   537         case KPublish2WeeksAgoPlaylistUID:
       
   538             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published 2 Weeks Ago"));
       
   539             iDbPodcast->Get2WeeksAgoEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray);
       
   540             break;
       
   541 
       
   542         case KPublish3WeeksAgoPlaylistUID:
       
   543             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published 3 Weeks Ago"));
       
   544             iDbPodcast->Get3WeeksAgoEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray);
       
   545             break;
       
   546 
       
   547         case KPublishLastMonthPlaylistUID:
       
   548             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published Last Month"));
       
   549             iDbPodcast->GetLastMonthEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray);
       
   550             break;
       
   551 
       
   552         case KPublishEarlierPlaylistUID:
       
   553             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published Earlier"));
       
   554             iDbPodcast->GetEarlierEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray);
       
   555             break;
       
   556 
       
   557         case KPublishUnknownPlaylistUID:
       
   558             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published Unknown"));
       
   559             iDbPodcast->GetUnknownEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray);
       
   560             break;
       
   561 
       
   562         default:
       
   563             MPX_DEBUG2 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Invalid publish ID [%d]"), aPlaylistId);
       
   564             User::Leave(KErrNotFound);
       
   565             break;
       
   566         }
       
   567 
       
   568     if (aPlaylistId != KPublishAllPlaylistUID)
       
   569         {
       
   570         numEpisodes = aMediaArray.Count();
       
   571         }
       
   572 
       
   573     return numEpisodes;
       
   574     }
       
   575 
       
   576 // ----------------------------------------------------------------------------
       
   577 // Get the name of the row matching the given ID
       
   578 // ----------------------------------------------------------------------------
       
   579 //
       
   580 HBufC* CMPXPodcastDbHandler::GetTitleNameMatchingIdL(
       
   581     const TUint32 aId)
       
   582     {
       
   583     MPX_FUNC("CMPXPodcastDbHandler::GetTitleNameMatchingIdL");
       
   584     return iDbAlbum->GetNameL(aId);
       
   585     }
       
   586 
       
   587 // ----------------------------------------------------------------------------
       
   588 // Get the URI of the row matching the given ID
       
   589 // ----------------------------------------------------------------------------
       
   590 //
       
   591 HBufC* CMPXPodcastDbHandler::GetUriMatchingIdL(
       
   592     const TUint32 aId)
       
   593     {
       
   594     MPX_FUNC("CMPXPodcastDbHandler::GetUriMatchingIdL");
       
   595 
       
   596     return iDbPodcast->GetUriL(aId);
       
   597     }
       
   598 
       
   599 // ----------------------------------------------------------------------------
       
   600 // Find episode(s) that satisfy the specified criteria
       
   601 // ----------------------------------------------------------------------------
       
   602 //
       
   603 CMPXMedia* CMPXPodcastDbHandler::FindAllLC(
       
   604     const CMPXMedia& aCriteria,
       
   605     const TArray<TMPXAttribute>& aAttrs)
       
   606     {
       
   607     MPX_FUNC("CMPXPodcastDbHandler::FindAllLC");
       
   608 
       
   609     // leave if the given media doesn't contain the following attributes
       
   610     if (!aCriteria.IsSupported(KMPXMediaGeneralType) ||
       
   611         !aCriteria.IsSupported(KMPXMediaGeneralCategory))
       
   612         {
       
   613         User::Leave(KErrArgument);
       
   614         }
       
   615 
       
   616     RArray<TInt> supportedIds;
       
   617     CleanupClosePushL(supportedIds);
       
   618     supportedIds.AppendL(KMPXMediaIdContainer);
       
   619     MPXDbCommonUtil::FillInSupportedUIDsL(aAttrs, supportedIds);
       
   620 
       
   621     CMPXMedia* entries = CMPXMedia::NewL(supportedIds.Array());
       
   622     CleanupStack::PopAndDestroy(&supportedIds);
       
   623     CleanupStack::PushL(entries);
       
   624 
       
   625     CMPXMediaArray* array = CMPXMediaArray::NewL();
       
   626     CleanupStack::PushL(array);
       
   627 
       
   628     FindAllL(aCriteria, aAttrs, *array);
       
   629 
       
   630     entries->SetTObjectValueL(KMPXMediaGeneralType, EMPXGroup);
       
   631     entries->SetTObjectValueL(KMPXMediaGeneralCategory,
       
   632          aCriteria.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory));
       
   633     entries->SetCObjectValueL(KMPXMediaArrayContents, array);
       
   634     entries->SetTObjectValueL(KMPXMediaArrayCount, array->Count());
       
   635 
       
   636     CleanupStack::PopAndDestroy(array);
       
   637     return entries;
       
   638     }
       
   639 
       
   640 // ----------------------------------------------------------------------------
       
   641 // Find the number of items in the database
       
   642 // ----------------------------------------------------------------------------
       
   643 //
       
   644 TInt CMPXPodcastDbHandler::NumberOfItemsL(
       
   645     TMPXPodcastCategory aCategory)
       
   646     {
       
   647     MPX_FUNC("CMPXPodcastDbHandler::NumberOfItemsL");
       
   648 
       
   649     TInt numOfItems(0);
       
   650 
       
   651     switch(aCategory)
       
   652         {
       
   653         case EMPXAll:
       
   654         case EMPXEpisode:
       
   655             {
       
   656             numOfItems = iDbPodcast->CountL();
       
   657             break;
       
   658             }
       
   659         case EMPXRecentlyAdded:
       
   660             {
       
   661             numOfItems = iDbPodcast->GetRecentlyAddedEpisodesCountL();
       
   662             break;
       
   663             }
       
   664         case EMPXNotYetPlayed:
       
   665             {
       
   666             numOfItems = iDbPodcast->GetNotYetPlayedEpisodesCountL();
       
   667             break;
       
   668             }
       
   669         case EMPXTitle:
       
   670             {
       
   671             numOfItems = iDbPodcast->GetNotYetPlayedEpisodesCountL();
       
   672             break;
       
   673             }
       
   674         default:
       
   675             {
       
   676             User::Leave(KErrNotSupported);
       
   677             }
       
   678         }
       
   679 
       
   680     return numOfItems;
       
   681     }
       
   682 
       
   683 // ----------------------------------------------------------------------------
       
   684 // Has the database been created?
       
   685 // ----------------------------------------------------------------------------
       
   686 //
       
   687 TBool CMPXPodcastDbHandler::DatabaseCreated()
       
   688     {
       
   689     MPX_FUNC("CMPXPodcastDbHandler::DatabaseCreated");
       
   690 
       
   691     TBool AuxilaryDbIsRefreshed(EFalse);
       
   692     TRAP_IGNORE(AuxilaryDbIsRefreshed = iDbAuxiliary->IsRefreshedL());
       
   693     // If none of the databases were available, ie out of disk
       
   694     // we return EFalse
       
   695     return iDbManager->IsInitialized() && AuxilaryDbIsRefreshed;
       
   696     }
       
   697 
       
   698 // ----------------------------------------------------------------------------
       
   699 //  CMPXPodcastDbHandler::GetAllEpisodesDurationL
       
   700 // ----------------------------------------------------------------------------
       
   701 //
       
   702 TInt CMPXPodcastDbHandler::GetAllEpisodesDurationL()
       
   703     {
       
   704     MPX_FUNC("CMPXPodcastDbHandler::GetAllEpisodesDurationL");
       
   705     return iDbPodcast->AllEpisodesDurationL();
       
   706     }
       
   707 
       
   708 // ----------------------------------------------------------------------------
       
   709 //  CMPXPodcastDbHandler::GetTitleDurationL
       
   710 // ----------------------------------------------------------------------------
       
   711 //
       
   712 TInt CMPXPodcastDbHandler::GetTitleDurationL(
       
   713     TUint32 aTitleId)
       
   714     {
       
   715     MPX_FUNC("CMPXPodcastDbHandler::GetTitleDurationL");
       
   716     return iDbPodcast->TitleDurationL(aTitleId);
       
   717     }
       
   718 
       
   719 // ----------------------------------------------------------------------------
       
   720 //  CMPXPodcastDbHandler::GetNotPlayedDurationL
       
   721 // ----------------------------------------------------------------------------
       
   722 //
       
   723 TInt CMPXPodcastDbHandler::GetNotPlayedDurationL()
       
   724     {
       
   725     MPX_FUNC("CMPXPodcastDbHandler::GetNotPlayedDurationL");
       
   726     return iDbPodcast->NotPlayedDurationL();
       
   727     }
       
   728 
       
   729 // ----------------------------------------------------------------------------
       
   730 //  CMPXPodcastDbHandler::GetRecentlyAddedDurationL
       
   731 // ----------------------------------------------------------------------------
       
   732 //
       
   733 TInt CMPXPodcastDbHandler::GetRecentlyAddedDurationL()
       
   734     {
       
   735     MPX_FUNC("CMPXPodcastDbHandler::GetRecentlyAddedDurationL");
       
   736     return iDbPodcast->RecentlyAddedDurationL();
       
   737     }
       
   738 
       
   739 // ----------------------------------------------------------------------------
       
   740 // Set the last refreshed time into the collection
       
   741 // ----------------------------------------------------------------------------
       
   742 //
       
   743 void CMPXPodcastDbHandler::SetLastRefreshedTimeL(
       
   744     TTime aTime)
       
   745     {
       
   746     MPX_FUNC("CMPXPodcastDbHandler::SetLastRefreshedTimeL");
       
   747 
       
   748     BeginTransactionL();
       
   749     MPX_TRAPD(err, iDbAuxiliary->SetLastRefreshedTimeL(aTime));
       
   750     EndTransactionL(err);
       
   751     }
       
   752 
       
   753 // ----------------------------------------------------------------------------
       
   754 // Get the last refreshed time into the collection
       
   755 // ----------------------------------------------------------------------------
       
   756 //
       
   757 TTime CMPXPodcastDbHandler::GetLastRefreshedTimeL()
       
   758     {
       
   759     MPX_FUNC("CMPXPodcastDbHandler::GetLastRefreshedTimeL");
       
   760     return iDbAuxiliary->LastRefreshedTimeL();
       
   761     }
       
   762 
       
   763 // ----------------------------------------------------------------------------
       
   764 // Set the db corrupted state for all drives
       
   765 // ----------------------------------------------------------------------------
       
   766 //
       
   767 void CMPXPodcastDbHandler::SetDBCorruptedL(
       
   768     TBool aCorrupted)
       
   769     {
       
   770     MPX_FUNC("CMPXPodcastDbHandler::SetDBCorruptedL");
       
   771 
       
   772     BeginTransactionL();
       
   773     MPX_TRAPD(err, iDbAuxiliary->SetDBCorruptedL(aCorrupted));
       
   774     EndTransactionL(err);
       
   775     }
       
   776 
       
   777 // ----------------------------------------------------------------------------
       
   778 // Gets the db corrupted state for all drives
       
   779 // ----------------------------------------------------------------------------
       
   780 //
       
   781 TBool CMPXPodcastDbHandler::IsDBCorruptedL()
       
   782     {
       
   783     MPX_FUNC("CMPXPodcastDbHandler::IsDBCorruptedL");
       
   784     return iDbAuxiliary->DBCorruptedL();
       
   785     }
       
   786 
       
   787 // ----------------------------------------------------------------------------
       
   788 // Opens a database
       
   789 // ----------------------------------------------------------------------------
       
   790 //
       
   791 void CMPXPodcastDbHandler::OpenDatabaseL(
       
   792     TInt aDrive)
       
   793     {
       
   794     MPX_FUNC("CMPXPodcastDbHandler::OpenDatabaseL");
       
   795     iDbManager->OpenDatabaseL(aDrive);
       
   796 
       
   797     // Verify the volume ID after a remount event
       
   798     VerifyVolumeIdL();
       
   799     }
       
   800 
       
   801 // ----------------------------------------------------------------------------
       
   802 // Close a database
       
   803 // ----------------------------------------------------------------------------
       
   804 //
       
   805 void CMPXPodcastDbHandler::CloseDatabaseL(
       
   806     TInt aDrive)
       
   807     {
       
   808     MPX_FUNC("CMPXPodcastDbHandler::CloseDatabaseL");
       
   809     iDbManager->CloseDatabaseL(aDrive);
       
   810     }
       
   811 
       
   812 // ----------------------------------------------------------------------------
       
   813 // Re-create all databases
       
   814 // ----------------------------------------------------------------------------
       
   815 //
       
   816 void CMPXPodcastDbHandler::ReCreateDatabasesL()
       
   817     {
       
   818     MPX_FUNC("CMPXPodcastDbHandler::ReCreateDatabasesL");
       
   819     iDbManager->RecreateAllDatabasesL();
       
   820     }
       
   821 
       
   822 // ----------------------------------------------------------------------------
       
   823 // Set handler refresh status
       
   824 // ----------------------------------------------------------------------------
       
   825 //
       
   826 void CMPXPodcastDbHandler::RefreshStartL()
       
   827     {
       
   828     MPX_FUNC("CMPXPodcastDbHandler::RefreshStartL");
       
   829 
       
   830     iOutOfDisk = EFalse;
       
   831     // Re-open databases
       
   832     // This is needed for the case where we were OOD before, but user
       
   833     // has cleared some space but now try to refresh
       
   834     MPX_TRAPD(err, iDbManager->InitDatabasesL(iDbDrives));
       
   835 
       
   836     if(err == KErrDiskFull)
       
   837         {
       
   838         iOutOfDisk = ETrue;
       
   839         }
       
   840 
       
   841     if(!iOutOfDisk)
       
   842     {
       
   843         MPX_TRAP(err,CheckDiskSpaceOnDrivesL());
       
   844 
       
   845         if(err == KErrDiskFull)
       
   846             {
       
   847             iOutOfDisk = ETrue;
       
   848             }
       
   849     }
       
   850     BeginTransactionL();
       
   851     }
       
   852 
       
   853 // ----------------------------------------------------------------------------
       
   854 // Re-set handler refresh status
       
   855 // ----------------------------------------------------------------------------
       
   856 //
       
   857 void CMPXPodcastDbHandler::RefreshEndL()
       
   858     {
       
   859     MPX_FUNC("CMPXPodcastDbHandler::RefreshEndL");
       
   860 
       
   861     EndTransactionL(KErrNone);
       
   862 
       
   863     if (!iOutOfDisk)
       
   864         {
       
   865         // Write last refreshed time as current time
       
   866         // This also sets corrupt = 0
       
   867         TTime curTime;
       
   868         curTime.HomeTime();
       
   869         SetLastRefreshedTimeL(curTime);
       
   870 //        iDbManager->PrintDatabaseL();    // PREQ2536 the files sqlrowsetutil.h and sqlrowsetutil.cpp has been removed
       
   871         }
       
   872     }
       
   873 
       
   874 // ----------------------------------------------------------------------------
       
   875 // CMPXPodcastDbHandler::SetIsPlayingL
       
   876 // ----------------------------------------------------------------------------
       
   877 //
       
   878 void CMPXPodcastDbHandler::SetIsPlayingL(
       
   879     const CMPXMedia& aMedia,
       
   880     TBool aIsPlaying)
       
   881     {
       
   882     MPX_FUNC("CMPXPodcastDbHandler::SetIsPlayingL");
       
   883 
       
   884     TUint32 episodeId(0);
       
   885     if (aMedia.IsSupported(KMPXMediaGeneralId))
       
   886         {
       
   887         episodeId = aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
   888         }
       
   889     else if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
   890         {
       
   891         const TDesC& location(aMedia.ValueText(KMPXMediaGeneralUri));
       
   892         episodeId = MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, location, EFalse);
       
   893         }
       
   894     else
       
   895         {
       
   896         User::Leave(KErrArgument);
       
   897         }
       
   898 
       
   899     BeginTransactionL();
       
   900     MPX_TRAPD(err, iDbPodcast->SetIsPlayingL(episodeId, aIsPlaying));
       
   901     EndTransactionL(err);
       
   902     }
       
   903 
       
   904 // ----------------------------------------------------------------------------
       
   905 // Get all records count for podcasts
       
   906 // ----------------------------------------------------------------------------
       
   907 //
       
   908 TUint CMPXPodcastDbHandler::GetTotalCountL(TInt aDrive)
       
   909     {
       
   910     MPX_FUNC("CMPXPodcastDbHandler::GetTotalCountL");
       
   911     TUint total(0);
       
   912 
       
   913     total = iDbPodcast->GetDrivePodcastCountL(aDrive);
       
   914 
       
   915     return total;
       
   916     }
       
   917 
       
   918 // ----------------------------------------------------------------------------
       
   919 // Get all records count for podcasts
       
   920 // ----------------------------------------------------------------------------
       
   921 //
       
   922 void CMPXPodcastDbHandler::GetPodcastUriArrayL(TInt aDrive, TInt aFromID, TInt aRecords,
       
   923                                                CDesCArray& aUriArr, TInt& aLastID)
       
   924     {
       
   925     MPX_FUNC("CMPXPodcastDbHandler::GetTotalUriArrayL");
       
   926 
       
   927     iDbPodcast->GetPodcastUriArrayL(aDrive,aFromID,aRecords,aUriArr,aLastID);
       
   928     }
       
   929 
       
   930 // ----------------------------------------------------------------------------
       
   931 // CMPXPodcastDbHandler::DoCleanupDeletedRecordsL
       
   932 // ----------------------------------------------------------------------------
       
   933 //
       
   934 void CMPXPodcastDbHandler::DoCleanupDeletedRecordsL()
       
   935     {
       
   936     MPX_FUNC("CMPXPodcastDbHandler::DoCleanupDeletedRecordsL");
       
   937 
       
   938     // delete all marked records from the Music table
       
   939     iDbPodcast->CleanupL();
       
   940 
       
   941     // reset the count in the Auxiliary table
       
   942     iDbAuxiliary->SetSaveDeletedRecordCountL(KDbManagerAllDrives,0);
       
   943     }
       
   944 
       
   945 // ----------------------------------------------------------------------------
       
   946 // FindAllL helper
       
   947 // ----------------------------------------------------------------------------
       
   948 //
       
   949 void CMPXPodcastDbHandler::FindAllL(
       
   950     const CMPXMedia& aCriteria,
       
   951     const TArray<TMPXAttribute>& aAttrs,
       
   952     CMPXMediaArray& aMediaArray)
       
   953     {
       
   954     MPX_FUNC("CMPXPodcastDbHandler::FindAllL");
       
   955 
       
   956     RArray<TMPXAttribute> attributes;
       
   957     CleanupClosePushL (attributes);
       
   958     MPXUser::MergeAttributeL(aAttrs, attributes);
       
   959 
       
   960     // TODO: b10liu: update all users to properly use podcast category?
       
   961     // Some users of FindAll still call without specifying a podcast category group(ie.. delete helper)
       
   962     // so need to check and use media category instead if not available.
       
   963     if (!aCriteria.IsSupported(KMPXMediaPodcastCategoryGroup))
       
   964         {
       
   965         if (!aCriteria.IsSupported(KMPXMediaGeneralCategory))
       
   966             {
       
   967             User::Leave(KErrArgument);
       
   968             }
       
   969         TMPXGeneralCategory category = aCriteria.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
   970 
       
   971         switch (category)
       
   972             {
       
   973             case EMPXAlbum:
       
   974                 {
       
   975                 if (!aCriteria.IsSupported(KMPXMediaGeneralId))
       
   976                     {
       
   977                     User::Leave(KErrArgument);
       
   978                     }
       
   979                 // return all episodes within this title
       
   980                 TMPXItemId episodeTitleId = aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
   981                 GetEpisodesMatchingTitleL(episodeTitleId, aAttrs, aMediaArray);
       
   982                 break;
       
   983                 }
       
   984             case EMPXPodcast:
       
   985             case EMPXSong:
       
   986                 {
       
   987                 FindEpisodesL(aCriteria, attributes.Array(), aMediaArray);
       
   988                 break;
       
   989                 }
       
   990             case EMPXGenre:
       
   991             case EMPXPlaylist:
       
   992             case EMPXArtist:
       
   993             case EMPXComposer:
       
   994             default:
       
   995                 {
       
   996                 DbCategoryL(category)->FindAllL(aCriteria, attributes.Array(), aMediaArray);
       
   997                 break;
       
   998                 }
       
   999             }
       
  1000         }
       
  1001     else
       
  1002         {
       
  1003         TMPXPodcastCategory category =
       
  1004              aCriteria.ValueTObjectL<TMPXPodcastCategory>(KMPXMediaPodcastCategoryGroup);
       
  1005 
       
  1006         switch (category)
       
  1007             {
       
  1008             case EMPXTitle:
       
  1009                 {
       
  1010                 if (!aCriteria.IsSupported(KMPXMediaGeneralId))
       
  1011                     {
       
  1012                     User::Leave(KErrArgument);
       
  1013                     }
       
  1014                 // return all episodes within this title
       
  1015                 TMPXItemId episodeTitleId = aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  1016                 GetEpisodesMatchingTitleL(episodeTitleId, aAttrs, aMediaArray);
       
  1017                 break;
       
  1018                 }
       
  1019             case EMPXPubDate:
       
  1020                 {
       
  1021                 if (!aCriteria.IsSupported(KMPXMediaGeneralId))
       
  1022                     {
       
  1023                     User::Leave(KErrArgument);
       
  1024                     }
       
  1025 
       
  1026                 TMPXItemId categoryId = aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  1027 
       
  1028                 // zero out the high 4 bits which indicate the general category
       
  1029                 categoryId.iId2 &= 0x00FFFFFF;
       
  1030                 GetEpisodesMatchingPublishPlaylistL(categoryId.iId2 + KPublishTodayPlaylistUID, // offset by KPublishTodayPlaylistUID
       
  1031                     aAttrs, EFalse, aMediaArray);
       
  1032                 break;
       
  1033                 }
       
  1034             case EMPXRecentlyAdded:
       
  1035             case EMPXNotYetPlayed:
       
  1036                 {
       
  1037                 break;
       
  1038                 }
       
  1039             case EMPXAll:
       
  1040             case EMPXEpisode:
       
  1041             case EMPXNew:
       
  1042             case EMPXPartlyPlayed:
       
  1043             case EMPXCompletelyPlayed:
       
  1044                 {
       
  1045                 FindEpisodesL(aCriteria, attributes.Array(), aMediaArray);
       
  1046                 break;
       
  1047                 }
       
  1048             default:
       
  1049                 User::Leave(KErrNotSupported);
       
  1050             }
       
  1051         }
       
  1052 
       
  1053     CleanupStack::PopAndDestroy(&attributes);
       
  1054     }
       
  1055 
       
  1056 // ----------------------------------------------------------------------------
       
  1057 // Get episode(s) from the music table that match the given criteria
       
  1058 // ----------------------------------------------------------------------------
       
  1059 //
       
  1060 void CMPXPodcastDbHandler::FindEpisodesL(
       
  1061     const CMPXMedia& aCriteria,
       
  1062     const TArray<TMPXAttribute>& aAttrs,
       
  1063     CMPXMediaArray& aMediaArray)
       
  1064     {
       
  1065     MPX_FUNC("CMPXPodcastDbHandler::FindEpisodesL");
       
  1066 
       
  1067     TMPXGeneralType type(EMPXNoType);
       
  1068     if (!aCriteria.IsSupported(KMPXMediaGeneralType))
       
  1069         {
       
  1070         User::Leave(KErrArgument);
       
  1071         }
       
  1072     type = aCriteria.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
       
  1073 
       
  1074     TMPXPodcastType podcastType(EMPXPodcastNoType);
       
  1075     if (aCriteria.IsSupported(KMPXMediaPodcastType))
       
  1076         {
       
  1077         podcastType = aCriteria.ValueTObjectL<TMPXPodcastType>(KMPXMediaPodcastType);
       
  1078         }
       
  1079 
       
  1080     TUint32 id(0);
       
  1081     if (aCriteria.IsSupported(KMPXMediaGeneralId))
       
  1082         {
       
  1083         id = aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  1084         }
       
  1085 
       
  1086     TUint32 containerId(0);
       
  1087     if (aCriteria.IsSupported(KMPXMediaGeneralContainerId))
       
  1088         {
       
  1089         containerId = aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralContainerId);
       
  1090         }
       
  1091 
       
  1092     MPX_TRAPD(err, iDbPodcast->FindEpisodesL(id, containerId, type, podcastType,
       
  1093         aCriteria, aAttrs, aMediaArray));
       
  1094     if (err == KErrNotSupported)
       
  1095         {
       
  1096         User::Leave(KErrNotFound);
       
  1097         }
       
  1098 
       
  1099     User::LeaveIfError(err);
       
  1100     }
       
  1101 
       
  1102 // ----------------------------------------------------------------------------
       
  1103 // Add episode to collection
       
  1104 // ----------------------------------------------------------------------------
       
  1105 //
       
  1106 TUint32 CMPXPodcastDbHandler::DoAddEpisodeL(
       
  1107     const CMPXMedia& aMedia)
       
  1108     {
       
  1109     MPX_FUNC("CMPXPodcastDbHandler::DoAddEpisodeL");
       
  1110 
       
  1111     if (!aMedia.IsSupported(KMPXMediaGeneralUri))
       
  1112         {
       
  1113         User::Leave(KErrArgument);
       
  1114         }
       
  1115 
       
  1116     TDriveUnit drive(aMedia.ValueText(KMPXMediaGeneralUri));
       
  1117     return iDbPodcast->AddEpisodeL(aMedia, drive);
       
  1118     }
       
  1119 
       
  1120 // ----------------------------------------------------------------------------
       
  1121 // Update a episode in the collection
       
  1122 // ----------------------------------------------------------------------------
       
  1123 //
       
  1124 CMPXDbActiveTask::TChangeVisibility CMPXPodcastDbHandler::DoUpdateEpisodeL(
       
  1125     const CMPXMedia& aMedia,
       
  1126     CMPXMessageArray& aItemChangedMessages)
       
  1127     {
       
  1128     MPX_FUNC("CMPXPodcastDbHandler::DoUpdateEpisodeL");
       
  1129 
       
  1130     CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
       
  1131     TUint32 curId(0);
       
  1132     TUint32 newId(0);
       
  1133     TInt curDrive(KErrNotFound);
       
  1134     TInt newDrive(KErrNotFound);
       
  1135 
       
  1136     // find the episode by Id and update it
       
  1137     if( aMedia.IsSupported(KMPXMediaGeneralId))
       
  1138         {
       
  1139         curId = (aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
       
  1140         curDrive = iDbPodcast->GetDriveL(curId);
       
  1141         }
       
  1142     // find the episode by URI and update it
       
  1143     if(aMedia.IsSupported(KMPXMediaGeneralUri))
       
  1144         {
       
  1145         const TDesC& uri = aMedia.ValueText(KMPXMediaGeneralUri);
       
  1146         if (uri.Length() == 0)
       
  1147             {
       
  1148             User::Leave( KErrArgument );
       
  1149             }
       
  1150 
       
  1151         newDrive = TDriveUnit(uri);
       
  1152         newId = MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, uri, EFalse);
       
  1153         }
       
  1154     if (!curId && !newId)
       
  1155         {
       
  1156         User::Leave(KErrNotSupported);
       
  1157         }
       
  1158 
       
  1159     TInt driveId = (curDrive != KErrNotFound) ? curDrive : newDrive;
       
  1160 
       
  1161     if (driveId != KErrNotFound)
       
  1162         {
       
  1163         TUint32 episodeId = curId ? curId : newId;
       
  1164 
       
  1165         // Update the Podcast table
       
  1166         visibleChange = iDbPodcast->UpdateEpisodeL(episodeId, aMedia, aItemChangedMessages);
       
  1167         }
       
  1168 
       
  1169     return visibleChange;
       
  1170     }
       
  1171 
       
  1172 // ----------------------------------------------------------------------------
       
  1173 // CMPXPodcastDbHandler::DoRemoveEpisodeL
       
  1174 // ----------------------------------------------------------------------------
       
  1175 //
       
  1176 void CMPXPodcastDbHandler::DoRemoveEpisodeL(
       
  1177     TUint32 aEpisodeId,
       
  1178     CDesCArray& aUriArray,
       
  1179     CMPXMessageArray& aItemChangedMessages,
       
  1180     TBool aDeleteRecord)
       
  1181     {
       
  1182     MPX_FUNC("CMPXPodcastDbHandler::DoRemoveEpisodeL");
       
  1183 
       
  1184     TBool deleteRecord(ETrue);
       
  1185 
       
  1186 #if defined (__MTP_PROTOCOL_SUPPORT)
       
  1187     // Mark the song record as deleted if the following is true; otherwise, delete the
       
  1188     // song record.
       
  1189     //
       
  1190     // A client other than MTP has initiated this song deletion (aDeleteRecord is EFalse)
       
  1191     // and MTP has turned on its cenrep key to save deleted records and current number of
       
  1192     // saved deleted records has not exceeded its maximum, KMCMaxSavedDeletedRecords.
       
  1193     //
       
  1194     // Songs are marked as deleted in order to support auto-sync. MTP will delete these
       
  1195     // marked records at the end of each session via CleanupDeletedMediasL.
       
  1196     //
       
  1197     // For performance consideration, if the number of saved records exceeds its maximum,
       
  1198     // song record will be deleted.
       
  1199     if (!aDeleteRecord && SaveDeletedSongs())
       
  1200         {
       
  1201         TUint32 savedDeletedRecordCount(iDbAuxiliary->SaveDeletedRecordCountL());
       
  1202         MPX_DEBUG2("Current number of saved deleted record count is %d", savedDeletedRecordCount);
       
  1203 
       
  1204         if (savedDeletedRecordCount < KMCMaxSavedDeletedRecords)
       
  1205             {
       
  1206             deleteRecord = EFalse;
       
  1207             TInt drive = iDbPodcast->GetDriveL(aEpisodeId);
       
  1208             TUint32 savedDeletedDriveRecordCount(iDbAuxiliary->SaveDeletedRecordCountL(drive));
       
  1209             iDbAuxiliary->SetSaveDeletedRecordCountL(drive,++savedDeletedDriveRecordCount);
       
  1210             }
       
  1211         }
       
  1212 #endif
       
  1213 
       
  1214     // delete the episode
       
  1215     iDbPodcast->DeleteEpisodeL(aEpisodeId, aUriArray, aItemChangedMessages, deleteRecord);
       
  1216     }
       
  1217 
       
  1218 // ----------------------------------------------------------------------------
       
  1219 // CMPXPodcastDbHandler::DoRemoveEpisodesMatchingCategoryL
       
  1220 // ----------------------------------------------------------------------------
       
  1221 //
       
  1222 void CMPXPodcastDbHandler::DoRemoveEpisodesMatchingCategoryL(
       
  1223     TMPXGeneralCategory aCategory,
       
  1224     TUint32 aCategoryId,
       
  1225     CDesCArray& aUriArray,
       
  1226     CMPXMessageArray& aItemChangedMessages)
       
  1227     {
       
  1228     MPX_FUNC("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingCategoryL");
       
  1229     iDbPodcast->DeleteCategoryL(aCategory, aCategoryId, aUriArray,
       
  1230         aItemChangedMessages);
       
  1231     }
       
  1232 
       
  1233 // ----------------------------------------------------------------------------
       
  1234 // CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL
       
  1235 // ----------------------------------------------------------------------------
       
  1236 //
       
  1237 void CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL(
       
  1238     TUint32 aCategoryId,
       
  1239     CDesCArray& aUriArray,
       
  1240     CMPXMessageArray& aItemChangedMessages)
       
  1241     {
       
  1242     MPX_FUNC("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL");
       
  1243 
       
  1244     switch (aCategoryId + KPublishTodayPlaylistUID)
       
  1245         {
       
  1246         case KPublishTodayPlaylistUID:
       
  1247             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published Today"));
       
  1248             iDbPodcast->DeleteTodayEpisodesL(aUriArray, aItemChangedMessages);
       
  1249             break;
       
  1250 
       
  1251         case KPublishYesterdayPlaylistUID:
       
  1252             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published Yesterday"));
       
  1253             iDbPodcast->DeleteYesterdayEpisodesL(aUriArray, aItemChangedMessages);
       
  1254             break;
       
  1255 
       
  1256         case KPublishThisWeekPlaylistUID:
       
  1257             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published This Week"));
       
  1258             iDbPodcast->DeleteThisWeekEpisodesL(aUriArray, aItemChangedMessages);
       
  1259             break;
       
  1260 
       
  1261         case KPublishLastWeekPlaylistUID:
       
  1262             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published Last Week"));
       
  1263             iDbPodcast->DeleteLastWeekEpisodesL(aUriArray, aItemChangedMessages);
       
  1264             break;
       
  1265 
       
  1266         case KPublish2WeeksAgoPlaylistUID:
       
  1267             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published 2 Weeks Ago"));
       
  1268             iDbPodcast->Delete2WeeksAgoEpisodesL(aUriArray, aItemChangedMessages);
       
  1269             break;
       
  1270 
       
  1271         case KPublish3WeeksAgoPlaylistUID:
       
  1272             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published 3 Weeks Ago"));
       
  1273             iDbPodcast->Delete3WeeksAgoEpisodesL(aUriArray, aItemChangedMessages);
       
  1274             break;
       
  1275 
       
  1276         case KPublishLastMonthPlaylistUID:
       
  1277             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published Last Month"));
       
  1278             iDbPodcast->DeleteLastMonthEpisodesL(aUriArray, aItemChangedMessages);
       
  1279             break;
       
  1280 
       
  1281         case KPublishEarlierPlaylistUID:
       
  1282             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published Earlier"));
       
  1283             iDbPodcast->DeleteEarlierEpisodesL(aUriArray, aItemChangedMessages);
       
  1284             break;
       
  1285 
       
  1286         case KPublishUnknownPlaylistUID:
       
  1287             MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published Unknown"));
       
  1288             iDbPodcast->DeleteUnknownEpisodesL(aUriArray, aItemChangedMessages);
       
  1289             break;
       
  1290 
       
  1291         default:
       
  1292             MPX_DEBUG2 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Invalid publish date ID [%d]"), aCategoryId);
       
  1293             // TODO: Leave with error?
       
  1294             break;
       
  1295         }
       
  1296     }
       
  1297 
       
  1298 // ----------------------------------------------------------------------------
       
  1299 // CMPXPodcastDbHandler::ProcessPodcastFoldersL
       
  1300 // ----------------------------------------------------------------------------
       
  1301 //
       
  1302 void CMPXPodcastDbHandler::ProcessPodcastFoldersL(
       
  1303     const CDesCArray& aFolders)
       
  1304     {
       
  1305     MPX_FUNC("CMPXPodcastDbHandler::ProcessPodcastFoldersL");
       
  1306 
       
  1307     TInt count(aFolders.MdcaCount());
       
  1308     for (TInt i = 0; i < count; ++i)
       
  1309         {
       
  1310         TPtrC16 folder = aFolders.MdcaPoint(i);
       
  1311 
       
  1312         // check if disk is inserted and act accordingly
       
  1313         TDriveUnit driveUnit(folder);
       
  1314         if (!iFs.IsValidDrive(driveUnit))
       
  1315             {
       
  1316             User::Leave(KErrArgument);
       
  1317             }
       
  1318 
       
  1319         // append the drive to the drive list
       
  1320         iDbDrives.AppendL(driveUnit);
       
  1321 
       
  1322         // make sure the folder is created
       
  1323         TVolumeInfo info;
       
  1324         if (iFs.Volume(info, driveUnit) == KErrNone)
       
  1325            {
       
  1326             if (!BaflUtils::PathExists(iFs, folder))
       
  1327                 {
       
  1328                 // create music folder if necessary
       
  1329                 TInt err(iFs.MkDirAll(folder));
       
  1330                 MPX_DEBUG3("Try to create podcast folder %S return code %d", &folder, err);
       
  1331                 if (err != KErrAlreadyExists)
       
  1332                     {
       
  1333                     User::LeaveIfError(err);
       
  1334                     }
       
  1335                 }
       
  1336             }
       
  1337         }
       
  1338     }
       
  1339 
       
  1340 // ----------------------------------------------------------------------------
       
  1341 // CMPXPodcastDbHandler::DbCategoryL
       
  1342 // ----------------------------------------------------------------------------
       
  1343 //
       
  1344 CMPXDbCategory* CMPXPodcastDbHandler::DbCategoryL(
       
  1345     TMPXGeneralCategory aCategory) const
       
  1346     {
       
  1347     MPX_FUNC("CMPXPodcastDbHandler::DbCategoryL");
       
  1348 
       
  1349     CMPXDbCategory* dbCategory(NULL);
       
  1350     switch (aCategory)
       
  1351         {
       
  1352         case EMPXArtist:
       
  1353             {
       
  1354             dbCategory = iDbArtist;
       
  1355             break;
       
  1356             }
       
  1357         case EMPXAlbum:
       
  1358             {
       
  1359             dbCategory = iDbAlbum;
       
  1360             break;
       
  1361             }
       
  1362         case EMPXGenre:
       
  1363             {
       
  1364             dbCategory = iDbGenre;
       
  1365             break;
       
  1366             }
       
  1367         case EMPXComposer:
       
  1368             {
       
  1369             dbCategory = iDbComposer;
       
  1370             break;
       
  1371             }
       
  1372         default:
       
  1373             User::Leave(KErrNotSupported);
       
  1374         }
       
  1375 
       
  1376     return dbCategory;
       
  1377     }
       
  1378 
       
  1379 // ----------------------------------------------------------------------------
       
  1380 // Starts a transaction on all databases
       
  1381 // ----------------------------------------------------------------------------
       
  1382 //
       
  1383 void CMPXPodcastDbHandler::BeginTransactionL()
       
  1384     {
       
  1385     MPX_FUNC("CMPXPodcastDbHandler::BeginTransactionL");
       
  1386     iDbManager->BeginL();
       
  1387     }
       
  1388 
       
  1389 // ----------------------------------------------------------------------------
       
  1390 // Ends a transaction on all databases
       
  1391 // ----------------------------------------------------------------------------
       
  1392 //
       
  1393 void CMPXPodcastDbHandler::EndTransactionL(
       
  1394     TInt aError)
       
  1395     {
       
  1396     MPX_FUNC("CMPXPodcastDbHandler::EndTransactionL");
       
  1397 
       
  1398     if (aError)
       
  1399         {
       
  1400         iDbManager->RollbackL();
       
  1401         
       
  1402         // KSqlDbCorrupted indicates DB corrupted, need to recreate.
       
  1403         if ( aError != KSqlDbCorrupted )
       
  1404             {
       
  1405             User::Leave(aError);
       
  1406             }
       
  1407         }
       
  1408     else
       
  1409         {
       
  1410         iDbManager->CommitL();
       
  1411         }
       
  1412     }
       
  1413 
       
  1414 // ----------------------------------------------------------------------------
       
  1415 // Checks if the database is currently in a transaction
       
  1416 // ----------------------------------------------------------------------------
       
  1417 //
       
  1418 TBool CMPXPodcastDbHandler::InTransaction()
       
  1419     {
       
  1420     MPX_FUNC("CMPXPodcastDbHandler::InTransaction");
       
  1421     return iDbManager->InTransaction();
       
  1422     }
       
  1423 
       
  1424 // ----------------------------------------------------------------------------
       
  1425 // Verifies that the volume ID of the database matches the drive
       
  1426 // ----------------------------------------------------------------------------
       
  1427 //
       
  1428 void CMPXPodcastDbHandler::VerifyVolumeIdL()
       
  1429     {
       
  1430     MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL <--");
       
  1431 
       
  1432     TInt count( iDbDrives.Count() );
       
  1433     for( TInt i=0; i<count; ++i )
       
  1434         {
       
  1435         if( iDbManager->IsOpen(iDbDrives[i]) )
       
  1436             {
       
  1437             TVolumeInfo volInfo;
       
  1438             iFs.Volume(volInfo, iDbDrives[i] );
       
  1439             TUint curId(volInfo.iUniqueID);
       
  1440 
       
  1441             TInt volId = iDbAuxiliary->IdL( iDbDrives[i] );
       
  1442 
       
  1443             // New database, no volume id set, mask out top bit because this is an uint
       
  1444             //
       
  1445             MPX_DEBUG3("CMPXPodcastDbHandler::VerifyVolumeIdL drive:%i db:%i", curId, volId);
       
  1446             if( volId == 0 )
       
  1447                 {
       
  1448                 MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL -- New ID");
       
  1449                 BeginTransactionL();
       
  1450                 TRAPD( err, iDbAuxiliary->SetIdL( iDbDrives[i], curId&0x7FFFFFFF ) );
       
  1451                 EndTransactionL( err );
       
  1452 
       
  1453                 // KSqlDbCorrupted indicates DB corrupted, need to recreate.
       
  1454                 if ( err == KSqlDbCorrupted )
       
  1455                     {
       
  1456                     MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL -- Corrupted DB");
       
  1457                     iDbManager->RecreateDatabaseL(iDbDrives[i]);
       
  1458                     BeginTransactionL();
       
  1459                     TRAPD(err, iDbAuxiliary->SetDBCorruptedL( ETrue ) );
       
  1460                     EndTransactionL( err );
       
  1461                     }
       
  1462                 }
       
  1463             // Unmatched volume id, mark db as corrupt
       
  1464             //
       
  1465             else if ( (curId&0x7FFFFFFF) != (volId&0x7FFFFFFFF) )
       
  1466                 {
       
  1467                 MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL -- ID match FAILED");
       
  1468                 iDbManager->RecreateDatabaseL(iDbDrives[i]);
       
  1469                 BeginTransactionL();
       
  1470                 TRAPD(err, iDbAuxiliary->SetDBCorruptedL( ETrue ) );
       
  1471                 EndTransactionL( err );
       
  1472                 }
       
  1473             }
       
  1474         }
       
  1475     MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL -->");
       
  1476     }
       
  1477 
       
  1478 // ----------------------------------------------------------------------------
       
  1479 // Checks if there is a drive that has a low disk space
       
  1480 // ----------------------------------------------------------------------------
       
  1481 //
       
  1482 void CMPXPodcastDbHandler::CheckDiskSpaceOnDrivesL()
       
  1483     {
       
  1484     MPX_DEBUG1("CMPXPodcastDbHandler::CheckDiskSpaceOnDrivesL <--");
       
  1485 
       
  1486     TInt count( iDbDrives.Count() );
       
  1487     for( TInt index=0; index<count; ++index )
       
  1488         {
       
  1489         iDbManager->CheckDiskSpaceL(iDbDrives[index]);
       
  1490         }
       
  1491     MPX_DEBUG1("CMPXPodcastDbHandler::CheckDiskSpaceOnDrivesL -->");
       
  1492     }
       
  1493 #if defined (__MTP_PROTOCOL_SUPPORT)
       
  1494 
       
  1495 // ----------------------------------------------------------------------------
       
  1496 // CMPXPodcastDbHandler::SaveDeletedSongs
       
  1497 // ----------------------------------------------------------------------------
       
  1498 //
       
  1499 TBool CMPXPodcastDbHandler::SaveDeletedSongs()
       
  1500     {
       
  1501     MPX_FUNC("CMPXPodcastDbHandler::SaveDeletedSongs");
       
  1502 
       
  1503     TBool saveDeletedSongs(ETrue);
       
  1504     CRepository* cenrep(NULL);
       
  1505     MPX_TRAPD(error, cenrep = CRepository::NewL(KMPXMtpSettings));
       
  1506     if (!error)
       
  1507         {
       
  1508         cenrep->Get(KMPXMtpSaveDeletedRecordFlag, saveDeletedSongs);
       
  1509         delete cenrep;
       
  1510         MPX_DEBUG2("MTP indicated to save deleted songs? %d", saveDeletedSongs);
       
  1511         }
       
  1512 
       
  1513     return saveDeletedSongs;
       
  1514     }
       
  1515 
       
  1516 #endif
       
  1517 
       
  1518 // ----------------------------------------------------------------------------
       
  1519 // CMPXPodcastDbHandler::AddCategoryItemL
       
  1520 // ----------------------------------------------------------------------------
       
  1521 //
       
  1522 TUint32 CMPXPodcastDbHandler::AddCategoryItemL(
       
  1523     TMPXGeneralCategory aCategory,
       
  1524     const TDesC& aName,
       
  1525     TInt aDriveId,
       
  1526     CMPXMessageArray* aItemChangedMessages)
       
  1527     {
       
  1528     MPX_FUNC("CMPXPodcastDbHandler::AddCategoryItemL");
       
  1529 
       
  1530     TBool newRecord(EFalse);
       
  1531     TUint32 id(DbCategoryL(aCategory)->AddItemL(aName, aDriveId, newRecord,
       
  1532         (aCategory != EMPXGenre)));
       
  1533     if (newRecord && aItemChangedMessages)
       
  1534         {
       
  1535         MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id,
       
  1536             EMPXItemInserted, aCategory, KDBPluginUid);
       
  1537         }
       
  1538 
       
  1539     return id;
       
  1540     }
       
  1541 
       
  1542 // ----------------------------------------------------------------------------
       
  1543 // CMPXPodcastDbHandler::DeleteEpisodeForCategoryL
       
  1544 // ----------------------------------------------------------------------------
       
  1545 //
       
  1546 void CMPXPodcastDbHandler::DeleteEpisodeForCategoryL(
       
  1547     TMPXGeneralCategory aCategory,
       
  1548     TUint32 aCategoryId,
       
  1549     TInt aDriveId,
       
  1550     CMPXMessageArray* aItemChangedMessages)
       
  1551     {
       
  1552     MPX_FUNC("CMPXPodcastDbHandler::DeleteEpisodeForCategoryL");
       
  1553     DbCategoryL(aCategory)->DecrementEpisodesForCategoryL(aCategoryId, aDriveId,
       
  1554         aItemChangedMessages);
       
  1555     }
       
  1556 
       
  1557 #ifdef RD_MULTIPLE_DRIVE
       
  1558 
       
  1559 // ----------------------------------------------------------------------------------------------------------
       
  1560 // Retrieve all visible podcast folder locations
       
  1561 // ----------------------------------------------------------------------------------------------------------
       
  1562 //
       
  1563 CDesCArrayFlat* CMPXPodcastDbHandler::GetPodcastFoldersL()
       
  1564     {
       
  1565     MPX_FUNC("CMPXPodcastDbHandler::GetPodcastFoldersL()");
       
  1566     TDriveList driveList;
       
  1567     TInt driveCount(0);
       
  1568     User::LeaveIfError(DriveInfo::GetUserVisibleDrives(iFs, driveList, driveCount));
       
  1569     MPX_DEBUG2 ("CMPXDbHandler::GetPodcastFoldersL() - driveCount = %d", driveCount);
       
  1570 
       
  1571     CDesCArrayFlat* folders = new (ELeave) CDesCArrayFlat(1); // granularity
       
  1572     CleanupStack::PushL(folders);
       
  1573 
       
  1574     for (TInt i = EDriveA; i <= EDriveZ; i++)
       
  1575         {
       
  1576         if ((driveList[i]) && (!IsRemoteDrive(static_cast<TDriveNumber>(i))))
       
  1577             {
       
  1578             if (i == EDriveC)
       
  1579                 {
       
  1580                 // Append the default phone memory path to the list
       
  1581                 // of music folders
       
  1582                 TPtrC rootPath(PathInfo::PhoneMemoryRootPath());
       
  1583                 folders->AppendL(rootPath);
       
  1584                 MPX_DEBUG2("CMPXDbHandler::GetPodcastFoldersL() - adding...%S", &rootPath);
       
  1585                 }
       
  1586             else
       
  1587                 {
       
  1588                 // Get drive letter
       
  1589                 TChar driveChar;
       
  1590                 User::LeaveIfError(iFs.DriveToChar(i, driveChar));
       
  1591 
       
  1592                 // Append visible drive to list of music folders
       
  1593                 TBuf<2> drive;
       
  1594                 drive.Append(driveChar);
       
  1595                 drive.Append(_L(":"));
       
  1596                 folders->AppendL(drive);
       
  1597                 MPX_DEBUG2 ("CMPXDbHandler::GetPodcastFoldersL() - adding...%S", &drive);
       
  1598                 }
       
  1599             }
       
  1600         }
       
  1601 
       
  1602     CleanupStack::Pop(folders);
       
  1603     return folders;
       
  1604     }
       
  1605 
       
  1606 #endif // RD_MULTIPLE_DRIVE
       
  1607 
       
  1608 // ---------------------------------------------------------------------------
       
  1609 // CMPXPodcastDbHandler::IsRemoteDrive
       
  1610 // ---------------------------------------------------------------------------
       
  1611 //
       
  1612 TBool CMPXPodcastDbHandler::IsRemoteDrive(TDriveNumber aDrive)
       
  1613     {
       
  1614     return iDbManager->IsRemoteDrive(aDrive);
       
  1615     }
       
  1616 
       
  1617 // End of File
       
  1618 
       
  1619