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 14class GURL; 15 16namespace sql { 17class Connection; 18} 19 20namespace history { 21 22class 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). 31class 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. 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. 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