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 "components/query_parser/query_parser.h"
     11 #include "components/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, the in-memory database).
     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   // newly generated ID for the row (the |id| in |info| is ignored). A row with
     77   // the given URL must not exist. Returns 0 on error.
     78   //
     79   // This does NOT add a row to the full text search database. Use
     80   // HistoryDatabase::SetPageIndexedData to do this.
     81   URLID AddURL(const URLRow& info) {
     82     return AddURLInternal(info, false);
     83   }
     84 
     85   // Either adds a new row to the URL table with the given information (with the
     86   // the |id| as specified in |info|), or updates the pre-existing row with this
     87   // |id| if there is one already. This is also known as an "upsert" or "merge"
     88   // operation. Returns true on success.
     89   bool InsertOrUpdateURLRowByID(const URLRow& info);
     90 
     91   // Delete the row of the corresponding URL. Only the row in the URL table and
     92   // corresponding keyword search terms will be deleted, not any other data that
     93   // may refer to the URL row. Returns true if the row existed and was deleted.
     94   bool DeleteURLRow(URLID id);
     95 
     96   // URL mass-deleting ---------------------------------------------------------
     97 
     98   // Begins the mass-deleting operation by creating a temporary URL table.
     99   // The caller than adds the URLs it wants to preseve to the temporary table,
    100   // and then deletes everything else by calling CommitTemporaryURLTable().
    101   // Returns true on success.
    102   bool CreateTemporaryURLTable();
    103 
    104   // Adds a row to the temporary URL table. This must be called between
    105   // CreateTemporaryURLTable() and CommitTemporaryURLTable() (see those for more
    106   // info). The ID of the URL will change in the temporary table, so the new ID
    107   // is returned. Returns 0 on failure.
    108   URLID AddTemporaryURL(const URLRow& row) {
    109     return AddURLInternal(row, true);
    110   }
    111 
    112   // Ends the mass-deleting by replacing the original URL table with the
    113   // temporary one created in CreateTemporaryURLTable. Returns true on success.
    114   bool CommitTemporaryURLTable();
    115 
    116   // Enumeration ---------------------------------------------------------------
    117 
    118   // A basic enumerator to enumerate urls database.
    119   class URLEnumeratorBase {
    120    public:
    121     URLEnumeratorBase();
    122     virtual ~URLEnumeratorBase();
    123 
    124    private:
    125     friend class URLDatabase;
    126 
    127     bool initialized_;
    128     sql::Statement statement_;
    129 
    130     DISALLOW_COPY_AND_ASSIGN(URLEnumeratorBase);
    131   };
    132 
    133   // A basic enumerator to enumerate urls
    134   class URLEnumerator : public URLEnumeratorBase {
    135    public:
    136     URLEnumerator();
    137 
    138     // Retreives the next url. Returns false if no more urls are available
    139     bool GetNextURL(history::URLRow* r);
    140 
    141    private:
    142     DISALLOW_COPY_AND_ASSIGN(URLEnumerator);
    143   };
    144 
    145   // Initializes the given enumerator to enumerator all URLs in the database.
    146   bool InitURLEnumeratorForEverything(URLEnumerator* enumerator);
    147 
    148   // Initializes the given enumerator to enumerator all URLs in the database
    149   // that are historically significant: ones having been visited within 3 days,
    150   // having their URL manually typed more than once, or having been visited
    151   // more than 3 times.
    152   bool InitURLEnumeratorForSignificant(URLEnumerator* enumerator);
    153 
    154   // Favicons ------------------------------------------------------------------
    155 
    156   // Autocomplete --------------------------------------------------------------
    157 
    158   // Fills the given array with URLs matching the given prefix.  They will be
    159   // sorted by typed count, then by visit count, then by visit date (most recent
    160   // first) up to the given maximum number.  If |typed_only| is true, only urls
    161   // that have been typed once are returned.  For caller convenience, returns
    162   // whether any results were found.
    163   bool AutocompleteForPrefix(const std::string& prefix,
    164                              size_t max_results,
    165                              bool typed_only,
    166                              URLRows* results);
    167 
    168   // Returns true if the database holds some past typed navigation to a URL on
    169   // the provided hostname.
    170   bool IsTypedHost(const std::string& host);
    171 
    172   // Tries to find the shortest URL beginning with |base| that strictly
    173   // prefixes |url|, and has minimum visit_ and typed_counts as specified.
    174   // If found, fills in |info| and returns true; otherwise returns false,
    175   // leaving |info| unchanged.
    176   // We allow matches of exactly |base| iff |allow_base| is true.
    177   bool FindShortestURLFromBase(const std::string& base,
    178                                const std::string& url,
    179                                int min_visits,
    180                                int min_typed,
    181                                bool allow_base,
    182                                history::URLRow* info);
    183 
    184   // History search ------------------------------------------------------------
    185 
    186   // Performs a brute force search over the database to find any URLs or titles
    187   // which match the |query| string.  Returns any matches in |results|.
    188   bool GetTextMatches(const base::string16& query, URLRows* results);
    189 
    190   // Keyword Search Terms ------------------------------------------------------
    191 
    192   // Sets the search terms for the specified url/keyword pair.
    193   bool SetKeywordSearchTermsForURL(URLID url_id,
    194                                    TemplateURLID keyword_id,
    195                                    const base::string16& term);
    196 
    197   // Looks up a keyword search term given a url id. Returns all the search terms
    198   // in |rows|. Returns true on success.
    199   bool GetKeywordSearchTermRow(URLID url_id, KeywordSearchTermRow* row);
    200 
    201   // Looks up all keyword search terms given a term, Fills the rows with data.
    202   // Returns true on success and false otherwise.
    203   bool GetKeywordSearchTermRows(const base::string16& term,
    204                                 std::vector<KeywordSearchTermRow>* rows);
    205 
    206   // Deletes all search terms for the specified keyword that have been added by
    207   // way of SetKeywordSearchTermsForURL.
    208   void DeleteAllSearchTermsForKeyword(TemplateURLID keyword_id);
    209 
    210   // Returns up to max_count of the most recent search terms for the specified
    211   // keyword.
    212   void GetMostRecentKeywordSearchTerms(
    213       TemplateURLID keyword_id,
    214       const base::string16& prefix,
    215       int max_count,
    216       std::vector<KeywordSearchTermVisit>* matches);
    217 
    218   // Deletes all searches matching |term|.
    219   bool DeleteKeywordSearchTerm(const base::string16& term);
    220 
    221   // Deletes any search corresponding to |url_id|.
    222   bool DeleteKeywordSearchTermForURL(URLID url_id);
    223 
    224   // Migration -----------------------------------------------------------------
    225 
    226   // Do to a bug we were setting the favicon of about:blank. This forces
    227   // about:blank to have no icon or title. Returns true on success, false if
    228   // the favicon couldn't be updated.
    229   bool MigrateFromVersion11ToVersion12();
    230 
    231  protected:
    232   friend class VisitDatabase;
    233 
    234   // See HISTORY_URL_ROW_FIELDS below.
    235   static const char kURLRowFields[];
    236 
    237   // The number of fiends in kURLRowFields. If callers need additional
    238   // fields, they can add their 0-based index to this value to get the index of
    239   // fields following kURLRowFields.
    240   static const int kNumURLRowFields;
    241 
    242   // Drops the starred_id column from urls, returning true on success. This does
    243   // nothing (and returns true) if the urls doesn't contain the starred_id
    244   // column.
    245   bool DropStarredIDFromURLs();
    246 
    247   // Initialization functions. The indexing functions are separate from the
    248   // table creation functions so the in-memory database and the temporary tables
    249   // used when clearing history can populate the table and then create the
    250   // index, which is faster than the reverse.
    251   //
    252   // is_temporary is false when generating the "regular" URLs table. The expirer
    253   // sets this to true to generate the  temporary table, which will have a
    254   // different name but the same schema.
    255   bool CreateURLTable(bool is_temporary);
    256 
    257   // Creates the index over URLs so we can quickly look up based on URL.
    258   bool CreateMainURLIndex();
    259 
    260   // Ensures the keyword search terms table exists.
    261   bool InitKeywordSearchTermsTable();
    262 
    263   // Creates the indices used for keyword search terms.
    264   bool CreateKeywordSearchTermsIndices();
    265 
    266   // Deletes the keyword search terms table.
    267   bool DropKeywordSearchTermsTable();
    268 
    269   // Inserts the given URL row into the URLs table, using the regular table
    270   // if is_temporary is false, or the temporary URL table if is temporary is
    271   // true. The current |id| of |info| will be ignored in both cases and a new ID
    272   // will be generated, which will also constitute the return value, except in
    273   // case of an error, when the return value is 0. The temporary table may only
    274   // be used in between CreateTemporaryURLTable() and CommitTemporaryURLTable().
    275   URLID AddURLInternal(const URLRow& info, bool is_temporary);
    276 
    277   // Convenience to fill a history::URLRow. Must be in sync with the fields in
    278   // kHistoryURLRowFields.
    279   static void FillURLRow(sql::Statement& s, URLRow* i);
    280 
    281   // Returns the database for the functions in this interface. The decendent of
    282   // this class implements these functions to return its objects.
    283   virtual sql::Connection& GetDB() = 0;
    284 
    285  private:
    286   // True if InitKeywordSearchTermsTable() has been invoked. Not all subclasses
    287   // have keyword search terms.
    288   bool has_keyword_search_terms_;
    289 
    290   query_parser::QueryParser query_parser_;
    291 
    292   DISALLOW_COPY_AND_ASSIGN(URLDatabase);
    293 };
    294 
    295 // The fields and order expected by FillURLRow(). ID is guaranteed to be first
    296 // so that DISTINCT can be prepended to get distinct URLs.
    297 //
    298 // This is available BOTH as a macro and a static string (kURLRowFields). Use
    299 // the macro if you want to put this in the middle of an otherwise constant
    300 // string, it will save time doing string appends. If you have to build a SQL
    301 // string dynamically anyway, use the constant, it will save space.
    302 #define HISTORY_URL_ROW_FIELDS \
    303     " urls.id, urls.url, urls.title, urls.visit_count, urls.typed_count, " \
    304     "urls.last_visit_time, urls.hidden "
    305 
    306 }  // namespace history
    307 
    308 #endif  // CHROME_BROWSER_HISTORY_URL_DATABASE_H_
    309