diff -r 14979e23cb5e -r 3de6c4cf6b67 mpxplugins/serviceplugins/collectionplugins/mpxsqlitedbplugin/src/mpxdbplaylist.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpxplugins/serviceplugins/collectionplugins/mpxsqlitedbplugin/src/mpxdbplaylist.cpp Wed Sep 01 12:32:02 2010 +0100 @@ -0,0 +1,1098 @@ +/* +* Copyright (c) 2007 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: Responsible for interaction with the playlist tables. +* +*/ + + +// INCLUDE FILES +#include +#include +#include + +#include "mpxdbcommonutil.h" +#include "mpxdbcommondef.h" +#include "mpxdbcommonstd.h" + +#include "mpxcollectiondbdef.h" +#include "mpxdbmanager.h" +#include "mpxdbutil.h" +#include "mpxdbpluginqueries.h" +#include "mpxdbplaylistsongs.h" +#include "mpxdbplaylist.h" + +// CONSTANTS +// UniqueID column in Uris requests +const TInt KColUniqueID = 0; +// URI column in Uris requests +const TInt KColUri = 1; + +// ============================ MEMBER FUNCTIONS ============================== + +// ---------------------------------------------------------------------------- +// Two-phased constructor. +// ---------------------------------------------------------------------------- +// +CMPXDbPlaylist* CMPXDbPlaylist::NewL( + CMPXDbManager& aDbManager, + MMPXDbPlaylistObserver& aObserver) + { + MPX_FUNC("CMPXDbPlaylist::NewL"); + + CMPXDbPlaylist* self = CMPXDbPlaylist::NewLC(aDbManager, aObserver); + CleanupStack::Pop(self); + return self; + } + +// ---------------------------------------------------------------------------- +// Two-phased constructor. +// ---------------------------------------------------------------------------- +// +CMPXDbPlaylist* CMPXDbPlaylist::NewLC( + CMPXDbManager& aDbManager, + MMPXDbPlaylistObserver& aObserver) + { + MPX_FUNC("CMPXDbPlaylist::NewLC"); + + CMPXDbPlaylist* self = new (ELeave) CMPXDbPlaylist(aDbManager, aObserver); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +// ---------------------------------------------------------------------------- +// Destructor +// ---------------------------------------------------------------------------- +// +CMPXDbPlaylist::~CMPXDbPlaylist() + { + MPX_FUNC("CMPXDbPlaylist::~CMPXDbPlaylist"); + delete iPlaylistSongs; + } + +// ---------------------------------------------------------------------------- +// Constructor +// ---------------------------------------------------------------------------- +// +CMPXDbPlaylist::CMPXDbPlaylist( + CMPXDbManager& aDbManager, + MMPXDbPlaylistObserver& aObserver) : + CMPXDbTable(aDbManager), + iObserver(aObserver) + { + MPX_FUNC("CMPXDbPlaylist::CMPXDbPlaylist"); + } + +// ---------------------------------------------------------------------------- +// Second phase constructor. +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::ConstructL() + { + MPX_FUNC("CMPXDbPlaylist::ConstructL"); + + BaseConstructL(); + iPlaylistSongs = CMPXDbPlaylistSongs::NewL(iDbManager); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::AddPlaylistL +// ---------------------------------------------------------------------------- +// +TUint32 CMPXDbPlaylist::AddPlaylistL( + const CMPXMedia& aMedia) + { + MPX_FUNC("CMPXDbPlaylist::AddPlaylistL"); + + // make sure the playlist and the corresponding songs are deleted + TUint32 playlistId(MPXDbCommonUtil::GenerateUniqueIdL(iDbManager.Fs(), EMPXPlaylist, + aMedia.ValueText(KMPXMediaGeneralUri), EFalse)); + DeletePlaylistNoUriL(playlistId); + + // add the playlist + return DoAddPlaylistL(aMedia, TDriveUnit(aMedia.ValueText(KMPXMediaGeneralUri))); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::AddSongsL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::AddSongsL( + TUint32 aPlaylistId, + const CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXDbPlaylist::AddSongsL"); + + // get the drive ID of corresponding playlist + TInt drive(GetDriveIdL(aPlaylistId)); + + // add the songs + iPlaylistSongs->AddSongsL(aPlaylistId, aMediaArray, drive); + + // update the time for the playlist + UpdatePlaylistTimeL(aPlaylistId, drive); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::UpdatePlaylistL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::UpdatePlaylistL( + const CMPXMedia& aMedia, + CMPXMessage& aMessage, + TInt aDriveId) + { + MPX_FUNC("CMPXDbPlaylist::UpdatePlaylistL"); + + TUint32 playlistId((aMedia.ValueTObjectL(KMPXMediaGeneralId)).iId2); + DoUpdatePlaylistL(playlistId, aMedia, aDriveId, aMessage); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::UpdateSongL +// ---------------------------------------------------------------------------- +// +TBool CMPXDbPlaylist::UpdateSongL( + const CMPXMedia& aMedia, + TBool aResetFlags, + CMPXMessageArray* aItemChangedMessages /* = NULL */) + { + MPX_FUNC("CMPXDbPlaylist::UpdateSongL"); + + // find the song ID + TInt oldSongId(0); + TInt newSongId(0); + if (aMedia.IsSupported(KMPXMediaGeneralId)) + { + oldSongId = (aMedia.ValueTObjectL(KMPXMediaGeneralId)).iId2; + } + if (aMedia.IsSupported(KMPXMediaGeneralUri)) + { + newSongId = MPXDbCommonUtil::GenerateUniqueIdL(iDbManager.Fs(), EMPXCollection, + aMedia.ValueText(KMPXMediaGeneralUri), EFalse); + } + if ( !aMedia.IsSupported( KMPXMediaGeneralId ) && !aMedia.IsSupported( KMPXMediaGeneralUri )) + { + User::Leave( KErrArgument ); + } + + if ( newSongId <= 0 ) + { + newSongId = oldSongId; + } + + if ( oldSongId <= 0 ) + { + oldSongId = newSongId; + } + + // update the PlaylistSongs and PlaylistSongInfo tables first + TBool updated(EFalse); + TBool visible(iPlaylistSongs->UpdateSongL( oldSongId, aMedia, aResetFlags, updated )); + TBool bSongInPlaylists( EFalse ); + if (updated) + { + UpdatePlaylistsForSongL( newSongId, aItemChangedMessages,bSongInPlaylists ); + } + + return visible; + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::DeleteSongL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::DeleteSongL( + TUint32 aSongId, + CMPXMessageArray& aItemChangedMessages) + { + MPX_FUNC("CMPXDbPlaylist::DeleteSongL"); + TBool bSongInPlaylists(EFalse); + // add item changed messages for all playlists that contain the song + UpdatePlaylistsForSongL (aSongId, &aItemChangedMessages, bSongInPlaylists); + if (bSongInPlaylists) + { + // delete the song from the PlaylistSongs and PlaylistSongInfo tables + iPlaylistSongs->DeleteSongL (aSongId); + } + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::DeleteSongL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::DeleteSongL( + TUint32 aPlaylistId, + TUint32 aSongId, + TInt aOrdinal) + { + MPX_FUNC("CMPXDbPlaylist::DeleteSongL"); + + // get playlist drive + TInt drive(GetDriveIdL(aPlaylistId)); + + // delete the song from the PlaylistSongs / PlaylistSongInfo tables + iPlaylistSongs->DeleteSongL(aPlaylistId, aSongId, aOrdinal, drive); + + // update the time for the playlist + UpdatePlaylistTimeL(aPlaylistId, drive); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::DeletePlaylistL +// ---------------------------------------------------------------------------- +// +HBufC* CMPXDbPlaylist::DeletePlaylistL( + TUint32 aPlaylistId) + { + MPX_FUNC("CMPXDbPlaylist::DeletePlaylistL"); + + // get the uri + HBufC* uri = GetUriL(aPlaylistId); + if (uri) + { + CleanupStack::PushL(uri); + TDriveUnit drive(*uri); + + // delete the songs from the PlaylistSongs table + iPlaylistSongs->DeleteSongsL(aPlaylistId, drive); + + // delete the playlist record from the Playlist table + iDbManager.ExecuteQueryL(drive, KQueryPlaylistDelete, aPlaylistId); + + CleanupStack::Pop(uri); + } + + return uri; + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::DeletePlaylistNoUriL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::DeletePlaylistNoUriL( + TUint32 aPlaylistId) + { + MPX_FUNC("CMPXDbPlaylist::DeletePlaylistNoUriL"); + + TInt drive(0); + MPX_TRAPD(err, drive = GetDriveIdL(aPlaylistId)); + if (err != KErrNotFound) + { + User::LeaveIfError(err); + + // delete the songs from the PlaylistSongs table + iPlaylistSongs->DeleteSongsL(aPlaylistId, drive); + + // delete the playlist record from the Playlist table + iDbManager.ExecuteQueryL(drive, KQueryPlaylistDelete, aPlaylistId); + } + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::DeleteAllPlaylistsL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::DeleteAllPlaylistsL() + { + MPX_FUNC("CMPXDbPlaylist::DeleteAllPlaylistsL"); + + // delete the songs from the PlaylistSongs table + iPlaylistSongs->DeleteAllSongsL(); + + // delete all playlists + iDbManager.ExecuteQueryL(KDbManagerAllDrives, KQueryPlaylistDeleteAll); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::CountL +// ---------------------------------------------------------------------------- +// +TInt CMPXDbPlaylist::CountL() + { + MPX_FUNC("CMPXDbPlaylist::CountL"); + return ExecuteSumQueryL(KQueryPlaylistCount); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::GetPlaylistL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::GetPlaylistL( + TUint32 aPlaylistId, + const TArray& aAttrs, + CMPXMedia& aMedia) + { + MPX_FUNC("CMPXDbPlaylist::GetPlaylistL"); + ExecuteMediaQueryL(aAttrs, aMedia, KQueryPlaylistGet, aPlaylistId); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::GetAllPlaylistsL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::GetAllPlaylistsL( + const TArray& aAttrs, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXDbPlaylist::GetAllPlaylistsL"); + ExecuteMediaQueryL(aAttrs, aMediaArray, KQueryPlaylistGetAll); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::GetNameL +// ---------------------------------------------------------------------------- +// +HBufC* CMPXDbPlaylist::GetNameL( + TUint32 aPlaylistId) + { + MPX_FUNC("CMPXDbPlaylist::GetNameL"); + + RSqlStatement recordset(GetPlaylistRecordL(aPlaylistId)); + CleanupClosePushL(recordset); + + HBufC* name(NULL); + TInt err(KErrNone); + if ((err = recordset.Next()) == KSqlAtRow) + { + name = MPXDbCommonUtil::GetColumnTextL(recordset, EPlaylistName).AllocL(); + } + CleanupStack::PopAndDestroy(&recordset); + + if (err != KSqlAtEnd) + { + User::LeaveIfError(err); + } + + if (name == NULL) + { + User::LeaveIfError(KErrNotFound); + } + return name; + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::GetUriL +// ---------------------------------------------------------------------------- +// +HBufC* CMPXDbPlaylist::GetUriL( + TUint32 aPlaylistId) + { + MPX_FUNC("CMPXDbPlaylist::GetUriL"); + + RSqlStatement recordset(GetPlaylistRecordL(aPlaylistId)); + CleanupClosePushL(recordset); + + HBufC* uri(NULL); + TInt err(KErrNone); + if ((err = recordset.Next()) == KSqlAtRow) + { + uri = MPXDbCommonUtil::CreateFullPathL( + MPXDbCommonUtil::GetDriveIdMatchVolIdL(iDbManager.Fs(), + recordset.ColumnInt64(EPlaylistVolumeId)), + MPXDbCommonUtil::GetColumnTextL(recordset, EPlaylistUri)); + + } + CleanupStack::PopAndDestroy(&recordset); + + if (err != KSqlAtEnd) + { + User::LeaveIfError(err); + } + + if (uri == NULL) + { + User::LeaveIfError(KErrNotFound); + } + + return uri; + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::GetIdL +// ---------------------------------------------------------------------------- +// +TUint32 CMPXDbPlaylist::GetIdL( + const TDesC& aUri) + { + MPX_FUNC("CMPXDbPlaylist::GetIdL"); + HBufC* uri = MPXDbCommonUtil::ProcessPatternCharsLC( aUri ); + TUint32 ret = ExecuteIntQueryL( + KQueryLikePlaylistId, uri->Mid( KMCPathStartPos ) ); + + CleanupStack::PopAndDestroy( uri ); + + return ret; + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::FindAllL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::FindAllL( + const CMPXMedia& aCriteria, + const TArray& aAttrs, + CMPXMediaArray& aMediaArray) + { + MPX_FUNC("CMPXDbPlaylist::FindAllL"); + + // process the requested attributes + // the UniqueId is always requested + TBool titleRequested(EFalse); + TBool counterRequested(EFalse); + + TInt viewingColumnCount(aAttrs.Count()); + for (TInt i = 0; (i < viewingColumnCount) && !(titleRequested && counterRequested); ++i) + { + if (aAttrs[i].ContentId() == KMPXMediaIdGeneral) + { + TUint attributeId(aAttrs[i].AttributeId()); + + if (attributeId & EMPXMediaGeneralTitle) + { + titleRequested = ETrue; + } + if (attributeId & EMPXMediaGeneralCount) + { + counterRequested = ETrue; + } + } + } + + TMPXGeneralType type = aCriteria.ValueTObjectL(KMPXMediaGeneralType); + + const TArray criteria = aCriteria.Attributes(); + TInt criteriaCount(criteria.Count()); + + // process the criteria and construct the criteria string + CDesCArrayFlat* criteriaArray = new (ELeave) CDesCArrayFlat(criteriaCount); + CleanupStack::PushL(criteriaArray); + + TBool criteriaCounterSet(EFalse); + TInt criteriaCounter(0); + + for (TInt i = 0; i < criteriaCount; ++i) + { + const TMPXAttribute& criterion = criteria[i]; + if (type == EMPXItem && criterion == KMPXMediaGeneralId) + { + TUint32 itemId((aCriteria.ValueTObjectL(KMPXMediaGeneralId)).iId2); + if (MPX_ITEM_CATEGORY(itemId) != EMPXPlaylist) + { + User::Leave(KErrNotSupported); + } + + MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, KCriterionPlaylistUniqueId, itemId); + } + else if (criterion == KMPXMediaGeneralTitle) + { + HBufC* title = MPXDbCommonUtil::ProcessPatternCharsLC( + aCriteria.ValueText(KMPXMediaGeneralTitle)); + if( type == EMPXOtherType ) + { + MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, KCriterionPlaylistTitle, *title); + } + else + { + MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, KCriterionPlaylistLikeTitle, *title); + } + CleanupStack::PopAndDestroy(title); + } + else if (criterion == KMPXMediaGeneralUri) + { + MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, KCriterionPlaylistUniqueId, + MPXDbCommonUtil::GenerateUniqueIdL(iDbManager.Fs(), EMPXPlaylist, + aCriteria.ValueText(KMPXMediaGeneralUri), EFalse)); + } + else if (criterion == KMPXMediaGeneralDrive) + { + const TDesC& drive(aCriteria.ValueText(KMPXMediaGeneralDrive)); + TDriveUnit driveUnit(drive); + MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, KCriterionPlaylistVolumeId, + MPXDbCommonUtil::GetVolIdMatchDriveIdL(iDbManager.Fs(), driveUnit)); + } + else if (criterion == KMPXMediaGeneralSynchronized) + { + MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, KCriterionPlaylistSync, + aCriteria.ValueTObjectL(KMPXMediaGeneralSynchronized)); + } + else if (criterion == KMPXMediaGeneralCount) + { + criteriaCounterSet = ETrue; + criteriaCounter = aCriteria.ValueTObjectL(KMPXMediaGeneralCount); + } + } + + // construct criteria string + HBufC* criteriaStr = MPXDbCommonUtil::StringFromArrayLC(*criteriaArray, KMCAndKeyword); + + HBufC* query(NULL); + if (criteriaStr->Length() > 0) + { + // construct and execute the query + query = HBufC::NewLC(KQueryPlaylistItems().Length() + criteriaStr->Length()); + query->Des().Format(KQueryPlaylistItems, criteriaStr); + } + else + { + query = HBufC::NewLC(KQueryPlaylistGetAll().Length()); + query->Des().Format(KQueryPlaylistGetAll); + } + + RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(*query)); + + CleanupStack::PopAndDestroy(query); + CleanupStack::PopAndDestroy(criteriaStr); + CleanupStack::PopAndDestroy(criteriaArray); + + CleanupClosePushL(recordset); + + TInt err(KErrNone); + while ((err = recordset.Next()) == KSqlAtRow) + { + // Setup basic info - with first record of a group + TUint32 playlistId(recordset.ColumnInt64(EPlaylistUniqueId)); + TUint32 volId(recordset.ColumnInt64(EPlaylistVolumeId)); + TInt driveId = MPXDbCommonUtil::GetDriveIdMatchVolIdL(iDbManager.Fs(), volId); + + TBool valid(ETrue); + TInt songCount(-1); + if (criteriaCounterSet) + { + if (driveId >= 0) + { + //valid disk + songCount = iPlaylistSongs->CountL(playlistId, driveId); + } + valid = (criteriaCounter == songCount); + } + + if (valid) + { + // start a new media object + CMPXMedia* media = CMPXMedia::NewL(); + CleanupStack::PushL(media); + + UpdateMediaL(recordset, aAttrs, *media); + + aMediaArray.AppendL(*media); + CleanupStack::PopAndDestroy(media); + } + } + + CleanupStack::PopAndDestroy(&recordset); + + if (err != KSqlAtEnd) + { + User::LeaveIfError(err); + } + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::GetDriveIdL +// ---------------------------------------------------------------------------- +// +TInt CMPXDbPlaylist::GetDriveIdL( + TUint32 aPlaylistId) + { + MPX_FUNC("CMPXDbPlaylist::GetDriveIdL"); + return MPXDbCommonUtil::GetDriveIdMatchVolIdL(iDbManager.Fs(), + ExecuteIntQueryL(KQueryPlaylistDriveId, aPlaylistId)); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::Songs +// ---------------------------------------------------------------------------- +// +CMPXDbPlaylistSongs& CMPXDbPlaylist::Songs() + { + return *iPlaylistSongs; + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::GetDrivePlaylistCount +// ---------------------------------------------------------------------------- +// +TUint CMPXDbPlaylist::GetDrivePlaylistCountL(TInt aDrive) + { + TUint count(0); + + RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(aDrive,KQueryPlaylistFileCount)); + CleanupClosePushL(recordset); + + if (recordset.Next() != KSqlAtRow) + { + User::Leave(KErrCorrupt); + } + + count = TUint(recordset.ColumnInt64(KMPXTableDefaultIndex)); + CleanupStack::PopAndDestroy(&recordset); + + return count; + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::GetPlaylistUriArrayL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::GetPlaylistUriArrayL(TInt aDrive, TInt aFromID, TInt aRecords, + CDesCArray& aUriArr, TInt& aLastID) + { + MPX_FUNC("CMPXDbPlaylist::GetPlaylistUriArrayL"); + + HBufC* query = NULL; + if(aFromID == 0) + { + query = HBufC::NewLC(KQueryPlaylistGetFileUris().Length() + + KMCIntegerLen); + query->Des().Format(KQueryPlaylistGetFileUris, aRecords); + } + else + { + query = HBufC::NewLC(KQueryPlaylistGetFileUrisFrom().Length() + + 2*KMCIntegerLen); + query->Des().Format(KQueryPlaylistGetFileUrisFrom, aFromID, aRecords); + } + + RSqlStatement playlist_rs(iDbManager.ExecuteSelectQueryL(aDrive,*query)); + + CleanupStack::PopAndDestroy(query); + + CleanupClosePushL(playlist_rs); + + TInt lastID = 0; + TInt err(KErrNone); + while((err = playlist_rs.Next()) == KSqlAtRow) + { + HBufC* fullPath = MPXDbCommonUtil::CreateFullPathL(aDrive, + MPXDbCommonUtil::GetColumnTextL(playlist_rs, KColUri)); + CleanupStack::PushL(fullPath); + aUriArr.AppendL(*fullPath); + CleanupStack::PopAndDestroy(fullPath); + + lastID = playlist_rs.ColumnInt(KColUniqueID); + } + CleanupStack::PopAndDestroy(&playlist_rs); + + aLastID = lastID; + + if (err!= KSqlAtEnd) + { + User::Leave(KErrCorrupt); + } + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::UpdateMediaL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::UpdateMediaL( + RSqlStatement& aRecord, + const TArray& aAttrs, + CMPXMedia& aMedia) + { + MPX_FUNC("CMPXDbPlaylist::UpdateMediaL"); + + TBool countRequested(EFalse); + TBool durationRequested(EFalse); + TUint32 playlistId(aRecord.ColumnInt64(EPlaylistUniqueId)); + + TInt count(aAttrs.Count()); + TUint32 volId(aRecord.ColumnInt64(EPlaylistVolumeId)); + TInt driveId = MPXDbCommonUtil::GetDriveIdMatchVolIdL(iDbManager.Fs(), volId); + for (TInt i = 0; i < count; ++i) + { + TInt contentId(aAttrs[i].ContentId()); + TUint attributeId(aAttrs[i].AttributeId()); + + if (contentId == KMPXMediaIdGeneral) + { + if (attributeId & EMPXMediaGeneralId) + { + aMedia.SetTObjectValueL(KMPXMediaGeneralId, playlistId); + MPX_DEBUG2(" Playlist ID[%u]", playlistId); + } + if (attributeId & EMPXMediaGeneralCollectionId) + { + aMedia.SetTObjectValueL(KMPXMediaGeneralCollectionId, + TUid::Uid(KDBPluginUid)); + } + if (attributeId & EMPXMediaGeneralTitle) + { + TPtrC title(MPXDbCommonUtil::GetColumnTextL(aRecord, EPlaylistName)); + aMedia.SetTextValueL(KMPXMediaGeneralTitle, title); + MPX_DEBUG2(" Title[%S]", &title); + } + if ((attributeId & EMPXMediaGeneralUri) || + (attributeId & EMPXMediaGeneralDrive) || + (attributeId & EMPXMediaGeneralFlags)) + { + + // LTAN-7GH6BZ, crash if eject memory card when adding song to existing playlist + // due to special timing issue, it is possible drive number is -1 and create a + // panic when use for TDriveUnit + MPX_DEBUG3("volId = %d, driveId = %d", volId, driveId); + + // handle possibly delay from framework notification + if (driveId < 0) + { + MPX_DEBUG1("invalid driveId, leave with KErrNotReady"); + User::Leave(KErrNotReady); + } + + TDriveUnit driveUnit(driveId); + + if (attributeId & EMPXMediaGeneralUri) + { + HBufC* fullPath = MPXDbCommonUtil::CreateFullPathL(driveUnit, + MPXDbCommonUtil::GetColumnTextL(aRecord, EPlaylistUri)); + CleanupStack::PushL(fullPath); + aMedia.SetTextValueL(KMPXMediaGeneralUri, *fullPath); + MPX_DEBUG2(" URI[%S]", fullPath); + CleanupStack::PopAndDestroy(fullPath); + } + if (attributeId & EMPXMediaGeneralDrive) + { + aMedia.SetTextValueL(KMPXMediaGeneralDrive, driveUnit.Name()); + } + if (attributeId & EMPXMediaGeneralFlags) + { + TUint32 dbFlags(aRecord.ColumnInt64(EPlaylistDbFlag)); + TInt driveId = driveUnit & KMPXMediaGeneralFlagsDriveInfo; // 5 bits + aMedia.SetTObjectValueL(KMPXMediaGeneralFlags, dbFlags | driveId); + } + } + if (attributeId & EMPXMediaGeneralSynchronized) + { + aMedia.SetTObjectValueL(KMPXMediaGeneralSynchronized, + aRecord.ColumnInt(EPlaylistSync)); + } + if (attributeId & EMPXMediaGeneralCount) + { + // make sure the PlaylistSongs query is executed after all fields + // from the current record have been processed, otherwise the recordset + // may point to something else + countRequested = ETrue; + } + if (attributeId & EMPXMediaGeneralDate) + { + // convert the time from the internal DB string format + // to the int64 format used by TTime + aMedia.SetTObjectValueL(KMPXMediaGeneralDate, + MPXDbCommonUtil::DesToTTimeL( + MPXDbCommonUtil::GetColumnTextL(aRecord, EPlaylistTime)).Int64()); + } + if ( attributeId & EMPXMediaGeneralDuration ) + { + // make sure the PlaylistSongs query is executed after all fields + // from the current record have been processed, otherwise the recordset + // may point to something else + + durationRequested = ETrue; + } + } // end if contentId == KMPXMediaIdGeneral + } // end for + + TInt plSongCount(0); + TInt plSongDuration(0); + if (countRequested) + { + if (driveId >= 0) + { + //valid disk + iObserver.HandlePlaylistInfoL(playlistId, plSongCount, plSongDuration); + } + aMedia.SetTObjectValueL(KMPXMediaGeneralCount, + plSongCount ); + + MPX_DEBUG1(" EMPXMediaGeneralCount"); + MPX_DEBUG2(" Count[%d]", plSongCount); + } + if (durationRequested) + { + aMedia.SetTObjectValueL(KMPXMediaGeneralDuration, plSongDuration); + + MPX_DEBUG1(" EMPXMediaGeneralDuration"); + MPX_DEBUG2(" Duration[%d]", plSongDuration); + } + + aMedia.SetTObjectValueL(KMPXMediaGeneralType, EMPXItem); + aMedia.SetTObjectValueL(KMPXMediaGeneralCategory, EMPXPlaylist); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::GetPlaylistRecordL +// ---------------------------------------------------------------------------- +// +RSqlStatement CMPXDbPlaylist::GetPlaylistRecordL( + TUint32 aPlaylistId) + { + MPX_FUNC("CMPXDbPlaylist::GetPlaylistRecordL"); + return iDbManager.ExecuteSelectQueryL(KQueryPlaylistGet, aPlaylistId); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::DoAddPlaylistL +// ---------------------------------------------------------------------------- +// +TUint32 CMPXDbPlaylist::DoAddPlaylistL( + const CMPXMedia& aMedia, + TInt aDriveId) + { + MPX_FUNC("CMPXDbPlaylist::DoAddPlaylistL"); + + const TDesC& playlistName(aMedia.ValueText(KMPXMediaGeneralTitle)); + const TDesC& playlistUri(aMedia.ValueText(KMPXMediaGeneralUri)); + + TUint32 playlistId(MPXDbCommonUtil::GenerateUniqueIdL(iDbManager.Fs(), EMPXPlaylist, playlistUri, EFalse)); + const CMPXMediaArray* mediaArray = aMedia.Value(KMPXMediaArrayContents); + if( !mediaArray ) + { + User::Leave( KErrNoMemory ); + } + // add the songs to the PlaylistSongs table + TInt count(mediaArray->Count()); + for (TInt i = 0; i < count; ++i) + { + iPlaylistSongs->AddSongL(playlistId, i, *mediaArray->AtL(i), aDriveId); + } + + // determine the value of DbFlag + TUint dbflags(0); + if (aMedia.IsSupported(KMPXMediaGeneralFlags)) + { + TUint flag(aMedia.ValueTObjectL(KMPXMediaGeneralFlags)); + if (flag & KMPXMediaGeneralFlagsSetOrUnsetBit ) + { + // Set flag + dbflags |= flag; + MPX_DEBUG2(" GeneralFlags[%b]", dbflags); + } + } + + // add playlist record + HBufC* time = MPXDbCommonUtil::CurrentTimeDesLC(); + HBufC* name = MPXDbCommonUtil::ProcessSingleQuotesLC(playlistName); + HBufC* uri = MPXDbCommonUtil::ProcessSingleQuotesLC(playlistUri); + TPtrC uriPtr(uri->Mid(KMCPathStartPos)); + TPtrC namePtr(name->Left(KMCMaxTextLen)); + + iDbManager.ExecuteQueryL(aDriveId, KQueryPlaylistInsert, playlistId, &namePtr, + &uriPtr, MPXDbCommonUtil::GetVolIdMatchDriveIdL(iDbManager.Fs(), aDriveId), + dbflags, time); + + CleanupStack::PopAndDestroy(uri); + CleanupStack::PopAndDestroy(name); + CleanupStack::PopAndDestroy(time); + + return playlistId; + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::DoUpdatePlaylistL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::DoUpdatePlaylistL( + TUint32 aPlaylistId, + const CMPXMedia& aMedia, + TInt aDriveId, + CMPXMessage& aMessage) + { + MPX_FUNC("CMPXDbPlaylist::DoUpdatePlaylistL"); + + // construct the criteria array + const TArray attributes = aMedia.Attributes(); + + CDesCArrayFlat* criteriaArray = new (ELeave) CDesCArrayFlat(attributes.Count()); + CleanupStack::PushL(criteriaArray); + + TInt attrCount(attributes.Count()); + for (TInt index = 0; index < attrCount; ++index) + { + TInt contentId(attributes[index].ContentId()); + TUint attributeId(attributes[index].AttributeId()); + + switch(contentId) + { + case KMPXMediaIdGeneral: + { + if (attributeId & EMPXMediaGeneralTitle) + { + MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, KCriterionPlaylistTitle, + aMedia.ValueText(KMPXMediaGeneralTitle)); + } + if (attributeId & EMPXMediaGeneralUri) + { + const TDesC& uri(aMedia.ValueText (KMPXMediaGeneralUri)); + + // determine if we are changing URI of an existing playlist. + // if so, update playlist URI + its Id + TUint32 newId(MPXDbCommonUtil::GenerateUniqueIdL(iDbManager.Fs(), EMPXPlaylist, uri, EFalse)); + + if (aPlaylistId != newId) + { + aMessage.SetTObjectValueL(KMPXMessageMediaGeneralId, newId); + aMessage.SetTObjectValueL(KMPXMessageMediaDeprecatedId, aPlaylistId); + + // Change event handling for renaming a playlist should be like a song + // The item focus should goto the new name of the playlist + // to-do: this should be abstracted from the plugin. framework should + // have enough info to deal with this scenario, if not, add more + // info in the message passing back to framework + aMessage.SetTObjectValueL(KMPXMessageMediaGeneralCategory, + EMPXSong); + + // update the PlaylistSongs to reflect playlist id change + iPlaylistSongs->UpdateSongsL(aPlaylistId, newId); + + // this takes care of processing the single quotes in the URI + MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, KCriterionPlaylistUri, + uri.Mid(KMCPathStartPos)); + MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, KCriterionPlaylistVolumeId, + MPXDbCommonUtil::GetVolIdMatchDriveIdL(iDbManager.Fs(), TDriveUnit(uri))); + MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, KCriterionPlaylistUniqueId, + newId); + } + } + if (attributeId & EMPXMediaGeneralSynchronized) + { + MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, KCriterionPlaylistSync, + aMedia.ValueTObjectL(KMPXMediaGeneralSynchronized)); + } + } + break; + + default: + break; + + } // end switch + } // end for + + // update the time field to the current time + HBufC* time = MPXDbCommonUtil::CurrentTimeDesLC(); + MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, KCriterionPlaylistTime, *time); + CleanupStack::PopAndDestroy(time); + + // construct a string from all criteria + HBufC* criteria = MPXDbCommonUtil::StringFromArrayLC(*criteriaArray, KMCCommaSign); + + // execute the query + iDbManager.ExecuteQueryL(aDriveId, KQueryPlaylistUpdate, criteria, aPlaylistId); + + CleanupStack::PopAndDestroy(criteria); + CleanupStack::PopAndDestroy(criteriaArray); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::UpdatePlaylistsForSongL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::UpdatePlaylistsForSongL( + TUint32 aSongId, + CMPXMessageArray* aItemChangedMessages, TBool& aSongInPlaylists) + { + MPX_FUNC("CMPXDbPlaylist::UpdatePlaylistsForSongL"); + + aSongInPlaylists = EFalse; + if (aItemChangedMessages) + { + // get all playlists for the song + RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(KQueryPlaylistGetForSong, aSongId)); + CleanupClosePushL(recordset); + + // ignore the errors + while (recordset.Next() == KSqlAtRow) + { + aSongInPlaylists = ETrue; + // add item changed messages for all of them + MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, + recordset.ColumnInt64(KMPXTableDefaultIndex), EMPXItemModified, + EMPXPlaylist, KDBPluginUid); + } + + CleanupStack::PopAndDestroy(&recordset); + } + if (aSongInPlaylists) + { + // update the time for all playlists that contain this song + HBufC* time = MPXDbCommonUtil::CurrentTimeDesLC(); + iDbManager.ExecuteQueryL (KDbManagerAllDrives, + KQueryPlaylistUpdateTimeForSong, time, aSongId); + CleanupStack::PopAndDestroy (time); + } + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::CreateTableL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::UpdatePlaylistTimeL( + TUint32 aPlaylistId, + TInt aDrive) + { + MPX_FUNC("CMPXDbPlaylist::UpdatePlaylistTimeL"); + + HBufC* time = MPXDbCommonUtil::CurrentTimeDesLC(); + iDbManager.ExecuteQueryL(aDrive, KQueryPlaylistUpdateTime, time, aPlaylistId); + CleanupStack::PopAndDestroy(time); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::GetDrivePlaylistDuration +// ---------------------------------------------------------------------------- +// +TInt CMPXDbPlaylist::GetDrivePlaylistDuration(TUint32 aPlaylistId) + { + return 0; + } +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::CreateTableL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::CreateTableL( + RSqlDatabase& aDatabase, + TBool /* aCorruptTable */) + { + MPX_FUNC("CMPXDbPlaylist::CreateTableL"); + + // create the table + User::LeaveIfError(aDatabase.Exec(KPlaylistCreateTable)); + + // create the index on the Name field + User::LeaveIfError(aDatabase.Exec(KPlaylistNameIndex)); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::DropTableL +// ---------------------------------------------------------------------------- +// +void CMPXDbPlaylist::DropTableL( + RSqlDatabase& aDatabase) + { + MPX_FUNC("CMPXDbPlaylist::DropTableL"); + User::LeaveIfError(aDatabase.Exec(KPlaylistDropTable)); + } + +// ---------------------------------------------------------------------------- +// CMPXDbPlaylist::CheckTableL +// ---------------------------------------------------------------------------- +// +TBool CMPXDbPlaylist::CheckTableL( + RSqlDatabase& aDatabase) + { + MPX_FUNC("CMPXDbPlaylist::CheckTableL"); + return DoCheckTable(aDatabase, KPlaylistCheckTable); + } + +// End of File