Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: chrome/browser/history/visit_database.cc

Issue 9789001: Changes to add duration into history database. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added a column in visits db instead of a new table Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/message_loop.h" 13 #include "base/message_loop.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/string_number_conversions.h" 15 #include "base/string_number_conversions.h"
16 #include "base/timer.h" 16 #include "base/timer.h"
17 #include "base/stl_util.h" 17 #include "base/stl_util.h"
18 #include "chrome/browser/history/url_database.h" 18 #include "chrome/browser/history/url_database.h"
19 #include "chrome/browser/history/visit_filter.h" 19 #include "chrome/browser/history/visit_filter.h"
20 #include "chrome/common/url_constants.h" 20 #include "chrome/common/url_constants.h"
21 #include "content/public/common/page_transition_types.h" 21 #include "content/public/common/page_transition_types.h"
22 #include "sql/statement.h" 22 #include "sql/statement.h"
23 23
24 // Rows, in order, of the visit table. 24 // Rows, in order, of the visit table.
25 #define HISTORY_VISIT_ROW_FIELDS \ 25 #define HISTORY_VISIT_ROW_FIELDS \
26 " id,url,visit_time,from_visit,transition,segment_id,is_indexed " 26 " id,url,visit_time,from_visit,transition,segment_id,is_indexed," \
GeorgeY 2012/03/27 21:15:57 nit: I think we should have 4 spaces indent here a
Wei Li 2012/03/27 23:01:50 Done.
27 "visit_duration "
27 28
28 namespace history { 29 namespace history {
29 30
30 // Performs analysis of all local browsing data in the visits table to 31 // Performs analysis of all local browsing data in the visits table to
31 // assess the feasibility of performing prerendering on that data. 32 // assess the feasibility of performing prerendering on that data.
32 // Will emulate prerendering based on a simple heuristic: On each 33 // Will emulate prerendering based on a simple heuristic: On each
33 // pageview, pick most likely next page viewed in the next 5 minutes 34 // pageview, pick most likely next page viewed in the next 5 minutes
34 // based on historical data; keep a maximum of 5 prerenders; evict 35 // based on historical data; keep a maximum of 5 prerenders; evict
35 // prerenders older than 5 minutes or based on likelihood. Will report 36 // prerenders older than 5 minutes or based on likelihood. Will report
36 // back hypothetical prerender rate & accuracy via histograms. 37 // back hypothetical prerender rate & accuracy via histograms.
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 visit_analysis_->Init(); 338 visit_analysis_->Init();
338 if (!GetDB().DoesTableExist("visits")) { 339 if (!GetDB().DoesTableExist("visits")) {
339 if (!GetDB().Execute("CREATE TABLE visits(" 340 if (!GetDB().Execute("CREATE TABLE visits("
340 "id INTEGER PRIMARY KEY," 341 "id INTEGER PRIMARY KEY,"
341 "url INTEGER NOT NULL," // key of the URL this corresponds to 342 "url INTEGER NOT NULL," // key of the URL this corresponds to
342 "visit_time INTEGER NOT NULL," 343 "visit_time INTEGER NOT NULL,"
343 "from_visit INTEGER," 344 "from_visit INTEGER,"
344 "transition INTEGER DEFAULT 0 NOT NULL," 345 "transition INTEGER DEFAULT 0 NOT NULL,"
345 "segment_id INTEGER," 346 "segment_id INTEGER,"
346 // True when we have indexed data for this visit. 347 // True when we have indexed data for this visit.
347 "is_indexed BOOLEAN)")) 348 "is_indexed BOOLEAN,"
349 "visit_duration INTEGER DEFAULT 0 NOT NULL)"))
348 return false; 350 return false;
349 } else if (!GetDB().DoesColumnExist("visits", "is_indexed")) { 351 } else {
350 // Old versions don't have the is_indexed column, we can just add that and 352 if (!GetDB().DoesColumnExist("visits", "is_indexed")) {
351 // not worry about different database revisions, since old ones will 353 // Old versions don't have the is_indexed column, we can just add that and
352 // continue to work. 354 // not worry about different database revisions, since old ones will
353 // 355 // continue to work.
354 // TODO(brettw) this should be removed once we think everybody has been 356 //
355 // updated (added early Mar 2008). 357 // TODO(brettw) this should be removed once we think everybody has been
356 if (!GetDB().Execute("ALTER TABLE visits ADD COLUMN is_indexed BOOLEAN")) 358 // updated (added early Mar 2008).
357 return false; 359 if (!GetDB().Execute("ALTER TABLE visits ADD COLUMN is_indexed BOOLEAN"))
360 return false;
361 }
362 if (!GetDB().DoesColumnExist("visits", "visit_duration")) {
GeorgeY 2012/03/27 21:15:57 Why do we need to do here as well in addition to M
Wei Li 2012/03/27 23:01:50 I used this to guard some manual errors such as ve
363 // Old versions don't have the visit_duration column, we can just add that
364 // without worrying about different database revisions since old ones will
365 // continue to work.
366 if (!GetDB().Execute("ALTER TABLE visits "
367 "ADD COLUMN visit_duration INTEGER DEFAULT 0 NOT NULL"))
368 return false;
369 }
358 } 370 }
359 371
360 // Visit source table contains the source information for all the visits. To 372 // Visit source table contains the source information for all the visits. To
361 // save space, we do not record those user browsed visits which would be the 373 // save space, we do not record those user browsed visits which would be the
362 // majority in this table. Only other sources are recorded. 374 // majority in this table. Only other sources are recorded.
363 // Due to the tight relationship between visit_source and visits table, they 375 // Due to the tight relationship between visit_source and visits table, they
364 // should be created and dropped at the same time. 376 // should be created and dropped at the same time.
365 if (!GetDB().DoesTableExist("visit_source")) { 377 if (!GetDB().DoesTableExist("visit_source")) {
366 if (!GetDB().Execute("CREATE TABLE visit_source(" 378 if (!GetDB().Execute("CREATE TABLE visit_source("
367 "id INTEGER PRIMARY KEY,source INTEGER NOT NULL)")) 379 "id INTEGER PRIMARY KEY,source INTEGER NOT NULL)"))
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 // Must be in sync with HISTORY_VISIT_ROW_FIELDS. 412 // Must be in sync with HISTORY_VISIT_ROW_FIELDS.
401 // static 413 // static
402 void VisitDatabase::FillVisitRow(sql::Statement& statement, VisitRow* visit) { 414 void VisitDatabase::FillVisitRow(sql::Statement& statement, VisitRow* visit) {
403 visit->visit_id = statement.ColumnInt64(0); 415 visit->visit_id = statement.ColumnInt64(0);
404 visit->url_id = statement.ColumnInt64(1); 416 visit->url_id = statement.ColumnInt64(1);
405 visit->visit_time = base::Time::FromInternalValue(statement.ColumnInt64(2)); 417 visit->visit_time = base::Time::FromInternalValue(statement.ColumnInt64(2));
406 visit->referring_visit = statement.ColumnInt64(3); 418 visit->referring_visit = statement.ColumnInt64(3);
407 visit->transition = content::PageTransitionFromInt(statement.ColumnInt(4)); 419 visit->transition = content::PageTransitionFromInt(statement.ColumnInt(4));
408 visit->segment_id = statement.ColumnInt64(5); 420 visit->segment_id = statement.ColumnInt64(5);
409 visit->is_indexed = !!statement.ColumnInt(6); 421 visit->is_indexed = !!statement.ColumnInt(6);
422 visit->visit_duration =
423 base::TimeDelta::FromInternalValue(statement.ColumnInt64(7));
410 } 424 }
411 425
412 // static 426 // static
413 bool VisitDatabase::FillVisitVector(sql::Statement& statement, 427 bool VisitDatabase::FillVisitVector(sql::Statement& statement,
414 VisitVector* visits) { 428 VisitVector* visits) {
415 if (!statement.is_valid()) 429 if (!statement.is_valid())
416 return false; 430 return false;
417 431
418 while (statement.Step()) { 432 while (statement.Step()) {
419 history::VisitRow visit; 433 history::VisitRow visit;
420 FillVisitRow(statement, &visit); 434 FillVisitRow(statement, &visit);
421 visits->push_back(visit); 435 visits->push_back(visit);
422 } 436 }
423 437
424 return statement.Succeeded(); 438 return statement.Succeeded();
425 } 439 }
426 440
427 VisitID VisitDatabase::AddVisit(VisitRow* visit, VisitSource source) { 441 VisitID VisitDatabase::AddVisit(VisitRow* visit, VisitSource source) {
428 visit_analysis_->AddVisit(visit); 442 visit_analysis_->AddVisit(visit);
429 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 443 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
430 "INSERT INTO visits " 444 "INSERT INTO visits "
431 "(url, visit_time, from_visit, transition, segment_id, is_indexed) " 445 "(url, visit_time, from_visit, transition, segment_id, is_indexed, "
432 "VALUES (?,?,?,?,?,?)")); 446 "visit_duration) VALUES (?,?,?,?,?,?,?)"));
433 statement.BindInt64(0, visit->url_id); 447 statement.BindInt64(0, visit->url_id);
434 statement.BindInt64(1, visit->visit_time.ToInternalValue()); 448 statement.BindInt64(1, visit->visit_time.ToInternalValue());
435 statement.BindInt64(2, visit->referring_visit); 449 statement.BindInt64(2, visit->referring_visit);
436 statement.BindInt64(3, visit->transition); 450 statement.BindInt64(3, visit->transition);
437 statement.BindInt64(4, visit->segment_id); 451 statement.BindInt64(4, visit->segment_id);
438 statement.BindInt64(5, visit->is_indexed); 452 statement.BindInt64(5, visit->is_indexed);
453 statement.BindInt64(6, visit->visit_duration.ToInternalValue());
439 454
440 if (!statement.Run()) { 455 if (!statement.Run()) {
441 VLOG(0) << "Failed to execute visit insert statement: " 456 VLOG(0) << "Failed to execute visit insert statement: "
442 << "url_id = " << visit->url_id; 457 << "url_id = " << visit->url_id;
443 return 0; 458 return 0;
444 } 459 }
445 460
446 visit->visit_id = GetDB().GetLastInsertRowId(); 461 visit->visit_id = GetDB().GetLastInsertRowId();
447 462
448 if (source != SOURCE_BROWSED) { 463 if (source != SOURCE_BROWSED) {
449 // Record the source of this visit when it is not browsed. 464 // Record the source of this visit when it is not browsed.
450 sql::Statement statement1(GetDB().GetCachedStatement(SQL_FROM_HERE, 465 sql::Statement statement1(GetDB().GetCachedStatement(SQL_FROM_HERE,
451 "INSERT INTO visit_source (id, source) VALUES (?,?)")); 466 "INSERT INTO visit_source (id, source) VALUES (?,?)"));
452 statement1.BindInt64(0, visit->visit_id); 467 statement1.BindInt64(0, visit->visit_id);
453 statement1.BindInt64(1, source); 468 statement1.BindInt64(1, source);
454 469
455 if (!statement1.Run()) { 470 if (!statement1.Run()) {
456 VLOG(0) << "Failed to execute visit_source insert statement: " 471 VLOG(0) << "Failed to execute visit_source insert statement: "
457 << "url_id = " << visit->visit_id; 472 << "id = " << visit->visit_id;
458 return 0; 473 return 0;
459 } 474 }
460 } 475 }
461 476
462 return visit->visit_id; 477 return visit->visit_id;
463 } 478 }
464 479
465 void VisitDatabase::DeleteVisit(const VisitRow& visit) { 480 void VisitDatabase::DeleteVisit(const VisitRow& visit) {
466 // Patch around this visit. Any visits that this went to will now have their 481 // Patch around this visit. Any visits that this went to will now have their
467 // "source" be the deleted visit's source. 482 // "source" be the deleted visit's source.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 } 522 }
508 523
509 bool VisitDatabase::UpdateVisitRow(const VisitRow& visit) { 524 bool VisitDatabase::UpdateVisitRow(const VisitRow& visit) {
510 // Don't store inconsistent data to the database. 525 // Don't store inconsistent data to the database.
511 DCHECK_NE(visit.visit_id, visit.referring_visit); 526 DCHECK_NE(visit.visit_id, visit.referring_visit);
512 if (visit.visit_id == visit.referring_visit) 527 if (visit.visit_id == visit.referring_visit)
513 return false; 528 return false;
514 529
515 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 530 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
516 "UPDATE visits SET " 531 "UPDATE visits SET "
517 "url=?,visit_time=?,from_visit=?,transition=?,segment_id=?,is_indexed=? " 532 "url=?,visit_time=?,from_visit=?,transition=?,segment_id=?,is_indexed=?,"
518 "WHERE id=?")); 533 "visit_duration=? WHERE id=?"));
519 statement.BindInt64(0, visit.url_id); 534 statement.BindInt64(0, visit.url_id);
520 statement.BindInt64(1, visit.visit_time.ToInternalValue()); 535 statement.BindInt64(1, visit.visit_time.ToInternalValue());
521 statement.BindInt64(2, visit.referring_visit); 536 statement.BindInt64(2, visit.referring_visit);
522 statement.BindInt64(3, visit.transition); 537 statement.BindInt64(3, visit.transition);
523 statement.BindInt64(4, visit.segment_id); 538 statement.BindInt64(4, visit.segment_id);
524 statement.BindInt64(5, visit.is_indexed); 539 statement.BindInt64(5, visit.is_indexed);
525 statement.BindInt64(6, visit.visit_id); 540 statement.BindInt64(6, visit.visit_duration.ToInternalValue());
541 statement.BindInt64(7, visit.visit_id);
526 542
527 return statement.Run(); 543 return statement.Run();
528 } 544 }
529 545
530 bool VisitDatabase::GetVisitsForURL(URLID url_id, VisitVector* visits) { 546 bool VisitDatabase::GetVisitsForURL(URLID url_id, VisitVector* visits) {
531 visits->clear(); 547 visits->clear();
532 548
533 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 549 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
534 "SELECT" HISTORY_VISIT_ROW_FIELDS 550 "SELECT" HISTORY_VISIT_ROW_FIELDS
535 "FROM visits " 551 "FROM visits "
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 851
836 // Get the source entries out of the query result. 852 // Get the source entries out of the query result.
837 while (statement.Step()) { 853 while (statement.Step()) {
838 std::pair<VisitID, VisitSource> source_entry(statement.ColumnInt64(0), 854 std::pair<VisitID, VisitSource> source_entry(statement.ColumnInt64(0),
839 static_cast<VisitSource>(statement.ColumnInt(1))); 855 static_cast<VisitSource>(statement.ColumnInt(1)));
840 sources->insert(source_entry); 856 sources->insert(source_entry);
841 } 857 }
842 } 858 }
843 } 859 }
844 860
861 bool VisitDatabase::MigrateVisitsWithoutDuration() {
862 if (!GetDB().DoesTableExist("visits")) {
863 NOTREACHED() << " Visits table should exist before migration";
864 return false;
865 }
866
867 if (!GetDB().DoesColumnExist("visits", "visit_duration")) {
868 // Old versions don't have the visit_duration column, we modify the table
869 // to add that field.
870 if (!GetDB().Execute(
871 "ALTER TABLE visits ADD COLUMN visit_duration DEFAULT 0 NOT NULL"))
872 return false;
873 }
874 return true;
875 }
876
845 } // namespace history 877 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698