summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/history/history.cc8
-rw-r--r--chrome/browser/history/history.h6
-rw-r--r--chrome/browser/history/history_backend.cc49
-rw-r--r--chrome/browser/history/history_backend.h14
-rw-r--r--chrome/browser/history/history_notifications.h6
-rw-r--r--chrome/browser/history/visit_database.cc27
-rw-r--r--chrome/browser/history/visit_database.h6
7 files changed, 115 insertions, 1 deletions
diff --git a/chrome/browser/history/history.cc b/chrome/browser/history/history.cc
index 220f3cc..01d3e35 100644
--- a/chrome/browser/history/history.cc
+++ b/chrome/browser/history/history.cc
@@ -516,6 +516,14 @@ HistoryService::Handle HistoryService::QueryRedirectsFrom(
new history::QueryRedirectsRequest(callback), from_url);
}
+HistoryService::Handle HistoryService::QueryRedirectsTo(
+ const GURL& to_url,
+ CancelableRequestConsumerBase* consumer,
+ QueryRedirectsCallback* callback) {
+ return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryRedirectsTo, consumer,
+ new history::QueryRedirectsRequest(callback), to_url);
+}
+
HistoryService::Handle HistoryService::GetVisitCountToHost(
const GURL& url,
CancelableRequestConsumerBase* consumer,
diff --git a/chrome/browser/history/history.h b/chrome/browser/history/history.h
index 2b480a7..8ca8878 100644
--- a/chrome/browser/history/history.h
+++ b/chrome/browser/history/history.h
@@ -280,6 +280,12 @@ class HistoryService : public CancelableRequestProvider,
CancelableRequestConsumerBase* consumer,
QueryRedirectsCallback* callback);
+ // Schedules a query to get the most recent redirects ending at the given
+ // URL.
+ Handle QueryRedirectsTo(const GURL& to_url,
+ CancelableRequestConsumerBase* consumer,
+ QueryRedirectsCallback* callback);
+
typedef Callback4<Handle,
bool, // Were we able to determine the # of visits?
int, // Number of visits.
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc
index 691f24a..3200355 100644
--- a/chrome/browser/history/history_backend.cc
+++ b/chrome/browser/history/history_backend.cc
@@ -648,6 +648,7 @@ std::pair<URLID, VisitID> HistoryBackend::AddPageVisit(
URLVisitedDetails* details = new URLVisitedDetails;
details->transition = transition;
details->row = url_info;
+ GetMostRecentRedirectsTo(url, &details->redirects);
BroadcastNotifications(NotificationType::HISTORY_URL_VISITED, details);
}
@@ -1127,6 +1128,16 @@ void HistoryBackend::QueryRedirectsFrom(
request->handle(), url, success, &request->value));
}
+void HistoryBackend::QueryRedirectsTo(
+ scoped_refptr<QueryRedirectsRequest> request,
+ const GURL& url) {
+ if (request->canceled())
+ return;
+ bool success = GetMostRecentRedirectsTo(url, &request->value);
+ request->ForwardResult(QueryRedirectsRequest::TupleType(
+ request->handle(), url, success, &request->value));
+}
+
void HistoryBackend::GetVisitCountToHost(
scoped_refptr<GetVisitCountToHostRequest> request,
const GURL& url) {
@@ -1158,6 +1169,28 @@ void HistoryBackend::GetRedirectsFromSpecificVisit(
}
}
+void HistoryBackend::GetRedirectsToSpecificVisit(
+ VisitID cur_visit,
+ HistoryService::RedirectList* redirects) {
+ // Follow redirects going to cur_visit. These are added to |redirects| in
+ // the order they are found. If a redirect chain looks like A -> B -> C and
+ // |cur_visit| = C, redirects will be {B, A} in that order.
+ if (!db_.get())
+ return;
+
+ GURL cur_url;
+ std::set<VisitID> visit_set;
+ visit_set.insert(cur_visit);
+ while (db_->GetRedirectToVisit(cur_visit, &cur_visit, &cur_url)) {
+ if (visit_set.find(cur_visit) != visit_set.end()) {
+ NOTREACHED() << "Loop in visit chain, giving up";
+ return;
+ }
+ visit_set.insert(cur_visit);
+ redirects->push_back(cur_url);
+ }
+}
+
bool HistoryBackend::GetMostRecentRedirectsFrom(
const GURL& from_url,
HistoryService::RedirectList* redirects) {
@@ -1174,6 +1207,22 @@ bool HistoryBackend::GetMostRecentRedirectsFrom(
return true;
}
+bool HistoryBackend::GetMostRecentRedirectsTo(
+ const GURL& to_url,
+ HistoryService::RedirectList* redirects) {
+ redirects->clear();
+ if (!db_.get())
+ return false;
+
+ URLID to_url_id = db_->GetRowForURL(to_url, NULL);
+ VisitID cur_visit = db_->GetMostRecentVisitForURL(to_url_id, NULL);
+ if (!cur_visit)
+ return false; // No visits for URL.
+
+ GetRedirectsToSpecificVisit(cur_visit, redirects);
+ return true;
+}
+
void HistoryBackend::ScheduleAutocomplete(HistoryURLProvider* provider,
HistoryURLProviderParams* params) {
// ExecuteWithDB should handle the NULL database case.
diff --git a/chrome/browser/history/history_backend.h b/chrome/browser/history/history_backend.h
index 1e08bab..421e0a0 100644
--- a/chrome/browser/history/history_backend.h
+++ b/chrome/browser/history/history_backend.h
@@ -142,6 +142,8 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
const QueryOptions& options);
void QueryRedirectsFrom(scoped_refptr<QueryRedirectsRequest> request,
const GURL& url);
+ void QueryRedirectsTo(scoped_refptr<QueryRedirectsRequest> request,
+ const GURL& url);
void GetVisitCountToHost(scoped_refptr<GetVisitCountToHostRequest> request,
const GURL& url);
@@ -155,6 +157,13 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
bool GetMostRecentRedirectsFrom(const GURL& url,
HistoryService::RedirectList* redirects);
+ // Similar to above function except computes a chain of redirects to the
+ // given URL. Stores the most recent list of redirects ending at |url| in the
+ // given RedirectList. For example, if we have the redirect list A -> B -> C,
+ // then calling this function with url=C would fill redirects with {B, A}.
+ bool GetMostRecentRedirectsTo(const GURL& url,
+ HistoryService::RedirectList* redirects);
+
// Thumbnails ----------------------------------------------------------------
void SetPageThumbnail(const GURL& url,
@@ -298,6 +307,11 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
void GetRedirectsFromSpecificVisit(
VisitID cur_visit, HistoryService::RedirectList* redirects);
+ // Similar to the above function except returns a redirect list ending
+ // at |cur_visit|.
+ void GetRedirectsToSpecificVisit(
+ VisitID cur_visit, HistoryService::RedirectList* redirects);
+
// Thumbnail Helpers ---------------------------------------------------------
// When a simple GetMostRecentRedirectsFrom() fails, this method is
diff --git a/chrome/browser/history/history_notifications.h b/chrome/browser/history/history_notifications.h
index 4eb9289..1281f2f4 100644
--- a/chrome/browser/history/history_notifications.h
+++ b/chrome/browser/history/history_notifications.h
@@ -27,6 +27,12 @@ struct HistoryDetails {
struct URLVisitedDetails : public HistoryDetails {
PageTransition::Type transition;
URLRow row;
+
+ // A list of redirects leading up to the URL represented by this struct. If
+ // we have the redirect chain A -> B -> C and this struct represents visiting
+ // C, then redirects[0]=B and redirects[1]=A. If there are no redirects,
+ // this will be an empty vector.
+ std::vector<GURL> redirects;
};
// Details for NOTIFY_HISTORY_TYPED_URLS_MODIFIED.
diff --git a/chrome/browser/history/visit_database.cc b/chrome/browser/history/visit_database.cc
index c118bf2..7ce3e62 100644
--- a/chrome/browser/history/visit_database.cc
+++ b/chrome/browser/history/visit_database.cc
@@ -327,6 +327,31 @@ bool VisitDatabase::GetRedirectFromVisit(VisitID from_visit,
return true;
}
+bool VisitDatabase::GetRedirectToVisit(VisitID to_visit,
+ VisitID* from_visit,
+ GURL* from_url) {
+ VisitRow row;
+ if (!GetRowForVisit(to_visit, &row))
+ return false;
+
+ if (from_visit)
+ *from_visit = row.referring_visit;
+
+ if (from_url) {
+ SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ "SELECT u.url "
+ "FROM visits v JOIN urls u ON v.url = u.id "
+ "WHERE v.id = ?");
+ statement->bind_int64(0, row.referring_visit);
+
+ if (statement->step() != SQLITE_ROW)
+ return false;
+
+ *from_url = GURL(statement->column_string(0));
+ }
+ return true;
+}
+
bool VisitDatabase::GetVisitCountToHost(const GURL& url,
int* count,
Time* first_visit) {
@@ -373,7 +398,7 @@ bool VisitDatabase::GetVisitCountToHost(const GURL& url,
bool VisitDatabase::GetStartDate(Time* first_visit) {
SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
"SELECT MIN(visit_time) FROM visits WHERE visit_time != 0");
- if (!statement.is_valid() || statement->step() != SQLITE_ROW ||
+ if (!statement.is_valid() || statement->step() != SQLITE_ROW ||
statement->column_int64(0) == 0) {
*first_visit = Time::Now();
return false;
diff --git a/chrome/browser/history/visit_database.h b/chrome/browser/history/visit_database.h
index 0b2549e..2f73f90 100644
--- a/chrome/browser/history/visit_database.h
+++ b/chrome/browser/history/visit_database.h
@@ -111,6 +111,12 @@ class VisitDatabase {
VisitID* to_visit,
GURL* to_url);
+ // Similar to the above function except finds a redirect going to a given
+ // |to_visit|.
+ bool GetRedirectToVisit(VisitID to_visit,
+ VisitID* from_visit,
+ GURL* from_url);
+
// Returns the number of visits to all urls on the scheme/host/post
// identified by url. This is only valid for http and https urls (all other
// schemes are ignored and false is returned).