mpxplugins/serviceplugins/collectionplugins/mpxsqlitepodcastdbplugin/src/mpxdbcategory.cpp
changeset 0 ff3acec5bc43
child 18 c54d95799c80
equal deleted inserted replaced
-1:000000000000 0:ff3acec5bc43
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implements the base class for the various lookup tables
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <sqldb.h>
       
    21 
       
    22 #include <mpxmedia.h>
       
    23 #include <mpxmediaarray.h>
       
    24 #include <mpxmediageneraldefs.h>
       
    25 #include <mpxlog.h>
       
    26 
       
    27 #include "mpxdbcommonutil.h"
       
    28 #include "mpxdbcommondef.h"
       
    29 #include "mpxdbmanager.h"
       
    30 
       
    31 #include "mpxdbutil.h"
       
    32 #include "mpxpodcastcollectiondbdef.h"
       
    33 #include "mpxpodcastcollectiondbstd.h"
       
    34 #include "mpxpodcastdbpluginqueries.h"
       
    35 #include "mpxdbcategory.h"
       
    36 
       
    37 // CONSTANTS
       
    38 
       
    39 // maximum number of table name entries per query
       
    40 const TInt KMaxTableNameCount = 2;
       
    41 
       
    42 // ============================ MEMBER FUNCTIONS ==============================
       
    43 
       
    44 // ----------------------------------------------------------------------------
       
    45 // Two-phased constructor.
       
    46 // ----------------------------------------------------------------------------
       
    47 //
       
    48 CMPXDbCategory* CMPXDbCategory::NewL(
       
    49     CMPXDbManager& aDbManager,
       
    50     TMPXGeneralCategory aCategory)
       
    51     {
       
    52     MPX_FUNC("CMPXDbCategory::NewL");
       
    53 
       
    54     CMPXDbCategory* self = CMPXDbCategory::NewLC(aDbManager, aCategory);
       
    55     CleanupStack::Pop(self);
       
    56     return self;
       
    57     }
       
    58 
       
    59 // ----------------------------------------------------------------------------
       
    60 // Two-phased constructor, leave object in cleanup stack.
       
    61 // ----------------------------------------------------------------------------
       
    62 //
       
    63 CMPXDbCategory* CMPXDbCategory::NewLC(
       
    64     CMPXDbManager& aDbManager,
       
    65     TMPXGeneralCategory aCategory)
       
    66     {
       
    67     MPX_FUNC("CMPXDbCategory::NewLC");
       
    68 
       
    69     CMPXDbCategory* self = new (ELeave) CMPXDbCategory(aDbManager, aCategory);
       
    70     CleanupStack::PushL(self);
       
    71     self->ConstructL();
       
    72     return self;
       
    73     }
       
    74 
       
    75 // ----------------------------------------------------------------------------
       
    76 // Destructor.
       
    77 // ----------------------------------------------------------------------------
       
    78 //
       
    79 CMPXDbCategory::~CMPXDbCategory()
       
    80     {
       
    81     MPX_FUNC("CMPXDbCategory::~CMPXDbCategory");
       
    82     delete iTableName;
       
    83     }
       
    84 
       
    85 // ----------------------------------------------------------------------------
       
    86 // Constructor
       
    87 // ----------------------------------------------------------------------------
       
    88 //
       
    89 CMPXDbCategory::CMPXDbCategory(
       
    90     CMPXDbManager& aDbManager,
       
    91     TMPXGeneralCategory aCategory) :
       
    92     CMPXDbTable(aDbManager),
       
    93     iCategory(aCategory)
       
    94     {
       
    95     MPX_FUNC("CMPXDbCategory::CMPXDbCategory");
       
    96     }
       
    97 
       
    98 // ----------------------------------------------------------------------------
       
    99 // Symbian 2nd phase constructor can leave.
       
   100 // ----------------------------------------------------------------------------
       
   101 //
       
   102 void CMPXDbCategory::ConstructL()
       
   103     {
       
   104     MPX_FUNC("CMPXDbCategory::ConstructL");
       
   105 
       
   106     BaseConstructL();
       
   107     iTableName = MPXDbUtil::TableNameForCategoryL(iCategory).AllocL();
       
   108     }
       
   109 
       
   110 // ----------------------------------------------------------------------------
       
   111 // Add a row containing the name to the lookup table
       
   112 // If the name already exists in the table, increment the count
       
   113 // ----------------------------------------------------------------------------
       
   114 //
       
   115 TUint32 CMPXDbCategory::AddItemL(
       
   116     const TDesC& aName,
       
   117     TInt aDriveId,
       
   118     TBool& aNewRecord,
       
   119     TBool aCaseSensitive)
       
   120     {
       
   121     MPX_FUNC("CMPXDbCategory::AddItemL");
       
   122 
       
   123     // try to find the item first
       
   124     TUint32 rowId(MPXDbCommonUtil::GenerateUniqueIdL(iDbManager.Fs(), iCategory, aName, aCaseSensitive));
       
   125     aNewRecord = !CategoryItemExistsL(aDriveId, rowId);
       
   126 
       
   127     if (aNewRecord)
       
   128         {
       
   129         // insert new
       
   130         HBufC* query = PreProcessStringLC(KQueryCategoryInsert);
       
   131         HBufC* name = MPXDbCommonUtil::ProcessSingleQuotesLC(aName);
       
   132 
       
   133         iDbManager.ExecuteQueryL(aDriveId, *query, rowId, name, 1);
       
   134 
       
   135         CleanupStack::PopAndDestroy(name);
       
   136         CleanupStack::PopAndDestroy(query);
       
   137         }
       
   138     else
       
   139         {
       
   140         // increment the number of episodes for the category
       
   141         HBufC* query = PreProcessStringLC(KQueryCategoryIncrementEpisodeCount);
       
   142         iDbManager.ExecuteQueryL(aDriveId, *query, rowId);
       
   143         CleanupStack::PopAndDestroy(query);
       
   144         }
       
   145 
       
   146     return rowId;
       
   147     }
       
   148 
       
   149 // ----------------------------------------------------------------------------
       
   150 // Get the name of the row matching the given ID
       
   151 // ----------------------------------------------------------------------------
       
   152 //
       
   153 HBufC* CMPXDbCategory::GetNameL(
       
   154     TUint32 aId)
       
   155     {
       
   156     MPX_FUNC("CMPXDbCategory::GetNameL");
       
   157 
       
   158     RSqlStatement recordset(GetCategoryRecordL(aId));
       
   159     CleanupClosePushL(recordset);
       
   160 
       
   161     if (recordset.Next() != KSqlAtRow)
       
   162         {
       
   163         User::LeaveIfError(KErrNotFound);
       
   164         }
       
   165 
       
   166     HBufC* name = MPXDbCommonUtil::GetColumnTextL(recordset, ECategoryName).AllocL();
       
   167     CleanupStack::PopAndDestroy(&recordset);
       
   168 
       
   169     return name;
       
   170     }
       
   171 
       
   172 // ----------------------------------------------------------------------------
       
   173 // Count the total number of items
       
   174 // ----------------------------------------------------------------------------
       
   175 //
       
   176 TInt CMPXDbCategory::CountL()
       
   177     {
       
   178     MPX_FUNC("CMPXDbCategory::CountL");
       
   179 
       
   180     HBufC* query = PreProcessStringLC(KQueryCategoryCount);
       
   181     TInt count(ExecuteSumQueryL(*query));
       
   182     CleanupStack::PopAndDestroy(query);
       
   183 
       
   184     return count;
       
   185     }
       
   186 
       
   187 // ----------------------------------------------------------------------------
       
   188 // Find record(s) that match(es) the selection criteria
       
   189 // ----------------------------------------------------------------------------
       
   190 //
       
   191 void CMPXDbCategory::FindAllL(
       
   192     const CMPXMedia& aCriteria,
       
   193     const TArray<TMPXAttribute>& aAttrs,
       
   194     CMPXMediaArray& aMediaArray)
       
   195     {
       
   196     MPX_FUNC("CMPXDbCollection::FindAllL");
       
   197 
       
   198     // process the requested attributes
       
   199     // the UniqueId is always requested
       
   200     TBool titleRequested(EFalse);
       
   201     TBool counterRequested(EFalse);
       
   202 
       
   203     TInt viewingColumnCount(aAttrs.Count());
       
   204     for (TInt i = 0; i < viewingColumnCount; ++i)
       
   205         {
       
   206         TInt contentId(aAttrs[i].ContentId());
       
   207 
       
   208         if (contentId == KMPXMediaIdGeneral)
       
   209             {
       
   210             TUint attributeId(aAttrs[i].AttributeId());
       
   211 
       
   212             if (attributeId & EMPXMediaGeneralTitle)
       
   213                 {
       
   214                 titleRequested = ETrue;
       
   215                 }
       
   216             if (attributeId & EMPXMediaGeneralCount)
       
   217                 {
       
   218                 counterRequested = ETrue;
       
   219                 }
       
   220             }
       
   221         }
       
   222 
       
   223     TMPXGeneralType type = aCriteria.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
       
   224 
       
   225     const TArray<TMPXAttribute> criteria = aCriteria.Attributes();
       
   226     TInt criteriaCount(criteria.Count());
       
   227 
       
   228     // process the criteria and construct the criteria string
       
   229     CDesCArrayFlat* criteriaArray = new (ELeave) CDesCArrayFlat(criteriaCount + 1);
       
   230     CleanupStack::PushL(criteriaArray);
       
   231 
       
   232     TBool criteriaCounterSet(EFalse);
       
   233     TInt criteriaCounter(0);
       
   234     for (TInt i = 0; i < criteriaCount; ++i)
       
   235         {
       
   236         const TMPXAttribute& criterion = criteria[i];
       
   237         if ((type == EMPXItem) && (criterion == KMPXMediaGeneralId))
       
   238             {
       
   239             TUint32 itemId = (aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
       
   240             if (MPX_ITEM_CATEGORY(itemId) != iCategory)
       
   241                 {
       
   242                 User::Leave(KErrNotSupported);
       
   243                 }
       
   244 
       
   245             HBufC* critStr = PreProcessStringLC(KCriterionCategoryUniqueId);
       
   246             MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, *critStr, itemId);
       
   247             CleanupStack::PopAndDestroy(critStr);
       
   248             }
       
   249         else if (criterion == KMPXMediaGeneralTitle)
       
   250             {
       
   251             HBufC* critStr = PreProcessStringLC(KCriterionCategoryName);
       
   252             HBufC* title = MPXDbCommonUtil::ProcessPatternCharsLC(
       
   253                 aCriteria.ValueText(KMPXMediaGeneralTitle));
       
   254             MPXDbCommonUtil::AddSqlCriterionL(*criteriaArray, *critStr, *title);
       
   255             CleanupStack::PopAndDestroy(2, critStr); // title & Str
       
   256             }
       
   257         else if (criterion == KMPXMediaGeneralCount)
       
   258             {
       
   259             criteriaCounterSet = ETrue;
       
   260             criteriaCounter = aCriteria.ValueTObjectL<TInt>(KMPXMediaGeneralCount);
       
   261             }
       
   262         else
       
   263             {
       
   264             // ignore attribute
       
   265             }
       
   266         }
       
   267 
       
   268     // construct criteria string
       
   269     HBufC* criteriaStr = MPXDbCommonUtil::StringFromArrayLC(*criteriaArray, KMCAndKeyword);
       
   270 
       
   271     // either get all items or items filtered based on criteria
       
   272     HBufC* query = PreProcessStringLC(criteriaStr->Length() ?
       
   273         KQueryCategoryItems() : KQueryCategoryAll());
       
   274     RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(*query, criteriaStr));
       
   275 
       
   276     CleanupStack::PopAndDestroy(query);
       
   277     CleanupStack::PopAndDestroy(criteriaStr);
       
   278     CleanupStack::PopAndDestroy(criteriaArray);
       
   279 
       
   280     CleanupClosePushL(recordset);
       
   281 
       
   282     // It is possible to get multiple records with the same ID in the case where the same category
       
   283     // name is present on more than one drive (the unique ID is constructed from the name alone
       
   284     // for categories). The records have to be processed manually as the songs count cannot be
       
   285     // summed in the query.
       
   286     //
       
   287     // Unknown artist/album/genre/composer is stored in the database as NULL (name field). This
       
   288     // ensures the unknown artist/album/genre/composer to be the 1st found record if it exists.
       
   289     // This will save time in searching for the unknown record among the results and avoid
       
   290     // performing descriptor comparison.
       
   291     // If the 1st record is the unknown artist/album/genre/composer, it won't be appended to the
       
   292     // array until all other records have been put in the array.
       
   293     //
       
   294     // NOTE: putting unknown artist/album/genre/composer to the end of the array only takes place
       
   295     //       when title field is requested. normal sorting algorithm occurs if title isn't requested,
       
   296     //       i.e. client requests for Id only. The Id of the unknown record will be the 1st item in
       
   297     //       the array if it exists.
       
   298     //
       
   299     TBool firstGroup(ETrue);
       
   300     CMPXMedia* unknownMedia(NULL);
       
   301     CMPXMedia* media(NULL);
       
   302     TUint32 prevId(0);
       
   303     TUint32 currId(0);
       
   304     TUint32 accumulatedCounter(0);
       
   305     TInt err(KErrNone);
       
   306 
       
   307     while ((err = recordset.Next()) == KSqlAtRow)
       
   308         {
       
   309         // Setup basic info - with first record of a group
       
   310         currId = recordset.ColumnInt64(ECategoryUniqueId);
       
   311 
       
   312         if (currId != prevId)
       
   313             {
       
   314             // first or new set of records
       
   315             if (media)
       
   316                 {
       
   317                 // valid previous record set
       
   318                 if (criteriaCounterSet && (criteriaCounter != accumulatedCounter))
       
   319                     {
       
   320                     // the counter criterion does not match
       
   321                     // discard the media and unknownMedia
       
   322                     CleanupStack::PopAndDestroy(media);
       
   323                     if (firstGroup && unknownMedia)
       
   324                         {
       
   325                         unknownMedia = NULL;
       
   326                         }
       
   327                     }
       
   328                 else
       
   329                     {
       
   330                     if (!firstGroup || !unknownMedia)
       
   331                         {
       
   332                         // append the media to the array
       
   333                         if (counterRequested)
       
   334                             {
       
   335                             media->SetTObjectValueL<TInt>(KMPXMediaGeneralCount, accumulatedCounter);
       
   336                             }
       
   337 
       
   338                         aMediaArray.AppendL(*media);
       
   339                         CleanupStack::PopAndDestroy(media);
       
   340                         }
       
   341 
       
   342                     firstGroup = EFalse;
       
   343                     }
       
   344                 }
       
   345 
       
   346             // start a new media object
       
   347             media = CMPXMedia::NewL();
       
   348             CleanupStack::PushL(media);
       
   349 
       
   350             media->SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType, EMPXItem);
       
   351             media->SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory, iCategory);
       
   352             media->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, currId);
       
   353 
       
   354             if (titleRequested)
       
   355                 {
       
   356                 TPtrC name = MPXDbCommonUtil::GetColumnTextL(recordset, ECategoryName);
       
   357                 if (firstGroup && (name.Length() == 0))
       
   358                     {
       
   359                     unknownMedia = media;
       
   360                     }
       
   361                 media->SetTextValueL(KMPXMediaGeneralTitle, name);
       
   362                 }
       
   363 
       
   364             accumulatedCounter = 0;
       
   365             prevId = currId;
       
   366             }
       
   367 
       
   368         accumulatedCounter += GetEpisodeCountL(KDbManagerAllDrives, currId);
       
   369         }
       
   370 
       
   371     // process last record
       
   372     if (media)
       
   373         {
       
   374         // valid previous record set
       
   375         if (criteriaCounterSet && (criteriaCounter != accumulatedCounter))
       
   376             {
       
   377             // the counter criterion does not match
       
   378             // discard the media and unknownMedia
       
   379             CleanupStack::PopAndDestroy(media);
       
   380             if (firstGroup && unknownMedia)
       
   381                 {
       
   382                 unknownMedia = NULL;
       
   383                 }
       
   384             }
       
   385         else
       
   386             {
       
   387             if (!firstGroup || !unknownMedia)
       
   388                 {
       
   389                 // append the media to the array
       
   390                 if (counterRequested)
       
   391                     {
       
   392                     media->SetTObjectValueL<TInt>(KMPXMediaGeneralCount, accumulatedCounter);
       
   393                     }
       
   394 
       
   395                 aMediaArray.AppendL(*media);
       
   396                 CleanupStack::PopAndDestroy(media);
       
   397                 }
       
   398             }
       
   399         }
       
   400 
       
   401     if (unknownMedia)
       
   402         {
       
   403         aMediaArray.AppendL(*unknownMedia);
       
   404         CleanupStack::PopAndDestroy(unknownMedia); // the first media that contains unknown title
       
   405         }
       
   406 
       
   407     CleanupStack::PopAndDestroy(&recordset);
       
   408 
       
   409     if (err != KSqlAtEnd)
       
   410         {
       
   411         User::LeaveIfError(err);
       
   412         }
       
   413     }
       
   414 
       
   415 // ----------------------------------------------------------------------------
       
   416 // Decrement the number of episodes in the row. If the count gets to 0, remove the row.
       
   417 // ----------------------------------------------------------------------------
       
   418 //
       
   419 void CMPXDbCategory::DecrementEpisodesForCategoryL(
       
   420     const TUint32 aId,
       
   421     TInt aDriveId,
       
   422     CMPXMessageArray* aItemChangedMessages)
       
   423     {
       
   424     MPX_FUNC("CMPXDbCategory::DecrementEpisodesForCategoryL");
       
   425 
       
   426     // if just one episode uses this category, use <= just in case
       
   427     if (GetEpisodeCountL(aDriveId, aId) <= 1)
       
   428         {
       
   429         // delete the category
       
   430         DeleteCategoryL(aId, aDriveId);
       
   431 
       
   432         if (aItemChangedMessages)
       
   433             {
       
   434             // add the item changed message
       
   435             MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, aId, EMPXItemDeleted,
       
   436                 iCategory, KDBPluginUid);
       
   437             }
       
   438         }
       
   439     else
       
   440         {
       
   441         // decrement the number of episodes for the category
       
   442         HBufC* query = PreProcessStringLC(KQueryCategoryDecrementEpisodeCount);
       
   443         iDbManager.ExecuteQueryL(aDriveId, *query, aId);
       
   444         CleanupStack::PopAndDestroy(query);
       
   445         }
       
   446     }
       
   447 
       
   448 // ----------------------------------------------------------------------------
       
   449 // CMPXDbCategory::DeleteCategoryL
       
   450 // ----------------------------------------------------------------------------
       
   451 //
       
   452 void CMPXDbCategory::DeleteCategoryL(
       
   453     TUint32 aId,
       
   454     TInt aDriveId)
       
   455     {
       
   456     MPX_FUNC("CMPXDbCategory::DeleteCategoryL");
       
   457 
       
   458     HBufC* query = PreProcessStringLC(KQueryCategoryDelete);
       
   459     iDbManager.ExecuteQueryL(aDriveId, *query, aId);
       
   460     CleanupStack::PopAndDestroy(query);
       
   461     }
       
   462 
       
   463 // ----------------------------------------------------------------------------
       
   464 // CMPXDbCategory::GetCategoryItemL
       
   465 // ----------------------------------------------------------------------------
       
   466 //
       
   467 void CMPXDbCategory::GetCategoryItemL(
       
   468     TUint32 aId,
       
   469     const TArray<TMPXAttribute>& aAttrs,
       
   470     CMPXMedia& aMedia)
       
   471     {
       
   472     MPX_FUNC("CMPXDbCategory::GetCategoryItemL");
       
   473 
       
   474     HBufC* query = PreProcessStringLC(KQueryCategoryItem);
       
   475     ExecuteMediaQueryL(aAttrs, aMedia, *query, aId);
       
   476     CleanupStack::PopAndDestroy(query);
       
   477     }
       
   478 
       
   479 // ----------------------------------------------------------------------------
       
   480 // CMPXDbCategory::GetCategoryItemsL
       
   481 // ----------------------------------------------------------------------------
       
   482 //
       
   483 void CMPXDbCategory::GetCategoryItemsL(
       
   484     const TArray<TMPXAttribute>& aAttrs,
       
   485     CMPXMediaArray& aMediaArray)
       
   486     {
       
   487     MPX_FUNC("CMPXDbCategory::GetCategoryItemsL");
       
   488 
       
   489     // have to run one query to get all items as opposed to individual queries
       
   490     // because of the sorting
       
   491 
       
   492     // construct the unique ID criteria string
       
   493     // (UniqueId = %u OR UniqueId = %u ...)
       
   494     TInt itemCount(aMediaArray.Count());
       
   495     HBufC* criteria = HBufC::NewLC((2 * KCriterionCategoryUniqueId().Length() +
       
   496         KMCIntegerLen + KMCOrKeyword().Length() + 2) * itemCount);
       
   497     TPtr ptr(criteria->Des());
       
   498     ptr.Append(KMCOpenBracket);
       
   499     for (TInt index = 0; index < itemCount; ++index)
       
   500         {
       
   501         CMPXMedia* media = aMediaArray[index];
       
   502 
       
   503         HBufC* critStr = PreProcessStringLC(KCriterionCategoryUniqueId);
       
   504         HBufC* criterion = MPXDbCommonUtil::SqlCriterionLC(*critStr,
       
   505             media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
       
   506         ptr.Append(*criterion);
       
   507         CleanupStack::PopAndDestroy(criterion);
       
   508         CleanupStack::PopAndDestroy(critStr);
       
   509 
       
   510         if (index < itemCount - 1)
       
   511             {
       
   512             ptr.Append(KMCOrKeyword);
       
   513             }
       
   514         }
       
   515     ptr.Append(KMCCloseBracket);
       
   516 
       
   517     // the array has to be reset as the items have to be returned in a different sort order
       
   518     aMediaArray.Reset();
       
   519 
       
   520     HBufC* query = PreProcessStringLC(KQueryCategoryItems);
       
   521     RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(*query, criteria));
       
   522 
       
   523     CleanupStack::PopAndDestroy(query);
       
   524     CleanupStack::PopAndDestroy(criteria);
       
   525 
       
   526     CleanupClosePushL(recordset);
       
   527     ProcessRecordsetL(aAttrs, recordset, aMediaArray);
       
   528     CleanupStack::PopAndDestroy(&recordset);
       
   529     }
       
   530 
       
   531 // ----------------------------------------------------------------------------
       
   532 // CMPXDbCategory::GetAllCategoryItemsL
       
   533 // ----------------------------------------------------------------------------
       
   534 //
       
   535 void CMPXDbCategory::GetAllCategoryItemsL(
       
   536     const TArray<TMPXAttribute>& aAttrs,
       
   537     CMPXMediaArray& aMediaArray)
       
   538     {
       
   539     MPX_FUNC("CMPXDbCategory::GetAllCategoryItemsL");
       
   540 
       
   541     HBufC* query = PreProcessStringLC(KQueryCategoryAll);
       
   542     RSqlStatement recordset(iDbManager.ExecuteSelectQueryL(*query));
       
   543     CleanupStack::PopAndDestroy(query);
       
   544 
       
   545     CleanupClosePushL(recordset);
       
   546     ProcessRecordsetL(aAttrs, recordset, aMediaArray);
       
   547     CleanupStack::PopAndDestroy(&recordset);
       
   548     }
       
   549 
       
   550 // ----------------------------------------------------------------------------
       
   551 // CMPXDbCategory::CategoryItemExistsL
       
   552 // The category records must be in the same database as the corresponding
       
   553 // Podcast record, otherwise when adding a duplicate of a song on a
       
   554 // different drive this method will return true and the category record won't
       
   555 // be created.
       
   556 // ----------------------------------------------------------------------------
       
   557 //
       
   558 TBool CMPXDbCategory::CategoryItemExistsL(
       
   559     TInt aDriveId,
       
   560     TUint32 aId)
       
   561     {
       
   562     MPX_FUNC("CMPXDbCategory::CategoryItemExistsL");
       
   563 
       
   564     HBufC* query = PreProcessStringLC(KQueryCategoryItem);
       
   565     RSqlStatement recordset(
       
   566         iDbManager.ExecuteSelectQueryL(aDriveId, *query, aId));
       
   567 
       
   568     TBool exists(recordset.Next() == KSqlAtRow);
       
   569 
       
   570     recordset.Close();
       
   571     CleanupStack::PopAndDestroy(query);
       
   572 
       
   573     return exists;
       
   574     }
       
   575 
       
   576 // ----------------------------------------------------------------------------
       
   577 // CMPXDbCategory::GetSongsCountL
       
   578 // ----------------------------------------------------------------------------
       
   579 //
       
   580 TInt CMPXDbCategory::GetEpisodeCountL(
       
   581     TInt aDriveId,
       
   582     TUint32 aId)
       
   583     {
       
   584     MPX_FUNC("CMPXDbCategory::GetEpisodeCountL");
       
   585 
       
   586     HBufC* query = PreProcessStringLC(KQueryCategoryGetEpisodeCount);
       
   587     RSqlStatement recordset(
       
   588         iDbManager.ExecuteSelectQueryL(aDriveId, *query, aId));
       
   589     CleanupClosePushL(recordset);
       
   590 
       
   591     if (recordset.Next() != KSqlAtRow)
       
   592         {
       
   593         User::Leave(KErrNotFound);
       
   594         }
       
   595 
       
   596     TInt ret = recordset.ColumnInt(KMPXTableDefaultIndex);
       
   597 
       
   598     CleanupStack::PopAndDestroy(&recordset);
       
   599     CleanupStack::PopAndDestroy(query);
       
   600 
       
   601     return ret;
       
   602     }
       
   603 
       
   604 // ----------------------------------------------------------------------------
       
   605 // CMPXDbCategory::UpdateMediaL
       
   606 // ----------------------------------------------------------------------------
       
   607 //
       
   608 void CMPXDbCategory::UpdateMediaL(
       
   609     RSqlStatement& aRecord,
       
   610     const TArray<TMPXAttribute>& aAttrs,
       
   611     CMPXMedia& aMedia)
       
   612     {
       
   613     MPX_FUNC("CMPXDbCategory::UpdateMediaL");
       
   614 
       
   615     TInt attrCount(aAttrs.Count());
       
   616     for (TInt i = 0; i < attrCount; ++i)
       
   617         {
       
   618         TInt contentId(aAttrs[i].ContentId());
       
   619         TUint attributeId(aAttrs[i].AttributeId());
       
   620 
       
   621         if (contentId == KMPXMediaIdGeneral)
       
   622             {
       
   623             if (attributeId & EMPXMediaGeneralId)
       
   624                 {
       
   625                 aMedia.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId,
       
   626                     aRecord.ColumnInt64(ECategoryUniqueId));
       
   627                 }
       
   628             if (attributeId & EMPXMediaGeneralTitle)
       
   629                 {
       
   630                 aMedia.SetTextValueL(KMPXMediaGeneralTitle,
       
   631                     MPXDbCommonUtil::GetColumnTextL(aRecord, ECategoryName));
       
   632                 }
       
   633             if (attributeId & EMPXMediaGeneralCount)
       
   634                 {
       
   635                 aMedia.SetTObjectValueL<TInt>(KMPXMediaGeneralCount,
       
   636                     GetEpisodeCountL(KDbManagerAllDrives,
       
   637                     aRecord.ColumnInt64(ECategoryUniqueId)));
       
   638                 }
       
   639             } // end if contentId == KMPXMediaIdGeneral
       
   640         } // end for
       
   641 
       
   642     aMedia.SetTObjectValueL(KMPXMediaGeneralType, EMPXItem);
       
   643     aMedia.SetTObjectValueL(KMPXMediaGeneralCategory, iCategory);
       
   644     // Fix for EXAL-79ZC9M set the right Type and Cat for each item
       
   645     if (iCategory == EMPXAlbum)
       
   646         {
       
   647         aMedia.SetTObjectValueL(KMPXMediaPodcastType, EMPXPodcastGroup);
       
   648         aMedia.SetTObjectValueL(KMPXMediaPodcastCategoryGroup, EMPXTitle);
       
   649         }
       
   650     }
       
   651 
       
   652 // ----------------------------------------------------------------------------
       
   653 // CMPXDbCategory::GetCategoryRecordL
       
   654 // ----------------------------------------------------------------------------
       
   655 //
       
   656 RSqlStatement CMPXDbCategory::GetCategoryRecordL(
       
   657     TUint32 aId)
       
   658     {
       
   659     MPX_FUNC("CMPXDbCategory::GetCategoryRecordL");
       
   660 
       
   661     HBufC* query = PreProcessStringLC(KQueryCategoryItem);
       
   662     RSqlStatement statement(iDbManager.ExecuteSelectQueryL(*query, aId));
       
   663     CleanupStack::PopAndDestroy(query);
       
   664 
       
   665     return statement;
       
   666     }
       
   667 
       
   668 // ----------------------------------------------------------------------------
       
   669 // CMPXDbCategory::PreProcessStringLC
       
   670 // ----------------------------------------------------------------------------
       
   671 //
       
   672 HBufC* CMPXDbCategory::PreProcessStringLC(
       
   673     const TDesC& aQuery)
       
   674     {
       
   675     MPX_FUNC("CMPXDbCategory::PreProcessStringLC");
       
   676 
       
   677     HBufC* query = HBufC::NewLC(aQuery.Length() + KMaxTableNameCount *
       
   678         (iTableName->Length() + KCategoryTablePlaceholder().Length()));
       
   679     TPtr queryPtr(query->Des());
       
   680 
       
   681     // copy the query string
       
   682     queryPtr = aQuery;
       
   683 
       
   684     // replace all instances of the placeholder with the actual table name
       
   685     TInt index(0);
       
   686     while ((index = queryPtr.Find(KCategoryTablePlaceholder)) != KErrNotFound)
       
   687         {
       
   688         queryPtr.Replace(index, KCategoryTablePlaceholder().Length(), *iTableName);
       
   689         }
       
   690 
       
   691     return query;
       
   692     }
       
   693 
       
   694 // ----------------------------------------------------------------------------
       
   695 // CMPXDbCategory::ProcessRecordsetL
       
   696 // Unknown item is stored in the database as NULL (name field). This ensures the
       
   697 // unknown item to be the 1st found record if it exists. This will save time in
       
   698 // searching for the unknown record among the results and avoid performing
       
   699 // descriptor comparison. If the 1st record is the unknown item, it won't be
       
   700 // appended to the array until all other records have been put in the array.
       
   701 //
       
   702 // NOTE: putting unknown item to the end of the array only takes place when title
       
   703 //       field is requested. normal sorting algorithm occurs if title isn't
       
   704 //       requested.
       
   705 // ----------------------------------------------------------------------------
       
   706 //
       
   707 void CMPXDbCategory::ProcessRecordsetL(
       
   708     const TArray<TMPXAttribute>& aAttrs,
       
   709     RSqlStatement& aRecordset,
       
   710     CMPXMediaArray& aMediaArray)
       
   711     {
       
   712     MPX_FUNC("CMPXDbCategory::ProcessRecordsetL");
       
   713 
       
   714     // populate the array
       
   715     TBool firstRecord(ETrue);
       
   716     CMPXMedia* unknownMedia(NULL);
       
   717     TInt prevId(0);
       
   718     TInt err(KErrNone);
       
   719 
       
   720     while ((err = aRecordset.Next()) == KSqlAtRow)
       
   721         {
       
   722         TUint32 rowId(aRecordset.ColumnInt64(ECategoryUniqueId));
       
   723         if (prevId == rowId)
       
   724             {
       
   725             continue;
       
   726             }
       
   727 
       
   728         prevId = rowId;
       
   729         CMPXMedia* media = CMPXMedia::NewL();
       
   730         CleanupStack::PushL(media);
       
   731 
       
   732         UpdateMediaL(aRecordset, aAttrs, *media);
       
   733 
       
   734         if (firstRecord && (MPXDbCommonUtil::GetColumnTextL(aRecordset, ECategoryName).Length() == 0))
       
   735             {
       
   736             unknownMedia = media;
       
   737             }
       
   738 
       
   739         if (!firstRecord || !unknownMedia)
       
   740             {
       
   741             aMediaArray.AppendL(*media);
       
   742             CleanupStack::PopAndDestroy(media);
       
   743             }
       
   744 
       
   745         firstRecord = EFalse;
       
   746         } // end while
       
   747 
       
   748     if (err != KSqlAtEnd)
       
   749         {
       
   750         User::LeaveIfError(err);
       
   751         }
       
   752 
       
   753     if (unknownMedia)
       
   754         {
       
   755         aMediaArray.AppendL(*unknownMedia);
       
   756         CleanupStack::PopAndDestroy(unknownMedia);
       
   757         }
       
   758     }
       
   759 
       
   760 // ----------------------------------------------------------------------------
       
   761 // CMPXDbCategory::CreateTableL
       
   762 // ----------------------------------------------------------------------------
       
   763 //
       
   764 void CMPXDbCategory::CreateTableL(
       
   765     RSqlDatabase& aDatabase,
       
   766     TBool /* aCorruptTable */)
       
   767     {
       
   768     MPX_FUNC("CMPXDbCategory::CreateTableL");
       
   769 
       
   770     // create the table
       
   771     HBufC* query = PreProcessStringLC(KCategoryCreateTable);
       
   772     User::LeaveIfError(aDatabase.Exec(*query));
       
   773     CleanupStack::PopAndDestroy(query);
       
   774 
       
   775     // create the Name index
       
   776     query = PreProcessStringLC(KCategoryNameIndex);
       
   777     User::LeaveIfError(aDatabase.Exec(*query));
       
   778     CleanupStack::PopAndDestroy(query);
       
   779     }
       
   780 
       
   781 // ----------------------------------------------------------------------------
       
   782 // CMPXDbCategory::DropTableL
       
   783 // ----------------------------------------------------------------------------
       
   784 //
       
   785 void CMPXDbCategory::DropTableL(
       
   786     RSqlDatabase& aDatabase)
       
   787     {
       
   788     MPX_FUNC("CMPXDbCategory::DropTableL");
       
   789 
       
   790     HBufC* query = PreProcessStringLC(KCategoryDropTable);
       
   791     User::LeaveIfError(aDatabase.Exec(*query));
       
   792     CleanupStack::PopAndDestroy(query);
       
   793     }
       
   794 
       
   795 // ----------------------------------------------------------------------------
       
   796 // CMPXDbCategory::CheckTableL
       
   797 // ----------------------------------------------------------------------------
       
   798 //
       
   799 TBool CMPXDbCategory::CheckTableL(
       
   800     RSqlDatabase& aDatabase)
       
   801     {
       
   802     MPX_FUNC("CMPXDbCategory::CheckTableL");
       
   803 
       
   804     HBufC* query = PreProcessStringLC(KCategoryCheckTable);
       
   805     TBool check(DoCheckTable(aDatabase, *query));
       
   806     CleanupStack::PopAndDestroy(query);
       
   807 
       
   808     return check;
       
   809     }
       
   810 
       
   811 // End of File