15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/android/visit_sql_handler.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_database.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace history {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The interesting columns of this handler.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const HistoryAndBookmarkRow::ColumnID kInterestingColumns[] = {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HistoryAndBookmarkRow::CREATED, HistoryAndBookmarkRow::VISIT_COUNT,
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HistoryAndBookmarkRow::LAST_VISIT_TIME };
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VisitSQLHandler::VisitSQLHandler(HistoryDatabase* history_db)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : SQLHandler(kInterestingColumns, arraysize(kInterestingColumns)),
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history_db_(history_db) {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VisitSQLHandler::~VisitSQLHandler() {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The created time is updated according the given |row|.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We simulate updating created time by
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a. Remove all visits.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// b. Insert a new visit which has visit time same as created time.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// c. Insert the number of visits according the visit count in urls table.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Visit row is insertted/removed to keep consistent with urls table.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a. If the visit count in urls table is less than the visit rows in visit
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    table, all existent visits will be removed. The new visits will be
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    insertted according the value in urls table.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// b. Otherwise, only add the increased number of visit count.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VisitSQLHandler::Update(const HistoryAndBookmarkRow& row,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const TableIDRows& ids_set) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (TableIDRows::const_iterator id = ids_set.begin();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       id != ids_set.end(); ++id) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VisitVector visits;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!history_db_->GetVisitsForURL(id->url_id, &visits))
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int visit_count_in_table = visits.size();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLRow url_row;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!history_db_->GetURLRow(id->url_id, &url_row))
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int visit_count_needed = url_row.visit_count();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (visit_count_needed == 0)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return Delete(ids_set);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If created time is updated or new visit count is less than the current
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // one, delete all visit rows.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (row.is_value_set_explicitly(HistoryAndBookmarkRow::CREATED) ||
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        visit_count_in_table > visit_count_needed) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!DeleteVisitsForURL(id->url_id))
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      visit_count_in_table = 0;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (row.is_value_set_explicitly(HistoryAndBookmarkRow::CREATED) &&
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        visit_count_needed > 0) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!AddVisit(id->url_id, row.created()))
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      visit_count_in_table++;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!AddVisitRows(id->url_id, visit_count_needed - visit_count_in_table,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       url_row.last_visit()))
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VisitSQLHandler::Insert(HistoryAndBookmarkRow* row) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(row->is_value_set_explicitly(HistoryAndBookmarkRow::URL_ID));
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow url_row;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!history_db_->GetURLRow(row->url_id(), &url_row))
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int visit_count = url_row.visit_count();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (visit_count == 0)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a row if the last visit time is different from created time.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (row->is_value_set_explicitly(HistoryAndBookmarkRow::CREATED) &&
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      row->created() != url_row.last_visit() && visit_count > 0) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!AddVisit(row->url_id(), row->created()))
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visit_count--;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!AddVisitRows(row->url_id(), visit_count, url_row.last_visit()))
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VisitSQLHandler::Delete(const TableIDRows& ids_set) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (TableIDRows::const_iterator ids = ids_set.begin();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ids != ids_set.end(); ++ids) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeleteVisitsForURL(ids->url_id);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VisitSQLHandler::AddVisit(URLID url_id, const Time& visit_time) {
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO : Is 'ui::PAGE_TRANSITION_AUTO_BOOKMARK' proper?
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // if not, a new ui::PageTransition type will need.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitRow visit_row(url_id, visit_time, 0,
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     ui::PAGE_TRANSITION_AUTO_BOOKMARK, 0);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return history_db_->AddVisit(&visit_row, SOURCE_BROWSED);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VisitSQLHandler::AddVisitRows(URLID url_id,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int visit_count,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const Time& last_visit_time) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 last_update_value = last_visit_time.ToInternalValue();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < visit_count; i++) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!AddVisit(url_id, Time::FromInternalValue(last_update_value - i)))
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VisitSQLHandler::DeleteVisitsForURL(URLID url_id) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitVector visits;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!history_db_->GetVisitsForURL(url_id, &visits))
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (VisitVector::const_iterator v = visits.begin(); v != visits.end(); ++v) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_db_->DeleteVisit(*v);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace history.
146