| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/string_number_conversions.h" | 13 #include "base/string_number_conversions.h" |
| 14 #include "chrome/browser/history/url_database.h" | 14 #include "chrome/browser/history/url_database.h" |
| 15 #include "chrome/common/url_constants.h" | 15 #include "chrome/common/url_constants.h" |
| 16 #include "content/common/page_transition_types.h" | 16 #include "content/public/common/page_transition_types.h" |
| 17 #include "sql/statement.h" | 17 #include "sql/statement.h" |
| 18 | 18 |
| 19 // Rows, in order, of the visit table. | 19 // Rows, in order, of the visit table. |
| 20 #define HISTORY_VISIT_ROW_FIELDS \ | 20 #define HISTORY_VISIT_ROW_FIELDS \ |
| 21 " id,url,visit_time,from_visit,transition,segment_id,is_indexed " | 21 " id,url,visit_time,from_visit,transition,segment_id,is_indexed " |
| 22 | 22 |
| 23 namespace history { | 23 namespace history { |
| 24 | 24 |
| 25 VisitDatabase::VisitDatabase() { | 25 VisitDatabase::VisitDatabase() { |
| 26 } | 26 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 return GetDB().Execute("DROP TABLE visits"); | 84 return GetDB().Execute("DROP TABLE visits"); |
| 85 } | 85 } |
| 86 | 86 |
| 87 // Must be in sync with HISTORY_VISIT_ROW_FIELDS. | 87 // Must be in sync with HISTORY_VISIT_ROW_FIELDS. |
| 88 // static | 88 // static |
| 89 void VisitDatabase::FillVisitRow(sql::Statement& statement, VisitRow* visit) { | 89 void VisitDatabase::FillVisitRow(sql::Statement& statement, VisitRow* visit) { |
| 90 visit->visit_id = statement.ColumnInt64(0); | 90 visit->visit_id = statement.ColumnInt64(0); |
| 91 visit->url_id = statement.ColumnInt64(1); | 91 visit->url_id = statement.ColumnInt64(1); |
| 92 visit->visit_time = base::Time::FromInternalValue(statement.ColumnInt64(2)); | 92 visit->visit_time = base::Time::FromInternalValue(statement.ColumnInt64(2)); |
| 93 visit->referring_visit = statement.ColumnInt64(3); | 93 visit->referring_visit = statement.ColumnInt64(3); |
| 94 visit->transition = PageTransition::FromInt(statement.ColumnInt(4)); | 94 visit->transition = content::PageTransitionFromInt(statement.ColumnInt(4)); |
| 95 visit->segment_id = statement.ColumnInt64(5); | 95 visit->segment_id = statement.ColumnInt64(5); |
| 96 visit->is_indexed = !!statement.ColumnInt(6); | 96 visit->is_indexed = !!statement.ColumnInt(6); |
| 97 } | 97 } |
| 98 | 98 |
| 99 // static | 99 // static |
| 100 void VisitDatabase::FillVisitVector(sql::Statement& statement, | 100 void VisitDatabase::FillVisitVector(sql::Statement& statement, |
| 101 VisitVector* visits) { | 101 VisitVector* visits) { |
| 102 while (statement.Step()) { | 102 while (statement.Step()) { |
| 103 history::VisitRow visit; | 103 history::VisitRow visit; |
| 104 FillVisitRow(statement, &visit); | 104 FillVisitRow(statement, &visit); |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 statement.BindInt64(2, | 278 statement.BindInt64(2, |
| 279 max_results ? max_results : std::numeric_limits<int64>::max()); | 279 max_results ? max_results : std::numeric_limits<int64>::max()); |
| 280 | 280 |
| 281 FillVisitVector(statement, visits); | 281 FillVisitVector(statement, visits); |
| 282 } | 282 } |
| 283 | 283 |
| 284 void VisitDatabase::GetVisitsInRangeForTransition( | 284 void VisitDatabase::GetVisitsInRangeForTransition( |
| 285 base::Time begin_time, | 285 base::Time begin_time, |
| 286 base::Time end_time, | 286 base::Time end_time, |
| 287 int max_results, | 287 int max_results, |
| 288 PageTransition::Type transition, | 288 content::PageTransition transition, |
| 289 VisitVector* visits) { | 289 VisitVector* visits) { |
| 290 DCHECK(visits); | 290 DCHECK(visits); |
| 291 visits->clear(); | 291 visits->clear(); |
| 292 | 292 |
| 293 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 293 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 294 "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits " | 294 "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits " |
| 295 "WHERE visit_time >= ? AND visit_time < ? " | 295 "WHERE visit_time >= ? AND visit_time < ? " |
| 296 "AND (transition & ?) == ?" | 296 "AND (transition & ?) == ?" |
| 297 "ORDER BY visit_time LIMIT ?")); | 297 "ORDER BY visit_time LIMIT ?")); |
| 298 if (!statement) | 298 if (!statement) |
| 299 return; | 299 return; |
| 300 | 300 |
| 301 // See GetVisibleVisitsInRange for more info on how these times are bound. | 301 // See GetVisibleVisitsInRange for more info on how these times are bound. |
| 302 int64 end = end_time.ToInternalValue(); | 302 int64 end = end_time.ToInternalValue(); |
| 303 statement.BindInt64(0, begin_time.ToInternalValue()); | 303 statement.BindInt64(0, begin_time.ToInternalValue()); |
| 304 statement.BindInt64(1, end ? end : std::numeric_limits<int64>::max()); | 304 statement.BindInt64(1, end ? end : std::numeric_limits<int64>::max()); |
| 305 statement.BindInt(2, PageTransition::CORE_MASK); | 305 statement.BindInt(2, content::PAGE_TRANSITION_CORE_MASK); |
| 306 statement.BindInt(3, transition); | 306 statement.BindInt(3, transition); |
| 307 statement.BindInt64(4, | 307 statement.BindInt64(4, |
| 308 max_results ? max_results : std::numeric_limits<int64>::max()); | 308 max_results ? max_results : std::numeric_limits<int64>::max()); |
| 309 | 309 |
| 310 FillVisitVector(statement, visits); | 310 FillVisitVector(statement, visits); |
| 311 } | 311 } |
| 312 | 312 |
| 313 void VisitDatabase::GetVisibleVisitsInRange(base::Time begin_time, | 313 void VisitDatabase::GetVisibleVisitsInRange(base::Time begin_time, |
| 314 base::Time end_time, | 314 base::Time end_time, |
| 315 int max_count, | 315 int max_count, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 326 "ORDER BY visit_time DESC, id DESC")); | 326 "ORDER BY visit_time DESC, id DESC")); |
| 327 if (!statement) | 327 if (!statement) |
| 328 return; | 328 return; |
| 329 | 329 |
| 330 // Note that we use min/max values for querying unlimited ranges of time using | 330 // Note that we use min/max values for querying unlimited ranges of time using |
| 331 // the same statement. Since the time has an index, this will be about the | 331 // the same statement. Since the time has an index, this will be about the |
| 332 // same amount of work as just doing a query for everything with no qualifier. | 332 // same amount of work as just doing a query for everything with no qualifier. |
| 333 int64 end = end_time.ToInternalValue(); | 333 int64 end = end_time.ToInternalValue(); |
| 334 statement.BindInt64(0, begin_time.ToInternalValue()); | 334 statement.BindInt64(0, begin_time.ToInternalValue()); |
| 335 statement.BindInt64(1, end ? end : std::numeric_limits<int64>::max()); | 335 statement.BindInt64(1, end ? end : std::numeric_limits<int64>::max()); |
| 336 statement.BindInt(2, PageTransition::CHAIN_END); | 336 statement.BindInt(2, content::PAGE_TRANSITION_CHAIN_END); |
| 337 statement.BindInt(3, PageTransition::CORE_MASK); | 337 statement.BindInt(3, content::PAGE_TRANSITION_CORE_MASK); |
| 338 statement.BindInt(4, PageTransition::AUTO_SUBFRAME); | 338 statement.BindInt(4, content::PAGE_TRANSITION_AUTO_SUBFRAME); |
| 339 statement.BindInt(5, PageTransition::MANUAL_SUBFRAME); | 339 statement.BindInt(5, content::PAGE_TRANSITION_MANUAL_SUBFRAME); |
| 340 statement.BindInt(6, PageTransition::KEYWORD_GENERATED); | 340 statement.BindInt(6, content::PAGE_TRANSITION_KEYWORD_GENERATED); |
| 341 | 341 |
| 342 std::set<URLID> found_urls; | 342 std::set<URLID> found_urls; |
| 343 while (statement.Step()) { | 343 while (statement.Step()) { |
| 344 VisitRow visit; | 344 VisitRow visit; |
| 345 FillVisitRow(statement, &visit); | 345 FillVisitRow(statement, &visit); |
| 346 // Make sure the URL this visit corresponds to is unique. | 346 // Make sure the URL this visit corresponds to is unique. |
| 347 if (found_urls.find(visit.url_id) != found_urls.end()) | 347 if (found_urls.find(visit.url_id) != found_urls.end()) |
| 348 continue; | 348 continue; |
| 349 found_urls.insert(visit.url_id); | 349 found_urls.insert(visit.url_id); |
| 350 visits->push_back(visit); | 350 visits->push_back(visit); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 GURL* to_url) { | 404 GURL* to_url) { |
| 405 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 405 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 406 "SELECT v.id,u.url " | 406 "SELECT v.id,u.url " |
| 407 "FROM visits v JOIN urls u ON v.url = u.id " | 407 "FROM visits v JOIN urls u ON v.url = u.id " |
| 408 "WHERE v.from_visit = ? " | 408 "WHERE v.from_visit = ? " |
| 409 "AND (v.transition & ?) != 0")); // IS_REDIRECT_MASK | 409 "AND (v.transition & ?) != 0")); // IS_REDIRECT_MASK |
| 410 if (!statement) | 410 if (!statement) |
| 411 return false; | 411 return false; |
| 412 | 412 |
| 413 statement.BindInt64(0, from_visit); | 413 statement.BindInt64(0, from_visit); |
| 414 statement.BindInt(1, PageTransition::IS_REDIRECT_MASK); | 414 statement.BindInt(1, content::PAGE_TRANSITION_IS_REDIRECT_MASK); |
| 415 | 415 |
| 416 if (!statement.Step()) | 416 if (!statement.Step()) |
| 417 return false; // No redirect from this visit. | 417 return false; // No redirect from this visit. |
| 418 if (to_visit) | 418 if (to_visit) |
| 419 *to_visit = statement.ColumnInt64(0); | 419 *to_visit = statement.ColumnInt64(0); |
| 420 if (to_url) | 420 if (to_url) |
| 421 *to_url = GURL(statement.ColumnString(1)); | 421 *to_url = GURL(statement.ColumnString(1)); |
| 422 return true; | 422 return true; |
| 423 } | 423 } |
| 424 | 424 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 "FROM visits v INNER JOIN urls u ON v.url = u.id " | 471 "FROM visits v INNER JOIN urls u ON v.url = u.id " |
| 472 "WHERE u.url >= ? AND u.url < ? " | 472 "WHERE u.url >= ? AND u.url < ? " |
| 473 "AND (transition & ?) != 0 " | 473 "AND (transition & ?) != 0 " |
| 474 "AND (transition & ?) NOT IN (?, ?, ?)")); | 474 "AND (transition & ?) NOT IN (?, ?, ?)")); |
| 475 if (!statement) | 475 if (!statement) |
| 476 return false; | 476 return false; |
| 477 | 477 |
| 478 statement.BindString(0, host_query_min); | 478 statement.BindString(0, host_query_min); |
| 479 statement.BindString(1, | 479 statement.BindString(1, |
| 480 host_query_min.substr(0, host_query_min.size() - 1) + '0'); | 480 host_query_min.substr(0, host_query_min.size() - 1) + '0'); |
| 481 statement.BindInt(2, PageTransition::CHAIN_END); | 481 statement.BindInt(2, content::PAGE_TRANSITION_CHAIN_END); |
| 482 statement.BindInt(3, PageTransition::CORE_MASK); | 482 statement.BindInt(3, content::PAGE_TRANSITION_CORE_MASK); |
| 483 statement.BindInt(4, PageTransition::AUTO_SUBFRAME); | 483 statement.BindInt(4, content::PAGE_TRANSITION_AUTO_SUBFRAME); |
| 484 statement.BindInt(5, PageTransition::MANUAL_SUBFRAME); | 484 statement.BindInt(5, content::PAGE_TRANSITION_MANUAL_SUBFRAME); |
| 485 statement.BindInt(6, PageTransition::KEYWORD_GENERATED); | 485 statement.BindInt(6, content::PAGE_TRANSITION_KEYWORD_GENERATED); |
| 486 | 486 |
| 487 if (!statement.Step()) { | 487 if (!statement.Step()) { |
| 488 // We've never been to this page before. | 488 // We've never been to this page before. |
| 489 *count = 0; | 489 *count = 0; |
| 490 return true; | 490 return true; |
| 491 } | 491 } |
| 492 | 492 |
| 493 *first_visit = base::Time::FromInternalValue(statement.ColumnInt64(0)); | 493 *first_visit = base::Time::FromInternalValue(statement.ColumnInt64(0)); |
| 494 *count = statement.ColumnInt(1); | 494 *count = statement.ColumnInt(1); |
| 495 return true; | 495 return true; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 // Get the source entries out of the query result. | 538 // Get the source entries out of the query result. |
| 539 while (statement.Step()) { | 539 while (statement.Step()) { |
| 540 std::pair<VisitID, VisitSource> source_entry(statement.ColumnInt64(0), | 540 std::pair<VisitID, VisitSource> source_entry(statement.ColumnInt64(0), |
| 541 static_cast<VisitSource>(statement.ColumnInt(1))); | 541 static_cast<VisitSource>(statement.ColumnInt(1))); |
| 542 sources->insert(source_entry); | 542 sources->insert(source_entry); |
| 543 } | 543 } |
| 544 } | 544 } |
| 545 } | 545 } |
| 546 | 546 |
| 547 } // namespace history | 547 } // namespace history |
| OLD | NEW |