• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 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 #include "chrome/browser/predictors/logged_in_predictor_table.h"
6 
7 #include <algorithm>
8 #include <utility>
9 #include "base/logging.h"
10 #include "base/metrics/histogram.h"
11 #include "base/strings/stringprintf.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
14 #include "sql/statement.h"
15 
16 using content::BrowserThread;
17 using sql::Statement;
18 using std::string;
19 
20 namespace {
21 
22 const char kTableName[] = "logged_in_predictor";
23 
24 }  // namespace
25 
26 namespace predictors {
27 
LoggedInPredictorTable()28 LoggedInPredictorTable::LoggedInPredictorTable()
29     : PredictorTableBase() {
30 }
31 
~LoggedInPredictorTable()32 LoggedInPredictorTable::~LoggedInPredictorTable() {
33 }
34 
35 // static
GetKey(const GURL & url)36 string LoggedInPredictorTable::GetKey(const GURL& url) {
37   return GetKeyFromDomain(url.host());
38 }
39 
40 // static
GetKeyFromDomain(const std::string & domain)41 string LoggedInPredictorTable::GetKeyFromDomain(const std::string& domain) {
42   string effective_domain(
43       net::registry_controlled_domains::GetDomainAndRegistry(
44           domain,
45           net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES));
46   if (effective_domain.empty())
47     effective_domain = domain;
48 
49   // Strip off a preceding ".", if present.
50   if (!effective_domain.empty() && effective_domain[0] == '.')
51     return effective_domain.substr(1);
52   return effective_domain;
53 }
54 
AddDomainFromURL(const GURL & url)55 void LoggedInPredictorTable::AddDomainFromURL(const GURL& url) {
56   CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
57   if (CantAccessDatabase())
58     return;
59 
60   Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
61       base::StringPrintf("INSERT OR IGNORE INTO %s (domain, time) VALUES (?,?)",
62                          kTableName).c_str()));
63 
64   statement.BindString(0, GetKey(url));
65   statement.BindInt64(1, base::Time::Now().ToInternalValue());
66 
67   statement.Run();
68 }
69 
DeleteDomainFromURL(const GURL & url)70 void LoggedInPredictorTable::DeleteDomainFromURL(const GURL& url) {
71   CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
72   if (CantAccessDatabase())
73     return;
74 
75   Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
76       base::StringPrintf("DELETE FROM %s WHERE domain=?", kTableName).c_str()));
77 
78   statement.BindString(0, GetKey(url));
79 
80   statement.Run();
81 }
82 
DeleteDomain(const std::string & domain)83 void LoggedInPredictorTable::DeleteDomain(const std::string& domain) {
84   DeleteDomainFromURL(GURL("http://" + domain));
85 }
86 
HasUserLoggedIn(const GURL & url,bool * is_present,bool * lookup_succeeded)87 void LoggedInPredictorTable::HasUserLoggedIn(const GURL& url, bool* is_present,
88                                              bool* lookup_succeeded) {
89   CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
90   *lookup_succeeded = false;
91   if (CantAccessDatabase())
92     return;
93 
94   Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
95       base::StringPrintf("SELECT count(*) FROM %s WHERE domain=?",
96                          kTableName).c_str()));
97 
98   statement.BindString(0, GetKey(url));
99 
100   if (statement.Step()) {
101     *is_present = (statement.ColumnInt(0) > 0);
102     *lookup_succeeded = true;
103   }
104 }
105 
DeleteAllCreatedBetween(const base::Time & delete_begin,const base::Time & delete_end)106 void LoggedInPredictorTable::DeleteAllCreatedBetween(
107     const base::Time& delete_begin, const base::Time& delete_end) {
108   CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
109   if (CantAccessDatabase())
110     return;
111 
112   Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
113       base::StringPrintf("DELETE FROM %s WHERE time >= ? AND time <= ?",
114                          kTableName).c_str()));
115 
116   statement.BindInt64(0, delete_begin.ToInternalValue());
117   statement.BindInt64(1, delete_end.ToInternalValue());
118 
119   statement.Run();
120 }
121 
GetAllData(LoggedInPredictorTable::LoggedInStateMap * state_map)122 void LoggedInPredictorTable::GetAllData(
123     LoggedInPredictorTable::LoggedInStateMap* state_map) {
124   CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
125   DCHECK(state_map != NULL);
126   state_map->clear();
127   if (CantAccessDatabase())
128     return;
129 
130   Statement statement(DB()->GetUniqueStatement(
131       base::StringPrintf("SELECT * FROM %s", kTableName).c_str()));
132 
133   while (statement.Step()) {
134     string domain = statement.ColumnString(0);
135     int64 value = statement.ColumnInt64(1);
136     (*state_map)[domain] = value;
137   }
138 }
139 
CreateTableIfNonExistent()140 void LoggedInPredictorTable::CreateTableIfNonExistent() {
141   CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
142   if (CantAccessDatabase())
143     return;
144 
145   sql::Connection* db = DB();
146   if (db->DoesTableExist(kTableName))
147     return;
148 
149   const char* table_creator =
150       "CREATE TABLE %s (domain TEXT, time INTEGER, PRIMARY KEY(domain))";
151 
152   if (!db->Execute(base::StringPrintf(table_creator, kTableName).c_str()))
153     ResetDB();
154 }
155 
LogDatabaseStats()156 void LoggedInPredictorTable::LogDatabaseStats()  {
157   CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
158   if (CantAccessDatabase())
159     return;
160 
161   Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
162       base::StringPrintf("SELECT count(*) FROM %s", kTableName).c_str()));
163   if (statement.Step())
164     UMA_HISTOGRAM_COUNTS("LoggedInPredictor.TableRowCount",
165                          statement.ColumnInt(0));
166 }
167 
168 }  // namespace predictors
169