mpxplugins/serviceplugins/collectionplugins/mpxsqlitedbhgplugin/src/mpxdbplaylistsongs.cpp
changeset 0 ff3acec5bc43
child 9 13afc0e517bd
equal deleted inserted replaced
-1:000000000000 0:ff3acec5bc43
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Responsible for interaction with the PlaylistSongs and
       
    15 *                PlaylistSongInfo tables.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <f32file.h>
       
    22 #include <mpxlog.h>
       
    23 #include <mpxmedia.h>
       
    24 #include <mpxmediaarray.h>
       
    25 #include <mpxmediageneraldefs.h>
       
    26 #include "mpxdbcommonutil.h"
       
    27 
       
    28 #include "mpxcollectiondbdef.h"
       
    29 #include "mpxdbutil.h"
       
    30 #include "mpxdbpluginqueries.h"
       
    31 #include "mpxdbmanager.h"
       
    32 #include "mpxdbplaylistsongs.h"
       
    33 
       
    34 // ============================ MEMBER FUNCTIONS ==============================
       
    35 
       
    36 // ----------------------------------------------------------------------------
       
    37 // Two-phased constructor.
       
    38 // ----------------------------------------------------------------------------
       
    39 //
       
    40 CMPXDbPlaylistSongs* CMPXDbPlaylistSongs::NewL(
       
    41     CMPXDbManager& aDbManager)
       
    42     {
       
    43     MPX_FUNC("CMPXDbPlaylistSongs::NewL");
       
    44 
       
    45     CMPXDbPlaylistSongs* self = CMPXDbPlaylistSongs::NewLC(aDbManager);
       
    46     CleanupStack::Pop(self);
       
    47     return self;
       
    48     }
       
    49 
       
    50 // ----------------------------------------------------------------------------
       
    51 // Two-phased constructor.
       
    52 // ----------------------------------------------------------------------------
       
    53 //
       
    54 CMPXDbPlaylistSongs* CMPXDbPlaylistSongs::NewLC(
       
    55     CMPXDbManager& aDbManager)
       
    56     {
       
    57     MPX_FUNC("CMPXDbPlaylistSongs::NewLC");
       
    58 
       
    59     CMPXDbPlaylistSongs* self = new (ELeave) CMPXDbPlaylistSongs(aDbManager);
       
    60     CleanupStack::PushL(self);
       
    61     self->ConstructL();
       
    62     return self;
       
    63     }
       
    64 
       
    65 // ----------------------------------------------------------------------------
       
    66 // Destructor
       
    67 // ----------------------------------------------------------------------------
       
    68 //
       
    69 CMPXDbPlaylistSongs::~CMPXDbPlaylistSongs()
       
    70     {
       
    71     MPX_FUNC("CMPXDbPlaylistSongs::~CMPXDbPlaylistSongs");
       
    72     }
       
    73 
       
    74 // ----------------------------------------------------------------------------
       
    75 // Constructor
       
    76 // ----------------------------------------------------------------------------
       
    77 //
       
    78 CMPXDbPlaylistSongs::CMPXDbPlaylistSongs(
       
    79     CMPXDbManager& aDbManager) :
       
    80     CMPXDbTable(aDbManager)
       
    81     {
       
    82     MPX_FUNC("CMPXDbPlaylistSongs::CMPXDbPlaylistSongs");
       
    83     }
       
    84 
       
    85 // ----------------------------------------------------------------------------
       
    86 // Second phase constructor.
       
    87 // ----------------------------------------------------------------------------
       
    88 //
       
    89 void CMPXDbPlaylistSongs::ConstructL()
       
    90     {
       
    91     MPX_FUNC("CMPXDbPlaylistSongs::ConstructL");
       
    92     BaseConstructL();
       
    93     }
       
    94 
       
    95 // ----------------------------------------------------------------------------
       
    96 // CMPXDbPlaylistSongs::AddSongsL
       
    97 // ----------------------------------------------------------------------------
       
    98 //
       
    99 void CMPXDbPlaylistSongs::AddSongsL(
       
   100     TUint32 aPlaylistId,
       
   101     const CMPXMediaArray& aMediaArray,
       
   102     TInt aDriveId)
       
   103     {
       
   104     MPX_FUNC("CMPXDbPlaylistSongs::AddSongsL");
       
   105 
       
   106     TInt count(aMediaArray.Count());
       
   107     for (TInt index = 0; index < count; ++index)
       
   108         {
       
   109         AddSongL(aPlaylistId, *(aMediaArray[index]), aDriveId);
       
   110         }
       
   111     }
       
   112 
       
   113 // ----------------------------------------------------------------------------
       
   114 // CMPXDbPlaylistSongs::AddSongL
       
   115 // ----------------------------------------------------------------------------
       
   116 //
       
   117 TUint32 CMPXDbPlaylistSongs::AddSongL(
       
   118     TUint32 aPlaylistId,
       
   119     const CMPXMedia& aMedia,
       
   120     TInt aDriveId)
       
   121     {
       
   122     MPX_FUNC("CMPXDbPlaylistSongs::AddSongL");
       
   123     return AddSongL(aPlaylistId, CountL(aPlaylistId), aMedia, aDriveId);
       
   124     }
       
   125 
       
   126 // ----------------------------------------------------------------------------
       
   127 // CMPXDbPlaylistSongs::AddSongL
       
   128 // ----------------------------------------------------------------------------
       
   129 //
       
   130 TUint32 CMPXDbPlaylistSongs::AddSongL(
       
   131     TUint32 aPlaylistId,
       
   132     TInt aOrdinal,
       
   133     const CMPXMedia& aMedia,
       
   134     TInt aDriveId)
       
   135     {
       
   136     MPX_FUNC("CMPXDbPlaylistSongs::AddSongL");
       
   137 
       
   138     // the UniqueId field is AUTOINCREMENT and its value is going to be generated
       
   139     // automatically by the database - no need to supply it here
       
   140     TUint32 songId((aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2);
       
   141 
       
   142     // insert PlaylistSongs record
       
   143     iDbManager.ExecuteQueryL(aDriveId, KQueryPlaylistSongsInsert, aPlaylistId, songId, aOrdinal);
       
   144 
       
   145     // if the song is not already in the PlaylistSongInfo table - add it
       
   146     if (!SongInfoExistsL(aDriveId, songId))
       
   147         {
       
   148         // add a new song info record
       
   149         HBufC* uri = MPXDbCommonUtil::ProcessSingleQuotesLC(aMedia.ValueText(KMPXMediaGeneralUri));
       
   150         HBufC* title = MPXDbCommonUtil::ProcessSingleQuotesLC(aMedia.ValueText(KMPXMediaGeneralTitle));
       
   151 
       
   152         TUint32 dbFlag(0);
       
   153         if (aMedia.IsSupported(KMPXMediaGeneralFlags))
       
   154             {
       
   155             dbFlag = (aMedia.ValueTObjectL<TUint>(KMPXMediaGeneralFlags));
       
   156             dbFlag = dbFlag & (~KMPXMediaGeneralFlagsDriveInfo); // clear drive info
       
   157             }
       
   158 
       
   159         // add the URI without the drive letter
       
   160         TPtrC uriPtr(uri->Mid(KMCPathStartPos));
       
   161         iDbManager.ExecuteQueryL(aDriveId, KQueryPlaylistSongInfoInsert, songId, &uriPtr, title,
       
   162             MPXDbCommonUtil::GetVolIdMatchDriveIdL(iDbManager.Fs(), TDriveUnit(*uri)), dbFlag);
       
   163 
       
   164         CleanupStack::PopAndDestroy(title);
       
   165         CleanupStack::PopAndDestroy(uri);
       
   166         }
       
   167 
       
   168     return songId;
       
   169     }
       
   170 
       
   171 // ----------------------------------------------------------------------------
       
   172 // CMPXDbPlaylistSongs::UpdateSongL
       
   173 // ----------------------------------------------------------------------------
       
   174 //
       
   175 TBool CMPXDbPlaylistSongs::UpdateSongL(
       
   176     TUint32 aSongId,
       
   177     const CMPXMedia& aMedia,
       
   178     TBool aResetFlags,
       
   179     TBool& aUpdated)
       
   180     {
       
   181     MPX_FUNC("CMPXDbPlaylistSongs::UpdateSongL");
       
   182 
       
   183     aUpdated = EFalse;
       
   184     TBool visibleChange(EFalse);
       
   185 
       
   186     // get the current record
       
   187     RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(KQueryPlaylistSongInfoGet, aSongId));
       
   188     CleanupClosePushL(recordset);
       
   189 
       
   190     if (recordset.Next() == KSqlAtRow)
       
   191         {
       
   192         const TArray<TMPXAttribute> attributes = aMedia.Attributes();
       
   193 
       
   194         // stores the current song ID, which may change during execution
       
   195         TUint32 songId(aSongId);
       
   196 
       
   197         TInt attrCount(attributes.Count());
       
   198         for (TInt i = 0; i < attrCount; ++i)
       
   199             {
       
   200             TInt contentId(attributes[i].ContentId());
       
   201             TUint attributeId(attributes[i].AttributeId());
       
   202 
       
   203             switch(contentId)
       
   204                 {
       
   205                 case KMPXMediaIdGeneral:
       
   206                     {
       
   207                     if (attributeId & EMPXMediaGeneralTitle)
       
   208                         {
       
   209                         // existing title
       
   210                         TPtrC title(aMedia.ValueText(KMPXMediaGeneralTitle).Left(KMCMaxTextLen));
       
   211 
       
   212                         // compare with the old title
       
   213                         if (title.Compare(MPXDbCommonUtil::GetColumnTextL(recordset, EPlaylistSongInfoTitle)) != 0)
       
   214                             {
       
   215                             HBufC* titleProc = MPXDbCommonUtil::ProcessSingleQuotesLC(title);
       
   216 
       
   217                             // title has changed - update on all drives
       
   218                             iDbManager.ExecuteQueryL(KDbManagerAllDrives, KQueryPlaylistSongInfoUpdateTitle,
       
   219                                 titleProc, songId);
       
   220 
       
   221                             CleanupStack::PopAndDestroy(titleProc);
       
   222 
       
   223                             visibleChange = ETrue;
       
   224                             aUpdated = ETrue;
       
   225                             MPX_DEBUG2("    Title[%S]", &title);
       
   226                             }
       
   227                         }
       
   228 
       
   229                     if (attributeId & EMPXMediaGeneralUri)
       
   230                         {
       
   231                         const TDesC& uriOrig(aMedia.ValueText(KMPXMediaGeneralUri));
       
   232                         songId = MPXDbCommonUtil::GenerateUniqueIdL(iDbManager.Fs(), EMPXCollection, uriOrig, EFalse);
       
   233 
       
   234                         if (aSongId != songId)
       
   235                             {
       
   236                             // URI of the song has been changed. This changes the Id of the song and both the
       
   237                             // PlaylistSongs and PlaylistSongInfo tables should be updated accordingly.
       
   238 
       
   239                             HBufC* uri = MPXDbCommonUtil::ProcessSingleQuotesLC(uriOrig);
       
   240 
       
   241                             // use the URI without the drive letter
       
   242                             TPtrC uriPtr(uri->Mid(KMCPathStartPos));
       
   243 
       
   244                             // update the PlaylistSongInfo table on all drives
       
   245                             iDbManager.ExecuteQueryL(KDbManagerAllDrives, KQueryPlaylistSongInfoUpdate, songId,
       
   246                                 &uriPtr, MPXDbCommonUtil::GetVolIdMatchDriveIdL(iDbManager.Fs(), TDriveUnit(*uri)), aSongId);
       
   247 
       
   248                             // update the PlaylistSongs table on all drives
       
   249                             iDbManager.ExecuteQueryL(KDbManagerAllDrives, KQueryPlaylistSongsUpdate, songId,
       
   250                                 aSongId);
       
   251 
       
   252                             aUpdated = ETrue;
       
   253                             MPX_DEBUG3("    CurrentSongId[0x%x] changed to [0x%x]", aSongId, songId);
       
   254 
       
   255                             CleanupStack::PopAndDestroy(uri);
       
   256                             }
       
   257                         }
       
   258 
       
   259                     if (attributeId & EMPXMediaGeneralFlags)
       
   260                         {
       
   261                         TUint flag(aMedia.ValueTObjectL<TUint>(KMPXMediaGeneralFlags));
       
   262                         TUint32 curFlag(recordset.ColumnInt64(EPlaylistSongInfoDbFlag));
       
   263 
       
   264                         if (flag & KMPXMediaGeneralFlagsSetOrUnsetBit)
       
   265                             {
       
   266                             if (aResetFlags)
       
   267                                 {
       
   268                                 visibleChange = ETrue;
       
   269                                 curFlag = flag;
       
   270                                 }
       
   271                             else
       
   272                                 {
       
   273                                 // Set flag, visible change is true only if the flag status is changing
       
   274                                 visibleChange = visibleChange || ((curFlag^flag) & 0x7FFFFFFF);
       
   275                                 curFlag |= flag;
       
   276                                 }
       
   277                             }
       
   278                         else
       
   279                             {
       
   280                             // Clear flag, visible change is true only if the flag status is changing
       
   281                             visibleChange = visibleChange || (((curFlag^0xFFFFFFFF)^flag) & 0x7FFFFFFF);
       
   282                             curFlag &= (~flag);
       
   283                             }
       
   284 
       
   285                         if (visibleChange)
       
   286                             {
       
   287                             // update the flags on all drives
       
   288                             iDbManager.ExecuteQueryL(KDbManagerAllDrives, KQueryPlaylistSongInfoUpdateFlags,
       
   289                                 curFlag, songId);
       
   290                             aUpdated = ETrue;
       
   291                             }
       
   292 
       
   293                         MPX_DEBUG2("    GeneralFlags[%b]", curFlag);
       
   294                         }
       
   295                     } // end case
       
   296                 } // end switch
       
   297             } // end for
       
   298         }
       
   299 
       
   300     CleanupStack::PopAndDestroy(&recordset);
       
   301     return visibleChange;
       
   302     }
       
   303 
       
   304 // ----------------------------------------------------------------------------
       
   305 // CMPXDbPlaylistSongs::UpdateSongsL
       
   306 // ----------------------------------------------------------------------------
       
   307 //
       
   308 void CMPXDbPlaylistSongs::UpdateSongsL(
       
   309     TUint32 aPlaylistId,
       
   310     TUint32 aNewPlaylistId)
       
   311     {
       
   312     MPX_FUNC("CMPXDbPlaylistSongs::UpdateSongsL");
       
   313 
       
   314     // update the PlaylistSongs table on all drives
       
   315     iDbManager.ExecuteQueryL(KDbManagerAllDrives, KQueryPlaylistSongsUpdatePlaylistId,
       
   316         aNewPlaylistId, aPlaylistId);
       
   317     }
       
   318 
       
   319 // ----------------------------------------------------------------------------
       
   320 // CMPXDbPlaylistSongs::ReorderSongL
       
   321 // ----------------------------------------------------------------------------
       
   322 //
       
   323 void CMPXDbPlaylistSongs::ReorderSongL(
       
   324     const TMPXItemId& aPlaylistId,
       
   325     const TMPXItemId& aSongId,
       
   326     TUint aOriginalOrdinal,
       
   327     TUint aNewOrdinal)
       
   328     {
       
   329     MPX_DEBUG1("-->CMPXDbPlaylistSongs::ReorderSongL");
       
   330     MPX_DEBUG5("    playlist[0x%x, 0x%x], song[0x%x, 0x%x]",
       
   331                aPlaylistId.iId1, aPlaylistId.iId2, aSongId.iId1, aSongId.iId2);
       
   332 
       
   333     //
       
   334     // Move the song up. The rest of the songs in between the old ordinal and new ordinal
       
   335     // need to be moved down, i.e. their ordinals need to be incremented
       
   336     //
       
   337     if (aOriginalOrdinal > aNewOrdinal)
       
   338         {
       
   339         iDbManager.ExecuteQueryL(KDbManagerAllDrives, KQueryPlaylistSongsMoveSongUp,
       
   340             aPlaylistId.iId2, aNewOrdinal, aOriginalOrdinal);
       
   341         }
       
   342 
       
   343     //
       
   344     // Move the song down. The rest of the songs in between the old ordinal and new ordinal
       
   345     // need to be moved up, i.e. their ordinals need to be decremented
       
   346     //
       
   347     else if (aOriginalOrdinal < aNewOrdinal)
       
   348         {
       
   349         iDbManager.ExecuteQueryL(KDbManagerAllDrives, KQueryPlaylistSongsMoveSongDown,
       
   350             aPlaylistId.iId2, aNewOrdinal, aOriginalOrdinal);
       
   351         }
       
   352 
       
   353     //
       
   354     // Change the ordinal of the song itself. If the ordinal is unchanged, no update is
       
   355     // required
       
   356     //
       
   357     if (aOriginalOrdinal != aNewOrdinal)
       
   358         {
       
   359         iDbManager.ExecuteQueryL(KDbManagerAllDrives, KQueryPlaylistSongsUpdateSongOrdinal,
       
   360             aNewOrdinal, aSongId.iId1);
       
   361         }
       
   362 
       
   363     MPX_DEBUG1("<--CMPXDbPlaylistSongs::ReorderSongL");
       
   364     }
       
   365 
       
   366 // ----------------------------------------------------------------------------
       
   367 // CMPXDbPlaylistSongs::DeleteSongL
       
   368 // ----------------------------------------------------------------------------
       
   369 //
       
   370 void CMPXDbPlaylistSongs::DeleteSongL(
       
   371     TUint32 aSongId)
       
   372     {
       
   373     MPX_FUNC("CMPXDbPlaylistSongs::DeleteSongL");
       
   374 
       
   375     // delete from the PlaylistSongs table on all drives
       
   376     iDbManager.ExecuteQueryL(KDbManagerAllDrives, KQueryPlaylistSongsDelete, aSongId);
       
   377 
       
   378     // delete from the PlaylistSongInfo table on all drives
       
   379     iDbManager.ExecuteQueryL(KDbManagerAllDrives, KQueryPlaylistSongInfoDelete, aSongId);
       
   380     }
       
   381 
       
   382 // ----------------------------------------------------------------------------
       
   383 // CMPXDbPlaylistSongs::DeleteSongL
       
   384 // ----------------------------------------------------------------------------
       
   385 //
       
   386 void CMPXDbPlaylistSongs::DeleteSongL(
       
   387     TUint32 aPlaylistId,
       
   388     TUint32 aSongId,
       
   389     TInt aOrdinal,
       
   390     TInt aDriveId)
       
   391     {
       
   392     MPX_FUNC("CMPXDbPlaylist::DeleteSongL");
       
   393 
       
   394     // get the number of instances for the song in the playlist
       
   395     TInt count(SongInstanceCountL(aPlaylistId, aSongId));
       
   396 
       
   397     if (1 == count)
       
   398         {
       
   399         // just one instance with this ID in the playlist
       
   400         // delete it regardless of the ordinal
       
   401         iDbManager.ExecuteQueryL(aDriveId, KQueryPlaylistSongsDeleteSong, aPlaylistId, aSongId);
       
   402 
       
   403         // check how many instances of this song are left for all playlists
       
   404         if (!SongCountL(aSongId))
       
   405             {
       
   406             // delete the PlaylistSongInfo record
       
   407             iDbManager.ExecuteQueryL(aDriveId, KQueryPlaylistSongInfoDelete, aSongId);
       
   408             }
       
   409         }
       
   410     else if (count > 1)
       
   411         {
       
   412         // multiple songs with this id in the playlist
       
   413         // try to delete the one with the specified ordinal
       
   414         iDbManager.ExecuteQueryL(aDriveId, KQueryPlaylistSongsDeleteSongOrdinal, aPlaylistId,
       
   415             aSongId, aOrdinal);
       
   416         }
       
   417     else
       
   418         {
       
   419         // no such song in the playlist
       
   420         User::Leave(KErrCorrupt);
       
   421         }
       
   422     // adjust song ordinals for the songs after the deleted song
       
   423     iDbManager.ExecuteQueryL(aDriveId, KQueryPlaylistSongsUpdateSongOrdinalAfterDelete,
       
   424         aPlaylistId, aOrdinal);
       
   425     }
       
   426 
       
   427 // ----------------------------------------------------------------------------
       
   428 // CMPXDbPlaylistSongs::DeleteSongsL
       
   429 // ----------------------------------------------------------------------------
       
   430 //
       
   431 void CMPXDbPlaylistSongs::DeleteSongsL(
       
   432     TUint32 aPlaylistId,
       
   433     TInt aDriveId)
       
   434     {
       
   435     MPX_FUNC("CMPXDbPlaylist::DeleteSongsL");
       
   436 
       
   437     // delete the records from the PlaylistSongs table
       
   438     iDbManager.ExecuteQueryL(aDriveId, KQueryPlaylistSongsDeletePlaylist, aPlaylistId);
       
   439 
       
   440     // delete the unused records from the PlaylistSongInfo table
       
   441     CleanupSongInfoL(aDriveId);
       
   442     }
       
   443 
       
   444 // ----------------------------------------------------------------------------
       
   445 // CMPXDbPlaylistSongs::DeleteSongsForCategoryL
       
   446 // ----------------------------------------------------------------------------
       
   447 //
       
   448 void CMPXDbPlaylistSongs::DeleteSongsForCategoryL(
       
   449     TMPXGeneralCategory aCategory,
       
   450     TUint32 aCategoryId,
       
   451     TInt aDriveId)
       
   452     {
       
   453     MPX_FUNC("CMPXDbPlaylist::DeleteSongsForCategoryL");
       
   454 
       
   455     // get the category field name in the Music table
       
   456     TPtrC category = MPXDbUtil::MusicFieldNameForCategoryL(aCategory);
       
   457 
       
   458     iDbManager.ExecuteQueryL(aDriveId, KQueryPlaylistSongsDeleteForCategory,
       
   459         &category, aCategoryId);
       
   460 
       
   461     // delete the unused records from the PlaylistSongInfo table
       
   462     CleanupSongInfoL(aDriveId);
       
   463     }
       
   464 
       
   465 // ----------------------------------------------------------------------------
       
   466 // CMPXDbPlaylistSongs::DeleteSongsForArtistAndAlbumL
       
   467 // ----------------------------------------------------------------------------
       
   468 //
       
   469 void CMPXDbPlaylistSongs::DeleteSongsForArtistAndAlbumL(
       
   470     TUint32 aArtistId,
       
   471     TUint32 aAlbumId,
       
   472     TInt aDriveId)
       
   473     {
       
   474     MPX_FUNC("CMPXDbPlaylist::DeleteSongsForArtistAndAlbumL");
       
   475 
       
   476     // delete the songs in the PlaylisSongs table
       
   477     iDbManager.ExecuteQueryL(aDriveId, KQueryPlaylistSongsDeleteForArtistAlbum,
       
   478         aArtistId, aAlbumId);
       
   479 
       
   480     // delete the unused records from the PlaylistSongInfo table
       
   481     CleanupSongInfoL(aDriveId);
       
   482     }
       
   483 
       
   484 // ----------------------------------------------------------------------------
       
   485 // CMPXDbPlaylistSongs::DeleteAllSongsL
       
   486 // ----------------------------------------------------------------------------
       
   487 //
       
   488 void CMPXDbPlaylistSongs::DeleteAllSongsL()
       
   489     {
       
   490     MPX_FUNC("CMPXDbPlaylist::DeleteAllSongsL");
       
   491 
       
   492     // delete all records from the PlaylistSongs table, all drives
       
   493     iDbManager.ExecuteQueryL(KDbManagerAllDrives, KQueryPlaylistSongsDeleteAll);
       
   494 
       
   495     // delete all records from the PlaylistSongInfo table, all drives
       
   496     iDbManager.ExecuteQueryL(KDbManagerAllDrives, KQueryPlaylistSongInfoDeleteAll);
       
   497     }
       
   498 
       
   499 // ----------------------------------------------------------------------------
       
   500 // CMPXDbPlaylistSongs::GetSongsL
       
   501 // ----------------------------------------------------------------------------
       
   502 //
       
   503 void CMPXDbPlaylistSongs::GetSongsL(
       
   504     TUint32 aPlaylistId,
       
   505     CMPXMediaArray& aMediaArray)
       
   506     {
       
   507     MPX_DEBUG2("-->CMPXDbPlaylistSongs::GetSongsL(playlist 0x%x)", aPlaylistId);
       
   508 
       
   509     RArray<TMPXAttribute> attributes;
       
   510     CleanupClosePushL( attributes );
       
   511 
       
   512     attributes.AppendL(KMPXMediaGeneralType);
       
   513     attributes.AppendL(KMPXMediaGeneralCategory);
       
   514     attributes.AppendL(KMPXMediaGeneralId);
       
   515 
       
   516     // cannot execute a joined query to the music table
       
   517     // because the song records in the music table may be on a different drive
       
   518     ExecuteMediaQueryL(attributes.Array(), aMediaArray, KQueryPlaylistSongsGetSongs, aPlaylistId);
       
   519 
       
   520     CleanupStack::PopAndDestroy(&attributes);
       
   521 
       
   522     MPX_DEBUG1("<--CMPXDbPlaylistSongs::GetSongsL");
       
   523     }
       
   524 
       
   525 // ----------------------------------------------------------------------------
       
   526 // CMPXDbPlaylistSongs::GetSongsL
       
   527 // ----------------------------------------------------------------------------
       
   528 //
       
   529 TBool CMPXDbPlaylistSongs::GetSongsL(
       
   530     TUint32 aPlaylistId,
       
   531     const TArray<TMPXAttribute>& aAttrs,
       
   532     CMPXMediaArray& aMediaArray)
       
   533     {
       
   534     MPX_DEBUG2("-->CMPXDbPlaylistSongs::GetSongsL(playlist 0x%x)", aPlaylistId);
       
   535     TBool valid(EFalse);
       
   536 
       
   537     RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(KQueryPlaylistSongsGetSongsInfo,
       
   538     		aPlaylistId));
       
   539     CleanupClosePushL(recordset);
       
   540 
       
   541     TInt err(KErrNone);
       
   542     while ((err = recordset.Next()) == KSqlAtRow)
       
   543         {
       
   544         CMPXMedia* media = CMPXMedia::NewL();
       
   545         CleanupStack::PushL(media);
       
   546 
       
   547         UpdateMediaL(recordset, aAttrs, *media);
       
   548 
       
   549         aMediaArray.AppendL(*media);
       
   550         CleanupStack::PopAndDestroy(media);
       
   551         }
       
   552     CleanupStack::PopAndDestroy(&recordset);
       
   553 
       
   554     if (err!= KSqlAtEnd)
       
   555         {
       
   556         User::Leave(KErrCorrupt);
       
   557         }
       
   558     else
       
   559     	{
       
   560     	valid = ETrue;
       
   561     	}
       
   562 
       
   563     MPX_DEBUG1("<--CMPXDbPlaylistSongs::GetSongsL");
       
   564     return valid;
       
   565     }
       
   566 
       
   567 // ----------------------------------------------------------------------------
       
   568 // CMPXDbPlaylistSongs::GetSongL
       
   569 // ----------------------------------------------------------------------------
       
   570 //
       
   571 TBool CMPXDbPlaylistSongs::GetSongL(
       
   572     TUint32 aPlaylistId,
       
   573     TUint32 aSongId,
       
   574     const TArray<TMPXAttribute>& aAttrs,
       
   575     CMPXMedia& aMedia)
       
   576     {
       
   577     MPX_FUNC("CMPXDbPlaylist::GetSongL");
       
   578 
       
   579     // get the song
       
   580     TBool valid(EFalse);
       
   581     RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(KQueryPlaylistSongsGetSong,
       
   582         aPlaylistId, aSongId));
       
   583     CleanupClosePushL(recordset);
       
   584 
       
   585     if (recordset.Next() == KSqlAtRow)
       
   586         {
       
   587         // convert to media
       
   588         UpdateMediaL(recordset, aAttrs, aMedia);
       
   589         valid = ETrue;
       
   590         }
       
   591 
       
   592     CleanupStack::PopAndDestroy(&recordset);
       
   593 
       
   594     return valid;
       
   595     }
       
   596 
       
   597 // ----------------------------------------------------------------------------
       
   598 // CMPXDbPlaylistSongs::GetSongL
       
   599 // ----------------------------------------------------------------------------
       
   600 //
       
   601 TBool CMPXDbPlaylistSongs::GetSongL(
       
   602     const TMPXItemId& aSongId,
       
   603     const TArray<TMPXAttribute>& aAttrs,
       
   604     CMPXMedia*& aMedia)
       
   605     {
       
   606     MPX_FUNC("CMPXDbPlaylist::GetSongL");
       
   607 
       
   608     // get the song
       
   609     TBool valid(EFalse);
       
   610     RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(KQueryPlaylistSongsGetSongInfo,
       
   611         aSongId.iId1, aSongId.iId2));
       
   612     CleanupClosePushL(recordset);
       
   613 
       
   614     if (recordset.Next() == KSqlAtRow)
       
   615         {
       
   616         // convert to media
       
   617         aMedia = CMPXMedia::NewL();
       
   618         CleanupStack::PushL(aMedia);
       
   619         UpdateMediaL(recordset, aAttrs, *aMedia);
       
   620         CleanupStack::Pop(aMedia);
       
   621         valid = ETrue;
       
   622         }
       
   623 
       
   624     CleanupStack::PopAndDestroy(&recordset);
       
   625 
       
   626     return valid;
       
   627     }
       
   628 
       
   629 // ----------------------------------------------------------------------------
       
   630 // CMPXDbPlaylistSongs::CountL
       
   631 // ----------------------------------------------------------------------------
       
   632 //
       
   633 TInt CMPXDbPlaylistSongs::CountL(
       
   634     TUint32 aPlaylistId)
       
   635     {
       
   636     MPX_FUNC("CMPXDbPlaylist::CountL");
       
   637     return ExecuteSumQueryL(KQueryPlaylistSongsCount, aPlaylistId);
       
   638     }
       
   639 
       
   640 // ----------------------------------------------------------------------------
       
   641 // CMPXDbPlaylistSongs::UpdateMediaL
       
   642 // ----------------------------------------------------------------------------
       
   643 //
       
   644 void CMPXDbPlaylistSongs::UpdateMediaL(
       
   645     RSqlStatement& aRecord,
       
   646     const TArray<TMPXAttribute>& aAttrs,
       
   647     CMPXMedia& aMedia)
       
   648     {
       
   649     MPX_FUNC("CMPXDbPlaylist::UpdateMediaL");
       
   650 
       
   651     aMedia.SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType, EMPXItem);
       
   652     aMedia.SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory, EMPXSong);
       
   653     aMedia.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, TMPXItemId(
       
   654         aRecord.ColumnInt64(EPlaylistSongsUniqueId),
       
   655         aRecord.ColumnInt64(EPlaylistSongsSongId)));
       
   656 
       
   657 /*
       
   658     aMedia.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId,
       
   659         aRecord.ColumnInt64(EPlaylistSongsSongId));
       
   660 */
       
   661     TInt count(aAttrs.Count());
       
   662     for (TInt index = 0; index < count; ++index)
       
   663         {
       
   664         TInt contentId(aAttrs[index].ContentId());
       
   665         TUint attributeId(aAttrs[index].AttributeId());
       
   666 
       
   667         if (contentId == KMPXMediaIdGeneral)
       
   668             {
       
   669             if (attributeId & EMPXMediaGeneralCollectionId)
       
   670                 {
       
   671                 aMedia.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralCollectionId,
       
   672                     aRecord.ColumnInt64(EPlaylistSongsPlaylistId));
       
   673                 }
       
   674             if (attributeId & EMPXMediaGeneralTitle)
       
   675                 {
       
   676                 TPtrC title(MPXDbCommonUtil::GetColumnTextL(aRecord, EPlaylistSongsTitle));
       
   677                 aMedia.SetTextValueL(KMPXMediaGeneralTitle, title);
       
   678                 MPX_DEBUG2("    Title[%S]", &title);
       
   679                 }
       
   680             if (attributeId & EMPXMediaGeneralUri)
       
   681                 {
       
   682                 TUint volId(aRecord.ColumnInt64(EPlaylistSongsVolumeId));
       
   683                 HBufC* uri = MPXDbCommonUtil::CreateFullPathL(
       
   684                     MPXDbCommonUtil::GetDriveIdMatchVolIdL(iDbManager.Fs(), volId),
       
   685                     MPXDbCommonUtil::GetColumnTextL(aRecord, EPlaylistSongsUri));
       
   686                 CleanupStack::PushL(uri);
       
   687 
       
   688                 aMedia.SetTextValueL(KMPXMediaGeneralUri, *uri);
       
   689 
       
   690                 MPX_DEBUG2("    URI[%S]", uri);
       
   691                 CleanupStack::PopAndDestroy(uri);
       
   692                 }
       
   693             if (attributeId & EMPXMediaGeneralFlags)
       
   694                 {
       
   695                 // assuming song details shouldn't be available for this song
       
   696                 TUint32 dbFlags(aRecord.ColumnInt64(EPlaylistSongsDbFlag) |
       
   697                                 KMPXMediaGeneralFlagsIsMissingDetails);
       
   698                 TUint32 volId(aRecord.ColumnInt64(EPlaylistSongsVolumeId));
       
   699                 TDriveUnit driveUnit(EDriveC);
       
   700                 if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
   701                     {
       
   702                     // ignore the return value
       
   703                     MPXDbCommonUtil::GetDriveL(aMedia.ValueText(KMPXMediaGeneralUri), driveUnit);
       
   704                     }
       
   705                 else
       
   706                     {
       
   707                     driveUnit = MPXDbCommonUtil::GetDriveIdMatchVolIdL(iDbManager.Fs(), volId);
       
   708                     }
       
   709 
       
   710                 // the volume the playlist song is located on may be removed
       
   711                 if (~dbFlags & KMPXMediaGeneralFlagsIsInvalid)
       
   712                     {
       
   713                     if (((volId != 0) && (MPXDbCommonUtil::GetDriveIdMatchVolIdL(iDbManager.Fs(), volId) == KErrNotFound)) ||
       
   714                         ((volId == 0) && (MPXDbCommonUtil::GetVolIdMatchDriveIdL(iDbManager.Fs(), driveUnit) == 0)))
       
   715                         {
       
   716                         dbFlags |= KMPXMediaGeneralFlagsIsInvalid;
       
   717                         }
       
   718                     }
       
   719 
       
   720                 TInt driveId(driveUnit & KMPXMediaGeneralFlagsDriveInfo);  // 5 bits
       
   721                 aMedia.SetTObjectValueL<TUint>(KMPXMediaGeneralFlags, dbFlags | driveId);
       
   722                 MPX_DEBUG2("    GeneralFlags[%b]", dbFlags | driveId);
       
   723                 }
       
   724             }
       
   725         }
       
   726     }
       
   727 
       
   728 // ----------------------------------------------------------------------------
       
   729 // CMPXDbPlaylistSongs::SongInstanceCountL
       
   730 // ----------------------------------------------------------------------------
       
   731 //
       
   732 TInt CMPXDbPlaylistSongs::SongInstanceCountL(
       
   733     TUint32 aPlaylistId,
       
   734     TUint32 aSongId)
       
   735     {
       
   736     MPX_FUNC("CMPXDbPlaylistSongs::SongInstanceCountL");
       
   737     return ExecuteSumQueryL(KQueryPlaylistSongsPlaylistSongCount, aPlaylistId, aSongId);
       
   738     }
       
   739 
       
   740 // ----------------------------------------------------------------------------
       
   741 // CMPXDbPlaylistSongs::SongCountL
       
   742 // ----------------------------------------------------------------------------
       
   743 //
       
   744 TInt CMPXDbPlaylistSongs::SongCountL(
       
   745     TUint32 aSongId)
       
   746     {
       
   747     MPX_FUNC("CMPXDbPlaylistSongs::SongCountL");
       
   748     return ExecuteSumQueryL(KQueryPlaylistSongsSongCount, aSongId);
       
   749     }
       
   750 
       
   751 // ----------------------------------------------------------------------------
       
   752 // CMPXDbPlaylistSongs::SongInfoExistsL
       
   753 // The song info record must be in the same database as the corresponding
       
   754 // PlaylistSongs record(s), otherwise when adding a duplicate of a song on a
       
   755 // different drive this method will return true and the song info record won't
       
   756 // be created.
       
   757 // ----------------------------------------------------------------------------
       
   758 //
       
   759 TBool CMPXDbPlaylistSongs::SongInfoExistsL(
       
   760     TInt aDriveId,
       
   761     TUint32 aSongId)
       
   762     {
       
   763     MPX_FUNC("CMPXDbPlaylistSongs::SongInfoExistsL");
       
   764 
       
   765     RSqlStatement recordset(
       
   766         iDbManager.ExecuteSelectQueryL(aDriveId, KQueryPlaylistSongInfoExists, aSongId));
       
   767     TBool exists(recordset.Next() == KSqlAtRow);
       
   768     recordset.Close();
       
   769     return exists;
       
   770     }
       
   771 
       
   772 // ----------------------------------------------------------------------------
       
   773 // CMPXDbPlaylistSongs::CleanupSongInfoL
       
   774 // ----------------------------------------------------------------------------
       
   775 //
       
   776 void CMPXDbPlaylistSongs::CleanupSongInfoL(
       
   777     TInt aDriveId)
       
   778     {
       
   779     MPX_FUNC("CMPXDbPlaylistSongs::CleanupSongInfoL");
       
   780     iDbManager.ExecuteQueryL(aDriveId, KQueryPlaylistSongInfoCleanup);
       
   781     }
       
   782 
       
   783 // ----------------------------------------------------------------------------
       
   784 // CMPXDbPlaylistSongs::CreateTableL
       
   785 // ----------------------------------------------------------------------------
       
   786 //
       
   787 void CMPXDbPlaylistSongs::CreateTableL(
       
   788     RSqlDatabase& aDatabase,
       
   789     TBool /* aCorruptTable */)
       
   790     {
       
   791     MPX_FUNC("CMPXDbPlaylistSongs::CreateTableL");
       
   792 
       
   793     // create the PlaylistSongs table
       
   794     User::LeaveIfError(aDatabase.Exec(KPlaylistSongsCreateTable));
       
   795 
       
   796     // create the PlaylistSongInfo table
       
   797     User::LeaveIfError(aDatabase.Exec(KPlaylistSongInfoCreateTable));
       
   798     }
       
   799 
       
   800 // ----------------------------------------------------------------------------
       
   801 // CMPXDbPlaylistSongs::DropTableL
       
   802 // ----------------------------------------------------------------------------
       
   803 //
       
   804 void CMPXDbPlaylistSongs::DropTableL(
       
   805     RSqlDatabase& aDatabase)
       
   806     {
       
   807     MPX_FUNC("CMPXDbPlaylistSongs::DropTableL");
       
   808 
       
   809     // drop the PlaylistSongs table
       
   810     User::LeaveIfError(aDatabase.Exec(KPlaylistSongsDropTable));
       
   811 
       
   812     // drop the PlaylistSongInfo table
       
   813     User::LeaveIfError(aDatabase.Exec(KPlaylistSongInfoDropTable));
       
   814     }
       
   815 
       
   816 // ----------------------------------------------------------------------------
       
   817 // CMPXDbPlaylistSongs::CheckTableL
       
   818 // ----------------------------------------------------------------------------
       
   819 //
       
   820 TBool CMPXDbPlaylistSongs::CheckTableL(
       
   821     RSqlDatabase& aDatabase)
       
   822     {
       
   823     MPX_FUNC("CMPXDbPlaylistSongs::CheckTableL");
       
   824 
       
   825     // check the PlaylistSongs table
       
   826     TBool check = DoCheckTable(aDatabase, KPlaylistSongsCheckTable);
       
   827 
       
   828     // check the PlaylistSongInfo table
       
   829     return check && DoCheckTable(aDatabase, KPlaylistSongInfoCheckTable);
       
   830     }
       
   831 
       
   832 // End of File