| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/history/visit_database.h" | 5 #include "chrome/browser/history/visit_database.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 statement.BindInt64(0, row.referring_visit); | 425 statement.BindInt64(0, row.referring_visit); |
| 426 | 426 |
| 427 if (!statement.Step()) | 427 if (!statement.Step()) |
| 428 return false; | 428 return false; |
| 429 | 429 |
| 430 *from_url = GURL(statement.ColumnString(0)); | 430 *from_url = GURL(statement.ColumnString(0)); |
| 431 } | 431 } |
| 432 return true; | 432 return true; |
| 433 } | 433 } |
| 434 | 434 |
| 435 bool VisitDatabase::GetVisitCountToHost(const GURL& url, | 435 bool VisitDatabase::GetVisibleVisitCountToHost(const GURL& url, |
| 436 int* count, | 436 int* count, |
| 437 base::Time* first_visit) { | 437 base::Time* first_visit) { |
| 438 if (!url.SchemeIs(chrome::kHttpScheme) && !url.SchemeIs(chrome::kHttpsScheme)) | 438 if (!url.SchemeIs(chrome::kHttpScheme) && !url.SchemeIs(chrome::kHttpsScheme)) |
| 439 return false; | 439 return false; |
| 440 | 440 |
| 441 // We need to search for URLs with a matching host/port. One way to query for | 441 // We need to search for URLs with a matching host/port. One way to query for |
| 442 // this is to use the LIKE operator, eg 'url LIKE http://google.com/%'. This | 442 // this is to use the LIKE operator, eg 'url LIKE http://google.com/%'. This |
| 443 // is inefficient though in that it doesn't use the index and each entry must | 443 // is inefficient though in that it doesn't use the index and each entry must |
| 444 // be visited. The same query can be executed by using >= and < operator. | 444 // be visited. The same query can be executed by using >= and < operator. |
| 445 // The query becomes: | 445 // The query becomes: |
| 446 // 'url >= http://google.com/' and url < http://google.com0'. | 446 // 'url >= http://google.com/' and url < http://google.com0'. |
| 447 // 0 is used as it is one character greater than '/'. | 447 // 0 is used as it is one character greater than '/'. |
| 448 GURL search_url(url); | 448 const std::string host_query_min = url.GetOrigin().spec(); |
| 449 const std::string host_query_min = search_url.GetOrigin().spec(); | |
| 450 | |
| 451 if (host_query_min.empty()) | 449 if (host_query_min.empty()) |
| 452 return false; | 450 return false; |
| 453 | 451 |
| 454 std::string host_query_max = host_query_min; | 452 // We also want to restrict ourselves to main frame navigations that are not |
| 455 host_query_max[host_query_max.size() - 1] = '0'; | 453 // in the middle of redirect chains, hence the transition checks. |
| 456 | |
| 457 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 454 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 458 "SELECT MIN(v.visit_time), COUNT(*) " | 455 "SELECT MIN(v.visit_time), COUNT(*) " |
| 459 "FROM visits v INNER JOIN urls u ON v.url = u.id " | 456 "FROM visits v INNER JOIN urls u ON v.url = u.id " |
| 460 "WHERE (u.url >= ? AND u.url < ?)")); | 457 "WHERE u.url >= ? AND u.url < ? " |
| 458 "AND (transition & ?) != 0 " |
| 459 "AND (transition & ?) NOT IN (?, ?, ?)")); |
| 461 if (!statement) | 460 if (!statement) |
| 462 return false; | 461 return false; |
| 463 | 462 |
| 464 statement.BindString(0, host_query_min); | 463 statement.BindString(0, host_query_min); |
| 465 statement.BindString(1, host_query_max); | 464 statement.BindString(1, |
| 465 host_query_min.substr(0, host_query_min.size() - 1) + '0'); |
| 466 statement.BindInt(2, PageTransition::CHAIN_END); |
| 467 statement.BindInt(3, PageTransition::CORE_MASK); |
| 468 statement.BindInt(4, PageTransition::AUTO_SUBFRAME); |
| 469 statement.BindInt(5, PageTransition::MANUAL_SUBFRAME); |
| 470 statement.BindInt(6, PageTransition::KEYWORD_GENERATED); |
| 466 | 471 |
| 467 if (!statement.Step()) { | 472 if (!statement.Step()) { |
| 468 // We've never been to this page before. | 473 // We've never been to this page before. |
| 469 *count = 0; | 474 *count = 0; |
| 470 return true; | 475 return true; |
| 471 } | 476 } |
| 472 | 477 |
| 473 *first_visit = base::Time::FromInternalValue(statement.ColumnInt64(0)); | 478 *first_visit = base::Time::FromInternalValue(statement.ColumnInt64(0)); |
| 474 *count = statement.ColumnInt(1); | 479 *count = statement.ColumnInt(1); |
| 475 return true; | 480 return true; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 // Get the source entries out of the query result. | 523 // Get the source entries out of the query result. |
| 519 while (statement.Step()) { | 524 while (statement.Step()) { |
| 520 std::pair<VisitID, VisitSource> source_entry(statement.ColumnInt64(0), | 525 std::pair<VisitID, VisitSource> source_entry(statement.ColumnInt64(0), |
| 521 static_cast<VisitSource>(statement.ColumnInt(1))); | 526 static_cast<VisitSource>(statement.ColumnInt(1))); |
| 522 sources->insert(source_entry); | 527 sources->insert(source_entry); |
| 523 } | 528 } |
| 524 } | 529 } |
| 525 } | 530 } |
| 526 | 531 |
| 527 } // namespace history | 532 } // namespace history |
| OLD | NEW |