Index: chrome/browser/extensions/activity_database.cc |
=================================================================== |
--- chrome/browser/extensions/activity_database.cc (revision 0) |
+++ chrome/browser/extensions/activity_database.cc (revision 0) |
@@ -0,0 +1,174 @@ |
+// Copyright (c) 2012 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 <string> |
+#include "base/logging.h" |
+#include "base/string_util.h" |
+#include "chrome/browser/extensions/activity_database.h" |
+#include "chrome/browser/history/url_database.h" |
+#include "sql/transaction.h" |
+ |
+#if defined(OS_MACOSX) |
+#include "base/mac/mac_util.h" |
+#endif |
+ |
+namespace { |
+ |
+void LogStatementFailure(const std::string& sql_str) { |
+ LOG(ERROR) << "Activity log database I/O failed: " << sql_str; |
+} |
+ |
+} // namespace |
+ |
+namespace extensions { |
+ |
+ActivityDatabase::ActivityDatabase() : initialized_(false) {} |
+ |
+ActivityDatabase::~ActivityDatabase() { |
+ Close(); // Safe to call Close() even if Open() never happened. |
+} |
+ |
+sql::InitStatus ActivityDatabase::Init( |
+ const FilePath& db_name, |
+ sql::ErrorDelegate* error_delegate) { |
+ db_.set_error_delegate(error_delegate); |
+ db_.set_page_size(4096); |
+ db_.set_cache_size(32); |
+ |
+ if (!db_.Open(db_name)) { |
+ LOG(ERROR) << db_.GetErrorMessage(); |
+ return sql::INIT_FAILURE; |
+ } |
+ |
+ // Wrap the initialization in a transaction so that the db doesn't |
+ // get corrupted if init fails/crashes. |
+ sql::Transaction committer(&db_); |
+ if (!committer.Begin()) |
+ return sql::INIT_FAILURE; |
+ |
+#if defined(OS_MACOSX) |
+ // Exclude the database from backups. |
+ base::mac::SetFileBackupExclusion(db_name); |
+#endif |
+ |
+ db_.Preload(); |
+ |
+ // Create the UrlAction database. |
+ if (InitializeTable(UrlAction::kTableName, UrlAction::kTableStructure) != |
+ sql::INIT_OK) |
+ return sql::INIT_FAILURE; |
+ |
+ // Create the ManagerAction database. |
+ if (InitializeTable(ManagerAction::kTableName, ManagerAction::kTableStructure) |
+ != sql::INIT_OK) |
+ return sql::INIT_FAILURE; |
+ |
+ // Create the BlockedAction database. |
+ if (InitializeTable(BlockedAction::kTableName, BlockedAction::kTableStructure) |
+ != sql::INIT_OK) |
+ return sql::INIT_FAILURE; |
+ |
+ sql::InitStatus stat = committer.Commit() ? sql::INIT_OK : sql::INIT_FAILURE; |
+ if (stat == sql::INIT_OK) |
+ initialized_ = true; |
+ return stat; |
+} |
+ |
+sql::InitStatus ActivityDatabase::InitializeTable(const char* table_name, |
+ const char* table_structure) { |
+ if (!db_.DoesTableExist(table_name)) { |
+ char table_creator[1000]; |
+ base::snprintf(table_creator, |
+ arraysize(table_creator), |
+ "CREATE TABLE %s %s", table_name, table_structure); |
+ if (!db_.Execute(table_creator)) |
+ return sql::INIT_FAILURE; |
+ } |
+ return sql::INIT_OK; |
+} |
+ |
+// The table structure is defined in url_actions.h. |
+void ActivityDatabase::RecordUrlAction(scoped_refptr<UrlAction> action) { |
+ if (!initialized_) |
+ return; |
+ std::string sql_str = "INSERT INTO " + std::string(UrlAction::kTableName) + |
+ " (extension_id, time, url_action_type, url, url_title, api_call)" |
+ " VALUES (?,?,?,?,?,?)"; |
+ sql::Statement statement(db_.GetCachedStatement( |
+ sql::StatementID(SQL_FROM_HERE), sql_str.c_str())); |
+ statement.BindString(0, action->extension_id()); |
+ statement.BindInt64(1, action->time().ToInternalValue()); |
+ statement.BindString(2, action->VerbAsString()); |
+ statement.BindString(3, |
+ history::URLDatabase::GURLToDatabaseURL(action->url())); |
+ statement.BindString16(4, action->url_title()); |
+ statement.BindString(5, action->script()); |
+ if (!statement.Run()) |
+ LogStatementFailure(sql_str); |
+} |
+ |
+// The table structure is defined in manager_actions.h. |
+void ActivityDatabase::RecordManagerAction( |
+ scoped_refptr<ManagerAction> action) { |
+ if (!initialized_) |
+ return; |
+ std::string sql_str = "INSERT INTO " + std::string(ManagerAction::kTableName) |
+ + " (extension_id, time, manager_action_type, target_type, api_call)" |
+ " VALUES (?,?,?,?,?)"; |
+ sql::Statement statement(db_.GetCachedStatement( |
+ sql::StatementID(SQL_FROM_HERE), sql_str.c_str())); |
+ statement.BindString(0, action->extension_id()); |
+ statement.BindInt64(1, action->time().ToInternalValue()); |
+ statement.BindString(2, action->VerbAsString()); |
+ statement.BindString(3, action->TargetAsString()); |
+ statement.BindString(4, action->api_call()); |
+ if (!statement.Run()) |
+ LogStatementFailure(sql_str); |
+} |
+ |
+// The table structure is defined in blocked_actions.h |
+void ActivityDatabase::RecordBlockedAction( |
+ scoped_refptr<BlockedAction> action) { |
+ if (!initialized_) |
+ return; |
+ std::string sql_str = "INSERT INTO " + std::string(BlockedAction::kTableName) |
+ + " (extension_id, time, blocked_action, reason) VALUES (?,?,?,?)"; |
+ sql::Statement statement(db_.GetCachedStatement( |
+ sql::StatementID(SQL_FROM_HERE), sql_str.c_str())); |
+ statement.BindString(0, action->extension_id()); |
+ statement.BindInt64(1, action->time().ToInternalValue()); |
+ statement.BindString(2, action->blocked_action()); |
+ statement.BindString(3, action->reason()); |
+ if (!statement.Run()) |
+ LogStatementFailure(sql_str); |
+} |
+ |
+void ActivityDatabase::BeginTransaction() { |
+ db_.BeginTransaction(); |
+} |
+ |
+void ActivityDatabase::CommitTransaction() { |
+ db_.CommitTransaction(); |
+} |
+ |
+void ActivityDatabase::RollbackTransaction() { |
+ db_.RollbackTransaction(); |
+} |
+ |
+bool ActivityDatabase::Raze() { |
+ return db_.Raze(); |
+} |
+ |
+void ActivityDatabase::Close() { |
+ db_.Close(); |
+} |
+ |
+void ActivityDatabase::KillDatabase() { |
+ db_.RollbackTransaction(); |
+ db_.Raze(); |
+ db_.Close(); |
+} |
+ |
+} // namespace extensions |
+ |