--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mpserviceplugins/mpxsqlitedbhgplugin/src/mpxdbalbum.cpp Tue Aug 31 15:12:29 2010 +0300
@@ -0,0 +1,1130 @@
+/*
+* 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 interation with the category tables:
+* Artist, Album, Genre and Composer
+*
+*/
+
+
+// INCLUDE FILES
+#include <sqldb.h>
+
+#include <mpxlog.h>
+
+#include "mpxdbcommonutil.h"
+#include "mpxdbcommondef.h"
+#include "mpxdbmanager.h"
+
+#include "mpxcollectiondbdef.h"
+#include "mpxmediamusicdefs.h"
+#include "mpxdbpluginqueries.h"
+#include "mpxdbutil.h"
+#include "mpxdbalbum.h"
+
+// CONSTANTS
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+_LIT( KAbstractAlbumExt, ".alb" );
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+
+_LIT( KAlbumAlbumArtistSeperator, "\t1");
+_LIT( KAlbumArtistSeperator, "\t2");
+
+const TInt KUnknownAlbumsGranularity = 250;
+
+// ============================ MEMBER FUNCTIONS ==============================
+
+// ----------------------------------------------------------------------------
+// Two-phased constructor.
+// ----------------------------------------------------------------------------
+//
+CMPXDbAlbum* CMPXDbAlbum::NewL(
+ CMPXDbManager& aDbManager,
+ TMPXGeneralCategory aCategory,
+ MMPXDbAlbumObserver& aObserver)
+ {
+ MPX_FUNC("CMPXDbAlbum::NewL");
+
+ CMPXDbAlbum* self = CMPXDbAlbum::NewLC(aDbManager, aCategory, aObserver);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// Two-phased constructor.
+// ----------------------------------------------------------------------------
+//
+CMPXDbAlbum* CMPXDbAlbum::NewLC(
+ CMPXDbManager& aDbManager,
+ TMPXGeneralCategory aCategory,
+ MMPXDbAlbumObserver& aObserver)
+ {
+ MPX_FUNC("CMPXDbAlbum::NewLC");
+
+ CMPXDbAlbum* self = new (ELeave) CMPXDbAlbum(aDbManager, aCategory, aObserver);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// Destructor
+// ----------------------------------------------------------------------------
+//
+CMPXDbAlbum::~CMPXDbAlbum()
+ {
+ MPX_FUNC("CMPXDbAlbum::~CMPXDbAlbum");
+
+ iUnknownArtists.ResetAndDestroy();
+ iUnknownAlbums.ResetAndDestroy();
+ }
+
+// ----------------------------------------------------------------------------
+// Constructor
+// ----------------------------------------------------------------------------
+//
+CMPXDbAlbum::CMPXDbAlbum(
+ CMPXDbManager& aDbManager,
+ TMPXGeneralCategory aCategory,
+ MMPXDbAlbumObserver& aObserver) :
+ CMPXDbCategory(aDbManager, aCategory),
+ iObserver(aObserver),
+ iUnknownArtists(KUnknownAlbumsGranularity),
+ iUnknownAlbums(KUnknownAlbumsGranularity)
+ {
+ MPX_FUNC("CMPXDbAlbum::CMPXDbAlbum");
+ }
+
+// ----------------------------------------------------------------------------
+// Second phase constructor.
+// ----------------------------------------------------------------------------
+//
+void CMPXDbAlbum::ConstructL()
+ {
+ MPX_FUNC("CMPXDbAlbum::ConstructL");
+
+ BaseConstructL();
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::AddItemL
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbAlbum::AddItemL(
+ TMPXGeneralCategory /*aCategory*/,
+ const CMPXMedia& aMedia,
+ TInt aDriveId,
+ TBool& aNewRecord,
+ TBool aCaseSensitive)
+ {
+ MPX_FUNC("CMPXDbAlbum::AddItemL");
+
+ TPtrC album(KNullDesC);
+ TPtrC albumArtist(KNullDesC);
+ TPtrC artist(KNullDesC);
+ TPtrC albumArt(KNullDesC);
+
+ // try to find the item first
+ TUint32 rowId(GenerateUniqueIdL(aMedia));
+
+ // retrieve the existing record
+ HBufC* query = PreProcessStringLC(KQueryCategoryItem);
+ RSqlStatement recordset(
+ iDbManager.ExecuteSelectQueryL(aDriveId, *query, rowId));
+ CleanupStack::PopAndDestroy(query);
+ CleanupClosePushL(recordset);
+
+ TInt result = recordset.Next();
+ if (result == KSqlAtEnd)
+ {
+ aNewRecord = result;
+
+ // check Album attribute
+ if (aMedia.IsSupported(KMPXMediaMusicAlbum))
+ {
+ album.Set(aMedia.ValueText(KMPXMediaMusicAlbum).Left(KMCMaxTextLen));
+ }
+
+ // check AlbumArt attirbute
+ if (aMedia.IsSupported(KMPXMediaMusicAlbumArtFileName))
+ {
+ albumArt.Set(aMedia.ValueText(KMPXMediaMusicAlbumArtFileName).Left(KMCMaxTextLen));
+ }
+
+ // insert new
+ HBufC* name = MPXDbCommonUtil::ProcessSingleQuotesLC(album);
+ TUint32 artistId(0);
+ HBufC* artistName = NULL;
+ if (RetrieveAlbumArtistL(aMedia, albumArtist))
+ {
+ artistId = iObserver.AddAlbumArtistL(albumArtist, albumArt, aDriveId);
+ artistName = MPXDbCommonUtil::ProcessSingleQuotesLC(albumArtist);
+ }
+ else
+ {
+ RetrieveArtist(aMedia, artist);
+ artistId = iObserver.AddAlbumArtistL(artist, albumArt, aDriveId);
+ artistName = MPXDbCommonUtil::ProcessSingleQuotesLC(artist);
+ }
+
+ HBufC* art = MPXDbCommonUtil::ProcessSingleQuotesLC(albumArt);
+
+ iDbManager.ExecuteQueryL(aDriveId, KQueryAlbumInsert, rowId, name, 1, artistId, artistName,art);
+
+ CleanupStack::PopAndDestroy(art);
+ CleanupStack::PopAndDestroy(artistName);
+ CleanupStack::PopAndDestroy(name);
+ }
+ else if (result == KSqlAtRow)
+ {
+ // retrieve Art from Album table
+ TPtrC art(KNullDesC);
+ art.Set(MPXDbCommonUtil::GetColumnTextL(recordset, EAlbumArt));
+
+ // the current one is Unknown and the new one is Not Unknown
+ if ( art == KNullDesC && albumArt != KNullDesC )
+ {
+ HBufC* artReplaceSingleQuote =
+ MPXDbCommonUtil::ProcessSingleQuotesLC( albumArt );
+
+ TPtrC criteria(KCriterionArt);
+ HBufC* setStr = HBufC::NewLC(criteria.Length() + artReplaceSingleQuote->Length());
+ setStr->Des().Format( KCriterionArt, artReplaceSingleQuote );
+
+ iDbManager.ExecuteQueryL(aDriveId, KQueryAlbumUpdate, setStr, rowId);
+ CleanupStack::PopAndDestroy(setStr);
+ CleanupStack::PopAndDestroy(artReplaceSingleQuote);
+ }
+
+ // increment the number of songs for the category
+ query = PreProcessStringLC(KQueryCategoryIncrementSongCount);
+ iDbManager.ExecuteQueryL(aDriveId, *query, rowId);
+ CleanupStack::PopAndDestroy(query);
+ } // existing record
+ else
+ {
+ MPX_DEBUG2("SQL error %d", result);
+ User::Leave(result);
+ }
+
+ CleanupStack::PopAndDestroy(&recordset);
+
+ return rowId;
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::DecrementSongsForAlbumL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbAlbum::DecrementSongsForAlbumL(
+ const TUint32 aId,
+ TInt aDriveId,
+ CMPXMessageArray* aItemChangedMessages,
+ TBool& aItemExist,
+ const TDesC& aArt)
+ {
+ MPX_FUNC("CMPXDbAlbum::DecrementSongsForAlbumL");
+
+ // retrieve the existing record
+ HBufC* query = PreProcessStringLC(KQueryCategoryItem);
+ RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(*query, aId));
+ CleanupStack::PopAndDestroy(query);
+
+ CleanupClosePushL(recordset);
+
+ if (recordset.Next() != KSqlAtRow)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ // if just one song uses this category. Use <= just in case
+ if (recordset.ColumnInt64(EAlbumSongCount) <= 1)
+ {
+ aItemExist = EFalse;
+
+ // Decrement albums count on artist
+ TUint32 albumArtistId = recordset.ColumnInt64(EAlbumArtist);
+ iObserver.DeleteAlbumForArtistL(albumArtistId, aDriveId, aItemChangedMessages);
+ CleanupStack::PopAndDestroy(&recordset);
+
+ // delete the category
+ DeleteCategoryL(aId, aDriveId);
+
+ if (aItemChangedMessages)
+ {
+ // add the item changed message
+ MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, aId, EMPXItemDeleted,
+ iCategory, KDBPluginUid);
+ }
+ }
+ else
+ {
+ aItemExist = ETrue;
+
+ TBool itemModified = EFalse;
+
+ TPtrC art(MPXDbCommonUtil::GetColumnTextL(recordset, EAlbumArt));
+ if (NeedToUpdateArt(aArt, art))
+ {
+ MPX_DEBUG2("AlbumArt of the Song to be deleted is [%S]", &aArt);
+
+ //need to get alternative art in the same album to display
+ HBufC* newArt = AlbumartForAlbumL(aId, aArt);
+ CleanupStack::PushL(newArt);
+
+ //update Album table only if alternative albumart found
+ if (newArt)
+ {
+ MPX_DEBUG1("CMPXDbAlbum::DecrementSongsForAlbumL, get newArt");
+ HBufC* artReplaceSingleQuote = MPXDbCommonUtil::ProcessSingleQuotesLC( *newArt );
+ TPtrC criteria(KCriterionArt);
+ HBufC* setStr = HBufC::NewLC(criteria.Length() + artReplaceSingleQuote->Length());
+ setStr->Des().Format( KCriterionArt, artReplaceSingleQuote );
+
+ iDbManager.ExecuteQueryL(aDriveId, KQueryAlbumUpdate, setStr, aId);
+ CleanupStack::PopAndDestroy(setStr);
+ CleanupStack::PopAndDestroy(artReplaceSingleQuote);
+ itemModified = ETrue;
+ }
+ CleanupStack::PopAndDestroy(newArt);
+ }
+
+ if (aItemChangedMessages && itemModified)
+ {
+ // add the item changed message
+ MPXDbCommonUtil::AddItemAlbumChangedMessageL(*aItemChangedMessages, aId, EMPXItemModified,
+ EMPXAlbum, KDBPluginUid, ETrue, 0 );
+ }
+ CleanupStack::PopAndDestroy(&recordset);
+
+ // decrement the number of songs for the category
+ query = PreProcessStringLC(KQueryCategoryDecrementSongCount);
+ iDbManager.ExecuteQueryL(aDriveId, *query, aId);
+ CleanupStack::PopAndDestroy(query);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::GetAllCategoryItemsL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbAlbum::GetAllCategoryItemsL(
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray& aMediaArray)
+ {
+ MPX_FUNC("CMPXDbAlbum::GetAllCategoryItemsL");
+
+ RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(KQueryAlbumAll));
+
+ CleanupClosePushL(recordset);
+ TRAPD(err, ProcessAlbumRecordSetL(aAttrs, recordset, aMediaArray));
+ if (err != KErrNone)
+ {
+ iUnknownArtists.ResetAndDestroy();
+ iUnknownAlbums.ResetAndDestroy();
+
+ User::LeaveIfError(err);
+ }
+ CleanupStack::PopAndDestroy(&recordset);
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::GetAllCategoryItemsMediaWallL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbAlbum::GetAllCategoryItemsMediaWallL(
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray& aMediaArray)
+ {
+ MPX_FUNC("CMPXDbAlbum::GetAllCategoryItemsL");
+
+ RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(KQueryAlbumAllMediaWall));
+
+ CleanupClosePushL(recordset);
+ TRAPD(err, ProcessMediaWallAlbumRecordSetL(aAttrs, recordset, aMediaArray));
+ if (err != KErrNone)
+ {
+ iUnknownArtists.ResetAndDestroy();
+ iUnknownAlbums.ResetAndDestroy();
+
+ User::LeaveIfError(err);
+ }
+ CleanupStack::PopAndDestroy(&recordset);
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbCategory::GetSubCategoryItemsL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbAlbum::GetSubCategoryItemsL(
+ TMPXGeneralCategory aParentCategory,
+ TUint32 aParentId,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray& aMediaArray)
+ {
+ MPX_FUNC("CMPXDbCategory::GetSubCategoryItemsL");
+
+ // this is only valid for albums belonging to an artist
+ ASSERT((iCategory == EMPXAlbum) && (aParentCategory == EMPXArtist));
+
+ // to handle the UREL warning
+ (void)aParentCategory;
+
+ RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(KQueryMusicGetAlbumsforArtist, aParentId));
+ CleanupClosePushL(recordset);
+ ProcessAlbumRecordSetL(aAttrs, recordset, aMediaArray);
+ CleanupStack::PopAndDestroy(&recordset);
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::UpdateItemL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbAlbum::UpdateItemL(
+ TUint32 aId,
+ const CMPXMedia& aMedia,
+ TInt aDriveId,
+ CMPXMessageArray* aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbAlbum::UpdateItemL");
+
+ CDesCArrayFlat* fields = new (ELeave) CDesCArrayFlat(EAlbumFieldCount);
+ CleanupStack::PushL(fields);
+ CDesCArrayFlat* values = new (ELeave) CDesCArrayFlat(EAlbumFieldCount);
+ CleanupStack::PushL(values);
+
+ // process the media parameter and construct the fields and values array
+ GenerateAlbumFieldsValuesL(aMedia, *fields, *values);
+
+ // construct the SET string
+ HBufC* setStr = MPXDbCommonUtil::StringFromArraysLC(*fields, *values, KMCEqualSign, KMCCommaSign);
+
+ if (setStr->Length())
+ {
+ // execute the query
+ iDbManager.ExecuteQueryL(aDriveId, KQueryAlbumUpdate, setStr, aId);
+ MPXDbCommonUtil::AddItemAlbumChangedMessageL(*aItemChangedMessages, aId, EMPXItemModified,
+ EMPXAlbum, KDBPluginUid, ETrue, 0 );
+ }
+
+ CleanupStack::PopAndDestroy(setStr);
+ CleanupStack::PopAndDestroy(values);
+ CleanupStack::PopAndDestroy(fields);
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::GetSongsCountInAlbumMatchingArtistL
+// ----------------------------------------------------------------------------
+//
+TInt CMPXDbAlbum::GetSongsCountInAlbumMatchingArtistL(TUint32 aArtistId, TUint32 aAlbumId)
+ {
+ MPX_FUNC("CMPXDbAlbum::GetSongsCountInAlbumMatchingArtistL");
+
+ return ExecuteSumQueryL(KQuerySongsInArtistAlbum, aArtistId, aAlbumId);
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::UpdateMediaL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbAlbum::UpdateMediaL(
+ RSqlStatement& aRecord,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMedia& aMedia)
+ {
+ MPX_FUNC("CMPXDbAlbum::UpdateMediaL");
+
+ TInt count(aAttrs.Count());
+ for (TInt i = 0; i < count; ++i)
+ {
+ TInt contentId(aAttrs[i].ContentId());
+ TUint attributeId(aAttrs[i].AttributeId());
+
+ if (contentId == KMPXMediaIdGeneral)
+ {
+ if (attributeId & EMPXMediaGeneralId)
+ {
+ MPX_DEBUG1(" EMPXMediaGeneralId");
+
+ aMedia.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId,
+ aRecord.ColumnInt64(EAlbumUniqueId));
+ }
+ if (attributeId & EMPXMediaGeneralTitle)
+ {
+ MPX_DEBUG1(" EMPXMediaGeneralTitle");
+
+ TPtrC album( MPXDbCommonUtil::GetColumnTextL(aRecord, EAlbumName) );
+ aMedia.SetTextValueL(KMPXMediaGeneralTitle,
+ MPXDbCommonUtil::GetColumnTextL(aRecord, EAlbumName));
+ MPX_DEBUG2(" Album[%S]", &album );
+ }
+ if (attributeId & EMPXMediaGeneralCount)
+ {
+ MPX_DEBUG1(" EMPXMediaGeneralCount");
+
+ TInt songCount = GetSongsCountL(KDbManagerAllDrives,
+ aRecord.ColumnInt64(EAlbumUniqueId));
+ aMedia.SetTObjectValueL<TInt>(KMPXMediaGeneralCount, songCount );
+ MPX_DEBUG2(" SongCount[%d]", songCount );
+ }
+ } // end if contentId == KMPXMediaIdGeneral
+ else if ( contentId == KMPXMediaIdMusic )
+ {
+ if (attributeId & EMPXMediaMusicArtist)
+ {
+ MPX_DEBUG1(" EMPXMediaMusicArtist");
+
+ TPtrC artistName(MPXDbCommonUtil::GetColumnTextL(aRecord, EAlbumArtistName));
+ aMedia.SetTextValueL(KMPXMediaMusicArtist, artistName);
+ MPX_DEBUG2(" Artist[%S]", &artistName);
+ }
+
+ if (attributeId & EMPXMediaMusicAlbum)
+ {
+ MPX_DEBUG1(" EMPXMediaMusicAlbum");
+
+ TPtrC albumName(KNullDesC);
+ TPtrC album( MPXDbCommonUtil::GetColumnTextL(aRecord, EAlbumName) );
+
+
+ // if album is unknown
+ if ( album != KNullDesC)
+ {
+ albumName.Set(album);
+ }
+
+ aMedia.SetTextValueL(KMPXMediaMusicAlbum, albumName);
+ MPX_DEBUG2(" Album[%S]", &albumName);
+ }
+ if (attributeId & EMPXMediaMusicAlbumArtFileName)
+ {
+ MPX_DEBUG1(" EMPXMediaMusicAlbumArtFileName");
+
+ TPtrC art(MPXDbCommonUtil::GetColumnTextL(aRecord, EAlbumArt));
+ aMedia.SetTextValueL(KMPXMediaMusicAlbumArtFileName, art);
+ MPX_DEBUG2(" Art[%S]", &art);
+ }
+ }
+ } // end for
+
+ aMedia.SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType, EMPXItem);
+ aMedia.SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory, iCategory);
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::GenerateAlbumFieldsValuesL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbAlbum::GenerateAlbumFieldsValuesL(const CMPXMedia& aMedia, CDesCArray& aFields, CDesCArray& aValues)
+ {
+ if (aMedia.IsSupported(KMPXMediaMusicAlbumArtFileName))
+ {
+ const TDesC& albumArtFilename = aMedia.ValueText(KMPXMediaMusicAlbumArtFileName).Left(KMCMaxTextLen);
+ MPXDbCommonUtil::AppendValueL(aFields, aValues, KMCMusicArt, albumArtFilename);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::AlbumartForAlbumL
+// ----------------------------------------------------------------------------
+//
+HBufC* CMPXDbAlbum::AlbumartForAlbumL(const TUint32 aId, TPtrC aArt)
+ {
+ return iObserver.HandleAlbumartForAlbumL(aId, aArt);
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::ProcessAlbumRecordSetL
+// Unknown album or Unknown artist are stored in the database as NULL (Name field and ArtistName field).
+// The available unknown artist is saved for later and will be appended to the array
+// as the last item among items which have the same artist.
+// The available unknown albums are saved for later and will be appended to the array
+// as the last items after all known albums are appended.
+// The unknown album and unknown artist is saved for later and will be appended to the array
+// as the last item.
+//
+// NOTE: putting unknown album to the end of the array only takes place when title
+// field is requested. normal sorting algorithm occurs if title isn't
+// requested.
+//
+// Example:
+// Album X of artist A
+// Album X of artist B
+// Album X of unknown artist
+// Album Y of artist A
+// Album Y of unknown artist
+// Unknown album of artist A
+// Unknown album of artist B
+// Unknown album of unknown artist
+// ----------------------------------------------------------------------------
+//
+void CMPXDbAlbum::ProcessAlbumRecordSetL(
+ const TArray<TMPXAttribute>& aAttrs,
+ RSqlStatement& aRecordset,
+ CMPXMediaArray& aMediaArray)
+ {
+ // populate the array
+ TBool firstRecord(ETrue);
+ CMPXMedia* unknownAlbumUnknownArtistMedia(NULL);
+ CMPXMedia* unknownMedia(NULL);
+ TUint32 prevId(0);
+ TUint32 albumId(0);
+ TUint32 prevAlbumId(0);
+ TInt count(0);
+ TInt err(KErrNone);
+
+ // Reset array for unknown artists
+ if (iUnknownArtists.Count() > 0)
+ {
+ iUnknownArtists.ResetAndDestroy();
+ }
+
+ // Reset array for unknown albums
+ if (iUnknownAlbums.Count() > 0)
+ {
+ iUnknownAlbums.ResetAndDestroy();
+ }
+
+ TInt pPath(0);
+ if (aMediaArray.Count())
+ {
+ CMPXMedia* pMedia = aMediaArray[0];
+ if (pMedia->IsSupported(KMPXMediaGeneralValue))
+ { // Query excuted by OpenL
+ pPath = pMedia->ValueTObjectL<TInt>(KMPXMediaGeneralValue);
+ MPX_ASSERT(pPath);
+ }
+ }
+
+ RArray<TMPXItemId> ids;
+ CleanupClosePushL(ids);
+
+ while ((err = aRecordset.Next()) == KSqlAtRow)
+ {
+ TUint32 rowId(aRecordset.ColumnInt64(EAlbumUniqueId));
+ if (prevId == rowId)
+ {
+ continue;
+ }
+
+ prevId = rowId;
+ CMPXMedia* media = CMPXMedia::NewL();
+ CleanupStack::PushL(media);
+
+ UpdateMediaL(aRecordset, aAttrs, *media);
+
+ albumId = MPXDbCommonUtil::GenerateUniqueIdL(iDbManager.Fs(), EMPXAlbum,
+ MPXDbCommonUtil::GetColumnTextL(aRecordset, EAlbumName), ETrue);
+
+ // Append Known album and Unknown artists
+ count = iUnknownArtists.Count();
+ if ( prevAlbumId != albumId && count > 0)
+ {
+ unknownMedia = NULL;
+
+ for (TInt i = 0; i < count; i++)
+ {
+ unknownMedia = iUnknownArtists[i];
+ if (unknownMedia->IsSupported(KMPXMediaGeneralId) && pPath)
+ {
+ ids.Append(unknownMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
+ }
+ aMediaArray.AppendL(*unknownMedia);
+ }
+
+ iUnknownArtists.ResetAndDestroy();
+ }
+
+ // for Unknown album and Unknown artist
+ if (firstRecord && (MPXDbCommonUtil::GetColumnTextL(aRecordset, EAlbumArtistName).Length() == 0) &&
+ (MPXDbCommonUtil::GetColumnTextL(aRecordset, EAlbumName).Length() == 0))
+ {
+ unknownAlbumUnknownArtistMedia = media;
+ }
+ // for Unknown albums and Known artists
+ else if (MPXDbCommonUtil::GetColumnTextL(aRecordset, EAlbumName).Length() == 0)
+ {
+ iUnknownAlbums.Append(media);
+ CleanupStack::Pop(media);
+ }
+ // for Known album and Unknown artist
+ else if (MPXDbCommonUtil::GetColumnTextL(aRecordset, EAlbumArtistName).Length() == 0)
+ {
+ iUnknownArtists.Append(media);
+ CleanupStack::Pop(media);
+
+ prevAlbumId = albumId;
+ }
+ else
+ {
+ if (media->IsSupported(KMPXMediaGeneralId) && pPath)
+ {
+ ids.AppendL(media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
+ }
+ aMediaArray.AppendL(*media);
+ CleanupStack::PopAndDestroy(media);
+ }
+
+ firstRecord = EFalse;
+ } // end while
+
+ if (err != KSqlAtEnd)
+ {
+ User::LeaveIfError(err);
+ }
+
+ // Append Known artist and Unknown albums
+ count = iUnknownArtists.Count();
+ if ( count > 0)
+ {
+ unknownMedia = NULL;
+
+ for (TInt i = 0; i < count; i++)
+ {
+ unknownMedia = iUnknownArtists[i];
+ if (unknownMedia->IsSupported(KMPXMediaGeneralId) && pPath)
+ {
+ ids.Append(unknownMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
+ }
+ aMediaArray.AppendL(*unknownMedia);
+ }
+
+ iUnknownArtists.ResetAndDestroy();
+ }
+
+ // Append Unknown artists to MediaArray
+ count = iUnknownAlbums.Count();
+ if ( count > 0)
+ {
+ CMPXMedia* unknownMedia = NULL;
+
+ for (TInt i = 0; i < count; i++)
+ {
+ unknownMedia = iUnknownAlbums[i];
+ if (unknownMedia->IsSupported(KMPXMediaGeneralId) && pPath)
+ {
+ ids.Append(unknownMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
+ }
+ aMediaArray.AppendL(*unknownMedia);
+ }
+
+ iUnknownAlbums.ResetAndDestroy();
+ }
+
+ // the last item in the list
+ if (unknownAlbumUnknownArtistMedia)
+ {
+ if (unknownAlbumUnknownArtistMedia->IsSupported(KMPXMediaGeneralId) && pPath)
+ {
+ ids.AppendL(unknownAlbumUnknownArtistMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
+ }
+ aMediaArray.AppendL(*unknownAlbumUnknownArtistMedia);
+ CleanupStack::PopAndDestroy(unknownAlbumUnknownArtistMedia);
+ }
+
+ // Append ids to the returned path
+ if (pPath)
+ {
+ ((CMPXCollectionPath*)pPath)->AppendL(ids.Array());
+ }
+ CleanupStack::PopAndDestroy(&ids);
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::ProcessMediaWallAlbumRecordSetL
+// Unknown album or Unknown artist are stored in the database as NULL (Name field and ArtistName field).
+// The available unknown album is saved for later and will be appended to the array
+// as the last item among items which have the same artist.
+// The available unknown artists are saved for later and will be appended to the array
+// as the last items after all known artists are appended.
+// The unknown album and unknown artist is saved for later and will be appended to the array
+// as the last item.
+//
+// NOTE: putting unknown album to the end of the array only takes place when title
+// field is requested. normal sorting algorithm occurs if title isn't
+// requested.
+//
+// Example:
+// Album X of artist A
+// Album Y of artist A
+// Unknown album of artist A
+// Album X of artist B
+// Album Z of artist B
+// Unknown album of artist B
+// Album X of unknown artist
+// Album Y of unknown artist
+// Unknown album of unknown artist
+// ----------------------------------------------------------------------------
+//
+//
+void CMPXDbAlbum::ProcessMediaWallAlbumRecordSetL(
+ const TArray<TMPXAttribute>& aAttrs,
+ RSqlStatement& aRecordset,
+ CMPXMediaArray& aMediaArray)
+ {
+ // populate the array
+ TBool firstRecord(ETrue);
+ CMPXMedia* unknownAlbumUnknownArtistMedia(NULL);
+ CMPXMedia* unknownMedia(NULL);
+ TUint32 prevId(0);
+ TUint32 artistId(0);
+ TUint32 prevArtistId(0);
+ TInt count(0);
+ TInt err(KErrNone);
+
+ // Reset array for unknown artists
+ if (iUnknownArtists.Count() > 0)
+ {
+ iUnknownArtists.ResetAndDestroy();
+ }
+
+ // Reset array for unknown albums
+ if (iUnknownAlbums.Count() > 0)
+ {
+ iUnknownAlbums.ResetAndDestroy();
+ }
+
+ TInt pPath(0);
+ if (aMediaArray.Count())
+ {
+ CMPXMedia* pMedia = aMediaArray[0];
+ if (pMedia->IsSupported(KMPXMediaGeneralValue))
+ { // Query excuted by OpenL
+ pPath = pMedia->ValueTObjectL<TInt>(KMPXMediaGeneralValue);
+ MPX_ASSERT(pPath);
+ }
+ }
+
+ RArray<TMPXItemId> ids;
+ CleanupClosePushL(ids);
+
+ while ((err = aRecordset.Next()) == KSqlAtRow)
+ {
+ TUint32 rowId(aRecordset.ColumnInt64(EAlbumUniqueId));
+ if (prevId == rowId)
+ {
+ continue;
+ }
+
+ prevId = rowId;
+ CMPXMedia* media = CMPXMedia::NewL();
+ CleanupStack::PushL(media);
+
+ UpdateMediaL(aRecordset, aAttrs, *media);
+
+ artistId = aRecordset.ColumnInt64(EAlbumArtist);
+
+ // Append Known artist and Unknown albums
+ count = iUnknownAlbums.Count();
+ if (prevArtistId != artistId && count > 0)
+ {
+ unknownMedia = NULL;
+
+ for (TInt i = 0; i < count; i++)
+ {
+ unknownMedia = iUnknownAlbums[i];
+ if (unknownMedia->IsSupported(KMPXMediaGeneralId) && pPath)
+ {
+ ids.Append(unknownMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
+ }
+ aMediaArray.AppendL(*unknownMedia);
+ }
+
+ iUnknownAlbums.ResetAndDestroy();
+ }
+
+ // for Unknown artist and Unknown album
+ if (firstRecord && (MPXDbCommonUtil::GetColumnTextL(aRecordset, EAlbumName).Length() == 0) &&
+ (MPXDbCommonUtil::GetColumnTextL(aRecordset, EAlbumArtistName).Length() == 0))
+ {
+ unknownAlbumUnknownArtistMedia = media;
+ }
+ // for Unknown artists and Known albums
+ else if (MPXDbCommonUtil::GetColumnTextL(aRecordset, EAlbumArtistName).Length() == 0)
+ {
+ iUnknownArtists.Append(media);
+ CleanupStack::Pop(media);
+ }
+ // for Known artist and Unknown album
+ else if (MPXDbCommonUtil::GetColumnTextL(aRecordset, EAlbumName).Length() == 0)
+ {
+ iUnknownAlbums.Append(media);
+ CleanupStack::Pop(media);
+ prevArtistId = artistId;
+ }
+ else
+ {
+ if (media->IsSupported(KMPXMediaGeneralId) && pPath)
+ {
+ ids.AppendL(media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
+ }
+ aMediaArray.AppendL(*media);
+ CleanupStack::PopAndDestroy(media);
+ }
+
+ firstRecord = EFalse;
+ } // end while
+
+ if (err != KSqlAtEnd)
+ {
+ User::LeaveIfError(err);
+ }
+
+ // Append Known artist and Unknown albums
+ count = iUnknownAlbums.Count();
+ if ( count > 0)
+ {
+ unknownMedia = NULL;
+
+ for (TInt i = 0; i < count; i++)
+ {
+ unknownMedia = iUnknownAlbums[i];
+ if (unknownMedia->IsSupported(KMPXMediaGeneralId) && pPath)
+ {
+ ids.Append(unknownMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
+ }
+ aMediaArray.AppendL(*unknownMedia);
+ }
+
+ iUnknownAlbums.ResetAndDestroy();
+ }
+
+ // Append Unknown artists to MediaArray
+ count = iUnknownArtists.Count();
+ if ( count > 0)
+ {
+ CMPXMedia* unknownMedia = NULL;
+
+ for (TInt i = 0; i < count; i++)
+ {
+ unknownMedia = iUnknownArtists[i];
+ if (unknownMedia->IsSupported(KMPXMediaGeneralId) && pPath)
+ {
+ ids.Append(unknownMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
+ }
+ aMediaArray.AppendL(*unknownMedia);
+ }
+
+ iUnknownArtists.ResetAndDestroy();
+ }
+
+ // the last item in the list
+ if (unknownAlbumUnknownArtistMedia)
+ {
+ if (unknownAlbumUnknownArtistMedia->IsSupported(KMPXMediaGeneralId) && pPath)
+ {
+ ids.AppendL(unknownAlbumUnknownArtistMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
+ }
+ aMediaArray.AppendL(*unknownAlbumUnknownArtistMedia);
+ CleanupStack::PopAndDestroy(unknownAlbumUnknownArtistMedia);
+ }
+
+ // Append ids to the returned path
+ if (pPath)
+ {
+ ((CMPXCollectionPath*)pPath)->AppendL(ids.Array());
+ }
+ CleanupStack::PopAndDestroy(&ids);
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::GenerateUniqueIdL
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbAlbum::GenerateUniqueIdL(const CMPXMedia& aMedia)
+ {
+ TPtrC album(KNullDesC);
+ TPtrC albumArtist(KNullDesC);
+ TPtrC artist(KNullDesC);
+
+ // check Album attirbute
+ if (aMedia.IsSupported(KMPXMediaMusicAlbum))
+ {
+ album.Set(aMedia.ValueText(KMPXMediaMusicAlbum).Left(KMCMaxTextLen));
+ }
+
+ HBufC* buf(NULL);
+ if (RetrieveAlbumArtistL(aMedia, albumArtist))
+ {
+ buf = HBufC::NewLC(album.Length() + albumArtist.Length() + KAlbumAlbumArtistSeperator().Length());
+
+ buf->Des().Append(album);
+ buf->Des().Append(KAlbumAlbumArtistSeperator);
+ buf->Des().Append(albumArtist);
+ }
+ else
+ {
+ RetrieveArtist(aMedia, artist);
+
+ buf = HBufC::NewLC(album.Length() + artist.Length() + KAlbumArtistSeperator().Length());
+
+ buf->Des().Append(album);
+ buf->Des().Append(KAlbumArtistSeperator);
+ buf->Des().Append(artist);
+ }
+
+ // try to find the item first
+ TUint32 id(MPXDbCommonUtil::GenerateUniqueIdL(iDbManager.Fs(), EMPXAlbum,
+ *buf, ETrue));
+ CleanupStack::PopAndDestroy(buf);
+
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::IsUnknownAlbumL
+// ----------------------------------------------------------------------------
+//
+TBool CMPXDbAlbum::IsUnknownAlbumL(const TUint32 aId)
+ {
+ HBufC* query = PreProcessStringLC(KQueryCategoryItem);
+ RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(*query, aId));
+ CleanupStack::PopAndDestroy(query);
+ CleanupClosePushL(recordset);
+
+ if (recordset.Next() != KSqlAtRow)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ TPtrC album(MPXDbCommonUtil::GetColumnTextL(recordset, EAlbumName));
+ TPtrC artistName(MPXDbCommonUtil::GetColumnTextL(recordset, EAlbumArtistName));
+
+ TBool ret = EFalse;
+ if (album.Length() == 0 || artistName.Length() == 0)
+ {
+ ret = ETrue;
+ }
+ else
+ {
+ ret = EFalse;
+ }
+
+ CleanupStack::PopAndDestroy(&recordset);
+
+ return ret;
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::RetrieveAlbumArtistL
+// ----------------------------------------------------------------------------
+//
+TBool CMPXDbAlbum::RetrieveAlbumArtistL(const CMPXMedia& aMedia, TPtrC& aName)
+ {
+ // check AlbumArtist attribute
+ if (aMedia.IsSupported(KMPXMediaMusicAlbumArtist))
+ {
+ aName.Set(aMedia.ValueText(KMPXMediaMusicAlbumArtist).Left(KMCMaxTextLen));
+ }
+ else
+ {
+ aName.Set(KNullDesC);
+ }
+
+ if (aName.Length() > 0 )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::RetrieveArtist
+// ----------------------------------------------------------------------------
+//
+void CMPXDbAlbum::RetrieveArtist(const CMPXMedia& aMedia, TPtrC& aName)
+ {
+ // check Artist attribute
+ if (aMedia.IsSupported(KMPXMediaMusicArtist))
+ {
+ aName.Set(aMedia.ValueText(KMPXMediaMusicArtist).Left(KMCMaxTextLen));
+ }
+ else
+ {
+ aName.Set(KNullDesC);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::NeedToUpdateArt
+// ----------------------------------------------------------------------------
+//
+TBool CMPXDbAlbum::NeedToUpdateArt(const TDesC& aDeletedSongArt, const TDesC& aCurrentAlbumArt)
+ {
+ if (aDeletedSongArt.Length() == 0)
+ {
+ // Deleted song's art has default album art
+ return EFalse;
+ }
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+ else
+ if (aDeletedSongArt.Length() > 0)
+ {
+ TParsePtrC parse(aDeletedSongArt);
+ TPtrC ext(parse.Ext());
+ //set flag to false, so .alb will not overwrite art field in album, artist table
+ // when song with embedded art
+ if (ext.CompareF(KAbstractAlbumExt) == 0)
+ {
+ // Deleted song's art is Non-embedded album art
+ return EFalse;
+ }
+ }
+ else
+#endif
+ if (aDeletedSongArt.Length() > 0 && aCurrentAlbumArt.Length() > 0 && aDeletedSongArt.CompareF(aCurrentAlbumArt) == 0)
+ {
+ // Deleted song's art is Embedded album art and it is the same as Album's current art
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::CreateTableL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbAlbum::CreateTableL(
+ RSqlDatabase& aDatabase,
+ TBool /* aCorruptTable */)
+ {
+ MPX_FUNC("CMPXDbCategory::CreateTableL");
+
+ // create the table
+ User::LeaveIfError(aDatabase.Exec(KAlbumCreateTable));
+
+ // do not create an index on the Name field
+ // as it only slows down the insert/update queries overall
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbAlbum::CheckTableL
+// ----------------------------------------------------------------------------
+//
+TBool CMPXDbAlbum::CheckTableL(
+ RSqlDatabase& aDatabase)
+ {
+ MPX_FUNC("CMPXDbCategory::CheckTableL");
+
+ TBool check(DoCheckTable(aDatabase, KAlbumCheckTable));
+
+ return check;
+ }
+
+// End of File