browserutilities/feedsengine/FeedsServer/Server/src/FeedsDatabase.cpp
changeset 0 dd21522fd290
child 8 7c90e6132015
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2005 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 the License "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:  The feeds server database.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <badesca.h>
       
    20 #include <e32math.h>
       
    21 
       
    22 #include "FeedAttributes.h"
       
    23 #include "FeedsDatabase.h"
       
    24 #include "FolderAttributes.h"
       
    25 #include "PackedAttributes.h"
       
    26 #include "LeakTracker.h"
       
    27 #include "Logger.h"
       
    28 #include "PackedFeed.h"
       
    29 #include "PackedFolder.h"
       
    30 #include "FeedsServer.h"
       
    31 
       
    32 // Constants
       
    33 // Database file name.
       
    34 const TUid KSecureUid = {0x10281F95};
       
    35 _LIT(KSecure,	"SECURE");
       
    36 _LIT(KDatabaseFileName, "FeedsDatabase");
       
    37 _LIT(KDbExtension, ".db");    
       
    38 
       
    39 // Table names.
       
    40 _LIT(KVersionTable, "VersionTable");
       
    41 _LIT(KFolderListTable, "FolderListTable");
       
    42 _LIT(KFeedTable, "FeedTable");
       
    43 _LIT(KItemTable, "ItemTable");
       
    44 _LIT(KEnclosureTable, "EnclosureTable");
       
    45 _LIT(KSettingsTable, "SettingsTable");
       
    46 
       
    47 // Table index names.
       
    48 _LIT(KFolderListTableIndex, "FolderListTableIndex");
       
    49 _LIT(KFeedTableIndex, "FeedTableIndex");
       
    50 _LIT(KItemTableIndex, "ItemTableIndex");
       
    51 _LIT(KEnclosureTableIndex, "EnclosureTableIndex");
       
    52 _LIT(KSettingsTableIndex, "SettingsTableIndex");
       
    53 
       
    54 // Table field names.
       
    55 _LIT(KFolderListId, "FolderListId");
       
    56 _LIT(KFolderItemId, "FolderItemId");
       
    57 _LIT(KIsFolder, "IsFolder");
       
    58 _LIT(KItemId, "ItemId");
       
    59 _LIT(KParentId, "ParentId");
       
    60 _LIT(KSiblingOrder, "SiblingOrder");
       
    61 _LIT(KStatus,"Status");
       
    62 _LIT(KVersion, "Version");
       
    63 _LIT(KVersionId, "VersionID");
       
    64 _LIT(KTitle_100MaxLen, "Title");
       
    65 _LIT(KFeedId, "FeedId");
       
    66 _LIT(KDate, "Date");
       
    67 _LIT(KFeedUrl, "FeedUrl");
       
    68 _LIT(KWebUrl, "WebUrl");
       
    69 _LIT(KDescription, "Description");
       
    70 _LIT(KItemStatus, "ItemStatus");
       
    71 _LIT(KEnclosureId, "EnclosureId");
       
    72 _LIT(KLength_100MaxLen, "Length");
       
    73 _LIT(KContentType_100MaxLen, "ContentType");
       
    74 _LIT(KItemIdStr, "ItemIdStr");
       
    75 _LIT(KUnreadCount, "UnreadCount");
       
    76 _LIT(KAccessPoint, "AccessPoint");
       
    77 _LIT(KAutoUpdate, "AutoUpdate");
       
    78 _LIT(KAutoUpdateWhileRoaming, "AutoUpdateWhileRoaming");
       
    79 _LIT(KAutoUpdateFreq, "AutoUpdateFreq");
       
    80 _LIT(KLastAutoUpdate, "LastAutoUpdate");
       
    81 
       
    82 // Misc string consts.
       
    83 _LIT(KSpace, " ");
       
    84 _LIT(KNew, "new");
       
    85 _LIT(KUnread, "unread");
       
    86 _LIT(KRead, "read");
       
    87 
       
    88 // Root folder related.
       
    89 const TInt  KRootFolderId = 0;
       
    90 _LIT(KRootFolder, "Root Folder");
       
    91 
       
    92 // Misc consts.
       
    93 const TInt K100MaxLen = 100;
       
    94 const TInt KIntLength = 15;
       
    95 const TInt KInt64Length = 25;
       
    96 const TInt KVersion31 = 1;
       
    97 //const TInt KVersion32 = 2;
       
    98 const TInt KVersion50 = 3;
       
    99 const TInt KVersion71 = 4;
       
   100 
       
   101 const TInt KResvSpaceForDupTitles = 6; //Space should be left in feed/folder title to append number in case of duplicate titles.
       
   102 const TInt KAutoUpdatingOff = 0;
       
   103 
       
   104 // DATA TYPES
       
   105 struct TAttribute
       
   106     {
       
   107     TUint  token;
       
   108     TPtrC  value;
       
   109     };
       
   110     
       
   111   
       
   112 // TODO: RDbDatabase::Begin/Commit/RollBack and RDbRowSet::Cancel needs to be
       
   113 //      used to guard the consistancy of the databse.  See CMidRecordStoreDb 
       
   114 //      (CMidRecordStoreDb.cpp) for a good example.
       
   115 
       
   116 // -----------------------------------------------------------------------------
       
   117 // CFeedsDatabase::NewL
       
   118 //
       
   119 // Two-phased constructor.
       
   120 // -----------------------------------------------------------------------------
       
   121 //
       
   122 CFeedsDatabase* CFeedsDatabase::NewL(CFeedsServer* aFeedsServer, TBool &aDatabaseCreated)
       
   123     {
       
   124     CFeedsDatabase* self = new (ELeave) CFeedsDatabase(aFeedsServer);
       
   125 
       
   126     aDatabaseCreated = EFalse;
       
   127     
       
   128     CleanupStack::PushL(self);
       
   129     self->ConstructL(aDatabaseCreated);
       
   130     CleanupStack::Pop();
       
   131     
       
   132     return self;
       
   133     }
       
   134 
       
   135 
       
   136 // -----------------------------------------------------------------------------
       
   137 // CFeedsDatabase::NewL
       
   138 //
       
   139 // Symbian 2nd phase constructor can leave.
       
   140 // -----------------------------------------------------------------------------
       
   141 //
       
   142 void CFeedsDatabase::ConstructL(TBool &aDatabaseCreated)
       
   143     {
       
   144     TInt     err;
       
   145     User::LeaveIfError( iDBs.Connect() );
       
   146 
       
   147     // Create the path to the database file.
       
   148     TParse aParse;
       
   149     TDriveName cDrive = TDriveUnit( EDriveC ).Name(); 
       
   150     User::LeaveIfError( aParse.SetNoWild( KDatabaseFileName, &cDrive, &KDbExtension() ) );
       
   151     
       
   152 
       
   153     // Determine if the database exists.    
       
   154     TBool isDbExists = EFalse;  
       
   155     CDbDatabaseNames *dbNames = iDBs.DatabaseNamesL(EDriveC, KSecureUid);   
       
   156     for(int i = 0; i < dbNames->Count(); i++)
       
   157     	{
       
   158     	if( (*dbNames)[i] == aParse.NameAndExt() )
       
   159     		{
       
   160     		isDbExists = ETrue;
       
   161     		break;
       
   162     		}
       
   163     	}
       
   164     delete dbNames;
       
   165     
       
   166     iDatabasePath = aParse.FullName();
       
   167     // If the database file doesn't exit create it and create the tables.
       
   168     if ( !isDbExists )
       
   169         {
       
   170         TRAP( err, ResetDatabaseL() );
       
   171 
       
   172         // Ensure that the database isn't partially initialized.
       
   173         if ( err != KErrNone )
       
   174             {
       
   175             iDBs.DeleteDatabase( iDatabasePath, KSecureUid );
       
   176             User::Leave( err );
       
   177             }
       
   178         
       
   179         aDatabaseCreated = ETrue;
       
   180         }
       
   181         
       
   182     // Otherwise, just open the database.
       
   183     else
       
   184         {
       
   185     	TBuf<32> format;
       
   186         format.Copy(KSecure);
       
   187         format.Append(KSecureUid.Name());
       
   188     
       
   189         User::LeaveIfError(iDatabase.Open(iDBs, iDatabasePath, format));
       
   190 
       
   191         // check version
       
   192         UseVersionTableLC( RDbTable::EReadOnly );
       
   193         // Get the row.
       
   194         iVersionTable.FirstL();
       
   195         iVersionTable.GetL();
       
   196         // Get version
       
   197         TInt version = iVersionTable.ColUint16(iVersionColSet->ColNo(KVersionId));
       
   198         //
       
   199         CleanupStack::PopAndDestroy(/*version Table*/);
       
   200         // If version is lower than 5.0, add a new column into old database, then update the version table.
       
   201         if ( version < KVersion50 )
       
   202             {                
       
   203                             
       
   204             UseFolderListTableLC(RDbTable::EUpdatable);
       
   205 		    
       
   206             // get the exiting col set
       
   207             CDbColSet* colSet = iDatabase.ColSetL(KFolderListTable);
       
   208 		    
       
   209             colSet->AddL(TDbCol(KStatus, EDbColInt32));
       
   210             iDatabase.AlterTable(KFolderListTable, *colSet);
       
   211 		    
       
   212             CleanupStack::PopAndDestroy(/* FolderListTable */);  		     
       
   213 		    
       
   214 		    // Set the status as KErrorNone
       
   215             // Prep the item table.
       
   216     	    UseFolderListTableLC(RDbTable::EUpdatable);
       
   217 
       
   218             while( iFolderListTable.NextL() )
       
   219                 {
       
   220                 // Get the row. and add the default value.
       
   221                 iFolderListTable.GetL();
       
   222                 iFolderListTable.UpdateL();
       
   223 
       
   224                 iFolderListTable.SetColL(iFolderListColSet->ColNo(KStatus), KErrNone);
       
   225 		        
       
   226                 iFolderListTable.PutL();
       
   227 
       
   228                 }
       
   229 					
       
   230             CleanupStack::PopAndDestroy(/* FolderListTable */);
       
   231             
       
   232             //Add a new colum KAutoUpdateFreq to FeedTable
       
   233             AlterFeedTableWithAutoFequencyL();
       
   234             // Add the version as 7.1
       
   235             UseVersionTableLC(RDbTable::EUpdatable);
       
   236 		    
       
   237             // Update the version table.There is only one row in this table.
       
   238             iVersionTable.FirstL();
       
   239 		    
       
   240             if (iVersionTable.AtRow())
       
   241                 {        
       
   242                 iVersionTable.GetL();
       
   243                 iVersionTable.UpdateL();
       
   244                 }
       
   245             else
       
   246                 {
       
   247                 iVersionTable.Reset();
       
   248                 iVersionTable.InsertL();
       
   249                 }
       
   250 		    
       
   251 		    // Add the version as 7.1
       
   252             iVersionTable.SetColL(iVersionColSet->ColNo(KVersionId), KVersion71);
       
   253             iVersionTable.PutL();
       
   254             CleanupStack::PopAndDestroy(/* version table */);
       
   255 
       
   256             }
       
   257         else if( version < KVersion71 )
       
   258             {
       
   259             //Add a new colum KAutoUpdateFreq to FeedTable
       
   260             AlterFeedTableWithAutoFequencyL();
       
   261 	        // Add the version as 7.1 in DB
       
   262             UseVersionTableLC(RDbTable::EUpdatable);
       
   263 		    
       
   264             // Update the database.  There is only one row in this table...
       
   265             iVersionTable.FirstL();
       
   266 		    
       
   267             if (iVersionTable.AtRow())
       
   268                 {        
       
   269                 iVersionTable.GetL();
       
   270                 iVersionTable.UpdateL();
       
   271                 }
       
   272             else
       
   273                 {
       
   274                 iVersionTable.Reset();
       
   275                 iVersionTable.InsertL();
       
   276                 }
       
   277 		    
       
   278             // Add the version as 7.1
       
   279             iVersionTable.SetColL(iVersionColSet->ColNo(KVersionId), KVersion71);
       
   280             iVersionTable.PutL();
       
   281             CleanupStack::PopAndDestroy(/* version table */);
       
   282 		    
       
   283             }
       
   284         else if ( version == KVersion31 )
       
   285             {                
       
   286             // JH todo: transform here!
       
   287             }
       
   288         }        
       
   289     }
       
   290 
       
   291 
       
   292 // -----------------------------------------------------------------------------
       
   293 // CFeedsDatabase::CFeedsDatabase
       
   294 //
       
   295 // C++ default constructor can NOT contain any code that
       
   296 // might leave.
       
   297 // -----------------------------------------------------------------------------
       
   298 //
       
   299 CFeedsDatabase::CFeedsDatabase(CFeedsServer* aFeedsServer):
       
   300     iLeakTracker(CLeakTracker::EFeedsDatabase),iFeedsServer(aFeedsServer)
       
   301     {
       
   302     }
       
   303 
       
   304 
       
   305 // -----------------------------------------------------------------------------
       
   306 // CFeedsDatabase::~CFeedsDatabase
       
   307 //
       
   308 // Destructor
       
   309 // -----------------------------------------------------------------------------
       
   310 //
       
   311 CFeedsDatabase::~CFeedsDatabase()
       
   312     {
       
   313     delete iFolderListColSet;
       
   314     iFolderListTable.Close();
       
   315 
       
   316     delete iFeedColSet;
       
   317     iFeedTable.Close();
       
   318 
       
   319     delete iItemColSet;
       
   320     iItemTable.Close();
       
   321 
       
   322     delete iEnclosureColSet;
       
   323     iEnclosureTable.Close();
       
   324 
       
   325     delete iVersionColSet;
       
   326     iVersionTable.Close();
       
   327 
       
   328     delete iSettingsColSet;
       
   329     iSettingsTable.Close();
       
   330 
       
   331     iDatabase.Close();
       
   332     iDBs.Close();
       
   333     }
       
   334 
       
   335 
       
   336 // -----------------------------------------------------------------------------
       
   337 // CFeedsDatabase::FeedIdFromUrlL
       
   338 //
       
   339 // Returns the feed if of the feed with the given url.
       
   340 // -----------------------------------------------------------------------------
       
   341 //
       
   342 TBool CFeedsDatabase::FeedIdFromUrlL(const TDesC& aFeedUrl, TInt aFolderListId, TInt& aFeedId)
       
   343     {
       
   344     RDbView  view;
       
   345     TBool    found = EFalse;
       
   346     HBufC*   query = NULL;
       
   347     
       
   348     // Create a view given this select...    
       
   349     // SELECT FeedId FROM FeedTable WHERE FeedUrl = 'aFeedUrl' AND FolderListId = aFolderListId
       
   350     _LIT(KQuery, "SELECT FeedId FROM FeedTable WHERE FeedUrl = \'%S\' AND FolderListId = %d");
       
   351     
       
   352     query = HBufC::NewLC( KQuery().Length() + aFeedUrl.Length() + KIntLength );
       
   353             
       
   354     query->Des().Format( KQuery, &aFeedUrl, aFolderListId );
       
   355 
       
   356     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EReadOnly));
       
   357     CleanupClosePushL(view);
       
   358 
       
   359     CDbColSet* colSet = view.ColSetL();
       
   360     CleanupStack::PushL(colSet);
       
   361     
       
   362     // Search for the feed.
       
   363     if (view.Evaluate() >= 0)
       
   364         {
       
   365         if (view.FirstL())
       
   366             {
       
   367             // Get the feed id.
       
   368             view.GetL();        
       
   369             aFeedId = view.ColUint16(colSet->ColNo(KFeedId));
       
   370             found = ETrue;
       
   371             }
       
   372         }
       
   373 
       
   374     CleanupStack::PopAndDestroy(colSet);
       
   375     CleanupStack::PopAndDestroy(/*view*/);
       
   376     CleanupStack::PopAndDestroy(query);
       
   377     
       
   378     return found;
       
   379     }
       
   380 
       
   381 
       
   382 // -----------------------------------------------------------------------------
       
   383 // CFeedsDatabase::FolderListIdFromFeedIdL
       
   384 //
       
   385 // Returns the feed if of the feed with the given url.
       
   386 // -----------------------------------------------------------------------------
       
   387 //
       
   388 void CFeedsDatabase::FolderListIdFromFeedIdL( TInt aFeedId, TInt& aFolderListId )
       
   389     {
       
   390     TDbSeekKey  seekKey((TUint16) aFeedId);
       
   391     
       
   392     // Prep the feed table.
       
   393     UseFeedTableLC(RDbTable::EReadOnly);
       
   394 
       
   395     // Get the information about the feed.
       
   396     if (iFeedTable.SeekL(seekKey))
       
   397         {        
       
   398         // Get the row.
       
   399         iFeedTable.GetL();
       
   400         
       
   401         // Extract the fields.
       
   402         aFolderListId = iFeedTable.ColInt32(iFeedColSet->ColNo(KFolderListId));        
       
   403         }
       
   404     else
       
   405         {
       
   406         User::Leave(KErrCorrupt);
       
   407         }
       
   408                 
       
   409     CleanupStack::PopAndDestroy(/*Feed Table*/);
       
   410     }
       
   411     
       
   412     
       
   413 // -----------------------------------------------------------------------------
       
   414 // CFeedsDatabase::FeedIdFromFolderItemIdL
       
   415 //
       
   416 // Return the feed-id of the given folder-item-id.
       
   417 // -----------------------------------------------------------------------------
       
   418 //
       
   419 TBool CFeedsDatabase::FeedIdFromFolderItemIdL(TInt aFolderItemId, TInt& aFeedId)
       
   420     {
       
   421     TDbSeekKey  seekKey((TUint16) aFolderItemId);
       
   422     TBool       found = EFalse;
       
   423     
       
   424     // Prep the FolderList table.
       
   425     UseFolderListTableLC(RDbTable::EReadOnly);
       
   426 
       
   427     // Get the folder item.
       
   428     if (iFolderListTable.SeekL(seekKey))
       
   429         {        
       
   430         TBool  isFolder;
       
   431         
       
   432         // Get the row.
       
   433         iFolderListTable.GetL();
       
   434         
       
   435         isFolder = iFolderListTable.ColUint8(iFolderListColSet->ColNo(KIsFolder));
       
   436         
       
   437         if (!isFolder)
       
   438             {                
       
   439             aFeedId = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KFeedId));
       
   440             found = ETrue;
       
   441             }
       
   442         }
       
   443                 
       
   444     CleanupStack::PopAndDestroy(/*folder list Table*/);
       
   445     
       
   446     return found;
       
   447     }
       
   448     
       
   449 
       
   450 // -----------------------------------------------------------------------------
       
   451 // CFeedsDatabase::FolderItemInfoL
       
   452 //
       
   453 // Return the folder item info from folder-item-id.
       
   454 // -----------------------------------------------------------------------------
       
   455 //
       
   456 void CFeedsDatabase::FolderItemInfoL(TInt aFolderItemId, TBool &aIsFolder, HBufC*& aTitle, HBufC*& aFeedUrl)
       
   457 	{
       
   458 	TDbSeekKey  seekKey((TUint16) aFolderItemId);
       
   459 
       
   460 	// Prep the FolderList table.
       
   461 	UseFolderListTableLC(RDbTable::EReadOnly);
       
   462 
       
   463 	// Get the folder item.
       
   464 	if (iFolderListTable.SeekL(seekKey))
       
   465 		{        
       
   466 		// Get the row.
       
   467 		iFolderListTable.GetL();
       
   468 
       
   469 		aIsFolder = iFolderListTable.ColUint8(iFolderListColSet->ColNo(KIsFolder));
       
   470 	
       
   471 		*aTitle = iFolderListTable.ColDes16(iFolderListColSet->ColNo(KTitle_100MaxLen));
       
   472 	
       
   473 		TInt FeedId = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KFeedId));
       
   474 
       
   475 		if(!aIsFolder)
       
   476 			{
       
   477 
       
   478 			RDbView  view;
       
   479 			HBufC*   query = NULL;
       
   480     
       
   481 			// Create a view given this select...    
       
   482 			// SELECT FeedUrl FROM FeedTable WHERE FeedId = aFeedId
       
   483 			_LIT(KQuery, "SELECT FeedUrl FROM FeedTable WHERE FeedId = %d");
       
   484     
       
   485 			query = HBufC::NewLC(KQuery().Length() + KIntLength);
       
   486             
       
   487 			query->Des().Format(KQuery, FeedId);
       
   488 
       
   489 			User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EReadOnly));
       
   490 			CleanupClosePushL(view);
       
   491 
       
   492 			CDbColSet* colSet = view.ColSetL();
       
   493 			CleanupStack::PushL(colSet);
       
   494     
       
   495 			// Search for the feed.
       
   496 			if (view.Evaluate() >= 0)
       
   497 				{
       
   498 				if (view.FirstL())
       
   499 					{
       
   500 					// Get the feed id.
       
   501 					view.GetL();        
       
   502 					ReadLongTextL(view, colSet->ColNo(KFeedUrl), aFeedUrl);
       
   503 					}
       
   504 				}
       
   505         
       
   506 			CleanupStack::PopAndDestroy(/*colSet*/);
       
   507 			CleanupStack::PopAndDestroy(/*view*/);
       
   508 			CleanupStack::PopAndDestroy(/*query*/);
       
   509 			}
       
   510         }
       
   511 
       
   512 	CleanupStack::PopAndDestroy(/*folder list Table*/);
       
   513 	}
       
   514 
       
   515 // -----------------------------------------------------------------------------
       
   516 // CFeedsDatabase::UrlFromFeedIdL
       
   517 //
       
   518 // Return the url of the feed with the given feed-id.
       
   519 // -----------------------------------------------------------------------------
       
   520 //
       
   521 TBool CFeedsDatabase::UrlFromFeedIdL(TInt aFeedId, HBufC*& aFeedUrl)
       
   522     {
       
   523     RDbView  view;
       
   524     TBool    found = EFalse;
       
   525     HBufC*   query = NULL;
       
   526     
       
   527     // Create a view given this select...    
       
   528     // SELECT FeedUrl FROM FeedTable WHERE FeedId = aFeedId
       
   529     _LIT(KQuery, "SELECT FeedUrl FROM FeedTable WHERE FeedId = %d");
       
   530     
       
   531     query = HBufC::NewLC(KQuery().Length() + KIntLength);
       
   532             
       
   533     query->Des().Format(KQuery, aFeedId);
       
   534 
       
   535     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EReadOnly));
       
   536     CleanupClosePushL(view);
       
   537 
       
   538     CDbColSet* colSet = view.ColSetL();
       
   539     CleanupStack::PushL(colSet);
       
   540     
       
   541     // Search for the feed.
       
   542     if (view.Evaluate() >= 0)
       
   543         {
       
   544         if (view.FirstL())
       
   545             {
       
   546             // Get the feed id.
       
   547             view.GetL();        
       
   548             ReadLongTextL(view, colSet->ColNo(KFeedUrl), aFeedUrl);
       
   549             found = ETrue;
       
   550             }
       
   551         }
       
   552         
       
   553     CleanupStack::PopAndDestroy(colSet);
       
   554     CleanupStack::PopAndDestroy(/*view*/);
       
   555     CleanupStack::PopAndDestroy(query);
       
   556 
       
   557     return found;
       
   558     }
       
   559     
       
   560     
       
   561 // -----------------------------------------------------------------------------
       
   562 // CFeedsDatabase::FindItemL
       
   563 //
       
   564 // Finds the item with the given item-id-str and returns its id.
       
   565 // -----------------------------------------------------------------------------
       
   566 //
       
   567 TBool CFeedsDatabase::FindItemL(TInt aFeedId, const TDesC& aItemIdStr, TInt& aItemId)
       
   568     {
       
   569     RDbView  view;
       
   570     TBool    found = EFalse;
       
   571     HBufC*   query = NULL;
       
   572     
       
   573     // Create a view given this select...    
       
   574     // SELECT ItemId FROM ItemTable WHERE FeedId = aFeedId AND ItemIdStr = 'aItemIdStr'
       
   575     _LIT(KQuery, "SELECT ItemId FROM ItemTable WHERE FeedId = %d AND ItemIdStr = \'%S\'");
       
   576     
       
   577     query = HBufC::NewLC(KQuery().Length() + KIntLength + aItemIdStr.Length()); 
       
   578             
       
   579     query->Des().Format(KQuery, aFeedId, &aItemIdStr);
       
   580 
       
   581     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EReadOnly));
       
   582     CleanupClosePushL(view);
       
   583 
       
   584     CDbColSet* colSet = view.ColSetL();
       
   585     CleanupStack::PushL(colSet);
       
   586     
       
   587     // Find the item.
       
   588     if (view.Evaluate() >= 0)
       
   589         {
       
   590         if (view.FirstL())
       
   591             {
       
   592             // Get the item id.
       
   593             view.GetL();        
       
   594             aItemId = view.ColUint16(colSet->ColNo(KItemId));
       
   595             found = ETrue;
       
   596             }
       
   597         }
       
   598         
       
   599     CleanupStack::PopAndDestroy(colSet);
       
   600     CleanupStack::PopAndDestroy(/*view*/);
       
   601     CleanupStack::PopAndDestroy(query);
       
   602     return found;
       
   603     }
       
   604     
       
   605     
       
   606 // -----------------------------------------------------------------------------
       
   607 // CFeedsDatabase::FindFolderItemL
       
   608 //
       
   609 // Finds the folder item with the given name.
       
   610 // -----------------------------------------------------------------------------
       
   611 //
       
   612 TBool CFeedsDatabase::FindFolderItemL(TInt& aFolderListId, const TDesC& aName, 
       
   613         TInt& aFolderItemId)
       
   614     {
       
   615     RDbView  view;
       
   616     TBool    found = EFalse;
       
   617     HBufC*   query = NULL;
       
   618     
       
   619     // Create a view given this select...    
       
   620     // SELECT FolderItemId FROM FolderListTable WHERE FolderListId = aFolderListId 
       
   621     // AND Title = 'aName'
       
   622     _LIT(KQuery, "SELECT FolderItemId FROM FolderListTable WHERE FolderListId = %d AND Title = '%S'");
       
   623     
       
   624     query = HBufC::NewLC(KQuery().Length() + KIntLength + aName.Length());
       
   625             
       
   626     query->Des().Format(KQuery, aFolderListId, &aName);
       
   627 
       
   628     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EReadOnly));
       
   629     CleanupClosePushL(view);
       
   630 
       
   631     CDbColSet* colSet = view.ColSetL();
       
   632     CleanupStack::PushL(colSet);
       
   633     
       
   634     // Search for the feed.
       
   635     if (view.Evaluate() >= 0)
       
   636         {
       
   637         if (view.FirstL())
       
   638             {
       
   639             // Get the feed id.
       
   640             view.GetL();        
       
   641             aFolderItemId = view.ColUint16(colSet->ColNo(KFolderItemId));
       
   642             found = ETrue;
       
   643             }
       
   644         }
       
   645         
       
   646     CleanupStack::PopAndDestroy(colSet);
       
   647     CleanupStack::PopAndDestroy(/*view*/);
       
   648     CleanupStack::PopAndDestroy(query);
       
   649     
       
   650     return found;
       
   651     }
       
   652 
       
   653 
       
   654 // -----------------------------------------------------------------------------
       
   655 // CFeedsDatabase::GetDuplicateFolderCounter
       
   656 //
       
   657 // Parses the Folder/Feed name to get the postfix integer for duplicated names 
       
   658 //    (ex Folder, Folder (1), Folder (2) ...)
       
   659 // -----------------------------------------------------------------------------
       
   660 //
       
   661 //TBool CFeedsDatabase::GetDuplicateFolderCounter(const TDesC& aFolderTitle, TInt &aCounterVal)
       
   662 TBool CFeedsDatabase::GetDuplicateFolderCounter(const TDesC& aFolderToBeAdded, const TDesC& aFolderTitle, TInt &aCounterVal)
       
   663 	{
       
   664 	
       
   665 	if(aFolderToBeAdded == aFolderTitle)
       
   666 		return ETrue;
       
   667 	
       
   668 	// return EFalse if FolderTitle is empty
       
   669 	if(aFolderTitle.Length()<=0)
       
   670 		return EFalse;
       
   671 	
       
   672 	// Use a lexical parser to parse the FolderTitle ( FolderName (%d))
       
   673 	TLex parser(aFolderTitle);
       
   674 	
       
   675 	// Go til first '('
       
   676 	while(!parser.Eos())
       
   677 		{
       
   678 		TChar c(parser.Peek());
       
   679 		if( c != '(')
       
   680 			parser.Get();
       
   681 		else
       
   682 			break;
       
   683 		}
       
   684 
       
   685 	// If end of string return EFalse
       
   686 	if(parser.Eos())
       
   687 		return EFalse;
       
   688 	
       
   689 	// skip '('
       
   690 	parser.Get();
       
   691 
       
   692     // Get postfix integer value
       
   693 	if(parser.Val(aCounterVal) != KErrNone)	
       
   694 		return EFalse;
       
   695 	
       
   696 	// If not ending with ')' return EFalse
       
   697 	if(parser.Get() != ')')
       
   698 		return EFalse;
       
   699 	
       
   700 	// If end of string return ETrue
       
   701 	if(parser.Eos())
       
   702 		return ETrue;	
       
   703 
       
   704 	return EFalse;
       
   705 	}
       
   706 	
       
   707 // -----------------------------------------------------------------------------
       
   708 // CFeedsDatabase::ValidateFeedURLL
       
   709 //
       
   710 // Checks for the FeedURL's existance
       
   711 // Returns EFalse if the specified URL exists else ETrue
       
   712 // -----------------------------------------------------------------------------
       
   713 //
       
   714 TBool CFeedsDatabase::ValidateFeedURLL(const TInt &aFolderListId,  const TDesC& aUrl)
       
   715 	{
       
   716 
       
   717 	RDbView	view;
       
   718 	HBufC*	query = NULL;
       
   719 	TBool	IsValid = ETrue;	
       
   720 	
       
   721 	// If URL is empty return EFalse
       
   722 	if(aUrl.Length() <= 0)
       
   723 		return EFalse;
       
   724 
       
   725 	// Check for the URL duplicate
       
   726 	_LIT(KQuery, "SELECT FeedId FROM FeedTable WHERE FeedUrl = \'%S\' AND FolderListId = %d");
       
   727 	query = HBufC::NewLC(KQuery().Length() + KIntLength + aUrl.Length());
       
   728 
       
   729 	query->Des().Format(KQuery, &aUrl, aFolderListId);
       
   730 
       
   731 	User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EReadOnly));
       
   732 	CleanupClosePushL(view);
       
   733 
       
   734 	CDbColSet* colSet = view.ColSetL();
       
   735 	CleanupStack::PushL(colSet);
       
   736 
       
   737 	// If there exists atleast one record we are not suppose to add the feed again
       
   738 	if (view.Evaluate() >= 0)
       
   739 		{
       
   740 		if (view.FirstL())
       
   741 			{
       
   742 			// FeedURL aleady exists, no need to process this feed
       
   743 			IsValid = EFalse;
       
   744 			}
       
   745 		}
       
   746 			
       
   747 	CleanupStack::PopAndDestroy(/*colSet*/);
       
   748 	CleanupStack::PopAndDestroy(/*view*/);
       
   749 	CleanupStack::PopAndDestroy(/*query*/);
       
   750 	
       
   751 	return IsValid;
       
   752 	}
       
   753 
       
   754 // -----------------------------------------------------------------------------
       
   755 // CFeedsDatabase::GenerateNewFolderTitleL
       
   756 //
       
   757 // This will check for the duplicate folder names and suggest a new folder title if duplicated
       
   758 // -----------------------------------------------------------------------------
       
   759 //
       
   760 void CFeedsDatabase::GenerateNewFeedFolderTitleL(
       
   761 											const TInt &aFolderListId, 
       
   762 											const TInt &aParentEntryId, 
       
   763 											const TDesC& aTitle, 
       
   764 											TDes& aNewFeedFolderTitle
       
   765 											)
       
   766 	{
       
   767 	RDbView  view;
       
   768 	HBufC*   query = NULL;
       
   769 
       
   770 	// Create a view given this select...    
       
   771 	_LIT(KQuery, "SELECT Title FROM FolderListTable WHERE FolderListId = %d AND ParentId = %d AND Title LIKE '%S*'");
       
   772 
       
   773 	if(aTitle.Length() <= 0)
       
   774 		return;
       
   775 
       
   776 	query = HBufC::NewLC(KQuery().Length() + KIntLength + aTitle.Length());
       
   777 
       
   778 	query->Des().Format(KQuery, aFolderListId, aParentEntryId, &aTitle);
       
   779 
       
   780 	User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EReadOnly));
       
   781 	CleanupClosePushL(view);
       
   782 
       
   783 	CDbColSet* colSet = view.ColSetL();
       
   784 	CleanupStack::PushL(colSet);
       
   785 
       
   786 	// Search for the feed.
       
   787 	if (view.EvaluateAll() >= 0)
       
   788 		{
       
   789 		
       
   790 		if(view.CountL() <= 0)
       
   791 			{
       
   792 			// Name doesnt exist, so no problem adding this name
       
   793 			aNewFeedFolderTitle = aTitle;
       
   794 			}
       
   795 		else
       
   796 			{
       
   797 			RArray<TInt> FolderPostfixArray;
       
   798 			CleanupClosePushL(FolderPostfixArray);
       
   799 	
       
   800 			// Store all folder name extensions ('FolderName (%d)') in an array
       
   801 			for (view.FirstL(); view.AtRow(); view.NextL())
       
   802 				{
       
   803 				// Get the current row.
       
   804 				view.GetL();
       
   805 
       
   806 				HBufC *FolderTitle = NULL;
       
   807 				ReadLongTextL(view, colSet->ColNo(KTitle_100MaxLen), FolderTitle);
       
   808 				CleanupStack::PushL(FolderTitle);
       
   809 				
       
   810 				TInt PostfixVal=0;
       
   811 				if(GetDuplicateFolderCounter(aTitle, FolderTitle->Des(), PostfixVal))
       
   812 					FolderPostfixArray.Append(PostfixVal);
       
   813 
       
   814 				CleanupStack::PopAndDestroy(/*FolderTitle*/);
       
   815 				}
       
   816 
       
   817 			// Search for a free postfix counter for duplicated folder/feed title
       
   818 			TInt PostfixVal = 1;
       
   819 			TInt length = FolderPostfixArray.Count();
       
   820 			if(length <= 0)
       
   821 				{
       
   822 					aNewFeedFolderTitle = aTitle;		
       
   823 				}
       
   824 				else
       
   825 				{
       
   826 				do
       
   827 					{
       
   828 					TInt index = 0;
       
   829 				    for (index = 0 ; index < length ; index++)
       
   830 						{
       
   831 						if(FolderPostfixArray[index] == PostfixVal)
       
   832 							break;
       
   833 						}
       
   834 
       
   835 					if(index >= length)
       
   836 						break;
       
   837 					
       
   838 					PostfixVal++;
       
   839 					}
       
   840 				while(ETrue);
       
   841 				// Generate a new folder/feed title by appending the new counter
       
   842 				_LIT(KFolderNameFormat, "%S (%d)");
       
   843 				aNewFeedFolderTitle.Format(KFolderNameFormat, &aTitle, PostfixVal);
       
   844 				}
       
   845 				
       
   846 			CleanupStack::PopAndDestroy(/*FolderPostfixArray*/);
       
   847 			}
       
   848 		}
       
   849 	else
       
   850 		{
       
   851 		aNewFeedFolderTitle = aTitle;		
       
   852 		}
       
   853 
       
   854 	CleanupStack::PopAndDestroy(/*colSet*/);
       
   855 	CleanupStack::PopAndDestroy(/*view*/);
       
   856 	CleanupStack::PopAndDestroy(/*query*/);
       
   857 	}
       
   858 	
       
   859 // -----------------------------------------------------------------------------
       
   860 // CFeedsDatabase::ValidateFeedFolderTitleL
       
   861 //
       
   862 // This will check for the duplicate folder names and feed URLs and suggest the next title
       
   863 // Returns ETrue if the Feed/Folder can be added to database else EFalse
       
   864 // -----------------------------------------------------------------------------
       
   865 //
       
   866 TBool CFeedsDatabase::ValidateFeedFolderTitleL(
       
   867 												const TInt &aFolderListId, 
       
   868 												const TInt &aParentEntryId, 
       
   869 												const TDesC& aTitle, 
       
   870 												const TBool aIsFolder, 
       
   871 												TDes& aNewFeedTitle
       
   872 											  )
       
   873 	{
       
   874 	if(!aIsFolder)
       
   875 		{
       
   876 
       
   877 		// If Feed URL is duplicated return EFalse
       
   878 		//if(!ValidateFeedURLL(aFolderListId, aUrl))
       
   879 		//	return EFalse;
       
   880 
       
   881 		}
       
   882 
       
   883 	if(aTitle.Length() <=0)
       
   884 		return EFalse;
       
   885 
       
   886 	GenerateNewFeedFolderTitleL(aFolderListId, aParentEntryId, aTitle, aNewFeedTitle);
       
   887 
       
   888 	return ETrue;
       
   889 	}
       
   890     
       
   891 // -----------------------------------------------------------------------------
       
   892 // CFeedsDatabase::AllFeedIds
       
   893 //
       
   894 // Extract all of the feed-ids.
       
   895 // -----------------------------------------------------------------------------
       
   896 //
       
   897 void CFeedsDatabase::AllFeedIdsL( RArray<TInt>& aFeedIds, TInt aFolderListId )
       
   898     {
       
   899     RDbView  view;
       
   900     HBufC*   query = NULL;
       
   901     
       
   902     if( aFolderListId == KAllFolderListId )
       
   903         {
       
   904         // Create a view given this select...    
       
   905         // SELECT FeedId FROM FeedTable
       
   906         _LIT(KQuery, "SELECT FeedId FROM FeedTable");
       
   907     
       
   908         query = HBufC::NewLC( KQuery().Length() );             
       
   909         }
       
   910     else
       
   911         {
       
   912         // Create a view given this select...    
       
   913         // SELECT FeedId FROM FeedTable WHERE FolderListId = aFolderListId
       
   914         _LIT(KQuery, "SELECT FeedId FROM FeedTable WHERE FolderListId = %d");
       
   915     
       
   916         query = HBufC::NewLC( KQuery().Length() + KIntLength );             
       
   917         query->Des().Format( KQuery, aFolderListId );
       
   918         }
       
   919 
       
   920     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EReadOnly));
       
   921     CleanupClosePushL(view);
       
   922 
       
   923     CDbColSet* colSet = view.ColSetL();
       
   924     CleanupStack::PushL(colSet);
       
   925     
       
   926     // Find the item.
       
   927     if (view.EvaluateAll() >= 0)
       
   928         {
       
   929         for (view.FirstL(); view.AtRow(); view.NextL())
       
   930             {
       
   931             // Get the current row.
       
   932             view.GetL();
       
   933             
       
   934             aFeedIds.AppendL(view.ColUint16(colSet->ColNo(KFeedId)));
       
   935             }
       
   936         }
       
   937         
       
   938     CleanupStack::PopAndDestroy(colSet);
       
   939     CleanupStack::PopAndDestroy(/*view*/);
       
   940     CleanupStack::PopAndDestroy(query);
       
   941     }
       
   942     
       
   943     
       
   944 // -----------------------------------------------------------------------------
       
   945 // CFeedsDatabase::IsFreshL
       
   946 //
       
   947 // Determines if the given feed is newly created (not ok to read from the database).
       
   948 // -----------------------------------------------------------------------------
       
   949 //
       
   950 TBool CFeedsDatabase::IsNewlyCreatedL(TInt aFeedId)
       
   951     {
       
   952     TDbSeekKey  seekKey((TUint16) aFeedId);
       
   953     TBool       isNewlyCreated = EFalse;
       
   954     TTime       now;
       
   955     
       
   956     // Prep the feed table.
       
   957     UseFeedTableLC(RDbTable::EReadOnly);
       
   958 
       
   959     // Get the information about the feed.
       
   960     if (iFeedTable.SeekL(seekKey))
       
   961         {        
       
   962         // Get the row.
       
   963         iFeedTable.GetL();
       
   964         
       
   965         // Extract the fields.
       
   966         TTime  date = iFeedTable.ColTime(iFeedColSet->ColNo(KDate));
       
   967         
       
   968         // Determine if the feed is fresh.
       
   969         if (date == 0)
       
   970             {
       
   971             isNewlyCreated = ETrue;
       
   972             }
       
   973         }
       
   974     else
       
   975         {
       
   976         User::Leave(KErrCorrupt);
       
   977         }
       
   978                 
       
   979     CleanupStack::PopAndDestroy(/*Feed Table*/);
       
   980     
       
   981     return isNewlyCreated;
       
   982     }
       
   983 
       
   984 
       
   985 // -----------------------------------------------------------------------------
       
   986 // CFeedsDatabase::ExtractFeedL
       
   987 //
       
   988 // Extracts the feed from the database.
       
   989 // -----------------------------------------------------------------------------
       
   990 //
       
   991 void CFeedsDatabase::ExtractFeedL(TInt aFeedId, CPackedFeed& aFeed)
       
   992     {
       
   993     // Pack the feed.
       
   994     PackFeedL(aFeedId, aFeed);
       
   995     
       
   996     // Pack the feed's items.
       
   997     PackItemsL(aFeedId, aFeed);
       
   998 
       
   999     // Signal the end of the feed.
       
  1000     aFeed.FeedEndsL();
       
  1001     aFeed.Trim();    
       
  1002     }
       
  1003 
       
  1004 
       
  1005 // -----------------------------------------------------------------------------
       
  1006 // CFeedsDatabase::ExtractRootFolderL
       
  1007 //
       
  1008 // Extracts the folder from the database.
       
  1009 // -----------------------------------------------------------------------------
       
  1010 //
       
  1011 void CFeedsDatabase::ExtractRootFolderL( TInt aFolderListId, CPackedFolder& aPackedFolder, TBool aItemTitleNeed )
       
  1012     {
       
  1013     // Use the tables.
       
  1014     UseFeedTableLC(RDbTable::EReadOnly);
       
  1015     
       
  1016     // Extract the root folder and all of its children.
       
  1017     aPackedFolder.FolderBeginsL(KRootFolder, KRootFolderId);
       
  1018     PackFolderL( aFolderListId, KRootFolderId, aPackedFolder, aItemTitleNeed );
       
  1019     aPackedFolder.FolderEndsL();
       
  1020     aPackedFolder.DoneL();
       
  1021 
       
  1022     // Clean up.
       
  1023     CleanupStack::PopAndDestroy(/*feed table*/);
       
  1024     }
       
  1025     
       
  1026     
       
  1027 // -----------------------------------------------------------------------------
       
  1028 // CFeedsDatabase::UpdateFeedL
       
  1029 //
       
  1030 // Update the database given the packed feed.
       
  1031 // -----------------------------------------------------------------------------
       
  1032 //
       
  1033 void CFeedsDatabase::UpdateFeedL(const CPackedFeed& aPackedFeed, const TDesC& /* aFeedUrl */,TInt aFeedId,
       
  1034         TInt aFolderListId, TBool aPurgeOldItems)
       
  1035     {
       
  1036     RArray<TInt>        itemIds;
       
  1037     RArray<TAttribute>  feedAttributes;
       
  1038     RArray<TAttribute>  itemAttributes;
       
  1039     RArray<TAttribute>  enclosureAttributes;
       
  1040     TBool               isFeed = EFalse;
       
  1041     TBool               isItem = EFalse;
       
  1042     TBool               isEnclosure = EFalse;
       
  1043     TInt                feedId = 0;
       
  1044     TInt                itemId = 0;
       
  1045     TInt                enclosureId = 0;
       
  1046     TAttribute          attribute;
       
  1047     TUint               attributeToken;
       
  1048     TPtrC               attributeValue;
       
  1049     TBool               isNewFeed = EFalse;
       
  1050     TInt                newItemCount = 0;
       
  1051     TBool               newItem = EFalse;
       
  1052     feedId = aFeedId;
       
  1053 
       
  1054     // This array holds the ids of the items found in the feed.  The array is then 
       
  1055     // used to remove items from the database that aren't in the updated feed.
       
  1056     CleanupClosePushL(itemIds);
       
  1057 
       
  1058     CleanupClosePushL(feedAttributes);
       
  1059     CleanupClosePushL(itemAttributes);
       
  1060     CleanupClosePushL(enclosureAttributes);
       
  1061 
       
  1062     // Use the various tables
       
  1063     UseFeedTableLC(RDbTable::EUpdatable);
       
  1064     UseItemTableLC(RDbTable::EUpdatable);
       
  1065     UseEnclosureTableLC(RDbTable::EUpdatable);
       
  1066 
       
  1067     // Unpack the packed feed.
       
  1068     while (aPackedFeed.HasNextToken())
       
  1069         {
       
  1070         TUint token;
       
  1071         
       
  1072         token = aPackedFeed.NextToken();
       
  1073         
       
  1074         switch (token)
       
  1075             {
       
  1076             case EFeedTokenFeedBegin:
       
  1077                 isFeed = ETrue;  
       
  1078                 //isNewFeed = ETrue;
       
  1079                 // Resolve the url to determine if this feed is already in the database.
       
  1080                 //if (FeedIdFromUrlL(aFeedUrl, aFolderListId, feedId))
       
  1081                 //    {
       
  1082                 //    isNewFeed = EFalse;
       
  1083                 //    }
       
  1084                     
       
  1085                 // Otherwise lookup a new feed id to use.
       
  1086                 //else
       
  1087                 //    {
       
  1088                 //    // Get a new id for the feed.
       
  1089                 //    feedId = NextFeedIdL();
       
  1090                 //    }
       
  1091                 break;
       
  1092 
       
  1093             case EFeedTokenFeedEnd:
       
  1094                 {
       
  1095                 // TODO: Track whether or not any new item were added.  The feed's timestamp
       
  1096                 //       should only be updated if this happened.  So rather than updating the
       
  1097                 //       timestamp in CommitFeedL it should be updated here.
       
  1098                 //
       
  1099                 //       Or prehaps this shouldn't be done.  If this is done the user's "last update"
       
  1100                 //       timestamp won't be updated - so they may _feel_ the update didn't happen.
       
  1101         
       
  1102                 // Remove any items that weren't in the packed feed (this removes old items).
       
  1103                 TInt purgedUnreadNewCount = 0;
       
  1104                 if (aPurgeOldItems)
       
  1105                     {        
       
  1106                     purgedUnreadNewCount = PurgeOtherItemsL(feedId, itemIds);
       
  1107                     }
       
  1108                 newItemCount -= purgedUnreadNewCount;
       
  1109     
       
  1110                 TTime  now;
       
  1111                 
       
  1112                 // Commit the feed to the database.
       
  1113                 now.UniversalTime();
       
  1114                 CommitFeedL(aFolderListId, isNewFeed, feedId, feedAttributes, now, newItemCount);
       
  1115                 
       
  1116                 feedAttributes.Reset();
       
  1117                 isFeed = EFalse;
       
  1118                 }
       
  1119                 break;
       
  1120 
       
  1121             case EFeedTokenItemBegin:
       
  1122                 isItem = ETrue; 
       
  1123                 itemId = NextItemIdL();              
       
  1124                 enclosureId = 0;
       
  1125                 break;
       
  1126 
       
  1127             case EFeedTokenItemEnd:
       
  1128                 // Commit the item to the database.
       
  1129                 newItem = CommitItemL(itemId, feedId, itemAttributes, itemIds);
       
  1130 
       
  1131                 itemAttributes.Reset();
       
  1132                 isItem = EFalse;
       
  1133                 if( newItem )
       
  1134                     {
       
  1135                     newItemCount++;
       
  1136                     }
       
  1137                 break;
       
  1138 
       
  1139             case EFeedTokenEnclosureBegin:
       
  1140                 isEnclosure = ETrue;
       
  1141                 break;
       
  1142 
       
  1143             case EFeedTokenEnclosureEnd:
       
  1144                 // Commit the enclosure to the database.
       
  1145                 CommitEnclosureL(enclosureId++, itemId, feedId, enclosureAttributes);
       
  1146 
       
  1147                 enclosureAttributes.Reset();
       
  1148                 isEnclosure = EFalse;
       
  1149                 break;
       
  1150                 
       
  1151             case EPackedTokenAttribute:
       
  1152                 // Apply the given attribute to the current object (enclosure, item, or feed).
       
  1153                 aPackedFeed.ExtractAttributeValue(attributeToken, attributeValue);
       
  1154 
       
  1155                 attribute.token = attributeToken;
       
  1156                 attribute.value.Set(attributeValue);
       
  1157                 
       
  1158                 if (isEnclosure)
       
  1159                     {
       
  1160                     enclosureAttributes.AppendL(attribute);
       
  1161                     }
       
  1162                 else if (isItem)
       
  1163                     {
       
  1164                     itemAttributes.AppendL(attribute);
       
  1165                     }
       
  1166                 else if (isFeed)
       
  1167                     {
       
  1168                     feedAttributes.AppendL(attribute);
       
  1169                     }
       
  1170                 break;
       
  1171             }
       
  1172         }
       
  1173 
       
  1174     // Clean up.
       
  1175     CleanupStack::PopAndDestroy(/*enclosure table*/);
       
  1176     CleanupStack::PopAndDestroy(/*item table*/);
       
  1177     CleanupStack::PopAndDestroy(/*feed table*/);
       
  1178 
       
  1179     CleanupStack::PopAndDestroy(/*enclosureAttributes*/);
       
  1180     CleanupStack::PopAndDestroy(/*attributeValue*/);
       
  1181     CleanupStack::PopAndDestroy(/*feedAttributes*/);
       
  1182 
       
  1183     CleanupStack::PopAndDestroy(/*itemIds*/);
       
  1184     iDatabase.Compact();
       
  1185     }
       
  1186         
       
  1187     
       
  1188 // -----------------------------------------------------------------------------
       
  1189 // CFeedsDatabase::ImportFolderL
       
  1190 //
       
  1191 // Update the database given the packed folder.
       
  1192 // -----------------------------------------------------------------------------
       
  1193 //
       
  1194 void CFeedsDatabase::ImportFolderL(TInt aFolderListId, const CPackedFolder& aPackedFolder)
       
  1195     {
       
  1196     RArray<TInt>        parentStack;
       
  1197     RArray<TInt>        siblingIndexStack;
       
  1198     TInt                parent;
       
  1199     TInt                siblingIndex;
       
  1200     TInt                folderId;
       
  1201     TBool               foundRootFolder = EFalse;
       
  1202     TPtrC               title;
       
  1203     TPtrC               url;
       
  1204     TInt                entryId;
       
  1205     TInt                feedId;
       
  1206     TTime               timestamp;
       
  1207     TInt                unreadCount;
       
  1208     TInt 				statusCode;
       
  1209     TInt                freq;
       
  1210 
       
  1211     // Open the various tables
       
  1212     UseFolderListTableLC(RDbTable::EUpdatable);
       
  1213     UseFeedTableLC(RDbTable::EUpdatable);
       
  1214 
       
  1215     // A simple stack is used to track the folder-nesting.  Start with the root-folder.
       
  1216     CleanupClosePushL(parentStack);
       
  1217     CleanupClosePushL(siblingIndexStack);
       
  1218     
       
  1219     parentStack.AppendL(KRootFolderId);    
       
  1220     siblingIndexStack.AppendL(0);
       
  1221     
       
  1222     // Unpack the packed folder.
       
  1223     while (aPackedFolder.HasNextToken())
       
  1224         {
       
  1225         TUint token;
       
  1226         
       
  1227         token = aPackedFolder.NextToken();
       
  1228         
       
  1229         switch (token)
       
  1230             {
       
  1231             case EFolderTokenFolderBegin:
       
  1232                 // Extract the attributes.
       
  1233                 aPackedFolder.ExtractAttributes(title, url, entryId, feedId, timestamp, unreadCount, statusCode, freq);
       
  1234                 
       
  1235                 // The first folder in the PackedFolder is the root-folder.  There is no
       
  1236                 // reason to store this folder in the database, as such this folder is skipped.
       
  1237                 if (!foundRootFolder)
       
  1238                     {
       
  1239                     foundRootFolder = ETrue;
       
  1240                     continue;
       
  1241                     }
       
  1242 
       
  1243                 // Determine the parent and its sibling index.
       
  1244                 parent = parentStack[parentStack.Count() - 1];
       
  1245                 siblingIndex = siblingIndexStack[siblingIndexStack.Count() - 1];
       
  1246                 siblingIndexStack[siblingIndexStack.Count() - 1]++;
       
  1247 
       
  1248                 // Add the folder.
       
  1249 				TInt feedId;
       
  1250                 FolderItemAddHelperL(aFolderListId, title, KNullDesC, 
       
  1251                         ETrue, siblingIndex, parent, folderId, feedId, freq);
       
  1252 
       
  1253                 // Push this folder on the stack as the active parent.
       
  1254                 parentStack.AppendL(folderId);
       
  1255                 siblingIndexStack.AppendL(0);
       
  1256                 break;
       
  1257 
       
  1258             case EFolderTokenFolderEnd:
       
  1259                 // Pop this folder off of the stacks.
       
  1260                 parentStack.Remove(parentStack.Count() - 1);
       
  1261                 siblingIndexStack.Remove(siblingIndexStack.Count() - 1);
       
  1262                 break;
       
  1263 
       
  1264             case EFolderTokenFeed:
       
  1265                 // Extract the attributes.
       
  1266                 aPackedFolder.ExtractAttributes(title, url, entryId, feedId, timestamp, unreadCount, statusCode, freq);
       
  1267 
       
  1268                 // Determine the parent and its sibling index.
       
  1269                 parent = parentStack[parentStack.Count() - 1];
       
  1270                 siblingIndex = siblingIndexStack[siblingIndexStack.Count() - 1];
       
  1271                 
       
  1272                 // Add the feed.                
       
  1273 
       
  1274 				TInt folderId, newfeedId;
       
  1275                 TRAPD( err, FolderItemAddHelperL(aFolderListId, title, url, 
       
  1276                         EFalse, siblingIndex, parent, folderId, newfeedId, freq) );
       
  1277 
       
  1278                 // Ignore problematic ones and continue to the next token
       
  1279                 if( err == KErrNone )
       
  1280                     {
       
  1281                     siblingIndexStack[siblingIndexStack.Count() - 1]++;
       
  1282                     }
       
  1283                 break;               
       
  1284             }
       
  1285         }
       
  1286 
       
  1287     CleanupStack::PopAndDestroy(/*siblingIndexStack*/);
       
  1288     CleanupStack::PopAndDestroy(/*parentStack*/);
       
  1289     CleanupStack::PopAndDestroy(/*feed table*/);
       
  1290     CleanupStack::PopAndDestroy(/*folder list table*/);
       
  1291     }
       
  1292 
       
  1293 // -----------------------------------------------------------------------------
       
  1294 // CFeedsDatabase::FolderItemAddL
       
  1295 //
       
  1296 // Add a new entry.
       
  1297 // -----------------------------------------------------------------------------
       
  1298 //
       
  1299 TInt CFeedsDatabase::FolderItemAddL(TInt aFolderListId, const TDesC& aTitle,
       
  1300         const TDesC& aUrl, TBool aIsFolder, TInt aParentEntryId, TInt aFreq)
       
  1301     {
       
  1302     TInt  entryId = 0;
       
  1303     
       
  1304     // Open the various tables
       
  1305     UseFolderListTableLC(RDbTable::EUpdatable);
       
  1306     UseFeedTableLC(RDbTable::EUpdatable);
       
  1307     
       
  1308     // Adjust the sibling indexes of the existing folder items such that this
       
  1309     // item can be inserted at index zero.
       
  1310     CreateSiblingIndexHoleL(aParentEntryId, 0, 1);
       
  1311     
       
  1312     // Add the folder item at sibling index 0.
       
  1313 	TInt feedId = 0;
       
  1314     TRAPD( err, FolderItemAddHelperL(aFolderListId, aTitle, aUrl, aIsFolder, 
       
  1315             0, aParentEntryId, entryId, feedId, aFreq) );
       
  1316     User::LeaveIfError( err );
       
  1317     
       
  1318     // Clean up.
       
  1319     CleanupStack::PopAndDestroy(/*feed table*/);
       
  1320     CleanupStack::PopAndDestroy(/*folder list table*/);
       
  1321     if(feedId != KUnassignedId)
       
  1322         {
       
  1323         iFeedsServer->UpdateFeedL(aFolderListId,feedId,EFalse);
       
  1324         }
       
  1325     return entryId;
       
  1326     }
       
  1327 
       
  1328 
       
  1329 // -----------------------------------------------------------------------------
       
  1330 // CFeedsDatabase::FolderItemAddHelperL
       
  1331 //
       
  1332 // Add a new entry.
       
  1333 // -----------------------------------------------------------------------------
       
  1334 //
       
  1335 void CFeedsDatabase::FolderItemAddHelperL(TInt aFolderListId, const TDesC& aTitle,
       
  1336                 const TDesC& aUrl, TBool aIsFolder, TInt aSiblingIndex, TInt aParentEntryId,
       
  1337                 TInt& aOutFolderId, TInt& aOutFeedId, TInt aFreq)
       
  1338     {
       
  1339 
       
  1340 	HBufC*		safeTitle = NULL;
       
  1341 	TBool		found(ETrue);
       
  1342 	TBuf<K100MaxLen>	NewTitle;
       
  1343 	
       
  1344 	aOutFeedId = KUnassignedId;
       
  1345 
       
  1346 	// Get a unique id for this new folder item.
       
  1347 	aOutFolderId = NextFolderItemIdL();
       
  1348 
       
  1349 	// Remove any chars that may not be database safe.
       
  1350 	safeTitle = aTitle.AllocLC();
       
  1351 
       
  1352 	do
       
  1353 		{
       
  1354 		TInt pos(0);
       
  1355 		if ((pos = safeTitle->Locate('\'')) != KErrNotFound)
       
  1356 			{            
       
  1357 			safeTitle->Des().Delete(pos, 1);
       
  1358 			}
       
  1359 		else
       
  1360 			{
       
  1361 			found = EFalse;
       
  1362 			}
       
  1363 		}
       
  1364 	while (found);
       
  1365 	
       
  1366     if(safeTitle->Des().Length()>NewTitle.MaxLength()-KResvSpaceForDupTitles)
       
  1367     {
       
  1368     	safeTitle->Des().SetLength(NewTitle.MaxLength()-KResvSpaceForDupTitles);
       
  1369     }
       
  1370     
       
  1371     // Fixed for Bug id - JJUN-78VES7 (FeedsServer crashes under IPC attack)
       
  1372     // It is a common mistake to use Des() to create a TDesC16& reference. 
       
  1373     // While not incorrect, it is simpler and much more efficient to simply dereference
       
  1374     // the heap descriptor.
       
  1375 
       
  1376 	if( ValidateFeedFolderTitleL(aFolderListId, aParentEntryId, *safeTitle, aIsFolder, NewTitle) )
       
  1377 		{
       
  1378 		// Add it to the feed table if its a new feed.
       
  1379 		if (!aIsFolder)
       
  1380 			{
       
  1381             aOutFeedId = CommitFeedL(aFolderListId, NewTitle, aUrl, aFreq);
       
  1382 			}
       
  1383 		// Add it to the folder list table.
       
  1384 		CommitFolderListL(aFolderListId, aOutFolderId, aParentEntryId, aSiblingIndex, 
       
  1385 							aIsFolder, aOutFeedId, NewTitle);
       
  1386 		}
       
  1387 		
       
  1388 	CleanupStack::PopAndDestroy(safeTitle);
       
  1389 	}
       
  1390 
       
  1391 // -----------------------------------------------------------------------------
       
  1392 // CFeedsDatabase::FolderItemUpdateL
       
  1393 //
       
  1394 // Update an entry.
       
  1395 // -----------------------------------------------------------------------------
       
  1396 //
       
  1397 void CFeedsDatabase::FolderItemUpdateL(TInt aFolderItemId, 
       
  1398         const TDesC& aTitle, const TDesC& aUrl, TInt aFreq)
       
  1399     {
       
  1400     TDbSeekKey  folderListKey(aFolderItemId);
       
  1401 
       
  1402     // Open the various tables
       
  1403     UseFolderListTableLC(RDbTable::EUpdatable);
       
  1404     TInt  feedId = KUnassignedId;
       
  1405     TInt  folderListId = 0;
       
  1406     if (iFolderListTable.SeekL(folderListKey))
       
  1407         {
       
  1408         TBool  isFolder;
       
  1409     //    TInt   folderListId;
       
  1410         
       
  1411         // Update the title in the folder list table.
       
  1412         iFolderListTable.GetL();
       
  1413         iFolderListTable.UpdateL();
       
  1414         
       
  1415         isFolder = iFolderListTable.ColUint8(iFolderListColSet->ColNo(KIsFolder));
       
  1416      //   folderListId = iFolderListTable.ColInt32(iFolderListColSet->ColNo(KFolderListId));
       
  1417 
       
  1418         iFolderListTable.SetColL(iFolderListColSet->ColNo(KTitle_100MaxLen), 
       
  1419                 aTitle.Left(K100MaxLen));
       
  1420             
       
  1421         // If the entry is a feed then make sure the feed id is still valid.
       
  1422         if (!isFolder)
       
  1423             {    
       
  1424             feedId = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KFeedId));
       
  1425             folderListId = iFolderListTable.ColInt32(iFolderListColSet->ColNo(KFolderListId));
       
  1426             // Resolve the url to determine if this feed is already subscribed to.  If it's
       
  1427             // a new feed it is added to the database.
       
  1428             //if (!FeedIdFromUrlL(aUrl, folderListId, feedId))
       
  1429             //    {
       
  1430             //    feedId = CommitFeedL(folderListId, aTitle, aUrl);
       
  1431             //    }
       
  1432 
       
  1433 
       
  1434 		    UseFeedTableLC(RDbTable::EUpdatable);
       
  1435 	        TDbSeekKey  seekKey((TUint16) feedId);
       
  1436         
       
  1437         	if (iFeedTable.SeekL(seekKey))
       
  1438         	    {        
       
  1439         	    iFeedTable.GetL();
       
  1440         	    iFeedTable.UpdateL();
       
  1441         	    }
       
  1442         	else
       
  1443         	    {
       
  1444         	    User::Leave(KErrCorrupt);
       
  1445         	    }
       
  1446 		    iFeedTable.SetColL(iFeedColSet->ColNo(KTitle_100MaxLen), aTitle.Left(K100MaxLen));
       
  1447     		WriteLongTextL(iFeedTable, iFeedColSet->ColNo(KFeedUrl), aUrl);
       
  1448             iFeedTable.SetColL(iFeedColSet->ColNo(KAutoUpdateFreq), aFreq);
       
  1449 			iFeedTable.PutL();
       
  1450 		    CleanupStack::PopAndDestroy(/*feed table*/);  
       
  1451 		    // Set the feed id.
       
  1452             //iFolderListTable.SetColL(iFolderListColSet->ColNo(KFeedId), feedId);
       
  1453             }
       
  1454 
       
  1455         iFolderListTable.PutL();
       
  1456         if(feedId != KUnassignedId)
       
  1457             {
       
  1458             iFeedsServer->UpdateFeedL(folderListId,feedId,EFalse);
       
  1459             }
       
  1460         }
       
  1461     
       
  1462     // Clean up.
       
  1463     CleanupStack::PopAndDestroy(/*folder list table*/);
       
  1464     }
       
  1465 
       
  1466 
       
  1467 // -----------------------------------------------------------------------------
       
  1468 // CFeedsDatabase::FolderItemDeleteL
       
  1469 //
       
  1470 // Delete the given folder items and any newly unreferenced feeds.
       
  1471 // -----------------------------------------------------------------------------
       
  1472 //
       
  1473 void CFeedsDatabase::FolderItemDeleteL(const RArray<TInt>& aFolderItemIds, TBool aSessionCalled)
       
  1474     {
       
  1475     RArray<TInt> feedIds;
       
  1476 
       
  1477     CleanupClosePushL(feedIds);
       
  1478 	if(aSessionCalled)
       
  1479 		{
       
  1480 	    iDeleteFolderArray.Reset();
       
  1481 	    for(TInt i = 0; i < aFolderItemIds.Count(); i++)
       
  1482 		    {
       
  1483 			iDeleteFolderArray.AppendL(aFolderItemIds[i]);
       
  1484 		    }
       
  1485     	}
       
  1486     // Delete the items, including all the children of any folders.
       
  1487     FolderItemDeleteHelperL(aFolderItemIds, feedIds);
       
  1488 
       
  1489     // Purge unreferenced feeds.
       
  1490     for (TInt i = 0; i < feedIds.Count(); i++)
       
  1491         {                
       
  1492         PurgeFeedIfNotReferencedL(feedIds[i]);
       
  1493         }
       
  1494         
       
  1495 	CleanupStack::PopAndDestroy(/*feedIds*/);
       
  1496     }
       
  1497     
       
  1498 
       
  1499 // -----------------------------------------------------------------------------
       
  1500 // CFeedsDatabase::FolderListDeleteL
       
  1501 //
       
  1502 // Delete anything under the folder list.
       
  1503 // -----------------------------------------------------------------------------
       
  1504 //
       
  1505 void CFeedsDatabase::FolderListDeleteL( TInt aFolderListId )
       
  1506     {
       
  1507     HBufC*  query = NULL;
       
  1508     RArray<TInt> feedIds;
       
  1509 
       
  1510     // Purge the feeds and their items, enclosures.
       
  1511     CleanupClosePushL(feedIds);  
       
  1512     AllFeedIdsL( feedIds, aFolderListId );
       
  1513     for (TInt i = 0; i < feedIds.Count(); i++)
       
  1514         {                
       
  1515         FeedPurgeL(feedIds[i], ETrue);
       
  1516         }       
       
  1517 	CleanupStack::PopAndDestroy(/*feedIds*/);
       
  1518 
       
  1519     // Delete the folder items from the FolderListTable.
       
  1520     // DELETE FROM FolderListTable WHERE FolderListId = aFolderListId
       
  1521     _LIT(KQuery, "DELETE FROM FolderListTable WHERE FolderListId = %d");
       
  1522     query = HBufC::NewLC(KQuery().Length() + KIntLength);                 
       
  1523     query->Des().Format(KQuery, aFolderListId);   
       
  1524     // err is KErrNone even multiple records are deleted
       
  1525     TInt err = iDatabase.Execute(*query);
       
  1526     CleanupStack::PopAndDestroy(query);
       
  1527     iFeedsServer->ScheduleUpdateManagerL(aFolderListId);
       
  1528     }
       
  1529     
       
  1530     
       
  1531 // -----------------------------------------------------------------------------
       
  1532 // CFeedsDatabase::FolderItemDeleteHelperL
       
  1533 //
       
  1534 // Delete the given folder items and store the feedIds in aFeedIds.  aFeedIds 
       
  1535 // can then be used to delete any newly unreferenced feeds.
       
  1536 // -----------------------------------------------------------------------------
       
  1537 //
       
  1538 void CFeedsDatabase::FolderItemDeleteHelperL(const RArray<TInt>& aFolderItemIds,
       
  1539         RArray<TInt>& aFeedIds)
       
  1540     {
       
  1541     TInt  parentId = 0;
       
  1542     TInt  err;
       
  1543     TInt  statusCode;
       
  1544     
       
  1545     if (aFolderItemIds.Count() == 0)
       
  1546         {
       
  1547         return;
       
  1548         }
       
  1549         
       
  1550     // Use the table.
       
  1551     UseFolderListTableLC(RDbTable::EUpdatable);
       
  1552     
       
  1553     // Delete each of the entries.
       
  1554     for (TInt i = 0; i < aFolderItemIds.Count(); i++)
       
  1555         {        
       
  1556         // Find the entry.
       
  1557         TDbSeekKey  seekKey(aFolderItemIds[i]);
       
  1558         
       
  1559         if (iFolderListTable.SeekL(seekKey))
       
  1560             {            
       
  1561             TInt   folderItemId;
       
  1562             TInt   feedId;
       
  1563             TBool  isFolder;
       
  1564 
       
  1565             iFolderListTable.GetL();
       
  1566 
       
  1567             // Get the parent, so it can adjust the sibling order.  This only 
       
  1568             // needs to be done once -- on the first iter...
       
  1569             if (i == 0)
       
  1570                 {
       
  1571                 parentId = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KParentId));
       
  1572                 }
       
  1573 
       
  1574             folderItemId = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KFolderItemId));
       
  1575             feedId = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KFeedId));
       
  1576             isFolder = iFolderListTable.ColUint8(iFolderListColSet->ColNo(KIsFolder));
       
  1577             statusCode = iFolderListTable.ColInt32(iFolderListColSet->ColNo(KStatus));
       
  1578             // Delete it.
       
  1579             iFolderListTable.DeleteL();
       
  1580             
       
  1581             // If this is a folder then all of the children need to be deleted too.
       
  1582             if (isFolder)
       
  1583                 {
       
  1584                 RArray<TInt>  children;
       
  1585                 
       
  1586                 // Get the children.
       
  1587                 CleanupClosePushL(children);                
       
  1588                 FolderItemGetChildrenL(folderItemId, children);
       
  1589                 
       
  1590                 // Delete the children.
       
  1591                 FolderItemDeleteL(children);                
       
  1592                 CleanupStack::PopAndDestroy(/*children*/);                
       
  1593                 }
       
  1594                
       
  1595             // Otherwise add the feed-id to the array of potentially unreferenced feeds.
       
  1596             else
       
  1597                 {
       
  1598                 err = aFeedIds.InsertInOrder(feedId);
       
  1599                 if ((err != KErrNone) && (err != KErrAlreadyExists))
       
  1600                     {
       
  1601                     User::Leave(err);
       
  1602                     }
       
  1603                 }
       
  1604             if(statusCode != KErrNone && iDeleteFolderArray.Find(folderItemId) != KErrNotFound)
       
  1605             	{
       
  1606             	TInt parent = parentId;
       
  1607             	TInt previousStatus = KErrNone;
       
  1608         	    while(parent != KRootFolderId)
       
  1609         	    	{
       
  1610             		TDbSeekKey  folderListKey(parent);
       
  1611             		if(iFolderListTable.SeekL(folderListKey))
       
  1612             			{
       
  1613             	        iFolderListTable.GetL();
       
  1614             			parent = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KParentId));
       
  1615             			previousStatus = iFolderListTable.ColInt32(iFolderListColSet->ColNo(KStatus));
       
  1616         				iFolderListTable.UpdateL(); 
       
  1617         				// Folder status value should be -ve of total errorneous folder/feeds contained by it.
       
  1618         				TInt status = previousStatus + 1;
       
  1619         				iFolderListTable.SetColL(iFolderListColSet->ColNo(KStatus), status);
       
  1620         				iFolderListTable.PutL();
       
  1621 
       
  1622             			if(status != KErrNone)
       
  1623             				{
       
  1624             					break;
       
  1625             				}
       
  1626             			}
       
  1627         	    	}
       
  1628 
       
  1629             	}
       
  1630             }
       
  1631         }
       
  1632         
       
  1633     // Fix up the sibling indexes.
       
  1634     AdjustSiblingIndexesL(parentId);
       
  1635     
       
  1636     // Clean up.
       
  1637     CleanupStack::PopAndDestroy(/*folder list table*/);
       
  1638     }
       
  1639     
       
  1640     
       
  1641 // -----------------------------------------------------------------------------
       
  1642 // CFeedsDatabase::FolderItemMoveL
       
  1643 //
       
  1644 // Move the folder items within their parent.
       
  1645 // -----------------------------------------------------------------------------
       
  1646 //
       
  1647 void CFeedsDatabase::FolderItemMoveL(const RArray<TInt>& aFolderItemIds, 
       
  1648         TInt aNewIndex)
       
  1649     {
       
  1650     TInt  parentId = 0;
       
  1651     TInt  count;
       
  1652                 
       
  1653     if (aFolderItemIds.Count() == 0)
       
  1654         {
       
  1655         return;
       
  1656         }
       
  1657         
       
  1658     // Use the table.
       
  1659     UseFolderListTableLC(RDbTable::EUpdatable);
       
  1660     count = iFolderListTable.CountL();
       
  1661     
       
  1662     // 1) Move the entries to the end, by changing there sibling indexes.
       
  1663     for (TInt i = 0; i < aFolderItemIds.Count(); i++)
       
  1664         {        
       
  1665         // Find the entry.
       
  1666         TDbSeekKey  seekKey(aFolderItemIds[i]);
       
  1667         
       
  1668         if (iFolderListTable.SeekL(seekKey))
       
  1669             {
       
  1670             iFolderListTable.GetL();
       
  1671 
       
  1672             // Get the parent This only needs to be done once -- on the first iter...
       
  1673             if (i == 0)
       
  1674                 {   
       
  1675                 parentId = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KParentId));         
       
  1676                 }
       
  1677                 
       
  1678             iFolderListTable.UpdateL();
       
  1679             iFolderListTable.SetColL(iFolderListColSet->ColNo(KSiblingOrder), count + i);
       
  1680             iFolderListTable.PutL();
       
  1681             }
       
  1682         }
       
  1683 
       
  1684     // 2) Create a hole for the entries to be moved to, this also adjusts all of the
       
  1685     //    indexes to remove any holes that may have been created by the move.
       
  1686     CreateSiblingIndexHoleL(parentId, aNewIndex, aFolderItemIds.Count());
       
  1687 
       
  1688     // 3) Move the entries into the newly created hole by changing their sibling indexes.
       
  1689     for (TInt i = 0; i < aFolderItemIds.Count(); i++)
       
  1690         {        
       
  1691         // Find the entry.
       
  1692         TDbSeekKey  seekKey(aFolderItemIds[i]);
       
  1693         
       
  1694         if (iFolderListTable.SeekL(seekKey))
       
  1695             {
       
  1696             iFolderListTable.GetL();
       
  1697 
       
  1698             iFolderListTable.UpdateL();
       
  1699             iFolderListTable.SetColL(iFolderListColSet->ColNo(KSiblingOrder), aNewIndex + i);
       
  1700             iFolderListTable.PutL();
       
  1701             }
       
  1702         }
       
  1703     
       
  1704     // Clean up.
       
  1705     CleanupStack::PopAndDestroy(/*folder list table*/);
       
  1706     }
       
  1707     
       
  1708     
       
  1709 // -----------------------------------------------------------------------------
       
  1710 // CFeedsDatabase::FolderItemMoveToL
       
  1711 //
       
  1712 // Move the entries to another parent.
       
  1713 // -----------------------------------------------------------------------------
       
  1714 //
       
  1715 void CFeedsDatabase::FolderItemMoveToL(const RArray<TInt>& aFolderItemIds, 
       
  1716         TInt aNewParent)
       
  1717     {
       
  1718     TInt  parentId = 0;
       
  1719     TInt  statusCode = KErrNone;
       
  1720 
       
  1721     if (aFolderItemIds.Count() == 0)
       
  1722         {
       
  1723         return;
       
  1724         }
       
  1725         
       
  1726     // Use the table.
       
  1727     UseFolderListTableLC(RDbTable::EUpdatable);
       
  1728     
       
  1729     // Move each of the entries.
       
  1730     for (TInt i = 0; i < aFolderItemIds.Count(); i++)
       
  1731         {        
       
  1732         // Find the entry.
       
  1733         TDbSeekKey seekKey(aFolderItemIds[i]);
       
  1734         
       
  1735         if (iFolderListTable.SeekL(seekKey))
       
  1736             {
       
  1737             iFolderListTable.GetL();
       
  1738 
       
  1739             // Create a hole in the new parent folder for the items to be moved.  This only 
       
  1740             // needs to be done once -- on the first iter...
       
  1741             if (i == 0)
       
  1742                 {                   
       
  1743                 parentId = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KParentId));         
       
  1744                 CreateSiblingIndexHoleL(aNewParent, 0, aFolderItemIds.Count());
       
  1745                 }
       
  1746             statusCode = iFolderListTable.ColInt32(iFolderListColSet->ColNo(KStatus));
       
  1747             // Change the new parent and sibling index.  The moved folder items are placed
       
  1748             // at the beginning of the new parent.
       
  1749             iFolderListTable.UpdateL();
       
  1750             iFolderListTable.SetColL(iFolderListColSet->ColNo(KParentId), aNewParent);
       
  1751             iFolderListTable.SetColL(iFolderListColSet->ColNo(KSiblingOrder), i);
       
  1752             iFolderListTable.PutL();
       
  1753             
       
  1754             if(statusCode != KErrNone)
       
  1755             	{
       
  1756             	TInt parent = parentId;
       
  1757             	TInt previousStatus = KErrNone;
       
  1758         	    while(parent != KRootFolderId)
       
  1759         	    	{
       
  1760             		TDbSeekKey  folderListKey(parent);
       
  1761             		if(iFolderListTable.SeekL(folderListKey))
       
  1762             			{
       
  1763             	        iFolderListTable.GetL();
       
  1764             			parent = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KParentId));
       
  1765             			previousStatus = iFolderListTable.ColInt32(iFolderListColSet->ColNo(KStatus));
       
  1766         				iFolderListTable.UpdateL();
       
  1767         				TInt status = previousStatus + 1;
       
  1768         				iFolderListTable.SetColL(iFolderListColSet->ColNo(KStatus), status);
       
  1769         				iFolderListTable.PutL();
       
  1770 
       
  1771             			if(status != KErrNone)
       
  1772             				{
       
  1773             					break;
       
  1774             				}
       
  1775             			}
       
  1776         	    	}
       
  1777             	parent = aNewParent;
       
  1778         	    while(parent != KRootFolderId)
       
  1779         	    	{
       
  1780             		TDbSeekKey  folderListKey(parent);
       
  1781             		if(iFolderListTable.SeekL(folderListKey))
       
  1782             			{
       
  1783             	        iFolderListTable.GetL();
       
  1784             			parent = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KParentId));
       
  1785             			previousStatus = iFolderListTable.ColInt32(iFolderListColSet->ColNo(KStatus));
       
  1786         				iFolderListTable.UpdateL();
       
  1787         				iFolderListTable.SetColL(iFolderListColSet->ColNo(KStatus), previousStatus - 1);
       
  1788         				iFolderListTable.PutL();
       
  1789 
       
  1790             			if(previousStatus != KErrNone)
       
  1791             				{
       
  1792             					break;
       
  1793             				}
       
  1794             			}
       
  1795         	    	}
       
  1796             		
       
  1797             	}
       
  1798             }
       
  1799         }
       
  1800     
       
  1801     // Fix up the sibling indexes of the old parent.
       
  1802     AdjustSiblingIndexesL(parentId);
       
  1803     
       
  1804     // Clean up.
       
  1805     CleanupStack::PopAndDestroy(/*folder list table*/);
       
  1806     }
       
  1807     
       
  1808     
       
  1809 // -----------------------------------------------------------------------------
       
  1810 // CFeedsDatabase::AdjustSiblingIndexesL
       
  1811 //
       
  1812 // Reorders the sibling indexes.
       
  1813 // -----------------------------------------------------------------------------
       
  1814 //
       
  1815 void CFeedsDatabase::AdjustSiblingIndexesL(TInt aParentId)
       
  1816     {
       
  1817     RDbView  view;
       
  1818     HBufC*   query = NULL;
       
  1819     TInt     siblingIndex = 0;
       
  1820     
       
  1821     // Create a view given this select...    
       
  1822     // SELECT SiblingOrder FROM FolderListTable WHERE ParentId = aParentId ORDER BY SiblingOrder    
       
  1823     _LIT(KQuery, "SELECT SiblingOrder FROM FolderListTable WHERE ParentId = %d ORDER BY SiblingOrder");
       
  1824     
       
  1825     query = HBufC::NewLC(KQuery().Length() + KIntLength); 
       
  1826             
       
  1827     query->Des().Format(KQuery, aParentId);
       
  1828 
       
  1829     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EUpdatable));
       
  1830 
       
  1831     CleanupStack::PopAndDestroy(query);
       
  1832     CleanupClosePushL(view);
       
  1833 
       
  1834     CDbColSet* colSet = view.ColSetL();
       
  1835     CleanupStack::PushL(colSet);
       
  1836         
       
  1837     // Reorder each entry in the given folder-list and parent folder.
       
  1838     if (view.EvaluateAll() >= 0)
       
  1839         {
       
  1840         for (view.FirstL(); view.AtRow(); view.NextL())
       
  1841             {
       
  1842             // Get the current row.
       
  1843             view.GetL();
       
  1844 
       
  1845             // Update the order.
       
  1846             view.UpdateL();
       
  1847             view.SetColL(colSet->ColNo(KSiblingOrder), siblingIndex++);
       
  1848             view.PutL();
       
  1849             }
       
  1850         }
       
  1851         
       
  1852     CleanupStack::PopAndDestroy(colSet);
       
  1853     CleanupStack::PopAndDestroy(/*view*/);
       
  1854     }
       
  1855     
       
  1856     
       
  1857 // -----------------------------------------------------------------------------
       
  1858 // CFeedsDatabase::CreateSiblingIndexHoleL
       
  1859 //
       
  1860 // Creates a hole in the sibling index.
       
  1861 // -----------------------------------------------------------------------------
       
  1862 //
       
  1863 void CFeedsDatabase::CreateSiblingIndexHoleL(TInt aParentId, TInt aNewIndex, TInt aHoleSize)
       
  1864     {
       
  1865     RDbView  view;
       
  1866     HBufC*   query = NULL;
       
  1867     TInt     siblingIndex = 0;
       
  1868     
       
  1869     // Create a view given this select...    
       
  1870     // SELECT SiblingOrder FROM FolderListTable 
       
  1871     // WHERE ParentId = aParentId
       
  1872     // ORDER BY SiblingOrder
       
  1873     _LIT(KQuery, "SELECT SiblingOrder FROM FolderListTable WHERE ParentId = %d ORDER BY SiblingOrder");
       
  1874     
       
  1875     query = HBufC::NewLC(KQuery().Length() + KIntLength); 
       
  1876                         
       
  1877     query->Des().Format(KQuery, aParentId);
       
  1878 
       
  1879     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EUpdatable));
       
  1880 
       
  1881     CleanupStack::PopAndDestroy(query);
       
  1882     CleanupClosePushL(view);
       
  1883 
       
  1884     CDbColSet* colSet = view.ColSetL();
       
  1885     CleanupStack::PushL(colSet);
       
  1886         
       
  1887     // Reorder each entry in the given folder-list and parent folder.
       
  1888     if (view.EvaluateAll() >= 0)
       
  1889         {
       
  1890         TInt  index = 0;
       
  1891 
       
  1892         for (view.FirstL(); view.AtRow(); view.NextL())
       
  1893             {
       
  1894             // Get the current row.
       
  1895             view.GetL();
       
  1896 
       
  1897             siblingIndex = view.ColUint16(colSet->ColNo(KSiblingOrder));
       
  1898             
       
  1899             if (index == aNewIndex)
       
  1900                 {
       
  1901                 index += aHoleSize;
       
  1902                 }
       
  1903                 
       
  1904             // Update the order.
       
  1905             if (index != siblingIndex)
       
  1906                 {                
       
  1907                 view.UpdateL();
       
  1908                 view.SetColL(colSet->ColNo(KSiblingOrder), index);
       
  1909                 view.PutL();
       
  1910                 }
       
  1911                 
       
  1912             index++;
       
  1913             }
       
  1914         }
       
  1915         
       
  1916     CleanupStack::PopAndDestroy(colSet);
       
  1917     CleanupStack::PopAndDestroy(/*view*/);
       
  1918     }
       
  1919     
       
  1920     
       
  1921 // -----------------------------------------------------------------------------
       
  1922 // CFeedsDatabase::FolderItemGetChildrenL
       
  1923 //
       
  1924 // Extract the folder-item-ids of the children of the given parent.
       
  1925 // -----------------------------------------------------------------------------
       
  1926 //
       
  1927 void CFeedsDatabase::FolderItemGetChildrenL(TInt aFolderItemId, RArray<TInt>& aChildren)
       
  1928     {
       
  1929     RDbView  view;
       
  1930     HBufC*   query = NULL;
       
  1931     
       
  1932     // Create a view given this select...    
       
  1933     // SELECT FolderItemId FROM FolderListTable WHERE ParentId = aFolderItemId 
       
  1934     _LIT(KQuery, "SELECT FolderItemId FROM FolderListTable WHERE ParentId = %d");
       
  1935     
       
  1936     query = HBufC::NewLC(KQuery().Length() + KIntLength); 
       
  1937                         
       
  1938     query->Des().Format(KQuery, aFolderItemId);
       
  1939 
       
  1940     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EReadOnly));
       
  1941 
       
  1942     CleanupStack::PopAndDestroy(query);
       
  1943     CleanupClosePushL(view);
       
  1944 
       
  1945     CDbColSet* colSet = view.ColSetL();
       
  1946     CleanupStack::PushL(colSet);
       
  1947 
       
  1948     // Extract and add the children's folder-item-id to aChildren.        
       
  1949     if (view.EvaluateAll() >= 0)
       
  1950         {
       
  1951         for (view.FirstL(); view.AtRow(); view.NextL())
       
  1952             {
       
  1953             TInt   folderItemId;
       
  1954             
       
  1955             // Get the current row.
       
  1956             view.GetL();
       
  1957         
       
  1958             // Get the fields
       
  1959             folderItemId = view.ColUint16(colSet->ColNo(KFolderItemId));
       
  1960             
       
  1961             // Append it.
       
  1962             aChildren.AppendL(folderItemId);
       
  1963             }
       
  1964         }
       
  1965         
       
  1966     CleanupStack::PopAndDestroy(colSet);
       
  1967     CleanupStack::PopAndDestroy(/*view*/);
       
  1968     }
       
  1969 
       
  1970 
       
  1971 // -----------------------------------------------------------------------------
       
  1972 // CFeedsDatabase::FeedUpdateItemStatusL
       
  1973 //
       
  1974 // Update the status of each of the items in the given feed.
       
  1975 // -----------------------------------------------------------------------------
       
  1976 //
       
  1977 void CFeedsDatabase::FeedUpdateItemStatusL(TInt aFeedId, 
       
  1978         const RArray<TInt>& aItemIds, const RArray<TInt>& aItemStatus, TInt aUnreadCount)
       
  1979     {
       
  1980     HBufC*   query = NULL;
       
  1981     RDbView  view;
       
  1982     
       
  1983     if (aItemIds.Count() == 0)
       
  1984         {
       
  1985         return;
       
  1986         }
       
  1987         
       
  1988     // Perpare the query.    
       
  1989     // SELECT ItemId, ItemStatus FROM ItemTable WHERE FeedId = aFeedId
       
  1990     _LIT(KQuery, "SELECT ItemId, ItemStatus FROM ItemTable WHERE FeedId = %d");
       
  1991     
       
  1992     query = HBufC::NewLC(KQuery().Length() + KIntLength); 
       
  1993                         
       
  1994     query->Des().Format(KQuery, aFeedId);
       
  1995 
       
  1996     // Execute the query.
       
  1997     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EUpdatable));
       
  1998     CleanupStack::PopAndDestroy(query);
       
  1999     CleanupClosePushL(view);
       
  2000 
       
  2001     CDbColSet* colSet = view.ColSetL();
       
  2002     CleanupStack::PushL(colSet);
       
  2003         
       
  2004     // Purge the old items.
       
  2005     if (view.EvaluateAll() >= 0)
       
  2006         {
       
  2007         for (view.FirstL(); view.AtRow(); view.NextL())
       
  2008             {
       
  2009             TInt  itemId;
       
  2010             TInt  itemStatus;
       
  2011             TInt  pos;
       
  2012             
       
  2013             // Get the current row.
       
  2014             view.GetL();
       
  2015 
       
  2016             // Get the itemId and current Status.
       
  2017             itemId = view.ColUint16(colSet->ColNo(KItemId));
       
  2018             itemStatus = view.ColUint16(colSet->ColNo(KItemStatus));
       
  2019             
       
  2020             // If found in aItemIds update its status.
       
  2021             if ((pos = aItemIds.Find(itemId)) != KErrNotFound)
       
  2022                 {
       
  2023                 if (aItemStatus[pos] != itemStatus)
       
  2024                     {                    
       
  2025                     view.UpdateL();
       
  2026                     view.SetColL(colSet->ColNo(KItemStatus), aItemStatus[pos]);
       
  2027                     view.PutL();
       
  2028                     }
       
  2029                 }
       
  2030             } // for loop
       
  2031 
       
  2032         // Prep the feed table.
       
  2033         UseFeedTableLC(RDbTable::EUpdatable);
       
  2034         // update the unread count for the feed
       
  2035         TDbSeekKey  seekKey((TUint16) aFeedId);
       
  2036         if (iFeedTable.SeekL(seekKey))
       
  2037             {        
       
  2038             // Write the count
       
  2039             iFeedTable.GetL();
       
  2040             iFeedTable.UpdateL();
       
  2041             iFeedTable.SetColL(iFeedColSet->ColNo(KUnreadCount), aUnreadCount);    
       
  2042             iFeedTable.PutL();
       
  2043             }
       
  2044         CleanupStack::PopAndDestroy(/*Feed Table*/);
       
  2045         }
       
  2046         
       
  2047     CleanupStack::PopAndDestroy(colSet);
       
  2048     CleanupStack::PopAndDestroy(/*view*/);
       
  2049     }
       
  2050     
       
  2051 
       
  2052 // -----------------------------------------------------------------------------
       
  2053 // CFeedsDatabase::PurgeFeedIfNotReferencedL
       
  2054 //
       
  2055 // Deletes the feed if the feedId isn't referenced in the folder-list table.
       
  2056 // -----------------------------------------------------------------------------
       
  2057 //
       
  2058 void CFeedsDatabase::PurgeFeedIfNotReferencedL(TInt aFeedId)
       
  2059     {
       
  2060     RDbView  view;
       
  2061     HBufC*   query = NULL;
       
  2062     TBool    deleted = EFalse;
       
  2063     
       
  2064     // Create a view given this select...    
       
  2065     // SELECT FolderItemId FROM FolderListTable WHERE FeedId = aFeedId 
       
  2066     _LIT(KQuery, "SELECT FolderItemId FROM FolderListTable WHERE FeedId = %d");
       
  2067     
       
  2068     query = HBufC::NewLC(KQuery().Length() + KIntLength); 
       
  2069                         
       
  2070     query->Des().Format(KQuery, aFeedId);
       
  2071 
       
  2072     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EReadOnly));
       
  2073 
       
  2074     CleanupStack::PopAndDestroy(query);
       
  2075     CleanupClosePushL(view);
       
  2076 
       
  2077     CDbColSet* colSet = view.ColSetL();
       
  2078     CleanupStack::PushL(colSet);
       
  2079 
       
  2080     // Evalulate the query if no rows are returned then purge the feed.
       
  2081     if (view.Evaluate() >= 0)
       
  2082         {
       
  2083         view.FirstL();
       
  2084         if (!view.AtRow())
       
  2085             {
       
  2086             FeedPurgeL(aFeedId, ETrue);
       
  2087             deleted = ETrue;
       
  2088             }
       
  2089         }
       
  2090         
       
  2091     CleanupStack::PopAndDestroy(colSet);
       
  2092     CleanupStack::PopAndDestroy(/*view*/);    
       
  2093     if(deleted)
       
  2094         {
       
  2095         iFeedsServer->UpdateFeedL(KNoFolderListId,aFeedId,ETrue);
       
  2096         }
       
  2097     }
       
  2098     
       
  2099     
       
  2100 // -----------------------------------------------------------------------------
       
  2101 // CFeedsDatabase::FeedPurgeL
       
  2102 //
       
  2103 // Removes the feed's items also deletes the feed if aDeleteFeed is ETrue.
       
  2104 // It is only safe to call this method with aDeleteFeed set to ETrue if
       
  2105 // aFeedId is not found in the FolderListTable.
       
  2106 // -----------------------------------------------------------------------------
       
  2107 //
       
  2108 void CFeedsDatabase::FeedPurgeL(TInt aFeedId, TBool aDeleteFeed)
       
  2109     {
       
  2110     HBufC*  query = NULL;
       
  2111         
       
  2112     // Delete the enclosures from the Enclosure Table.  This is done first to 
       
  2113     // Ensure that enclosures don't get ophaned if the delete-items query leaves.
       
  2114     // DELETE FROM EnclosureTable WHERE FeedId = aFeedId
       
  2115     _LIT(KQueryE, "DELETE FROM EnclosureTable WHERE FeedId = %d");
       
  2116 
       
  2117     query = HBufC::NewLC(KQueryE().Length() + KIntLength);                 
       
  2118     query->Des().Format(KQueryE, aFeedId);
       
  2119     
       
  2120     // err is KErrNone even multiple records are deleted
       
  2121     TInt err = iDatabase.Execute(*query);
       
  2122     CleanupStack::PopAndDestroy(query);
       
  2123 
       
  2124     // Delete the items from the Item Table
       
  2125     // DELETE FROM ItemTable WHERE FeedId = aFeedId
       
  2126     _LIT(KQueryI, "DELETE FROM ItemTable WHERE FeedId = %d");
       
  2127     query = HBufC::NewLC(KQueryI().Length() + KIntLength);                 
       
  2128     query->Des().Format(KQueryI, aFeedId);
       
  2129     
       
  2130     err = iDatabase.Execute(*query);
       
  2131     CleanupStack::PopAndDestroy(query);
       
  2132 
       
  2133     // Delete the feed from the Feed Table
       
  2134     if (aDeleteFeed)
       
  2135         {        
       
  2136         // DELETE FROM FeedTable WHERE FeedId = aFeedId
       
  2137         _LIT(KQueryF, "DELETE FROM FeedTable WHERE FeedId = %d");
       
  2138         query = HBufC::NewLC(KQueryF().Length() + KIntLength);                 
       
  2139         query->Des().Format(KQueryF, aFeedId);
       
  2140         
       
  2141         err = iDatabase.Execute(*query);
       
  2142         CleanupStack::PopAndDestroy(query);
       
  2143         }
       
  2144     }
       
  2145     
       
  2146     
       
  2147 // -----------------------------------------------------------------------------
       
  2148 // CFeedsDatabase::PurgeOldItemsL
       
  2149 //
       
  2150 // Purge any old items in the given feed.
       
  2151 // -----------------------------------------------------------------------------
       
  2152 //
       
  2153 void CFeedsDatabase::PurgeOldItemsL(TInt aFeedId, const TTime& aTimestamp)
       
  2154     {
       
  2155     HBufC*                        query = NULL;
       
  2156     TBuf<KMaxTimeFormatSpec * 2>  tsStr;
       
  2157     TBuf<KMaxTimeFormatSpec * 2>  temp;    
       
  2158     RDbView                       view;
       
  2159         // Convert aTimestamp to the query form -- i.e #1997-12-31 23:59:59#.
       
  2160     aTimestamp.FormatL(tsStr, TShortDateFormatSpec());
       
  2161     tsStr.Append(KSpace);
       
  2162     aTimestamp.FormatL(temp, TTimeFormatSpec());
       
  2163     tsStr.Append(temp);
       
  2164 
       
  2165     // Perpare the query.    
       
  2166     // SELECT ItemId, Date FROM ItemTable WHERE FeedId = aFeedId AND Date < #tsStr#
       
  2167     _LIT(KQuery, "SELECT ItemId, Date FROM ItemTable WHERE FeedId = %d AND Date < #%S#");
       
  2168     
       
  2169     query = HBufC::NewLC(KQuery().Length() + KIntLength + tsStr.Length()); 
       
  2170                         
       
  2171     query->Des().Format(KQuery, aFeedId, &tsStr);
       
  2172 
       
  2173     // Execute the query.
       
  2174     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EUpdatable));
       
  2175     CleanupStack::PopAndDestroy(query);
       
  2176     CleanupClosePushL(view);
       
  2177 
       
  2178     CDbColSet* colSet = view.ColSetL();
       
  2179     CleanupStack::PushL(colSet);
       
  2180         
       
  2181     // Purge the old items.
       
  2182     if (view.EvaluateAll() >= 0)
       
  2183         {
       
  2184         for (view.FirstL(); view.AtRow(); view.NextL())
       
  2185             {
       
  2186             TInt    itemId;
       
  2187             
       
  2188             // Get the current row.
       
  2189             view.GetL();
       
  2190 
       
  2191             // Get the itemId and date.
       
  2192             itemId = view.ColUint16(colSet->ColNo(KItemId));
       
  2193 
       
  2194             // Purge the associated enclosures.  This is done first to ensure that 
       
  2195             // enclosures don't get ophaned if the delete-item statement leaves.
       
  2196             PurgeEnclosuresL(aFeedId, itemId);
       
  2197             
       
  2198             // Delete the item.
       
  2199             view.DeleteL();
       
  2200             }
       
  2201         }
       
  2202         
       
  2203     CleanupStack::PopAndDestroy(colSet);
       
  2204     CleanupStack::PopAndDestroy(/*view*/);
       
  2205     }
       
  2206 
       
  2207 
       
  2208 // -----------------------------------------------------------------------------
       
  2209 // CFeedsDatabase::PurgeEnclosuresL
       
  2210 //
       
  2211 // Purge the associated enclosures
       
  2212 // -----------------------------------------------------------------------------
       
  2213 //
       
  2214 void CFeedsDatabase::PurgeEnclosuresL(TInt aFeedId, TInt aItemId)
       
  2215     {
       
  2216     HBufC*  query = NULL;
       
  2217 
       
  2218     // DELETE FROM EnclosureTable WHERE FeedId = aFeedId AND ItemId = aItemId
       
  2219     _LIT(KQuery, "DELETE FROM EnclosureTable WHERE FeedId = %d AND ItemId = %d");
       
  2220     
       
  2221     query = HBufC::NewLC(KQuery().Length() + KIntLength + KIntLength); 
       
  2222                         
       
  2223     query->Des().Format(KQuery, aFeedId, aItemId);
       
  2224     
       
  2225     User::LeaveIfError(iDatabase.Execute(*query));
       
  2226     CleanupStack::PopAndDestroy(query);
       
  2227     }
       
  2228     
       
  2229     
       
  2230 // -----------------------------------------------------------------------------
       
  2231 // CFeedsDatabase::PurgeOtherItemsL
       
  2232 //
       
  2233 // Purge all items not found in the given array.
       
  2234 // -----------------------------------------------------------------------------
       
  2235 //
       
  2236 TInt CFeedsDatabase::PurgeOtherItemsL(TInt aFeedId, const RArray<TInt>& aItemIds)
       
  2237     {
       
  2238     HBufC*   query = NULL;
       
  2239     RDbView  view;
       
  2240     TInt purgedUnreadNewCount = 0;
       
  2241 
       
  2242     // SELECT ItemId, ItemStatus FROM ItemTable WHERE FeedId = aFeedId
       
  2243     _LIT(KQuery, "SELECT ItemId, ItemStatus FROM ItemTable WHERE FeedId = %d");
       
  2244     
       
  2245     query = HBufC::NewLC(KQuery().Length() + KIntLength); 
       
  2246                         
       
  2247     query->Des().Format(KQuery, aFeedId);
       
  2248 
       
  2249     // Execute the query.
       
  2250     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EUpdatable));
       
  2251     CleanupStack::PopAndDestroy(query);
       
  2252     CleanupClosePushL(view);
       
  2253 
       
  2254     CDbColSet* colSet = view.ColSetL();
       
  2255     CleanupStack::PushL(colSet);
       
  2256         
       
  2257     // Purge the old items.
       
  2258     if (view.EvaluateAll() >= 0)
       
  2259         {
       
  2260         for (view.FirstL(); view.AtRow(); view.NextL())
       
  2261             {
       
  2262             TInt    itemId;
       
  2263             
       
  2264             // Get the current row.
       
  2265             view.GetL();
       
  2266 
       
  2267             itemId = view.ColUint16(colSet->ColNo(KItemId));
       
  2268             
       
  2269             // If this item isn't in aItemIds then delete the item and 
       
  2270             // its enclosures.
       
  2271             if (aItemIds.Find(itemId) == KErrNotFound)
       
  2272                 {                
       
  2273                 TInt itemStatus = view.ColUint8(colSet->ColNo(KItemStatus));
       
  2274                 if( itemStatus == EUnreadItem || itemStatus == ENewItem )
       
  2275                     {
       
  2276                     purgedUnreadNewCount++;
       
  2277                     }
       
  2278                 // Purge the associated enclosures.  This is done first to ensure that 
       
  2279                 // enclosures don't get ophaned if the delete-item statement leaves.
       
  2280                 PurgeEnclosuresL(aFeedId, itemId);
       
  2281                 
       
  2282                 // Delete the item.
       
  2283                 view.DeleteL();
       
  2284                 }
       
  2285             }
       
  2286         }
       
  2287         
       
  2288     CleanupStack::PopAndDestroy(colSet);
       
  2289     CleanupStack::PopAndDestroy(/*view*/);
       
  2290 
       
  2291     return purgedUnreadNewCount;
       
  2292     }
       
  2293 
       
  2294 
       
  2295 // -----------------------------------------------------------------------------
       
  2296 // CFeedsDatabase::ResetDatabaseL
       
  2297 //
       
  2298 // Reset the database.
       
  2299 // -----------------------------------------------------------------------------
       
  2300 //
       
  2301 void CFeedsDatabase::ResetDatabaseL()
       
  2302     {
       
  2303     TBuf<32> format;
       
  2304     format.Copy(KSecure);
       
  2305     format.Append(KSecureUid.Name());
       
  2306     
       
  2307     // Create the database file.
       
  2308     TInt err = iDatabase.Create( iDBs, iDatabasePath, format); 
       
  2309     User::LeaveIfError( err );
       
  2310         
       
  2311     // Create the tables.
       
  2312     CreateVersionTableL();
       
  2313     CreateFolderListTableL();
       
  2314     CreateFeedTableL();
       
  2315     CreateFeedItemTableL();
       
  2316     CreateItemEnclosureTableL();
       
  2317     CreateSettingsTableL();
       
  2318     }
       
  2319 
       
  2320 
       
  2321 // -----------------------------------------------------------------------------
       
  2322 // CFeedsDatabase::CreateVersionTableL
       
  2323 //
       
  2324 // Creates the version table.
       
  2325 // -----------------------------------------------------------------------------
       
  2326 //
       
  2327 void CFeedsDatabase::CreateVersionTableL()
       
  2328     {
       
  2329     CDbColSet*  colSet = NULL;
       
  2330     
       
  2331     // Create the table's column set.
       
  2332     colSet = CDbColSet::NewLC();
       
  2333     colSet->AddL(TDbCol(KVersion,         EDbColText16));
       
  2334     colSet->AddL(TDbCol(KVersionId,       EDbColUint16));
       
  2335     
       
  2336     // Create the table.
       
  2337     User::LeaveIfError(iDatabase.CreateTable(KVersionTable, *colSet));
       
  2338     CleanupStack::PopAndDestroy(colSet);
       
  2339 
       
  2340     // Prep the settings table.
       
  2341     UseVersionTableLC(RDbTable::EUpdatable);
       
  2342     
       
  2343     // Update the database.  There is only one row in this table...
       
  2344     iVersionTable.FirstL();
       
  2345     
       
  2346     if (iVersionTable.AtRow())
       
  2347         {        
       
  2348         iVersionTable.GetL();
       
  2349         iVersionTable.UpdateL();
       
  2350         }
       
  2351     else
       
  2352         {
       
  2353         iVersionTable.Reset();
       
  2354         iVersionTable.InsertL();
       
  2355         }
       
  2356     
       
  2357     iVersionTable.SetColL(iVersionColSet->ColNo(KVersionId), KVersion71);
       
  2358     
       
  2359     iVersionTable.PutL();
       
  2360     CleanupStack::PopAndDestroy(/* version table */);
       
  2361     }
       
  2362     
       
  2363 
       
  2364 // -----------------------------------------------------------------------------
       
  2365 // CFeedsDatabase::CreateFolderListTableL
       
  2366 //
       
  2367 // Creates the folder-list table.
       
  2368 // -----------------------------------------------------------------------------
       
  2369 //
       
  2370 void CFeedsDatabase::CreateFolderListTableL()
       
  2371     {
       
  2372     CDbColSet*  colSet = NULL;
       
  2373     TDbKeyCol   folderItemIdCol(KFolderItemId);
       
  2374     CDbKey*     indexKey = NULL;    
       
  2375     
       
  2376     // Create the table's column set.
       
  2377     colSet = CDbColSet::NewLC();
       
  2378     colSet->AddL(TDbCol(KFolderListId,    EDbColInt32));
       
  2379     colSet->AddL(TDbCol(KFolderItemId,    EDbColUint16));
       
  2380     colSet->AddL(TDbCol(KParentId,        EDbColUint16));
       
  2381     colSet->AddL(TDbCol(KSiblingOrder,    EDbColUint16));
       
  2382     colSet->AddL(TDbCol(KIsFolder,        EDbColUint8));
       
  2383     colSet->AddL(TDbCol(KFeedId,          EDbColUint16));
       
  2384     colSet->AddL(TDbCol(KTitle_100MaxLen, EDbColText16, K100MaxLen));
       
  2385     colSet->AddL(TDbCol(KStatus,		  EDbColInt32));
       
  2386     // Create the table.
       
  2387     User::LeaveIfError(iDatabase.CreateTable(KFolderListTable, *colSet));
       
  2388     CleanupStack::PopAndDestroy(colSet);
       
  2389 
       
  2390     // Index the table.    
       
  2391     indexKey = CDbKey::NewLC();
       
  2392 
       
  2393     indexKey->AddL(folderItemIdCol);
       
  2394     User::LeaveIfError(iDatabase.CreateIndex(KFolderListTableIndex, 
       
  2395             KFolderListTable, *indexKey));
       
  2396     CleanupStack::PopAndDestroy(indexKey);
       
  2397     }
       
  2398     
       
  2399 
       
  2400 // -----------------------------------------------------------------------------
       
  2401 // CFeedsDatabase::CreateFeedTableL
       
  2402 //
       
  2403 // Creates the feed table.
       
  2404 // -----------------------------------------------------------------------------
       
  2405 //
       
  2406 void CFeedsDatabase::CreateFeedTableL()
       
  2407     {
       
  2408     CDbColSet*  colSet = NULL;
       
  2409     TDbKeyCol   feedIdCol(KFeedId);
       
  2410     CDbKey*     indexKey = NULL;    
       
  2411     
       
  2412     // Create the table's column set.
       
  2413     colSet = CDbColSet::NewLC();
       
  2414     
       
  2415     colSet->AddL(TDbCol(KFolderListId,      EDbColInt32));
       
  2416     colSet->AddL(TDbCol(KFeedId,            EDbColUint16));
       
  2417     colSet->AddL(TDbCol(KDate,              EDbColDateTime));
       
  2418     colSet->AddL(TDbCol(KTitle_100MaxLen,   EDbColText16, K100MaxLen));
       
  2419     colSet->AddL(TDbCol(KFeedUrl,           EDbColLongText16));
       
  2420     colSet->AddL(TDbCol(KDescription,       EDbColLongText16));
       
  2421     colSet->AddL(TDbCol(KWebUrl,            EDbColLongText16));
       
  2422     colSet->AddL(TDbCol(KUnreadCount,       EDbColUint16));
       
  2423     colSet->AddL(TDbCol(KAutoUpdateFreq,      EDbColUint32));
       
  2424     
       
  2425     // Create the table.
       
  2426     User::LeaveIfError(iDatabase.CreateTable(KFeedTable, *colSet));
       
  2427     CleanupStack::PopAndDestroy(colSet);
       
  2428 
       
  2429     // Index the table.    
       
  2430     indexKey = CDbKey::NewLC();
       
  2431     
       
  2432     indexKey->AddL(feedIdCol);
       
  2433     User::LeaveIfError(iDatabase.CreateIndex(KFeedTableIndex, KFeedTable, *indexKey));
       
  2434     CleanupStack::PopAndDestroy(indexKey);
       
  2435     }
       
  2436     
       
  2437 
       
  2438 // -----------------------------------------------------------------------------
       
  2439 // CFeedsDatabase::CreateFeedItemTableL
       
  2440 //
       
  2441 // Creates the feed-list table.
       
  2442 // -----------------------------------------------------------------------------
       
  2443 //
       
  2444 void CFeedsDatabase::CreateFeedItemTableL()
       
  2445     {
       
  2446     CDbColSet*  colSet = NULL;
       
  2447     TDbKeyCol   feedIdCol(KFeedId);
       
  2448     TDbKeyCol   itemIdCol(KItemId);
       
  2449     CDbKey*     indexKey = NULL;    
       
  2450     
       
  2451     // Create the table's column set.
       
  2452     colSet = CDbColSet::NewLC();
       
  2453     
       
  2454     colSet->AddL(TDbCol(KItemId,            EDbColUint16));
       
  2455     colSet->AddL(TDbCol(KFeedId,            EDbColUint16));
       
  2456     colSet->AddL(TDbCol(KDate,              EDbColDateTime));
       
  2457     colSet->AddL(TDbCol(KItemStatus,        EDbColUint8));
       
  2458     colSet->AddL(TDbCol(KTitle_100MaxLen,   EDbColText16, K100MaxLen));
       
  2459     colSet->AddL(TDbCol(KDescription,       EDbColLongText16));
       
  2460     colSet->AddL(TDbCol(KWebUrl,            EDbColLongText16));
       
  2461     colSet->AddL(TDbCol(KItemIdStr,         EDbColLongText16));
       
  2462     
       
  2463     // Create the table.
       
  2464     User::LeaveIfError(iDatabase.CreateTable(KItemTable, *colSet));
       
  2465     CleanupStack::PopAndDestroy(colSet);
       
  2466 
       
  2467     // Index the table.    
       
  2468     indexKey = CDbKey::NewLC();
       
  2469     
       
  2470     indexKey->AddL(itemIdCol);
       
  2471     User::LeaveIfError(iDatabase.CreateIndex(KItemTableIndex, KItemTable, *indexKey));
       
  2472     CleanupStack::PopAndDestroy(indexKey);
       
  2473     }
       
  2474     
       
  2475 
       
  2476 // -----------------------------------------------------------------------------
       
  2477 // CFeedsDatabase::CreateItemEnclosureTableL
       
  2478 //
       
  2479 // Creates the item-enclosure table.
       
  2480 // -----------------------------------------------------------------------------
       
  2481 //
       
  2482 void CFeedsDatabase::CreateItemEnclosureTableL()
       
  2483     {
       
  2484     CDbColSet*  colSet = NULL;
       
  2485     TDbKeyCol   feedIdCol(KFeedId);
       
  2486     TDbKeyCol   itemIdCol(KItemId);
       
  2487     TDbKeyCol   enclosureIdCol(KEnclosureId);        
       
  2488     CDbKey*     indexKey = NULL;    
       
  2489     
       
  2490     // Create the table's column set.
       
  2491     colSet = CDbColSet::NewLC();
       
  2492     
       
  2493     colSet->AddL(TDbCol(KEnclosureId,               EDbColUint16));
       
  2494     colSet->AddL(TDbCol(KItemId,                    EDbColUint16));
       
  2495     colSet->AddL(TDbCol(KFeedId,                    EDbColUint16));
       
  2496     colSet->AddL(TDbCol(KLength_100MaxLen,          EDbColText16, K100MaxLen));
       
  2497     colSet->AddL(TDbCol(KTitle_100MaxLen,           EDbColText16, K100MaxLen));
       
  2498     colSet->AddL(TDbCol(KContentType_100MaxLen,     EDbColText16, K100MaxLen));
       
  2499     colSet->AddL(TDbCol(KWebUrl,                    EDbColLongText16));
       
  2500     
       
  2501     // Create the table.
       
  2502     User::LeaveIfError(iDatabase.CreateTable(KEnclosureTable, *colSet));
       
  2503     CleanupStack::PopAndDestroy(colSet);
       
  2504 
       
  2505     // Index the table.    
       
  2506     indexKey = CDbKey::NewLC();
       
  2507     
       
  2508     indexKey->AddL(feedIdCol);
       
  2509     indexKey->AddL(itemIdCol);
       
  2510     indexKey->AddL(enclosureIdCol);
       
  2511     User::LeaveIfError(iDatabase.CreateIndex(KEnclosureTableIndex, KEnclosureTable, *indexKey));
       
  2512     CleanupStack::PopAndDestroy(indexKey);
       
  2513     }
       
  2514 
       
  2515 
       
  2516 // -----------------------------------------------------------------------------
       
  2517 // CFeedsDatabase::CreateSettingsTableL
       
  2518 //
       
  2519 // Creates the settings table.
       
  2520 // -----------------------------------------------------------------------------
       
  2521 //
       
  2522 void CFeedsDatabase::CreateSettingsTableL()
       
  2523     {
       
  2524     CDbColSet*  colSet = NULL;
       
  2525     TDbKeyCol   folderListIdCol( KFolderListId );
       
  2526     CDbKey*     indexKey = NULL;    
       
  2527     
       
  2528     // Create the table's column set.
       
  2529     colSet = CDbColSet::NewLC();
       
  2530     colSet->AddL(TDbCol(KFolderListId,				EDbColInt32));
       
  2531     colSet->AddL(TDbCol(KAutoUpdate,				EDbColUint8));
       
  2532     colSet->AddL(TDbCol(KAutoUpdateWhileRoaming,	EDbColUint8));
       
  2533     colSet->AddL(TDbCol(KAccessPoint,				EDbColUint32));
       
  2534     colSet->AddL(TDbCol(KAutoUpdateFreq,			EDbColUint32));
       
  2535     colSet->AddL(TDbCol(KLastAutoUpdate,			EDbColDateTime));
       
  2536     
       
  2537     // Create the table.
       
  2538     User::LeaveIfError(iDatabase.CreateTable(KSettingsTable, *colSet));
       
  2539     CleanupStack::PopAndDestroy(colSet);
       
  2540 
       
  2541     // Index the table.    
       
  2542     indexKey = CDbKey::NewLC();
       
  2543 
       
  2544     indexKey->AddL( folderListIdCol );
       
  2545     User::LeaveIfError(iDatabase.CreateIndex(KSettingsTableIndex, 
       
  2546             KSettingsTable, *indexKey));
       
  2547     CleanupStack::PopAndDestroy(indexKey);
       
  2548     }
       
  2549     
       
  2550 
       
  2551 // -----------------------------------------------------------------------------
       
  2552 // CFeedsDatabase::NextFolderItemIdL
       
  2553 //
       
  2554 // Returns an available folder-item id.
       
  2555 // -----------------------------------------------------------------------------
       
  2556 //
       
  2557 TInt CFeedsDatabase::NextFolderItemIdL()
       
  2558     {
       
  2559     TBool     found;
       
  2560     TUint16   id;
       
  2561     
       
  2562     // Prep the folder table.
       
  2563     UseFolderListTableLC(RDbTable::EReadOnly);
       
  2564     
       
  2565     // Search for a unquie id.
       
  2566     do
       
  2567         {
       
  2568         id = (TUint16) Math::Random();
       
  2569         TDbSeekKey  seekKey(id);
       
  2570         
       
  2571         found = iFolderListTable.SeekL(seekKey);
       
  2572             
       
  2573         // Don't allow the root folder id to be picked.
       
  2574         if (id == KRootFolderId)
       
  2575             {
       
  2576             found = ETrue;
       
  2577             }
       
  2578         }
       
  2579     while (found);
       
  2580     
       
  2581     CleanupStack::PopAndDestroy(/*Folder list Table*/);
       
  2582     return id;
       
  2583     }
       
  2584 
       
  2585 
       
  2586 // -----------------------------------------------------------------------------
       
  2587 // CFeedsDatabase::NextFeedIdL
       
  2588 //
       
  2589 // Returns an available feed id.
       
  2590 // -----------------------------------------------------------------------------
       
  2591 //
       
  2592 TInt CFeedsDatabase::NextFeedIdL()
       
  2593     {
       
  2594     TBool     found = ETrue;
       
  2595     TUint16   id;
       
  2596     
       
  2597     // Prep the folder table.
       
  2598     UseFeedTableLC(RDbTable::EReadOnly);
       
  2599     
       
  2600     // Search for a unquie id.
       
  2601     do
       
  2602         {
       
  2603         id = (TUint16) Math::Random();
       
  2604         
       
  2605         // A feed id of 0 is special (meaning unassigned).
       
  2606         if (id != 0)
       
  2607             {            
       
  2608             TDbSeekKey  seekKey(id);
       
  2609             
       
  2610             found = iFeedTable.SeekL(seekKey);
       
  2611             }
       
  2612         }
       
  2613     while (found);
       
  2614     
       
  2615     CleanupStack::PopAndDestroy(/*Feed Table*/);
       
  2616     return id;
       
  2617     }
       
  2618 
       
  2619 
       
  2620 // -----------------------------------------------------------------------------
       
  2621 // CFeedsDatabase::NextItemIdL
       
  2622 //
       
  2623 // Returns an available item id.
       
  2624 // -----------------------------------------------------------------------------
       
  2625 //
       
  2626 TInt CFeedsDatabase::NextItemIdL()
       
  2627     {
       
  2628     TBool     found = ETrue;
       
  2629     TUint16   id;
       
  2630     
       
  2631     // Prep the folder table.
       
  2632     UseItemTableLC(RDbTable::EReadOnly);
       
  2633     
       
  2634     // Search for a unquie id.
       
  2635     do
       
  2636         {
       
  2637         id = (TUint16) Math::Random();
       
  2638         
       
  2639         // A item id of 0 is special (meaning unassigned).
       
  2640         if (id != 0)
       
  2641             {            
       
  2642             TDbSeekKey  seekKey(id);
       
  2643             
       
  2644             found = iItemTable.SeekL(seekKey);
       
  2645             }
       
  2646         }
       
  2647     while (found);
       
  2648     
       
  2649     CleanupStack::PopAndDestroy(/*item Table*/);
       
  2650     return id;
       
  2651     }
       
  2652 
       
  2653 
       
  2654 // -----------------------------------------------------------------------------
       
  2655 // CFeedsDatabase::CommitFolderListL
       
  2656 //
       
  2657 // Commit the folder entry to the database.
       
  2658 // -----------------------------------------------------------------------------
       
  2659 //
       
  2660 void CFeedsDatabase::CommitFolderListL(TInt aFolderListId, TInt aFolderItemId, 
       
  2661         TInt aParentId, TInt aSiblingIndex, TBool aIsFolder, TInt aFeedId, 
       
  2662         const TDesC& aTitle)
       
  2663     {
       
  2664     if (aFeedId == KUnassignedId)
       
  2665         {
       
  2666         aFeedId = 0;
       
  2667         }
       
  2668         
       
  2669     // Update the database.
       
  2670     iFolderListTable.Reset();
       
  2671     iFolderListTable.InsertL();
       
  2672     
       
  2673     iFolderListTable.SetColL(iFolderListColSet->ColNo(KFolderListId), aFolderListId);
       
  2674     iFolderListTable.SetColL(iFolderListColSet->ColNo(KFolderItemId), aFolderItemId);
       
  2675     iFolderListTable.SetColL(iFolderListColSet->ColNo(KParentId), aParentId);
       
  2676     iFolderListTable.SetColL(iFolderListColSet->ColNo(KSiblingOrder), aSiblingIndex);
       
  2677     iFolderListTable.SetColL(iFolderListColSet->ColNo(KIsFolder), aIsFolder);
       
  2678     iFolderListTable.SetColL(iFolderListColSet->ColNo(KFeedId), aFeedId);
       
  2679     iFolderListTable.SetColL(iFolderListColSet->ColNo(KTitle_100MaxLen), aTitle.Left(K100MaxLen));
       
  2680     iFolderListTable.SetColL(iFolderListColSet->ColNo(KStatus), KErrNone);
       
  2681         
       
  2682     iFolderListTable.PutL();
       
  2683     }
       
  2684 
       
  2685 // -----------------------------------------------------------------------------
       
  2686 // CFeedsDatabase::CommitFeedL
       
  2687 //
       
  2688 // Commit the feed to the database.
       
  2689 // -----------------------------------------------------------------------------
       
  2690 //
       
  2691 void CFeedsDatabase::CommitFeedL(TInt aFolderListId, TBool aIsNewFeed, TInt aFeedId, 
       
  2692         const RArray<TAttribute>& aAttributes, const TTime& aDefaultTime, TInt aUnreadCount)
       
  2693     {
       
  2694     TPtrC  title(KNullDesC);
       
  2695     TPtrC  description(KNullDesC);
       
  2696     TPtrC  link(KNullDesC);
       
  2697     TPtrC  timeStamp(KNullDesC);
       
  2698     TPtrC  feedUrl(KNullDesC);
       
  2699     TInt unreadCount = aUnreadCount;
       
  2700 
       
  2701     // Get the values.
       
  2702     for (TInt i = 0; i < aAttributes.Count(); i++)
       
  2703         {
       
  2704         switch (aAttributes[i].token)
       
  2705             {
       
  2706             case EFeedAttributeTitle:
       
  2707                 title.Set(aAttributes[i].value);
       
  2708                 break;
       
  2709                 
       
  2710             case EFeedAttributeLink:
       
  2711                 link.Set(aAttributes[i].value);
       
  2712                 break;
       
  2713                 
       
  2714             case EFeedAttributeDescription:
       
  2715                 description.Set(aAttributes[i].value);
       
  2716                 break;
       
  2717                 
       
  2718             case EFeedAttributeFeedUrl:
       
  2719                 feedUrl.Set(aAttributes[i].value);
       
  2720                 break;
       
  2721                 
       
  2722             case EFeedAttributeTimestamp:
       
  2723                 timeStamp.Set(aAttributes[i].value);
       
  2724                 break;                
       
  2725             }
       
  2726         }
       
  2727     
       
  2728     // If timeStamp was provided convert it into a TTime otherwise just
       
  2729     // use the default time.
       
  2730     TTime  date = aDefaultTime;
       
  2731 
       
  2732     // TODO: Two timestamps are needed -- one for tracking when the
       
  2733     //       author changed their feed and one for the last time the
       
  2734     //       feed was updated.
       
  2735 #if 0    
       
  2736     if (timeStamp.Length() > 0)
       
  2737         {
       
  2738         TLex16  lex(timeStamp);
       
  2739         TInt64  ts;
       
  2740         
       
  2741         User::LeaveIfError(lex.Val(ts));
       
  2742         date = ts;
       
  2743         }
       
  2744 #endif
       
  2745 
       
  2746     // If this is a new feed then get ready to insert a new entry.
       
  2747     if (aIsNewFeed)
       
  2748         {
       
  2749      
       
  2750         iFeedTable.Reset();
       
  2751         iFeedTable.InsertL();
       
  2752     
       
  2753         }
       
  2754         
       
  2755     // Otherwise get ready to update the existing entry.
       
  2756     else
       
  2757         {
       
  2758         TDbSeekKey  seekKey((TUint16) aFeedId);
       
  2759         
       
  2760         if (iFeedTable.SeekL(seekKey))
       
  2761             {        
       
  2762             iFeedTable.GetL();
       
  2763             iFeedTable.UpdateL();
       
  2764             }
       
  2765         else
       
  2766             {
       
  2767             User::Leave(KErrCorrupt);
       
  2768             }
       
  2769 
       
  2770         unreadCount = iFeedTable.ColUint16(iFeedColSet->ColNo(KUnreadCount));
       
  2771         unreadCount += aUnreadCount;    
       
  2772         }
       
  2773     // Write the entry. aFolderListId       
       
  2774     iFeedTable.SetColL(iFeedColSet->ColNo(KFolderListId), aFolderListId);
       
  2775     iFeedTable.SetColL(iFeedColSet->ColNo(KFeedId), aFeedId);
       
  2776     iFeedTable.SetColL(iFeedColSet->ColNo(KDate), date);
       
  2777     iFeedTable.SetColL(iFeedColSet->ColNo(KTitle_100MaxLen), title.Left(K100MaxLen));
       
  2778     WriteLongTextL(iFeedTable, iFeedColSet->ColNo(KFeedUrl), feedUrl);
       
  2779     WriteLongTextL(iFeedTable, iFeedColSet->ColNo(KDescription), description);
       
  2780     WriteLongTextL(iFeedTable, iFeedColSet->ColNo(KWebUrl), link);
       
  2781     iFeedTable.SetColL(iFeedColSet->ColNo(KUnreadCount), unreadCount);    
       
  2782         
       
  2783     iFeedTable.PutL();
       
  2784    
       
  2785     }
       
  2786 
       
  2787 
       
  2788 // -----------------------------------------------------------------------------
       
  2789 // CFeedsDatabase::CommitFeedL
       
  2790 //
       
  2791 // Commit a new feed to the database.
       
  2792 // -----------------------------------------------------------------------------
       
  2793 //
       
  2794 TInt CFeedsDatabase::CommitFeedL(TInt aFolderListId, const TDesC& aTitle, const TDesC& aUrl, TInt aFreq)
       
  2795     {    
       
  2796     RArray<TAttribute>  attributes;
       
  2797     TAttribute          attribute;
       
  2798     TTime               zero(0);
       
  2799     TInt                feedId;
       
  2800     TInt                zeroCount = 0;
       
  2801     
       
  2802     UseFeedTableLC(RDbTable::EUpdatable);
       
  2803 
       
  2804     CleanupClosePushL(attributes);
       
  2805     attributes.Reset();        
       
  2806 
       
  2807     // Add the title to the attribute list.
       
  2808     attribute.token = EFeedAttributeTitle;
       
  2809     attribute.value.Set(aTitle);
       
  2810     attributes.AppendL(attribute);
       
  2811 
       
  2812     // Add the url to the attribute list.
       
  2813     attribute.token = EFeedAttributeFeedUrl;
       
  2814     attribute.value.Set(aUrl);
       
  2815     attributes.AppendL(attribute);
       
  2816 
       
  2817     // Get a id for the feed.
       
  2818     feedId = NextFeedIdL();
       
  2819 
       
  2820     // Add an entry for the feed in the feed table.
       
  2821     CommitFeedL(aFolderListId, ETrue, feedId, attributes, zero, zeroCount, aFreq);
       
  2822 
       
  2823     // Clean up.
       
  2824     CleanupStack::PopAndDestroy(/*attributes*/);  
       
  2825     CleanupStack::PopAndDestroy(/*feed table*/);  
       
  2826     
       
  2827     return feedId;  
       
  2828     }
       
  2829     
       
  2830 // -----------------------------------------------------------------------------
       
  2831 // CFeedsDatabase::CommitFeedL
       
  2832 //
       
  2833 // Commit the feed to the database.
       
  2834 // -----------------------------------------------------------------------------
       
  2835 //
       
  2836 void CFeedsDatabase::CommitFeedL(TInt aFolderListId, TBool aIsNewFeed, TInt aFeedId, 
       
  2837         const RArray<TAttribute>& aAttributes, const TTime& aDefaultTime, TInt aUnreadCount,TInt aFreq)
       
  2838     {
       
  2839     TPtrC  title(KNullDesC);
       
  2840     TPtrC  description(KNullDesC);
       
  2841     TPtrC  link(KNullDesC);
       
  2842     TPtrC  timeStamp(KNullDesC);
       
  2843     TPtrC  feedUrl(KNullDesC);
       
  2844     TInt unreadCount = aUnreadCount;
       
  2845 
       
  2846     // Get the values.
       
  2847     for (TInt i = 0; i < aAttributes.Count(); i++)
       
  2848         {
       
  2849         switch (aAttributes[i].token)
       
  2850             {
       
  2851             case EFeedAttributeTitle:
       
  2852                 title.Set(aAttributes[i].value);
       
  2853                 break;
       
  2854 
       
  2855             case EFeedAttributeLink:
       
  2856                 link.Set(aAttributes[i].value);
       
  2857                 break;
       
  2858 
       
  2859             case EFeedAttributeDescription:
       
  2860                 description.Set(aAttributes[i].value);
       
  2861                 break;
       
  2862 
       
  2863             case EFeedAttributeFeedUrl:
       
  2864                 feedUrl.Set(aAttributes[i].value);
       
  2865                 break;
       
  2866 
       
  2867             case EFeedAttributeTimestamp:
       
  2868                 timeStamp.Set(aAttributes[i].value);
       
  2869                 break;                
       
  2870             }
       
  2871         }
       
  2872 
       
  2873     // If timeStamp was provided convert it into a TTime otherwise just
       
  2874     // use the default time.
       
  2875     TTime  date = aDefaultTime;
       
  2876 
       
  2877     // TODO: Two timestamps are needed -- one for tracking when the
       
  2878     //       author changed their feed and one for the last time the
       
  2879     //       feed was updated.
       
  2880 #if 0
       
  2881     if (timeStamp.Length() > 0)
       
  2882         {
       
  2883         TLex16  lex(timeStamp);
       
  2884         TInt64  ts;
       
  2885         
       
  2886         User::LeaveIfError(lex.Val(ts));
       
  2887         date = ts;
       
  2888         }
       
  2889 #endif
       
  2890 
       
  2891     // If this is a new feed then get ready to insert a new entry.
       
  2892     if (aIsNewFeed)
       
  2893         {
       
  2894         iFeedTable.Reset();
       
  2895         iFeedTable.InsertL();
       
  2896         }
       
  2897 
       
  2898     // Otherwise get ready to update the existing entry.
       
  2899     else
       
  2900         {
       
  2901         TDbSeekKey  seekKey((TUint16) aFeedId);
       
  2902 
       
  2903         if (iFeedTable.SeekL(seekKey))
       
  2904             {        
       
  2905             iFeedTable.GetL();
       
  2906             iFeedTable.UpdateL();
       
  2907             }
       
  2908         else
       
  2909             {
       
  2910             User::Leave(KErrCorrupt);
       
  2911             }
       
  2912 
       
  2913         unreadCount = iFeedTable.ColUint16(iFeedColSet->ColNo(KUnreadCount));
       
  2914         unreadCount += aUnreadCount;
       
  2915         }
       
  2916     // Write the entry. aFolderListId
       
  2917     iFeedTable.SetColL(iFeedColSet->ColNo(KFolderListId), aFolderListId);
       
  2918     iFeedTable.SetColL(iFeedColSet->ColNo(KFeedId), aFeedId);
       
  2919     iFeedTable.SetColL(iFeedColSet->ColNo(KDate), date);
       
  2920     iFeedTable.SetColL(iFeedColSet->ColNo(KTitle_100MaxLen), title.Left(K100MaxLen));
       
  2921     WriteLongTextL(iFeedTable, iFeedColSet->ColNo(KFeedUrl), feedUrl);
       
  2922     WriteLongTextL(iFeedTable, iFeedColSet->ColNo(KDescription), description);
       
  2923     WriteLongTextL(iFeedTable, iFeedColSet->ColNo(KWebUrl), link);
       
  2924     iFeedTable.SetColL(iFeedColSet->ColNo(KUnreadCount), unreadCount);
       
  2925     iFeedTable.SetColL(iFeedColSet->ColNo(KAutoUpdateFreq), aFreq);
       
  2926 
       
  2927     iFeedTable.PutL();
       
  2928 
       
  2929     }
       
  2930 // -----------------------------------------------------------------------------
       
  2931 // CFeedsDatabase::CommitItemL
       
  2932 //
       
  2933 // Commit the item to the database.  The itemIdStr is also appended to aItemIdStrs.
       
  2934 // -----------------------------------------------------------------------------
       
  2935 // 
       
  2936 TBool CFeedsDatabase::CommitItemL(TInt aItemId, TInt aFeedId, 
       
  2937         const RArray<TAttribute>& aAttributes, RArray<TInt>& aItemIds)
       
  2938     {
       
  2939     TPtrC  timeStamp(KNullDesC);
       
  2940     TPtrC  title(KNullDesC);
       
  2941     TPtrC  description(KNullDesC);
       
  2942     TPtrC  link(KNullDesC);
       
  2943     TPtrC  itemIdStr(KNullDesC);
       
  2944 
       
  2945     // Get the values.
       
  2946     for (TInt i = 0; i < aAttributes.Count(); i++)
       
  2947         {
       
  2948         switch (aAttributes[i].token)
       
  2949             {
       
  2950             case EItemAttributeIdStr:
       
  2951                 itemIdStr.Set(aAttributes[i].value);
       
  2952                 break;                
       
  2953 
       
  2954             case EItemAttributeTitle:
       
  2955                 title.Set(aAttributes[i].value);
       
  2956                 break;
       
  2957                 
       
  2958             case EItemAttributeDescription:
       
  2959                 description.Set(aAttributes[i].value);
       
  2960                 break;                
       
  2961 
       
  2962             case EItemAttributeLink:
       
  2963                 link.Set(aAttributes[i].value);
       
  2964                 break;                
       
  2965                 
       
  2966             case EItemAttributeTimestamp:
       
  2967                 timeStamp.Set(aAttributes[i].value);
       
  2968                 break;                
       
  2969             }
       
  2970         }
       
  2971     
       
  2972     // Ignore the item if it is already in the database.
       
  2973     // TODO: Don't ignore it if the timestamp changes.  In this case 
       
  2974     //       the item needs to be updated below rather than inserted.
       
  2975     TInt  id;
       
  2976     
       
  2977     if (FindItemL(aFeedId, itemIdStr, id))
       
  2978         {
       
  2979         // If the item is found then append it's id to aItemIds.
       
  2980         aItemIds.AppendL(id);
       
  2981 
       
  2982         return EFalse;
       
  2983         }
       
  2984         
       
  2985     // Otherwise this is a new item so append the provided id to aItemIds.
       
  2986     else
       
  2987         {
       
  2988         aItemIds.AppendL(aItemId);
       
  2989         }
       
  2990 
       
  2991     // If timeStamp was provided convert it into a TTime otherwise just
       
  2992     // use the current time.
       
  2993     TTime  date;
       
  2994 
       
  2995     if (timeStamp.Length() > 0)
       
  2996         {
       
  2997         TLex16  lex(timeStamp);
       
  2998         TInt64  ts;
       
  2999         
       
  3000         User::LeaveIfError(lex.Val(ts));
       
  3001         date = ts;
       
  3002         }
       
  3003     else
       
  3004         {
       
  3005         date.UniversalTime();
       
  3006         }
       
  3007         
       
  3008     // Update the database.
       
  3009     iItemTable.Reset();
       
  3010     iItemTable.InsertL();
       
  3011     
       
  3012     iItemTable.SetColL(iItemColSet->ColNo(KItemId), aItemId);
       
  3013     iItemTable.SetColL(iItemColSet->ColNo(KFeedId), aFeedId);
       
  3014     iItemTable.SetColL(iItemColSet->ColNo(KDate), date);
       
  3015     iItemTable.SetColL(iItemColSet->ColNo(KItemStatus), ENewItem);
       
  3016     iItemTable.SetColL(iItemColSet->ColNo(KTitle_100MaxLen), title.Left(K100MaxLen));
       
  3017     WriteLongTextL(iItemTable, iItemColSet->ColNo(KDescription), description);
       
  3018     WriteLongTextL(iItemTable, iItemColSet->ColNo(KWebUrl), link);
       
  3019     WriteLongTextL(iItemTable, iItemColSet->ColNo(KItemIdStr), itemIdStr);
       
  3020     
       
  3021     iItemTable.PutL();
       
  3022     
       
  3023     return ETrue;
       
  3024     }
       
  3025     
       
  3026     
       
  3027 // -----------------------------------------------------------------------------
       
  3028 // CFeedsDatabase::CommitEnclosureL
       
  3029 //
       
  3030 // Commit the enclosure to the database
       
  3031 // -----------------------------------------------------------------------------
       
  3032 //
       
  3033 void CFeedsDatabase::CommitEnclosureL(TInt aEnclosureId, TInt aItemId, 
       
  3034         TInt aFeedId, const RArray<TAttribute>& aAttributes)
       
  3035     {
       
  3036     TPtrC  title(KNullDesC);
       
  3037     TPtrC  length(KNullDesC);
       
  3038     TPtrC  contentType(KNullDesC);
       
  3039     TPtrC  link(KNullDesC);
       
  3040 
       
  3041     // Get the values.
       
  3042     for (TInt i = 0; i < aAttributes.Count(); i++)
       
  3043         {
       
  3044         switch (aAttributes[i].token)
       
  3045             {
       
  3046             case EEnclosureAttributeTitle:
       
  3047                 title.Set(aAttributes[i].value);
       
  3048                 break;
       
  3049                 
       
  3050             case EEnclosureAttributeSize:
       
  3051                 length.Set(aAttributes[i].value);
       
  3052                 break;
       
  3053                 
       
  3054             case EEnclosureAttributeContentType:
       
  3055                 contentType.Set(aAttributes[i].value);
       
  3056                 break;
       
  3057                 
       
  3058             case EEnclosureAttributeLink:
       
  3059                 link.Set(aAttributes[i].value);
       
  3060                 break;
       
  3061             }
       
  3062         }
       
  3063     
       
  3064     // Update the database.
       
  3065     iEnclosureTable.Reset();
       
  3066     iEnclosureTable.InsertL();
       
  3067     
       
  3068     iEnclosureTable.SetColL(iEnclosureColSet->ColNo(KTitle_100MaxLen), title.Left(K100MaxLen));
       
  3069     iEnclosureTable.SetColL(iEnclosureColSet->ColNo(KEnclosureId), aEnclosureId);
       
  3070     iEnclosureTable.SetColL(iEnclosureColSet->ColNo(KItemId), aItemId);
       
  3071     iEnclosureTable.SetColL(iEnclosureColSet->ColNo(KFeedId), aFeedId);
       
  3072     iEnclosureTable.SetColL(iEnclosureColSet->ColNo(KLength_100MaxLen), length.Left(K100MaxLen));
       
  3073     iEnclosureTable.SetColL(iEnclosureColSet->ColNo(KContentType_100MaxLen), contentType.Left(K100MaxLen));
       
  3074     WriteLongTextL(iEnclosureTable, iEnclosureColSet->ColNo(KWebUrl), link);
       
  3075     
       
  3076     iEnclosureTable.PutL();
       
  3077     }
       
  3078 
       
  3079 
       
  3080 // -----------------------------------------------------------------------------
       
  3081 // CFeedsDatabase::ExtractFolderListIdInSettingsL
       
  3082 //
       
  3083 // Get the folder list Ids from the settings table from the database.
       
  3084 // -----------------------------------------------------------------------------
       
  3085 //
       
  3086 void CFeedsDatabase::ExtractFolderListIdInSettingsL( RArray<TInt>& aFolderListIds )
       
  3087     {
       
  3088     TInt folderListId;
       
  3089 
       
  3090     // Prep the settings table.
       
  3091     UseSettingsTableLC(RDbTable::EReadOnly);
       
  3092 
       
  3093     while( iSettingsTable.NextL() )
       
  3094         {
       
  3095         iSettingsTable.GetL();
       
  3096         folderListId = iSettingsTable.ColInt32(iSettingsColSet->ColNo(KFolderListId));
       
  3097         aFolderListIds.AppendL( folderListId );
       
  3098         }
       
  3099 
       
  3100     CleanupStack::PopAndDestroy(/* settings table */);
       
  3101     }
       
  3102 
       
  3103 
       
  3104 // -----------------------------------------------------------------------------
       
  3105 // CFeedsDatabase::ExtractAutoUpdateSettingsL
       
  3106 //
       
  3107 // Get the settings from the database.
       
  3108 // -----------------------------------------------------------------------------
       
  3109 //
       
  3110 void CFeedsDatabase::ExtractAutoUpdateSettingsL( TInt aFolderListId, TBool& aAutoUpdate, TInt& aAutoUpdateFreq,
       
  3111         TUint32& aAutoUpdateAP, TBool &autoUpdateWhileRoaming  )
       
  3112     {
       
  3113     // Prep the settings table.
       
  3114     UseSettingsTableLC(RDbTable::EReadOnly);
       
  3115     
       
  3116     TDbSeekKey  seekKey( aFolderListId );
       
  3117     // Extract the values.
       
  3118     if (iSettingsTable.SeekL(seekKey))
       
  3119         {        
       
  3120         iSettingsTable.GetL();
       
  3121 
       
  3122         aAutoUpdate = iSettingsTable.ColUint8(iSettingsColSet->ColNo(KAutoUpdate));
       
  3123         aAutoUpdateAP = iSettingsTable.ColUint32(iSettingsColSet->ColNo(KAccessPoint));
       
  3124         aAutoUpdateFreq = iSettingsTable.ColUint32(iSettingsColSet->ColNo(KAutoUpdateFreq));
       
  3125 		autoUpdateWhileRoaming = iSettingsTable.ColUint8(iSettingsColSet->ColNo(KAutoUpdateWhileRoaming));
       
  3126         }
       
  3127     else
       
  3128         {
       
  3129         User::Leave(KErrNotFound);
       
  3130         }
       
  3131         
       
  3132     CleanupStack::PopAndDestroy(/* settings table */);
       
  3133     }
       
  3134     
       
  3135     
       
  3136 // -----------------------------------------------------------------------------
       
  3137 // CFeedsDatabase::CommitAutoUpdateSettingsL
       
  3138 //
       
  3139 // Commit the settings to the database
       
  3140 // -----------------------------------------------------------------------------
       
  3141 //
       
  3142 void CFeedsDatabase::CommitAutoUpdateSettingsL( TInt aFolderListId, TBool aAutoUpdate, TInt aAutoUpdateFreq,
       
  3143         TUint32 aAutoUpdateAP, TBool aAutoUpdateWhileRoaming )
       
  3144     {
       
  3145     TTime  never(0);
       
  3146 
       
  3147     // Prep the settings table.
       
  3148     UseSettingsTableLC(RDbTable::EUpdatable);
       
  3149     
       
  3150     TDbSeekKey  seekKey( aFolderListId );
       
  3151     // Update the database.
       
  3152     if (iSettingsTable.SeekL(seekKey))
       
  3153         {           
       
  3154         iSettingsTable.GetL();
       
  3155         iSettingsTable.UpdateL();
       
  3156 
       
  3157         iSettingsTable.SetColL(iSettingsColSet->ColNo(KAutoUpdate), aAutoUpdate);
       
  3158         iSettingsTable.SetColL(iSettingsColSet->ColNo(KAccessPoint), aAutoUpdateAP);
       
  3159         iSettingsTable.SetColL(iSettingsColSet->ColNo(KAutoUpdateFreq), aAutoUpdateFreq);
       
  3160         iSettingsTable.SetColL(iSettingsColSet->ColNo(KAutoUpdateWhileRoaming), aAutoUpdateWhileRoaming);
       
  3161         }
       
  3162     else
       
  3163         {
       
  3164         iSettingsTable.Reset();
       
  3165         iSettingsTable.InsertL();
       
  3166 
       
  3167         // initiate last auto update to 0
       
  3168         iSettingsTable.SetColL(iSettingsColSet->ColNo(KFolderListId), aFolderListId);
       
  3169         iSettingsTable.SetColL(iSettingsColSet->ColNo(KAutoUpdate), aAutoUpdate);
       
  3170         iSettingsTable.SetColL(iSettingsColSet->ColNo(KAccessPoint), aAutoUpdateAP);
       
  3171         iSettingsTable.SetColL(iSettingsColSet->ColNo(KAutoUpdateFreq), aAutoUpdateFreq);
       
  3172         iSettingsTable.SetColL(iSettingsColSet->ColNo(KAutoUpdateWhileRoaming), aAutoUpdateWhileRoaming);
       
  3173         iSettingsTable.SetColL(iSettingsColSet->ColNo(KLastAutoUpdate), never);
       
  3174         }
       
  3175     
       
  3176     iSettingsTable.PutL();
       
  3177         
       
  3178     CleanupStack::PopAndDestroy(/* settings table */);
       
  3179     }
       
  3180 
       
  3181 
       
  3182 // -----------------------------------------------------------------------------
       
  3183 // CFeedsDatabase::ExtractLastAutoUpdateSettingsL
       
  3184 //
       
  3185 // Get the last auto update settings from the database.
       
  3186 // -----------------------------------------------------------------------------
       
  3187 //
       
  3188 void CFeedsDatabase::ExtractLastAutoUpdateSettingsL( TInt aFolderListId, TTime& aLastAutoUpdate )
       
  3189     {
       
  3190     // Prep the settings table.
       
  3191     UseSettingsTableLC(RDbTable::EReadOnly);
       
  3192     
       
  3193     TDbSeekKey  seekKey( aFolderListId );
       
  3194     // Extract the values.
       
  3195     if (iSettingsTable.SeekL(seekKey))
       
  3196         {        
       
  3197         iSettingsTable.GetL();
       
  3198 
       
  3199         aLastAutoUpdate = iSettingsTable.ColTime(iSettingsColSet->ColNo(KLastAutoUpdate));                    
       
  3200         }
       
  3201     else
       
  3202         {
       
  3203         User::Leave(KErrNotFound);
       
  3204         }
       
  3205         
       
  3206     CleanupStack::PopAndDestroy(/* settings table */);
       
  3207     }
       
  3208     
       
  3209     
       
  3210 // -----------------------------------------------------------------------------
       
  3211 // CFeedsDatabase::CommitLastAutoUpdateSettingsL
       
  3212 //
       
  3213 // Commit the last auto update settings to the database
       
  3214 // -----------------------------------------------------------------------------
       
  3215 //
       
  3216 void CFeedsDatabase::CommitLastAutoUpdateSettingsL( TInt aFolderListId, TTime aLastAutoUpdate )
       
  3217     {
       
  3218     // Prep the settings table.
       
  3219     UseSettingsTableLC(RDbTable::EUpdatable);
       
  3220     
       
  3221     TDbSeekKey  seekKey( aFolderListId );
       
  3222     // Update the database.
       
  3223     if (iSettingsTable.SeekL(seekKey))
       
  3224         {           
       
  3225         iSettingsTable.GetL();
       
  3226         iSettingsTable.UpdateL();
       
  3227     
       
  3228         iSettingsTable.SetColL(iSettingsColSet->ColNo(KLastAutoUpdate), aLastAutoUpdate);
       
  3229     
       
  3230         iSettingsTable.PutL();
       
  3231         }
       
  3232     else
       
  3233         {
       
  3234         User::Leave(KErrNotFound);
       
  3235         }
       
  3236         
       
  3237     CleanupStack::PopAndDestroy(/* settings table */);
       
  3238     }
       
  3239 
       
  3240 
       
  3241 // -----------------------------------------------------------------------------
       
  3242 // CFeedsDatabase::Compact
       
  3243 //
       
  3244 // Compacts the database.
       
  3245 // -----------------------------------------------------------------------------
       
  3246 //
       
  3247 void CFeedsDatabase::Compact()
       
  3248     {
       
  3249     iDatabase.Compact();
       
  3250     }
       
  3251     
       
  3252     
       
  3253 // -----------------------------------------------------------------------------
       
  3254 // CFeedsDatabase::PackFolderL
       
  3255 //
       
  3256 // Extracts and pack the folder.
       
  3257 // -----------------------------------------------------------------------------
       
  3258 //
       
  3259 void CFeedsDatabase::PackFolderL( TInt aFolderListId, TInt aFolderId, 
       
  3260         CPackedFolder& aPackedFolder, TBool aItemTitleNeed )
       
  3261     {
       
  3262     RDbView  view;
       
  3263     HBufC*   query = NULL;
       
  3264     
       
  3265     // Create a view given this select...    
       
  3266     // SELECT FolderItemId, SiblingOrder, IsFolder, FeedId, Title FROM FolderListTable 
       
  3267     // WHERE FolderListId = aFolderListId AND ParentId = aFolderId 
       
  3268     // ORDER BY SiblingOrder
       
  3269     _LIT(KQuery, "SELECT FolderItemId, SiblingOrder, IsFolder, FeedId, Title, Status FROM FolderListTable WHERE FolderListId = %d AND ParentId = %d ORDER BY SiblingOrder");
       
  3270     
       
  3271     query = HBufC::NewLC(KQuery().Length() + KIntLength + KIntLength); 
       
  3272                         
       
  3273     query->Des().Format(KQuery, aFolderListId, aFolderId);
       
  3274 
       
  3275     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EReadOnly));
       
  3276 
       
  3277     CleanupStack::PopAndDestroy(query);
       
  3278     CleanupClosePushL(view);
       
  3279 
       
  3280     CDbColSet* colSet = view.ColSetL();
       
  3281     CleanupStack::PushL(colSet);
       
  3282         
       
  3283     // For each entry either write the feed or folder to aPackedFolder (where folders
       
  3284     // are written recursively.
       
  3285     if (view.EvaluateAll() >= 0)
       
  3286         {
       
  3287         for (view.FirstL(); view.AtRow(); view.NextL())
       
  3288             {
       
  3289             TInt   folderItemId;
       
  3290             TInt   isFolder;
       
  3291             TPtrC  title;
       
  3292             TInt   statusCode;
       
  3293             // Get the current row.
       
  3294             view.GetL();
       
  3295         
       
  3296             // Get the fields
       
  3297             folderItemId = view.ColUint16(colSet->ColNo(KFolderItemId));
       
  3298             isFolder = view.ColUint8(colSet->ColNo(KIsFolder));
       
  3299             title.Set(view.ColDes16(colSet->ColNo(KTitle_100MaxLen)));
       
  3300             statusCode = view.ColInt32(colSet->ColNo(KStatus));
       
  3301             
       
  3302             // Process the folder.
       
  3303             if (isFolder)
       
  3304                 {
       
  3305                 // Recursively pack the folder.
       
  3306                 aPackedFolder.FolderBeginsL(title, folderItemId, statusCode);
       
  3307                 PackFolderL( aFolderListId, folderItemId, aPackedFolder, aItemTitleNeed );
       
  3308                 aPackedFolder.FolderEndsL();
       
  3309                 }
       
  3310             
       
  3311             // Otherwise append the feed.
       
  3312             else
       
  3313                 {
       
  3314                 TDbSeekKey  seekKey;   
       
  3315                 TInt        feedId; 
       
  3316         
       
  3317                 // Init the key to the feedId of this folder item.
       
  3318                 feedId = view.ColUint16(colSet->ColNo(KFeedId));
       
  3319                 seekKey.Add(feedId);
       
  3320                 
       
  3321                 if(iFeedTable.SeekL(seekKey))
       
  3322                     {
       
  3323                     HBufC*  url;
       
  3324                     TTime   lastUpdate;
       
  3325                     
       
  3326                     iFeedTable.GetL();                    
       
  3327 
       
  3328                     // Get the feed's feed url.
       
  3329                     ReadLongTextL(iFeedTable, iFeedColSet->ColNo(KFeedUrl), url);
       
  3330                     CleanupStack::PushL(url);
       
  3331                     
       
  3332                     // Get the feed's feed last update timestamp.
       
  3333                     lastUpdate = iFeedTable.ColTime(iFeedColSet->ColNo(KDate));                    
       
  3334 
       
  3335                     TInt unreadCount = iFeedTable.ColUint16(iFeedColSet->ColNo(KUnreadCount));
       
  3336                     TInt freq        = iFeedTable.ColUint32(iFeedColSet->ColNo(KAutoUpdateFreq));
       
  3337                    
       
  3338                     // Pack the feed.
       
  3339                     if (aItemTitleNeed)
       
  3340                         {
       
  3341                         aPackedFolder.AddFeedL( title, *url, lastUpdate, freq, statusCode, unreadCount, folderItemId, feedId );
       
  3342                         SelectMiniItemsL( feedId, ENewItem, aPackedFolder );
       
  3343                         }
       
  3344                     else
       
  3345                         {
       
  3346                         aPackedFolder.AddFeedL( title, *url, lastUpdate, freq, statusCode, unreadCount, folderItemId, feedId );
       
  3347                         }
       
  3348 
       
  3349                     CleanupStack::PopAndDestroy(url);                    
       
  3350                     }
       
  3351                 }
       
  3352             }
       
  3353         }
       
  3354         
       
  3355     CleanupStack::PopAndDestroy(colSet);
       
  3356     CleanupStack::PopAndDestroy(/*view*/);
       
  3357     }
       
  3358     
       
  3359     
       
  3360 // -----------------------------------------------------------------------------
       
  3361 // CFeedsDatabase::PackFeedL
       
  3362 //
       
  3363 // Extracts and pack the feed.
       
  3364 // -----------------------------------------------------------------------------
       
  3365 //
       
  3366 void CFeedsDatabase::PackFeedL(TInt aFeedId, CPackedFeed& aFeed)
       
  3367     {
       
  3368     TDbSeekKey  seekKey((TUint16) aFeedId);
       
  3369     
       
  3370     // Prep the feed table.
       
  3371     UseFeedTableLC(RDbTable::EReadOnly);
       
  3372     
       
  3373     // Get the information about the feed.
       
  3374     if (iFeedTable.SeekL(seekKey))
       
  3375         {        
       
  3376         HBufC*  feedUrl = NULL;
       
  3377         HBufC*  description = NULL;
       
  3378         HBufC*  webUrl = NULL;
       
  3379 
       
  3380         // Get the row.
       
  3381         iFeedTable.GetL();
       
  3382         
       
  3383         // Extract the fields.
       
  3384         TTime    date = iFeedTable.ColTime(iFeedColSet->ColNo(KDate));
       
  3385         TPtrC16  title(iFeedTable.ColDes16(iFeedColSet->ColNo(KTitle_100MaxLen)));
       
  3386                 
       
  3387         ReadLongTextL(iFeedTable, iFeedColSet->ColNo(KFeedUrl), feedUrl);
       
  3388         CleanupStack::PushL(feedUrl);
       
  3389         ReadLongTextL(iFeedTable, iFeedColSet->ColNo(KDescription), description);
       
  3390         CleanupStack::PushL(description);
       
  3391         ReadLongTextL(iFeedTable, iFeedColSet->ColNo(KWebUrl), webUrl);
       
  3392         CleanupStack::PushL(webUrl);
       
  3393 
       
  3394         // Copy the data into the packed feed.
       
  3395         aFeed.FeedBeginsL();
       
  3396         
       
  3397         aFeed.AddAttributeL(EFeedAttributeFeedId, aFeedId);
       
  3398         
       
  3399         if (title.Length() > 0)
       
  3400             {
       
  3401             aFeed.AddAttributeL(EFeedAttributeTitle, title);
       
  3402             }
       
  3403         if (feedUrl->Length() > 0)
       
  3404             {
       
  3405             aFeed.AddAttributeL(EFeedAttributeFeedUrl, *feedUrl);
       
  3406             }
       
  3407         if (description->Length() > 0)
       
  3408             {
       
  3409             aFeed.AddAttributeL(EFeedAttributeDescription, *description);
       
  3410             }
       
  3411         if (webUrl->Length() > 0)
       
  3412             {
       
  3413             aFeed.AddAttributeL(EFeedAttributeLink, *webUrl);
       
  3414             }
       
  3415 
       
  3416         // Add the timestamp.
       
  3417         TBuf16<KInt64Length>  dateStr;
       
  3418         
       
  3419         dateStr.Format(_L("%Ld"), date.Int64());
       
  3420         aFeed.AddAttributeL(EFeedAttributeTimestamp, dateStr);
       
  3421         
       
  3422         CleanupStack::PopAndDestroy(webUrl);
       
  3423         CleanupStack::PopAndDestroy(description);
       
  3424         CleanupStack::PopAndDestroy(feedUrl);
       
  3425         }
       
  3426     else
       
  3427         {
       
  3428         User::Leave(KErrCorrupt);
       
  3429         }
       
  3430                 
       
  3431     CleanupStack::PopAndDestroy(/*Feed Table*/);
       
  3432     }
       
  3433 
       
  3434 
       
  3435 // -----------------------------------------------------------------------------
       
  3436 // CFeedsDatabase::PackItemsL
       
  3437 //
       
  3438 // Extracts and pack the items.
       
  3439 // -----------------------------------------------------------------------------
       
  3440 //
       
  3441 void CFeedsDatabase::PackItemsL(TInt aFeedId, CPackedFeed& aFeed)
       
  3442     {
       
  3443     RDbView  view;
       
  3444     HBufC*   query = NULL;
       
  3445     
       
  3446     // Create a view given this select...    
       
  3447     // SELECT * FROM ItemTable WHERE FeedId = aFeedId ORDER BY Date DESC
       
  3448     _LIT(KQuery, "SELECT * FROM ItemTable WHERE FeedId = %d ORDER BY Date DESC");
       
  3449     
       
  3450     query = HBufC::NewLC(KQuery().Length() + KIntLength); 
       
  3451                         
       
  3452     query->Des().Format(KQuery, aFeedId);
       
  3453 
       
  3454     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), 
       
  3455             RDbView::EReadOnly));
       
  3456     CleanupClosePushL(view);
       
  3457 
       
  3458     CDbColSet* colSet = view.ColSetL();
       
  3459     CleanupStack::PushL(colSet);
       
  3460     
       
  3461     if (view.EvaluateAll() >= 0)
       
  3462         {
       
  3463         for (view.FirstL(); view.AtRow(); view.NextL())
       
  3464             {
       
  3465             HBufC*  description = NULL;
       
  3466             HBufC*  webUrl = NULL;
       
  3467 
       
  3468             // Get the row.
       
  3469             view.GetL();
       
  3470             
       
  3471             // Extract the fields.
       
  3472             TInt     itemId = view.ColUint16(colSet->ColNo(KItemId));
       
  3473             TTime    date = view.ColTime(colSet->ColNo(KDate));
       
  3474             TInt     itemStatus = view.ColUint8(colSet->ColNo(KItemStatus));
       
  3475             TPtrC16  title(view.ColDes16(colSet->ColNo(KTitle_100MaxLen)));
       
  3476             
       
  3477             ReadLongTextL(view, colSet->ColNo(KDescription), description);
       
  3478             CleanupStack::PushL(description);
       
  3479             ReadLongTextL(view, colSet->ColNo(KWebUrl), webUrl);
       
  3480             CleanupStack::PushL(webUrl);
       
  3481 
       
  3482             // Copy the data into the packed feed.
       
  3483             aFeed.ItemBeginsL();
       
  3484             
       
  3485             if (title.Length() > 0)
       
  3486                 {
       
  3487                 aFeed.AddAttributeL(EItemAttributeTitle, title);
       
  3488                 }
       
  3489             if (description->Length() > 0)
       
  3490                 {
       
  3491                 aFeed.AddAttributeL(EItemAttributeDescription, *description);
       
  3492                 }
       
  3493             if (webUrl->Length() > 0)
       
  3494                 {
       
  3495                 aFeed.AddAttributeL(EItemAttributeLink, *webUrl);
       
  3496                 }
       
  3497             
       
  3498             aFeed.AddAttributeL(EItemAttributeItemId, itemId);            
       
  3499 
       
  3500             // Add the read status.
       
  3501             switch( itemStatus )
       
  3502                 {
       
  3503                 case EUnreadItem:
       
  3504                     {
       
  3505                     aFeed.AddAttributeL(EItemAttributeStatus, KUnread);
       
  3506                     }
       
  3507                     break;
       
  3508                 case EReadItem:
       
  3509                     {            
       
  3510                     aFeed.AddAttributeL(EItemAttributeStatus, KRead);
       
  3511                     }
       
  3512                     break;
       
  3513                 case ENewItem:
       
  3514                     {            
       
  3515                     aFeed.AddAttributeL(EItemAttributeStatus, KNew);
       
  3516                     }
       
  3517                     break;
       
  3518                 }
       
  3519             
       
  3520             // Add the timestamp.
       
  3521             TBuf16<KInt64Length>  dateStr;
       
  3522             
       
  3523             dateStr.Format(_L("%Ld"), date.Int64());
       
  3524             aFeed.AddAttributeL(EItemAttributeTimestamp, dateStr);
       
  3525             
       
  3526             CleanupStack::PopAndDestroy(webUrl);
       
  3527             CleanupStack::PopAndDestroy(description);
       
  3528 
       
  3529             // Pack the enclosures.
       
  3530             PackEnclosuresL(aFeedId, itemId, aFeed);
       
  3531             
       
  3532             // Signal the end of the item.
       
  3533             aFeed.ItemEndsL();
       
  3534             }
       
  3535         }
       
  3536         
       
  3537     CleanupStack::PopAndDestroy(colSet);
       
  3538     CleanupStack::PopAndDestroy(/*view*/);
       
  3539     CleanupStack::PopAndDestroy(query);
       
  3540     }
       
  3541 
       
  3542 
       
  3543 // -----------------------------------------------------------------------------
       
  3544 // CFeedsDatabase::PackEnclosuresL
       
  3545 //
       
  3546 // Extracts and pack the enclosure information.
       
  3547 // -----------------------------------------------------------------------------
       
  3548 //
       
  3549 void CFeedsDatabase::PackEnclosuresL(TInt aFeedId, TInt aItemId, CPackedFeed& aFeed)
       
  3550     {
       
  3551     RDbView  view;
       
  3552     HBufC*   query = NULL;
       
  3553     
       
  3554     // Create a view given this select...    
       
  3555     // SELECT * FROM EnclosureTable WHERE FeedId = aFeedId AND ItemId = aItemId 
       
  3556     _LIT(KQuery, "SELECT * FROM EnclosureTable WHERE FeedId = %d AND ItemId = %d");
       
  3557     
       
  3558     query = HBufC::NewLC(KQuery().Length() + KIntLength + KIntLength); 
       
  3559                         
       
  3560     query->Des().Format(KQuery, aFeedId, aItemId);
       
  3561 
       
  3562     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EReadOnly));
       
  3563     CleanupClosePushL(view);
       
  3564 
       
  3565     CDbColSet* colSet = view.ColSetL();
       
  3566     CleanupStack::PushL(colSet);
       
  3567     
       
  3568     if (view.EvaluateAll() >= 0)
       
  3569         {
       
  3570         for (view.FirstL(); view.AtRow(); view.NextL())
       
  3571             {
       
  3572             HBufC*  webUrl = NULL;
       
  3573 
       
  3574             // Get the row.
       
  3575             view.GetL();
       
  3576             
       
  3577             // Extract the fields.
       
  3578             TPtrC16  title(view.ColDes16(colSet->ColNo(KTitle_100MaxLen)));
       
  3579             TPtrC16  length(view.ColDes16(colSet->ColNo(KLength_100MaxLen)));
       
  3580             TPtrC16  contentType(view.ColDes16(colSet->ColNo(KContentType_100MaxLen)));
       
  3581 
       
  3582             ReadLongTextL(view, colSet->ColNo(KWebUrl), webUrl);
       
  3583             CleanupStack::PushL(webUrl);
       
  3584 
       
  3585             // Copy the data into the packed feed.
       
  3586             aFeed.EnclosureBeginsL();
       
  3587             
       
  3588             if (title.Length() > 0)
       
  3589                 {
       
  3590                 aFeed.AddAttributeL(EEnclosureAttributeTitle, title);
       
  3591                 }
       
  3592             if (length.Length() > 0)
       
  3593                 {
       
  3594                 aFeed.AddAttributeL(EEnclosureAttributeSize, length);
       
  3595                 }
       
  3596             if (contentType.Length() > 0)
       
  3597                 {
       
  3598                 aFeed.AddAttributeL(EEnclosureAttributeContentType, contentType);
       
  3599                 }
       
  3600             if (webUrl->Length() > 0)
       
  3601                 {
       
  3602                 aFeed.AddAttributeL(EEnclosureAttributeLink, *webUrl);
       
  3603                 }
       
  3604 
       
  3605             // Signal the end of the enclosure.
       
  3606             aFeed.EnclosureEndsL();
       
  3607             
       
  3608             CleanupStack::PopAndDestroy(webUrl);
       
  3609             }
       
  3610         }
       
  3611         
       
  3612     CleanupStack::PopAndDestroy(colSet);
       
  3613     CleanupStack::PopAndDestroy(/*view*/);
       
  3614     CleanupStack::PopAndDestroy(query);
       
  3615     }
       
  3616 
       
  3617 
       
  3618 // -----------------------------------------------------------------------------
       
  3619 // CFeedsDatabase::SelectMiniItemsL
       
  3620 //
       
  3621 // Select the minimum items information with the desired status.
       
  3622 // -----------------------------------------------------------------------------
       
  3623 //
       
  3624 void CFeedsDatabase::SelectMiniItemsL( TInt aFeedId, TInt aStatus, CPackedFolder& aFolder )
       
  3625     {
       
  3626     RDbView  view;
       
  3627     HBufC*   query = NULL;
       
  3628     
       
  3629     // Create a view given this select...    
       
  3630     _LIT(KQuery, "SELECT Title, ItemId FROM ItemTable WHERE FeedId = %d AND ItemStatus = %d");
       
  3631     
       
  3632     query = HBufC::NewLC( KQuery().Length() + KIntLength + KIntLength ); 
       
  3633                         
       
  3634     query->Des().Format( KQuery, aFeedId, aStatus );
       
  3635 
       
  3636     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), 
       
  3637             RDbView::EReadOnly));
       
  3638     CleanupClosePushL(view);
       
  3639 
       
  3640     CDbColSet* colSet = view.ColSetL();
       
  3641     CleanupStack::PushL(colSet);
       
  3642     
       
  3643     if (view.EvaluateAll() >= 0)
       
  3644         {
       
  3645         for (view.FirstL(); view.AtRow(); view.NextL())
       
  3646             {
       
  3647             // Get the row.
       
  3648             view.GetL();
       
  3649             
       
  3650             // Extract the fields.
       
  3651             TPtrC title( view.ColDes16(colSet->ColNo(KTitle_100MaxLen)) );
       
  3652             TInt  itemId = view.ColUint16(colSet->ColNo(KItemId));
       
  3653 
       
  3654             // Copy the data into the packed folder.
       
  3655             aFolder.ItemBeginsL();
       
  3656             
       
  3657             if (title.Length() > 0)
       
  3658                 {
       
  3659                 aFolder.AddAttributeL( EFolderAttributeMiniItemTitle, title );
       
  3660                 aFolder.AddAttributeL( EFolderAttributeMiniItemId, itemId );            
       
  3661                 }            
       
  3662 
       
  3663             // Signal the end of the item.
       
  3664             aFolder.ItemEndsL();
       
  3665             }
       
  3666         }
       
  3667         
       
  3668     CleanupStack::PopAndDestroy(colSet);
       
  3669     CleanupStack::PopAndDestroy(/*view*/);
       
  3670     CleanupStack::PopAndDestroy(query);
       
  3671     }
       
  3672 
       
  3673 
       
  3674 // -----------------------------------------------------------------------------
       
  3675 // CFeedsDatabase::WriteLongTextL
       
  3676 //
       
  3677 // Writes "long" text to the database.
       
  3678 // -----------------------------------------------------------------------------
       
  3679 //
       
  3680 void CFeedsDatabase::WriteLongTextL(RDbRowSet& aTable, TInt aColumnIndex, 
       
  3681         const TDesC& aValue)
       
  3682     {
       
  3683     RDbColWriteStream  stream;
       
  3684     
       
  3685     stream.OpenLC(aTable, aColumnIndex);
       
  3686     stream.WriteL(aValue);
       
  3687     stream.Close();
       
  3688     CleanupStack::Pop(/*stream*/);
       
  3689     }
       
  3690     
       
  3691     
       
  3692 // -----------------------------------------------------------------------------
       
  3693 // CFeedsDatabase::ReadLongTextL
       
  3694 //
       
  3695 // Reads "long" text from the database.
       
  3696 // -----------------------------------------------------------------------------
       
  3697 //
       
  3698 void CFeedsDatabase::ReadLongTextL(RDbRowSet& aTable, TInt aColumnIndex, 
       
  3699         HBufC*& aValue)
       
  3700     {
       
  3701     RDbColReadStream  stream;
       
  3702     HBufC*            value = NULL;
       
  3703     TInt              length;
       
  3704     
       
  3705     length = aTable.ColLength(aColumnIndex);
       
  3706     value = HBufC::NewLC(length);
       
  3707     TPtr  v(value->Des());
       
  3708     
       
  3709     if (length > 0)
       
  3710         {        
       
  3711         stream.OpenLC(aTable, aColumnIndex);
       
  3712         stream.ReadL(v, length);
       
  3713         stream.Close();
       
  3714         CleanupStack::Pop(/*stream*/);
       
  3715         }
       
  3716         
       
  3717     CleanupStack::Pop(value);    
       
  3718     aValue = value;
       
  3719     }
       
  3720 
       
  3721 
       
  3722 // -----------------------------------------------------------------------------
       
  3723 // CFeedsDatabase::UseFolderListTableLC
       
  3724 //
       
  3725 // Pushes the release table function onto cleanup stack 
       
  3726 // and opens the FolderList table for use.
       
  3727 // -----------------------------------------------------------------------------
       
  3728 //
       
  3729 void CFeedsDatabase::UseFolderListTableLC(RDbRowSet::TAccess aAccess)
       
  3730 	{
       
  3731 	// Push the clean up function on the stack.
       
  3732 	CleanupStack::PushL(TCleanupItem(&ReleaseFolderListTable, this));
       
  3733 
       
  3734 	OpenFolderListTableL(aAccess);
       
  3735 	}
       
  3736 
       
  3737 
       
  3738 // -----------------------------------------------------------------------------
       
  3739 // CFeedsDatabase::OpenFolderListTableL
       
  3740 //
       
  3741 // Closes the Feed table.
       
  3742 // -----------------------------------------------------------------------------
       
  3743 //
       
  3744 void CFeedsDatabase::OpenFolderListTableL(RDbRowSet::TAccess aAccess)
       
  3745 	{
       
  3746     // Inc the ref count.
       
  3747     iFolderListTableRefCount++;
       
  3748 
       
  3749     // If need be open the table.
       
  3750     if (iFolderListTableRefCount == 1)
       
  3751         {        
       
  3752         // Open the database a get the colSet.
       
  3753         User::LeaveIfError(iFolderListTable.Open(iDatabase, KFolderListTable, aAccess));
       
  3754         iFolderListColSet = iFolderListTable.ColSetL();
       
  3755 
       
  3756         User::LeaveIfError(iFolderListTable.SetIndex(KFolderListTableIndex));
       
  3757         }    
       
  3758 	}
       
  3759 
       
  3760     
       
  3761 // -----------------------------------------------------------------------------
       
  3762 // CFeedsDatabase::ReleaseFolderListTable
       
  3763 //
       
  3764 // Closes the Folder List table.
       
  3765 // -----------------------------------------------------------------------------
       
  3766 //
       
  3767 void CFeedsDatabase::ReleaseFolderListTable(TAny *aPtr)
       
  3768     {
       
  3769     CFeedsDatabase*  self = static_cast<CFeedsDatabase*>(aPtr);
       
  3770 
       
  3771     // Dec the ref count.
       
  3772     self->iFolderListTableRefCount--;
       
  3773     
       
  3774     // If need be close the table.
       
  3775     if (self->iFolderListTableRefCount == 0)
       
  3776         {        
       
  3777         delete self->iFolderListColSet;
       
  3778         self->iFolderListColSet = NULL;    
       
  3779         self->iFolderListTable.Close();
       
  3780         }
       
  3781     else if (self->iFolderListTableRefCount < 0)
       
  3782         {
       
  3783         User::Panic(_L("Feeds Server"), KErrArgument);
       
  3784         }
       
  3785     }
       
  3786     
       
  3787     
       
  3788 // -----------------------------------------------------------------------------
       
  3789 // CFeedsDatabase::UseFeedTableLC
       
  3790 //
       
  3791 // Pushes the release table function onto cleanup stack 
       
  3792 // and opens the Feed table for use.
       
  3793 // -----------------------------------------------------------------------------
       
  3794 //
       
  3795 void CFeedsDatabase::UseFeedTableLC(RDbRowSet::TAccess aAccess)
       
  3796     {
       
  3797     // Push the clean up function on the stack.
       
  3798     CleanupStack::PushL(TCleanupItem(&ReleaseFeedTable, this));
       
  3799     
       
  3800     OpenFeedTableL(aAccess);
       
  3801     }
       
  3802 
       
  3803 
       
  3804 // -----------------------------------------------------------------------------
       
  3805 // CFeedsDatabase::OpenFeedTableL
       
  3806 //
       
  3807 // Opens the Feed table for use.
       
  3808 // -----------------------------------------------------------------------------
       
  3809 //
       
  3810 void CFeedsDatabase::OpenFeedTableL(RDbRowSet::TAccess aAccess)
       
  3811 	{
       
  3812     // Inc the ref count.
       
  3813     iFeedTableRefCount++;
       
  3814     
       
  3815     // If need be open the table.
       
  3816     if (iFeedTableRefCount == 1)
       
  3817         {        
       
  3818         User::LeaveIfError(iFeedTable.Open(iDatabase, KFeedTable, aAccess));
       
  3819         iFeedColSet = iFeedTable.ColSetL();
       
  3820 
       
  3821         User::LeaveIfError(iFeedTable.SetIndex(KFeedTableIndex));
       
  3822         }  
       
  3823 	}
       
  3824 
       
  3825 // -----------------------------------------------------------------------------
       
  3826 // CFeedsDatabase::ReleaseFeedTable
       
  3827 //
       
  3828 // Closes the Feed table.
       
  3829 // -----------------------------------------------------------------------------
       
  3830 //
       
  3831 void CFeedsDatabase::ReleaseFeedTable(TAny *aPtr)
       
  3832     {
       
  3833     CFeedsDatabase*  self = static_cast<CFeedsDatabase*>(aPtr);
       
  3834     
       
  3835     // Dec the ref count.
       
  3836     self->iFeedTableRefCount--;
       
  3837     
       
  3838     // If need be close the table.
       
  3839     if (self->iFeedTableRefCount == 0)
       
  3840         {        
       
  3841         delete self->iFeedColSet;
       
  3842         self->iFeedColSet = NULL;
       
  3843         self->iFeedTable.Close();
       
  3844         }
       
  3845     else if (self->iFeedTableRefCount < 0)
       
  3846         {
       
  3847         User::Panic(_L("Feeds Server"), KErrArgument);
       
  3848         }
       
  3849     }
       
  3850 
       
  3851 
       
  3852 // -----------------------------------------------------------------------------
       
  3853 // CFeedsDatabase::PrepareImportTransationsL
       
  3854 //
       
  3855 // Opens the OPML import related tables (FeedTable and FolderListTable)
       
  3856 //	 and starts a transaction
       
  3857 // -----------------------------------------------------------------------------
       
  3858 //
       
  3859 void CFeedsDatabase::PrepareImportTransationsL()
       
  3860 	{
       
  3861 	
       
  3862 	OpenFeedTableL(RDbTable::EUpdatable);
       
  3863 	OpenFolderListTableL(RDbTable::EUpdatable);
       
  3864 
       
  3865 	// Start transaction        
       
  3866 	iDatabase.Begin();        
       
  3867 
       
  3868 	}
       
  3869 
       
  3870 // -----------------------------------------------------------------------------
       
  3871 // CFeedsDatabase::ReleaseImportTables
       
  3872 //
       
  3873 // Closes the OPML import related tables (FeedTable and FolderListTable)
       
  3874 // -----------------------------------------------------------------------------
       
  3875 //
       
  3876 void CFeedsDatabase::ReleaseImportTables()
       
  3877 	{
       
  3878 	ReleaseFolderListTable(this);
       
  3879 	ReleaseFeedTable(this);
       
  3880 	}
       
  3881 
       
  3882 
       
  3883 // -----------------------------------------------------------------------------
       
  3884 // CFeedsDatabase::CommitImportTransaction
       
  3885 //
       
  3886 // Commits current database transaction
       
  3887 // -----------------------------------------------------------------------------
       
  3888 //
       
  3889 void CFeedsDatabase::CommitImportTransaction()
       
  3890 	{
       
  3891 	if(iDatabase.InTransaction())
       
  3892 		iDatabase.Commit();
       
  3893 	}
       
  3894 
       
  3895 // -----------------------------------------------------------------------------
       
  3896 // CFeedsDatabase::CancelImportTransaction
       
  3897 //
       
  3898 // Cancels/Rollbacks current database transaction
       
  3899 // -----------------------------------------------------------------------------
       
  3900 //
       
  3901 void CFeedsDatabase::CancelImportTransaction()
       
  3902 	{
       
  3903 	if(iDatabase.InTransaction())
       
  3904 		iDatabase.Rollback();
       
  3905 	}
       
  3906 
       
  3907 // -----------------------------------------------------------------------------
       
  3908 // CFeedsDatabase::DeleteFeedTableRecordsL
       
  3909 //
       
  3910 // Deletes records from a FeedTable
       
  3911 // -----------------------------------------------------------------------------
       
  3912 //
       
  3913 void CFeedsDatabase::DeleteFeedTableRecordsL(RArray<TInt>& aFeedIds)
       
  3914 	{
       
  3915 	if(aFeedIds.Count() <= 0)
       
  3916 		return;
       
  3917 	
       
  3918 	DeleteRecordsFromTableL(KFeedTable, KFeedId, aFeedIds);
       
  3919 	}
       
  3920 	
       
  3921 // -----------------------------------------------------------------------------
       
  3922 // CFeedsDatabase::DeleteFolderListTableRecordsL
       
  3923 //
       
  3924 // Deletes records from a FolderListTable
       
  3925 // -----------------------------------------------------------------------------
       
  3926 //
       
  3927 void CFeedsDatabase::DeleteFolderListTableRecordsL(RArray<TInt>& aFolderItemIds)
       
  3928 	{
       
  3929 	if(aFolderItemIds.Count() <= 0)
       
  3930 		return;
       
  3931 	
       
  3932 	DeleteRecordsFromTableL(KFolderListTable, KFolderItemId, aFolderItemIds);
       
  3933 	}
       
  3934 
       
  3935 // -----------------------------------------------------------------------------
       
  3936 // CFeedsDatabase::DeleteRecordsFromTableL
       
  3937 //
       
  3938 // Deletes records from a given table
       
  3939 // -----------------------------------------------------------------------------
       
  3940 //
       
  3941 void CFeedsDatabase::DeleteRecordsFromTableL(const TDesC& aTableName, const TDesC& aColumnName, RArray<TInt>& aIds)
       
  3942 	{
       
  3943 	_LIT( KSQLDeleteFormat, "DELETE FROM %S WHERE %S = %d");
       
  3944 	
       
  3945 	TInt numIds = aIds.Count();
       
  3946 	if(numIds <= 0)
       
  3947 		{
       
  3948 		return;
       
  3949 		}	
       
  3950 
       
  3951 	HBufC*   query = NULL;
       
  3952     query = HBufC::NewLC( 
       
  3953     						KSQLDeleteFormat().Length()
       
  3954     					  	+ aTableName.Length()
       
  3955     					  	+ aColumnName.Length()
       
  3956     					  	+ KIntLength
       
  3957     					 );
       
  3958 
       
  3959 	for(TInt i=0; i<numIds; i++)
       
  3960 		{
       
  3961 		query->Des().Format(KSQLDeleteFormat, &aTableName, &aColumnName, aIds[i]);
       
  3962 		iDatabase.Execute(*query);
       
  3963 		}
       
  3964 
       
  3965  	CleanupStack::PopAndDestroy(query);
       
  3966 	}
       
  3967 
       
  3968 // -----------------------------------------------------------------------------
       
  3969 // CFeedsDatabase::UseItemTableLC
       
  3970 //
       
  3971 // Opens the Item table for use.
       
  3972 // -----------------------------------------------------------------------------
       
  3973 //
       
  3974 void CFeedsDatabase::UseItemTableLC(RDbRowSet::TAccess aAccess)
       
  3975     {
       
  3976     // Inc the ref count.
       
  3977     iItemTableRefCount++;
       
  3978     
       
  3979     // Push the clean up function on the stack.
       
  3980     CleanupStack::PushL(TCleanupItem(&ReleaseItemTable, this));
       
  3981 
       
  3982     // If need be open the table.
       
  3983     if (iItemTableRefCount == 1)
       
  3984         {        
       
  3985         User::LeaveIfError(iItemTable.Open(iDatabase, KItemTable, aAccess));
       
  3986         iItemColSet = iItemTable.ColSetL();
       
  3987 
       
  3988         User::LeaveIfError(iItemTable.SetIndex(KItemTableIndex));
       
  3989         }
       
  3990     }
       
  3991 
       
  3992 
       
  3993 // -----------------------------------------------------------------------------
       
  3994 // CFeedsDatabase::ReleaseItemTable
       
  3995 //
       
  3996 // Closes the Item table.
       
  3997 // -----------------------------------------------------------------------------
       
  3998 //
       
  3999 void CFeedsDatabase::ReleaseItemTable(TAny *aPtr)
       
  4000     {
       
  4001     CFeedsDatabase*  self = static_cast<CFeedsDatabase*>(aPtr);
       
  4002     
       
  4003     // Dec the ref count.
       
  4004     self->iItemTableRefCount--;
       
  4005     
       
  4006     // If need be close the table.
       
  4007     if (self->iItemTableRefCount == 0)
       
  4008         {        
       
  4009         delete self->iItemColSet;
       
  4010         self->iItemColSet = NULL;
       
  4011         self->iItemTable.Close();
       
  4012         }
       
  4013     else if (self->iItemTableRefCount < 0)
       
  4014         {
       
  4015         User::Panic(_L("Feeds Server"), KErrArgument);
       
  4016         }
       
  4017     }
       
  4018     
       
  4019     
       
  4020 // -----------------------------------------------------------------------------
       
  4021 // CFeedsDatabase::UseEnclosureTableLC
       
  4022 //
       
  4023 // Opens the Enclosure table for use.
       
  4024 // -----------------------------------------------------------------------------
       
  4025 //
       
  4026 void CFeedsDatabase::UseEnclosureTableLC(RDbRowSet::TAccess aAccess)
       
  4027     {
       
  4028     // Inc the ref count.
       
  4029     iEnclosureTableRefCount++;
       
  4030     
       
  4031     // Push the clean up function on the stack.
       
  4032     CleanupStack::PushL(TCleanupItem(&ReleaseEnclosureTable, this));
       
  4033 
       
  4034     // If need be open the table.
       
  4035     if (iEnclosureTableRefCount == 1)
       
  4036         {        
       
  4037         User::LeaveIfError(iEnclosureTable.Open(iDatabase, KEnclosureTable, aAccess));
       
  4038         iEnclosureColSet = iEnclosureTable.ColSetL();
       
  4039 
       
  4040         User::LeaveIfError(iEnclosureTable.SetIndex(KEnclosureTableIndex));
       
  4041         }
       
  4042     }
       
  4043 
       
  4044 
       
  4045 // -----------------------------------------------------------------------------
       
  4046 // CFeedsDatabase::ReleaseEnclosureTable
       
  4047 //
       
  4048 // Closes the Enclosure table.
       
  4049 // -----------------------------------------------------------------------------
       
  4050 //
       
  4051 void CFeedsDatabase::ReleaseEnclosureTable(TAny *aPtr)
       
  4052     {
       
  4053     CFeedsDatabase*  self = static_cast<CFeedsDatabase*>(aPtr);
       
  4054     
       
  4055     // Dec the ref count.
       
  4056     self->iEnclosureTableRefCount--;
       
  4057     
       
  4058     // If need be close the table.
       
  4059     if (self->iEnclosureTableRefCount == 0)
       
  4060         {        
       
  4061         delete self->iEnclosureColSet;
       
  4062         self->iEnclosureColSet = NULL;
       
  4063         self->iEnclosureTable.Close();
       
  4064         }
       
  4065     else if (self->iEnclosureTableRefCount < 0)
       
  4066         {
       
  4067         User::Panic(_L("Feeds Server"), KErrArgument);
       
  4068         }
       
  4069     }
       
  4070     
       
  4071 
       
  4072 // -----------------------------------------------------------------------------
       
  4073 // CFeedsDatabase::UseVersionTableLC
       
  4074 //
       
  4075 // Opens the Version table for use.
       
  4076 // -----------------------------------------------------------------------------
       
  4077 //
       
  4078 void CFeedsDatabase::UseVersionTableLC(RDbRowSet::TAccess aAccess)
       
  4079     {
       
  4080     // Inc the ref count.
       
  4081     iVersionTableRefCount++;
       
  4082     
       
  4083     // Push the clean up function on the stack.
       
  4084     CleanupStack::PushL(TCleanupItem(&ReleaseVersionTable, this));
       
  4085 
       
  4086     // If need be open the table.
       
  4087     if (iVersionTableRefCount == 1)
       
  4088         {        
       
  4089         User::LeaveIfError(iVersionTable.Open(iDatabase, KVersionTable, aAccess));
       
  4090         iVersionColSet = iVersionTable.ColSetL();
       
  4091         }
       
  4092     }
       
  4093 
       
  4094 
       
  4095 // -----------------------------------------------------------------------------
       
  4096 // CFeedsDatabase::ReleaseVersionTable
       
  4097 //
       
  4098 // Closes the Version table.
       
  4099 // -----------------------------------------------------------------------------
       
  4100 //
       
  4101 void CFeedsDatabase::ReleaseVersionTable(TAny *aPtr)
       
  4102     {
       
  4103     CFeedsDatabase*  self = static_cast<CFeedsDatabase*>(aPtr);
       
  4104     
       
  4105     // Dec the ref count.
       
  4106     self->iVersionTableRefCount--;
       
  4107     
       
  4108     // If need be close the table.
       
  4109     if (self->iVersionTableRefCount == 0)
       
  4110         {        
       
  4111         delete self->iVersionColSet;
       
  4112         self->iVersionColSet = NULL;
       
  4113         self->iVersionTable.Close();
       
  4114         }
       
  4115     else if (self->iVersionTableRefCount < 0)
       
  4116         {
       
  4117         User::Panic(_L("Feeds Server"), KErrArgument);
       
  4118         }
       
  4119     }
       
  4120 
       
  4121 
       
  4122 // -----------------------------------------------------------------------------
       
  4123 // CFeedsDatabase::UseSettingsTableLC
       
  4124 //
       
  4125 // Opens the Settings table for use.
       
  4126 // -----------------------------------------------------------------------------
       
  4127 //
       
  4128 void CFeedsDatabase::UseSettingsTableLC(RDbRowSet::TAccess aAccess)
       
  4129     {
       
  4130     // Inc the ref count.
       
  4131     iSettingsTableRefCount++;
       
  4132     
       
  4133     // Push the clean up function on the stack.
       
  4134     CleanupStack::PushL(TCleanupItem(&ReleaseSettingsTable, this));
       
  4135 
       
  4136     // If need be open the table.
       
  4137     if (iSettingsTableRefCount == 1)
       
  4138         {        
       
  4139         User::LeaveIfError(iSettingsTable.Open(iDatabase, KSettingsTable, aAccess));
       
  4140         iSettingsColSet = iSettingsTable.ColSetL();
       
  4141 
       
  4142         User::LeaveIfError(iSettingsTable.SetIndex( KSettingsTableIndex ));
       
  4143         }
       
  4144     }
       
  4145 
       
  4146 
       
  4147 // -----------------------------------------------------------------------------
       
  4148 // CFeedsDatabase::ReleaseSettingsTable
       
  4149 //
       
  4150 // Closes the Settings table.
       
  4151 // -----------------------------------------------------------------------------
       
  4152 //
       
  4153 void CFeedsDatabase::ReleaseSettingsTable(TAny *aPtr)
       
  4154     {
       
  4155     CFeedsDatabase*  self = static_cast<CFeedsDatabase*>(aPtr);
       
  4156     
       
  4157     // Dec the ref count.
       
  4158     self->iSettingsTableRefCount--;
       
  4159     
       
  4160     // If need be close the table.
       
  4161     if (self->iSettingsTableRefCount == 0)
       
  4162         {        
       
  4163         delete self->iSettingsColSet;
       
  4164         self->iSettingsColSet = NULL;
       
  4165         self->iSettingsTable.Close();
       
  4166         }
       
  4167     else if (self->iSettingsTableRefCount < 0)
       
  4168         {
       
  4169         User::Panic(_L("Feeds Server"), KErrArgument);
       
  4170         }
       
  4171     }   
       
  4172 
       
  4173 // -----------------------------------------------------------------------------
       
  4174 // CFeedsDatabase::UpdateFeedStatus
       
  4175 //
       
  4176 // Update feed with status Codes
       
  4177 // -----------------------------------------------------------------------------
       
  4178 //
       
  4179 void CFeedsDatabase::UpdateFeedStatusL(TInt aFeedId, TInt aFeedStatus)
       
  4180     {
       
  4181     RDbView  view;
       
  4182     TBool    found = EFalse;
       
  4183     HBufC*   query = NULL;
       
  4184     TInt previousStatus = KErrNone;
       
  4185     TInt parentId = KRootFolderId;
       
  4186     
       
  4187     // Create a view given this select...    
       
  4188     _LIT(KQuery, "SELECT ParentId,Status FROM FolderListTable WHERE FeedId = %d AND IsFolder = %d");
       
  4189     query = HBufC::NewLC( KQuery().Length() + KIntLength + KIntLength );
       
  4190             
       
  4191     query->Des().Format( KQuery, aFeedId, 0 );
       
  4192 
       
  4193     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EUpdatable));
       
  4194     CleanupClosePushL(view);
       
  4195 
       
  4196     CDbColSet* colSet = view.ColSetL();
       
  4197     CleanupStack::PushL(colSet);
       
  4198     
       
  4199     // Search for the feed.
       
  4200     if (view.Evaluate() >= 0)
       
  4201         {
       
  4202         if (view.FirstL())
       
  4203             {
       
  4204             // Get the feed id.
       
  4205             view.GetL();
       
  4206             view.UpdateL();        
       
  4207             previousStatus = view.ColInt32(colSet->ColNo(KStatus));
       
  4208             parentId = view.ColUint16(colSet->ColNo(KParentId));
       
  4209             view.SetColL(colSet->ColNo(KStatus),aFeedStatus);
       
  4210             view.PutL();
       
  4211             found = ETrue;
       
  4212             }
       
  4213         }
       
  4214 
       
  4215     CleanupStack::PopAndDestroy(colSet);
       
  4216     CleanupStack::PopAndDestroy(/*view*/);
       
  4217     CleanupStack::PopAndDestroy(query);
       
  4218 	if(!found)
       
  4219 	{
       
  4220 		return;
       
  4221 	}
       
  4222 
       
  4223     if(previousStatus == KErrNone && aFeedStatus == KErrNone)
       
  4224     	{
       
  4225     	return;
       
  4226     	}
       
  4227     else if(previousStatus != KErrNone && aFeedStatus != KErrNone)
       
  4228     	{
       
  4229     	return;
       
  4230     	}
       
  4231     else if(previousStatus == KErrNone && aFeedStatus != KErrNone)
       
  4232     	{
       
  4233     	    // Open the various tables
       
  4234     	    UseFolderListTableLC(RDbTable::EUpdatable);
       
  4235     	    while(parentId != KRootFolderId)
       
  4236     	    	{
       
  4237         		TDbSeekKey  folderListKey(parentId);
       
  4238         		if(iFolderListTable.SeekL(folderListKey))
       
  4239         			{
       
  4240         	        iFolderListTable.GetL();
       
  4241         			parentId = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KParentId));
       
  4242         			previousStatus = iFolderListTable.ColInt32(iFolderListColSet->ColNo(KStatus));
       
  4243     				iFolderListTable.UpdateL();
       
  4244     				iFolderListTable.SetColL(iFolderListColSet->ColNo(KStatus), previousStatus-1);
       
  4245     				iFolderListTable.PutL();
       
  4246     				if(previousStatus != KErrNone)
       
  4247         				{
       
  4248         					break;
       
  4249         				}
       
  4250         			}
       
  4251     	    	}
       
  4252     	    // Clean up.
       
  4253     	    CleanupStack::PopAndDestroy(/*folder list table*/);
       
  4254     	}
       
  4255     else if(previousStatus != KErrNone && aFeedStatus == KErrNone)
       
  4256     	{
       
  4257     	    // Open the various tables
       
  4258     	    UseFolderListTableLC(RDbTable::EUpdatable);
       
  4259     	    while(parentId != KRootFolderId)
       
  4260     	    	{
       
  4261         		TDbSeekKey  folderListKey(parentId);
       
  4262         		if(iFolderListTable.SeekL(folderListKey))
       
  4263         			{
       
  4264         	        iFolderListTable.GetL();
       
  4265         			parentId = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KParentId));
       
  4266         			previousStatus = iFolderListTable.ColInt32(iFolderListColSet->ColNo(KStatus));
       
  4267     				iFolderListTable.UpdateL();
       
  4268     				iFolderListTable.SetColL(iFolderListColSet->ColNo(KStatus), previousStatus+1);
       
  4269     				iFolderListTable.PutL();
       
  4270 
       
  4271         			if(previousStatus+1 != KErrNone)
       
  4272         				{
       
  4273         					break;
       
  4274         				}
       
  4275         			}
       
  4276     	    	}
       
  4277     	    // Clean up.
       
  4278     	    CleanupStack::PopAndDestroy(/*folder list table*/);
       
  4279     	}
       
  4280     }   
       
  4281 
       
  4282 // -----------------------------------------------------------------------------
       
  4283 // CFeedsDatabase::FreqFromFeedIdL
       
  4284 //
       
  4285 // Return the auto update freq of the feed with the given feed-id.
       
  4286 // -----------------------------------------------------------------------------
       
  4287 //
       
  4288 TBool CFeedsDatabase::FreqFromFeedIdL(TInt aFeedId, TInt& aFreq)
       
  4289     {
       
  4290     RDbView  view;
       
  4291     TBool    found = EFalse;
       
  4292     HBufC*   query = NULL;
       
  4293     
       
  4294     // Create a view given this select...    
       
  4295     // SELECT AutoUpdateFreq FROM FeedTable WHERE FeedId = aFeedId
       
  4296     _LIT(KQuery, "SELECT AutoUpdateFreq FROM FeedTable WHERE FeedId = %d");
       
  4297     
       
  4298     query = HBufC::NewLC(KQuery().Length() + KIntLength);
       
  4299             
       
  4300     query->Des().Format(KQuery, aFeedId);
       
  4301 
       
  4302     User::LeaveIfError(view.Prepare(iDatabase, TDbQuery(*query), RDbView::EReadOnly));
       
  4303     CleanupClosePushL(view);
       
  4304 
       
  4305     CDbColSet* colSet = view.ColSetL();
       
  4306     CleanupStack::PushL(colSet);
       
  4307     
       
  4308     // Search for the feed.
       
  4309     if (view.Evaluate() >= 0)
       
  4310         {
       
  4311         if (view.FirstL())
       
  4312             {
       
  4313             // Get the feed id.
       
  4314             view.GetL();        
       
  4315             aFreq = view.ColUint32(colSet->ColNo(KAutoUpdateFreq));
       
  4316             }
       
  4317         }
       
  4318         
       
  4319     CleanupStack::PopAndDestroy(colSet);
       
  4320     CleanupStack::PopAndDestroy(/*view*/);
       
  4321     CleanupStack::PopAndDestroy(query);
       
  4322 
       
  4323     return found;
       
  4324     }
       
  4325 
       
  4326 // -----------------------------------------------------------------------------
       
  4327 // CFeedsDatabase::AlterFeedTableWithAutoFequencyL
       
  4328 //
       
  4329 // Adds a new column AutoUpdateFreq to FeedTable in the case of versions less 
       
  4330 // than 7.1.
       
  4331 // -----------------------------------------------------------------------------
       
  4332 //
       
  4333 void CFeedsDatabase::AlterFeedTableWithAutoFequencyL()
       
  4334     {
       
  4335     UseFeedTableLC(RDbTable::EUpdatable);
       
  4336 
       
  4337     // get the exiting col set
       
  4338     CDbColSet* colSet = iDatabase.ColSetL(KFeedTable);
       
  4339 
       
  4340     colSet->AddL(TDbCol(KAutoUpdateFreq, EDbColUint32));
       
  4341     iDatabase.AlterTable(KFeedTable, *colSet);
       
  4342 
       
  4343     CleanupStack::PopAndDestroy(/* FeedTable */);  		     
       
  4344 
       
  4345     // Set the auto update frequency as KErrorNotSet
       
  4346     // Prep the item table.
       
  4347     UseFeedTableLC(RDbTable::EUpdatable);
       
  4348 
       
  4349     while( iFeedTable.NextL() )
       
  4350           {
       
  4351           // Get the row. and add the default value.
       
  4352           iFeedTable.GetL();
       
  4353           iFeedTable.UpdateL();
       
  4354 
       
  4355           iFeedTable.SetColL(iFeedColSet->ColNo(KAutoUpdateFreq), KAutoUpdatingOff);
       
  4356 
       
  4357           iFeedTable.PutL();
       
  4358           }
       
  4359 
       
  4360     CleanupStack::PopAndDestroy(/* iFeedTable */);
       
  4361     }
       
  4362 
       
  4363 #if defined(_DEBUG)
       
  4364 // -----------------------------------------------------------------------------
       
  4365 // CFeedsDatabase::DebugPrintTables
       
  4366 //
       
  4367 // Prints the tables to the log file.
       
  4368 // -----------------------------------------------------------------------------
       
  4369 //
       
  4370 void CFeedsDatabase::DebugPrintTablesL()
       
  4371     {
       
  4372     DebugPrintFolderListTableL();
       
  4373     DebugPrintItemTableL();
       
  4374     }
       
  4375 
       
  4376 // -----------------------------------------------------------------------------
       
  4377 // CFeedsDatabase::DebugPrintFolderListTableL
       
  4378 //
       
  4379 // Prints the folder list table to the log file.
       
  4380 // -----------------------------------------------------------------------------
       
  4381 //
       
  4382 void CFeedsDatabase::DebugPrintFolderListTableL()
       
  4383     {   
       
  4384     // Prep the FolderList table.
       
  4385     UseFolderListTableLC(RDbTable::EReadOnly);
       
  4386 
       
  4387     // column names
       
  4388     FEED_LOG(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4389         EFileLoggingModeAppend, _L(""));				
       
  4390     FEED_LOG(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4391         EFileLoggingModeAppend,
       
  4392         _L("============================================================================================================="));				
       
  4393     FEED_LOG(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4394         EFileLoggingModeAppend, _L("FolderListTable"));
       
  4395     FEED_LOG(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4396         EFileLoggingModeAppend, _L(""));				
       
  4397     FEED_LOG(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4398         EFileLoggingModeAppend, _L("ListId\t\tItemId\tParent\tSiblin\tType\tFeedId\tTitle"));
       
  4399     FEED_LOG(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4400         EFileLoggingModeAppend,
       
  4401         _L("============================================================================================================="));				
       
  4402 
       
  4403     while( iFolderListTable.NextL() )
       
  4404         {
       
  4405         // Get the row.
       
  4406         iFolderListTable.GetL();
       
  4407         
       
  4408         TInt folderListId = iFolderListTable.ColInt32(iFolderListColSet->ColNo(KFolderListId));
       
  4409         TInt folderItemId = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KFolderItemId));
       
  4410         TInt parentId = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KParentId));
       
  4411         TInt SiblingOrder = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KSiblingOrder));
       
  4412         TBool isFolder = iFolderListTable.ColUint8(iFolderListColSet->ColNo(KIsFolder));
       
  4413         TInt feedId = iFolderListTable.ColUint16(iFolderListColSet->ColNo(KFeedId));
       
  4414         if( isFolder )
       
  4415             {
       
  4416             feedId = KUnassignedId;
       
  4417             }
       
  4418         TPtrC title( KNullDesC );
       
  4419         title.Set(iFolderListTable.ColDes16(iFolderListColSet->ColNo(KTitle_100MaxLen)));
       
  4420 
       
  4421         // folder or feed
       
  4422         if( isFolder )
       
  4423             {
       
  4424             if( folderListId == 0 )
       
  4425                 {
       
  4426                 FEED_LOG6(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4427                     EFileLoggingModeAppend, _L("%d\t\t%d\t%d\t%d\tfolder\t%d\t%S"), 
       
  4428                     folderListId, folderItemId, parentId, SiblingOrder, feedId, &title);
       
  4429                 }
       
  4430             else
       
  4431                 {
       
  4432                 FEED_LOG6(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4433                     EFileLoggingModeAppend, _L("%d\t%d\t%d\t%d\tfolder\t%d\t%S"), 
       
  4434                     folderListId, folderItemId, parentId, SiblingOrder, feedId, &title);
       
  4435                 }
       
  4436             }
       
  4437         else
       
  4438             {
       
  4439             if( folderListId == 0 )
       
  4440                 {
       
  4441                 FEED_LOG6(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4442                     EFileLoggingModeAppend, _L("%d\t\t%d\t%d\t%d\tfeed\t%d\t%S"), 
       
  4443                     folderListId, folderItemId, parentId, SiblingOrder, feedId, &title);
       
  4444                 }
       
  4445             else
       
  4446                 {
       
  4447                 FEED_LOG6(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4448                     EFileLoggingModeAppend, _L("%d\t%d\t%d\t%d\tfeed\t%d\t%S"), 
       
  4449                     folderListId, folderItemId, parentId, SiblingOrder, feedId, &title);
       
  4450                 }
       
  4451             }
       
  4452         }
       
  4453                 
       
  4454     CleanupStack::PopAndDestroy(/*folder list Table*/);
       
  4455     }
       
  4456 
       
  4457 
       
  4458 // -----------------------------------------------------------------------------
       
  4459 // CFeedsDatabase::DebugPrintItemTableL
       
  4460 //
       
  4461 // Prints the item table to the log file.
       
  4462 // -----------------------------------------------------------------------------
       
  4463 //
       
  4464 void CFeedsDatabase::DebugPrintItemTableL()
       
  4465     {
       
  4466     // Prep the item table.
       
  4467     UseItemTableLC(RDbTable::EReadOnly);
       
  4468 
       
  4469     // column names
       
  4470     FEED_LOG(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4471         EFileLoggingModeAppend, _L(""));				
       
  4472     FEED_LOG(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4473         EFileLoggingModeAppend,
       
  4474         _L("============================================================================================================="));				
       
  4475     FEED_LOG(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4476         EFileLoggingModeAppend, _L("ItemTable"));
       
  4477     FEED_LOG(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4478         EFileLoggingModeAppend, _L(""));				
       
  4479     FEED_LOG(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4480         EFileLoggingModeAppend, _L("ItemId\tFeedId\tStatus\tTitle\tIdStr"));
       
  4481     FEED_LOG(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4482         EFileLoggingModeAppend,
       
  4483         _L("============================================================================================================="));				
       
  4484 
       
  4485     while( iItemTable.NextL() )
       
  4486         {
       
  4487         // Get the row.
       
  4488         iItemTable.GetL();
       
  4489         
       
  4490         TInt itemId = iItemTable.ColUint16(iItemColSet->ColNo(KItemId));
       
  4491         TInt feedId = iItemTable.ColUint16(iItemColSet->ColNo(KFeedId));
       
  4492 
       
  4493         TBuf<(KMaxTimeFormatSpec + KMaxShortDateFormatSpec) * 2>  timestamp;
       
  4494         //TBuf<KMaxTimeFormatSpec * 2>  temp;    
       
  4495         TTime date = iItemTable.ColTime(iItemColSet->ColNo(KDate));
       
  4496         date.FormatL(timestamp, TTimeFormatSpec());
       
  4497         //date.FormatL(temp, TShortDateFormatSpec());
       
  4498         //timestamp.Append(_L("  "));
       
  4499         //timestamp.Append(temp);
       
  4500         // JH TO DO: why timestamp not shown up in the log
       
  4501 
       
  4502         TInt itemStatus = iItemTable.ColUint16(iItemColSet->ColNo(KItemStatus));
       
  4503         TPtrC title( KNullDesC );
       
  4504         title.Set(iItemTable.ColDes16(iItemColSet->ColNo(KTitle_100MaxLen)));
       
  4505         HBufC* idStr = NULL;
       
  4506         ReadLongTextL(iItemTable, iItemColSet->ColNo(KItemIdStr), idStr);
       
  4507         CleanupStack::PushL(idStr);
       
  4508 
       
  4509         switch( itemStatus )
       
  4510             {
       
  4511             case EUnreadItem:
       
  4512                 {
       
  4513                 FEED_LOG6(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4514                     EFileLoggingModeAppend, _L("%d\t%d\t%S\t%S\t%S\t%S"), 
       
  4515                     itemId, feedId, &KUnread(), &idStr->Des(), &title, &timestamp);
       
  4516                 }
       
  4517                 break;
       
  4518             case EReadItem:
       
  4519                 {            
       
  4520                 FEED_LOG6(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4521                     EFileLoggingModeAppend, _L("%d\t%d\t%S\t%S\t%S\t%S"), 
       
  4522                     itemId, feedId, &KRead(), &idStr->Des(), &title, &timestamp);
       
  4523                 }
       
  4524                 break;
       
  4525             case ENewItem:
       
  4526                 {            
       
  4527                 FEED_LOG6(_L("Feeds"), _L("Feeds_DB.log"), 
       
  4528                     EFileLoggingModeAppend, _L("%d\t%d\t%S\t%S\t%S\t%S"), 
       
  4529                     itemId, feedId, &KNew(), &idStr->Des(), &title, &timestamp);
       
  4530                 }
       
  4531                 break;
       
  4532             }
       
  4533 
       
  4534         CleanupStack::PopAndDestroy(/*idStr*/);
       
  4535         }
       
  4536                 
       
  4537     CleanupStack::PopAndDestroy(/*item Table*/);
       
  4538     }
       
  4539 #endif