Home | History | Annotate | Download | only in predictors
      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 
     28 LoggedInPredictorTable::LoggedInPredictorTable()
     29     : PredictorTableBase() {
     30 }
     31 
     32 LoggedInPredictorTable::~LoggedInPredictorTable() {
     33 }
     34 
     35 // static
     36 string LoggedInPredictorTable::GetKey(const GURL& url) {
     37   return GetKeyFromDomain(url.host());
     38 }
     39 
     40 // static
     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 
     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 
     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 
     83 void LoggedInPredictorTable::DeleteDomain(const std::string& domain) {
     84   DeleteDomainFromURL(GURL("http://" + domain));
     85 }
     86 
     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 
    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 
    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 
    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 
    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