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<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 struct HistoryNotification { 150 HistoryNotification(int type, HistoryDetails* detail); 151 ~HistoryNotification(); 152 153 int type; 154 // The ownership of the HistoryDetails pointer is transfered to |detail|. 155 HistoryDetails* detail; 156 }; 157 typedef std::vector<HistoryNotification> HistoryNotifications; 158 159 // The scoped transaction for AndroidProviderBackend. 160 // 161 // The new transactions are started automatically in both history and 162 // thumbnail database and could be a nesting transaction, if so, rolling back 163 // of this transaction will cause the exsting and subsequent nesting 164 // transactions failed. 165 // 166 // Commit() is used to commit the transaction, otherwise the transaction will 167 // be rolled back when the object is out of scope. This transaction could 168 // failed even the commit() is called if it is in a transaction that has been 169 // rolled back or the subsequent transaction in the same outermost 170 // transaction would be rolled back latter. 171 // 172 class ScopedTransaction { 173 public: 174 ScopedTransaction(HistoryDatabase* history_db, 175 ThumbnailDatabase* thumbnail_db); 176 ~ScopedTransaction(); 177 178 // Commit the transaction. 179 void Commit(); 180 181 private: 182 HistoryDatabase* history_db_; 183 ThumbnailDatabase* thumbnail_db_; 184 // Whether the transaction was committed. 185 bool committed_; 186 // The count of the nested transaction in history database. 187 const int history_transaction_nesting_; 188 // The count of the nested transaction in thumbnail database. 189 const int thumbnail_transaction_nesting_; 190 191 DISALLOW_COPY_AND_ASSIGN(ScopedTransaction); 192 }; 193 194 // Runs the given update and returns the number of updated rows in 195 // |update_count| and return true on success, false on error. 196 // 197 // The notifications are returned in |notifications| and the ownership of them 198 // is transfered to caller. 199 // 200 // |row| is the value to update. 201 // |selection| is the SQL WHERE clause without 'WHERE'. 202 // |selection_args| is the arguments for the WHERE clause. 203 bool UpdateHistoryAndBookmarks(const HistoryAndBookmarkRow& row, 204 const std::string& selection, 205 const std::vector<base::string16>& selection_args, 206 int* update_count, 207 HistoryNotifications* notifications); 208 209 // Inserts the given values and returns the URLID of the inserted row. 210 // The notifications are returned in |notifications| and the ownership of them 211 // is transfered to caller. 212 // The EnsureInitializedAndUpdated() will not be invoked if the 213 // |ensure_initialized_and_updated| is false. 214 AndroidURLID InsertHistoryAndBookmark(const HistoryAndBookmarkRow& values, 215 HistoryNotifications* notifications, 216 bool ensure_initialized_and_updated); 217 218 // Deletes the specified rows and returns the number of the deleted rows in 219 // |deleted_count|. 220 // |selection| is the SQL WHERE clause without 'WHERE'. 221 // |selection_args| is the arguments for the WHERE clause. 222 // 223 // The notifications are returned in |notifications| and the ownership of them 224 // is transfered to the caller. 225 // if |selection| is empty all history and bookmarks are deleted. 226 bool DeleteHistoryAndBookmarks( 227 const std::string& selection, 228 const std::vector<base::string16>& selection_args, 229 int* deleted_count, 230 HistoryNotifications* notifications); 231 232 // Deletes the matched history, returns true on success, false on error. 233 // The number of deleted row is returned in |deleted_count|. 234 // The notifications are returned in |notifications| and the ownership of them 235 // is transfered to caller. 236 // The url row is kept and the visit is reset if the matched url is 237 // bookmarked. 238 bool DeleteHistory(const std::string& selection, 239 const std::vector<base::string16>& selection_args, 240 int* deleted_count, 241 HistoryNotifications* notifications); 242 243 // Initializes and updates tables if necessary. 244 bool EnsureInitializedAndUpdated(); 245 246 // Initializes AndroidProviderBackend. 247 bool Init(); 248 249 // Update android_urls and bookmark_cache table if it is necessary. 250 bool UpdateTables(); 251 252 // Update the android_urls and bookmark_cache for visited urls. 253 bool UpdateVisitedURLs(); 254 255 // Update the android_urls for removed urls. 256 bool UpdateRemovedURLs(); 257 258 // Update the bookmark_cache table with bookmarks. 259 bool UpdateBookmarks(); 260 261 // Update the bookmark_cache table for favicon. 262 bool UpdateFavicon(); 263 264 // Update the search_term table 265 bool UpdateSearchTermTable(); 266 267 // Append the specified result columns in |projections| to the given 268 // |result_column|. 269 // To support the lazy binding, the index of favicon column will be 270 // returned if it exists, otherwise returns -1. 271 int AppendBookmarkResultColumn( 272 const std::vector<HistoryAndBookmarkRow::ColumnID>& projections, 273 std::string* result_column); 274 275 // Append the specified search result columns in |projections| to the given 276 // |result_column|. 277 void AppendSearchResultColumn( 278 const std::vector<SearchRow::ColumnID>& projections, 279 std::string* result_column); 280 281 // Runs the given query on history_bookmark virtual table and returns true if 282 // succeeds, the selected URLID and url are returned in |rows|. 283 bool GetSelectedURLs(const std::string& selection, 284 const std::vector<base::string16>& selection_args, 285 TableIDRows* rows); 286 287 // Runs the given query on search_terms table and returns true on success, 288 // The selected search term are returned in |rows|. 289 typedef std::vector<base::string16> SearchTerms; 290 bool GetSelectedSearchTerms(const std::string& selection, 291 const std::vector<base::string16>& selection_args, 292 SearchTerms* rows); 293 294 // Simulates update url by deleting the previous URL and creating a new one. 295 // Return true on success. 296 bool SimulateUpdateURL(const HistoryAndBookmarkRow& row, 297 const TableIDRows& ids, 298 HistoryNotifications* notifications); 299 300 // Query bookmark without sync the tables. It should be used after syncing 301 // tables. 302 AndroidStatement* QueryHistoryAndBookmarksInternal( 303 const std::vector<HistoryAndBookmarkRow::ColumnID>& projections, 304 const std::string& selection, 305 const std::vector<base::string16>& selection_args, 306 const std::string& sort_order); 307 308 // Delete the given urls' history, returns true on success, or false on error. 309 // If |delete_bookmarks| is set, the bookmarks are deleted as well. 310 // The notifications are returned in |notifications| and the ownership of them 311 // is transfered to caller. 312 bool DeleteHistoryInternal(const TableIDRows& urls, 313 bool delete_bookmarks, 314 HistoryNotifications* notifications); 315 316 void BroadcastNotifications(const HistoryNotifications& notifications); 317 318 // Add the search term from the given |values|. It will add the values.url() 319 // in the urls table if it doesn't exist, insert visit in the visits table, 320 // also add keyword in keyword_search_term. 321 bool AddSearchTerm(const SearchRow& values); 322 323 // SQLHandlers for different tables. 324 scoped_ptr<SQLHandler> urls_handler_; 325 scoped_ptr<SQLHandler> visit_handler_; 326 scoped_ptr<SQLHandler> android_urls_handler_; 327 scoped_ptr<SQLHandler> favicon_handler_; 328 scoped_ptr<SQLHandler> bookmark_model_handler_; 329 330 // The vector of all handlers 331 std::vector<SQLHandler*> sql_handlers_; 332 333 // Android cache database filename. 334 const base::FilePath android_cache_db_filename_; 335 336 // The history db's connection. 337 sql::Connection* db_; 338 339 HistoryDatabase* history_db_; 340 341 ThumbnailDatabase* thumbnail_db_; 342 343 BookmarkService* bookmark_service_; 344 345 // Whether AndroidProviderBackend has been initialized. 346 bool initialized_; 347 348 HistoryBackend::Delegate* delegate_; 349 350 DISALLOW_COPY_AND_ASSIGN(AndroidProviderBackend); 351 }; 352 353 } // namespace history 354 355 #endif // CHROME_BROWSER_HISTORY_ANDROID_ANDROID_PROVIDER_BACKEND_H_ 356