| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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> |
| 11 | 11 |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "chrome/browser/history/visit_filter.h" | 14 #include "chrome/browser/history/visit_filter.h" |
| 15 #include "chrome/common/url_constants.h" | 15 #include "chrome/common/url_constants.h" |
| 16 #include "components/history/core/browser/url_database.h" | 16 #include "components/history/core/browser/url_database.h" |
| 17 #include "content/public/common/page_transition_types.h" | |
| 18 #include "sql/statement.h" | 17 #include "sql/statement.h" |
| 18 #include "ui/base/page_transition_types.h" |
| 19 | 19 |
| 20 namespace history { | 20 namespace history { |
| 21 | 21 |
| 22 VisitDatabase::VisitDatabase() { | 22 VisitDatabase::VisitDatabase() { |
| 23 } | 23 } |
| 24 | 24 |
| 25 VisitDatabase::~VisitDatabase() { | 25 VisitDatabase::~VisitDatabase() { |
| 26 } | 26 } |
| 27 | 27 |
| 28 bool VisitDatabase::InitVisitTable() { | 28 bool VisitDatabase::InitVisitTable() { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 GetDB().Execute("DROP TABLE visits"); | 80 GetDB().Execute("DROP TABLE visits"); |
| 81 } | 81 } |
| 82 | 82 |
| 83 // Must be in sync with HISTORY_VISIT_ROW_FIELDS. | 83 // Must be in sync with HISTORY_VISIT_ROW_FIELDS. |
| 84 // static | 84 // static |
| 85 void VisitDatabase::FillVisitRow(sql::Statement& statement, VisitRow* visit) { | 85 void VisitDatabase::FillVisitRow(sql::Statement& statement, VisitRow* visit) { |
| 86 visit->visit_id = statement.ColumnInt64(0); | 86 visit->visit_id = statement.ColumnInt64(0); |
| 87 visit->url_id = statement.ColumnInt64(1); | 87 visit->url_id = statement.ColumnInt64(1); |
| 88 visit->visit_time = base::Time::FromInternalValue(statement.ColumnInt64(2)); | 88 visit->visit_time = base::Time::FromInternalValue(statement.ColumnInt64(2)); |
| 89 visit->referring_visit = statement.ColumnInt64(3); | 89 visit->referring_visit = statement.ColumnInt64(3); |
| 90 visit->transition = content::PageTransitionFromInt(statement.ColumnInt(4)); | 90 visit->transition = ui::PageTransitionFromInt(statement.ColumnInt(4)); |
| 91 visit->segment_id = statement.ColumnInt64(5); | 91 visit->segment_id = statement.ColumnInt64(5); |
| 92 visit->visit_duration = | 92 visit->visit_duration = |
| 93 base::TimeDelta::FromInternalValue(statement.ColumnInt64(6)); | 93 base::TimeDelta::FromInternalValue(statement.ColumnInt64(6)); |
| 94 } | 94 } |
| 95 | 95 |
| 96 // static | 96 // static |
| 97 bool VisitDatabase::FillVisitVector(sql::Statement& statement, | 97 bool VisitDatabase::FillVisitVector(sql::Statement& statement, |
| 98 VisitVector* visits) { | 98 VisitVector* visits) { |
| 99 if (!statement.is_valid()) | 99 if (!statement.is_valid()) |
| 100 return false; | 100 return false; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 "SELECT" HISTORY_VISIT_ROW_FIELDS | 264 "SELECT" HISTORY_VISIT_ROW_FIELDS |
| 265 "FROM visits " | 265 "FROM visits " |
| 266 "WHERE url=? AND visit_time >= ? AND visit_time < ? " | 266 "WHERE url=? AND visit_time >= ? AND visit_time < ? " |
| 267 "AND (transition & ?) != 0 " // CHAIN_END | 267 "AND (transition & ?) != 0 " // CHAIN_END |
| 268 "AND (transition & ?) NOT IN (?, ?, ?) " // NO SUBFRAME or | 268 "AND (transition & ?) NOT IN (?, ?, ?) " // NO SUBFRAME or |
| 269 // KEYWORD_GENERATED | 269 // KEYWORD_GENERATED |
| 270 "ORDER BY visit_time DESC")); | 270 "ORDER BY visit_time DESC")); |
| 271 statement.BindInt64(0, url_id); | 271 statement.BindInt64(0, url_id); |
| 272 statement.BindInt64(1, options.EffectiveBeginTime()); | 272 statement.BindInt64(1, options.EffectiveBeginTime()); |
| 273 statement.BindInt64(2, options.EffectiveEndTime()); | 273 statement.BindInt64(2, options.EffectiveEndTime()); |
| 274 statement.BindInt(3, content::PAGE_TRANSITION_CHAIN_END); | 274 statement.BindInt(3, ui::PAGE_TRANSITION_CHAIN_END); |
| 275 statement.BindInt(4, content::PAGE_TRANSITION_CORE_MASK); | 275 statement.BindInt(4, ui::PAGE_TRANSITION_CORE_MASK); |
| 276 statement.BindInt(5, content::PAGE_TRANSITION_AUTO_SUBFRAME); | 276 statement.BindInt(5, ui::PAGE_TRANSITION_AUTO_SUBFRAME); |
| 277 statement.BindInt(6, content::PAGE_TRANSITION_MANUAL_SUBFRAME); | 277 statement.BindInt(6, ui::PAGE_TRANSITION_MANUAL_SUBFRAME); |
| 278 statement.BindInt(7, content::PAGE_TRANSITION_KEYWORD_GENERATED); | 278 statement.BindInt(7, ui::PAGE_TRANSITION_KEYWORD_GENERATED); |
| 279 | 279 |
| 280 return FillVisitVectorWithOptions(statement, options, visits); | 280 return FillVisitVectorWithOptions(statement, options, visits); |
| 281 } | 281 } |
| 282 | 282 |
| 283 bool VisitDatabase::GetVisitsForTimes(const std::vector<base::Time>& times, | 283 bool VisitDatabase::GetVisitsForTimes(const std::vector<base::Time>& times, |
| 284 VisitVector* visits) { | 284 VisitVector* visits) { |
| 285 visits->clear(); | 285 visits->clear(); |
| 286 | 286 |
| 287 for (std::vector<base::Time>::const_iterator it = times.begin(); | 287 for (std::vector<base::Time>::const_iterator it = times.begin(); |
| 288 it != times.end(); ++it) { | 288 it != times.end(); ++it) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 316 statement.BindInt64(2, | 316 statement.BindInt64(2, |
| 317 max_results ? max_results : std::numeric_limits<int64>::max()); | 317 max_results ? max_results : std::numeric_limits<int64>::max()); |
| 318 | 318 |
| 319 return FillVisitVector(statement, visits); | 319 return FillVisitVector(statement, visits); |
| 320 } | 320 } |
| 321 | 321 |
| 322 bool VisitDatabase::GetVisitsInRangeForTransition( | 322 bool VisitDatabase::GetVisitsInRangeForTransition( |
| 323 base::Time begin_time, | 323 base::Time begin_time, |
| 324 base::Time end_time, | 324 base::Time end_time, |
| 325 int max_results, | 325 int max_results, |
| 326 content::PageTransition transition, | 326 ui::PageTransition transition, |
| 327 VisitVector* visits) { | 327 VisitVector* visits) { |
| 328 DCHECK(visits); | 328 DCHECK(visits); |
| 329 visits->clear(); | 329 visits->clear(); |
| 330 | 330 |
| 331 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 331 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 332 "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits " | 332 "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits " |
| 333 "WHERE visit_time >= ? AND visit_time < ? " | 333 "WHERE visit_time >= ? AND visit_time < ? " |
| 334 "AND (transition & ?) == ?" | 334 "AND (transition & ?) == ?" |
| 335 "ORDER BY visit_time LIMIT ?")); | 335 "ORDER BY visit_time LIMIT ?")); |
| 336 | 336 |
| 337 // See GetVisibleVisitsInRange for more info on how these times are bound. | 337 // See GetVisibleVisitsInRange for more info on how these times are bound. |
| 338 int64 end = end_time.ToInternalValue(); | 338 int64 end = end_time.ToInternalValue(); |
| 339 statement.BindInt64(0, begin_time.ToInternalValue()); | 339 statement.BindInt64(0, begin_time.ToInternalValue()); |
| 340 statement.BindInt64(1, end ? end : std::numeric_limits<int64>::max()); | 340 statement.BindInt64(1, end ? end : std::numeric_limits<int64>::max()); |
| 341 statement.BindInt(2, content::PAGE_TRANSITION_CORE_MASK); | 341 statement.BindInt(2, ui::PAGE_TRANSITION_CORE_MASK); |
| 342 statement.BindInt(3, transition); | 342 statement.BindInt(3, transition); |
| 343 statement.BindInt64(4, | 343 statement.BindInt64(4, |
| 344 max_results ? max_results : std::numeric_limits<int64>::max()); | 344 max_results ? max_results : std::numeric_limits<int64>::max()); |
| 345 | 345 |
| 346 return FillVisitVector(statement, visits); | 346 return FillVisitVector(statement, visits); |
| 347 } | 347 } |
| 348 | 348 |
| 349 bool VisitDatabase::GetVisibleVisitsInRange(const QueryOptions& options, | 349 bool VisitDatabase::GetVisibleVisitsInRange(const QueryOptions& options, |
| 350 VisitVector* visits) { | 350 VisitVector* visits) { |
| 351 visits->clear(); | 351 visits->clear(); |
| 352 // The visit_time values can be duplicated in a redirect chain, so we sort | 352 // The visit_time values can be duplicated in a redirect chain, so we sort |
| 353 // by id too, to ensure a consistent ordering just in case. | 353 // by id too, to ensure a consistent ordering just in case. |
| 354 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 354 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 355 "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits " | 355 "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits " |
| 356 "WHERE visit_time >= ? AND visit_time < ? " | 356 "WHERE visit_time >= ? AND visit_time < ? " |
| 357 "AND (transition & ?) != 0 " // CHAIN_END | 357 "AND (transition & ?) != 0 " // CHAIN_END |
| 358 "AND (transition & ?) NOT IN (?, ?, ?) " // NO SUBFRAME or | 358 "AND (transition & ?) NOT IN (?, ?, ?) " // NO SUBFRAME or |
| 359 // KEYWORD_GENERATED | 359 // KEYWORD_GENERATED |
| 360 "ORDER BY visit_time DESC, id DESC")); | 360 "ORDER BY visit_time DESC, id DESC")); |
| 361 | 361 |
| 362 statement.BindInt64(0, options.EffectiveBeginTime()); | 362 statement.BindInt64(0, options.EffectiveBeginTime()); |
| 363 statement.BindInt64(1, options.EffectiveEndTime()); | 363 statement.BindInt64(1, options.EffectiveEndTime()); |
| 364 statement.BindInt(2, content::PAGE_TRANSITION_CHAIN_END); | 364 statement.BindInt(2, ui::PAGE_TRANSITION_CHAIN_END); |
| 365 statement.BindInt(3, content::PAGE_TRANSITION_CORE_MASK); | 365 statement.BindInt(3, ui::PAGE_TRANSITION_CORE_MASK); |
| 366 statement.BindInt(4, content::PAGE_TRANSITION_AUTO_SUBFRAME); | 366 statement.BindInt(4, ui::PAGE_TRANSITION_AUTO_SUBFRAME); |
| 367 statement.BindInt(5, content::PAGE_TRANSITION_MANUAL_SUBFRAME); | 367 statement.BindInt(5, ui::PAGE_TRANSITION_MANUAL_SUBFRAME); |
| 368 statement.BindInt(6, content::PAGE_TRANSITION_KEYWORD_GENERATED); | 368 statement.BindInt(6, ui::PAGE_TRANSITION_KEYWORD_GENERATED); |
| 369 | 369 |
| 370 return FillVisitVectorWithOptions(statement, options, visits); | 370 return FillVisitVectorWithOptions(statement, options, visits); |
| 371 } | 371 } |
| 372 | 372 |
| 373 void VisitDatabase::GetDirectVisitsDuringTimes(const VisitFilter& time_filter, | 373 void VisitDatabase::GetDirectVisitsDuringTimes(const VisitFilter& time_filter, |
| 374 int max_results, | 374 int max_results, |
| 375 VisitVector* visits) { | 375 VisitVector* visits) { |
| 376 visits->clear(); | 376 visits->clear(); |
| 377 if (max_results) | 377 if (max_results) |
| 378 visits->reserve(max_results); | 378 visits->reserve(max_results); |
| 379 for (VisitFilter::TimeVector::const_iterator it = time_filter.times().begin(); | 379 for (VisitFilter::TimeVector::const_iterator it = time_filter.times().begin(); |
| 380 it != time_filter.times().end(); ++it) { | 380 it != time_filter.times().end(); ++it) { |
| 381 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 381 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 382 "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits " | 382 "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits " |
| 383 "WHERE visit_time >= ? AND visit_time < ? " | 383 "WHERE visit_time >= ? AND visit_time < ? " |
| 384 "AND (transition & ?) != 0 " // CHAIN_START | 384 "AND (transition & ?) != 0 " // CHAIN_START |
| 385 "AND (transition & ?) IN (?, ?) " // TYPED or AUTO_BOOKMARK only | 385 "AND (transition & ?) IN (?, ?) " // TYPED or AUTO_BOOKMARK only |
| 386 "ORDER BY visit_time DESC, id DESC")); | 386 "ORDER BY visit_time DESC, id DESC")); |
| 387 | 387 |
| 388 statement.BindInt64(0, it->first.ToInternalValue()); | 388 statement.BindInt64(0, it->first.ToInternalValue()); |
| 389 statement.BindInt64(1, it->second.ToInternalValue()); | 389 statement.BindInt64(1, it->second.ToInternalValue()); |
| 390 statement.BindInt(2, content::PAGE_TRANSITION_CHAIN_START); | 390 statement.BindInt(2, ui::PAGE_TRANSITION_CHAIN_START); |
| 391 statement.BindInt(3, content::PAGE_TRANSITION_CORE_MASK); | 391 statement.BindInt(3, ui::PAGE_TRANSITION_CORE_MASK); |
| 392 statement.BindInt(4, content::PAGE_TRANSITION_TYPED); | 392 statement.BindInt(4, ui::PAGE_TRANSITION_TYPED); |
| 393 statement.BindInt(5, content::PAGE_TRANSITION_AUTO_BOOKMARK); | 393 statement.BindInt(5, ui::PAGE_TRANSITION_AUTO_BOOKMARK); |
| 394 | 394 |
| 395 while (statement.Step()) { | 395 while (statement.Step()) { |
| 396 VisitRow visit; | 396 VisitRow visit; |
| 397 FillVisitRow(statement, &visit); | 397 FillVisitRow(statement, &visit); |
| 398 visits->push_back(visit); | 398 visits->push_back(visit); |
| 399 | 399 |
| 400 if (max_results > 0 && static_cast<int>(visits->size()) >= max_results) | 400 if (max_results > 0 && static_cast<int>(visits->size()) >= max_results) |
| 401 return; | 401 return; |
| 402 } | 402 } |
| 403 } | 403 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 | 444 |
| 445 bool VisitDatabase::GetRedirectFromVisit(VisitID from_visit, | 445 bool VisitDatabase::GetRedirectFromVisit(VisitID from_visit, |
| 446 VisitID* to_visit, | 446 VisitID* to_visit, |
| 447 GURL* to_url) { | 447 GURL* to_url) { |
| 448 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 448 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 449 "SELECT v.id,u.url " | 449 "SELECT v.id,u.url " |
| 450 "FROM visits v JOIN urls u ON v.url = u.id " | 450 "FROM visits v JOIN urls u ON v.url = u.id " |
| 451 "WHERE v.from_visit = ? " | 451 "WHERE v.from_visit = ? " |
| 452 "AND (v.transition & ?) != 0")); // IS_REDIRECT_MASK | 452 "AND (v.transition & ?) != 0")); // IS_REDIRECT_MASK |
| 453 statement.BindInt64(0, from_visit); | 453 statement.BindInt64(0, from_visit); |
| 454 statement.BindInt(1, content::PAGE_TRANSITION_IS_REDIRECT_MASK); | 454 statement.BindInt(1, ui::PAGE_TRANSITION_IS_REDIRECT_MASK); |
| 455 | 455 |
| 456 if (!statement.Step()) | 456 if (!statement.Step()) |
| 457 return false; // No redirect from this visit. (Or SQL error) | 457 return false; // No redirect from this visit. (Or SQL error) |
| 458 if (to_visit) | 458 if (to_visit) |
| 459 *to_visit = statement.ColumnInt64(0); | 459 *to_visit = statement.ColumnInt64(0); |
| 460 if (to_url) | 460 if (to_url) |
| 461 *to_url = GURL(statement.ColumnString(1)); | 461 *to_url = GURL(statement.ColumnString(1)); |
| 462 return true; | 462 return true; |
| 463 } | 463 } |
| 464 | 464 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 // in the middle of redirect chains, hence the transition checks. | 509 // in the middle of redirect chains, hence the transition checks. |
| 510 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 510 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 511 "SELECT MIN(v.visit_time), COUNT(*) " | 511 "SELECT MIN(v.visit_time), COUNT(*) " |
| 512 "FROM visits v INNER JOIN urls u ON v.url = u.id " | 512 "FROM visits v INNER JOIN urls u ON v.url = u.id " |
| 513 "WHERE u.url >= ? AND u.url < ? " | 513 "WHERE u.url >= ? AND u.url < ? " |
| 514 "AND (transition & ?) != 0 " | 514 "AND (transition & ?) != 0 " |
| 515 "AND (transition & ?) NOT IN (?, ?, ?)")); | 515 "AND (transition & ?) NOT IN (?, ?, ?)")); |
| 516 statement.BindString(0, host_query_min); | 516 statement.BindString(0, host_query_min); |
| 517 statement.BindString(1, | 517 statement.BindString(1, |
| 518 host_query_min.substr(0, host_query_min.size() - 1) + '0'); | 518 host_query_min.substr(0, host_query_min.size() - 1) + '0'); |
| 519 statement.BindInt(2, content::PAGE_TRANSITION_CHAIN_END); | 519 statement.BindInt(2, ui::PAGE_TRANSITION_CHAIN_END); |
| 520 statement.BindInt(3, content::PAGE_TRANSITION_CORE_MASK); | 520 statement.BindInt(3, ui::PAGE_TRANSITION_CORE_MASK); |
| 521 statement.BindInt(4, content::PAGE_TRANSITION_AUTO_SUBFRAME); | 521 statement.BindInt(4, ui::PAGE_TRANSITION_AUTO_SUBFRAME); |
| 522 statement.BindInt(5, content::PAGE_TRANSITION_MANUAL_SUBFRAME); | 522 statement.BindInt(5, ui::PAGE_TRANSITION_MANUAL_SUBFRAME); |
| 523 statement.BindInt(6, content::PAGE_TRANSITION_KEYWORD_GENERATED); | 523 statement.BindInt(6, ui::PAGE_TRANSITION_KEYWORD_GENERATED); |
| 524 | 524 |
| 525 if (!statement.Step()) { | 525 if (!statement.Step()) { |
| 526 // We've never been to this page before. | 526 // We've never been to this page before. |
| 527 *count = 0; | 527 *count = 0; |
| 528 return true; | 528 return true; |
| 529 } | 529 } |
| 530 | 530 |
| 531 if (!statement.Succeeded()) | 531 if (!statement.Succeeded()) |
| 532 return false; | 532 return false; |
| 533 | 533 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 | 610 |
| 611 statement.BindInt64(0, max_visits); | 611 statement.BindInt64(0, max_visits); |
| 612 | 612 |
| 613 if (!statement.is_valid()) | 613 if (!statement.is_valid()) |
| 614 return; | 614 return; |
| 615 | 615 |
| 616 while (statement.Step()) { | 616 while (statement.Step()) { |
| 617 BriefVisitInfo info; | 617 BriefVisitInfo info; |
| 618 info.url_id = statement.ColumnInt64(0); | 618 info.url_id = statement.ColumnInt64(0); |
| 619 info.time = base::Time::FromInternalValue(statement.ColumnInt64(1)); | 619 info.time = base::Time::FromInternalValue(statement.ColumnInt64(1)); |
| 620 info.transition = content::PageTransitionFromInt(statement.ColumnInt(2)); | 620 info.transition = ui::PageTransitionFromInt(statement.ColumnInt(2)); |
| 621 result_vector->push_back(info); | 621 result_vector->push_back(info); |
| 622 } | 622 } |
| 623 } | 623 } |
| 624 | 624 |
| 625 } // namespace history | 625 } // namespace history |
| OLD | NEW |