Home | History | Annotate | Download | only in history
      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_THUMBNAIL_DATABASE_H_
      6 #define CHROME_BROWSER_HISTORY_THUMBNAIL_DATABASE_H_
      7 
      8 #include <vector>
      9 
     10 #include "base/gtest_prod_util.h"
     11 #include "base/memory/ref_counted.h"
     12 #include "components/history/core/browser/history_types.h"
     13 #include "sql/connection.h"
     14 #include "sql/init_status.h"
     15 #include "sql/meta_table.h"
     16 #include "sql/statement.h"
     17 
     18 namespace base {
     19 class FilePath;
     20 class RefCountedMemory;
     21 class Time;
     22 }
     23 
     24 namespace history {
     25 
     26 class HistoryClient;
     27 
     28 // This database interface is owned by the history backend and runs on the
     29 // history thread. It is a totally separate component from history partially
     30 // because we may want to move it to its own thread in the future. The
     31 // operations we will do on this database will be slow, but we can tolerate
     32 // higher latency (it's OK for thumbnails to come in slower than the rest
     33 // of the data). Moving this to a separate thread would not block potentially
     34 // higher priority history operations.
     35 class ThumbnailDatabase {
     36  public:
     37   explicit ThumbnailDatabase(HistoryClient* history_client);
     38   ~ThumbnailDatabase();
     39 
     40   // Must be called after creation but before any other methods are called.
     41   // When not INIT_OK, no other functions should be called.
     42   sql::InitStatus Init(const base::FilePath& db_name);
     43 
     44   // Computes and records various metrics for the database. Should only be
     45   // called once and only upon successful Init.
     46   void ComputeDatabaseMetrics();
     47 
     48   // Transactions on the database.
     49   void BeginTransaction();
     50   void CommitTransaction();
     51   int transaction_nesting() const {
     52     return db_.transaction_nesting();
     53   }
     54   void RollbackTransaction();
     55 
     56   // Vacuums the database. This will cause sqlite to defragment and collect
     57   // unused space in the file. It can be VERY SLOW.
     58   void Vacuum();
     59 
     60   // Try to trim the cache memory used by the database.  If |aggressively| is
     61   // true try to trim all unused cache, otherwise trim by half.
     62   void TrimMemory(bool aggressively);
     63 
     64   // Favicon Bitmaps -----------------------------------------------------------
     65 
     66   // Returns true if there are favicon bitmaps for |icon_id|. If
     67   // |bitmap_id_sizes| is non NULL, sets it to a list of the favicon bitmap ids
     68   // and their associated pixel sizes for the favicon with |icon_id|.
     69   // The list contains results for the bitmaps which are cached in the
     70   // favicon_bitmaps table. The pixel sizes are a subset of the sizes in the
     71   // 'sizes' field of the favicons table for |icon_id|.
     72   bool GetFaviconBitmapIDSizes(
     73       favicon_base::FaviconID icon_id,
     74       std::vector<FaviconBitmapIDSize>* bitmap_id_sizes);
     75 
     76   // Returns true if there are any matched bitmaps for the given |icon_id|. All
     77   // matched results are returned if |favicon_bitmaps| is not NULL.
     78   bool GetFaviconBitmaps(favicon_base::FaviconID icon_id,
     79                          std::vector<FaviconBitmap>* favicon_bitmaps);
     80 
     81   // Gets the last updated time, bitmap data, and pixel size of the favicon
     82   // bitmap at |bitmap_id|. Returns true if successful.
     83   bool GetFaviconBitmap(FaviconBitmapID bitmap_id,
     84                         base::Time* last_updated,
     85                         scoped_refptr<base::RefCountedMemory>* png_icon_data,
     86                         gfx::Size* pixel_size);
     87 
     88   // Adds a bitmap component at |pixel_size| for the favicon with |icon_id|.
     89   // Only favicons representing a .ico file should have multiple favicon bitmaps
     90   // per favicon.
     91   // |icon_data| is the png encoded data.
     92   // The |time| indicates the access time, and is used to detect when the
     93   // favicon should be refreshed.
     94   // |pixel_size| is the pixel dimensions of |icon_data|.
     95   // Returns the id of the added bitmap or 0 if unsuccessful.
     96   FaviconBitmapID AddFaviconBitmap(
     97       favicon_base::FaviconID icon_id,
     98       const scoped_refptr<base::RefCountedMemory>& icon_data,
     99       base::Time time,
    100       const gfx::Size& pixel_size);
    101 
    102   // Sets the bitmap data and the last updated time for the favicon bitmap at
    103   // |bitmap_id|.
    104   // Returns true if successful.
    105   bool SetFaviconBitmap(FaviconBitmapID bitmap_id,
    106                         scoped_refptr<base::RefCountedMemory> bitmap_data,
    107                         base::Time time);
    108 
    109   // Sets the last updated time for the favicon bitmap at |bitmap_id|.
    110   // Returns true if successful.
    111   bool SetFaviconBitmapLastUpdateTime(FaviconBitmapID bitmap_id,
    112                                       base::Time time);
    113 
    114   // Deletes the favicon bitmap with |bitmap_id|.
    115   // Returns true if successful.
    116   bool DeleteFaviconBitmap(FaviconBitmapID bitmap_id);
    117 
    118   // Favicons ------------------------------------------------------------------
    119 
    120   // Sets the the favicon as out of date. This will set |last_updated| for all
    121   // of the bitmaps for |icon_id| to be out of date.
    122   bool SetFaviconOutOfDate(favicon_base::FaviconID icon_id);
    123 
    124   // Returns the id of the entry in the favicon database with the specified url
    125   // and icon type. If |required_icon_type| contains multiple icon types and
    126   // there are more than one matched icon in database, only one icon will be
    127   // returned in the priority of TOUCH_PRECOMPOSED_ICON, TOUCH_ICON, and
    128   // FAVICON, and the icon type is returned in icon_type parameter if it is not
    129   // NULL.
    130   // Returns 0 if no entry exists for the specified url.
    131   favicon_base::FaviconID GetFaviconIDForFaviconURL(
    132       const GURL& icon_url,
    133       int required_icon_type,
    134       favicon_base::IconType* icon_type);
    135 
    136   // Gets the icon_url, icon_type and sizes for the specified |icon_id|.
    137   bool GetFaviconHeader(favicon_base::FaviconID icon_id,
    138                         GURL* icon_url,
    139                         favicon_base::IconType* icon_type);
    140 
    141   // Adds favicon with |icon_url|, |icon_type| and |favicon_sizes| to the
    142   // favicon db, returning its id.
    143   favicon_base::FaviconID AddFavicon(const GURL& icon_url,
    144                                      favicon_base::IconType icon_type);
    145 
    146   // Adds a favicon with a single bitmap. This call is equivalent to calling
    147   // AddFavicon and AddFaviconBitmap.
    148   favicon_base::FaviconID AddFavicon(
    149       const GURL& icon_url,
    150       favicon_base::IconType icon_type,
    151       const scoped_refptr<base::RefCountedMemory>& icon_data,
    152       base::Time time,
    153       const gfx::Size& pixel_size);
    154 
    155   // Delete the favicon with the provided id. Returns false on failure
    156   bool DeleteFavicon(favicon_base::FaviconID id);
    157 
    158   // Icon Mapping --------------------------------------------------------------
    159   //
    160   // Returns true if there is a matched icon mapping for the given page and
    161   // icon type.
    162   // The matched icon mapping is returned in the icon_mapping parameter if it is
    163   // not NULL.
    164 
    165   // Returns true if there are icon mappings for the given page and icon types.
    166   // If |required_icon_types| contains multiple icon types and there is more
    167   // than one matched icon type in the database, icons of only a single type
    168   // will be returned in the priority of TOUCH_PRECOMPOSED_ICON, TOUCH_ICON,
    169   // and FAVICON.
    170   // The matched icon mappings are returned in the |mapping_data| parameter if
    171   // it is not NULL.
    172   bool GetIconMappingsForPageURL(const GURL& page_url,
    173                                  int required_icon_types,
    174                                  std::vector<IconMapping>* mapping_data);
    175 
    176   // Returns true if there is any matched icon mapping for the given page.
    177   // All matched icon mappings are returned in descent order of IconType if
    178   // mapping_data is not NULL.
    179   bool GetIconMappingsForPageURL(const GURL& page_url,
    180                                  std::vector<IconMapping>* mapping_data);
    181 
    182   // Adds a mapping between the given page_url and icon_id.
    183   // Returns the new mapping id if the adding succeeds, otherwise 0 is returned.
    184   IconMappingID AddIconMapping(const GURL& page_url,
    185                                favicon_base::FaviconID icon_id);
    186 
    187   // Updates the page and icon mapping for the given mapping_id with the given
    188   // icon_id.
    189   // Returns true if the update succeeded.
    190   bool UpdateIconMapping(IconMappingID mapping_id,
    191                          favicon_base::FaviconID icon_id);
    192 
    193   // Deletes the icon mapping entries for the given page url.
    194   // Returns true if the deletion succeeded.
    195   bool DeleteIconMappings(const GURL& page_url);
    196 
    197   // Deletes the icon mapping with |mapping_id|.
    198   // Returns true if the deletion succeeded.
    199   bool DeleteIconMapping(IconMappingID mapping_id);
    200 
    201   // Checks whether a favicon is used by any URLs in the database.
    202   bool HasMappingFor(favicon_base::FaviconID id);
    203 
    204   // Clones the existing mappings from |old_page_url| if |new_page_url| has no
    205   // mappings. Otherwise, will leave mappings alone.
    206   bool CloneIconMappings(const GURL& old_page_url, const GURL& new_page_url);
    207 
    208   // The class to enumerate icon mappings. Use InitIconMappingEnumerator to
    209   // initialize.
    210   class IconMappingEnumerator {
    211    public:
    212     IconMappingEnumerator();
    213     ~IconMappingEnumerator();
    214 
    215     // Get the next icon mapping, return false if no more are available.
    216     bool GetNextIconMapping(IconMapping* icon_mapping);
    217 
    218    private:
    219     friend class ThumbnailDatabase;
    220 
    221     // Used to query database and return the data for filling IconMapping in
    222     // each call of GetNextIconMapping().
    223     sql::Statement statement_;
    224 
    225     DISALLOW_COPY_AND_ASSIGN(IconMappingEnumerator);
    226   };
    227 
    228   // Return all icon mappings of the given |icon_type|.
    229   bool InitIconMappingEnumerator(favicon_base::IconType type,
    230                                  IconMappingEnumerator* enumerator);
    231 
    232   // Remove all data except that associated with the passed page urls.
    233   // Returns false in case of failure.  A nested transaction is used,
    234   // so failure causes any outer transaction to be rolled back.
    235   bool RetainDataForPageUrls(const std::vector<GURL>& urls_to_keep);
    236 
    237  private:
    238   FRIEND_TEST_ALL_PREFIXES(ThumbnailDatabaseTest, RetainDataForPageUrls);
    239   FRIEND_TEST_ALL_PREFIXES(ThumbnailDatabaseTest, Version3);
    240   FRIEND_TEST_ALL_PREFIXES(ThumbnailDatabaseTest, Version4);
    241   FRIEND_TEST_ALL_PREFIXES(ThumbnailDatabaseTest, Version5);
    242   FRIEND_TEST_ALL_PREFIXES(ThumbnailDatabaseTest, Version6);
    243   FRIEND_TEST_ALL_PREFIXES(ThumbnailDatabaseTest, Version7);
    244   FRIEND_TEST_ALL_PREFIXES(ThumbnailDatabaseTest, WildSchema);
    245 
    246   // Open database on a given filename. If the file does not exist,
    247   // it is created.
    248   // |db| is the database to open.
    249   // |db_name| is a path to the database file.
    250   sql::InitStatus OpenDatabase(sql::Connection* db,
    251                                const base::FilePath& db_name);
    252 
    253   // Helper function to implement internals of Init().  This allows
    254   // Init() to retry in case of failure, since some failures run
    255   // recovery code.
    256   sql::InitStatus InitImpl(const base::FilePath& db_name);
    257 
    258   // Helper function to handle cleanup on upgrade failures.
    259   sql::InitStatus CantUpgradeToVersion(int cur_version);
    260 
    261   // Adds support for size in favicons table.
    262   bool UpgradeToVersion6();
    263 
    264   // Removes sizes column.
    265   bool UpgradeToVersion7();
    266 
    267   // Returns true if the |favicons| database is missing a column.
    268   bool IsFaviconDBStructureIncorrect();
    269 
    270   sql::Connection db_;
    271   sql::MetaTable meta_table_;
    272 
    273   HistoryClient* history_client_;
    274 };
    275 
    276 }  // namespace history
    277 
    278 #endif  // CHROME_BROWSER_HISTORY_THUMBNAIL_DATABASE_H_
    279