blob: cbeee47c958d1f10e7152118e2e21fbd04382fb5 [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/predictors/logged_in_predictor_table.h"
#include <algorithm>
#include <utility>
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/strings/stringprintf.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "sql/statement.h"
using content::BrowserThread;
using sql::Statement;
using std::string;
namespace {
const char kTableName[] = "logged_in_predictor";
} // namespace
namespace predictors {
LoggedInPredictorTable::LoggedInPredictorTable()
: PredictorTableBase() {
}
LoggedInPredictorTable::~LoggedInPredictorTable() {
}
// static
string LoggedInPredictorTable::GetKey(const GURL& url) {
return GetKeyFromDomain(url.host());
}
// static
string LoggedInPredictorTable::GetKeyFromDomain(const std::string& domain) {
string effective_domain(
net::registry_controlled_domains::GetDomainAndRegistry(
domain,
net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES));
if (effective_domain.empty())
effective_domain = domain;
// Strip off a preceding ".", if present.
if (!effective_domain.empty() && effective_domain[0] == '.')
return effective_domain.substr(1);
return effective_domain;
}
void LoggedInPredictorTable::AddDomainFromURL(const GURL& url) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
if (CantAccessDatabase())
return;
Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
base::StringPrintf("INSERT OR IGNORE INTO %s (domain, time) VALUES (?,?)",
kTableName).c_str()));
statement.BindString(0, GetKey(url));
statement.BindInt64(1, base::Time::Now().ToInternalValue());
statement.Run();
}
void LoggedInPredictorTable::DeleteDomainFromURL(const GURL& url) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
if (CantAccessDatabase())
return;
Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
base::StringPrintf("DELETE FROM %s WHERE domain=?", kTableName).c_str()));
statement.BindString(0, GetKey(url));
statement.Run();
}
void LoggedInPredictorTable::DeleteDomain(const std::string& domain) {
DeleteDomainFromURL(GURL("http://" + domain));
}
void LoggedInPredictorTable::HasUserLoggedIn(const GURL& url, bool* is_present,
bool* lookup_succeeded) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
*lookup_succeeded = false;
if (CantAccessDatabase())
return;
Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
base::StringPrintf("SELECT count(*) FROM %s WHERE domain=?",
kTableName).c_str()));
statement.BindString(0, GetKey(url));
if (statement.Step()) {
*is_present = (statement.ColumnInt(0) > 0);
*lookup_succeeded = true;
}
}
void LoggedInPredictorTable::DeleteAllCreatedBetween(
const base::Time& delete_begin, const base::Time& delete_end) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
if (CantAccessDatabase())
return;
Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
base::StringPrintf("DELETE FROM %s WHERE time >= ? AND time <= ?",
kTableName).c_str()));
statement.BindInt64(0, delete_begin.ToInternalValue());
statement.BindInt64(1, delete_end.ToInternalValue());
statement.Run();
}
void LoggedInPredictorTable::GetAllData(
LoggedInPredictorTable::LoggedInStateMap* state_map) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
DCHECK(state_map != NULL);
state_map->clear();
if (CantAccessDatabase())
return;
Statement statement(DB()->GetUniqueStatement(
base::StringPrintf("SELECT * FROM %s", kTableName).c_str()));
while (statement.Step()) {
string domain = statement.ColumnString(0);
int64 value = statement.ColumnInt64(1);
(*state_map)[domain] = value;
}
}
void LoggedInPredictorTable::CreateTableIfNonExistent() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
if (CantAccessDatabase())
return;
sql::Connection* db = DB();
if (db->DoesTableExist(kTableName))
return;
const char* table_creator =
"CREATE TABLE %s (domain TEXT, time INTEGER, PRIMARY KEY(domain))";
if (!db->Execute(base::StringPrintf(table_creator, kTableName).c_str()))
ResetDB();
}
void LoggedInPredictorTable::LogDatabaseStats() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
if (CantAccessDatabase())
return;
Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE,
base::StringPrintf("SELECT count(*) FROM %s", kTableName).c_str()));
if (statement.Step())
UMA_HISTOGRAM_COUNTS("LoggedInPredictor.TableRowCount",
statement.ColumnInt(0));
}
} // namespace predictors