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 <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