Home | History | Annotate | Download | only in android
      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.
      4 
      5 #include "chrome/browser/history/android/urls_sql_handler.h"
      6 
      7 #include "base/logging.h"
      8 #include "chrome/browser/history/history_database.h"
      9 
     10 using base::Time;
     11 
     12 namespace history {
     13 
     14 namespace {
     15 
     16 const HistoryAndBookmarkRow::ColumnID kInterestingColumns[] = {
     17     HistoryAndBookmarkRow::URL, HistoryAndBookmarkRow::VISIT_COUNT,
     18     HistoryAndBookmarkRow::TITLE, HistoryAndBookmarkRow::LAST_VISIT_TIME };
     19 
     20 }  // namespace
     21 
     22 UrlsSQLHandler::UrlsSQLHandler(HistoryDatabase* history_db)
     23     : SQLHandler(kInterestingColumns, arraysize(kInterestingColumns)),
     24       history_db_(history_db) {
     25 }
     26 
     27 UrlsSQLHandler:: ~UrlsSQLHandler() {
     28 }
     29 
     30 bool UrlsSQLHandler::Insert(HistoryAndBookmarkRow* row) {
     31   URLRow url_row(row->url());
     32 
     33   URLID id = history_db_->GetRowForURL(row->url(), &url_row);
     34   if (id) {
     35     LOG(ERROR) << "AndroidProviderBackend::Insert Urls; url exists.";
     36     return false; // We already has this row.
     37   }
     38 
     39   if (row->is_value_set_explicitly(HistoryAndBookmarkRow::TITLE))
     40     url_row.set_title(row->title());
     41 
     42   if (row->is_value_set_explicitly(HistoryAndBookmarkRow::LAST_VISIT_TIME))
     43     url_row.set_last_visit(row->last_visit_time());
     44 
     45   if (row->is_value_set_explicitly(HistoryAndBookmarkRow::VISIT_COUNT))
     46     url_row.set_visit_count(row->visit_count());
     47 
     48   // Adjust the last_visit_time if it not set.
     49   if (!row->is_value_set_explicitly(HistoryAndBookmarkRow::LAST_VISIT_TIME)) {
     50     if (row->is_value_set_explicitly(HistoryAndBookmarkRow::CREATED))
     51       url_row.set_last_visit(row->created());
     52     else if (row->is_value_set_explicitly(HistoryAndBookmarkRow::VISIT_COUNT))
     53       url_row.set_last_visit(Time::Now());
     54   }
     55 
     56   // Adjust the visit_count if it not set.
     57   if (!row->is_value_set_explicitly(HistoryAndBookmarkRow::VISIT_COUNT)) {
     58     int visit_count = 0;
     59     if (row->is_value_set_explicitly(HistoryAndBookmarkRow::CREATED) &&
     60         row->is_value_set_explicitly(HistoryAndBookmarkRow::LAST_VISIT_TIME) &&
     61         row->last_visit_time() == row->created()) {
     62       visit_count = 1;
     63     } else {
     64       if (row->is_value_set_explicitly(HistoryAndBookmarkRow::CREATED))
     65         visit_count++;
     66       if (row->is_value_set_explicitly(HistoryAndBookmarkRow::LAST_VISIT_TIME))
     67         visit_count++;
     68     }
     69     url_row.set_visit_count(visit_count);
     70   }
     71 
     72   URLID new_id = history_db_->AddURL(url_row);
     73 
     74   // The subsequent inserts need this information.
     75   row->set_url_id(new_id);
     76   return new_id;
     77 }
     78 
     79 // Only the title, the visit time and the vist count can be updated, since the
     80 // visit count and the visit time are related. If they are not both specified,
     81 // The not specified one will be adjusted according the speficied one. The rule
     82 // is:
     83 // a. If the visit time changed and the visit count is not specified, the visit
     84 //    count will be increased by one.
     85 // b. If the visit count increased and the visit time is not specified, the last
     86 //    visit time is set to Now.
     87 // c. If the visit count is 0, it means clear the history, the last visit time
     88 //    will be set to 0.
     89 // d. The new visit time should great than or equal to the current one,
     90 //    otherwise update failed.
     91 // e. The title is free to update.
     92 //
     93 bool UrlsSQLHandler::Update(const HistoryAndBookmarkRow& row,
     94                             const TableIDRows& ids_set) {
     95   // Directly updating the URL is not allowed, we should insert the new URL
     96   // and remove the older one.
     97   DCHECK(!row.is_value_set_explicitly(HistoryAndBookmarkRow::URL));
     98 
     99   for (TableIDRows::const_iterator ids = ids_set.begin();
    100        ids != ids_set.end(); ++ids) {
    101     URLRow url_row;
    102     if (!history_db_->GetURLRow(ids->url_id, &url_row))
    103       return false;
    104 
    105     URLRow update_row = url_row;
    106 
    107     if (row.is_value_set_explicitly(HistoryAndBookmarkRow::TITLE))
    108       update_row.set_title(row.title());
    109 
    110     if (row.is_value_set_explicitly(HistoryAndBookmarkRow::VISIT_COUNT))
    111       update_row.set_visit_count(row.visit_count());
    112 
    113     if (row.is_value_set_explicitly(HistoryAndBookmarkRow::LAST_VISIT_TIME)) {
    114       // The new last_visit_time can't be less than current one.
    115       if (row.last_visit_time() < url_row.last_visit())
    116         return false;
    117       update_row.set_last_visit(row.last_visit_time());
    118     }
    119 
    120     // Adjust the visit_count if it not set.
    121     if (!row.is_value_set_explicitly(HistoryAndBookmarkRow::VISIT_COUNT) &&
    122         row.is_value_set_explicitly(HistoryAndBookmarkRow::LAST_VISIT_TIME) &&
    123         (row.last_visit_time() != url_row.last_visit()))
    124           // If last visit time is changed, visit count needs increase by 1,
    125           // as a row will be added in visit database
    126       update_row.set_visit_count(url_row.visit_count() + 1);
    127 
    128     // Adjust the last_vsit_time if it not set.
    129     if (!row.is_value_set_explicitly(HistoryAndBookmarkRow::LAST_VISIT_TIME)) {
    130       if (row.is_value_set_explicitly(HistoryAndBookmarkRow::VISIT_COUNT) &&
    131           row.visit_count() == 0) {
    132         // User want to clear history
    133         update_row.set_last_visit(Time());
    134       } else if (row.visit_count() > url_row.visit_count()) {
    135         update_row.set_last_visit(Time::Now());
    136       }
    137     }
    138 
    139     if (!history_db_->UpdateURLRow(ids->url_id, update_row))
    140       return false;
    141   }
    142   return true;
    143 }
    144 
    145 bool UrlsSQLHandler::Delete(const TableIDRows& ids_set) {
    146   for (TableIDRows::const_iterator ids = ids_set.begin();
    147        ids != ids_set.end(); ++ids) {
    148     if (!history_db_->DeleteURLRow(ids->url_id))
    149       return false;
    150   }
    151   return true;
    152 }
    153 
    154 }  // namespace history
    155