Home | History | Annotate | Download | only in history
      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_URL_DATABASE_H_
      6 #define CHROME_BROWSER_HISTORY_URL_DATABASE_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "chrome/browser/history/history_types.h"
     10 #include "chrome/browser/history/query_parser.h"
     11 #include "chrome/browser/search_engines/template_url_id.h"
     12 #include "sql/statement.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(URLRows* 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.  For caller convenience, returns
    171   // whether any results were found.
    172   bool AutocompleteForPrefix(const std::string& prefix,
    173                              size_t max_results,
    174                              bool typed_only,
    175                              URLRows* results);
    176 
    177   // Returns true if the database holds some past typed navigation to a URL on
    178   // the provided hostname.
    179   bool IsTypedHost(const std::string& host);
    180 
    181   // Tries to find the shortest URL beginning with |base| that strictly
    182   // prefixes |url|, and has minimum visit_ and typed_counts as specified.
    183   // If found, fills in |info| and returns true; otherwise returns false,
    184   // leaving |info| unchanged.
    185   // We allow matches of exactly |base| iff |allow_base| is true.
    186   bool FindShortestURLFromBase(const std::string& base,
    187                                const std::string& url,
    188                                int min_visits,
    189                                int min_typed,
    190                                bool allow_base,
    191                                history::URLRow* info);
    192 
    193   // History search ------------------------------------------------------------
    194 
    195   // Performs a brute force search over the database to find any URLs or titles
    196   // which match the |query| string.  Returns any matches in |results|.
    197   bool GetTextMatches(const string16& query, URLRows* results);
    198 
    199   // Keyword Search Terms ------------------------------------------------------
    200 
    201   // Sets the search terms for the specified url/keyword pair.
    202   bool SetKeywordSearchTermsForURL(URLID url_id,
    203                                    TemplateURLID keyword_id,
    204                                    const string16& term);
    205 
    206   // Looks up a keyword search term given a url id. Returns all the search terms
    207   // in |rows|. Returns true on success.
    208   bool GetKeywordSearchTermRow(URLID url_id, KeywordSearchTermRow* row);
    209 
    210   // Looks up all keyword search terms given a term, Fills the rows with data.
    211   // Returns true on success and false otherwise.
    212   bool GetKeywordSearchTermRows(const string16& term,
    213                                 std::vector<KeywordSearchTermRow>* rows);
    214 
    215   // Deletes all search terms for the specified keyword that have been added by
    216   // way of SetKeywordSearchTermsForURL.
    217   void DeleteAllSearchTermsForKeyword(TemplateURLID keyword_id);
    218 
    219   // Returns up to max_count of the most recent search terms for the specified
    220   // keyword.
    221   void GetMostRecentKeywordSearchTerms(
    222       TemplateURLID keyword_id,
    223       const string16& prefix,
    224       int max_count,
    225       std::vector<KeywordSearchTermVisit>* matches);
    226 
    227   // Deletes all searches matching |term|.
    228   bool DeleteKeywordSearchTerm(const string16& term);
    229 
    230   // Migration -----------------------------------------------------------------
    231 
    232   // Do to a bug we were setting the favicon of about:blank. This forces
    233   // about:blank to have no icon or title. Returns true on success, false if
    234   // the favicon couldn't be updated.
    235   bool MigrateFromVersion11ToVersion12();
    236 
    237   // Initializes the given enumerator to enumerator all URL and icon mappings
    238   // in the database. Only used for icon mapping migration.
    239   bool InitIconMappingEnumeratorForEverything(
    240       IconMappingEnumerator* enumerator);
    241 
    242  protected:
    243   friend class VisitDatabase;
    244 
    245   // See HISTORY_URL_ROW_FIELDS below.
    246   static const char kURLRowFields[];
    247 
    248   // The number of fiends in kURLRowFields. If callers need additional
    249   // fields, they can add their 0-based index to this value to get the index of
    250   // fields following kURLRowFields.
    251   static const int kNumURLRowFields;
    252 
    253   // Drops the starred_id column from urls, returning true on success. This does
    254   // nothing (and returns true) if the urls doesn't contain the starred_id
    255   // column.
    256   bool DropStarredIDFromURLs();
    257 
    258   // Initialization functions. The indexing functions are separate from the
    259   // table creation functions so the in-memory database and the temporary tables
    260   // used when clearing history can populate the table and then create the
    261   // index, which is faster than the reverse.
    262   //
    263   // is_temporary is false when generating the "regular" URLs table. The expirer
    264   // sets this to true to generate the  temporary table, which will have a
    265   // different name but the same schema.
    266   bool CreateURLTable(bool is_temporary);
    267   // We have two tiers of indices for the URL table. The main tier is used by
    268   // all URL databases, and is an index over the URL itself.
    269   bool CreateMainURLIndex();
    270 
    271   // Ensures the keyword search terms table exists.
    272   bool InitKeywordSearchTermsTable();
    273 
    274   // Creates the indices used for keyword search terms.
    275   bool CreateKeywordSearchTermsIndices();
    276 
    277   // Deletes the keyword search terms table.
    278   bool DropKeywordSearchTermsTable();
    279 
    280   // Inserts the given URL row into the URLs table, using the regular table
    281   // if is_temporary is false, or the temporary URL table if is temporary is
    282   // true. The temporary table may only be used in between
    283   // CreateTemporaryURLTable() and CommitTemporaryURLTable().
    284   URLID AddURLInternal(const URLRow& info, bool is_temporary);
    285 
    286   // Convenience to fill a history::URLRow. Must be in sync with the fields in
    287   // kHistoryURLRowFields.
    288   static void FillURLRow(sql::Statement& s, URLRow* i);
    289 
    290   // Returns the database for the functions in this interface. The decendent of
    291   // this class implements these functions to return its objects.
    292   virtual sql::Connection& GetDB() = 0;
    293 
    294  private:
    295   // True if InitKeywordSearchTermsTable() has been invoked. Not all subclasses
    296   // have keyword search terms.
    297   bool has_keyword_search_terms_;
    298 
    299   QueryParser query_parser_;
    300 
    301   DISALLOW_COPY_AND_ASSIGN(URLDatabase);
    302 };
    303 
    304 // The fields and order expected by FillURLRow(). ID is guaranteed to be first
    305 // so that DISTINCT can be prepended to get distinct URLs.
    306 //
    307 // This is available BOTH as a macro and a static string (kURLRowFields). Use
    308 // the macro if you want to put this in the middle of an otherwise constant
    309 // string, it will save time doing string appends. If you have to build a SQL
    310 // string dynamically anyway, use the constant, it will save space.
    311 #define HISTORY_URL_ROW_FIELDS \
    312     " urls.id, urls.url, urls.title, urls.visit_count, urls.typed_count, " \
    313     "urls.last_visit_time, urls.hidden "
    314 
    315 }  // namespace history
    316 
    317 #endif  // CHROME_BROWSER_HISTORY_URL_DATABASE_H_
    318