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
19class FilePath;
20class RefCountedMemory;
21struct ThumbnailScore;
22class SkBitmap;
23
24namespace base {
25class Time;
26}
27
28namespace history {
29
30class ExpireHistoryBackend;
31class 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.
40class 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