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
3 // found in the LICENSE file.
5 #include "chrome/browser/history/android/visit_sql_handler.h"
7 #include "base/logging.h"
8 #include "chrome/browser/history/history_database.h"
16 // The interesting columns of this handler.
17 const HistoryAndBookmarkRow::ColumnID kInterestingColumns[] = {
18 HistoryAndBookmarkRow::CREATED, HistoryAndBookmarkRow::VISIT_COUNT,
19 HistoryAndBookmarkRow::LAST_VISIT_TIME };
23 VisitSQLHandler::VisitSQLHandler(HistoryDatabase* history_db)
24 : SQLHandler(kInterestingColumns, arraysize(kInterestingColumns)),
25 history_db_(history_db) {
28 VisitSQLHandler::~VisitSQLHandler() {
31 // The created time is updated according the given |row|.
32 // We simulate updating created time by
33 // a. Remove all visits.
34 // b. Insert a new visit which has visit time same as created time.
35 // c. Insert the number of visits according the visit count in urls table.
37 // Visit row is insertted/removed to keep consistent with urls table.
38 // a. If the visit count in urls table is less than the visit rows in visit
39 // table, all existent visits will be removed. The new visits will be
40 // insertted according the value in urls table.
41 // b. Otherwise, only add the increased number of visit count.
42 bool VisitSQLHandler::Update(const HistoryAndBookmarkRow& row,
43 const TableIDRows& ids_set) {
44 for (TableIDRows::const_iterator id = ids_set.begin();
45 id != ids_set.end(); ++id) {
47 if (!history_db_->GetVisitsForURL(id->url_id, &visits))
49 int visit_count_in_table = visits.size();
51 if (!history_db_->GetURLRow(id->url_id, &url_row))
53 int visit_count_needed = url_row.visit_count();
55 if (visit_count_needed == 0)
56 return Delete(ids_set);
58 // If created time is updated or new visit count is less than the current
59 // one, delete all visit rows.
60 if (row.is_value_set_explicitly(HistoryAndBookmarkRow::CREATED) ||
61 visit_count_in_table > visit_count_needed) {
62 if (!DeleteVisitsForURL(id->url_id))
64 visit_count_in_table = 0;
67 if (row.is_value_set_explicitly(HistoryAndBookmarkRow::CREATED) &&
68 visit_count_needed > 0) {
69 if (!AddVisit(id->url_id, row.created()))
71 visit_count_in_table++;
74 if (!AddVisitRows(id->url_id, visit_count_needed - visit_count_in_table,
75 url_row.last_visit()))
81 bool VisitSQLHandler::Insert(HistoryAndBookmarkRow* row) {
82 DCHECK(row->is_value_set_explicitly(HistoryAndBookmarkRow::URL_ID));
85 if (!history_db_->GetURLRow(row->url_id(), &url_row))
88 int visit_count = url_row.visit_count();
93 // Add a row if the last visit time is different from created time.
94 if (row->is_value_set_explicitly(HistoryAndBookmarkRow::CREATED) &&
95 row->created() != url_row.last_visit() && visit_count > 0) {
96 if (!AddVisit(row->url_id(), row->created()))
101 if (!AddVisitRows(row->url_id(), visit_count, url_row.last_visit()))
107 bool VisitSQLHandler::Delete(const TableIDRows& ids_set) {
108 for (TableIDRows::const_iterator ids = ids_set.begin();
109 ids != ids_set.end(); ++ids) {
110 DeleteVisitsForURL(ids->url_id);
115 bool VisitSQLHandler::AddVisit(URLID url_id, const Time& visit_time) {
116 // TODO : Is 'content::PAGE_TRANSITION_AUTO_BOOKMARK' proper?
117 // if not, a new content::PageTransition type will need.
118 VisitRow visit_row(url_id, visit_time, 0,
119 content::PAGE_TRANSITION_AUTO_BOOKMARK, 0);
120 return history_db_->AddVisit(&visit_row, SOURCE_BROWSED);
123 bool VisitSQLHandler::AddVisitRows(URLID url_id,
125 const Time& last_visit_time) {
126 int64 last_update_value = last_visit_time.ToInternalValue();
127 for (int i = 0; i < visit_count; i++) {
128 if (!AddVisit(url_id, Time::FromInternalValue(last_update_value - i)))
134 bool VisitSQLHandler::DeleteVisitsForURL(URLID url_id) {
136 if (!history_db_->GetVisitsForURL(url_id, &visits))
139 for (VisitVector::const_iterator v = visits.begin(); v != visits.end(); ++v) {
140 history_db_->DeleteVisit(*v);
145 } // namespace history.