1// Copyright 2014 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 COMPONENTS_HISTORY_CORE_BROWSER_URL_ROW_H_
6#define COMPONENTS_HISTORY_CORE_BROWSER_URL_ROW_H_
7
8#include "base/basictypes.h"
9#include "base/strings/string16.h"
10#include "base/time/time.h"
11#include "components/query_parser/snippet.h"
12#include "url/gurl.h"
13
14namespace history {
15
16typedef int64 URLID;
17
18// Holds all information globally associated with one URL (one row in the
19// URL table).
20//
21// This keeps track of dirty bits, which are currently unused:
22//
23// TODO(brettw) the dirty bits are broken in a number of respects. First, the
24// database will want to update them on a const object, so they need to be
25// mutable.
26//
27// Second, there is a problem copying. If you make a copy of this structure
28// (as we allow since we put this into vectors in various places) then the
29// dirty bits will not be in sync for these copies.
30class URLRow {
31 public:
32  URLRow();
33
34  explicit URLRow(const GURL& url);
35
36  // We need to be able to set the id of a URLRow that's being passed through
37  // an IPC message.  This constructor should probably not be used otherwise.
38  URLRow(const GURL& url, URLID id);
39
40  virtual ~URLRow();
41  URLRow& operator=(const URLRow& other);
42
43  URLID id() const { return id_; }
44
45  // Sets the id of the row. The id should only be manually set when a row has
46  // been retrieved from the history database or other dataset based on criteria
47  // other than its id (i.e. by URL) and when the id has not yet been set in the
48  // row.
49  void set_id(URLID id) { id_ = id; }
50
51  const GURL& url() const { return url_; }
52
53  const base::string16& title() const {
54    return title_;
55  }
56  void set_title(const base::string16& title) {
57    // The title is frequently set to the same thing, so we don't bother
58    // updating unless the string has changed.
59    if (title != title_) {
60      title_ = title;
61    }
62  }
63
64  // The number of times this URL has been visited. This will often match the
65  // number of entries in the visit table for this URL, but won't always. It's
66  // really designed for autocomplete ranking, so some "useless" transitions
67  // from the visit table aren't counted in this tally.
68  int visit_count() const {
69    return visit_count_;
70  }
71  void set_visit_count(int visit_count) {
72    visit_count_ = visit_count;
73  }
74
75  // Number of times the URL was typed in the Omnibox. This "should" match
76  // the number of TYPED transitions in the visit table. It's used primarily
77  // for faster autocomplete ranking. If you need to know the actual number of
78  // TYPED transitions, you should query the visit table since there could be
79  // something out of sync.
80  int typed_count() const {
81    return typed_count_;
82  }
83  void set_typed_count(int typed_count) {
84    typed_count_ = typed_count;
85  }
86
87  base::Time last_visit() const {
88    return last_visit_;
89  }
90  void set_last_visit(base::Time last_visit) {
91    last_visit_ = last_visit;
92  }
93
94  // If this is set, we won't autocomplete this URL.
95  bool hidden() const {
96    return hidden_;
97  }
98  void set_hidden(bool hidden) {
99    hidden_ = hidden;
100  }
101
102  // Helper functor that determines if an URLRow refers to a given URL.
103  class URLRowHasURL {
104   public:
105    explicit URLRowHasURL(const GURL& url) : url_(url) {}
106
107    bool operator()(const URLRow& row) {
108      return row.url() == url_;
109    }
110
111   private:
112    const GURL& url_;
113  };
114
115 protected:
116  // Swaps the contents of this URLRow with another, which allows it to be
117  // destructively copied without memory allocations.
118  void Swap(URLRow* other);
119
120 private:
121  // This class writes directly into this structure and clears our dirty bits
122  // when reading out of the DB.
123  friend class URLDatabase;
124  friend class HistoryBackend;
125
126  // Initializes all values that need initialization to their defaults.
127  // This excludes objects which autoinitialize such as strings.
128  void Initialize();
129
130  // The row ID of this URL from the history database. This is immutable except
131  // when retrieving the row from the database or when determining if the URL
132  // referenced by the URLRow already exists in the database.
133  URLID id_;
134
135  // The URL of this row. Immutable except for the database which sets it
136  // when it pulls them out. If clients want to change it, they must use
137  // the constructor to make a new one.
138  GURL url_;
139
140  base::string16 title_;
141
142  // Total number of times this URL has been visited.
143  int visit_count_;
144
145  // Number of times this URL has been manually entered in the URL bar.
146  int typed_count_;
147
148  // The date of the last visit of this URL, which saves us from having to
149  // loop up in the visit table for things like autocomplete and expiration.
150  base::Time last_visit_;
151
152  // Indicates this entry should now be shown in typical UI or queries, this
153  // is usually for subframes.
154  bool hidden_;
155
156  // We support the implicit copy constuctor and operator=.
157};
158typedef std::vector<URLRow> URLRows;
159
160
161class URLResult : public URLRow {
162 public:
163  URLResult();
164  URLResult(const GURL& url, base::Time visit_time);
165  // Constructor that create a URLResult from the specified URL and title match
166  // positions from title_matches.
167  URLResult(const GURL& url,
168            const query_parser::Snippet::MatchPositions& title_matches);
169  explicit URLResult(const URLRow& url_row);
170  virtual ~URLResult();
171
172  base::Time visit_time() const { return visit_time_; }
173  void set_visit_time(base::Time visit_time) { visit_time_ = visit_time; }
174
175  const query_parser::Snippet& snippet() const { return snippet_; }
176
177  bool blocked_visit() const { return blocked_visit_; }
178  void set_blocked_visit(bool blocked_visit) {
179    blocked_visit_ = blocked_visit;
180  }
181
182  // If this is a title match, title_match_positions contains an entry for
183  // every word in the title that matched one of the query parameters. Each
184  // entry contains the start and end of the match.
185  const query_parser::Snippet::MatchPositions& title_match_positions() const {
186    return title_match_positions_;
187  }
188
189  void SwapResult(URLResult* other);
190
191  static bool CompareVisitTime(const URLResult& lhs, const URLResult& rhs);
192
193 private:
194  friend class HistoryBackend;
195
196  // The time that this result corresponds to.
197  base::Time visit_time_;
198
199  // These values are typically set by HistoryBackend.
200  query_parser::Snippet snippet_;
201  query_parser::Snippet::MatchPositions title_match_positions_;
202
203  // Whether a managed user was blocked when attempting to visit this URL.
204  bool blocked_visit_;
205
206  // We support the implicit copy constructor and operator=.
207};
208
209}  // namespace history
210
211#endif  // COMPONENTS_HISTORY_CORE_BROWSER_URL_ROW_H_
212