engine/src/FeedEngine.cpp
changeset 60 4d230e702aa3
parent 32 26a3f2dfba08
child 65 bcd88ba95046
equal deleted inserted replaced
59:9569ea080d5a 60:4d230e702aa3
    24 #include "ShowEngine.h"
    24 #include "ShowEngine.h"
    25 #include <e32hashtab.h>
    25 #include <e32hashtab.h>
    26 #include "OpmlParser.h"
    26 #include "OpmlParser.h"
    27 #include "PodcastUtils.h"
    27 #include "PodcastUtils.h"
    28 #include <utf.h>
    28 #include <utf.h>
    29 
    29 #include "Podcatcher.pan"
    30 // Cleanup stack macro for SQLite3
    30 
    31 // TODO Move this to some common place.
    31 _LIT(KFeedParseStorePath, "feeds\\");
    32 static void Cleanup_sqlite3_finalize_wrapper(TAny* handle)
       
    33 	{
       
    34 	sqlite3_finalize(static_cast<sqlite3_stmt*>(handle));
       
    35 	}
       
    36 #define Cleanup_sqlite3_finalize_PushL(__handle) CleanupStack::PushL(TCleanupItem(&Cleanup_sqlite3_finalize_wrapper, __handle))
       
    37 
       
    38 
    32 
    39 CFeedEngine* CFeedEngine::NewL(CPodcastModel& aPodcastModel)
    33 CFeedEngine* CFeedEngine::NewL(CPodcastModel& aPodcastModel)
    40 	{
    34 	{
    41 	CFeedEngine* self = new (ELeave) CFeedEngine(aPodcastModel);
    35 	CFeedEngine* self = new (ELeave) CFeedEngine(aPodcastModel);
    42 	CleanupStack::PushL(self);
    36 	CleanupStack::PushL(self);
    50 	iParser = new (ELeave) CFeedParser(*this, iPodcastModel.FsSession());
    44 	iParser = new (ELeave) CFeedParser(*this, iPodcastModel.FsSession());
    51 	
    45 	
    52 	iFeedClient = CHttpClient::NewL(iPodcastModel, *this);
    46 	iFeedClient = CHttpClient::NewL(iPodcastModel, *this);
    53 	iFeedTimer.ConstructL();
    47 	iFeedTimer.ConstructL();
    54 	
    48 	
    55 	RunFeedTimer();
    49 	TInt err = KErrNone;
    56 	
    50 	TInt feedCount = 0;
    57     if (DBGetFeedCount() > 0) 
    51 	
       
    52 	TRAP(err, feedCount = DBGetFeedCountL());
       
    53     if (err == KErrNone && feedCount > 0)
    58     	{
    54     	{
    59 		DP("Loading feeds from DB");
    55 		DP("Loading feeds from DB");
    60 		DBLoadFeedsL();
    56 		TRAP(err, DBLoadFeedsL());
    61 		} 
    57     	}		
       
    58 
    62     
    59     
    63 	if (iPodcastModel.IsFirstStartup()) {
    60 	if (err != KErrNone || iPodcastModel.IsFirstStartup()) {
    64 		TFileName defaultFile = iPodcastModel.SettingsEngine().DefaultFeedsFileName();
    61 		TFileName defaultFile = iPodcastModel.SettingsEngine().DefaultFeedsFileName();
    65 		DP1("Loading default feeds from %S", &defaultFile);
    62 		DP1("Loading default feeds from %S", &defaultFile);
    66 		if (BaflUtils::FileExists(iPodcastModel.FsSession(), defaultFile)) {
    63 		if (BaflUtils::FileExists(iPodcastModel.FsSession(), defaultFile)) {
    67 			ImportFeedsL(defaultFile);
    64 			ImportFeedsL(defaultFile);
    68 		}
    65 		}
    69 	}
    66 	} 
       
    67 	
       
    68 	// clean out feeds temp directory
       
    69 	TFileName feedTempPath;
       
    70 	feedTempPath.Copy (iPodcastModel.SettingsEngine().PrivatePath ());
       
    71 	feedTempPath.Append(KFeedParseStorePath);
       
    72 	feedTempPath.Append(_L("*"));
       
    73 
       
    74 	BaflUtils::EnsurePathExistsL(iPodcastModel.FsSession(), feedTempPath);
       
    75 	BaflUtils::DeleteFile(iPodcastModel.FsSession(),feedTempPath);
    70     
    76     
    71     TFileName importFile = iPodcastModel.SettingsEngine().ImportFeedsFileName();
    77     TFileName importFile = iPodcastModel.SettingsEngine().ImportFeedsFileName();
    72     if (BaflUtils::FileExists(iPodcastModel.FsSession(), importFile)) {
    78     if (BaflUtils::FileExists(iPodcastModel.FsSession(), importFile)) {
    73     	DP("Importing feeds");
    79     	DP("Importing feeds");
    74     	ImportFeedsL(importFile);
    80     	TRAP_IGNORE(ImportFeedsL(importFile));
    75 		}
    81 		}
       
    82     
       
    83 	RunFeedTimer();
    76 	}
    84 	}
    77 
    85 
    78 CFeedEngine::CFeedEngine(CPodcastModel& aPodcastModel)
    86 CFeedEngine::CFeedEngine(CPodcastModel& aPodcastModel)
    79 		: iClientState(EIdle),
    87 		: iClientState(EIdle),
    80 		  iFeedTimer(this),
    88 		  iFeedTimer(this),
   146 		}
   154 		}
   147 
   155 
   148 	TInt cnt = iSortedFeeds.Count();
   156 	TInt cnt = iSortedFeeds.Count();
   149 	for (int i=0;i<cnt;i++)
   157 	for (int i=0;i<cnt;i++)
   150 		{
   158 		{
   151 		iFeedsUpdating.Append(iSortedFeeds[i]);
   159 		iFeedsUpdating.Append(iSortedFeeds[i]->Uid());
   152 		}
   160 		}
   153 
   161 
   154 	UpdateNextFeedL();
   162 	UpdateNextFeedL();
   155 	}
   163 	}
   156 
   164 
   166 
   174 
   167 void CFeedEngine::UpdateNextFeedL()
   175 void CFeedEngine::UpdateNextFeedL()
   168 	{
   176 	{
   169 	DP1("UpdateNextFeed. %d feeds left to update", iFeedsUpdating.Count());
   177 	DP1("UpdateNextFeed. %d feeds left to update", iFeedsUpdating.Count());
   170 	
   178 	
       
   179 	// reset active feed, will be set again in UpdateFeedL if needed
       
   180 	iActiveFeed = NULL;
       
   181 	
   171 	if (iFeedsUpdating.Count() > 0)
   182 	if (iFeedsUpdating.Count() > 0)
   172 		{
   183 		{
   173 		CFeedInfo *info = iFeedsUpdating[0];
   184 		CFeedInfo *info = GetFeedInfoByUid(iFeedsUpdating[0]);
   174 		iFeedsUpdating.Remove(0);
   185 		iFeedsUpdating.Remove(0);
   175 		TBool result = EFalse;
   186 		
   176 		//DP2("** UpdateNextFeed: %S, ID: %u", &(info->Url()), info->Uid());
   187 		if (info == NULL)
   177 		TRAPD(error, result = UpdateFeedL(info->Uid()));
   188 			{
   178 		
   189 			UpdateNextFeedL();
   179 		if (error != KErrNone || !result)
   190 			}
   180 			{
   191 		else
   181 			DP("Error while updating all feeds");
   192 			{
   182 			for (TInt i=0;i<iObservers.Count();i++) 
   193 			TBool result = EFalse;
       
   194 			//DP2("** UpdateNextFeed: %S, ID: %u", &(info->Url()), info->Uid());
       
   195 			TRAPD(error, result = UpdateFeedL(info->Uid()));
       
   196 			
       
   197 			if (error != KErrNone || !result)
   183 				{
   198 				{
   184 				TRAP_IGNORE(iObservers[i]->FeedUpdateAllCompleteL(iAutoUpdatedInitiator?MFeedEngineObserver::EFeedAutoUpdate:MFeedEngineObserver::EFeedManualUpdate));
   199 				DP("Error while updating all feeds");
       
   200 				for (TInt i=0;i<iObservers.Count();i++) 
       
   201 					{
       
   202 					TRAP_IGNORE(iObservers[i]->FeedUpdateAllCompleteL(iAutoUpdatedInitiator?MFeedEngineObserver::EFeedAutoUpdate:MFeedEngineObserver::EFeedManualUpdate));
       
   203 					}
   185 				}
   204 				}
   186 			}
   205 			}
   187 		}
   206 		}
   188 	else
   207 	else
   189 		{
   208 		{
   196 	}
   215 	}
   197 
   216 
   198 EXPORT_C TBool CFeedEngine::UpdateFeedL(TUint aFeedUid)
   217 EXPORT_C TBool CFeedEngine::UpdateFeedL(TUint aFeedUid)
   199 	{
   218 	{
   200 	DP("FeedEngine::UpdateFeedL BEGIN");
   219 	DP("FeedEngine::UpdateFeedL BEGIN");
       
   220 	
       
   221 	if (iActiveFeed)
       
   222 		{
       
   223 		User::Leave(KErrInUse);
       
   224 		}
       
   225 	
   201 	iActiveFeed = GetFeedInfoByUid(aFeedUid);
   226 	iActiveFeed = GetFeedInfoByUid(aFeedUid);
   202 	iCatchupCounter = 0;
   227 	
   203 	iCancelRequested = EFalse;
   228 	iCancelRequested = EFalse;
   204 
   229 
   205 	if (iActiveFeed->LastUpdated() == 0)
   230 	if (iActiveFeed->LastUpdated() == 0)
   206 		{
   231 		{
   207 		iCatchupMode = ETrue;
   232 		iCatchupMode = ETrue;
       
   233 		iCatchupCounter = 0;
   208 		}
   234 		}
   209 	
   235 	
   210 	iActiveFeed->SetLastError(KErrNone);
   236 	iActiveFeed->SetLastError(KErrNone);
   211 	DBUpdateFeed(*iActiveFeed);
   237 	DBUpdateFeedL(*iActiveFeed);
   212 	
   238 	
   213 	iUpdatingFeedFileName.Copy (iPodcastModel.SettingsEngine().PrivatePath ());
   239 	iUpdatingFeedFileName.Copy (iPodcastModel.SettingsEngine().PrivatePath ());
       
   240 	iUpdatingFeedFileName.Append(KFeedParseStorePath);
       
   241 	BaflUtils::EnsurePathExistsL(iPodcastModel.FsSession(), iUpdatingFeedFileName);
       
   242 	
   214 	_LIT(KFileNameFormat, "%lu.xml");
   243 	_LIT(KFileNameFormat, "%lu.xml");
   215 	iUpdatingFeedFileName.AppendFormat(KFileNameFormat, aFeedUid);
   244 	iUpdatingFeedFileName.AppendFormat(KFileNameFormat, aFeedUid);
   216 	
   245 	
       
   246 	iClientState = EUpdatingFeed;
       
   247 			
       
   248 	for (TInt i=0;i<iObservers.Count();i++)
       
   249 		{
       
   250 		TRAP_IGNORE(iObservers[i]->FeedDownloadStartedL(iAutoUpdatedInitiator?MFeedEngineObserver::EFeedAutoUpdate:MFeedEngineObserver::EFeedManualUpdate, iActiveFeed->Uid()));
       
   251 		}
       
   252 
   217 	if(iFeedClient->GetL(iActiveFeed->Url(), iUpdatingFeedFileName, iPodcastModel.SettingsEngine().SpecificIAP()))
   253 	if(iFeedClient->GetL(iActiveFeed->Url(), iUpdatingFeedFileName, iPodcastModel.SettingsEngine().SpecificIAP()))
   218 		{
   254 		{
   219 		iClientState = EUpdatingFeed;
   255 		
   220 		
       
   221 		for (TInt i=0;i<iObservers.Count();i++)
       
   222 			{
       
   223 			TRAP_IGNORE(iObservers[i]->FeedDownloadStartedL(iAutoUpdatedInitiator?MFeedEngineObserver::EFeedAutoUpdate:MFeedEngineObserver::EFeedManualUpdate, iActiveFeed->Uid()));
       
   224 			}
       
   225 
       
   226 		DP("FeedEngine::UpdateFeedL END, return ETrue");
   256 		DP("FeedEngine::UpdateFeedL END, return ETrue");
   227 		return ETrue;
   257 		return ETrue;
   228 		}
   258 		}
   229 	else
   259 	else
   230 		{
   260 		{
   248 		if (++iCatchupCounter > 1) {
   278 		if (++iCatchupCounter > 1) {
   249 			aItem.SetPlayState(EPlayed);
   279 			aItem.SetPlayState(EPlayed);
   250 		}
   280 		}
   251 	}
   281 	}
   252 	
   282 	
   253 	TBool isShowAdded = iPodcastModel.ShowEngine().AddShowL(aItem);
   283 	TRAPD(err, iPodcastModel.ShowEngine().AddShowL(aItem));
   254 
   284 
   255 	if (aItem.PlayState() == ENeverPlayed && isShowAdded && iPodcastModel.SettingsEngine().DownloadAutomatically()) 
   285 	if (err == KErrNone && aItem.PlayState() == ENeverPlayed && 
       
   286 			iPodcastModel.SettingsEngine().DownloadAutomatically()) 
   256 		{
   287 		{
   257 		iPodcastModel.ShowEngine().AddDownloadL(aItem);
   288 		iPodcastModel.ShowEngine().AddDownloadL(aItem);
   258 		}	
   289 		}	
   259 	}
   290 	}
   260 
   291 
   275 	relPath.Append(fileName);
   306 	relPath.Append(fileName);
   276 	PodcastUtils::EnsureProperPathName(relPath);
   307 	PodcastUtils::EnsureProperPathName(relPath);
   277 	
   308 	
   278 	// complete file path is base dir + rel path
   309 	// complete file path is base dir + rel path
   279 	filePath.Append(relPath);
   310 	filePath.Append(relPath);
   280 	aFeedInfo->SetImageFileNameL(filePath);
   311 	aFeedInfo->SetImageFileNameL(filePath, NULL);
   281 
   312 
   282 	if(iFeedClient->GetL(aFeedInfo->ImageUrl(), filePath, ETrue))
   313 	if(iFeedClient->GetL(aFeedInfo->ImageUrl(), filePath, ETrue))
   283 		{
   314 		{
   284 			iClientState = EUpdatingImage;
   315 			iClientState = EUpdatingImage;
   285 		}
   316 		}
   307 	// Save the feeds into DB
   338 	// Save the feeds into DB
   308 	DBAddFeedL(aItem);
   339 	DBAddFeedL(aItem);
   309 	return ETrue;
   340 	return ETrue;
   310 	}
   341 	}
   311 
   342 
   312 TBool CFeedEngine::DBAddFeedL(const CFeedInfo& aItem)
   343 void CFeedEngine::DBAddFeedL(const CFeedInfo& aItem)
   313 	{
   344 	{
   314 	DP2("CFeedEngine::DBAddFeed, title=%S, URL=%S", &aItem.Title(), &aItem.Url());
   345 	DP2("CFeedEngine::DBAddFeed, title=%S, URL=%S", &aItem.Title(), &aItem.Url());
   315 	
   346 	
   316 	CFeedInfo *info = DBGetFeedInfoByUidL(aItem.Uid());
   347 	CFeedInfo *info;
   317 	if (info) {
   348 	
   318 		DP("Feed already exists!");
   349 	TRAPD(err, info = DBGetFeedInfoByUidL(aItem.Uid()));
       
   350 	
       
   351 	if (err == KErrNone && info) {
   319 		delete info;
   352 		delete info;
   320 		return EFalse;
   353 		User::Leave(KErrAlreadyExists);
   321 	}
   354 	}
   322 
   355 
   323 	HBufC* titleBuf = HBufC::NewLC(KMaxLineLength);
   356 	HBufC* titleBuf = HBufC::NewLC(KMaxLineLength);
   324 	TPtr titlePtr(titleBuf->Des());
   357 	TPtr titlePtr(titleBuf->Des());
   325 	titlePtr.Copy(aItem.Title());
   358 	titlePtr.Copy(aItem.Title());
   339 	CleanupStack::PopAndDestroy(descBuf);
   372 	CleanupStack::PopAndDestroy(descBuf);
   340 	CleanupStack::PopAndDestroy(titleBuf);
   373 	CleanupStack::PopAndDestroy(titleBuf);
   341 	
   374 	
   342 	sqlite3_stmt *st;
   375 	sqlite3_stmt *st;
   343 	 
   376 	 
   344 	//DP1("SQL statement length=%d", iSqlBuffer.Length());
       
   345 	int rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st, (const void**) NULL);
   377 	int rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st, (const void**) NULL);
   346 	
   378 	
   347 	if (rc==SQLITE_OK)
   379 	if (rc==SQLITE_OK)
   348 		{
   380 		{
       
   381 		Cleanup_sqlite3_finalize_PushL(st);
   349 		rc = sqlite3_step(st);
   382 		rc = sqlite3_step(st);
   350 
   383 
   351 		if (rc == SQLITE_DONE)
   384 		if (rc != SQLITE_DONE)
   352 			{
   385 			{
   353 			sqlite3_finalize(st);
   386 			User::Leave(KErrCorrupt);
   354 			return ETrue;
   387 			}
   355 			}
   388 		CleanupStack::PopAndDestroy(); // st
   356 		else {
   389 		}
   357 			sqlite3_finalize(st);
   390 	else
   358 		}
   391 		{
   359 	}
   392 		User::Leave(KErrCorrupt);
   360 
   393 		}
   361 	return EFalse;
       
   362 	}
   394 	}
   363 
   395 
   364 EXPORT_C void CFeedEngine::RemoveFeedL(TUint aUid) 
   396 EXPORT_C void CFeedEngine::RemoveFeedL(TUint aUid) 
   365 	{
   397 	{
       
   398 	if (iActiveFeed && iActiveFeed->Uid() == aUid)
       
   399 		{
       
   400 		User::Leave(KErrInUse);
       
   401 		}
       
   402 	
   366 	for (int i=0;i<iSortedFeeds.Count();i++) 
   403 	for (int i=0;i<iSortedFeeds.Count();i++) 
   367 		{
   404 		{
   368 		if (iSortedFeeds[i]->Uid() == aUid) 
   405 		if (iSortedFeeds[i]->Uid() == aUid) 
   369 			{
   406 			{
   370 			iPodcastModel.ShowEngine().DeleteAllShowsByFeedL(aUid);
   407 			iPodcastModel.ShowEngine().DeleteAllShowsByFeedL(aUid);
   371 					
   408 
   372 			CFeedInfo* feedToRemove = iSortedFeeds[i];
   409 			CFeedInfo* feedToRemove = iSortedFeeds[i];
   373 			
   410 			
   374 			//delete the image file if it exists
   411 			//delete the image file if it exists
   375 			if ((feedToRemove->ImageFileName().Length() >0)
   412 			if ((feedToRemove->ImageFileName().Length() >0)
   376 					&& BaflUtils::FileExists(iPodcastModel.FsSession(), feedToRemove->ImageFileName()))
   413 					&& BaflUtils::FileExists(iPodcastModel.FsSession(), feedToRemove->ImageFileName()))
   389 			delete feedToRemove;
   426 			delete feedToRemove;
   390 			
   427 			
   391 			DP("Removed feed from array");
   428 			DP("Removed feed from array");
   392 			
   429 			
   393 			// now remove it from DB
   430 			// now remove it from DB
   394 			DBRemoveFeed(aUid);
   431 			DBRemoveFeedL(aUid);
   395 
       
   396 			return;
       
   397 		}
   432 		}
   398 	}
   433 	}
   399 }
   434 }
   400 
   435 
   401 
   436 
   402 TBool CFeedEngine::DBRemoveFeed(TUint aUid)
   437 void CFeedEngine::DBRemoveFeedL(TUint aUid)
   403 	{
   438 	{
   404 	DP("CFeedEngine::DBRemoveFeed");
   439 	DP("CFeedEngine::DBRemoveFeed");
   405 	_LIT(KSqlStatement, "delete from feeds where uid=%u");
   440 	_LIT(KSqlStatement, "delete from feeds where uid=%u");
   406 	iSqlBuffer.Format(KSqlStatement, aUid);
   441 	iSqlBuffer.Format(KSqlStatement, aUid);
   407 
   442 
   409 	 
   444 	 
   410 	int rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st,	(const void**) NULL);
   445 	int rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st,	(const void**) NULL);
   411 	
   446 	
   412 	if (rc==SQLITE_OK)
   447 	if (rc==SQLITE_OK)
   413 		{
   448 		{
       
   449 		Cleanup_sqlite3_finalize_PushL(st);
   414 		rc = sqlite3_step(st);
   450 		rc = sqlite3_step(st);
   415 		sqlite3_finalize(st);
   451 
   416 
   452 		if (rc != SQLITE_DONE)
   417 		if (rc == SQLITE_DONE)
   453 			{
   418 			{
   454 			User::Leave(KErrNotFound);
   419 			DP("Feed removed from DB");
   455 			}
   420 			return ETrue;
   456 		
   421 			}
   457 		CleanupStack::PopAndDestroy(); //st
   422 		else
   458 		}
   423 			{
   459 	else
   424 			DP("Error when removing feed from DB");
   460 		{
   425 			}
   461 		User::Leave(KErrCorrupt);
   426 		}
   462 		}
   427 	return EFalse;	
   463 	}
   428 	}
   464 
   429 
   465 void CFeedEngine::DBUpdateFeedL(const CFeedInfo &aItem)
   430 TBool CFeedEngine::DBUpdateFeed(const CFeedInfo &aItem)
       
   431 	{
   466 	{
   432 	DP2("CFeedEngine::DBUpdateFeed, title=%S, URL=%S", &aItem.Title(), &aItem.Url());
   467 	DP2("CFeedEngine::DBUpdateFeed, title=%S, URL=%S", &aItem.Title(), &aItem.Url());
   433 	
   468 	
   434 	HBufC* titleBuf = HBufC::NewLC(KMaxLineLength);
   469 	HBufC* titleBuf = HBufC::NewLC(KMaxLineLength);
   435 	TPtr titlePtr(titleBuf->Des());
   470 	TPtr titlePtr(titleBuf->Des());
   450 	CleanupStack::PopAndDestroy(descBuf);
   485 	CleanupStack::PopAndDestroy(descBuf);
   451 	CleanupStack::PopAndDestroy(titleBuf);
   486 	CleanupStack::PopAndDestroy(titleBuf);
   452 	
   487 	
   453 	sqlite3_stmt *st;
   488 	sqlite3_stmt *st;
   454 	 
   489 	 
   455 	//DP1("SQL statement length=%d", iSqlBuffer.Length());
       
   456 	int rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st, (const void**) NULL);
   490 	int rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st, (const void**) NULL);
   457 	
   491 	
   458 	if (rc==SQLITE_OK)
   492 	if (rc==SQLITE_OK)
   459 		{
   493 		{
       
   494 		Cleanup_sqlite3_finalize_PushL(st);
   460 		rc = sqlite3_step(st);
   495 		rc = sqlite3_step(st);
   461 		sqlite3_finalize(st);
   496 		
   462 		
   497 		if (rc != SQLITE_DONE)
   463 		if (rc == SQLITE_DONE)
   498 			{
   464 			{
   499 			User::Leave(KErrNotFound);
   465 			return ETrue;
   500 			}
   466 			}
   501 		CleanupStack::PopAndDestroy(); //st
   467 		}
   502 		}
   468 	else
   503 	else
   469 		{
   504 		{
   470 		DP1("SQLite rc=%d", rc);
   505 		User::Leave(KErrCorrupt);
   471 		}
   506 		}
   472 
       
   473 	return EFalse;
       
   474 	}
   507 	}
   475 
   508 
   476 void CFeedEngine::ParsingCompleteL(CFeedInfo *item)
   509 void CFeedEngine::ParsingCompleteL(CFeedInfo *item)
   477 	{
   510 	{
   478 	TBuf<KMaxLineLength> title;
   511 	TBuf<KMaxLineLength> title;
   508 	{
   541 	{
   509 	DP2("CFeedEngine::CompleteL BEGIN, iClientState=%d, aSuccessful=%d", iClientState, aError);
   542 	DP2("CFeedEngine::CompleteL BEGIN, iClientState=%d, aSuccessful=%d", iClientState, aError);
   510 
   543 
   511 	switch(iClientState)
   544 	switch(iClientState)
   512 		{		
   545 		{		
   513 		default:
       
   514 			if(iActiveFeed != NULL)
       
   515 				{
       
   516 				TTime time;
       
   517 				time.HomeTime();
       
   518 				iActiveFeed->SetLastUpdated(time);
       
   519 				iActiveFeed->SetLastError(aError);
       
   520 				NotifyFeedUpdateComplete(aError);
       
   521 				}
       
   522 			break;
       
   523 		case EUpdatingFeed: 
   546 		case EUpdatingFeed: 
   524 		{
   547 		{
   525 		// Parse the feed. We need to trap this call since it could leave and then
       
   526 		// the whole update chain will be broken
       
   527 		// change client state
       
   528 		iClientState = EIdle;
   548 		iClientState = EIdle;
   529 		switch (aError)
   549 		switch (aError)
   530 			{
   550 			{
   531 			case KErrCancel:						
   551 			case KErrCancel:						
   532 				{
   552 				{
   543 					TTime time;
   563 					TTime time;
   544 					time.HomeTime();
   564 					time.HomeTime();
   545 					iActiveFeed->SetLastUpdated(time);
   565 					iActiveFeed->SetLastUpdated(time);
   546 	
   566 	
   547 					if( aError == KErrNone)
   567 					if( aError == KErrNone)
   548 						{			
   568 						{
       
   569 						// Parse the feed. We need to trap this call since it could leave and then
       
   570 						// the whole update chain will be broken
       
   571 						// change client state
   549 						TRAPD(parserErr, iParser->ParseFeedL(iUpdatingFeedFileName, iActiveFeed, iPodcastModel.SettingsEngine().MaxListItems()));
   572 						TRAPD(parserErr, iParser->ParseFeedL(iUpdatingFeedFileName, iActiveFeed, iPodcastModel.SettingsEngine().MaxListItems()));
   550 	
   573 	
   551 						if(parserErr)
   574 						if(parserErr)
   552 							{
   575 							{
   553 							// we do not need to any special action on this error.
   576 							// we do not need to any special action on this error.
   554 							iActiveFeed->SetLastError(parserErr);
   577 							iActiveFeed->SetLastError(parserErr);
   555 							DP1("CFeedEngine::Complete()\t Failed to parse feed. Leave with error code=%d", parserErr);
   578 							DP1("CFeedEngine::Complete()\t Failed to parse feed. Leave with error code=%d", parserErr);
   556 							}
   579 							}
   557 						else
   580 						else
   558 							{
   581 							{
   559 							iPodcastModel.ShowEngine().DeleteOldShowsByFeed(iActiveFeed->Uid());
   582 							iPodcastModel.ShowEngine().DeleteOldShowsByFeedL(iActiveFeed->Uid());
   560 							}
   583 							}
   561 	
   584 	
   562 						// delete the downloaded XML file as it is no longer needed
   585 						// delete the downloaded XML file as it is no longer needed
   563 						BaflUtils::DeleteFile(iPodcastModel.FsSession(),iUpdatingFeedFileName);			
   586 						BaflUtils::DeleteFile(iPodcastModel.FsSession(),iUpdatingFeedFileName);			
   564 	
   587 	
   580 									iClientState = EIdle;							
   603 									iClientState = EIdle;							
   581 									}
   604 									}
   582 								}	
   605 								}	
   583 							}
   606 							}
   584 						}
   607 						}
       
   608 					else
       
   609 						{
       
   610 						// even if it fails, this will allow us to move on
       
   611 						iClientState = EIdle;
       
   612 						}
   585 					}
   613 					}
   586 				iCancelRequested = EFalse;
   614 				iCancelRequested = EFalse;
   587 				}break;
   615 				}break;
   588 			}
   616 			}
   589 		
   617 			DBUpdateFeedL(*iActiveFeed);
   590 			NotifyFeedUpdateComplete(aError);
   618 			NotifyFeedUpdateComplete(iActiveFeed->Uid(), aError);
   591 	
   619 
   592 			// we will wait until the image has been downloaded to start the next feed update.
   620 			// we will wait until the image has been downloaded to start the next feed update.
   593 			if (iClientState == EIdle)
   621 			if (iClientState == EIdle)
   594 				{
   622 				{
   595 				UpdateNextFeedL();	
   623 				UpdateNextFeedL();	
   596 				}
   624 				}
   597 			}break;
   625 			}break;
   598 		case EUpdatingImage:
   626 		case EUpdatingImage:
   599 			{
   627 			{
   600 			// change client state to not updating
   628 			// change client state to not updating
   601 			iClientState = EIdle;
   629 			iClientState = EIdle;
   602 	
   630 			if(aError == KErrNone)
   603 			NotifyFeedUpdateComplete(aError);
   631 				{
       
   632 				// now the image has been downloaded, so we set it again in the FeedInfo to start
       
   633 				// converting it
       
   634 				HBufC *fileNameCopy = iActiveFeed->ImageFileName().AllocLC();
       
   635 				TRAP_IGNORE(iActiveFeed->SetImageFileNameL(*fileNameCopy, &iPodcastModel));
       
   636 				CleanupStack::PopAndDestroy(fileNameCopy);
       
   637 				}
       
   638 			DBUpdateFeedL(*iActiveFeed);
       
   639 			NotifyFeedUpdateComplete(iActiveFeed->Uid(), aError);
   604 			UpdateNextFeedL();
   640 			UpdateNextFeedL();
   605 			}break;
   641 			}break;
   606 		case ESearching: 
   642 		case ESearching: 
   607 			{
   643 			{
   608 			iClientState = EIdle;
   644 			iClientState = EIdle;
   618 				DP("Parsing OPML");
   654 				DP("Parsing OPML");
   619 				iOpmlParser->ParseOpmlL(iSearchResultsFileName, ETrue);
   655 				iOpmlParser->ParseOpmlL(iSearchResultsFileName, ETrue);
   620 				}
   656 				}
   621 			else
   657 			else
   622 				{
   658 				{
   623 				NotifyOpmlParsingComplete(aError, 0);
   659 				NotifyOpmlParsingCompleteL(aError, 0);
   624 				}
   660 				}
   625 			
   661 			
   626 			BaflUtils::DeleteFile(iPodcastModel.FsSession(), iSearchResultsFileName);
   662 			BaflUtils::DeleteFile(iPodcastModel.FsSession(), iSearchResultsFileName);
   627 			}break;
   663 			}break;
       
   664 		case EIdle:
       
   665 			UpdateNextFeedL();	
       
   666 			break;
       
   667 		default:
       
   668 			Panic(EPodcatcherPanicFeedEngineState);
       
   669 			break;
   628 		}
   670 		}
   629 	DP("CFeedEngine::CompleteL END");
   671 	DP("CFeedEngine::CompleteL END");
   630 	}
   672 	}
   631 
   673 
   632 void CFeedEngine::NotifyFeedUpdateComplete(TInt aError)
   674 void CFeedEngine::NotifyFeedUpdateComplete(TInt aFeedUid, TInt aError)
   633 	{
   675 	{
   634 	DP("CFeedEngine::NotifyFeedUpdateComplete");
   676 	DP("CFeedEngine::NotifyFeedUpdateComplete");	
   635 	DBUpdateFeed(*iActiveFeed);
       
   636 	for (TInt i=0;i<iObservers.Count();i++) 
   677 	for (TInt i=0;i<iObservers.Count();i++) 
   637 		{
   678 		{
   638 		TRAP_IGNORE(iObservers[i]->FeedDownloadFinishedL(iAutoUpdatedInitiator?MFeedEngineObserver::EFeedAutoUpdate:MFeedEngineObserver::EFeedManualUpdate, iActiveFeed->Uid(), aError));
   679 		TRAP_IGNORE(iObservers[i]->FeedDownloadFinishedL(MFeedEngineObserver::EFeedAutoUpdate, aFeedUid, aError));
   639 		}
   680 		}
   640 	}
   681 	}
   641 
   682 
   642 void CFeedEngine::Disconnected(CHttpClient* /*aClient*/)
   683 void CFeedEngine::Disconnected(CHttpClient* /*aClient*/)
   643 	{
   684 	{
   770 	{
   811 	{
   771 		//DP2("Comparing %S to %S", &a.Title(), &b.Title());
   812 		//DP2("Comparing %S to %S", &a.Title(), &b.Title());
   772 		return a.Title().CompareF(b.Title());
   813 		return a.Title().CompareF(b.Title());
   773 	}
   814 	}
   774 
   815 
   775 EXPORT_C void CFeedEngine::GetDownloadedStats(TUint &aNumShows, TUint &aNumUnplayed)
   816 EXPORT_C void CFeedEngine::GetStatsByFeedL(TUint aFeedUid, TUint &aNumShows, TUint &aNumUnplayed)
   776 	{
   817 	{
   777 	DP("CFeedEngine::GetDownloadedStats");
   818 	//DP1("CFeedEngine::GetStatsByFeed, aFeedUid=%u", aFeedUid);
   778 	_LIT(KSqlStatement, "select count(*) from shows where downloadstate=%u");
   819 	DBGetStatsByFeedL(aFeedUid, aNumShows, aNumUnplayed);
   779 	iSqlBuffer.Format(KSqlStatement, EDownloaded);
   820 	}
       
   821 
       
   822 void CFeedEngine::DBGetStatsByFeedL(TUint aFeedUid, TUint &aNumShows, TUint &aNumUnplayed)
       
   823 	{
       
   824 	//DP1("CFeedEngine::DBGetStatsByFeed, feedUid=%u", aFeedUid);
       
   825 	_LIT(KSqlStatement, "select count(*) from shows where feeduid=%u");
       
   826 	iSqlBuffer.Format(KSqlStatement, aFeedUid);
   780 
   827 
   781 	sqlite3_stmt *st;
   828 	sqlite3_stmt *st;
   782 	 
   829 	 
   783 	int rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st,	(const void**) NULL);
   830 	int rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st,	(const void**) NULL);
   784 	
   831 	
   785 	if( rc==SQLITE_OK ){
   832 	if( rc==SQLITE_OK)
       
   833 		{
       
   834 		Cleanup_sqlite3_finalize_PushL(st);
   786 	  	rc = sqlite3_step(st);
   835 	  	rc = sqlite3_step(st);
   787 	  	
   836 	  	
   788 	  	if (rc == SQLITE_ROW) {
   837 	  	if (rc == SQLITE_ROW)
       
   838 	  		{
   789 	  		aNumShows = sqlite3_column_int(st, 0);
   839 	  		aNumShows = sqlite3_column_int(st, 0);
   790 	  	}
   840 	  		}
   791 	}
   841 	  	else
       
   842 	  		{
       
   843 			User::Leave(KErrNotFound);
       
   844 	  		}
       
   845 	  	CleanupStack::PopAndDestroy(); // st
       
   846 		}
       
   847 	else
       
   848 		{
       
   849 		User::Leave(KErrCorrupt);
       
   850 		}
   792 		  
   851 		  
   793 	sqlite3_finalize(st);
   852 	_LIT(KSqlStatement2, "select count(*) from shows where feeduid=%u and playstate=0");
   794 
   853 	iSqlBuffer.Format(KSqlStatement2, aFeedUid);
   795 	_LIT(KSqlStatement2, "select count(*) from shows where downloadstate=%u and playstate=%u");
       
   796 	iSqlBuffer.Format(KSqlStatement2, EDownloaded, ENeverPlayed);
       
   797 
   854 
   798 	rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st,	(const void**) NULL);
   855 	rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st,	(const void**) NULL);
   799 		
   856 		
   800 	if( rc==SQLITE_OK ){
   857 	if(rc==SQLITE_OK)
       
   858 		{
       
   859 		Cleanup_sqlite3_finalize_PushL(st);
   801 	  	rc = sqlite3_step(st);
   860 	  	rc = sqlite3_step(st);
   802 	  	
   861 	  	
   803 	  	if (rc == SQLITE_ROW) {
   862 	  	if (rc == SQLITE_ROW)
       
   863 	  		{
   804 	  		aNumUnplayed = sqlite3_column_int(st, 0);
   864 	  		aNumUnplayed = sqlite3_column_int(st, 0);
   805 	  	}
   865 	  		}
   806 	}
   866 	  	else
   807 		  
   867 	  		{
   808 	sqlite3_finalize(st);
   868 			User::Leave(KErrNotFound);
   809 	}
   869 	  		}
   810 
   870 	  	CleanupStack::PopAndDestroy(); // st
   811 EXPORT_C void CFeedEngine::GetStatsByFeed(TUint aFeedUid, TUint &aNumShows, TUint &aNumUnplayed)
   871 	}
   812 	{
   872 }
   813 	//DP1("CFeedEngine::GetStatsByFeed, aFeedUid=%u", aFeedUid);
   873 
   814 	DBGetStatsByFeed(aFeedUid, aNumShows, aNumUnplayed);
   874 TUint CFeedEngine::DBGetFeedCountL()
   815 	}
   875 	{
   816 
   876 	DP("DBGetFeedCount BEGIN");
   817 void CFeedEngine::DBGetStatsByFeed(TUint aFeedUid, TUint &aNumShows, TUint &aNumUnplayed)
       
   818 	{
       
   819 	//DP1("CFeedEngine::DBGetStatsByFeed, feedUid=%u", aFeedUid);
       
   820 	_LIT(KSqlStatement, "select count(*) from shows where feeduid=%u");
       
   821 	iSqlBuffer.Format(KSqlStatement, aFeedUid);
       
   822 
       
   823 	sqlite3_stmt *st;
   877 	sqlite3_stmt *st;
       
   878 	int rc = sqlite3_prepare_v2(&iDB,"select count(*) from feeds" , -1, &st, (const char**) NULL);
       
   879 	TUint size = 0;
   824 	 
   880 	 
   825 	int rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st,	(const void**) NULL);
   881 	if( rc==SQLITE_OK )
   826 	
   882 		{
   827 	if( rc==SQLITE_OK ){
   883 		Cleanup_sqlite3_finalize_PushL(st);
   828 	  	rc = sqlite3_step(st);
   884 		rc = sqlite3_step(st);
   829 	  	
   885 			
   830 	  	if (rc == SQLITE_ROW) {
   886 		if (rc == SQLITE_ROW)
   831 	  		aNumShows = sqlite3_column_int(st, 0);
   887 			{
   832 	  	}
       
   833 	}
       
   834 		  
       
   835 	sqlite3_finalize(st);
       
   836 
       
   837 	_LIT(KSqlStatement2, "select count(*) from shows where feeduid=%u and playstate=0");
       
   838 	iSqlBuffer.Format(KSqlStatement2, aFeedUid);
       
   839 
       
   840 	rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st,	(const void**) NULL);
       
   841 		
       
   842 	if( rc==SQLITE_OK ){
       
   843 	  	rc = sqlite3_step(st);
       
   844 	  	
       
   845 	  	if (rc == SQLITE_ROW) {
       
   846 	  		aNumUnplayed = sqlite3_column_int(st, 0);
       
   847 	  	}
       
   848 	}
       
   849 		  
       
   850 	sqlite3_finalize(st);
       
   851 }
       
   852 
       
   853 TUint CFeedEngine::DBGetFeedCount()
       
   854 	{
       
   855 	 DP("DBGetFeedCount BEGIN");
       
   856 	 sqlite3_stmt *st;
       
   857 	 int rc = sqlite3_prepare_v2(&iDB,"select count(*) from feeds" , -1, &st, (const char**) NULL);
       
   858 	 TUint size = 0;
       
   859 	 
       
   860 	 if( rc==SQLITE_OK ){
       
   861 	  	rc = sqlite3_step(st);
       
   862 	  	
       
   863 	  	if (rc == SQLITE_ROW) {
       
   864 	  		size = sqlite3_column_int(st, 0);
   888 	  		size = sqlite3_column_int(st, 0);
   865 	  	}
   889 	  		}
   866 	  }
   890 		else
   867 	  
   891 			{
   868 	  sqlite3_finalize(st);
   892 	  		User::Leave(KErrCorrupt);
   869 	  DP1("DBGetFeedCount END=%d", size);
   893 	  		}
   870 	  return size;
   894 		CleanupStack::PopAndDestroy(); // st
       
   895 		}
       
   896 	else
       
   897 		{
       
   898 		User::Leave(KErrCorrupt);
       
   899 		}
       
   900 
       
   901 	DP1("DBGetFeedCount END=%d", size);
       
   902 	return size;
   871 }
   903 }
   872 
   904 
   873 void CFeedEngine::DBLoadFeedsL()
   905 void CFeedEngine::DBLoadFeedsL()
   874 	{
   906 	{
   875 	DP("DBLoadFeeds BEGIN");
   907 	DP("DBLoadFeeds BEGIN");
   876 	iSortedFeeds.Reset();
   908 	iSortedFeeds.Reset();
   877 	CFeedInfo *feedInfo = NULL;
   909 	CFeedInfo *feedInfo = NULL;
   878 	
   910 	
   879 	_LIT(KSqlStatement, "select url, title, description, imageurl, imagefile, link, built, lastupdated, uid, feedtype, customtitle from feeds");
   911 	_LIT(KSqlStatement, "select url, title, description, imageurl, imagefile, link, built, lastupdated, uid, feedtype, customtitle, lasterror from feeds");
   880 	iSqlBuffer.Format(KSqlStatement);
   912 	iSqlBuffer.Format(KSqlStatement);
   881 
   913 
   882 	sqlite3_stmt *st;
   914 	sqlite3_stmt *st;
   883 	 
   915 	 
   884 	TLinearOrder<CFeedInfo> sortOrder( CFeedEngine::CompareFeedsByTitle);
   916 	TLinearOrder<CFeedInfo> sortOrder( CFeedEngine::CompareFeedsByTitle);
   885 
   917 
   886 	int rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st,	(const void**) NULL);
   918 	int rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st,	(const void**) NULL);
   887 	Cleanup_sqlite3_finalize_PushL(st);
   919 	
   888 	
   920 	if (rc==SQLITE_OK)
   889 	if (rc==SQLITE_OK) {
   921 		{
       
   922 		Cleanup_sqlite3_finalize_PushL(st);
   890 		rc = sqlite3_step(st);
   923 		rc = sqlite3_step(st);
   891 		while(rc == SQLITE_ROW) {
   924 		while(rc == SQLITE_ROW) 
       
   925 			{
   892 			feedInfo = CFeedInfo::NewLC();
   926 			feedInfo = CFeedInfo::NewLC();
   893 			
   927 			
   894 			const void *urlz = sqlite3_column_text16(st, 0);
   928 			const void *urlz = sqlite3_column_text16(st, 0);
   895 			TPtrC16 url((const TUint16*)urlz);
   929 			TPtrC16 url((const TUint16*)urlz);
   896 			feedInfo->SetUrlL(url);
   930 			feedInfo->SetUrlL(url);
   907 			TPtrC16 image((const TUint16*)imagez);
   941 			TPtrC16 image((const TUint16*)imagez);
   908 			feedInfo->SetImageUrlL(image);
   942 			feedInfo->SetImageUrlL(image);
   909 
   943 
   910 			const void *imagefilez = sqlite3_column_text16(st, 4);
   944 			const void *imagefilez = sqlite3_column_text16(st, 4);
   911 			TPtrC16 imagefile((const TUint16*)imagefilez);
   945 			TPtrC16 imagefile((const TUint16*)imagefilez);
   912 			feedInfo->SetImageFileNameL(imagefile);
   946 			if (imagefile.Length() > 0)
   913 						
   947 				{
       
   948 				feedInfo->SetImageFileNameL(imagefile, &iPodcastModel);
       
   949 				}
       
   950 			
   914 			const void *linkz = sqlite3_column_text16(st, 5);
   951 			const void *linkz = sqlite3_column_text16(st, 5);
   915 			TPtrC16 link((const TUint16*)linkz);
   952 			TPtrC16 link((const TUint16*)linkz);
   916 			feedInfo->SetDescriptionL(link);
   953 			feedInfo->SetDescriptionL(link);
   917 					
   954 					
   918 			sqlite3_int64 built = sqlite3_column_int64(st, 6);
   955 			sqlite3_int64 built = sqlite3_column_int64(st, 6);
   922 			sqlite3_int64 lastupdated = sqlite3_column_int64(st, 7);
   959 			sqlite3_int64 lastupdated = sqlite3_column_int64(st, 7);
   923 			TTime lastupdatedtime(lastupdated);
   960 			TTime lastupdatedtime(lastupdated);
   924 			feedInfo->SetLastUpdated(lastupdatedtime);
   961 			feedInfo->SetLastUpdated(lastupdatedtime);
   925 			
   962 			
   926 			sqlite3_int64 customtitle = sqlite3_column_int64(st, 10);
   963 			sqlite3_int64 customtitle = sqlite3_column_int64(st, 10);
   927 			if (customtitle) {
   964 			if (customtitle)
       
   965 				{
   928 				feedInfo->SetCustomTitle();
   966 				feedInfo->SetCustomTitle();
   929 			}
   967 				}
   930 			
   968 			
   931 			TInt lasterror = sqlite3_column_int(st, 11);
   969 			sqlite3_int64 lasterror = sqlite3_column_int(st, 11);
   932 			feedInfo->SetLastError(lasterror);
   970 			feedInfo->SetLastError(lasterror);
   933 			
   971 			
   934 			TLinearOrder<CFeedInfo> sortOrder( CFeedEngine::CompareFeedsByTitle);
   972 			TLinearOrder<CFeedInfo> sortOrder( CFeedEngine::CompareFeedsByTitle);
   935 
   973 
   936 			iSortedFeeds.InsertInOrder(feedInfo, sortOrder);
   974 			iSortedFeeds.InsertInOrder(feedInfo, sortOrder);
   937 			
   975 			
   938 			CleanupStack::Pop(feedInfo);
   976 			CleanupStack::Pop(feedInfo);
   939 				
   977 				
   940 			rc = sqlite3_step(st);
   978 			rc = sqlite3_step(st);
   941 		}
   979 			}	
   942 	}
   980 		CleanupStack::PopAndDestroy();//st
   943 
   981 		}
   944 	CleanupStack::PopAndDestroy();//st
   982 	else
       
   983 		{
       
   984 		User::Leave(KErrCorrupt);
       
   985 		}
   945 
   986 
   946 	DP("DBLoadFeeds END");
   987 	DP("DBLoadFeeds END");
   947 	}
   988 	}
   948 
   989 
   949 CFeedInfo* CFeedEngine::DBGetFeedInfoByUidL(TUint aFeedUid)
   990 CFeedInfo* CFeedEngine::DBGetFeedInfoByUidL(TUint aFeedUid)
   952 	CFeedInfo *feedInfo = NULL;
   993 	CFeedInfo *feedInfo = NULL;
   953 	_LIT(KSqlStatement, "select url, title, description, imageurl, imagefile, link, built, lastupdated, uid, feedtype, customtitle, lasterror from feeds where uid=%u");
   994 	_LIT(KSqlStatement, "select url, title, description, imageurl, imagefile, link, built, lastupdated, uid, feedtype, customtitle, lasterror from feeds where uid=%u");
   954 	iSqlBuffer.Format(KSqlStatement, aFeedUid);
   995 	iSqlBuffer.Format(KSqlStatement, aFeedUid);
   955 
   996 
   956 	sqlite3_stmt *st;
   997 	sqlite3_stmt *st;
   957 	 
   998 	
   958 	//DP1("SQL statement length=%d", iSqlBuffer.Length());
       
   959 
       
   960 	int rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st,	(const void**) NULL);
   999 	int rc = sqlite3_prepare16_v2(&iDB, (const void*)iSqlBuffer.PtrZ() , -1, &st,	(const void**) NULL);
   961 	
  1000 	
   962 	if (rc==SQLITE_OK) {
  1001 	if (rc==SQLITE_OK)
       
  1002 		{
   963 		Cleanup_sqlite3_finalize_PushL(st);
  1003 		Cleanup_sqlite3_finalize_PushL(st);
   964 		rc = sqlite3_step(st);
  1004 		rc = sqlite3_step(st);
   965 		if (rc == SQLITE_ROW) {
  1005 		if (rc == SQLITE_ROW)
       
  1006 			{
   966 			feedInfo = CFeedInfo::NewLC();
  1007 			feedInfo = CFeedInfo::NewLC();
   967 			
  1008 			
   968 			const void *urlz = sqlite3_column_text16(st, 0);
  1009 			const void *urlz = sqlite3_column_text16(st, 0);
   969 			TPtrC16 url((const TUint16*)urlz);
  1010 			TPtrC16 url((const TUint16*)urlz);
   970 			feedInfo->SetUrlL(url);
  1011 			feedInfo->SetUrlL(url);
  1004 			
  1045 			
  1005 			TInt lasterror = sqlite3_column_int(st, 11);
  1046 			TInt lasterror = sqlite3_column_int(st, 11);
  1006 			feedInfo->SetLastError(lasterror);
  1047 			feedInfo->SetLastError(lasterror);
  1007 						
  1048 						
  1008 			CleanupStack::Pop(feedInfo);
  1049 			CleanupStack::Pop(feedInfo);
  1009 		}
  1050 			}
       
  1051 		else
       
  1052 			{
       
  1053 			User::Leave(KErrNotFound);
       
  1054 			}
  1010 		CleanupStack::PopAndDestroy();//st	
  1055 		CleanupStack::PopAndDestroy();//st	
  1011 	}
  1056 		}
       
  1057 	else
       
  1058 		{
       
  1059 		User::Leave(KErrNotFound);
       
  1060 		}
  1012 	
  1061 	
  1013 	return feedInfo;
  1062 	return feedInfo;
  1014 }
  1063 }
  1015 
  1064 
  1016 EXPORT_C void CFeedEngine::UpdateFeed(CFeedInfo *aItem)
  1065 EXPORT_C void CFeedEngine::UpdateFeedInfoL(CFeedInfo *aItem)
  1017 	{
  1066 	{
  1018 	DBUpdateFeed(*aItem);
  1067 	if (iActiveFeed && iActiveFeed->Uid() == aItem->Uid())
       
  1068 		{
       
  1069 		User::Leave(KErrInUse);
       
  1070 		}
       
  1071 	
       
  1072 	DBUpdateFeedL(*aItem);
  1019 	}
  1073 	}
  1020 
  1074 
  1021 EXPORT_C void CFeedEngine::SearchForFeedL(TDesC& aSearchString)
  1075 EXPORT_C void CFeedEngine::SearchForFeedL(TDesC& aSearchString)
  1022 	{
  1076 	{
  1023 	DP1("FeedEngine::SearchForFeedL BEGIN, aSearchString=%S", &aSearchString);
  1077 	DP1("FeedEngine::SearchForFeedL BEGIN, aSearchString=%S", &aSearchString);
  1069 	{
  1123 	{
  1070 	return iSearchResults;
  1124 	return iSearchResults;
  1071 	}
  1125 	}
  1072 
  1126 
  1073 
  1127 
  1074 EXPORT_C void CFeedEngine::OpmlParsingComplete(TInt aError, TUint aNumFeedsAdded)
  1128 EXPORT_C void CFeedEngine::OpmlParsingCompleteL(TInt aError, TUint aNumFeedsAdded)
  1075 	{
  1129 	{
  1076 	NotifyOpmlParsingComplete(aError, aNumFeedsAdded);
  1130 	NotifyOpmlParsingCompleteL(aError, aNumFeedsAdded);
  1077 	}
  1131 	}
  1078 
  1132 
  1079 void CFeedEngine::NotifyOpmlParsingComplete(TInt aError, TUint aNumFeedsAdded)
  1133 void CFeedEngine::NotifyOpmlParsingCompleteL(TInt aError, TUint aNumFeedsAdded)
  1080 	{
  1134 	{
  1081 	for (TInt i=0;i<iObservers.Count();i++) 
  1135 	for (TInt i=0;i<iObservers.Count();i++) 
  1082 		{
  1136 		{
  1083 		iObservers[i]->OpmlParsingComplete(aError, aNumFeedsAdded);
  1137 		iObservers[i]->OpmlParsingComplete(aError, aNumFeedsAdded);
  1084 		}
  1138 		}