Home | History | Annotate | Download | only in android
      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