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