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#ifndef CHROME_BROWSER_HISTORY_ANDROID_ANDROID_PROVIDER_BACKEND_H_ 6#define CHROME_BROWSER_HISTORY_ANDROID_ANDROID_PROVIDER_BACKEND_H_ 7 8#include <set> 9 10#include "base/containers/hash_tables.h" 11#include "base/files/file_path.h" 12#include "base/gtest_prod_util.h" 13#include "base/memory/ref_counted.h" 14#include "base/memory/scoped_ptr.h" 15#include "base/memory/scoped_vector.h" 16#include "chrome/browser/history/android/android_cache_database.h" 17#include "chrome/browser/history/android/android_history_types.h" 18#include "chrome/browser/history/android/sql_handler.h" 19#include "chrome/browser/history/history_backend.h" 20#include "chrome/browser/history/history_notifications.h" 21#include "sql/statement.h" 22#include "sql/transaction.h" 23 24namespace history { 25 26class AndroidProviderBackend; 27class AndroidURLsSQLHandler; 28class HistoryClient; 29class HistoryDatabase; 30class ThumbnailDatabase; 31 32// This class provides the query/insert/update/remove methods to implement 33// android.provider.Browser.BookmarkColumns and 34// android.provider.Browser.SearchColumns API. 35// 36// When used it: 37// a. The android_urls table is created in history database if it doesn't 38// exists. 39// b. The android_cache database is created. 40// c. The bookmark_cache table is created. 41// 42// Android_urls and android_cache database is only updated before the related 43// methods are accessed. A data change will not triger the update. 44// 45// The android_cache database is deleted when shutdown. 46class AndroidProviderBackend { 47 public: 48 AndroidProviderBackend(const base::FilePath& cache_db_name, 49 HistoryDatabase* history_db, 50 ThumbnailDatabase* thumbnail_db, 51 HistoryClient* history_client_, 52 HistoryBackend::Delegate* delegate); 53 54 ~AndroidProviderBackend(); 55 56 // Bookmarks ---------------------------------------------------------------- 57 // 58 // Runs the given query and returns the result on success, NULL on error or 59 // the |projections| is empty. 60 // 61 // |projections| is the vector of the result columns. 62 // |selection| is the SQL WHERE clause without 'WHERE'. 63 // |selection_args| is the arguments for WHERE clause. 64 // |sort_order| is the SQL ORDER clause. 65 AndroidStatement* QueryHistoryAndBookmarks( 66 const std::vector<HistoryAndBookmarkRow::ColumnID>& projections, 67 const std::string& selection, 68 const std::vector<base::string16>& selection_args, 69 const std::string& sort_order); 70 71 // Runs the given update and returns the number of the updated rows in 72 // |update_count| and return true on success, false on error. 73 // 74 // |row| is the value to update. 75 // |selection| is the SQL WHERE clause without 'WHERE'. 76 // |selection_args| is the arguments for the WHERE clause. 77 bool UpdateHistoryAndBookmarks( 78 const HistoryAndBookmarkRow& row, 79 const std::string& selection, 80 const std::vector<base::string16>& selection_args, 81 int* update_count); 82 83 // Inserts the given values and returns the URLID of the inserted row. 84 AndroidURLID InsertHistoryAndBookmark(const HistoryAndBookmarkRow& values); 85 86 // Deletes the specified rows and returns the number of the deleted rows in 87 // |deleted_count|. 88 // |selection| is the SQL WHERE clause without 'WHERE'. 89 // |selection_args| is the arguments for the WHERE clause. 90 // 91 // if |selection| is empty all history and bookmarks are deleted. 92 bool DeleteHistoryAndBookmarks( 93 const std::string& selection, 94 const std::vector<base::string16>& selection_args, 95 int* deleted_count); 96 97 // Deletes the matched history, returns true on success, false on error. 98 // The number of deleted row is returned in |deleted_count|. 99 // The url row is kept and the visit count is reset if the matched url 100 // is bookmarked. 101 bool DeleteHistory(const std::string& selection, 102 const std::vector<base::string16>& selection_args, 103 int* deleted_count); 104 105 // SearchTerms -------------------------------------------------------------- 106 // 107 // Returns the result of the given query. 108 // |projections| specifies the result columns, can not be empty, otherwise 109 // NULL is returned. 110 // |selection| is the SQL WHERE clause without 'WHERE'. 111 // |selection_args| is the arguments for WHERE clause. 112 // |sort_order| the SQL ORDER clause. 113 AndroidStatement* QuerySearchTerms( 114 const std::vector<SearchRow::ColumnID>& projections, 115 const std::string& selection, 116 const std::vector<base::string16>& selection_args, 117 const std::string& sort_order); 118 119 // Runs the given update and returns the number of updated rows in 120 // |update_count| and return true, false returned if there is any error. 121 // 122 // |row| is the value need to update. 123 // |selection| is the SQL WHERE clause without 'WHERE'. 124 // |selection_args| is the arguments for WHERE clause. 125 bool UpdateSearchTerms(const SearchRow& row, 126 const std::string& selection, 127 const std::vector<base::string16>& selection_args, 128 int* update_count); 129 130 // Inserts the given valus and return the SearchTermID of inserted row. 131 SearchTermID InsertSearchTerm(const SearchRow& values); 132 133 // Deletes the matched rows and the number of deleted rows is returned in 134 // |deleted_count|. 135 // |selection| is the SQL WHERE clause without 'WHERE'. 136 // |selection_args| is the arguments for WHERE clause. 137 // 138 // if |selection| is empty all search be deleted. 139 bool DeleteSearchTerms(const std::string& selection, 140 const std::vector<base::string16>& selection_args, 141 int * deleted_count); 142 143 private: 144 friend class AndroidProviderBackendTest; 145 146 FRIEND_TEST_ALL_PREFIXES(AndroidProviderBackendTest, UpdateTables); 147 FRIEND_TEST_ALL_PREFIXES(AndroidProviderBackendTest, UpdateSearchTermTable); 148 149 class HistoryNotifications { 150 public: 151 HistoryNotifications(); 152 ~HistoryNotifications(); 153 154 void PushBack(int type, scoped_ptr<HistoryDetails> detail); 155 int PopBackType(); 156 scoped_ptr<HistoryDetails> PopBackDetails(); 157 158 bool empty() const { return types_.empty(); } 159 160 private: 161 std::vector<int> types_; 162 ScopedVector<HistoryDetails> details_; 163 164 DISALLOW_COPY_AND_ASSIGN(HistoryNotifications); 165 }; 166 167 // The scoped transaction for AndroidProviderBackend. 168 // 169 // The new transactions are started automatically in both history and 170 // thumbnail database and could be a nesting transaction, if so, rolling back 171 // of this transaction will cause the exsting and subsequent nesting 172 // transactions failed. 173 // 174 // Commit() is used to commit the transaction, otherwise the transaction will 175 // be rolled back when the object is out of scope. This transaction could 176 // failed even the commit() is called if it is in a transaction that has been 177 // rolled back or the subsequent transaction in the same outermost 178 // transaction would be rolled back latter. 179 // 180 class ScopedTransaction { 181 public: 182 ScopedTransaction(HistoryDatabase* history_db, 183 ThumbnailDatabase* thumbnail_db); 184 ~ScopedTransaction(); 185 186 // Commit the transaction. 187 void Commit(); 188 189 private: 190 HistoryDatabase* history_db_; 191 ThumbnailDatabase* thumbnail_db_; 192 // Whether the transaction was committed. 193 bool committed_; 194 // The count of the nested transaction in history database. 195 const int history_transaction_nesting_; 196 // The count of the nested transaction in thumbnail database. 197 const int thumbnail_transaction_nesting_; 198 199 DISALLOW_COPY_AND_ASSIGN(ScopedTransaction); 200 }; 201 202 // Runs the given update and returns the number of updated rows in 203 // |update_count| and return true on success, false on error. 204 // 205 // The notifications are returned in |notifications| and the ownership of them 206 // is transfered to caller. 207 // 208 // |row| is the value to update. 209 // |selection| is the SQL WHERE clause without 'WHERE'. 210 // |selection_args| is the arguments for the WHERE clause. 211 bool UpdateHistoryAndBookmarks(const HistoryAndBookmarkRow& row, 212 const std::string& selection, 213 const std::vector<base::string16>& selection_args, 214 int* update_count, 215 HistoryNotifications* notifications); 216 217 // Inserts the given values and returns the URLID of the inserted row. 218 // The notifications are returned in |notifications| and the ownership of them 219 // is transfered to caller. 220 // The EnsureInitializedAndUpdated() will not be invoked if the 221 // |ensure_initialized_and_updated| is false. 222 AndroidURLID InsertHistoryAndBookmark(const HistoryAndBookmarkRow& values, 223 bool ensure_initialized_and_updated, 224 HistoryNotifications* notifications); 225 226 // Deletes the specified rows and returns the number of the deleted rows in 227 // |deleted_count|. 228 // |selection| is the SQL WHERE clause without 'WHERE'. 229 // |selection_args| is the arguments for the WHERE clause. 230 // 231 // The notifications are returned in |notifications| and the ownership of them 232 // is transfered to the caller. 233 // if |selection| is empty all history and bookmarks are deleted. 234 bool DeleteHistoryAndBookmarks( 235 const std::string& selection, 236 const std::vector<base::string16>& selection_args, 237 int* deleted_count, 238 HistoryNotifications* notifications); 239 240 // Deletes the matched history, returns true on success, false on error. 241 // The number of deleted row is returned in |deleted_count|. 242 // The notifications are returned in |notifications| and the ownership of them 243 // is transfered to caller. 244 // The url row is kept and the visit is reset if the matched url is 245 // bookmarked. 246 bool DeleteHistory(const std::string& selection, 247 const std::vector<base::string16>& selection_args, 248 int* deleted_count, 249 HistoryNotifications* notifications); 250 251 // Initializes and updates tables if necessary. 252 bool EnsureInitializedAndUpdated(); 253 254 // Initializes AndroidProviderBackend. 255 bool Init(); 256 257 // Update android_urls and bookmark_cache table if it is necessary. 258 bool UpdateTables(); 259 260 // Update the android_urls and bookmark_cache for visited urls. 261 bool UpdateVisitedURLs(); 262 263 // Update the android_urls for removed urls. 264 bool UpdateRemovedURLs(); 265 266 // Update the bookmark_cache table with bookmarks. 267 bool UpdateBookmarks(); 268 269 // Update the bookmark_cache table for favicon. 270 bool UpdateFavicon(); 271 272 // Update the search_term table 273 bool UpdateSearchTermTable(); 274 275 // Append the specified result columns in |projections| to the given 276 // |result_column|. 277 // To support the lazy binding, the index of favicon column will be 278 // returned if it exists, otherwise returns -1. 279 int AppendBookmarkResultColumn( 280 const std::vector<HistoryAndBookmarkRow::ColumnID>& projections, 281 std::string* result_column); 282 283 // Append the specified search result columns in |projections| to the given 284 // |result_column|. 285 void AppendSearchResultColumn( 286 const std::vector<SearchRow::ColumnID>& projections, 287 std::string* result_column); 288 289 // Runs the given query on history_bookmark virtual table and returns true if 290 // succeeds, the selected URLID and url are returned in |rows|. 291 bool GetSelectedURLs(const std::string& selection, 292 const std::vector<base::string16>& selection_args, 293 TableIDRows* rows); 294 295 // Runs the given query on search_terms table and returns true on success, 296 // The selected search term are returned in |rows|. 297 typedef std::vector<base::string16> SearchTerms; 298 bool GetSelectedSearchTerms(const std::string& selection, 299 const std::vector<base::string16>& selection_args, 300 SearchTerms* rows); 301 302 // Simulates update url by deleting the previous URL and creating a new one. 303 // Return true on success. 304 bool SimulateUpdateURL(const HistoryAndBookmarkRow& row, 305 const TableIDRows& ids, 306 HistoryNotifications* notifications); 307 308 // Query bookmark without sync the tables. It should be used after syncing 309 // tables. 310 AndroidStatement* QueryHistoryAndBookmarksInternal( 311 const std::vector<HistoryAndBookmarkRow::ColumnID>& projections, 312 const std::string& selection, 313 const std::vector<base::string16>& selection_args, 314 const std::string& sort_order); 315 316 // Delete the given urls' history, returns true on success, or false on error. 317 // If |delete_bookmarks| is set, the bookmarks are deleted as well. 318 // The notifications are returned in |notifications| and the ownership of them 319 // is transfered to caller. 320 bool DeleteHistoryInternal(const TableIDRows& urls, 321 bool delete_bookmarks, 322 HistoryNotifications* notifications); 323 324 // Broadcasts |notifications|. Broadcasting takes ownership of the 325 // notifications, so on return |notifications| will be empty. 326 void BroadcastNotifications(HistoryNotifications* notifications); 327 328 // Add the search term from the given |values|. It will add the values.url() 329 // in the urls table if it doesn't exist, insert visit in the visits table, 330 // also add keyword in keyword_search_term. 331 bool AddSearchTerm(const SearchRow& values); 332 333 // SQLHandlers for different tables. 334 scoped_ptr<SQLHandler> urls_handler_; 335 scoped_ptr<SQLHandler> visit_handler_; 336 scoped_ptr<SQLHandler> android_urls_handler_; 337 scoped_ptr<SQLHandler> favicon_handler_; 338 scoped_ptr<SQLHandler> bookmark_model_handler_; 339 340 // The vector of all handlers 341 std::vector<SQLHandler*> sql_handlers_; 342 343 // Android cache database filename. 344 const base::FilePath android_cache_db_filename_; 345 346 // The history db's connection. 347 sql::Connection* db_; 348 349 HistoryDatabase* history_db_; 350 351 ThumbnailDatabase* thumbnail_db_; 352 353 HistoryClient* history_client_; 354 355 // Whether AndroidProviderBackend has been initialized. 356 bool initialized_; 357 358 HistoryBackend::Delegate* delegate_; 359 360 DISALLOW_COPY_AND_ASSIGN(AndroidProviderBackend); 361}; 362 363} // namespace history 364 365#endif // CHROME_BROWSER_HISTORY_ANDROID_ANDROID_PROVIDER_BACKEND_H_ 366