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