diff -r 14979e23cb5e -r 3de6c4cf6b67 mpxplugins/serviceplugins/collectionplugins/mpxsqlitepodcastdbplugin/src/mpxpodcastdbhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpxplugins/serviceplugins/collectionplugins/mpxsqlitepodcastdbplugin/src/mpxpodcastdbhandler.cpp Wed Sep 01 12:32:02 2010 +0100 @@ -0,0 +1,1616 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This class is used by db plugin to add episodes into DB or +* remove episodes from DB +* +*/ + + +// INCLUDE FILES +#include +#include +#include +#ifdef RD_MULTIPLE_DRIVE +#include +#include +#endif //RD_MULTIPLE_DRIVE + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mpxdbcommondef.h" +#include "mpxresource.h" +#include "mpxdbcommonutil.h" + +#include "mpxdbutil.h" +#include "mpxpodcastcollectiondbdef.h" +#include "mpxpodcastdbmanager.h" +#include "mpxdbcategory.h" +#include "mpxdbauxiliary.h" +#include "mpxpodcastdbhandler.h" +#include "mpxpodcastdbpluginqueries.h" + +// CONSTANTS +#if defined (__MTP_PROTOCOL_SUPPORT) +#include + +const TUid KMPXMtpSettings = {0x101FFC53}; // MTP CenRep Key UID +const TUint32 KMPXMtpSaveDeletedRecordFlag = 0x00000001; // MTP CenRep Key for Delete contents +#endif +const TInt KSqlDbCorrupted = -321; + +// ============================ MEMBER FUNCTIONS ============================== + +// ---------------------------------------------------------------------------- +// Two-phased constructor. +// ---------------------------------------------------------------------------- +// +CMPXPodcastDbHandler* CMPXPodcastDbHandler::NewL( + RFs& aFs, + CMPXResource& aResource) + { + MPX_FUNC("CMPXPodcastDbHandler::NewL"); + + CMPXPodcastDbHandler* self = CMPXPodcastDbHandler::NewLC(aFs, aResource); + CleanupStack::Pop(self); + return self; + } + +// ---------------------------------------------------------------------------- +// Two-phased constructor. +// ---------------------------------------------------------------------------- +// +CMPXPodcastDbHandler* CMPXPodcastDbHandler::NewLC( + RFs& aFs, + CMPXResource& aResource) + { + MPX_FUNC("CMPXPodcastDbHandler::NewLC"); + + CMPXPodcastDbHandler* self = new (ELeave) CMPXPodcastDbHandler(aFs, aResource); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// ---------------------------------------------------------------------------- +// Destructor +// ---------------------------------------------------------------------------- +// +CMPXPodcastDbHandler::~CMPXPodcastDbHandler() + { + MPX_FUNC("CMPXPodcastDbHandler::~CMPXPodcastDbHandler"); + + delete iDbPodcast; + delete iDbArtist; + delete iDbAlbum; + delete iDbGenre; + delete iDbComposer; + delete iDbAuxiliary; + delete iDbManager; + + delete iPodcastPublishDateCat; + iPodcastPublishDateIds.Close(); + iDbDrives.Close(); + } + +// ---------------------------------------------------------------------------- +// C++ default constructor can NOT contain any code, that might leave +// ---------------------------------------------------------------------------- +// +CMPXPodcastDbHandler::CMPXPodcastDbHandler( + RFs& aFs, + CMPXResource& aResource) : + iFs(aFs), + iResource(aResource) + { + MPX_FUNC("CMPXPodcastDbHandler::CMPXPodcastDbHandler"); + } + +// ---------------------------------------------------------------------------- +// Symbian 2nd phase constructor can leave. +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::ConstructL() + { + MPX_FUNC("CMPXPodcastDbHandler::ConstructL"); + + iPodcastPublishDateCat = iResource.ReadMenuArrayL(R_MPX_QTN_NMP_PUBLISH_DATE_ARRAY, + iPodcastPublishDateIds); + + //create db manager + iDbManager = CMPXPodcastDbManager::NewL(iFs); + CDesCArrayFlat* podcastFolders = +#ifdef RD_MULTIPLE_DRIVE + GetPodcastFoldersL(); +#else + iResource.ReadDesCArrayL(R_MC_DEFAULT_MUSIC_FOLDERS); +#endif + + // create the podcast folders and initialize iDbDrives + CleanupStack::PushL(podcastFolders); + ProcessPodcastFoldersL(*podcastFolders); + CleanupStack::PopAndDestroy(podcastFolders); + + // create the db infrastructure + iDbPodcast = CMPXDbPodcast::NewL(*iDbManager, iResource, *this); + iDbArtist = CMPXDbCategory::NewL(*iDbManager, EMPXArtist); + iDbAlbum = CMPXDbCategory::NewL(*iDbManager, EMPXAlbum); + iDbGenre = CMPXDbCategory::NewL(*iDbManager, EMPXGenre); + iDbComposer = CMPXDbCategory::NewL(*iDbManager, EMPXComposer); + iDbAuxiliary = CMPXDbAuxiliary::NewL(*iDbManager); + + // make sure all databases are created and valid + MPX_TRAPD(err, iDbManager->InitDatabasesL(iDbDrives)); + + // If KErrCorrupt is returned, a database file was found to be corrupted + // and was replaced with a new one. The db plugin can ignore this error and continue + // because a new db file was successfully created in a subsequent retry. + if ((err != KErrNone) && (err != KErrCorrupt) && (err != KErrDiskFull)) + { + // leave to signal the caller that there was an error why creating and opening + // one or more of the databases + User::Leave(err); + } + else if (err == KErrDiskFull) + { + iOutOfDisk = ETrue; + } + else + { + // do nothing + } + // Verify the volume ID Matches + MPX_TRAP(err,VerifyVolumeIdL()); + if ((err != KErrNone) && (err != KErrDiskFull)) + { + // leave to signal the caller that there was an error why creating and opening + // one or more of the databases + User::Leave(err); + } + else if (err == KErrDiskFull) + { + iOutOfDisk = ETrue; + } + + // iDbManager->PrintDatabaseL(); + + MPX_DEBUG2("CMPXDbHandler::ConstructL DbCount[%d]", iDbManager->DatabaseCount()); + } + +// ---------------------------------------------------------------------------- +// Add episode into collection +// ---------------------------------------------------------------------------- +// +TUint32 CMPXPodcastDbHandler::AddEpisodeL( + const CMPXMedia& aMedia) + { + MPX_FUNC("CMPXPodcastDbHandler::AddEpisodeL"); + + BeginTransactionL(); + + TUint32 episodeId(0); + MPX_TRAPD(err, episodeId = DoAddEpisodeL(aMedia)); + + if (iOutOfDisk && (err == KErrNotFound)) + { + err = KErrDiskFull; + } + EndTransactionL(err); + + return episodeId; + } + +// ---------------------------------------------------------------------------- +// Update a episode in the collection +// ---------------------------------------------------------------------------- +// +CMPXDbActiveTask::TChangeVisibility CMPXPodcastDbHandler::UpdateEpisodeL( + const CMPXMedia& aMedia, + CMPXMessageArray& aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbHandler::UpdateEpisodeL"); + + BeginTransactionL(); + CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile); + MPX_TRAPD(err, visibleChange = DoUpdateEpisodeL(aMedia, aItemChangedMessages)); + EndTransactionL(err); + return visibleChange; + } + +// ---------------------------------------------------------------------------- +// Remove the entire podcast collection database +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::RemoveEntireCollectionL() + { + MPX_FUNC("CMPXPodcastDbHandler::RemoveEntireCollectionL"); + + BeginTransactionL(); + MPX_TRAPD(err, iDbManager->RecreateAllDatabasesL()); + EndTransactionL(err); + } + +// ---------------------------------------------------------------------------- +// Delete a episode from collection +// The function notifies collection model to perform deletion +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::RemoveEpisodeL( + TUint32 aEpisodeId, + CDesCArray& aUriArray, + CMPXMessageArray& aItemChangedMessages, + TBool aDeleteRecord) + { + MPX_FUNC("CMPXPodcastDbHandler::RemoveEpisodeL"); + + BeginTransactionL(); + MPX_TRAPD(err, DoRemoveEpisodeL(aEpisodeId, aUriArray, aItemChangedMessages, aDeleteRecord)); + EndTransactionL(err); + } + +// ---------------------------------------------------------------------------- +// Removes a category of episodes from the podcast collection, and its +// corresponding category in the lookup table +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::RemoveEpisodesMatchingCategoryL( + TMPXGeneralCategory aCategory, + TUint32 aCategoryId, + CDesCArray& aUriArray, + CMPXMessageArray& aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbHandler::RemoveEpisodesMatchingCategoryL"); + + BeginTransactionL(); + MPX_TRAPD(err, DoRemoveEpisodesMatchingCategoryL(aCategory, aCategoryId, + aUriArray, aItemChangedMessages)); + EndTransactionL(err); + } + +// ---------------------------------------------------------------------------- +// Delete episode(s) from collection belonging to specified publish date category +// The function notifies collection model to perform deletion +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::RemoveEpisodesMatchingPublishDateCategoryL( + TUint32 aCategoryId, + CDesCArray& aUriArray, + CMPXMessageArray& aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbHandler::RemoveEpisodesMatchingPublishDateCategoryL"); + + BeginTransactionL(); + MPX_TRAPD(err, DoRemoveEpisodesMatchingPublishDateCategoryL(aCategoryId, + aUriArray, aItemChangedMessages)); + EndTransactionL(err); + } + +// ---------------------------------------------------------------------------- +// Cleanup records marked as deleted. This is designated for MTP to clean up +// records marked as deleted at the end of its session. +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::CleanupDeletedRecordsL() + { + MPX_FUNC("CMPXPodcastDbHandler::CleanupDeletedRecordsL"); + + BeginTransactionL(); + MPX_TRAPD(err, DoCleanupDeletedRecordsL()); + EndTransactionL(err); + } + +// ---------------------------------------------------------------------------- +// Read all episodes and cache them into an array ordered by episode name +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::GetAllEpisodesL( + const TArray& aAttrs, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXPodcastDbHandler::GetAllEpisodesL"); + iDbPodcast->GetAllEpisodesL(aAttrs, aMediaArray); + } + +// ---------------------------------------------------------------------------- +// Retrieve the episode(s) with the specified title +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::GetEpisodesMatchingTitleL( + TUint aTitleId, + const TArray& aAttrs, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXPodcastDbHandler::GetEpisodesMatchingTitleL"); + iDbPodcast->GetEpisodesForCategoryL(EMPXAlbum, aTitleId, aAttrs, + aMediaArray, ETrue); + } + +// ---------------------------------------------------------------------------- +// Retrieve the episode(s) belonging to the specified playlist +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::GetEpisodesMatchingPlaylistL( + TUint aPlaylistId, + const TArray& aAttrs, + CMPXMediaArray& aMediaArray, + TInt& aIndexOfCurrentlyPlayingItem) + { + MPX_FUNC("CMPXPodcastDbHandler::GetEpisodesMatchingPlaylistL"); + + switch (aPlaylistId) + { + case KRecentlyAddedPlaylistUID: + { + iDbPodcast->GetRecentlyAddedPlaylistEpisodesL(aAttrs, aMediaArray, + aIndexOfCurrentlyPlayingItem); + break; + } + case KNotPlayedPlaylistUID: + { + iDbPodcast->GetNotYetPlayedPlaylistEpisodesL(aAttrs, aMediaArray, + aIndexOfCurrentlyPlayingItem); + break; + } + default: + { + User::Leave(KErrNotSupported); + } + } + } + +// ---------------------------------------------------------------------------- +// Retrieve the episode with the specified ID +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::GetEpisodeL( + TUint32 aEpisodeId, + const TArray& aAttrs, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXPodcastDbHandler::GetEpisodeL"); + + CMPXMedia* media = CMPXMedia::NewL(); + CleanupStack::PushL(media); + + GetEpisodeL(aEpisodeId, aAttrs, *media); + aMediaArray.AppendL(*media); + + CleanupStack::PopAndDestroy(media); + } + +// ---------------------------------------------------------------------------- +// Retrieve the episode with the specified ID +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::GetEpisodeL( + TUint32 aEpisodeId, + const TArray& aAttrs, + CMPXMedia& aMedia) + { + MPX_FUNC("CMPXPodcastDbHandler::GetEpisodeL"); + iDbPodcast->GetEpisodeL(aEpisodeId, aAttrs, aMedia); + } + +// ---------------------------------------------------------------------------- +// Retrieve the episode with the specified URI +// ---------------------------------------------------------------------------- +// +TUint32 CMPXPodcastDbHandler::GetEpisodeIdMatchingUriL( + const TDesC& aUri) + { + MPX_FUNC("CMPXPodcastDbHandler::GetEpisodeIdMatchingUriL"); + return MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, aUri, EFalse); + } + +// ---------------------------------------------------------------------------- +// Return all podcast title names +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::GetAllPodcastTitlesL( + const TArray& aAttrs, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXPodcastDbHandler::GetAllPodcastTitlesL"); + iDbAlbum->GetAllCategoryItemsL(aAttrs, aMediaArray); + } + +// ---------------------------------------------------------------------------- +// Retrieve episodes matching the specified publish playlist id +// ---------------------------------------------------------------------------- +// +TInt CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL( + TUint aPlaylistId, + const TArray& aAttrs, + TBool aPendingCategoryDeletionFlag, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL"); + + TInt numEpisodes(0); + TMPXItemId podcastPublishDateCatId = 0; + + // the deletion helper is retrieving all the media within this category + // to delete it so need to record category id within last item so + // that the HandleChangeL callback can cause OpenL to be called after the + // last item within the category is deleted + if (aPendingCategoryDeletionFlag) + { + TInt categoryID(EMPXOther); + + // pass in the category Id so that the helper method can add + // the category Id to the last item in this category to aid + // in deletion of a category + podcastPublishDateCatId = (aPlaylistId - KPublishTodayPlaylistUID) | (categoryID << 28); + } + + switch (aPlaylistId) + { + case KPublishAllPlaylistUID: + { + TInt itemCount(iPodcastPublishDateCat->Count()); + for (TInt i = 0; i < itemCount; ++i) + { + TMPXItemId itemId = iPodcastPublishDateIds[i]; + TInt count(0); + + switch (iPodcastPublishDateIds[i] + KPublishTodayPlaylistUID) + { + case KPublishTodayPlaylistUID: + count = iDbPodcast->GetTodayEpisodesCountL(); + break; + case KPublishYesterdayPlaylistUID: + count = iDbPodcast->GetYesterdayEpisodesCountL(); + break; + case KPublishThisWeekPlaylistUID: + count = iDbPodcast->GetThisWeekEpisodesCountL(); + break; + case KPublishLastWeekPlaylistUID: + count = iDbPodcast->GetLastWeekEpisodesCountL(); + break; + case KPublish2WeeksAgoPlaylistUID: + count = iDbPodcast->Get2WeeksAgoEpisodesCountL(); + break; + case KPublish3WeeksAgoPlaylistUID: + count = iDbPodcast->Get3WeeksAgoEpisodesCountL(); + break; + case KPublishLastMonthPlaylistUID: + count = iDbPodcast->GetLastMonthEpisodesCountL(); + break; + case KPublishEarlierPlaylistUID: + count = iDbPodcast->GetEarlierEpisodesCountL(); + break; + case KPublishUnknownPlaylistUID: + count = iDbPodcast->GetUnknownEpisodesCountL(); + break; + default: + User::Leave(KErrNotFound); + break; + }; + + if (count > 0) + { + numEpisodes += count; + MPXDbUtil::AppendMediaL(aMediaArray, iPodcastPublishDateCat->MdcaPoint(i), + EMPXGroup, EMPXPlaylist, EMPXPodcastGroup, EMPXPubDate, itemId); + } + } + break; + } + + case KPublishTodayPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published Today")); + iDbPodcast->GetTodayEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray); + break; + + case KPublishYesterdayPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published Yesterday")); + iDbPodcast->GetYesterdayEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray); + break; + + case KPublishThisWeekPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published This Week")); + iDbPodcast->GetThisWeekEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray); + break; + + case KPublishLastWeekPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published Last Week")); + iDbPodcast->GetLastWeekEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray); + break; + + case KPublish2WeeksAgoPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published 2 Weeks Ago")); + iDbPodcast->Get2WeeksAgoEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray); + break; + + case KPublish3WeeksAgoPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published 3 Weeks Ago")); + iDbPodcast->Get3WeeksAgoEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray); + break; + + case KPublishLastMonthPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published Last Month")); + iDbPodcast->GetLastMonthEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray); + break; + + case KPublishEarlierPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published Earlier")); + iDbPodcast->GetEarlierEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray); + break; + + case KPublishUnknownPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Published Unknown")); + iDbPodcast->GetUnknownEpisodesL(podcastPublishDateCatId, aAttrs, aMediaArray); + break; + + default: + MPX_DEBUG2 (_L("CMPXPodcastDbHandler::GetEpisodesMatchingPublishPlaylistL: Invalid publish ID [%d]"), aPlaylistId); + User::Leave(KErrNotFound); + break; + } + + if (aPlaylistId != KPublishAllPlaylistUID) + { + numEpisodes = aMediaArray.Count(); + } + + return numEpisodes; + } + +// ---------------------------------------------------------------------------- +// Get the name of the row matching the given ID +// ---------------------------------------------------------------------------- +// +HBufC* CMPXPodcastDbHandler::GetTitleNameMatchingIdL( + const TUint32 aId) + { + MPX_FUNC("CMPXPodcastDbHandler::GetTitleNameMatchingIdL"); + return iDbAlbum->GetNameL(aId); + } + +// ---------------------------------------------------------------------------- +// Get the URI of the row matching the given ID +// ---------------------------------------------------------------------------- +// +HBufC* CMPXPodcastDbHandler::GetUriMatchingIdL( + const TUint32 aId) + { + MPX_FUNC("CMPXPodcastDbHandler::GetUriMatchingIdL"); + + return iDbPodcast->GetUriL(aId); + } + +// ---------------------------------------------------------------------------- +// Find episode(s) that satisfy the specified criteria +// ---------------------------------------------------------------------------- +// +CMPXMedia* CMPXPodcastDbHandler::FindAllLC( + const CMPXMedia& aCriteria, + const TArray& aAttrs) + { + MPX_FUNC("CMPXPodcastDbHandler::FindAllLC"); + + // leave if the given media doesn't contain the following attributes + if (!aCriteria.IsSupported(KMPXMediaGeneralType) || + !aCriteria.IsSupported(KMPXMediaGeneralCategory)) + { + User::Leave(KErrArgument); + } + + RArray supportedIds; + CleanupClosePushL(supportedIds); + supportedIds.AppendL(KMPXMediaIdContainer); + MPXDbCommonUtil::FillInSupportedUIDsL(aAttrs, supportedIds); + + CMPXMedia* entries = CMPXMedia::NewL(supportedIds.Array()); + CleanupStack::PopAndDestroy(&supportedIds); + CleanupStack::PushL(entries); + + CMPXMediaArray* array = CMPXMediaArray::NewL(); + CleanupStack::PushL(array); + + FindAllL(aCriteria, aAttrs, *array); + + entries->SetTObjectValueL(KMPXMediaGeneralType, EMPXGroup); + entries->SetTObjectValueL(KMPXMediaGeneralCategory, + aCriteria.ValueTObjectL(KMPXMediaGeneralCategory)); + entries->SetCObjectValueL(KMPXMediaArrayContents, array); + entries->SetTObjectValueL(KMPXMediaArrayCount, array->Count()); + + CleanupStack::PopAndDestroy(array); + return entries; + } + +// ---------------------------------------------------------------------------- +// Find the number of items in the database +// ---------------------------------------------------------------------------- +// +TInt CMPXPodcastDbHandler::NumberOfItemsL( + TMPXPodcastCategory aCategory) + { + MPX_FUNC("CMPXPodcastDbHandler::NumberOfItemsL"); + + TInt numOfItems(0); + + switch(aCategory) + { + case EMPXAll: + case EMPXEpisode: + { + numOfItems = iDbPodcast->CountL(); + break; + } + case EMPXRecentlyAdded: + { + numOfItems = iDbPodcast->GetRecentlyAddedEpisodesCountL(); + break; + } + case EMPXNotYetPlayed: + { + numOfItems = iDbPodcast->GetNotYetPlayedEpisodesCountL(); + break; + } + case EMPXTitle: + { + numOfItems = iDbPodcast->GetNotYetPlayedEpisodesCountL(); + break; + } + default: + { + User::Leave(KErrNotSupported); + } + } + + return numOfItems; + } + +// ---------------------------------------------------------------------------- +// Has the database been created? +// ---------------------------------------------------------------------------- +// +TBool CMPXPodcastDbHandler::DatabaseCreated() + { + MPX_FUNC("CMPXPodcastDbHandler::DatabaseCreated"); + + TBool AuxilaryDbIsRefreshed(EFalse); + TRAP_IGNORE(AuxilaryDbIsRefreshed = iDbAuxiliary->IsRefreshedL()); + // If none of the databases were available, ie out of disk + // we return EFalse + return iDbManager->IsInitialized() && AuxilaryDbIsRefreshed; + } + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::GetAllEpisodesDurationL +// ---------------------------------------------------------------------------- +// +TInt CMPXPodcastDbHandler::GetAllEpisodesDurationL() + { + MPX_FUNC("CMPXPodcastDbHandler::GetAllEpisodesDurationL"); + return iDbPodcast->AllEpisodesDurationL(); + } + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::GetTitleDurationL +// ---------------------------------------------------------------------------- +// +TInt CMPXPodcastDbHandler::GetTitleDurationL( + TUint32 aTitleId) + { + MPX_FUNC("CMPXPodcastDbHandler::GetTitleDurationL"); + return iDbPodcast->TitleDurationL(aTitleId); + } + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::GetNotPlayedDurationL +// ---------------------------------------------------------------------------- +// +TInt CMPXPodcastDbHandler::GetNotPlayedDurationL() + { + MPX_FUNC("CMPXPodcastDbHandler::GetNotPlayedDurationL"); + return iDbPodcast->NotPlayedDurationL(); + } + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::GetRecentlyAddedDurationL +// ---------------------------------------------------------------------------- +// +TInt CMPXPodcastDbHandler::GetRecentlyAddedDurationL() + { + MPX_FUNC("CMPXPodcastDbHandler::GetRecentlyAddedDurationL"); + return iDbPodcast->RecentlyAddedDurationL(); + } + +// ---------------------------------------------------------------------------- +// Set the last refreshed time into the collection +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::SetLastRefreshedTimeL( + TTime aTime) + { + MPX_FUNC("CMPXPodcastDbHandler::SetLastRefreshedTimeL"); + + BeginTransactionL(); + MPX_TRAPD(err, iDbAuxiliary->SetLastRefreshedTimeL(aTime)); + EndTransactionL(err); + } + +// ---------------------------------------------------------------------------- +// Get the last refreshed time into the collection +// ---------------------------------------------------------------------------- +// +TTime CMPXPodcastDbHandler::GetLastRefreshedTimeL() + { + MPX_FUNC("CMPXPodcastDbHandler::GetLastRefreshedTimeL"); + return iDbAuxiliary->LastRefreshedTimeL(); + } + +// ---------------------------------------------------------------------------- +// Set the db corrupted state for all drives +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::SetDBCorruptedL( + TBool aCorrupted) + { + MPX_FUNC("CMPXPodcastDbHandler::SetDBCorruptedL"); + + BeginTransactionL(); + MPX_TRAPD(err, iDbAuxiliary->SetDBCorruptedL(aCorrupted)); + EndTransactionL(err); + } + +// ---------------------------------------------------------------------------- +// Gets the db corrupted state for all drives +// ---------------------------------------------------------------------------- +// +TBool CMPXPodcastDbHandler::IsDBCorruptedL() + { + MPX_FUNC("CMPXPodcastDbHandler::IsDBCorruptedL"); + return iDbAuxiliary->DBCorruptedL(); + } + +// ---------------------------------------------------------------------------- +// Opens a database +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::OpenDatabaseL( + TInt aDrive) + { + MPX_FUNC("CMPXPodcastDbHandler::OpenDatabaseL"); + iDbManager->OpenDatabaseL(aDrive); + + // Verify the volume ID after a remount event + VerifyVolumeIdL( aDrive ); + } + +// ---------------------------------------------------------------------------- +// Close a database +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::CloseDatabaseL( + TInt aDrive) + { + MPX_FUNC("CMPXPodcastDbHandler::CloseDatabaseL"); + iDbManager->CloseDatabaseL(aDrive); + } + +// ---------------------------------------------------------------------------- +// Re-create all databases +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::ReCreateDatabasesL() + { + MPX_FUNC("CMPXPodcastDbHandler::ReCreateDatabasesL"); + iDbManager->RecreateAllDatabasesL(); + } + +// ---------------------------------------------------------------------------- +// Set handler refresh status +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::RefreshStartL() + { + MPX_FUNC("CMPXPodcastDbHandler::RefreshStartL"); + + iOutOfDisk = EFalse; + // Re-open databases + // This is needed for the case where we were OOD before, but user + // has cleared some space but now try to refresh + MPX_TRAPD(err, iDbManager->InitDatabasesL(iDbDrives)); + + if(err == KErrDiskFull) + { + iOutOfDisk = ETrue; + } + + if(!iOutOfDisk) + { + MPX_TRAP(err,CheckDiskSpaceOnDrivesL()); + + if(err == KErrDiskFull) + { + iOutOfDisk = ETrue; + } + } + BeginTransactionL(); + } + +// ---------------------------------------------------------------------------- +// Re-set handler refresh status +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::RefreshEndL() + { + MPX_FUNC("CMPXPodcastDbHandler::RefreshEndL"); + + EndTransactionL(KErrNone); + + if (!iOutOfDisk) + { + // Write last refreshed time as current time + // This also sets corrupt = 0 + TTime curTime; + curTime.HomeTime(); + SetLastRefreshedTimeL(curTime); +// iDbManager->PrintDatabaseL(); // PREQ2536 the files sqlrowsetutil.h and sqlrowsetutil.cpp has been removed + } + } + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::SetIsPlayingL +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::SetIsPlayingL( + const CMPXMedia& aMedia, + TBool aIsPlaying) + { + MPX_FUNC("CMPXPodcastDbHandler::SetIsPlayingL"); + + TUint32 episodeId(0); + if (aMedia.IsSupported(KMPXMediaGeneralId)) + { + episodeId = aMedia.ValueTObjectL(KMPXMediaGeneralId); + } + else if (aMedia.IsSupported(KMPXMediaGeneralUri)) + { + const TDesC& location(aMedia.ValueText(KMPXMediaGeneralUri)); + episodeId = MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, location, EFalse); + } + else + { + User::Leave(KErrArgument); + } + + BeginTransactionL(); + MPX_TRAPD(err, iDbPodcast->SetIsPlayingL(episodeId, aIsPlaying)); + EndTransactionL(err); + } + +// ---------------------------------------------------------------------------- +// Get all records count for podcasts +// ---------------------------------------------------------------------------- +// +TUint CMPXPodcastDbHandler::GetTotalCountL(TInt aDrive) + { + MPX_FUNC("CMPXPodcastDbHandler::GetTotalCountL"); + TUint total(0); + + total = iDbPodcast->GetDrivePodcastCountL(aDrive); + + return total; + } + +// ---------------------------------------------------------------------------- +// Get all records count for podcasts +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::GetPodcastUriArrayL(TInt aDrive, TInt aFromID, TInt aRecords, + CDesCArray& aUriArr, TInt& aLastID) + { + MPX_FUNC("CMPXPodcastDbHandler::GetTotalUriArrayL"); + + iDbPodcast->GetPodcastUriArrayL(aDrive,aFromID,aRecords,aUriArr,aLastID); + } + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::DoCleanupDeletedRecordsL +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::DoCleanupDeletedRecordsL() + { + MPX_FUNC("CMPXPodcastDbHandler::DoCleanupDeletedRecordsL"); + + // delete all marked records from the Music table + iDbPodcast->CleanupL(); + + // reset the count in the Auxiliary table + iDbAuxiliary->SetSaveDeletedRecordCountL(KDbManagerAllDrives,0); + } + +// ---------------------------------------------------------------------------- +// FindAllL helper +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::FindAllL( + const CMPXMedia& aCriteria, + const TArray& aAttrs, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXPodcastDbHandler::FindAllL"); + + RArray attributes; + CleanupClosePushL (attributes); + MPXUser::MergeAttributeL(aAttrs, attributes); + + // TODO: b10liu: update all users to properly use podcast category? + // Some users of FindAll still call without specifying a podcast category group(ie.. delete helper) + // so need to check and use media category instead if not available. + if (!aCriteria.IsSupported(KMPXMediaPodcastCategoryGroup)) + { + if (!aCriteria.IsSupported(KMPXMediaGeneralCategory)) + { + User::Leave(KErrArgument); + } + TMPXGeneralCategory category = aCriteria.ValueTObjectL(KMPXMediaGeneralCategory); + + switch (category) + { + case EMPXAlbum: + { + if (!aCriteria.IsSupported(KMPXMediaGeneralId)) + { + User::Leave(KErrArgument); + } + // return all episodes within this title + TMPXItemId episodeTitleId = aCriteria.ValueTObjectL(KMPXMediaGeneralId); + GetEpisodesMatchingTitleL(episodeTitleId, aAttrs, aMediaArray); + break; + } + case EMPXPodcast: + case EMPXSong: + { + FindEpisodesL(aCriteria, attributes.Array(), aMediaArray); + break; + } + case EMPXGenre: + case EMPXPlaylist: + case EMPXArtist: + case EMPXComposer: + default: + { + DbCategoryL(category)->FindAllL(aCriteria, attributes.Array(), aMediaArray); + break; + } + } + } + else + { + TMPXPodcastCategory category = + aCriteria.ValueTObjectL(KMPXMediaPodcastCategoryGroup); + + switch (category) + { + case EMPXTitle: + { + if (!aCriteria.IsSupported(KMPXMediaGeneralId)) + { + User::Leave(KErrArgument); + } + // return all episodes within this title + TMPXItemId episodeTitleId = aCriteria.ValueTObjectL(KMPXMediaGeneralId); + GetEpisodesMatchingTitleL(episodeTitleId, aAttrs, aMediaArray); + break; + } + case EMPXPubDate: + { + if (!aCriteria.IsSupported(KMPXMediaGeneralId)) + { + User::Leave(KErrArgument); + } + + TMPXItemId categoryId = aCriteria.ValueTObjectL(KMPXMediaGeneralId); + + // zero out the high 4 bits which indicate the general category + categoryId.iId2 &= 0x00FFFFFF; + GetEpisodesMatchingPublishPlaylistL(categoryId.iId2 + KPublishTodayPlaylistUID, // offset by KPublishTodayPlaylistUID + aAttrs, EFalse, aMediaArray); + break; + } + case EMPXRecentlyAdded: + case EMPXNotYetPlayed: + { + break; + } + case EMPXAll: + case EMPXEpisode: + case EMPXNew: + case EMPXPartlyPlayed: + case EMPXCompletelyPlayed: + { + FindEpisodesL(aCriteria, attributes.Array(), aMediaArray); + break; + } + default: + User::Leave(KErrNotSupported); + } + } + + CleanupStack::PopAndDestroy(&attributes); + } + +// ---------------------------------------------------------------------------- +// Get episode(s) from the music table that match the given criteria +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::FindEpisodesL( + const CMPXMedia& aCriteria, + const TArray& aAttrs, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXPodcastDbHandler::FindEpisodesL"); + + TMPXGeneralType type(EMPXNoType); + if (!aCriteria.IsSupported(KMPXMediaGeneralType)) + { + User::Leave(KErrArgument); + } + type = aCriteria.ValueTObjectL(KMPXMediaGeneralType); + + TMPXPodcastType podcastType(EMPXPodcastNoType); + if (aCriteria.IsSupported(KMPXMediaPodcastType)) + { + podcastType = aCriteria.ValueTObjectL(KMPXMediaPodcastType); + } + + TUint32 id(0); + if (aCriteria.IsSupported(KMPXMediaGeneralId)) + { + id = aCriteria.ValueTObjectL(KMPXMediaGeneralId); + } + + TUint32 containerId(0); + if (aCriteria.IsSupported(KMPXMediaGeneralContainerId)) + { + containerId = aCriteria.ValueTObjectL(KMPXMediaGeneralContainerId); + } + + MPX_TRAPD(err, iDbPodcast->FindEpisodesL(id, containerId, type, podcastType, + aCriteria, aAttrs, aMediaArray)); + if (err == KErrNotSupported) + { + User::Leave(KErrNotFound); + } + + User::LeaveIfError(err); + } + +// ---------------------------------------------------------------------------- +// Add episode to collection +// ---------------------------------------------------------------------------- +// +TUint32 CMPXPodcastDbHandler::DoAddEpisodeL( + const CMPXMedia& aMedia) + { + MPX_FUNC("CMPXPodcastDbHandler::DoAddEpisodeL"); + + if (!aMedia.IsSupported(KMPXMediaGeneralUri)) + { + User::Leave(KErrArgument); + } + + TDriveUnit drive(aMedia.ValueText(KMPXMediaGeneralUri)); + return iDbPodcast->AddEpisodeL(aMedia, drive); + } + +// ---------------------------------------------------------------------------- +// Update a episode in the collection +// ---------------------------------------------------------------------------- +// +CMPXDbActiveTask::TChangeVisibility CMPXPodcastDbHandler::DoUpdateEpisodeL( + const CMPXMedia& aMedia, + CMPXMessageArray& aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbHandler::DoUpdateEpisodeL"); + + CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile); + TUint32 curId(0); + TUint32 newId(0); + TInt curDrive(KErrNotFound); + TInt newDrive(KErrNotFound); + + // find the episode by Id and update it + if( aMedia.IsSupported(KMPXMediaGeneralId)) + { + curId = (aMedia.ValueTObjectL(KMPXMediaGeneralId)).iId2; + curDrive = iDbPodcast->GetDriveL(curId); + } + // find the episode by URI and update it + if(aMedia.IsSupported(KMPXMediaGeneralUri)) + { + const TDesC& uri = aMedia.ValueText(KMPXMediaGeneralUri); + if (uri.Length() == 0) + { + User::Leave( KErrArgument ); + } + + newDrive = TDriveUnit(uri); + newId = MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, uri, EFalse); + } + if (!curId && !newId) + { + User::Leave(KErrNotSupported); + } + + TInt driveId = (curDrive != KErrNotFound) ? curDrive : newDrive; + + if (driveId != KErrNotFound) + { + TUint32 episodeId = curId ? curId : newId; + + // Update the Podcast table + visibleChange = iDbPodcast->UpdateEpisodeL(episodeId, aMedia, aItemChangedMessages); + } + + return visibleChange; + } + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::DoRemoveEpisodeL +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::DoRemoveEpisodeL( + TUint32 aEpisodeId, + CDesCArray& aUriArray, + CMPXMessageArray& aItemChangedMessages, + TBool aDeleteRecord) + { + MPX_FUNC("CMPXPodcastDbHandler::DoRemoveEpisodeL"); + + TBool deleteRecord(ETrue); + +#if defined (__MTP_PROTOCOL_SUPPORT) + // Mark the song record as deleted if the following is true; otherwise, delete the + // song record. + // + // A client other than MTP has initiated this song deletion (aDeleteRecord is EFalse) + // and MTP has turned on its cenrep key to save deleted records and current number of + // saved deleted records has not exceeded its maximum, KMCMaxSavedDeletedRecords. + // + // Songs are marked as deleted in order to support auto-sync. MTP will delete these + // marked records at the end of each session via CleanupDeletedMediasL. + // + // For performance consideration, if the number of saved records exceeds its maximum, + // song record will be deleted. + if (!aDeleteRecord && SaveDeletedSongs()) + { + TUint32 savedDeletedRecordCount(iDbAuxiliary->SaveDeletedRecordCountL()); + MPX_DEBUG2("Current number of saved deleted record count is %d", savedDeletedRecordCount); + + if (savedDeletedRecordCount < KMCMaxSavedDeletedRecords) + { + deleteRecord = EFalse; + TInt drive = iDbPodcast->GetDriveL(aEpisodeId); + TUint32 savedDeletedDriveRecordCount(iDbAuxiliary->SaveDeletedRecordCountL(drive)); + iDbAuxiliary->SetSaveDeletedRecordCountL(drive,++savedDeletedDriveRecordCount); + } + } +#endif + + // delete the episode + // IsAdd is passed EFalse to ensure the episode count will be decremented + iDbPodcast->DeleteEpisodeL(aEpisodeId, aUriArray, aItemChangedMessages, EFalse, deleteRecord); + } + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::DoRemoveEpisodesMatchingCategoryL +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::DoRemoveEpisodesMatchingCategoryL( + TMPXGeneralCategory aCategory, + TUint32 aCategoryId, + CDesCArray& aUriArray, + CMPXMessageArray& aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingCategoryL"); + iDbPodcast->DeleteCategoryL(aCategory, aCategoryId, aUriArray, + aItemChangedMessages); + } + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL( + TUint32 aCategoryId, + CDesCArray& aUriArray, + CMPXMessageArray& aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL"); + + switch (aCategoryId + KPublishTodayPlaylistUID) + { + case KPublishTodayPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published Today")); + iDbPodcast->DeleteTodayEpisodesL(aUriArray, aItemChangedMessages); + break; + + case KPublishYesterdayPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published Yesterday")); + iDbPodcast->DeleteYesterdayEpisodesL(aUriArray, aItemChangedMessages); + break; + + case KPublishThisWeekPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published This Week")); + iDbPodcast->DeleteThisWeekEpisodesL(aUriArray, aItemChangedMessages); + break; + + case KPublishLastWeekPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published Last Week")); + iDbPodcast->DeleteLastWeekEpisodesL(aUriArray, aItemChangedMessages); + break; + + case KPublish2WeeksAgoPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published 2 Weeks Ago")); + iDbPodcast->Delete2WeeksAgoEpisodesL(aUriArray, aItemChangedMessages); + break; + + case KPublish3WeeksAgoPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published 3 Weeks Ago")); + iDbPodcast->Delete3WeeksAgoEpisodesL(aUriArray, aItemChangedMessages); + break; + + case KPublishLastMonthPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published Last Month")); + iDbPodcast->DeleteLastMonthEpisodesL(aUriArray, aItemChangedMessages); + break; + + case KPublishEarlierPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published Earlier")); + iDbPodcast->DeleteEarlierEpisodesL(aUriArray, aItemChangedMessages); + break; + + case KPublishUnknownPlaylistUID: + MPX_DEBUG1 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Published Unknown")); + iDbPodcast->DeleteUnknownEpisodesL(aUriArray, aItemChangedMessages); + break; + + default: + MPX_DEBUG2 (_L("CMPXPodcastDbHandler::DoRemoveEpisodesMatchingPublishDateCategoryL: Invalid publish date ID [%d]"), aCategoryId); + // TODO: Leave with error? + break; + } + } + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::ProcessPodcastFoldersL +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::ProcessPodcastFoldersL( + const CDesCArray& aFolders) + { + MPX_FUNC("CMPXPodcastDbHandler::ProcessPodcastFoldersL"); + + TInt count(aFolders.MdcaCount()); + for (TInt i = 0; i < count; ++i) + { + TPtrC16 folder = aFolders.MdcaPoint(i); + + // check if disk is inserted and act accordingly + TDriveUnit driveUnit(folder); + if (!iFs.IsValidDrive(driveUnit)) + { + User::Leave(KErrArgument); + } + + // append the drive to the drive list + iDbDrives.AppendL(driveUnit); + } + } + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::DbCategoryL +// ---------------------------------------------------------------------------- +// +CMPXDbCategory* CMPXPodcastDbHandler::DbCategoryL( + TMPXGeneralCategory aCategory) const + { + MPX_FUNC("CMPXPodcastDbHandler::DbCategoryL"); + + CMPXDbCategory* dbCategory(NULL); + switch (aCategory) + { + case EMPXArtist: + { + dbCategory = iDbArtist; + break; + } + case EMPXAlbum: + { + dbCategory = iDbAlbum; + break; + } + case EMPXGenre: + { + dbCategory = iDbGenre; + break; + } + case EMPXComposer: + { + dbCategory = iDbComposer; + break; + } + default: + User::Leave(KErrNotSupported); + } + + return dbCategory; + } + +// ---------------------------------------------------------------------------- +// Starts a transaction on all databases +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::BeginTransactionL() + { + MPX_FUNC("CMPXPodcastDbHandler::BeginTransactionL"); + iDbManager->BeginL(); + } + +// ---------------------------------------------------------------------------- +// Ends a transaction on all databases +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::EndTransactionL( + TInt aError) + { + MPX_FUNC("CMPXPodcastDbHandler::EndTransactionL"); + + if (aError) + { + iDbManager->RollbackL(); + + // KSqlDbCorrupted indicates DB corrupted, need to recreate. + if ( aError != KSqlDbCorrupted ) + { + User::Leave(aError); + } + } + else + { + iDbManager->CommitL(); + } + } + +// ---------------------------------------------------------------------------- +// Checks if the database is currently in a transaction +// ---------------------------------------------------------------------------- +// +TBool CMPXPodcastDbHandler::InTransaction() + { + MPX_FUNC("CMPXPodcastDbHandler::InTransaction"); + return iDbManager->InTransaction(); + } + +// ---------------------------------------------------------------------------- +// Verifies that the volume ID of the database matches the drive +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::VerifyVolumeIdL( TInt aDrive ) + { + MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL <--"); + + if( iDbManager->IsOpen(aDrive) ) + { + TVolumeInfo volInfo; + iFs.Volume(volInfo, aDrive ); + TUint curId(volInfo.iUniqueID); + + TInt volId = iDbAuxiliary->IdL( aDrive ); + + // New database, no volume id set, mask out top bit because this is an uint + // + MPX_DEBUG3("CMPXPodcastDbHandler::VerifyVolumeIdL drive:%i db:%i", curId, volId); + if( volId == 0 && (curId&0x7FFFFFFF) ) + { + MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL -- New ID"); + BeginTransactionL(); + TRAPD( err, iDbAuxiliary->SetIdL( aDrive, curId&0x7FFFFFFF ) ); + EndTransactionL( err ); + + // KSqlDbCorrupted indicates DB corrupted, need to recreate. + if ( err == KSqlDbCorrupted ) + { + MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL -- Corrupted DB"); + iDbManager->RecreateDatabaseL( aDrive ); + BeginTransactionL(); + TRAPD( err, iDbAuxiliary->SetDBCorruptedL( ETrue ) ); + EndTransactionL( err ); + } + } + // Unmatched volume id, mark db as corrupt + // + else if ( (curId&0x7FFFFFFF) != (volId&0x7FFFFFFFF) ) + { + MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL -- ID match FAILED"); + iDbManager->RecreateDatabaseL( aDrive ); + BeginTransactionL(); + TRAPD( err, iDbAuxiliary->SetDBCorruptedL( ETrue ) ); + EndTransactionL( err ); + } + } + MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL -->"); + } + + +// ---------------------------------------------------------------------------- +// Verifies that the volume ID of the database matches the drive +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::VerifyVolumeIdL() + { + MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL <--"); + TInt count( iDbDrives.Count() ); + for( TInt i=0; i"); + } + +// ---------------------------------------------------------------------------- +// Checks if there is a drive that has a low disk space +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::CheckDiskSpaceOnDrivesL() + { + MPX_DEBUG1("CMPXPodcastDbHandler::CheckDiskSpaceOnDrivesL <--"); + + TInt count( iDbDrives.Count() ); + for( TInt index=0; indexCheckDiskSpaceL(iDbDrives[index]); + } + MPX_DEBUG1("CMPXPodcastDbHandler::CheckDiskSpaceOnDrivesL -->"); + } +#if defined (__MTP_PROTOCOL_SUPPORT) + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::SaveDeletedSongs +// ---------------------------------------------------------------------------- +// +TBool CMPXPodcastDbHandler::SaveDeletedSongs() + { + MPX_FUNC("CMPXPodcastDbHandler::SaveDeletedSongs"); + + TBool saveDeletedSongs(ETrue); + CRepository* cenrep(NULL); + MPX_TRAPD(error, cenrep = CRepository::NewL(KMPXMtpSettings)); + if (!error) + { + cenrep->Get(KMPXMtpSaveDeletedRecordFlag, saveDeletedSongs); + delete cenrep; + MPX_DEBUG2("MTP indicated to save deleted songs? %d", saveDeletedSongs); + } + + return saveDeletedSongs; + } + +#endif + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::AddCategoryItemL +// ---------------------------------------------------------------------------- +// +TUint32 CMPXPodcastDbHandler::AddCategoryItemL( + TMPXGeneralCategory aCategory, + const TDesC& aName, + TInt aDriveId, + CMPXMessageArray* aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbHandler::AddCategoryItemL"); + + TBool newRecord(EFalse); + TUint32 id(DbCategoryL(aCategory)->AddItemL(aName, aDriveId, newRecord, + (aCategory != EMPXGenre))); + if (newRecord && aItemChangedMessages) + { + MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id, + EMPXItemInserted, aCategory, KDBPluginUid); + } + + return id; + } + +// ---------------------------------------------------------------------------- +// CMPXPodcastDbHandler::DeleteEpisodeForCategoryL +// ---------------------------------------------------------------------------- +// +void CMPXPodcastDbHandler::DeleteEpisodeForCategoryL( + TMPXGeneralCategory aCategory, + TUint32 aCategoryId, + TInt aDriveId, + CMPXMessageArray* aItemChangedMessages) + { + MPX_FUNC("CMPXPodcastDbHandler::DeleteEpisodeForCategoryL"); + DbCategoryL(aCategory)->DecrementEpisodesForCategoryL(aCategoryId, aDriveId, + aItemChangedMessages); + } + +#ifdef RD_MULTIPLE_DRIVE + +// ---------------------------------------------------------------------------------------------------------- +// Retrieve all visible podcast folder locations +// ---------------------------------------------------------------------------------------------------------- +// +CDesCArrayFlat* CMPXPodcastDbHandler::GetPodcastFoldersL() + { + MPX_FUNC("CMPXPodcastDbHandler::GetPodcastFoldersL()"); + TDriveList driveList; + TInt driveCount(0); + User::LeaveIfError(DriveInfo::GetUserVisibleDrives(iFs, driveList, driveCount)); + MPX_DEBUG2 ("CMPXDbHandler::GetPodcastFoldersL() - driveCount = %d", driveCount); + + CDesCArrayFlat* folders = new (ELeave) CDesCArrayFlat(1); // granularity + CleanupStack::PushL(folders); + + for (TInt i = EDriveA; i <= EDriveZ; i++) + { + if ((driveList[i]) && (!IsRemoteDrive(static_cast(i)))) + { + if (i == EDriveC) + { + // Append the default phone memory path to the list + // of music folders + TPtrC rootPath(PathInfo::PhoneMemoryRootPath()); + folders->AppendL(rootPath); + MPX_DEBUG2("CMPXDbHandler::GetPodcastFoldersL() - adding...%S", &rootPath); + } + else + { + // Get drive letter + TChar driveChar; + User::LeaveIfError(iFs.DriveToChar(i, driveChar)); + + // Append visible drive to list of music folders + TBuf<2> drive; + drive.Append(driveChar); + drive.Append(_L(":")); + folders->AppendL(drive); + MPX_DEBUG2 ("CMPXDbHandler::GetPodcastFoldersL() - adding...%S", &drive); + } + } + } + + CleanupStack::Pop(folders); + return folders; + } + +#endif // RD_MULTIPLE_DRIVE + +// --------------------------------------------------------------------------- +// CMPXPodcastDbHandler::IsRemoteDrive +// --------------------------------------------------------------------------- +// +TBool CMPXPodcastDbHandler::IsRemoteDrive(TDriveNumber aDrive) + { + return iDbManager->IsRemoteDrive(aDrive); + } + +// End of File + +