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