| Index: chrome/browser/history/android/android_cache_database.cc
|
| diff --git a/chrome/browser/history/android/android_cache_database.cc b/chrome/browser/history/android/android_cache_database.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..eabc56cd51f003cfa41eb26f8e2cfbeafaf95760
|
| --- /dev/null
|
| +++ b/chrome/browser/history/android/android_cache_database.cc
|
| @@ -0,0 +1,195 @@
|
| +// 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 "chrome/browser/history/android/android_cache_database.h"
|
| +
|
| +#include "base/file_util.h"
|
| +#include "sql/statement.h"
|
| +
|
| +using base::Time;
|
| +using base::TimeDelta;
|
| +
|
| +namespace history {
|
| +
|
| +namespace {
|
| +
|
| +int64 ToMilliseconds(const Time& time) {
|
| + TimeDelta delta = time - Time::UnixEpoch();
|
| + return delta.InMilliseconds();
|
| +}
|
| +
|
| +} // namespace.
|
| +
|
| +AndroidCacheDatabase::AndroidCacheDatabase() {
|
| +}
|
| +
|
| +AndroidCacheDatabase::~AndroidCacheDatabase() {
|
| +}
|
| +
|
| +sql::InitStatus AndroidCacheDatabase::InitAndroidCacheDatabase(
|
| + const FilePath& db_name) {
|
| + if (!CreateDatabase(db_name))
|
| + return sql::INIT_FAILURE;
|
| +
|
| + if (!Attach())
|
| + return sql::INIT_FAILURE;
|
| +
|
| + if (!CreateBookmarkCacheTable())
|
| + return sql::INIT_FAILURE;
|
| +
|
| + return sql::INIT_OK;
|
| +}
|
| +
|
| +bool AndroidCacheDatabase::AddBookmarkCacheRow(const Time& created_time,
|
| + const Time& last_visit_time,
|
| + URLID url_id) {
|
| + sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
|
| + "INSERT INTO android_cache_db.bookmark_cache (created_time, "
|
| + "last_visit_time, url_id) VALUES (?, ?, ?)"));
|
| +
|
| + statement.BindInt64(0, ToMilliseconds(created_time));
|
| + statement.BindInt64(1, ToMilliseconds(last_visit_time));
|
| + statement.BindInt64(2, url_id);
|
| +
|
| + if (!statement.Run()) {
|
| + LOG(ERROR) << GetDB().GetErrorMessage();
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool AndroidCacheDatabase::ClearAllBookmarkCache() {
|
| + sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
|
| + "DELETE FROM android_cache_db.bookmark_cache"));
|
| + if (!statement.Run()) {
|
| + LOG(ERROR) << GetDB().GetErrorMessage();
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool AndroidCacheDatabase::MarkURLsAsBookmarked(
|
| + const std::vector<URLID>& url_ids) {
|
| + bool has_id = false;
|
| + std::ostringstream oss;
|
| + for (std::vector<URLID>::const_iterator i = url_ids.begin();
|
| + i != url_ids.end(); ++i) {
|
| + if (has_id)
|
| + oss << ", ";
|
| + else
|
| + has_id = true;
|
| + oss << *i;
|
| + }
|
| +
|
| + if (!has_id)
|
| + return true;
|
| +
|
| + std::string sql("UPDATE android_cache_db.bookmark_cache "
|
| + "SET bookmark = 1 WHERE url_id in (");
|
| + sql.append(oss.str());
|
| + sql.append(")");
|
| + if (!GetDB().Execute(sql.c_str())) {
|
| + LOG(ERROR) << GetDB().GetErrorMessage();
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool AndroidCacheDatabase::SetFaviconID(URLID url_id, FaviconID favicon_id) {
|
| + sql::Statement update_statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
|
| + "UPDATE android_cache_db.bookmark_cache "
|
| + "SET favicon_id = ? WHERE url_id = ? "));
|
| +
|
| + update_statement.BindInt64(0, favicon_id);
|
| + update_statement.BindInt64(1, url_id);
|
| + if (!update_statement.Run()) {
|
| + LOG(ERROR) << GetDB().GetErrorMessage();
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool AndroidCacheDatabase::CreateDatabase(const FilePath& db_name) {
|
| + db_name_ = db_name;
|
| + if (file_util::PathExists(db_name_))
|
| + file_util::Delete(db_name_, false);
|
| +
|
| + // Using a new connection, otherwise we can not create the database.
|
| + sql::Connection connection;
|
| +
|
| + // The db doesn't store too much data, so we don't need that big a page
|
| + // size or cache.
|
| + connection.set_page_size(2048);
|
| + connection.set_cache_size(32);
|
| +
|
| + // Run the database in exclusive mode. Nobody else should be accessing the
|
| + // database while we're running, and this will give somewhat improved perf.
|
| + connection.set_exclusive_locking();
|
| +
|
| + if (!connection.Open(db_name_)) {
|
| + LOG(ERROR) << connection.GetErrorMessage();
|
| + return false;
|
| + }
|
| + connection.Close();
|
| + return true;
|
| +}
|
| +
|
| +bool AndroidCacheDatabase::CreateBookmarkCacheTable() {
|
| + const char* name = "android_cache_db.bookmark_cache";
|
| + DCHECK(!GetDB().DoesTableExist(name));
|
| +
|
| + std::string sql;
|
| + sql.append("CREATE TABLE ");
|
| + sql.append(name);
|
| + sql.append("("
|
| + "id INTEGER PRIMARY KEY,"
|
| + "created_time INTEGER NOT NULL," // Time in millisecond.
|
| + "last_visit_time INTEGER NOT NULL," // Time in millisecond.
|
| + "url_id INTEGER NOT NULL," // url id in urls table.
|
| + "favicon_id INTEGER DEFAULT NULL," // favicon id.
|
| + "bookmark INTEGER DEFAULT 0" // whether is bookmark.
|
| + ")");
|
| + if (!GetDB().Execute(sql.c_str())) {
|
| + LOG(ERROR) << GetDB().GetErrorMessage();
|
| + return false;
|
| + }
|
| +
|
| + sql.assign("CREATE INDEX ");
|
| + sql.append("android_cache_db.bookmark_cache_url_id_idx ON "
|
| + "bookmark_cache(url_id)");
|
| + if (!GetDB().Execute(sql.c_str())) {
|
| + LOG(ERROR) << GetDB().GetErrorMessage();
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool AndroidCacheDatabase::Attach() {
|
| + // Commit all open transactions to make attach succeed.
|
| + if (GetDB().transaction_nesting())
|
| + GetDB().CommitTransaction();
|
| +
|
| + bool result = DoAttach();
|
| +
|
| + // No matter the attach succeed or not, we need to begin a new transaction.
|
| + GetDB().BeginTransaction();
|
| + return result;
|
| +}
|
| +
|
| +bool AndroidCacheDatabase::DoAttach() {
|
| + std::string sql("ATTACH ? AS android_cache_db");
|
| + sql::Statement attach(GetDB().GetUniqueStatement(sql.c_str()));
|
| + if (!attach.is_valid())
|
| + // Keep the transaction open, even though we failed.
|
| + return false;
|
| +
|
| + attach.BindString(0, db_name_.value());
|
| + if (!attach.Run())
|
| + return false;
|
| +
|
| + return true;
|
| +}
|
| +
|
| +} // namespace history
|
|
|