Index: chrome/browser/history/visit_database.cc |
diff --git a/chrome/browser/history/visit_database.cc b/chrome/browser/history/visit_database.cc |
index 2280a1b65df4ae965995d9be1ee86e54764cc685..252deccb64f03e9997160849b5b703088f029553 100644 |
--- a/chrome/browser/history/visit_database.cc |
+++ b/chrome/browser/history/visit_database.cc |
@@ -368,6 +368,16 @@ bool VisitDatabase::InitVisitTable() { |
return false; |
} |
+ // Visit details table contains some extra details about a visit such as |
+ // the visit duration. In the future, more information such as active |
+ // duration or language can be added too. |
+ if (!GetDB().DoesTableExist("visit_details")) { |
+ if (!GetDB().Execute("CREATE TABLE visit_details(" |
+ "id INTEGER PRIMARY KEY," |
+ "duration INTEGER DEFAULT 0 NOT NULL)")) |
+ return false; |
+ } |
+ |
// Index over url so we can quickly find visits for a page. |
if (!GetDB().Execute( |
"CREATE INDEX IF NOT EXISTS visits_url_index ON visits (url)")) |
@@ -393,6 +403,7 @@ bool VisitDatabase::InitVisitTable() { |
bool VisitDatabase::DropVisitTable() { |
// This will also drop the indices over the table. |
return |
+ GetDB().Execute("DROP TABLE IF EXISTS visit_details") && |
GetDB().Execute("DROP TABLE IF EXISTS visit_source") && |
GetDB().Execute("DROP TABLE visits"); |
} |
@@ -454,11 +465,23 @@ VisitID VisitDatabase::AddVisit(VisitRow* visit, VisitSource source) { |
if (!statement1.Run()) { |
VLOG(0) << "Failed to execute visit_source insert statement: " |
- << "url_id = " << visit->visit_id; |
+ << "id = " << visit->visit_id; |
return 0; |
} |
} |
+ // Add the visit into visit_details table as well. |
+ sql::Statement statement1(GetDB().GetCachedStatement(SQL_FROM_HERE, |
+ "INSERT INTO visit_details (id, duration) VALUES (?,?)")); |
+ statement1.BindInt64(0, visit->visit_id); |
+ statement1.BindInt64(1, 0); |
+ |
+ if (!statement1.Run()) { |
+ VLOG(0) << "Failed to execute visit_details insert statement: " |
+ << "id = " << visit->visit_id; |
+ return 0; |
+ } |
+ |
return visit->visit_id; |
} |
@@ -486,6 +509,15 @@ void VisitDatabase::DeleteVisit(const VisitRow& visit) { |
"DELETE FROM visit_source WHERE id=?")); |
del.BindInt64(0, visit.visit_id); |
del.Run(); |
+ |
+ // Delete the entry in visit_details table as well. |
+ // We don't care about archiving details information about visits. We will |
+ // simply delete all the information for either archived or deleted visits |
+ // when they are removed from visits database. |
+ del.Assign(GetDB().GetCachedStatement(SQL_FROM_HERE, |
+ "DELETE FROM visit_details WHERE id=?")); |
+ del.BindInt64(0, visit.visit_id); |
+ del.Run(); |
} |
bool VisitDatabase::GetRowForVisit(VisitID visit_id, VisitRow* out_visit) { |
@@ -842,4 +874,51 @@ void VisitDatabase::GetVisitsSource(const VisitVector& visits, |
} |
} |
+bool VisitDatabase::UpdateVisitDetails(VisitID visit_id, |
+ const base::TimeDelta duration) { |
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
+ "UPDATE visit_details SET duration=? WHERE id=?")); |
+ statement.BindInt64(0, duration.ToInternalValue()); |
+ statement.BindInt64(1, visit_id); |
+ |
+ return statement.Run(); |
+} |
+ |
+void VisitDatabase::GetVisitDetails(const VisitVector& visits, |
+ VisitDetailMap* details) { |
+ DCHECK(details); |
+ details->clear(); |
+ |
+ // We query the details in batch. Here defines the batch size. |
+ const size_t batch_size = 500; |
+ size_t visits_size = visits.size(); |
+ |
+ size_t start_index = 0, end_index = 0; |
+ while (end_index < visits_size) { |
+ start_index = end_index; |
+ end_index = end_index + batch_size < visits_size ? end_index + batch_size |
+ : visits_size; |
+ |
+ // Compose the sql statement with a list of ids. |
+ std::string sql = "SELECT id,duration FROM visit_details "; |
+ sql.append("WHERE id IN ("); |
+ // Append all the ids in the statement. |
+ for (size_t j = start_index; j < end_index; j++) { |
+ if (j != start_index) |
+ sql.push_back(','); |
+ sql.append(base::Int64ToString(visits[j].visit_id)); |
+ } |
+ sql.append(") ORDER BY id"); |
+ sql::Statement statement(GetDB().GetUniqueStatement(sql.c_str())); |
+ |
+ // Get the source entries out of the query result. |
+ while (statement.Step()) { |
+ VisitDetailRow row = |
+ {base::TimeDelta::FromInternalValue(statement.ColumnInt64(1))}; |
+ std::pair<VisitID, VisitDetailRow> entry(statement.ColumnInt64(0), row); |
+ details->insert(entry); |
+ } |
+ } |
+} |
+ |
} // namespace history |