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.
5 #ifndef CHROME_BROWSER_HISTORY_ANDROID_ANDROID_PROVIDER_BACKEND_H_
6 #define CHROME_BROWSER_HISTORY_ANDROID_ANDROID_PROVIDER_BACKEND_H_
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"
27 class AndroidProviderBackend;
28 class AndroidURLsSQLHandler;
30 class HistoryDatabase;
31 class ThumbnailDatabase;
33 // This class provides the query/insert/update/remove methods to implement
34 // android.provider.Browser.BookmarkColumns and
35 // android.provider.Browser.SearchColumns API.
38 // a. The android_urls table is created in history database if it doesn't
40 // b. The android_cache database is created.
41 // c. The bookmark_cache table is created.
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.
46 // The android_cache database is deleted when shutdown.
47 class AndroidProviderBackend {
49 AndroidProviderBackend(const base::FilePath& cache_db_name,
50 HistoryDatabase* history_db,
51 ThumbnailDatabase* thumbnail_db,
52 HistoryClient* history_client_,
53 HistoryBackend::Delegate* delegate);
55 ~AndroidProviderBackend();
57 // Bookmarks ----------------------------------------------------------------
59 // Runs the given query and returns the result on success, NULL on error or
60 // the |projections| is empty.
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);
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.
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,
84 // Inserts the given values and returns the URLID of the inserted row.
85 AndroidURLID InsertHistoryAndBookmark(const HistoryAndBookmarkRow& values);
87 // Deletes the specified rows and returns the number of the deleted rows in
89 // |selection| is the SQL WHERE clause without 'WHERE'.
90 // |selection_args| is the arguments for the WHERE clause.
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,
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
102 bool DeleteHistory(const std::string& selection,
103 const std::vector<base::string16>& selection_args,
106 // SearchTerms --------------------------------------------------------------
108 // Returns the result of the given query.
109 // |projections| specifies the result columns, can not be empty, otherwise
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);
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.
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,
131 // Inserts the given valus and return the SearchTermID of inserted row.
132 SearchTermID InsertSearchTerm(const SearchRow& values);
134 // Deletes the matched rows and the number of deleted rows is returned in
136 // |selection| is the SQL WHERE clause without 'WHERE'.
137 // |selection_args| is the arguments for WHERE clause.
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);
145 friend class AndroidProviderBackendTest;
147 FRIEND_TEST_ALL_PREFIXES(AndroidProviderBackendTest, UpdateTables);
148 FRIEND_TEST_ALL_PREFIXES(AndroidProviderBackendTest, UpdateSearchTermTable);
150 typedef std::list<base::Closure> HistoryNotifications;
152 // The scoped transaction for AndroidProviderBackend.
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.
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.
165 class ScopedTransaction {
167 ScopedTransaction(HistoryDatabase* history_db,
168 ThumbnailDatabase* thumbnail_db);
169 ~ScopedTransaction();
171 // Commit the transaction.
175 HistoryDatabase* history_db_;
176 ThumbnailDatabase* thumbnail_db_;
177 // Whether the transaction was 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_;
184 DISALLOW_COPY_AND_ASSIGN(ScopedTransaction);
187 // Runs the given update and returns the number of updated rows in
188 // |update_count| and return true on success, false on error.
190 // The notifications are returned in |notifications| and the ownership of them
191 // is transfered to caller.
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,
200 HistoryNotifications* notifications);
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);
211 // Deletes the specified rows and returns the number of the deleted rows in
213 // |selection| is the SQL WHERE clause without 'WHERE'.
214 // |selection_args| is the arguments for the WHERE clause.
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,
223 HistoryNotifications* notifications);
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
231 bool DeleteHistory(const std::string& selection,
232 const std::vector<base::string16>& selection_args,
234 HistoryNotifications* notifications);
236 // Initializes and updates tables if necessary.
237 bool EnsureInitializedAndUpdated();
239 // Initializes AndroidProviderBackend.
242 // Update android_urls and bookmark_cache table if it is necessary.
245 // Update the android_urls and bookmark_cache for visited urls.
246 bool UpdateVisitedURLs();
248 // Update the android_urls for removed urls.
249 bool UpdateRemovedURLs();
251 // Update the bookmark_cache table with bookmarks.
252 bool UpdateBookmarks();
254 // Update the bookmark_cache table for favicon.
255 bool UpdateFavicon();
257 // Update the search_term table
258 bool UpdateSearchTermTable();
260 // Append the specified result columns in |projections| to the given
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);
268 // Append the specified search result columns in |projections| to the given
270 void AppendSearchResultColumn(
271 const std::vector<SearchRow::ColumnID>& projections,
272 std::string* result_column);
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,
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,
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);
293 // Query bookmark without sync the tables. It should be used after syncing
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);
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);
309 // Broadcasts |notifications|. Broadcasting takes ownership of the
310 // notifications, so on return |notifications| will be empty.
311 void BroadcastNotifications(HistoryNotifications* notifications);
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);
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_;
325 // The vector of all handlers
326 std::vector<SQLHandler*> sql_handlers_;
328 // Android cache database filename.
329 const base::FilePath android_cache_db_filename_;
331 // The history db's connection.
332 sql::Connection* db_;
334 HistoryDatabase* history_db_;
336 ThumbnailDatabase* thumbnail_db_;
338 HistoryClient* history_client_;
340 // Whether AndroidProviderBackend has been initialized.
343 HistoryBackend::Delegate* delegate_;
345 DISALLOW_COPY_AND_ASSIGN(AndroidProviderBackend);
348 } // namespace history
350 #endif // CHROME_BROWSER_HISTORY_ANDROID_ANDROID_PROVIDER_BACKEND_H_