1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/history/in_memory_history_backend.h"
10 #include "base/command_line.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/time/time.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/history/history_notifications.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "components/history/core/browser/in_memory_database.h"
18 #include "components/history/core/browser/url_database.h"
19 #include "content/public/browser/notification_details.h"
20 #include "content/public/browser/notification_source.h"
24 InMemoryHistoryBackend::InMemoryHistoryBackend()
28 InMemoryHistoryBackend::~InMemoryHistoryBackend() {}
30 bool InMemoryHistoryBackend::Init(const base::FilePath& history_filename) {
31 db_.reset(new InMemoryDatabase);
32 return db_->InitFromDisk(history_filename);
35 void InMemoryHistoryBackend::AttachToHistoryService(Profile* profile) {
43 // TODO(evanm): this is currently necessitated by generate_profile, which
44 // runs without a browser process. generate_profile should really create
45 // a browser process, at which point this check can then be nuked.
46 if (!g_browser_process)
49 // Register for the notifications we care about.
50 // We only want notifications for the associated profile.
51 content::Source<Profile> source(profile_);
52 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED, source);
53 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_MODIFIED, source);
54 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, source);
56 this, chrome::NOTIFICATION_HISTORY_KEYWORD_SEARCH_TERM_UPDATED, source);
58 this, chrome::NOTIFICATION_HISTORY_KEYWORD_SEARCH_TERM_DELETED, source);
61 void InMemoryHistoryBackend::DeleteAllSearchTermsForKeyword(
62 KeywordID keyword_id) {
63 // For simplicity, this will not remove the corresponding URLRows, but
64 // this is okay, as the main database does not do so either.
65 db_->DeleteAllSearchTermsForKeyword(keyword_id);
68 void InMemoryHistoryBackend::Observe(
70 const content::NotificationSource& source,
71 const content::NotificationDetails& details) {
73 case chrome::NOTIFICATION_HISTORY_URL_VISITED:
74 OnURLVisitedOrModified(content::Details<URLVisitedDetails>(details)->row);
76 case chrome::NOTIFICATION_HISTORY_KEYWORD_SEARCH_TERM_UPDATED:
77 OnKeywordSearchTermUpdated(
78 *content::Details<KeywordSearchUpdatedDetails>(details).ptr());
80 case chrome::NOTIFICATION_HISTORY_KEYWORD_SEARCH_TERM_DELETED:
81 OnKeywordSearchTermDeleted(
82 *content::Details<KeywordSearchDeletedDetails>(details).ptr());
84 case chrome::NOTIFICATION_HISTORY_URLS_MODIFIED: {
85 const URLsModifiedDetails* modified_details =
86 content::Details<URLsModifiedDetails>(details).ptr();
87 URLRows::const_iterator it;
88 for (it = modified_details->changed_urls.begin();
89 it != modified_details->changed_urls.end(); ++it) {
90 OnURLVisitedOrModified(*it);
94 case chrome::NOTIFICATION_HISTORY_URLS_DELETED:
95 OnURLsDeleted(*content::Details<URLsDeletedDetails>(details).ptr());
98 // For simplicity, the unit tests send us all notifications, even when
99 // we haven't registered for them, so don't assert here.
104 void InMemoryHistoryBackend::OnURLVisitedOrModified(const URLRow& url_row) {
106 DCHECK(url_row.id());
107 if (url_row.typed_count() || db_->GetKeywordSearchTermRow(url_row.id(), NULL))
108 db_->InsertOrUpdateURLRowByID(url_row);
110 db_->DeleteURLRow(url_row.id());
113 void InMemoryHistoryBackend::OnURLsDeleted(const URLsDeletedDetails& details) {
116 if (details.all_history) {
117 // When all history is deleted, the individual URLs won't be listed. Just
118 // create a new database to quickly clear everything out.
119 db_.reset(new InMemoryDatabase);
120 if (!db_->InitFromScratch())
125 // Delete all matching URLs in our database.
126 for (URLRows::const_iterator row = details.rows.begin();
127 row != details.rows.end(); ++row) {
128 // This will also delete the corresponding keyword search term.
129 // Ignore errors, as we typically only cache a subset of URLRows.
130 db_->DeleteURLRow(row->id());
134 void InMemoryHistoryBackend::OnKeywordSearchTermUpdated(
135 const KeywordSearchUpdatedDetails& details) {
136 DCHECK(details.url_row.id());
137 db_->InsertOrUpdateURLRowByID(details.url_row);
138 db_->SetKeywordSearchTermsForURL(
139 details.url_row.id(), details.keyword_id, details.term);
142 void InMemoryHistoryBackend::OnKeywordSearchTermDeleted(
143 const KeywordSearchDeletedDetails& details) {
144 // For simplicity, this will not remove the corresponding URLRow, but this is
145 // okay, as the main database does not do so either.
146 db_->DeleteKeywordSearchTermForURL(details.url_row_id);
149 } // namespace history