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