• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 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_URL_DATABASE_H_
6 #define CHROME_BROWSER_HISTORY_URL_DATABASE_H_
7 #pragma once
8 
9 #include "app/sql/statement.h"
10 #include "base/basictypes.h"
11 #include "chrome/browser/history/history_types.h"
12 #include "chrome/browser/search_engines/template_url_id.h"
13 
14 class GURL;
15 
16 namespace sql {
17 class Connection;
18 }
19 
20 namespace history {
21 
22 class VisitDatabase;  // For friend statement.
23 
24 // Encapsulates an SQL database that holds URL info.  This is a subset of the
25 // full history data.  We split this class' functionality out from the larger
26 // HistoryDatabase class to support maintaining separate databases of URLs with
27 // different capabilities (for example, in-memory, or archived).
28 //
29 // This is refcounted to support calling InvokeLater() with some of its methods
30 // (necessary to maintain ordering of DB operations).
31 class URLDatabase {
32  public:
33   // Must call CreateURLTable() and CreateURLIndexes() before using to make
34   // sure the database is initialized.
35   URLDatabase();
36 
37   // This object must be destroyed on the thread where all accesses are
38   // happening to avoid thread-safety problems.
39   virtual ~URLDatabase();
40 
41   // Converts a GURL to a string used in the history database. We plan to
42   // do more complex operations than just getting the spec out involving
43   // punycode, so this function should be used instead of url.spec() when
44   // interacting with the database.
45   //
46   // TODO(brettw) this should be moved out of the public section and the
47   // entire public HistoryDatabase interface should use GURL. This should
48   // also probably return a string instead since that is what the DB uses
49   // internally and we can avoid the extra conversion.
50   static std::string GURLToDatabaseURL(const GURL& url);
51 
52   // URL table functions -------------------------------------------------------
53 
54   // Looks up a url given an id. Fills info with the data. Returns true on
55   // success and false otherwise.
56   bool GetURLRow(URLID url_id, URLRow* info);
57 
58   // Looks up all urls that were typed in manually. Fills info with the data.
59   // Returns true on success and false otherwise.
60   bool GetAllTypedUrls(std::vector<history::URLRow>* urls);
61 
62   // Looks up the given URL and if it exists, fills the given pointers with the
63   // associated info and returns the ID of that URL. If the info pointer is
64   // NULL, no information about the URL will be filled in, only the ID will be
65   // returned. Returns 0 if the URL was not found.
66   URLID GetRowForURL(const GURL& url, URLRow* info);
67 
68   // Given an already-existing row in the URL table, updates that URL's stats.
69   // This can not change the URL.  Returns true on success.
70   //
71   // This will NOT update the title used for full text indexing. If you are
72   // setting the title, call SetPageIndexedData with the new title.
73   bool UpdateURLRow(URLID url_id, const URLRow& info);
74 
75   // Adds a line to the URL database with the given information and returns the
76   // row ID. A row with the given URL must not exist. Returns 0 on error.
77   //
78   // This does NOT add a row to the full text search database. Use
79   // HistoryDatabase::SetPageIndexedData to do this.
AddURL(const URLRow & info)80   URLID AddURL(const URLRow& info) {
81     return AddURLInternal(info, false);
82   }
83 
84   // Delete the row of the corresponding URL. Only the row in the URL table
85   // will be deleted, not any other data that may refer to it. Returns true if
86   // the row existed and was deleted.
87   bool DeleteURLRow(URLID id);
88 
89   // URL mass-deleting ---------------------------------------------------------
90 
91   // Begins the mass-deleting operation by creating a temporary URL table.
92   // The caller than adds the URLs it wants to preseve to the temporary table,
93   // and then deletes everything else by calling CommitTemporaryURLTable().
94   // Returns true on success.
95   bool CreateTemporaryURLTable();
96 
97   // Adds a row to the temporary URL table. This must be called between
98   // CreateTemporaryURLTable() and CommitTemporaryURLTable() (see those for more
99   // info). The ID of the URL will change in the temporary table, so the new ID
100   // is returned. Returns 0 on failure.
AddTemporaryURL(const URLRow & row)101   URLID AddTemporaryURL(const URLRow& row) {
102     return AddURLInternal(row, true);
103   }
104 
105   // Ends the mass-deleting by replacing the original URL table with the
106   // temporary one created in CreateTemporaryURLTable. Returns true on success.
107   //
108   // This function does not create the supplimentary indices. It is virtual so
109   // that the main history database can provide this additional behavior.
110   virtual bool CommitTemporaryURLTable();
111 
112   // Enumeration ---------------------------------------------------------------
113 
114   // A basic enumerator to enumerate urls database.
115   class URLEnumeratorBase {
116    public:
117     URLEnumeratorBase();
118     virtual ~URLEnumeratorBase();
119 
120    private:
121     friend class URLDatabase;
122 
123     bool initialized_;
124     sql::Statement statement_;
125 
126     DISALLOW_COPY_AND_ASSIGN(URLEnumeratorBase);
127   };
128 
129   // A basic enumerator to enumerate urls
130   class URLEnumerator : public URLEnumeratorBase {
131    public:
132     URLEnumerator();
133 
134     // Retreives the next url. Returns false if no more urls are available
135     bool GetNextURL(history::URLRow* r);
136 
137    private:
138     DISALLOW_COPY_AND_ASSIGN(URLEnumerator);
139   };
140 
141   // A basic enumerator to enumerate icon mapping, it is only used for icon
142   // mapping migration.
143   class IconMappingEnumerator : public URLEnumeratorBase {
144    public:
145     IconMappingEnumerator();
146 
147     // Retreives the next url. Returns false if no more urls are available
148     bool GetNextIconMapping(IconMapping* r);
149 
150    private:
151     DISALLOW_COPY_AND_ASSIGN(IconMappingEnumerator);
152   };
153 
154   // Initializes the given enumerator to enumerator all URLs in the database.
155   bool InitURLEnumeratorForEverything(URLEnumerator* enumerator);
156 
157   // Initializes the given enumerator to enumerator all URLs in the database
158   // that are historically significant: ones having been visited within 3 days,
159   // having their URL manually typed more than once, or having been visited
160   // more than 3 times.
161   bool InitURLEnumeratorForSignificant(URLEnumerator* enumerator);
162 
163   // Favicons ------------------------------------------------------------------
164 
165   // Autocomplete --------------------------------------------------------------
166 
167   // Fills the given array with URLs matching the given prefix. They will be
168   // sorted by typed count, then by visit count, then by visit date (most recent
169   // first) up to the given maximum number.  If |typed_only| is true, only urls
170   // that have been typed once are returned. Called by HistoryURLProvider.
171   void AutocompleteForPrefix(const string16& prefix,
172                              size_t max_results,
173                              bool typed_only,
174                              std::vector<URLRow>* results);
175 
176   // Tries to find the shortest URL beginning with |base| that strictly
177   // prefixes |url|, and has minimum visit_ and typed_counts as specified.
178   // If found, fills in |info| and returns true; otherwise returns false,
179   // leaving |info| unchanged.
180   // We allow matches of exactly |base| iff |allow_base| is true.
181   bool FindShortestURLFromBase(const std::string& base,
182                                const std::string& url,
183                                int min_visits,
184                                int min_typed,
185                                bool allow_base,
186                                history::URLRow* info);
187 
188   // Keyword Search Terms ------------------------------------------------------
189 
190   // Sets the search terms for the specified url/keyword pair.
191   bool SetKeywordSearchTermsForURL(URLID url_id,
192                                    TemplateURLID keyword_id,
193                                    const string16& term);
194 
195   // Looks up a keyword search term given a url id. Fills row with the data.
196   // Returns true on success and false otherwise.
197   bool GetKeywordSearchTermRow(URLID url_id, KeywordSearchTermRow* row);
198 
199   // Deletes all search terms for the specified keyword that have been added by
200   // way of SetKeywordSearchTermsForURL.
201   void DeleteAllSearchTermsForKeyword(TemplateURLID keyword_id);
202 
203   // Returns up to max_count of the most recent search terms for the specified
204   // keyword.
205   void GetMostRecentKeywordSearchTerms(
206       TemplateURLID keyword_id,
207       const string16& prefix,
208       int max_count,
209       std::vector<KeywordSearchTermVisit>* matches);
210 
211   // Migration -----------------------------------------------------------------
212 
213   // Do to a bug we were setting the favicon of about:blank. This forces
214   // about:blank to have no icon or title. Returns true on success, false if
215   // the favicon couldn't be updated.
216   bool MigrateFromVersion11ToVersion12();
217 
218   // Initializes the given enumerator to enumerator all URL and icon mappings
219   // in the database. Only used for icon mapping migration.
220   bool InitIconMappingEnumeratorForEverything(
221       IconMappingEnumerator* enumerator);
222 
223  protected:
224   friend class VisitDatabase;
225 
226   // See HISTORY_URL_ROW_FIELDS below.
227   static const char kURLRowFields[];
228 
229   // The number of fiends in kURLRowFields. If callers need additional
230   // fields, they can add their 0-based index to this value to get the index of
231   // fields following kURLRowFields.
232   static const int kNumURLRowFields;
233 
234   // Drops the starred_id column from urls, returning true on success. This does
235   // nothing (and returns true) if the urls doesn't contain the starred_id
236   // column.
237   bool DropStarredIDFromURLs();
238 
239   // Initialization functions. The indexing functions are separate from the
240   // table creation functions so the in-memory database and the temporary tables
241   // used when clearing history can populate the table and then create the
242   // index, which is faster than the reverse.
243   //
244   // is_temporary is false when generating the "regular" URLs table. The expirer
245   // sets this to true to generate the  temporary table, which will have a
246   // different name but the same schema.
247   bool CreateURLTable(bool is_temporary);
248   // We have two tiers of indices for the URL table. The main tier is used by
249   // all URL databases, and is an index over the URL itself.
250   void CreateMainURLIndex();
251 
252   // Ensures the keyword search terms table exists.
253   bool InitKeywordSearchTermsTable();
254 
255   // Creates the indices used for keyword search terms.
256   void CreateKeywordSearchTermsIndices();
257 
258   // Deletes the keyword search terms table.
259   bool DropKeywordSearchTermsTable();
260 
261   // Inserts the given URL row into the URLs table, using the regular table
262   // if is_temporary is false, or the temporary URL table if is temporary is
263   // true. The temporary table may only be used in between
264   // CreateTemporaryURLTable() and CommitTemporaryURLTable().
265   URLID AddURLInternal(const URLRow& info, bool is_temporary);
266 
267   // Convenience to fill a history::URLRow. Must be in sync with the fields in
268   // kHistoryURLRowFields.
269   static void FillURLRow(sql::Statement& s, URLRow* i);
270 
271   // Returns the database for the functions in this interface. The decendent of
272   // this class implements these functions to return its objects.
273   virtual sql::Connection& GetDB() = 0;
274 
275  private:
276   // True if InitKeywordSearchTermsTable() has been invoked. Not all subclasses
277   // have keyword search terms.
278   bool has_keyword_search_terms_;
279 
280   DISALLOW_COPY_AND_ASSIGN(URLDatabase);
281 };
282 
283 // The fields and order expected by FillURLRow(). ID is guaranteed to be first
284 // so that DISTINCT can be prepended to get distinct URLs.
285 //
286 // This is available BOTH as a macro and a static string (kURLRowFields). Use
287 // the macro if you want to put this in the middle of an otherwise constant
288 // string, it will save time doing string appends. If you have to build a SQL
289 // string dynamically anyway, use the constant, it will save space.
290 #define HISTORY_URL_ROW_FIELDS \
291     " urls.id, urls.url, urls.title, urls.visit_count, urls.typed_count, " \
292     "urls.last_visit_time, urls.hidden "
293 
294 }  // history
295 
296 #endif  // CHROME_BROWSER_HISTORY_URL_DATABASE_H_
297