1 // Copyright (c) 2011 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 #pragma once 8 9 #include <vector> 10 11 #include "app/sql/connection.h" 12 #include "app/sql/init_status.h" 13 #include "app/sql/meta_table.h" 14 #include "base/gtest_prod_util.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/memory/scoped_ptr.h" 17 #include "chrome/browser/history/history_types.h" 18 19 class FilePath; 20 class RefCountedMemory; 21 struct ThumbnailScore; 22 class SkBitmap; 23 24 namespace base { 25 class Time; 26 } 27 28 namespace history { 29 30 class ExpireHistoryBackend; 31 class HistoryPublisher; 32 33 // This database interface is owned by the history backend and runs on the 34 // history thread. It is a totally separate component from history partially 35 // because we may want to move it to its own thread in the future. The 36 // operations we will do on this database will be slow, but we can tolerate 37 // higher latency (it's OK for thumbnails to come in slower than the rest 38 // of the data). Moving this to a separate thread would not block potentially 39 // higher priority history operations. 40 class ThumbnailDatabase { 41 public: 42 ThumbnailDatabase(); 43 ~ThumbnailDatabase(); 44 45 // Must be called after creation but before any other methods are called. 46 // When not INIT_OK, no other functions should be called. 47 sql::InitStatus Init(const FilePath& db_name, 48 const HistoryPublisher* history_publisher, 49 URLDatabase* url_database); 50 51 // Open database on a given filename. If the file does not exist, 52 // it is created. 53 // |db| is the database to open. 54 // |db_name| is a path to the database file. 55 static sql::InitStatus OpenDatabase(sql::Connection* db, 56 const FilePath& db_name); 57 58 // Transactions on the database. 59 void BeginTransaction(); 60 void CommitTransaction(); 61 int transaction_nesting() const { 62 return db_.transaction_nesting(); 63 } 64 65 // Vacuums the database. This will cause sqlite to defragment and collect 66 // unused space in the file. It can be VERY SLOW. 67 void Vacuum(); 68 69 // Thumbnails ---------------------------------------------------------------- 70 71 // Sets the given data to be the thumbnail for the given URL, 72 // overwriting any previous data. If the SkBitmap contains no pixel 73 // data, the thumbnail will be deleted. 74 void SetPageThumbnail(const GURL& url, 75 URLID id, 76 const SkBitmap& thumbnail, 77 const ThumbnailScore& score, 78 base::Time time); 79 80 // Retrieves thumbnail data for the given URL, returning true on success, 81 // false if there is no such thumbnail or there was some other error. 82 bool GetPageThumbnail(URLID id, std::vector<unsigned char>* data); 83 84 // Delete the thumbnail with the provided id. Returns false on failure 85 bool DeleteThumbnail(URLID id); 86 87 // If there is a thumbnail score for the id provided, retrieves the 88 // current thumbnail score and places it in |score| and returns 89 // true. Returns false otherwise. 90 bool ThumbnailScoreForId(URLID id, ThumbnailScore* score); 91 92 // Called by the to delete all old thumbnails and make a clean table. 93 // Returns true on success. 94 bool RecreateThumbnailTable(); 95 96 // Favicons ------------------------------------------------------------------ 97 98 // Sets the bits for a favicon. This should be png encoded data. 99 // The time indicates the access time, and is used to detect when the favicon 100 // should be refreshed. 101 bool SetFavicon(FaviconID icon_id, 102 scoped_refptr<RefCountedMemory> icon_data, 103 base::Time time); 104 105 // Sets the time the favicon was last updated. 106 bool SetFaviconLastUpdateTime(FaviconID icon_id, base::Time time); 107 108 // Returns the id of the entry in the favicon database with the specified url 109 // and icon type. If |required_icon_type| contains multiple icon types and 110 // there are more than one matched icon in database, only one icon will be 111 // returned in the priority of TOUCH_PRECOMPOSED_ICON, TOUCH_ICON, and 112 // FAVICON, and the icon type is returned in icon_type parameter if it is not 113 // NULL. 114 // Returns 0 if no entry exists for the specified url. 115 FaviconID GetFaviconIDForFaviconURL(const GURL& icon_url, 116 int required_icon_type, 117 IconType* icon_type); 118 119 // Gets the png encoded favicon and last updated time for the specified 120 // favicon id. 121 bool GetFavicon(FaviconID icon_id, 122 base::Time* last_updated, 123 std::vector<unsigned char>* png_icon_data, 124 GURL* icon_url); 125 126 // Adds the favicon URL and icon type to the favicon db, returning its id. 127 FaviconID AddFavicon(const GURL& icon_url, IconType icon_type); 128 129 // Delete the favicon with the provided id. Returns false on failure 130 bool DeleteFavicon(FaviconID id); 131 132 // Icon Mapping -------------------------------------------------------------- 133 // 134 // Returns true if there is a matched icon mapping for the given page and 135 // icon type. 136 // The matched icon mapping is returned in the icon_mapping parameter if it is 137 // not NULL. 138 bool GetIconMappingForPageURL(const GURL& page_url, 139 IconType required_icon_type, 140 IconMapping* icon_mapping); 141 142 // Returns true if there is any matched icon mapping for the given page. 143 // All matched icon mappings are returned in descent order of IconType if 144 // mapping_data is not NULL. 145 bool GetIconMappingsForPageURL(const GURL& page_url, 146 std::vector<IconMapping>* mapping_data); 147 148 // Adds a mapping between the given page_url and icon_id. 149 // Returns the new mapping id if the adding succeeds, otherwise 0 is returned. 150 IconMappingID AddIconMapping(const GURL& page_url, FaviconID icon_id); 151 152 // Updates the page and icon mapping for the given mapping_id with the given 153 // icon_id. 154 // Returns true if the update succeeded. 155 bool UpdateIconMapping(IconMappingID mapping_id, FaviconID icon_id); 156 157 // Deletes the icon mapping entries for the given page url. 158 // Returns true if the deletion succeeded. 159 bool DeleteIconMappings(const GURL& page_url); 160 161 // Checks whether a favicon is used by any URLs in the database. 162 bool HasMappingFor(FaviconID id); 163 164 // Temporary IconMapping ----------------------------------------------------- 165 // 166 // Creates a temporary table to store icon mapping. Icon mapping will be 167 // copied to this table by AddToTemporaryIconMappingTable() and then the 168 // original table will be dropped, leaving only those copied mapping 169 // remaining. This is used to quickly delete most of the icon mapping when 170 // clearing history. 171 bool InitTemporaryIconMappingTable() { 172 return InitIconMappingTable(&db_, true); 173 } 174 175 // Copies the given icon mapping from the "main" icon_mapping table to the 176 // temporary one. This is only valid in between calls to 177 // InitTemporaryIconMappingTable() 178 // and CommitTemporaryIconMappingTable(). 179 // 180 // The ID of the favicon will change when this copy takes place. The new ID 181 // is returned, or 0 on failure. 182 IconMappingID AddToTemporaryIconMappingTable(const GURL& page_url, 183 const FaviconID icon_id); 184 185 // Replaces the main icon mapping table with the temporary table created by 186 // InitTemporaryIconMappingTable(). This will mean all icon mapping not copied 187 // over will be deleted. Returns true on success. 188 bool CommitTemporaryIconMappingTable(); 189 190 // Temporary Favicons -------------------------------------------------------- 191 192 // Create a temporary table to store favicons. Favicons will be copied to 193 // this table by CopyToTemporaryFaviconTable() and then the original table 194 // will be dropped, leaving only those copied favicons remaining. This is 195 // used to quickly delete most of the favicons when clearing history. 196 bool InitTemporaryFaviconsTable() { 197 return InitFaviconsTable(&db_, true); 198 } 199 200 // Copies the given favicon from the "main" favicon table to the temporary 201 // one. This is only valid in between calls to InitTemporaryFaviconsTable() 202 // and CommitTemporaryFaviconTable(). 203 // 204 // The ID of the favicon will change when this copy takes place. The new ID 205 // is returned, or 0 on failure. 206 FaviconID CopyToTemporaryFaviconTable(FaviconID source); 207 208 // Replaces the main URL table with the temporary table created by 209 // InitTemporaryFaviconsTable(). This will mean all favicons not copied over 210 // will be deleted. Returns true on success. 211 bool CommitTemporaryFaviconTable(); 212 213 // Returns true iff the thumbnails table exists. 214 // Migrating to TopSites is dropping the thumbnails table. 215 bool NeedsMigrationToTopSites(); 216 217 // Renames the database file and drops the Thumbnails table. 218 bool RenameAndDropThumbnails(const FilePath& old_db_file, 219 const FilePath& new_db_file); 220 221 private: 222 friend class ExpireHistoryBackend; 223 FRIEND_TEST_ALL_PREFIXES(ThumbnailDatabaseTest, UpgradeToVersion4); 224 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, MigrationIconMapping); 225 226 // Creates the thumbnail table, returning true if the table already exists 227 // or was successfully created. 228 bool InitThumbnailTable(); 229 230 // Creates the favicon table, returning true if the table already exists, 231 // or was successfully created. |is_temporary| will be false when generating 232 // the "regular" favicons table. The expirer sets this to true to generate the 233 // temporary table, which will have a different name but the same schema. 234 // |db| is the connection to use for initializing the table. 235 // A different connection is used in RenameAndDropThumbnails, when we 236 // need to copy the favicons between two database files. 237 bool InitFaviconsTable(sql::Connection* db, bool is_temporary); 238 239 // Adds support for the new metadata on web page thumbnails. 240 bool UpgradeToVersion3(); 241 242 // Adds support for the icon_type in favicon table. 243 bool UpgradeToVersion4(); 244 245 // Migrates the icon mapping data from URL database to Thumbnail database. 246 // Return whether the migration succeeds. 247 bool MigrateIconMappingData(URLDatabase* url_db); 248 249 // Creates the index over the favicon table. This will be called during 250 // initialization after the table is created. This is a separate function 251 // because it is used by SwapFaviconTables to create an index over the 252 // newly-renamed favicons table (formerly the temporary table with no index). 253 void InitFaviconsIndex(); 254 255 // Creates the icon_map table, return true if the table already exists or was 256 // successfully created. 257 bool InitIconMappingTable(sql::Connection* db, bool is_temporary); 258 259 // Creates the index over the icon_mapping table, This will be called during 260 // initialization after the table is created. This is a separate function 261 // because it is used by CommitTemporaryIconMappingTable to create an index 262 // over the newly-renamed icon_mapping table (formerly the temporary table 263 // with no index). 264 void InitIconMappingIndex(); 265 266 // Adds a mapping between the given page_url and icon_id; The mapping will be 267 // added to temp_icon_mapping table if is_temporary is true. 268 // Returns the new mapping id if the adding succeeds, otherwise 0 is returned. 269 IconMappingID AddIconMapping(const GURL& page_url, 270 FaviconID icon_id, 271 bool is_temporary); 272 273 sql::Connection db_; 274 sql::MetaTable meta_table_; 275 276 // This object is created and managed by the history backend. We maintain an 277 // opaque pointer to the object for our use. 278 // This can be NULL if there are no indexers registered to receive indexing 279 // data from us. 280 const HistoryPublisher* history_publisher_; 281 282 // True if migration to TopSites has been done and the thumbnails 283 // table should not be used. 284 bool use_top_sites_; 285 }; 286 287 } // namespace history 288 289 #endif // CHROME_BROWSER_HISTORY_THUMBNAIL_DATABASE_H_ 290