diff options
author | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-27 03:27:46 +0000 |
---|---|---|
committer | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-27 03:27:46 +0000 |
commit | 90ef1313cb672e7da91312c4f7d3cdee41c7a767 (patch) | |
tree | b42df35c8c71ca921bf7900beb537a1773debacf /chrome/browser/history/history_backend.cc | |
parent | 7459794d5e6251014e322a4042d68c4f3f19a5f3 (diff) | |
download | chromium_src-90ef1313cb672e7da91312c4f7d3cdee41c7a767.zip chromium_src-90ef1313cb672e7da91312c4f7d3cdee41c7a767.tar.gz chromium_src-90ef1313cb672e7da91312c4f7d3cdee41c7a767.tar.bz2 |
Makes deleting history no longer delete starred urls. Thiseffectively reenables the code in ExpireHistoryBackend. I also madethe code consistent so that when we delete visits as the result ofhistory deletion we don't change the typed/visit count of theunderlying url.BUG=1214201 1256202TEST=none
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1423 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/history/history_backend.cc')
-rw-r--r-- | chrome/browser/history/history_backend.cc | 278 |
1 files changed, 147 insertions, 131 deletions
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc index 7682f6074..21f77fb 100644 --- a/chrome/browser/history/history_backend.cc +++ b/chrome/browser/history/history_backend.cc @@ -13,6 +13,7 @@ #include "base/string_util.h" #include "base/time.h" #include "chrome/browser/autocomplete/history_url_provider.h" +#include "chrome/browser/bookmarks/bookmark_service.h" #include "chrome/browser/history/download_types.h" #include "chrome/browser/history/in_memory_history_backend.h" #include "chrome/browser/history/page_usage_data.h" @@ -25,8 +26,7 @@ /* The HistoryBackend consists of a number of components: HistoryDatabase (stores past 3 months of history) - StarredURLDatabase (stores starred pages) - URLDatabase (stores a list of URLs) + URLDatabase (stores a list of URLs) DownloadDatabase (stores a list of downloads) VisitDatabase (stores a list of visits for the URLs) VisitSegmentDatabase (stores groups of URLs for the most visited view). @@ -36,8 +36,7 @@ DownloadDatabase (stores a list of downloads) VisitDatabase (stores a list of visits for the URLs) - (this does not store starred things or visit segments, all starred info - is stored in HistoryDatabase, and visit segments expire after 3 mos.) + (this does not store visit segments as they expire after 3 mos.) TextDatabaseManager (manages multiple text database for different times) TextDatabase (represents a single month of full-text index). @@ -187,15 +186,17 @@ class HistoryBackend::URLQuerier { // HistoryBackend -------------------------------------------------------------- HistoryBackend::HistoryBackend(const std::wstring& history_dir, - Delegate* delegate) + Delegate* delegate, + BookmarkService* bookmark_service) : delegate_(delegate), history_dir_(history_dir), #pragma warning(suppress: 4355) // OK to pass "this" here. - expirer_(this), + expirer_(this, bookmark_service), backend_destroy_message_loop_(NULL), recent_redirects_(kMaxRedirectCount), backend_destroy_task_(NULL), - segment_queried_(false) { + segment_queried_(false), + bookmark_service_(bookmark_service) { } HistoryBackend::~HistoryBackend() { @@ -229,103 +230,8 @@ HistoryBackend::~HistoryBackend() { } void HistoryBackend::Init() { - DCHECK(!db_.get()) << "Initializing HistoryBackend twice"; - // In the rare case where the db fails to initialize a dialog may get shown - // the blocks the caller, yet allows other messages through. For this reason - // we only set db_ to the created database if creation is successful. That - // way other methods won't do anything as db_ is still NULL. - - TimeTicks beginning_time = TimeTicks::Now(); - - // Compute the file names. Note that the index file can be removed when the - // text db manager is finished being hooked up. - std::wstring history_name = history_dir_; - file_util::AppendToPath(&history_name, chrome::kHistoryFilename); - std::wstring thumbnail_name = GetThumbnailFileName(); - std::wstring archived_name = GetArchivedFileName(); - std::wstring tmp_bookmarks_file = history_dir_; - file_util::AppendToPath(&tmp_bookmarks_file, - chrome::kHistoryBookmarksFileName); - - // History database. - db_.reset(new HistoryDatabase()); - switch (db_->Init(history_name, tmp_bookmarks_file)) { - case INIT_OK: - break; - case INIT_FAILURE: - // A NULL db_ will cause all calls on this object to notice this error - // and to not continue. - LOG(WARNING) << "Unable to initialize history DB."; - db_.reset(); - return; - case INIT_TOO_NEW: - delegate_->NotifyTooNew(); - db_.reset(); - return; - default: - NOTREACHED(); - } - - // Fill the in-memory database and send it back to the history service on the - // main thread. - InMemoryHistoryBackend* mem_backend = new InMemoryHistoryBackend; - if (mem_backend->Init(history_name)) - delegate_->SetInMemoryBackend(mem_backend); // Takes ownership of pointer. - else - delete mem_backend; // Error case, run without the in-memory DB. - db_->BeginExclusiveMode(); // Must be after the mem backend read the data. - - // Full-text database. This has to be first so we can pass it to the - // HistoryDatabase for migration. - text_database_.reset(new TextDatabaseManager(history_dir_, db_.get())); - if (!text_database_->Init()) { - LOG(WARNING) << "Text database initialization failed, running without it."; - text_database_.reset(); - } - - // Thumbnail database. - thumbnail_db_.reset(new ThumbnailDatabase()); - if (thumbnail_db_->Init(thumbnail_name) != INIT_OK) { - // Unlike the main database, we don't error out when the database is too - // new because this error is much less severe. Generally, this shouldn't - // happen since the thumbnail and main datbase versions should be in sync. - // We'll just continue without thumbnails & favicons in this case or any - // other error. - LOG(WARNING) << "Could not initialize the thumbnail database."; - thumbnail_db_.reset(); - } - - // Archived database. - archived_db_.reset(new ArchivedDatabase()); - if (!archived_db_->Init(archived_name)) { - LOG(WARNING) << "Could not initialize the archived database."; - archived_db_.reset(); - } - - // Tell the expiration module about all the nice databases we made. This must - // happen before db_->Init() is called since the callback ForceArchiveHistory - // may need to expire stuff. - // - // *sigh*, this can all be cleaned up when that migration code is removed. - // The main DB initialization should intuitively be first (not that it - // actually matters) and the expirer should be set last. - expirer_.SetDatabases(db_.get(), archived_db_.get(), - thumbnail_db_.get(), text_database_.get()); - - // Open the long-running transaction. - db_->BeginTransaction(); - if (thumbnail_db_.get()) - thumbnail_db_->BeginTransaction(); - if (archived_db_.get()) - archived_db_->BeginTransaction(); - if (text_database_.get()) - text_database_->BeginTransaction(); - - // Start expiring old stuff. - expirer_.StartArchivingOldStuff(TimeDelta::FromDays(kArchiveDaysThreshold)); - - HISTOGRAM_TIMES(L"History.InitTime", - TimeTicks::Now() - beginning_time); + InitImpl(); + delegate_->DBLoaded(); } void HistoryBackend::SetOnBackendDestroyTask(MessageLoop* message_loop, @@ -574,6 +480,106 @@ void HistoryBackend::AddPage(scoped_refptr<HistoryAddPageArgs> request) { ScheduleCommit(); } +void HistoryBackend::InitImpl() { + DCHECK(!db_.get()) << "Initializing HistoryBackend twice"; + // In the rare case where the db fails to initialize a dialog may get shown + // the blocks the caller, yet allows other messages through. For this reason + // we only set db_ to the created database if creation is successful. That + // way other methods won't do anything as db_ is still NULL. + + TimeTicks beginning_time = TimeTicks::Now(); + + // Compute the file names. Note that the index file can be removed when the + // text db manager is finished being hooked up. + std::wstring history_name = history_dir_; + file_util::AppendToPath(&history_name, chrome::kHistoryFilename); + std::wstring thumbnail_name = GetThumbnailFileName(); + std::wstring archived_name = GetArchivedFileName(); + std::wstring tmp_bookmarks_file = history_dir_; + file_util::AppendToPath(&tmp_bookmarks_file, + chrome::kHistoryBookmarksFileName); + + // History database. + db_.reset(new HistoryDatabase()); + switch (db_->Init(history_name, tmp_bookmarks_file)) { + case INIT_OK: + break; + case INIT_FAILURE: + // A NULL db_ will cause all calls on this object to notice this error + // and to not continue. + LOG(WARNING) << "Unable to initialize history DB."; + db_.reset(); + return; + case INIT_TOO_NEW: + delegate_->NotifyTooNew(); + db_.reset(); + return; + default: + NOTREACHED(); + } + + // Fill the in-memory database and send it back to the history service on the + // main thread. + InMemoryHistoryBackend* mem_backend = new InMemoryHistoryBackend; + if (mem_backend->Init(history_name)) + delegate_->SetInMemoryBackend(mem_backend); // Takes ownership of pointer. + else + delete mem_backend; // Error case, run without the in-memory DB. + db_->BeginExclusiveMode(); // Must be after the mem backend read the data. + + // Full-text database. This has to be first so we can pass it to the + // HistoryDatabase for migration. + text_database_.reset(new TextDatabaseManager(history_dir_, db_.get())); + if (!text_database_->Init()) { + LOG(WARNING) << "Text database initialization failed, running without it."; + text_database_.reset(); + } + + // Thumbnail database. + thumbnail_db_.reset(new ThumbnailDatabase()); + if (thumbnail_db_->Init(thumbnail_name) != INIT_OK) { + // Unlike the main database, we don't error out when the database is too + // new because this error is much less severe. Generally, this shouldn't + // happen since the thumbnail and main datbase versions should be in sync. + // We'll just continue without thumbnails & favicons in this case or any + // other error. + LOG(WARNING) << "Could not initialize the thumbnail database."; + thumbnail_db_.reset(); + } + + // Archived database. + archived_db_.reset(new ArchivedDatabase()); + if (!archived_db_->Init(archived_name)) { + LOG(WARNING) << "Could not initialize the archived database."; + archived_db_.reset(); + } + + // Tell the expiration module about all the nice databases we made. This must + // happen before db_->Init() is called since the callback ForceArchiveHistory + // may need to expire stuff. + // + // *sigh*, this can all be cleaned up when that migration code is removed. + // The main DB initialization should intuitively be first (not that it + // actually matters) and the expirer should be set last. + expirer_.SetDatabases(db_.get(), archived_db_.get(), + thumbnail_db_.get(), text_database_.get()); + + // Open the long-running transaction. + db_->BeginTransaction(); + if (thumbnail_db_.get()) + thumbnail_db_->BeginTransaction(); + if (archived_db_.get()) + archived_db_->BeginTransaction(); + if (text_database_.get()) + text_database_->BeginTransaction(); + + // Start expiring old stuff. + expirer_.StartArchivingOldStuff(TimeDelta::FromDays(kArchiveDaysThreshold)); + + HISTOGRAM_TIMES(L"History.InitTime", + TimeTicks::Now() - beginning_time); +} + std::pair<URLID, VisitID> HistoryBackend::AddPageVisit( const GURL& url, Time time, @@ -1052,8 +1058,7 @@ void HistoryBackend::QueryHistoryFTS(const std::wstring& text_query, URLQuerier querier(db_.get(), archived_db_.get(), true); - // Now get the row and visit information for each one, optionally - // filtering on starred items. + // Now get the row and visit information for each one. URLResult url_result; // Declare outside loop to prevent re-construction. for (size_t i = 0; i < fts_matches.size(); i++) { if (options.max_count != 0 && @@ -1291,7 +1296,7 @@ void HistoryBackend::SetImportedFavicons( Time now = Time::Now(); - // Track all starred URLs that had their favicons set or updated. + // Track all URLs that had their favicons set or updated. std::set<GURL> favicons_changed; for (size_t i = 0; i < favicon_usage.size(); i++) { @@ -1320,7 +1325,7 @@ void HistoryBackend::SetImportedFavicons( } if (!favicons_changed.empty()) { - // Send the notification about the changed favicons for starred URLs. + // Send the notification about the changed favicon URLs. FavIconChangeDetails* changed_details = new FavIconChangeDetails; changed_details->urls.swap(favicons_changed); BroadcastNotifications(NOTIFY_FAVICON_CHANGED, changed_details); @@ -1602,6 +1607,23 @@ void HistoryBackend::ExpireHistoryBetween( request->ForwardResult(ExpireHistoryRequest::TupleType()); } +void HistoryBackend::URLsNoLongerBookmarked(const std::set<GURL>& urls) { + if (!db_.get()) + return; + + for (std::set<GURL>::const_iterator i = urls.begin(); i != urls.end(); ++i) { + URLRow url_row; + if (!db_->GetRowForURL(*i, &url_row)) + continue; // The URL isn't in the db; nothing to do. + + VisitVector visits; + db_->GetVisitsForURL(url_row.id(), &visits); + + if (visits.empty()) + expirer_.DeleteURL(*i); // There are no more visits; nuke the URL. + } +} + void HistoryBackend::ProcessDBTask( scoped_refptr<HistoryDBTaskRequest> request) { DCHECK(request.get()); @@ -1619,11 +1641,6 @@ void HistoryBackend::ProcessDBTask( } } -void HistoryBackend::ProcessEmptyRequest( - scoped_refptr<EmptyHistoryRequest> request) { - request->ForwardResult(EmptyHistoryRequest::TupleType()); -} - void HistoryBackend::BroadcastNotifications( NotificationType type, HistoryDetails* details_deleted) { @@ -1645,29 +1662,23 @@ void HistoryBackend::DeleteAllHistory() { // Since we are likely to have very few bookmarks and their dependencies // compared to all history, this is also much faster than just deleting from // the original tables directly. - // - // TODO(brettw): bug 989802: When we store bookmarks in a separate file, this - // function can be simplified to having all the database objects close their - // connections and we just delete the files. - // Get starred entries and their corresponding URL rows. - std::vector<StarredEntry> starred_entries; + // Get the bookmarked URLs. + std::vector<GURL> starred_urls; + BookmarkService* bookmark_service = GetBookmarkService(); + if (bookmark_service) + bookmark_service_->GetBookmarks(&starred_urls); std::vector<URLRow> kept_urls; - for (size_t i = 0; i < starred_entries.size(); i++) { - if (starred_entries[i].type != StarredEntry::URL) - continue; - + for (size_t i = 0; i < starred_urls.size(); i++) { URLRow row; - if (!db_->GetURLRow(starred_entries[i].url_id, &row)) + if (!db_->GetRowForURL(starred_urls[i], &row)) continue; // Clear the last visit time so when we write these rows they are "clean." - // We keep the typed and visit counts. Since the kept URLs are bookmarks, - // we can assume that the user isn't trying to hide that they like them, - // and we can use these counts for giving better autocomplete suggestions. row.set_last_visit(Time()); - + row.set_visit_count(0); + row.set_typed_count(0); kept_urls.push_back(row); } @@ -1681,7 +1692,7 @@ void HistoryBackend::DeleteAllHistory() { // ClearAllMainHistory will change the IDs of the URLs in kept_urls. Therfore, // we clear the list afterwards to make sure nobody uses this invalid data. - if (!ClearAllMainHistory(&starred_entries, kept_urls)) + if (!ClearAllMainHistory(kept_urls)) LOG(ERROR) << "Main history could not be cleared"; kept_urls.clear(); @@ -1775,7 +1786,6 @@ bool HistoryBackend::ClearAllThumbnailHistory( } bool HistoryBackend::ClearAllMainHistory( - std::vector<StarredEntry>* starred_entries, const std::vector<URLRow>& kept_urls) { // Create the duplicate URL table. We will copy the kept URLs into this. if (!db_->CreateTemporaryURLTable()) @@ -1797,7 +1807,7 @@ bool HistoryBackend::ClearAllMainHistory( return false; // Delete the old tables and recreate them empty. - db_->RecreateAllButStarAndURLTables(); + db_->RecreateAllTablesButURL(); // Vacuum to reclaim the space from the dropped tables. This must be done // when there is no transaction open, and we assume that our long-running @@ -1808,5 +1818,11 @@ bool HistoryBackend::ClearAllMainHistory( return true; } +BookmarkService* HistoryBackend::GetBookmarkService() { + if (bookmark_service_) + bookmark_service_->BlockTillLoaded(); + return bookmark_service_; +} + } // namespace history |