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