summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/history/archived_database.cc74
-rw-r--r--chrome/browser/history/archived_database.h23
-rw-r--r--chrome/browser/history/download_database.cc185
-rw-r--r--chrome/browser/history/download_database.h24
-rw-r--r--chrome/browser/history/history_backend.cc2
-rw-r--r--chrome/browser/history/history_database.cc144
-rw-r--r--chrome/browser/history/history_database.h27
-rw-r--r--chrome/browser/history/history_unittest.cc18
-rw-r--r--chrome/browser/history/in_memory_database.cc61
-rw-r--r--chrome/browser/history/in_memory_database.h26
-rw-r--r--chrome/browser/history/in_memory_history_backend.cc4
-rw-r--r--chrome/browser/history/in_memory_history_backend.h3
-rw-r--r--chrome/browser/history/starred_url_database.cc149
-rw-r--r--chrome/browser/history/starred_url_database.h15
-rw-r--r--chrome/browser/history/starred_url_database_unittest.cc18
-rw-r--r--chrome/browser/history/text_database.cc12
-rw-r--r--chrome/browser/history/text_database_manager.cc1
-rw-r--r--chrome/browser/history/text_database_manager.h4
-rw-r--r--chrome/browser/history/text_database_manager_unittest.cc18
-rw-r--r--chrome/browser/history/thumbnail_database.cc296
-rw-r--r--chrome/browser/history/thumbnail_database.h28
-rw-r--r--chrome/browser/history/url_database.cc282
-rw-r--r--chrome/browser/history/url_database.h85
-rw-r--r--chrome/browser/history/url_database_unittest.cc21
-rw-r--r--chrome/browser/history/visit_database.cc296
-rw-r--r--chrome/browser/history/visit_database.h28
-rw-r--r--chrome/browser/history/visit_database_unittest.cc21
-rw-r--r--chrome/browser/history/visitsegment_database.cc271
-rw-r--r--chrome/browser/history/visitsegment_database.h29
-rw-r--r--chrome/browser/net/sqlite_persistent_cookie_store.cc2
-rw-r--r--chrome/browser/search_engines/edit_search_engine_controller.cc2
-rw-r--r--chrome/browser/thumbnail_store.cc101
-rw-r--r--chrome/browser/thumbnail_store.h8
-rw-r--r--chrome/browser/thumbnail_store_unittest.cc22
-rw-r--r--chrome/browser/webdata/web_database.cc2
-rw-r--r--chrome/browser/webdata/web_database.h2
36 files changed, 1033 insertions, 1271 deletions
diff --git a/chrome/browser/history/archived_database.cc b/chrome/browser/history/archived_database.cc
index 20b9cd8..b7cd8bd 100644
--- a/chrome/browser/history/archived_database.cc
+++ b/chrome/browser/history/archived_database.cc
@@ -1,13 +1,14 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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 <algorithm>
#include <string>
+#include "app/sql/statement.h"
+#include "app/sql/transaction.h"
#include "base/string_util.h"
#include "chrome/browser/history/archived_database.h"
-#include "chrome/common/sqlite_utils.h"
namespace history {
@@ -18,88 +19,71 @@ static const int kCompatibleVersionNumber = 2;
} // namespace
-ArchivedDatabase::ArchivedDatabase()
- : db_(NULL),
- statement_cache_(NULL),
- transaction_nesting_(0) {
+ArchivedDatabase::ArchivedDatabase() {
}
ArchivedDatabase::~ArchivedDatabase() {
}
bool ArchivedDatabase::Init(const FilePath& file_name) {
- // OpenSqliteDb uses the narrow version of open, indicating to sqlite that we
- // want the database to be in UTF-8 if it doesn't already exist.
- DCHECK(!db_) << "Already initialized!";
- if (OpenSqliteDb(file_name, &db_) != SQLITE_OK)
- return false;
- statement_cache_ = new SqliteStatementCache(db_);
- DBCloseScoper scoper(&db_, &statement_cache_);
-
// Set the database page size to something a little larger to give us
// better performance (we're typically seek rather than bandwidth limited).
// This only has an effect before any tables have been created, otherwise
// this is a NOP. Must be a power of 2 and a max of 8192.
- sqlite3_exec(db_, "PRAGMA page_size=4096", NULL, NULL, NULL);
+ db_.set_page_size(4096);
// Don't use very much memory caching this database. We seldom use it for
// anything important.
- sqlite3_exec(db_, "PRAGMA cache_size=64", NULL, NULL, NULL);
+ db_.set_cache_size(64);
// Run the database in exclusive mode. Nobody else should be accessing the
// database while we're running, and this will give somewhat improved perf.
- sqlite3_exec(db_, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, NULL);
+ db_.set_exclusive_locking();
- BeginTransaction();
+ if (!db_.Open(file_name))
+ return false;
+
+ sql::Transaction transaction(&db_);
+ if (!transaction.Begin()) {
+ db_.Close();
+ return false;
+ }
// Version check.
- if (!meta_table_.Init(std::string(), kCurrentVersionNumber,
- kCompatibleVersionNumber, db_))
+ if (!meta_table_.Init(&db_, kCurrentVersionNumber,
+ kCompatibleVersionNumber)) {
+ db_.Close();
return false;
+ }
// Create the tables.
if (!CreateURLTable(false) || !InitVisitTable() ||
- !InitKeywordSearchTermsTable())
+ !InitKeywordSearchTermsTable()) {
+ db_.Close();
return false;
+ }
CreateMainURLIndex();
- if (EnsureCurrentVersion() != INIT_OK)
+ if (EnsureCurrentVersion() != INIT_OK) {
+ db_.Close();
return false;
+ }
- // Succeeded: keep the DB open by detaching the auto-closer.
- scoper.Detach();
- db_closer_.Attach(&db_, &statement_cache_);
- CommitTransaction();
- return true;
+ return transaction.Commit();
}
void ArchivedDatabase::BeginTransaction() {
- DCHECK(db_);
- if (transaction_nesting_ == 0) {
- int rv = sqlite3_exec(db_, "BEGIN TRANSACTION", NULL, NULL, NULL);
- DCHECK(rv == SQLITE_OK) << "Failed to begin transaction";
- }
- transaction_nesting_++;
+ db_.BeginTransaction();
}
void ArchivedDatabase::CommitTransaction() {
- DCHECK(db_);
- DCHECK_GT(transaction_nesting_, 0) << "Committing too many transactions";
- transaction_nesting_--;
- if (transaction_nesting_ == 0) {
- int rv = sqlite3_exec(db_, "COMMIT", NULL, NULL, NULL);
- DCHECK(rv == SQLITE_OK) << "Failed to commit transaction";
- }
+ db_.CommitTransaction();
}
-sqlite3* ArchivedDatabase::GetDB() {
+sql::Connection& ArchivedDatabase::GetDB() {
return db_;
}
-SqliteStatementCache& ArchivedDatabase::GetStatementCache() {
- return *statement_cache_;
-}
-
// Migration -------------------------------------------------------------------
InitStatus ArchivedDatabase::EnsureCurrentVersion() {
diff --git a/chrome/browser/history/archived_database.h b/chrome/browser/history/archived_database.h
index f444477..13bc562 100644
--- a/chrome/browser/history/archived_database.h
+++ b/chrome/browser/history/archived_database.h
@@ -1,16 +1,15 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
#ifndef CHROME_BROWSER_HISTORY_ARCHIVED_DATABASE_H_
#define CHROME_BROWSER_HISTORY_ARCHIVED_DATABASE_H_
+#include "app/sql/connection.h"
+#include "app/sql/meta_table.h"
#include "base/basictypes.h"
#include "chrome/browser/history/url_database.h"
#include "chrome/browser/history/visit_database.h"
-#include "chrome/browser/meta_table_helper.h"
-
-struct sqlite3;
class FilePath;
@@ -40,8 +39,7 @@ class ArchivedDatabase : public URLDatabase,
private:
// Implemented for the specialized databases.
- virtual sqlite3* GetDB();
- virtual SqliteStatementCache& GetStatementCache();
+ virtual sql::Connection& GetDB();
// Makes sure the version is up-to-date, updating if necessary. If the
// database is too old to migrate, the user will be notified. In this case, or
@@ -53,17 +51,8 @@ class ArchivedDatabase : public URLDatabase,
InitStatus EnsureCurrentVersion();
// The database.
- //
- // The close scoper will free the database and delete the statement cache in
- // the correct order automatically when we are destroyed.
- DBCloseScoper db_closer_;
- sqlite3* db_;
- SqliteStatementCache* statement_cache_;
-
- // The number of nested transactions currently in progress.
- int transaction_nesting_;
-
- MetaTableHelper meta_table_;
+ sql::Connection db_;
+ sql::MetaTable meta_table_;
DISALLOW_COPY_AND_ASSIGN(ArchivedDatabase);
};
diff --git a/chrome/browser/history/download_database.cc b/chrome/browser/history/download_database.cc
index 996e1199..4fcf386 100644
--- a/chrome/browser/history/download_database.cc
+++ b/chrome/browser/history/download_database.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
@@ -7,12 +7,12 @@
#include <limits>
#include <vector>
+#include "app/sql/connection.h"
+#include "app/sql/statement.h"
+#include "base/string_util.h"
+#include "build/build_config.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/history/download_types.h"
-#include "chrome/common/sqlite_utils.h"
-#include "chrome/common/sqlite_compiled_statement.h"
-
-using base::Time;
// Download schema:
//
@@ -28,6 +28,32 @@ using base::Time;
namespace history {
+namespace {
+
+#if defined(OS_POSIX)
+
+// Binds/reads the given file path to the given column of the given statement.
+void BindFilePath(sql::Statement& statement, const FilePath& path, int col) {
+ statement.BindString(col, path.value());
+}
+FilePath ColumnFilePath(sql::Statement& statement, int col) {
+ return FilePath(statement.ColumnString(col));
+}
+
+#else
+
+// See above.
+void BindFilePath(sql::Statement& statement, const FilePath& path, int col) {
+ statement.BindString(col, UTF16ToUTF8(path.value()));
+}
+FilePath ColumnFilePath(sql::Statement& statement, int col) {
+ return FilePath(UTF8ToUTF16(statement.ColumnString(col)));
+}
+
+#endif
+
+} // namespace
+
DownloadDatabase::DownloadDatabase() {
}
@@ -35,51 +61,47 @@ DownloadDatabase::~DownloadDatabase() {
}
bool DownloadDatabase::InitDownloadTable() {
- if (!DoesSqliteTableExist(GetDB(), "downloads")) {
- if (sqlite3_exec(GetDB(),
- "CREATE TABLE downloads ("
- "id INTEGER PRIMARY KEY,"
- "full_path LONGVARCHAR NOT NULL,"
- "url LONGVARCHAR NOT NULL,"
- "start_time INTEGER NOT NULL,"
- "received_bytes INTEGER NOT NULL,"
- "total_bytes INTEGER NOT NULL,"
- "state INTEGER NOT NULL)", NULL, NULL, NULL) != SQLITE_OK)
+ if (!GetDB().DoesTableExist("downloads")) {
+ if (!GetDB().Execute(
+ "CREATE TABLE downloads ("
+ "id INTEGER PRIMARY KEY,"
+ "full_path LONGVARCHAR NOT NULL,"
+ "url LONGVARCHAR NOT NULL,"
+ "start_time INTEGER NOT NULL,"
+ "received_bytes INTEGER NOT NULL,"
+ "total_bytes INTEGER NOT NULL,"
+ "state INTEGER NOT NULL)"))
return false;
}
return true;
}
bool DownloadDatabase::DropDownloadTable() {
- return sqlite3_exec(GetDB(), "DROP TABLE downloads", NULL, NULL, NULL) ==
- SQLITE_OK;
+ return GetDB().Execute("DROP TABLE downloads");
}
void DownloadDatabase::QueryDownloads(
std::vector<DownloadCreateInfo>* results) {
results->clear();
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT id, full_path, url, start_time, received_bytes, "
"total_bytes, state "
"FROM downloads "
- "ORDER BY start_time");
- if (!statement.is_valid())
+ "ORDER BY start_time"));
+ if (!statement)
return;
- while (statement->step() == SQLITE_ROW) {
+ while (statement.Step()) {
DownloadCreateInfo info;
- info.db_handle = statement->column_int64(0);
- std::wstring path_str;
- statement->column_wstring(1, &path_str);
- info.path = FilePath::FromWStringHack(path_str);
- std::wstring url_str;
- statement->column_wstring(2, &url_str);
- info.url = GURL(WideToUTF8(url_str));
- info.start_time = Time::FromTimeT(statement->column_int64(3));
- info.received_bytes = statement->column_int64(4);
- info.total_bytes = statement->column_int64(5);
- info.state = statement->column_int(6);
+ info.db_handle = statement.ColumnInt64(0);
+
+ info.path = ColumnFilePath(statement, 1);
+ info.url = GURL(statement.ColumnString(2));
+ info.start_time = base::Time::FromTimeT(statement.ColumnInt64(3));
+ info.received_bytes = statement.ColumnInt64(4);
+ info.total_bytes = statement.ColumnInt64(5);
+ info.state = statement.ColumnInt(6);
results->push_back(info);
}
}
@@ -88,99 +110,98 @@ bool DownloadDatabase::UpdateDownload(int64 received_bytes,
int32 state,
DownloadID db_handle) {
DCHECK(db_handle > 0);
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"UPDATE downloads "
- "SET received_bytes=?, state=? WHERE id=?");
- if (!statement.is_valid())
+ "SET received_bytes=?, state=? WHERE id=?"));
+ if (!statement)
return false;
- statement->bind_int64(0, received_bytes);
- statement->bind_int(1, state);
- statement->bind_int64(2, db_handle);
- return statement->step() == SQLITE_DONE;
+ statement.BindInt64(0, received_bytes);
+ statement.BindInt(1, state);
+ statement.BindInt64(2, db_handle);
+ return statement.Run();
}
bool DownloadDatabase::UpdateDownloadPath(const std::wstring& path,
DownloadID db_handle) {
DCHECK(db_handle > 0);
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "UPDATE downloads "
- "SET full_path=? WHERE id=?");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "UPDATE downloads SET full_path=? WHERE id=?"));
+ if (!statement)
return false;
- statement->bind_wstring(0, path);
- statement->bind_int64(1, db_handle);
- return statement->step() == SQLITE_DONE;
+ statement.BindString(0, WideToUTF8(path));
+ statement.BindInt64(1, db_handle);
+ return statement.Run();
}
int64 DownloadDatabase::CreateDownload(const DownloadCreateInfo& info) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"INSERT INTO downloads "
"(full_path, url, start_time, received_bytes, total_bytes, state) "
- "VALUES (?, ?, ?, ?, ?, ?)");
- if (!statement.is_valid())
+ "VALUES (?, ?, ?, ?, ?, ?)"));
+ if (!statement)
return 0;
- statement->bind_wstring(0, info.path.ToWStringHack());
- statement->bind_wstring(1, UTF8ToWide(info.url.spec()));
- statement->bind_int64(2, info.start_time.ToTimeT());
- statement->bind_int64(3, info.received_bytes);
- statement->bind_int64(4, info.total_bytes);
- statement->bind_int(5, info.state);
- if (statement->step() == SQLITE_DONE)
- return sqlite3_last_insert_rowid(GetDB());
+ BindFilePath(statement, info.path, 0);
+ statement.BindString(1, info.url.spec());
+ statement.BindInt64(2, info.start_time.ToTimeT());
+ statement.BindInt64(3, info.received_bytes);
+ statement.BindInt64(4, info.total_bytes);
+ statement.BindInt(5, info.state);
+ if (statement.Run())
+ return GetDB().GetLastInsertRowId();
return 0;
}
void DownloadDatabase::RemoveDownload(DownloadID db_handle) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "DELETE FROM downloads WHERE id=?");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "DELETE FROM downloads WHERE id=?"));
+ if (!statement)
return;
- statement->bind_int64(0, db_handle);
- statement->step();
+ statement.BindInt64(0, db_handle);
+ statement.Run();
}
-void DownloadDatabase::RemoveDownloadsBetween(Time delete_begin,
- Time delete_end) {
+void DownloadDatabase::RemoveDownloadsBetween(base::Time delete_begin,
+ base::Time delete_end) {
// This does not use an index. We currently aren't likely to have enough
// downloads where an index by time will give us a lot of benefit.
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"DELETE FROM downloads WHERE start_time >= ? AND start_time < ? "
- "AND (State = ? OR State = ?)");
- if (!statement.is_valid())
+ "AND (State = ? OR State = ?)"));
+ if (!statement)
return;
time_t start_time = delete_begin.ToTimeT();
time_t end_time = delete_end.ToTimeT();
- statement->bind_int64(0, start_time);
- statement->bind_int64(
+ statement.BindInt64(0, start_time);
+ statement.BindInt64(
1,
end_time ? end_time : std::numeric_limits<int64>::max());
- statement->bind_int(2, DownloadItem::COMPLETE);
- statement->bind_int(3, DownloadItem::CANCELLED);
- statement->step();
+ statement.BindInt(2, DownloadItem::COMPLETE);
+ statement.BindInt(3, DownloadItem::CANCELLED);
+ statement.Run();
}
void DownloadDatabase::SearchDownloads(std::vector<int64>* results,
const std::wstring& search_text) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT id FROM downloads WHERE url LIKE ? "
- "OR full_path LIKE ? ORDER BY id");
- if (!statement.is_valid())
+ "OR full_path LIKE ? ORDER BY id"));
+ if (!statement)
return;
- std::wstring text(L"%");
- text.append(search_text);
- text.append(L"%");
- statement->bind_wstring(0, text);
- statement->bind_wstring(1, text);
+ std::string text("%");
+ text.append(WideToUTF8(search_text));
+ text.push_back('%');
+ statement.BindString(0, text);
+ statement.BindString(1, text);
- while (statement->step() == SQLITE_ROW)
- results->push_back(statement->column_int64(0));
+ while (statement.Step())
+ results->push_back(statement.ColumnInt64(0));
}
} // namespace history
diff --git a/chrome/browser/history/download_database.h b/chrome/browser/history/download_database.h
index e005de6..1efb6d4 100644
--- a/chrome/browser/history/download_database.h
+++ b/chrome/browser/history/download_database.h
@@ -1,17 +1,18 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
-#ifndef CHROME_BROWSER_HISTORY_DOWNLOAD_DATABASE_H__
-#define CHROME_BROWSER_HISTORY_DOWNLOAD_DATABASE_H__
+#ifndef CHROME_BROWSER_HISTORY_DOWNLOAD_DATABASE_H_
+#define CHROME_BROWSER_HISTORY_DOWNLOAD_DATABASE_H_
#include "chrome/browser/history/history_types.h"
-struct sqlite3;
-class SqliteStatementCache;
-class SQLStatement;
struct DownloadCreateInfo;
+namespace sql {
+class Connection;
+}
+
namespace history {
// Maintains a table of downloads.
@@ -47,11 +48,8 @@ class DownloadDatabase {
const std::wstring& search_text);
protected:
- // Returns the database and statement cache for the functions in this
- // interface. The descendant of this class implements these functions to
- // return its objects.
- virtual sqlite3* GetDB() = 0;
- virtual SqliteStatementCache& GetStatementCache() = 0;
+ // Returns the database for the functions in this interface.
+ virtual sql::Connection& GetDB() = 0;
// Creates the downloads table if needed.
bool InitDownloadTable();
@@ -61,9 +59,9 @@ class DownloadDatabase {
bool DropDownloadTable();
private:
- DISALLOW_EVIL_CONSTRUCTORS(DownloadDatabase);
+ DISALLOW_COPY_AND_ASSIGN(DownloadDatabase);
};
} // namespace history
-#endif // CHROME_BROWSER_HISTORY_DOWNLOAD_DATABASE_H__
+#endif // CHROME_BROWSER_HISTORY_DOWNLOAD_DATABASE_H_
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc
index 339d584..f9855f4 100644
--- a/chrome/browser/history/history_backend.cc
+++ b/chrome/browser/history/history_backend.cc
@@ -515,7 +515,7 @@ void HistoryBackend::InitImpl() {
// Fill the in-memory database and send it back to the history service on the
// main thread.
InMemoryHistoryBackend* mem_backend = new InMemoryHistoryBackend;
- if (mem_backend->Init(history_name.ToWStringHack()))
+ if (mem_backend->Init(history_name))
delegate_->SetInMemoryBackend(mem_backend); // Takes ownership of pointer.
else
delete mem_backend; // Error case, run without the in-memory DB.
diff --git a/chrome/browser/history/history_database.cc b/chrome/browser/history/history_database.cc
index 23939fc..ee0b179 100644
--- a/chrome/browser/history/history_database.cc
+++ b/chrome/browser/history/history_database.cc
@@ -8,13 +8,11 @@
#include <set>
#include <string>
+#include "app/sql/transaction.h"
#include "base/file_util.h"
#include "base/histogram.h"
#include "base/rand_util.h"
#include "base/string_util.h"
-#include "chrome/common/sqlite_utils.h"
-
-using base::Time;
namespace history {
@@ -27,7 +25,8 @@ static const int kCurrentVersionNumber = 17;
static const int kCompatibleVersionNumber = 16;
static const char kEarlyExpirationThresholdKey[] = "early_expiration_threshold";
-void ComputeDatabaseMetrics(const FilePath& history_name, sqlite3* db) {
+void ComputeDatabaseMetrics(const FilePath& history_name,
+ sql::Connection& db) {
if (base::RandInt(1, 100) != 50)
return; // Only do this computation sometimes since it can be expensive.
@@ -37,26 +36,22 @@ void ComputeDatabaseMetrics(const FilePath& history_name, sqlite3* db) {
int file_mb = static_cast<int>(file_size / (1024 * 1024));
UMA_HISTOGRAM_MEMORY_MB("History.DatabaseFileMB", file_mb);
- SQLStatement url_count;
- if (url_count.prepare(db, "SELECT count(*) FROM urls") != SQLITE_OK ||
- url_count.step() != SQLITE_ROW)
+ sql::Statement url_count(db.GetUniqueStatement("SELECT count(*) FROM urls"));
+ if (!url_count || !url_count.Step())
return;
- UMA_HISTOGRAM_COUNTS("History.URLTableCount", url_count.column_int(0));
+ UMA_HISTOGRAM_COUNTS("History.URLTableCount", url_count.ColumnInt(0));
- SQLStatement visit_count;
- if (visit_count.prepare(db, "SELECT count(*) FROM visits") != SQLITE_OK ||
- visit_count.step() != SQLITE_ROW)
+ sql::Statement visit_count(db.GetUniqueStatement(
+ "SELECT count(*) FROM visits"));
+ if (!visit_count || !visit_count.Step())
return;
- UMA_HISTOGRAM_COUNTS("History.VisitTableCount", visit_count.column_int(0));
+ UMA_HISTOGRAM_COUNTS("History.VisitTableCount", visit_count.ColumnInt(0));
}
} // namespace
HistoryDatabase::HistoryDatabase()
- : transaction_nesting_(0),
- db_(NULL),
- statement_cache_(NULL),
- needs_version_17_migration_(false) {
+ : needs_version_17_migration_(false) {
}
HistoryDatabase::~HistoryDatabase() {
@@ -64,41 +59,38 @@ HistoryDatabase::~HistoryDatabase() {
InitStatus HistoryDatabase::Init(const FilePath& history_name,
const FilePath& bookmarks_path) {
- // OpenSqliteDb uses the narrow version of open, indicating to sqlite that we
- // want the database to be in UTF-8 if it doesn't already exist.
- DCHECK(!db_) << "Already initialized!";
- if (OpenSqliteDb(history_name, &db_) != SQLITE_OK)
- return INIT_FAILURE;
- statement_cache_ = new SqliteStatementCache;
- DBCloseScoper scoper(&db_, &statement_cache_);
-
// Set the database page size to something a little larger to give us
// better performance (we're typically seek rather than bandwidth limited).
// This only has an effect before any tables have been created, otherwise
// this is a NOP. Must be a power of 2 and a max of 8192.
- sqlite3_exec(db_, "PRAGMA page_size=4096", NULL, NULL, NULL);
+ db_.set_page_size(4096);
// Increase the cache size. The page size, plus a little extra, times this
// value, tells us how much memory the cache will use maximum.
// 6000 * 4MB = 24MB
// TODO(brettw) scale this value to the amount of available memory.
- sqlite3_exec(db_, "PRAGMA cache_size=6000", NULL, NULL, NULL);
+ db_.set_cache_size(6000);
+
+ // Note that we don't set exclusive locking here. That's done by
+ // BeginExclusiveMode below which is called later (we have to be in shared
+ // mode to start out for the in-memory backend to read the data).
+
+ if (!db_.Open(history_name))
+ return INIT_FAILURE;
// Wrap the rest of init in a tranaction. This will prevent the database from
// getting corrupted if we crash in the middle of initialization or migration.
- TransactionScoper transaction(this);
-
- // Make sure the statement cache is properly initialized.
- statement_cache_->set_db(db_);
+ sql::Transaction committer(&db_);
+ if (!committer.Begin())
+ return INIT_FAILURE;
// Prime the cache.
- MetaTableHelper::PrimeCache(std::string(), db_);
+ db_.Preload();
// Create the tables and indices.
// NOTE: If you add something here, also add it to
// RecreateAllButStarAndURLTables.
- if (!meta_table_.Init(std::string(), kCurrentVersionNumber,
- kCompatibleVersionNumber, db_))
+ if (!meta_table_.Init(&db_, kCurrentVersionNumber, kCompatibleVersionNumber))
return INIT_FAILURE;
if (!CreateURLTable(false) || !InitVisitTable() ||
!InitKeywordSearchTermsTable() || !InitDownloadTable() ||
@@ -112,15 +104,14 @@ InitStatus HistoryDatabase::Init(const FilePath& history_name,
if (version_status != INIT_OK)
return version_status;
- // Succeeded: keep the DB open by detaching the auto-closer.
- scoper.Detach();
- db_closer_.Attach(&db_, &statement_cache_);
ComputeDatabaseMetrics(history_name, db_);
- return INIT_OK;
+ return committer.Commit() ? INIT_OK : INIT_FAILURE;
}
void HistoryDatabase::BeginExclusiveMode() {
- sqlite3_exec(db_, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, NULL);
+ // We can't use set_exclusive_locking() since that only has an effect before
+ // the DB is opened.
+ db_.Execute("PRAGMA locking_mode=EXCLUSIVE");
}
// static
@@ -129,22 +120,11 @@ int HistoryDatabase::GetCurrentVersion() {
}
void HistoryDatabase::BeginTransaction() {
- DCHECK(db_);
- if (transaction_nesting_ == 0) {
- int rv = sqlite3_exec(db_, "BEGIN TRANSACTION", NULL, NULL, NULL);
- DCHECK(rv == SQLITE_OK) << "Failed to begin transaction";
- }
- transaction_nesting_++;
+ db_.BeginTransaction();
}
void HistoryDatabase::CommitTransaction() {
- DCHECK(db_);
- DCHECK_GT(transaction_nesting_, 0) << "Committing too many transactions";
- transaction_nesting_--;
- if (transaction_nesting_ == 0) {
- int rv = sqlite3_exec(db_, "COMMIT", NULL, NULL, NULL);
- DCHECK(rv == SQLITE_OK) << "Failed to commit transaction";
- }
+ db_.CommitTransaction();
}
bool HistoryDatabase::RecreateAllTablesButURL() {
@@ -171,42 +151,43 @@ bool HistoryDatabase::RecreateAllTablesButURL() {
}
void HistoryDatabase::Vacuum() {
- DCHECK_EQ(0, transaction_nesting_) <<
+ DCHECK_EQ(0, db_.transaction_nesting()) <<
"Can not have a transaction when vacuuming.";
- sqlite3_exec(db_, "VACUUM", NULL, NULL, NULL);
+ db_.Execute("VACUUM");
}
bool HistoryDatabase::SetSegmentID(VisitID visit_id, SegmentID segment_id) {
- SQLStatement s;
- if (s.prepare(db_, "UPDATE visits SET segment_id = ? WHERE id = ?") !=
- SQLITE_OK) {
- NOTREACHED();
+ sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
+ "UPDATE visits SET segment_id = ? WHERE id = ?"));
+ if (!s) {
+ NOTREACHED() << db_.GetErrorMessage();
return false;
}
- s.bind_int64(0, segment_id);
- s.bind_int64(1, visit_id);
- return s.step() == SQLITE_DONE;
+ s.BindInt64(0, segment_id);
+ s.BindInt64(1, visit_id);
+ DCHECK(db_.GetLastChangeCount() == 1);
+ return s.Run();
}
SegmentID HistoryDatabase::GetSegmentID(VisitID visit_id) {
- SQLStatement s;
- if (s.prepare(db_, "SELECT segment_id FROM visits WHERE id = ?")
- != SQLITE_OK) {
- NOTREACHED();
+ sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
+ "SELECT segment_id FROM visits WHERE id = ?"));
+ if (!s) {
+ NOTREACHED() << db_.GetErrorMessage();
return 0;
}
- s.bind_int64(0, visit_id);
- if (s.step() == SQLITE_ROW) {
- if (s.column_type(0) == SQLITE_NULL)
+ s.BindInt64(0, visit_id);
+ if (s.Step()) {
+ if (s.ColumnType(0) == sql::COLUMN_TYPE_NULL)
return 0;
else
- return s.column_int64(0);
+ return s.ColumnInt64(0);
}
return 0;
}
-Time HistoryDatabase::GetEarlyExpirationThreshold() {
+base::Time HistoryDatabase::GetEarlyExpirationThreshold() {
if (!cached_early_expiration_threshold_.is_null())
return cached_early_expiration_threshold_;
@@ -217,24 +198,20 @@ Time HistoryDatabase::GetEarlyExpirationThreshold() {
threshold = 1L;
}
- cached_early_expiration_threshold_ = Time::FromInternalValue(threshold);
+ cached_early_expiration_threshold_ = base::Time::FromInternalValue(threshold);
return cached_early_expiration_threshold_;
}
-void HistoryDatabase::UpdateEarlyExpirationThreshold(Time threshold) {
+void HistoryDatabase::UpdateEarlyExpirationThreshold(base::Time threshold) {
meta_table_.SetValue(kEarlyExpirationThresholdKey,
threshold.ToInternalValue());
cached_early_expiration_threshold_ = threshold;
}
-sqlite3* HistoryDatabase::GetDB() {
+sql::Connection& HistoryDatabase::GetDB() {
return db_;
}
-SqliteStatementCache& HistoryDatabase::GetStatementCache() {
- return *statement_cache_;
-}
-
// Migration -------------------------------------------------------------------
InitStatus HistoryDatabase::EnsureCurrentVersion(
@@ -294,21 +271,18 @@ void HistoryDatabase::MigrateTimeEpoch() {
// Update all the times in the URLs and visits table in the main database.
// For visits, clear the indexed flag since we'll delete the FTS databases in
// the next step.
- sqlite3_exec(GetDB(),
+ db_.Execute(
"UPDATE urls "
"SET last_visit_time = last_visit_time + 11644473600000000 "
- "WHERE id IN (SELECT id FROM urls WHERE last_visit_time > 0);",
- NULL, NULL, NULL);
- sqlite3_exec(GetDB(),
+ "WHERE id IN (SELECT id FROM urls WHERE last_visit_time > 0);");
+ db_.Execute(
"UPDATE visits "
"SET visit_time = visit_time + 11644473600000000, is_indexed = 0 "
- "WHERE id IN (SELECT id FROM visits WHERE visit_time > 0);",
- NULL, NULL, NULL);
- sqlite3_exec(GetDB(),
+ "WHERE id IN (SELECT id FROM visits WHERE visit_time > 0);");
+ db_.Execute(
"UPDATE segment_usage "
"SET time_slot = time_slot + 11644473600000000 "
- "WHERE id IN (SELECT id FROM segment_usage WHERE time_slot > 0);",
- NULL, NULL, NULL);
+ "WHERE id IN (SELECT id FROM segment_usage WHERE time_slot > 0);");
// Erase all the full text index files. These will take a while to update and
// are less important, so we just blow them away. Same with the archived
diff --git a/chrome/browser/history/history_database.h b/chrome/browser/history/history_database.h
index 9351c26..560b699 100644
--- a/chrome/browser/history/history_database.h
+++ b/chrome/browser/history/history_database.h
@@ -1,10 +1,12 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
#ifndef CHROME_BROWSER_HISTORY_HISTORY_DATABASE_H_
#define CHROME_BROWSER_HISTORY_HISTORY_DATABASE_H_
+#include "app/sql/connection.h"
+#include "app/sql/meta_table.h"
#include "build/build_config.h"
#include "chrome/browser/history/download_database.h"
#include "chrome/browser/history/history_types.h"
@@ -12,9 +14,6 @@
#include "chrome/browser/history/url_database.h"
#include "chrome/browser/history/visit_database.h"
#include "chrome/browser/history/visitsegment_database.h"
-#include "chrome/browser/meta_table_helper.h"
-
-struct sqlite3;
class FilePath;
@@ -85,7 +84,7 @@ class HistoryDatabase : public DownloadDatabase,
void BeginTransaction();
void CommitTransaction();
int transaction_nesting() const { // for debugging and assertion purposes
- return transaction_nesting_;
+ return db_.transaction_nesting();
}
// Drops all tables except the URL, and download tables, and recreates them
@@ -142,8 +141,7 @@ class HistoryDatabase : public DownloadDatabase,
private:
// Implemented for URLDatabase.
- virtual sqlite3* GetDB();
- virtual SqliteStatementCache& GetStatementCache();
+ virtual sql::Connection& GetDB();
// Migration -----------------------------------------------------------------
@@ -164,20 +162,9 @@ class HistoryDatabase : public DownloadDatabase,
// ---------------------------------------------------------------------------
- // How many nested transactions are pending? When this gets to 0, we commit.
- int transaction_nesting_;
-
- // The database. The closer automatically closes the deletes the db and the
- // statement cache. These must be done in a specific order, so we don't want
- // to rely on C++'s implicit destructors for the individual objects.
- //
- // The close scoper will free the database and delete the statement cache in
- // the correct order automatically when we are destroyed.
- DBCloseScoper db_closer_;
- sqlite3* db_;
- SqliteStatementCache* statement_cache_;
+ sql::Connection db_;
+ sql::MetaTable meta_table_;
- MetaTableHelper meta_table_;
base::Time cached_early_expiration_threshold_;
// See the getter above.
diff --git a/chrome/browser/history/history_unittest.cc b/chrome/browser/history/history_unittest.cc
index 55bac89..be84f01 100644
--- a/chrome/browser/history/history_unittest.cc
+++ b/chrome/browser/history/history_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
@@ -20,6 +20,8 @@
#include <time.h>
#include <algorithm>
+#include "app/sql/connection.h"
+#include "app/sql/statement.h"
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/file_util.h"
@@ -39,7 +41,6 @@
#include "chrome/browser/history/page_usage_data.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/notification_service.h"
-#include "chrome/common/sqlite_utils.h"
#include "chrome/common/thumbnail_score.h"
#include "chrome/tools/profiles/thumbnail-inl.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -738,19 +739,16 @@ TEST(HistoryProfileTest, TypicalProfileVersion) {
int cur_version = HistoryDatabase::GetCurrentVersion();
- sqlite3* db;
- ASSERT_EQ(SQLITE_OK, OpenSqliteDb(file, &db));
+ sql::Connection db;
+ ASSERT_TRUE(db.Open(file));
{
- SQLStatement s;
- ASSERT_EQ(SQLITE_OK, s.prepare(db,
+ sql::Statement s(db.GetUniqueStatement(
"SELECT value FROM meta WHERE key = 'version'"));
- EXPECT_EQ(SQLITE_ROW, s.step());
- int file_version = s.column_int(0);
+ EXPECT_TRUE(s.Step());
+ int file_version = s.ColumnInt(0);
EXPECT_EQ(cur_version, file_version);
}
-
- ASSERT_EQ(SQLITE_OK, sqlite3_close(db));
}
namespace {
diff --git a/chrome/browser/history/in_memory_database.cc b/chrome/browser/history/in_memory_database.cc
index 245b75d..f5bff01 100644
--- a/chrome/browser/history/in_memory_database.cc
+++ b/chrome/browser/history/in_memory_database.cc
@@ -1,50 +1,46 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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/in_memory_database.h"
+#include "base/file_path.h"
#include "base/histogram.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/time.h"
+#include "build/build_config.h"
namespace history {
-InMemoryDatabase::InMemoryDatabase()
- : URLDatabase(),
- db_(NULL),
- statement_cache_(NULL) {
+InMemoryDatabase::InMemoryDatabase() : URLDatabase() {
}
InMemoryDatabase::~InMemoryDatabase() {
}
bool InMemoryDatabase::InitDB() {
- DCHECK(!db_) << "Already initialized!";
- if (sqlite3_open(":memory:", &db_) != SQLITE_OK) {
- NOTREACHED() << "Cannot open memory database";
+ // Set the database page size to 4K for better performance.
+ db_.set_page_size(4096);
+
+ if (!db_.OpenInMemory()) {
+ NOTREACHED() << "Cannot open databse " << GetDB().GetErrorMessage();
return false;
}
- statement_cache_ = new SqliteStatementCache(db_);
- DBCloseScoper scoper(&db_, &statement_cache_); // closes the DB on error
// No reason to leave data behind in memory when rows are removed.
- sqlite3_exec(db_, "PRAGMA auto_vacuum=1", NULL, NULL, NULL);
- // Set the database page size to 4K for better performance.
- sqlite3_exec(db_, "PRAGMA page_size=4096", NULL, NULL, NULL);
+ db_.Execute("PRAGMA auto_vacuum=1");
+
// Ensure this is really an in-memory-only cache.
- sqlite3_exec(db_, "PRAGMA temp_store=MEMORY", NULL, NULL, NULL);
+ db_.Execute("PRAGMA temp_store=MEMORY");
// Create the URL table, but leave it empty for now.
if (!CreateURLTable(false)) {
NOTREACHED() << "Unable to create table";
+ db_.Close();
return false;
}
- // Succeeded, keep the DB open.
- scoper.Detach();
- db_closer_.Attach(&db_, &statement_cache_);
return true;
}
@@ -58,38 +54,41 @@ bool InMemoryDatabase::InitFromScratch() {
return true;
}
-bool InMemoryDatabase::InitFromDisk(const std::wstring& history_name) {
+bool InMemoryDatabase::InitFromDisk(const FilePath& history_name) {
if (!InitDB())
return false;
// Attach to the history database on disk. (We can't ATTACH in the middle of
// a transaction.)
- SQLStatement attach;
- if (attach.prepare(db_, "ATTACH ? AS history") != SQLITE_OK) {
+ sql::Statement attach(GetDB().GetUniqueStatement("ATTACH ? AS history"));
+ if (!attach) {
NOTREACHED() << "Unable to attach to history database.";
return false;
}
- attach.bind_string(0, WideToUTF8(history_name));
- if (attach.step() != SQLITE_DONE) {
- NOTREACHED() << "Unable to bind";
+#if defined(OS_POSIX)
+ attach.BindString(0, history_name.value());
+#else
+ attach.BindString(0, WideToUTF8(history_name.value()));
+#endif
+ if (!attach.Run()) {
+ NOTREACHED() << GetDB().GetErrorMessage();
return false;
}
// Copy URL data to memory.
base::TimeTicks begin_load = base::TimeTicks::Now();
- if (sqlite3_exec(db_,
- "INSERT INTO urls SELECT * FROM history.urls WHERE typed_count > 0",
- NULL, NULL, NULL) != SQLITE_OK) {
+ if (!db_.Execute(
+ "INSERT INTO urls SELECT * FROM history.urls WHERE typed_count > 0")) {
// Unable to get data from the history database. This is OK, the file may
// just not exist yet.
}
base::TimeTicks end_load = base::TimeTicks::Now();
UMA_HISTOGRAM_MEDIUM_TIMES("History.InMemoryDBPopulate",
end_load - begin_load);
- UMA_HISTOGRAM_COUNTS("History.InMemoryDBItemCount", sqlite3_changes(db_));
+ UMA_HISTOGRAM_COUNTS("History.InMemoryDBItemCount", db_.GetLastChangeCount());
// Detach from the history database on disk.
- if (sqlite3_exec(db_, "DETACH history", NULL, NULL, NULL) != SQLITE_OK) {
+ if (!db_.Execute("DETACH history")) {
NOTREACHED() << "Unable to detach from history database.";
return false;
}
@@ -101,12 +100,8 @@ bool InMemoryDatabase::InitFromDisk(const std::wstring& history_name) {
return true;
}
-sqlite3* InMemoryDatabase::GetDB() {
+sql::Connection& InMemoryDatabase::GetDB() {
return db_;
}
-SqliteStatementCache& InMemoryDatabase::GetStatementCache() {
- return *statement_cache_;
-}
-
} // namespace history
diff --git a/chrome/browser/history/in_memory_database.h b/chrome/browser/history/in_memory_database.h
index 3d526fe..9f28cf2 100644
--- a/chrome/browser/history/in_memory_database.h
+++ b/chrome/browser/history/in_memory_database.h
@@ -1,18 +1,17 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
-#ifndef CHROME_BROWSER_HISTORY_HISTORY_MEMORY_DB_H__
-#define CHROME_BROWSER_HISTORY_HISTORY_MEMORY_DB_H__
+#ifndef CHROME_BROWSER_HISTORY_HISTORY_MEMORY_DB_H_
+#define CHROME_BROWSER_HISTORY_HISTORY_MEMORY_DB_H_
#include <string>
+#include "app/sql/connection.h"
#include "base/basictypes.h"
#include "chrome/browser/history/url_database.h"
-struct sqlite3;
-
-class SqliteStatementCache;
+class FilePath;
namespace history {
@@ -31,27 +30,22 @@ class InMemoryDatabase : public URLDatabase {
// file. Conceptually, the InMemoryHistoryBackend should do the populating
// after this object does some common initialization, but that would be
// much slower.
- bool InitFromDisk(const std::wstring& history_name);
+ bool InitFromDisk(const FilePath& history_name);
protected:
// Implemented for URLDatabase.
- virtual sqlite3* GetDB();
- virtual SqliteStatementCache& GetStatementCache();
+ virtual sql::Connection& GetDB();
private:
// Initializes the database connection, this is the shared code between
// InitFromScratch() and InitFromDisk() above. Returns true on success.
bool InitDB();
- // The close scoper will free the database and delete the statement cache in
- // the correct order automatically when we are destroyed.
- DBCloseScoper db_closer_;
- sqlite3* db_;
- SqliteStatementCache* statement_cache_;
+ sql::Connection db_;
- DISALLOW_EVIL_CONSTRUCTORS(InMemoryDatabase);
+ DISALLOW_COPY_AND_ASSIGN(InMemoryDatabase);
};
} // namespace history
-#endif // CHROME_BROWSER_HISTORY_HISTORY_MEMORY_DB_H__
+#endif // CHROME_BROWSER_HISTORY_HISTORY_MEMORY_DB_H_
diff --git a/chrome/browser/history/in_memory_history_backend.cc b/chrome/browser/history/in_memory_history_backend.cc
index ab9b34c..d40c581 100644
--- a/chrome/browser/history/in_memory_history_backend.cc
+++ b/chrome/browser/history/in_memory_history_backend.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
@@ -23,7 +23,7 @@ InMemoryHistoryBackend::InMemoryHistoryBackend()
InMemoryHistoryBackend::~InMemoryHistoryBackend() {
}
-bool InMemoryHistoryBackend::Init(const std::wstring& history_filename) {
+bool InMemoryHistoryBackend::Init(const FilePath& history_filename) {
db_.reset(new InMemoryDatabase);
return db_->InitFromDisk(history_filename);
}
diff --git a/chrome/browser/history/in_memory_history_backend.h b/chrome/browser/history/in_memory_history_backend.h
index 131a444..b421c5f 100644
--- a/chrome/browser/history/in_memory_history_backend.h
+++ b/chrome/browser/history/in_memory_history_backend.h
@@ -20,6 +20,7 @@
#include "chrome/common/notification_registrar.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
+class FilePath;
class HistoryDatabase;
class Profile;
@@ -35,7 +36,7 @@ class InMemoryHistoryBackend : public NotificationObserver {
~InMemoryHistoryBackend();
// Initializes with data from the given history database.
- bool Init(const std::wstring& history_filename);
+ bool Init(const FilePath& history_filename);
// Does initialization work when this object is attached to the history
// system on the main thread. The argument is the profile with which the
diff --git a/chrome/browser/history/starred_url_database.cc b/chrome/browser/history/starred_url_database.cc
index b56bcd9..7c77574 100644
--- a/chrome/browser/history/starred_url_database.cc
+++ b/chrome/browser/history/starred_url_database.cc
@@ -1,9 +1,11 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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/starred_url_database.h"
+#include "app/sql/connection.h"
+#include "app/sql/statement.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/json_writer.h"
@@ -16,10 +18,6 @@
#include "chrome/browser/history/history.h"
#include "chrome/browser/history/query_parser.h"
#include "chrome/browser/meta_table_helper.h"
-#include "chrome/common/sqlite_compiled_statement.h"
-#include "chrome/common/sqlite_utils.h"
-
-using base::Time;
// The following table is used to store star (aka bookmark) information. This
// class derives from URLDatabase, which has its own schema.
@@ -53,13 +51,13 @@ namespace {
"starred.group_id, starred.date_modified "
const char kHistoryStarFields[] = STAR_FIELDS;
-void FillInStarredEntry(SQLStatement* s, StarredEntry* entry) {
+void FillInStarredEntry(const sql::Statement& s, StarredEntry* entry) {
DCHECK(entry);
- entry->id = s->column_int64(0);
- switch (s->column_int(1)) {
+ entry->id = s.ColumnInt64(0);
+ switch (s.ColumnInt(1)) {
case 0:
entry->type = history::StarredEntry::URL;
- entry->url = GURL(WideToUTF8(s->column_wstring(6)));
+ entry->url = GURL(s.ColumnString(6));
break;
case 1:
entry->type = history::StarredEntry::BOOKMARK_BAR;
@@ -74,13 +72,13 @@ void FillInStarredEntry(SQLStatement* s, StarredEntry* entry) {
NOTREACHED();
break;
}
- entry->title = s->column_wstring(2);
- entry->date_added = Time::FromInternalValue(s->column_int64(3));
- entry->visual_order = s->column_int(4);
- entry->parent_group_id = s->column_int64(5);
- entry->url_id = s->column_int64(7);
- entry->group_id = s->column_int64(8);
- entry->date_group_modified = Time::FromInternalValue(s->column_int64(9));
+ entry->title = UTF8ToWide(s.ColumnString(2));
+ entry->date_added = base::Time::FromInternalValue(s.ColumnInt64(3));
+ entry->visual_order = s.ColumnInt(4);
+ entry->parent_group_id = s.ColumnInt64(5);
+ entry->url_id = s.ColumnInt64(7);
+ entry->group_id = s.ColumnInt64(8);
+ entry->date_group_modified = base::Time::FromInternalValue(s.ColumnInt64(9));
}
} // namespace
@@ -92,7 +90,7 @@ StarredURLDatabase::~StarredURLDatabase() {
}
bool StarredURLDatabase::MigrateBookmarksToFile(const FilePath& path) {
- if (!DoesSqliteTableExist(GetDB(), "starred"))
+ if (!GetDB().DoesTableExist("starred"))
return true;
if (EnsureStarredIntegrity() && !MigrateBookmarksToFileImpl(path)) {
@@ -100,8 +98,7 @@ bool StarredURLDatabase::MigrateBookmarksToFile(const FilePath& path) {
return false;
}
- if (sqlite3_exec(GetDB(), "DROP TABLE starred", NULL, NULL,
- NULL) != SQLITE_OK) {
+ if (!GetDB().Execute("DROP TABLE starred")) {
NOTREACHED() << "Unable to drop starred table";
return false;
}
@@ -116,15 +113,15 @@ bool StarredURLDatabase::GetAllStarredEntries(
sql.append("FROM starred LEFT JOIN urls ON starred.url_id = urls.id ");
sql += "ORDER BY parent_id, visual_order";
- SQLStatement s;
- if (s.prepare(GetDB(), sql.c_str()) != SQLITE_OK) {
+ sql::Statement s(GetDB().GetUniqueStatement(sql.c_str()));
+ if (!s) {
NOTREACHED() << "Statement prepare failed";
return false;
}
history::StarredEntry entry;
- while (s.step() == SQLITE_ROW) {
- FillInStarredEntry(&s, &entry);
+ while (s.Step()) {
+ FillInStarredEntry(s, &entry);
// Reset the url for non-url types. This is needed as we're reusing the
// same entry for the loop.
if (entry.type != history::StarredEntry::URL)
@@ -157,104 +154,104 @@ bool StarredURLDatabase::UpdateStarredEntryRow(StarID star_id,
const std::wstring& title,
UIStarID parent_group_id,
int visual_order,
- Time date_modified) {
+ base::Time date_modified) {
DCHECK(star_id && visual_order >= 0);
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"UPDATE starred SET title=?, parent_id=?, visual_order=?, "
- "date_modified=? WHERE id=?");
- if (!statement.is_valid())
+ "date_modified=? WHERE id=?"));
+ if (!statement)
return 0;
- statement->bind_wstring(0, title);
- statement->bind_int64(1, parent_group_id);
- statement->bind_int(2, visual_order);
- statement->bind_int64(3, date_modified.ToInternalValue());
- statement->bind_int64(4, star_id);
- return statement->step() == SQLITE_DONE;
+ statement.BindString(0, WideToUTF8(title));
+ statement.BindInt64(1, parent_group_id);
+ statement.BindInt(2, visual_order);
+ statement.BindInt64(3, date_modified.ToInternalValue());
+ statement.BindInt64(4, star_id);
+ return statement.Run();
}
bool StarredURLDatabase::AdjustStarredVisualOrder(UIStarID parent_group_id,
int start_visual_order,
int delta) {
DCHECK(parent_group_id && start_visual_order >= 0);
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"UPDATE starred SET visual_order=visual_order+? "
- "WHERE parent_id=? AND visual_order >= ?");
- if (!statement.is_valid())
+ "WHERE parent_id=? AND visual_order >= ?"));
+ if (!statement)
return false;
- statement->bind_int(0, delta);
- statement->bind_int64(1, parent_group_id);
- statement->bind_int(2, start_visual_order);
- return statement->step() == SQLITE_DONE;
+ statement.BindInt(0, delta);
+ statement.BindInt64(1, parent_group_id);
+ statement.BindInt(2, start_visual_order);
+ return statement.Run();
}
StarID StarredURLDatabase::CreateStarredEntryRow(URLID url_id,
UIStarID group_id,
UIStarID parent_group_id,
const std::wstring& title,
- const Time& date_added,
+ const base::Time& date_added,
int visual_order,
StarredEntry::Type type) {
DCHECK(visual_order >= 0 &&
(type != history::StarredEntry::URL || url_id));
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"INSERT INTO starred "
"(type, url_id, group_id, title, date_added, visual_order, parent_id, "
- "date_modified) VALUES (?,?,?,?,?,?,?,?)");
- if (!statement.is_valid())
+ "date_modified) VALUES (?,?,?,?,?,?,?,?)"));
+ if (!statement)
return 0;
switch (type) {
case history::StarredEntry::URL:
- statement->bind_int(0, 0);
+ statement.BindInt(0, 0);
break;
case history::StarredEntry::BOOKMARK_BAR:
- statement->bind_int(0, 1);
+ statement.BindInt(0, 1);
break;
case history::StarredEntry::USER_GROUP:
- statement->bind_int(0, 2);
+ statement.BindInt(0, 2);
break;
case history::StarredEntry::OTHER:
- statement->bind_int(0, 3);
+ statement.BindInt(0, 3);
break;
default:
NOTREACHED();
}
- statement->bind_int64(1, url_id);
- statement->bind_int64(2, group_id);
- statement->bind_wstring(3, title);
- statement->bind_int64(4, date_added.ToInternalValue());
- statement->bind_int(5, visual_order);
- statement->bind_int64(6, parent_group_id);
- statement->bind_int64(7, Time().ToInternalValue());
- if (statement->step() == SQLITE_DONE)
- return sqlite3_last_insert_rowid(GetDB());
+ statement.BindInt64(1, url_id);
+ statement.BindInt64(2, group_id);
+ statement.BindString(3, WideToUTF8(title));
+ statement.BindInt64(4, date_added.ToInternalValue());
+ statement.BindInt(5, visual_order);
+ statement.BindInt64(6, parent_group_id);
+ statement.BindInt64(7, base::Time().ToInternalValue());
+ if (statement.Run())
+ return GetDB().GetLastInsertRowId();
return 0;
}
bool StarredURLDatabase::DeleteStarredEntryRow(StarID star_id) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "DELETE FROM starred WHERE id=?");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "DELETE FROM starred WHERE id=?"));
+ if (!statement)
return false;
- statement->bind_int64(0, star_id);
- return statement->step() == SQLITE_DONE;
+ statement.BindInt64(0, star_id);
+ return statement.Run();
}
bool StarredURLDatabase::GetStarredEntry(StarID star_id, StarredEntry* entry) {
DCHECK(entry && star_id);
- SQLITE_UNIQUE_STATEMENT(s, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT" STAR_FIELDS "FROM starred LEFT JOIN urls ON "
- "starred.url_id = urls.id WHERE starred.id=?");
- if (!s.is_valid())
+ "starred.url_id = urls.id WHERE starred.id=?"));
+ if (!statement)
return false;
- s->bind_int64(0, star_id);
+ statement.BindInt64(0, star_id);
- if (s->step() == SQLITE_ROW) {
- FillInStarredEntry(s.statement(), entry);
+ if (statement.Step()) {
+ FillInStarredEntry(statement, entry);
return true;
}
return false;
@@ -306,17 +303,17 @@ StarID StarredURLDatabase::CreateStarredEntry(StarredEntry* entry) {
}
UIStarID StarredURLDatabase::GetMaxGroupID() {
- SQLStatement max_group_id_statement;
- if (max_group_id_statement.prepare(GetDB(),
- "SELECT MAX(group_id) FROM starred") != SQLITE_OK) {
- NOTREACHED();
+ sql::Statement max_group_id_statement(GetDB().GetUniqueStatement(
+ "SELECT MAX(group_id) FROM starred"));
+ if (!max_group_id_statement) {
+ NOTREACHED() << GetDB().GetErrorMessage();
return 0;
}
- if (max_group_id_statement.step() != SQLITE_ROW) {
- NOTREACHED();
+ if (!max_group_id_statement.Step()) {
+ NOTREACHED() << GetDB().GetErrorMessage();
return 0;
}
- return max_group_id_statement.column_int64(0);
+ return max_group_id_statement.ColumnInt64(0);
}
bool StarredURLDatabase::BuildStarNodes(
@@ -451,7 +448,7 @@ bool StarredURLDatabase::EnsureStarredIntegrityImpl(
return false;
}
entry.id = CreateStarredEntryRow(
- 0, entry.group_id, 0, L"other", Time::Now(), 0,
+ 0, entry.group_id, 0, L"other", base::Time::Now(), 0,
history::StarredEntry::OTHER);
if (!entry.id) {
NOTREACHED() << "Unable to create other bookmarks folder";
diff --git a/chrome/browser/history/starred_url_database.h b/chrome/browser/history/starred_url_database.h
index fd11ac2..1dd3337 100644
--- a/chrome/browser/history/starred_url_database.h
+++ b/chrome/browser/history/starred_url_database.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
@@ -13,9 +13,11 @@
#include "chrome/browser/history/url_database.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
-struct sqlite3;
class FilePath;
-class SqliteStatementCache;
+
+namespace sql {
+class Connection;
+}
namespace history {
@@ -38,11 +40,8 @@ class StarredURLDatabase : public URLDatabase {
// Writes bookmarks to the specified file.
bool MigrateBookmarksToFile(const FilePath& path);
- // Returns the database and statement cache for the functions in this
- // interface. The decendent of this class implements these functions to
- // return its objects.
- virtual sqlite3* GetDB() = 0;
- virtual SqliteStatementCache& GetStatementCache() = 0;
+ // Returns the database for the functions in this interface.
+ virtual sql::Connection& GetDB() = 0;
private:
// Makes sure the starred table is in a sane state. This does the following:
diff --git a/chrome/browser/history/starred_url_database_unittest.cc b/chrome/browser/history/starred_url_database_unittest.cc
index 1c97927..961b240 100644
--- a/chrome/browser/history/starred_url_database_unittest.cc
+++ b/chrome/browser/history/starred_url_database_unittest.cc
@@ -18,7 +18,7 @@ namespace history {
class StarredURLDatabaseTest : public testing::Test,
public StarredURLDatabase {
public:
- StarredURLDatabaseTest() : db_(NULL), statement_cache_(NULL) {
+ StarredURLDatabaseTest() {
}
void AddPage(const GURL& url) {
@@ -44,7 +44,7 @@ class StarredURLDatabaseTest : public testing::Test,
}
int GetStarredEntryCount() {
- DCHECK(db_);
+ DCHECK(db_.is_open());
std::vector<StarredEntry> entries;
GetAllStarredEntries(&entries);
return static_cast<int>(entries.size());
@@ -77,8 +77,7 @@ class StarredURLDatabaseTest : public testing::Test,
FILE_PATH_LITERAL("History_with_empty_starred"));
file_util::CopyFile(old_history_path, db_file_);
- EXPECT_EQ(SQLITE_OK, OpenSqliteDb(db_file_, &db_));
- statement_cache_ = new SqliteStatementCache(db_);
+ EXPECT_TRUE(db_.Open(db_file_));
// Initialize the tables for this test.
CreateURLTable(false);
@@ -86,22 +85,17 @@ class StarredURLDatabaseTest : public testing::Test,
EnsureStarredIntegrity();
}
void TearDown() {
- delete statement_cache_;
- sqlite3_close(db_);
+ db_.Close();
file_util::Delete(db_file_, false);
}
// Provided for URL/StarredURLDatabase.
- virtual sqlite3* GetDB() {
+ virtual sql::Connection& GetDB() {
return db_;
}
- virtual SqliteStatementCache& GetStatementCache() {
- return *statement_cache_;
- }
FilePath db_file_;
- sqlite3* db_;
- SqliteStatementCache* statement_cache_;
+ sql::Connection db_;
};
//-----------------------------------------------------------------------------
diff --git a/chrome/browser/history/text_database.cc b/chrome/browser/history/text_database.cc
index e9b37eb..fa46853 100644
--- a/chrome/browser/history/text_database.cc
+++ b/chrome/browser/history/text_database.cc
@@ -35,8 +35,6 @@
// an FTS table that is indexed like a normal table, and the index over it is
// free since sqlite always indexes the internal rowid.
-using base::Time;
-
namespace history {
namespace {
@@ -158,7 +156,7 @@ bool TextDatabase::Init() {
db_.set_exclusive_locking();
// Attach the database to our index file.
- if (!db_.Init(file_name_))
+ if (!db_.Open(file_name_))
return false;
// Meta table tracking version information.
@@ -215,7 +213,7 @@ bool TextDatabase::CreateTables() {
return true;
}
-bool TextDatabase::AddPageData(Time time,
+bool TextDatabase::AddPageData(base::Time time,
const std::string& url,
const std::string& title,
const std::string& contents) {
@@ -257,7 +255,7 @@ bool TextDatabase::AddPageData(Time time,
return committer.Commit();
}
-void TextDatabase::DeletePageData(Time time, const std::string& url) {
+void TextDatabase::DeletePageData(base::Time time, const std::string& url) {
// First get all rows that match. Selecing on time (which has an index) allows
// us to avoid brute-force searches on the full-text-index table (there will
// generally be only one match per time).
@@ -316,7 +314,7 @@ void TextDatabase::GetTextMatches(const std::string& query,
const QueryOptions& options,
std::vector<Match>* results,
URLSet* found_urls,
- Time* first_time_searched) {
+ base::Time* first_time_searched) {
*first_time_searched = options.begin_time;
sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
@@ -360,7 +358,7 @@ void TextDatabase::GetTextMatches(const std::string& query,
match.url.Swap(&url);
match.title = UTF8ToWide(statement.ColumnString(1));
- match.time = Time::FromInternalValue(statement.ColumnInt64(2));
+ match.time = base::Time::FromInternalValue(statement.ColumnInt64(2));
// Extract any matches in the title.
std::string offsets_str = statement.ColumnString(3);
diff --git a/chrome/browser/history/text_database_manager.cc b/chrome/browser/history/text_database_manager.cc
index 03e992f..868a5d8 100644
--- a/chrome/browser/history/text_database_manager.cc
+++ b/chrome/browser/history/text_database_manager.cc
@@ -72,7 +72,6 @@ TextDatabaseManager::TextDatabaseManager(const FilePath& dir,
URLDatabase* url_database,
VisitDatabase* visit_database)
: dir_(dir),
- db_(NULL),
url_database_(url_database),
visit_database_(visit_database),
recent_changes_(RecentChangeList::NO_AUTO_EVICT),
diff --git a/chrome/browser/history/text_database_manager.h b/chrome/browser/history/text_database_manager.h
index 85b9992..b27b9db 100644
--- a/chrome/browser/history/text_database_manager.h
+++ b/chrome/browser/history/text_database_manager.h
@@ -244,10 +244,6 @@ class TextDatabaseManager {
// Directory holding our index files.
const FilePath dir_;
- // The database connection.
- sqlite3* db_;
- DBCloseScoper db_close_scoper_;
-
// Non-owning pointers to the recent history databases for URLs and visits.
URLDatabase* url_database_;
VisitDatabase* visit_database_;
diff --git a/chrome/browser/history/text_database_manager_unittest.cc b/chrome/browser/history/text_database_manager_unittest.cc
index 9762ec1..ea23e96 100644
--- a/chrome/browser/history/text_database_manager_unittest.cc
+++ b/chrome/browser/history/text_database_manager_unittest.cc
@@ -1,7 +1,8 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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 "app/sql/connection.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/message_loop.h"
@@ -43,26 +44,19 @@ const wchar_t* kBody5 = L"FOO page one.";
class InMemDB : public URLDatabase, public VisitDatabase {
public:
InMemDB() {
- sqlite3_open(":memory:", &db_);
- statement_cache_ = new SqliteStatementCache(db_);
+ EXPECT_TRUE(db_.OpenInMemory());
CreateURLTable(false);
InitVisitTable();
}
~InMemDB() {
- delete statement_cache_;
- sqlite3_close(db_);
}
private:
- virtual sqlite3* GetDB() { return db_; }
- virtual SqliteStatementCache& GetStatementCache() {
- return *statement_cache_;
- }
+ virtual sql::Connection& GetDB() { return db_; }
- sqlite3* db_;
- SqliteStatementCache* statement_cache_;
+ sql::Connection db_;
- DISALLOW_EVIL_CONSTRUCTORS(InMemDB);
+ DISALLOW_COPY_AND_ASSIGN(InMemDB);
};
// Adds all the pages once, and the first page once more in the next month.
diff --git a/chrome/browser/history/thumbnail_database.cc b/chrome/browser/history/thumbnail_database.cc
index f3bdeca..735440f 100644
--- a/chrome/browser/history/thumbnail_database.cc
+++ b/chrome/browser/history/thumbnail_database.cc
@@ -1,32 +1,27 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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/thumbnail_database.h"
+#include "app/sql/statement.h"
+#include "app/sql/transaction.h"
#include "base/file_util.h"
#include "base/gfx/jpeg_codec.h"
#include "base/time.h"
#include "base/string_util.h"
#include "chrome/browser/history/history_publisher.h"
#include "chrome/browser/history/url_database.h"
-#include "chrome/common/sqlite_utils.h"
#include "chrome/common/thumbnail_score.h"
#include "third_party/skia/include/core/SkBitmap.h"
-using base::Time;
-
namespace history {
// Version number of the database.
static const int kCurrentVersionNumber = 3;
static const int kCompatibleVersionNumber = 3;
-ThumbnailDatabase::ThumbnailDatabase()
- : db_(NULL),
- statement_cache_(NULL),
- transaction_nesting_(0),
- history_publisher_(NULL) {
+ThumbnailDatabase::ThumbnailDatabase() : history_publisher_(NULL) {
}
ThumbnailDatabase::~ThumbnailDatabase() {
@@ -37,18 +32,13 @@ InitStatus ThumbnailDatabase::Init(const FilePath& db_name,
const HistoryPublisher* history_publisher) {
history_publisher_ = history_publisher;
- // OpenSqliteDb uses the narrow version of open, so the resulting DB is in
- // UTF-8.
- if (OpenSqliteDb(db_name, &db_) != SQLITE_OK)
- return INIT_FAILURE;
-
// Set the database page size to something larger to give us
// better performance (we're typically seek rather than bandwidth limited).
// This only has an effect before any tables have been created, otherwise
// this is a NOP. Must be a power of 2 and a max of 8192. We use a bigger
// one because we're storing larger data (4-16K) in it, so we want a few
// blocks per element.
- sqlite3_exec(db_, "PRAGMA page_size=4096", NULL, NULL, NULL);
+ db_.set_page_size(4096);
// The UI is generally designed to work well when the thumbnail database is
// slow, so we can tolerate much less caching. The file is also very large
@@ -56,25 +46,27 @@ InitStatus ThumbnailDatabase::Init(const FilePath& db_name,
// reducing the benefit of caching in the first place. With the default cache
// size of 2000 pages, it will take >8MB of memory, so reducing it can be a
// big savings.
- sqlite3_exec(db_, "PRAGMA cache_size=64", NULL, NULL, NULL);
+ db_.set_cache_size(64);
// Run the database in exclusive mode. Nobody else should be accessing the
// database while we're running, and this will give somewhat improved perf.
- sqlite3_exec(db_, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, NULL);
+ db_.set_exclusive_locking();
- statement_cache_ = new SqliteStatementCache;
- DBCloseScoper scoper(&db_, &statement_cache_);
+ if (!db_.Open(db_name))
+ return INIT_FAILURE;
// Scope initialization in a transaction so we can't be partially initialized.
- SQLTransaction transaction(db_);
+ sql::Transaction transaction(&db_);
transaction.Begin();
// Create the tables.
- if (!meta_table_.Init(std::string(), kCurrentVersionNumber,
- kCompatibleVersionNumber, db_) ||
+ if (!meta_table_.Init(&db_, kCurrentVersionNumber,
+ kCompatibleVersionNumber) ||
!InitThumbnailTable() ||
- !InitFavIconsTable(false))
+ !InitFavIconsTable(false)) {
+ db_.Close();
return INIT_FAILURE;
+ }
InitFavIconsIndex();
// Version check. We should not encounter a database too old for us to handle
@@ -88,6 +80,7 @@ InitStatus ThumbnailDatabase::Init(const FilePath& db_name,
if (cur_version == 2) {
if (!UpgradeToVersion3()) {
LOG(WARNING) << "Unable to update to thumbnail database to version 3.";
+ db_.Close();
return INIT_FAILURE;
}
++cur_version;
@@ -97,13 +90,10 @@ InitStatus ThumbnailDatabase::Init(const FilePath& db_name,
"Thumbnail database version " << cur_version << " is too old to handle.";
// Initialization is complete.
- if (transaction.Commit() != SQLITE_OK)
+ if (!transaction.Commit()) {
+ db_.Close();
return INIT_FAILURE;
-
- // Initialize the statement cache and the scoper to automatically close it.
- statement_cache_->set_db(db_);
- scoper.Detach();
- close_scoper_.Attach(&db_, &statement_cache_);
+ }
// The following code is useful in debugging the thumbnail database. Upon
// startup, it will spit out a file for each thumbnail in the database so you
@@ -111,12 +101,12 @@ InitStatus ThumbnailDatabase::Init(const FilePath& db_name,
// into the string below (I recommend using a blank directory since there may
// be a lot of files).
#if 0
- SQLStatement statement;
- statement.prepare(db_, "SELECT id, image_data FROM favicons");
- while (statement.step() == SQLITE_ROW) {
- int idx = statement.column_int(0);
+ sql::Statement statement(db_.GetUniqueStatement(
+ "SELECT id, image_data FROM favicons"));
+ while (statement.Step()) {
+ int idx = statement.ColumnInt(0);
std::vector<unsigned char> data;
- statement.column_blob_as_vector(1, &data);
+ statement.ColumnBlobAsVector(1, &data);
char filename[256];
sprintf(filename, "<<< YOUR PATH HERE >>>\\%d.png", idx);
@@ -132,14 +122,14 @@ InitStatus ThumbnailDatabase::Init(const FilePath& db_name,
}
bool ThumbnailDatabase::InitThumbnailTable() {
- if (!DoesSqliteTableExist(db_, "thumbnails")) {
- if (sqlite3_exec(db_, "CREATE TABLE thumbnails ("
+ if (!db_.DoesTableExist("thumbnails")) {
+ if (!db_.Execute("CREATE TABLE thumbnails ("
"url_id INTEGER PRIMARY KEY,"
"boring_score DOUBLE DEFAULT 1.0,"
"good_clipping INTEGER DEFAULT 0,"
"at_top INTEGER DEFAULT 0,"
"last_updated INTEGER DEFAULT 0,"
- "data BLOB)", NULL, NULL, NULL) != SQLITE_OK)
+ "data BLOB)"))
return false;
}
return true;
@@ -157,8 +147,7 @@ bool ThumbnailDatabase::UpgradeToVersion3() {
};
for (int i = 0; alterations[i] != NULL; ++i) {
- if (sqlite3_exec(db_, alterations[i],
- NULL, NULL, NULL) != SQLITE_OK) {
+ if (!db_.Execute(alterations[i])) {
NOTREACHED();
return false;
}
@@ -170,7 +159,7 @@ bool ThumbnailDatabase::UpgradeToVersion3() {
}
bool ThumbnailDatabase::RecreateThumbnailTable() {
- if (sqlite3_exec(db_, "DROP TABLE thumbnails", NULL, NULL, NULL) != SQLITE_OK)
+ if (!db_.Execute("DROP TABLE thumbnails"))
return false;
return InitThumbnailTable();
}
@@ -179,7 +168,7 @@ bool ThumbnailDatabase::InitFavIconsTable(bool is_temporary) {
// Note: if you update the schema, don't forget to update
// CopyToTemporaryFaviconTable as well.
const char* name = is_temporary ? "temp_favicons" : "favicons";
- if (!DoesSqliteTableExist(db_, name)) {
+ if (!db_.DoesTableExist(name)) {
std::string sql;
sql.append("CREATE TABLE ");
sql.append(name);
@@ -188,7 +177,7 @@ bool ThumbnailDatabase::InitFavIconsTable(bool is_temporary) {
"url LONGVARCHAR NOT NULL,"
"last_updated INTEGER DEFAULT 0,"
"image_data BLOB)");
- if (sqlite3_exec(db_, sql.c_str(), NULL, NULL, NULL) != SQLITE_OK)
+ if (!db_.Execute(sql.c_str()))
return false;
}
return true;
@@ -197,33 +186,21 @@ bool ThumbnailDatabase::InitFavIconsTable(bool is_temporary) {
void ThumbnailDatabase::InitFavIconsIndex() {
// Add an index on the url column. We ignore errors. Since this is always
// called during startup, the index will normally already exist.
- sqlite3_exec(db_, "CREATE INDEX favicons_url ON favicons(url)",
- NULL, NULL, NULL);
+ db_.Execute("CREATE INDEX favicons_url ON favicons(url)");
}
void ThumbnailDatabase::BeginTransaction() {
- DCHECK(db_);
- if (transaction_nesting_ == 0) {
- int rv = sqlite3_exec(db_, "BEGIN TRANSACTION", NULL, NULL, NULL);
- DCHECK(rv == SQLITE_OK) << "Failed to begin transaction";
- }
- transaction_nesting_++;
+ db_.BeginTransaction();
}
void ThumbnailDatabase::CommitTransaction() {
- DCHECK(db_);
- DCHECK(transaction_nesting_ > 0) << "Committing too many transaction";
- transaction_nesting_--;
- if (transaction_nesting_ == 0) {
- int rv = sqlite3_exec(db_, "COMMIT", NULL, NULL, NULL);
- DCHECK(rv == SQLITE_OK) << "Failed to commit transaction";
- }
+ db_.CommitTransaction();
}
void ThumbnailDatabase::Vacuum() {
- DCHECK(transaction_nesting_ == 0) <<
+ DCHECK(db_.transaction_nesting() == 0) <<
"Can not have a transaction when vacuuming.";
- sqlite3_exec(db_, "VACUUM", NULL, NULL, NULL);
+ db_.Execute("VACUUM");
}
void ThumbnailDatabase::SetPageThumbnail(
@@ -231,7 +208,7 @@ void ThumbnailDatabase::SetPageThumbnail(
URLID id,
const SkBitmap& thumbnail,
const ThumbnailScore& score,
- const Time& time) {
+ base::Time time) {
if (!thumbnail.isNull()) {
bool add_thumbnail = true;
ThumbnailScore current_score;
@@ -240,12 +217,11 @@ void ThumbnailDatabase::SetPageThumbnail(
}
if (add_thumbnail) {
- SQLITE_UNIQUE_STATEMENT(
- statement, *statement_cache_,
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
"INSERT OR REPLACE INTO thumbnails "
"(url_id, boring_score, good_clipping, at_top, last_updated, data) "
- "VALUES (?,?,?,?,?,?)");
- if (!statement.is_valid())
+ "VALUES (?,?,?,?,?,?)"));
+ if (!statement)
return;
// We use 90 quality (out of 100) which is pretty high, because
@@ -261,15 +237,15 @@ void ThumbnailDatabase::SetPageThumbnail(
&jpeg_data);
if (encoded) {
- statement->bind_int64(0, id);
- statement->bind_double(1, score.boring_score);
- statement->bind_bool(2, score.good_clipping);
- statement->bind_bool(3, score.at_top);
- statement->bind_int64(4, score.time_at_snapshot.ToTimeT());
- statement->bind_blob(5, &jpeg_data[0],
- static_cast<int>(jpeg_data.size()));
- if (statement->step() != SQLITE_DONE)
- DLOG(WARNING) << "Unable to insert thumbnail";
+ statement.BindInt64(0, id);
+ statement.BindDouble(1, score.boring_score);
+ statement.BindBool(2, score.good_clipping);
+ statement.BindBool(3, score.at_top);
+ statement.BindInt64(4, score.time_at_snapshot.ToTimeT());
+ statement.BindBlob(5, &jpeg_data[0],
+ static_cast<int>(jpeg_data.size()));
+ if (!statement.Run())
+ NOTREACHED() << db_.GetErrorMessage();
}
// Publish the thumbnail to any indexers listening to us.
@@ -278,55 +254,53 @@ void ThumbnailDatabase::SetPageThumbnail(
history_publisher_->PublishPageThumbnail(jpeg_data, url, time);
}
} else {
- if ( !DeleteThumbnail(id) )
+ if (!DeleteThumbnail(id) )
DLOG(WARNING) << "Unable to delete thumbnail";
}
}
bool ThumbnailDatabase::GetPageThumbnail(URLID id,
std::vector<unsigned char>* data) {
- SQLITE_UNIQUE_STATEMENT(
- statement, *statement_cache_,
- "SELECT data FROM thumbnails WHERE url_id=?");
- if (!statement.is_valid())
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
+ "SELECT data FROM thumbnails WHERE url_id=?"));
+ if (!statement)
return false;
- statement->bind_int64(0, id);
- if (statement->step() != SQLITE_ROW)
+ statement.BindInt64(0, id);
+ if (!statement.Step())
return false; // don't have a thumbnail for this ID
- return statement->column_blob_as_vector(0, data);
+ statement.ColumnBlobAsVector(0, data);
+ return true;
}
bool ThumbnailDatabase::DeleteThumbnail(URLID id) {
- SQLITE_UNIQUE_STATEMENT(
- statement, *statement_cache_,
- "DELETE FROM thumbnails WHERE url_id = ?");
- if (!statement.is_valid())
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
+ "DELETE FROM thumbnails WHERE url_id = ?"));
+ if (!statement)
return false;
- statement->bind_int64(0, id);
- return statement->step() == SQLITE_DONE;
+ statement.BindInt64(0, id);
+ return statement.Run();
}
-bool ThumbnailDatabase::ThumbnailScoreForId(
- URLID id,
- ThumbnailScore* score) {
+bool ThumbnailDatabase::ThumbnailScoreForId(URLID id,
+ ThumbnailScore* score) {
// Fetch the current thumbnail's information to make sure we
// aren't replacing a good thumbnail with one that's worse.
- SQLITE_UNIQUE_STATEMENT(
- select_statement, *statement_cache_,
+ sql::Statement select_statement(db_.GetCachedStatement(SQL_FROM_HERE,
"SELECT boring_score, good_clipping, at_top, last_updated "
- "FROM thumbnails WHERE url_id=?");
- if (!select_statement.is_valid()) {
+ "FROM thumbnails WHERE url_id=?"));
+ if (!select_statement) {
NOTREACHED() << "Couldn't build select statement!";
} else {
- select_statement->bind_int64(0, id);
- if (select_statement->step() == SQLITE_ROW) {
- double current_boring_score = select_statement->column_double(0);
- bool current_clipping = select_statement->column_bool(1);
- bool current_at_top = select_statement->column_bool(2);
- Time last_updated = Time::FromTimeT(select_statement->column_int64(3));
+ select_statement.BindInt64(0, id);
+ if (select_statement.Step()) {
+ double current_boring_score = select_statement.ColumnDouble(0);
+ bool current_clipping = select_statement.ColumnBool(1);
+ bool current_at_top = select_statement.ColumnBool(2);
+ base::Time last_updated =
+ base::Time::FromTimeT(select_statement.ColumnInt64(3));
*score = ThumbnailScore(current_boring_score, current_clipping,
current_at_top, last_updated);
return true;
@@ -338,131 +312,125 @@ bool ThumbnailDatabase::ThumbnailScoreForId(
bool ThumbnailDatabase::SetFavIcon(URLID icon_id,
const std::vector<unsigned char>& icon_data,
- Time time) {
+ base::Time time) {
DCHECK(icon_id);
if (icon_data.size()) {
- SQLITE_UNIQUE_STATEMENT(
- statement, *statement_cache_,
- "UPDATE favicons SET image_data=?, last_updated=? WHERE id=?");
- if (!statement.is_valid())
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
+ "UPDATE favicons SET image_data=?, last_updated=? WHERE id=?"));
+ if (!statement)
return 0;
- statement->bind_blob(0, &icon_data.front(),
- static_cast<int>(icon_data.size()));
- statement->bind_int64(1, time.ToTimeT());
- statement->bind_int64(2, icon_id);
- return statement->step() == SQLITE_DONE;
+ statement.BindBlob(0, &icon_data.front(),
+ static_cast<int>(icon_data.size()));
+ statement.BindInt64(1, time.ToTimeT());
+ statement.BindInt64(2, icon_id);
+ return statement.Run();
} else {
- SQLITE_UNIQUE_STATEMENT(
- statement, *statement_cache_,
- "UPDATE favicons SET image_data=NULL, last_updated=? WHERE id=?");
- if (!statement.is_valid())
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
+ "UPDATE favicons SET image_data=NULL, last_updated=? WHERE id=?"));
+ if (!statement)
return 0;
- statement->bind_int64(0, time.ToTimeT());
- statement->bind_int64(1, icon_id);
- return statement->step() == SQLITE_DONE;
+ statement.BindInt64(0, time.ToTimeT());
+ statement.BindInt64(1, icon_id);
+ return statement.Run();
}
}
bool ThumbnailDatabase::SetFavIconLastUpdateTime(FavIconID icon_id,
- const Time& time) {
- SQLITE_UNIQUE_STATEMENT(
- statement, *statement_cache_,
- "UPDATE favicons SET last_updated=? WHERE id=?");
- if (!statement.is_valid())
+ base::Time time) {
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
+ "UPDATE favicons SET last_updated=? WHERE id=?"));
+ if (!statement)
return 0;
- statement->bind_int64(0, time.ToTimeT());
- statement->bind_int64(1, icon_id);
- return statement->step() == SQLITE_DONE;
+ statement.BindInt64(0, time.ToTimeT());
+ statement.BindInt64(1, icon_id);
+ return statement.Run();
}
FavIconID ThumbnailDatabase::GetFavIconIDForFavIconURL(const GURL& icon_url) {
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "SELECT id FROM favicons WHERE url=?");
- if (!statement.is_valid())
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
+ "SELECT id FROM favicons WHERE url=?"));
+ if (!statement)
return 0;
- statement->bind_string(0, URLDatabase::GURLToDatabaseURL(icon_url));
- if (statement->step() != SQLITE_ROW)
+ statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url));
+ if (!statement.Step())
return 0; // not cached
- return statement->column_int64(0);
+ return statement.ColumnInt64(0);
}
bool ThumbnailDatabase::GetFavIcon(
FavIconID icon_id,
- Time* last_updated,
+ base::Time* last_updated,
std::vector<unsigned char>* png_icon_data,
GURL* icon_url) {
DCHECK(icon_id);
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "SELECT last_updated, image_data, url FROM favicons WHERE id=?");
- if (!statement.is_valid())
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
+ "SELECT last_updated, image_data, url FROM favicons WHERE id=?"));
+ if (!statement)
return 0;
- statement->bind_int64(0, icon_id);
+ statement.BindInt64(0, icon_id);
- if (statement->step() != SQLITE_ROW) {
- // No entry for the id.
- return false;
- }
+ if (!statement.Step())
+ return false; // No entry for the id.
- *last_updated = Time::FromTimeT(statement->column_int64(0));
- if (statement->column_bytes(1) > 0)
- statement->column_blob_as_vector(1, png_icon_data);
+ *last_updated = base::Time::FromTimeT(statement.ColumnInt64(0));
+ if (statement.ColumnByteLength(1) > 0)
+ statement.ColumnBlobAsVector(1, png_icon_data);
if (icon_url)
- *icon_url = GURL(statement->column_string(2));
+ *icon_url = GURL(statement.ColumnString(2));
return true;
}
FavIconID ThumbnailDatabase::AddFavIcon(const GURL& icon_url) {
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "INSERT INTO favicons (url) VALUES (?)");
- if (!statement.is_valid())
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
+ "INSERT INTO favicons (url) VALUES (?)"));
+ if (!statement)
return 0;
- statement->bind_string(0, URLDatabase::GURLToDatabaseURL(icon_url));
- if (statement->step() != SQLITE_DONE)
+ statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url));
+ if (!statement.Run())
return 0;
- return sqlite3_last_insert_rowid(db_);
+ return db_.GetLastInsertRowId();
}
bool ThumbnailDatabase::DeleteFavIcon(FavIconID id) {
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "DELETE FROM favicons WHERE id = ?");
- if (!statement.is_valid())
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
+ "DELETE FROM favicons WHERE id = ?"));
+ if (!statement)
return false;
- statement->bind_int64(0, id);
- return statement->step() == SQLITE_DONE;
+ statement.BindInt64(0, id);
+ return statement.Run();
}
FavIconID ThumbnailDatabase::CopyToTemporaryFavIconTable(FavIconID source) {
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
"INSERT INTO temp_favicons (url, last_updated, image_data)"
"SELECT url, last_updated, image_data "
- "FROM favicons WHERE id = ?");
- if (!statement.is_valid())
+ "FROM favicons WHERE id = ?"));
+ if (!statement)
return 0;
- statement->bind_int64(0, source);
- if (statement->step() != SQLITE_DONE)
+ statement.BindInt64(0, source);
+ if (!statement.Run())
return 0;
// We return the ID of the newly inserted favicon.
- return sqlite3_last_insert_rowid(db_);
+ return db_.GetLastInsertRowId();
}
bool ThumbnailDatabase::CommitTemporaryFavIconTable() {
// Delete the old favicons table.
- if (sqlite3_exec(db_, "DROP TABLE favicons", NULL, NULL, NULL) != SQLITE_OK)
+ if (!db_.Execute("DROP TABLE favicons"))
return false;
// Rename the temporary one.
- if (sqlite3_exec(db_, "ALTER TABLE temp_favicons RENAME TO favicons",
- NULL, NULL, NULL) != SQLITE_OK)
+ if (!db_.Execute("ALTER TABLE temp_favicons RENAME TO favicons"))
return false;
// The renamed table needs the index (the temporary table doesn't have one).
diff --git a/chrome/browser/history/thumbnail_database.h b/chrome/browser/history/thumbnail_database.h
index 7df5652..7fd9202 100644
--- a/chrome/browser/history/thumbnail_database.h
+++ b/chrome/browser/history/thumbnail_database.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
@@ -7,17 +7,18 @@
#include <vector>
+#include "app/sql/connection.h"
+#include "app/sql/meta_table.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/history/url_database.h" // For DBCloseScoper.
#include "chrome/browser/meta_table_helper.h"
-struct sqlite3;
class FilePath;
struct ThumbnailScore;
class SkBitmap;
-class SqliteStatementCache;
+
namespace base {
- class Time;
+class Time;
}
namespace history {
@@ -46,7 +47,7 @@ class ThumbnailDatabase {
void BeginTransaction();
void CommitTransaction();
int transaction_nesting() const {
- return transaction_nesting_;
+ return db_.transaction_nesting();
}
// Vacuums the database. This will cause sqlite to defragment and collect
@@ -62,7 +63,7 @@ class ThumbnailDatabase {
URLID id,
const SkBitmap& thumbnail,
const ThumbnailScore& score,
- const base::Time& time);
+ base::Time time);
// Retrieves thumbnail data for the given URL, returning true on success,
// false if there is no such thumbnail or there was some other error.
@@ -90,7 +91,7 @@ class ThumbnailDatabase {
base::Time time);
// Sets the time the favicon was last updated.
- bool SetFavIconLastUpdateTime(FavIconID icon_id, const base::Time& time);
+ bool SetFavIconLastUpdateTime(FavIconID icon_id, base::Time time);
// Returns the id of the entry in the favicon database with the specified url.
// Returns 0 if no entry exists for the specified url.
@@ -154,17 +155,8 @@ class ThumbnailDatabase {
// newly-renamed favicons table (formerly the temporary table with no index).
void InitFavIconsIndex();
- // Ensures that db_ and statement_cache_ are destroyed in the proper order.
- DBCloseScoper close_scoper_;
-
- // The database connection and the statement cache: MAY BE NULL if database
- // init failed. These are cleaned up by the close_scoper_.
- sqlite3* db_;
- SqliteStatementCache* statement_cache_;
-
- int transaction_nesting_;
-
- MetaTableHelper meta_table_;
+ sql::Connection db_;
+ sql::MetaTable meta_table_;
// This object is created and managed by the history backend. We maintain an
// opaque pointer to the object for our use.
diff --git a/chrome/browser/history/url_database.cc b/chrome/browser/history/url_database.cc
index b15af5b..0a9115f 100644
--- a/chrome/browser/history/url_database.cc
+++ b/chrome/browser/history/url_database.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
@@ -8,20 +8,19 @@
#include <limits>
#include "app/l10n_util.h"
+#include "app/sql/connection.h"
+#include "app/sql/statement.h"
#include "base/string_util.h"
-#include "chrome/common/sqlite_utils.h"
#include "chrome/common/url_constants.h"
#include "googleurl/src/gurl.h"
-using base::Time;
-
namespace history {
const char URLDatabase::kURLRowFields[] = HISTORY_URL_ROW_FIELDS;
const int URLDatabase::kNumURLRowFields = 9;
bool URLDatabase::URLEnumerator::GetNextURL(URLRow* r) {
- if (statement_.step() == SQLITE_ROW) {
+ if (statement_.Step()) {
FillURLRow(statement_, r);
return true;
}
@@ -42,16 +41,16 @@ std::string URLDatabase::GURLToDatabaseURL(const GURL& gurl) {
// Convenience to fill a history::URLRow. Must be in sync with the fields in
// kURLRowFields.
-void URLDatabase::FillURLRow(SQLStatement& s, history::URLRow* i) {
+void URLDatabase::FillURLRow(sql::Statement& s, history::URLRow* i) {
DCHECK(i);
- i->id_ = s.column_int64(0);
- i->url_ = GURL(s.column_string(1));
- i->title_ = s.column_wstring(2);
- i->visit_count_ = s.column_int(3);
- i->typed_count_ = s.column_int(4);
- i->last_visit_ = Time::FromInternalValue(s.column_int64(5));
- i->hidden_ = s.column_int(6) != 0;
- i->favicon_id_ = s.column_int64(7);
+ i->id_ = s.ColumnInt64(0);
+ i->url_ = GURL(s.ColumnString(1));
+ i->title_ = UTF8ToWide(s.ColumnString(2));
+ i->visit_count_ = s.ColumnInt(3);
+ i->typed_count_ = s.ColumnInt(4);
+ i->last_visit_ = base::Time::FromInternalValue(s.ColumnInt64(5));
+ i->hidden_ = s.ColumnInt(6) != 0;
+ i->favicon_id_ = s.ColumnInt64(7);
}
bool URLDatabase::GetURLRow(URLID url_id, URLRow* info) {
@@ -59,52 +58,52 @@ bool URLDatabase::GetURLRow(URLID url_id, URLRow* info) {
// there are old URLs in the database that are empty that got in before
// we added any checks. We should eventually be able to remove it
// when all inputs are using GURL (which prohibit empty input).
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls WHERE id=?");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls WHERE id=?"));
+ if (!statement)
return false;
- statement->bind_int64(0, url_id);
- if (statement->step() == SQLITE_ROW) {
- FillURLRow(*statement, info);
+ statement.BindInt64(0, url_id);
+ if (statement.Step()) {
+ FillURLRow(statement, info);
return true;
}
return false;
}
URLID URLDatabase::GetRowForURL(const GURL& url, history::URLRow* info) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls WHERE url=?");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls WHERE url=?"));
+ if (!statement)
return 0;
std::string url_string = GURLToDatabaseURL(url);
- statement->bind_string(0, url_string);
- if (statement->step() != SQLITE_ROW)
+ statement.BindString(0, url_string);
+ if (!statement.Step())
return 0; // no data
if (info)
- FillURLRow(*statement, info);
- return statement->column_int64(0);
+ FillURLRow(statement, info);
+ return statement.ColumnInt64(0);
}
bool URLDatabase::UpdateURLRow(URLID url_id,
const history::URLRow& info) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"UPDATE urls SET title=?,visit_count=?,typed_count=?,last_visit_time=?,"
"hidden=?,favicon_id=?"
- "WHERE id=?");
- if (!statement.is_valid())
+ "WHERE id=?"));
+ if (!statement)
return false;
- statement->bind_wstring(0, info.title());
- statement->bind_int(1, info.visit_count());
- statement->bind_int(2, info.typed_count());
- statement->bind_int64(3, info.last_visit().ToInternalValue());
- statement->bind_int(4, info.hidden() ? 1 : 0);
- statement->bind_int64(5, info.favicon_id());
- statement->bind_int64(6, url_id);
- return statement->step() == SQLITE_DONE;
+ statement.BindString(0, WideToUTF8(info.title()));
+ statement.BindInt(1, info.visit_count());
+ statement.BindInt(2, info.typed_count());
+ statement.BindInt64(3, info.last_visit().ToInternalValue());
+ statement.BindInt(4, info.hidden() ? 1 : 0);
+ statement.BindInt64(5, info.favicon_id());
+ statement.BindInt64(6, url_id);
+ return statement.Run();
}
URLID URLDatabase::AddURLInternal(const history::URLRow& info,
@@ -128,44 +127,46 @@ URLID URLDatabase::AddURLInternal(const history::URLRow& info,
}
#undef ADDURL_COMMON_SUFFIX
- SqliteCompiledStatement statement(statement_name, 0, GetStatementCache(),
- statement_sql);
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(
+ sql::StatementID(statement_name), statement_sql));
+ if (!statement) {
+ NOTREACHED() << GetDB().GetErrorMessage();
return 0;
+ }
- statement->bind_string(0, GURLToDatabaseURL(info.url()));
- statement->bind_wstring(1, info.title());
- statement->bind_int(2, info.visit_count());
- statement->bind_int(3, info.typed_count());
- statement->bind_int64(4, info.last_visit().ToInternalValue());
- statement->bind_int(5, info.hidden() ? 1 : 0);
- statement->bind_int64(6, info.favicon_id());
+ statement.BindString(0, GURLToDatabaseURL(info.url()));
+ statement.BindString(1, WideToUTF8(info.title()));
+ statement.BindInt(2, info.visit_count());
+ statement.BindInt(3, info.typed_count());
+ statement.BindInt64(4, info.last_visit().ToInternalValue());
+ statement.BindInt(5, info.hidden() ? 1 : 0);
+ statement.BindInt64(6, info.favicon_id());
- if (statement->step() != SQLITE_DONE)
+ if (!statement.Run())
return 0;
- return sqlite3_last_insert_rowid(GetDB());
+ return GetDB().GetLastInsertRowId();
}
bool URLDatabase::DeleteURLRow(URLID id) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "DELETE FROM urls WHERE id = ?");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "DELETE FROM urls WHERE id = ?"));
+ if (!statement)
return false;
- statement->bind_int64(0, id);
- if (statement->step() != SQLITE_DONE)
+ statement.BindInt64(0, id);
+ if (!statement.Run())
return false;
- // And delete any keyword visits.
+ // And delete any keyword visits.
if (!has_keyword_search_terms_)
return true;
- SQLITE_UNIQUE_STATEMENT(del_keyword_visit, GetStatementCache(),
- "DELETE FROM keyword_search_terms WHERE url_id=?");
- if (!del_keyword_visit.is_valid())
+ sql::Statement del_keyword_visit(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "DELETE FROM keyword_search_terms WHERE url_id=?"));
+ if (!del_keyword_visit)
return false;
- del_keyword_visit->bind_int64(0, id);
- return (del_keyword_visit->step() == SQLITE_DONE);
+ del_keyword_visit.BindInt64(0, id);
+ return del_keyword_visit.Run();
}
bool URLDatabase::CreateTemporaryURLTable() {
@@ -181,14 +182,12 @@ bool URLDatabase::CommitTemporaryURLTable() {
// supplimentary indices that the archived database doesn't need.
// Swap the url table out and replace it with the temporary one.
- if (sqlite3_exec(GetDB(), "DROP TABLE urls",
- NULL, NULL, NULL) != SQLITE_OK) {
- NOTREACHED();
+ if (!GetDB().Execute("DROP TABLE urls")) {
+ NOTREACHED() << GetDB().GetErrorMessage();
return false;
}
- if (sqlite3_exec(GetDB(), "ALTER TABLE temp_urls RENAME TO urls",
- NULL, NULL, NULL) != SQLITE_OK) {
- NOTREACHED();
+ if (!GetDB().Execute("ALTER TABLE temp_urls RENAME TO urls")) {
+ NOTREACHED() << GetDB().GetErrorMessage();
return false;
}
@@ -206,8 +205,9 @@ bool URLDatabase::InitURLEnumeratorForEverything(URLEnumerator* enumerator) {
std::string sql("SELECT ");
sql.append(kURLRowFields);
sql.append(" FROM urls");
- if (enumerator->statement_.prepare(GetDB(), sql.c_str()) != SQLITE_OK) {
- NOTREACHED() << "Query statement prep failed";
+ enumerator->statement_.Assign(GetDB().GetUniqueStatement(sql.c_str()));
+ if (!enumerator->statement_) {
+ NOTREACHED() << GetDB().GetErrorMessage();
return false;
}
enumerator->initialized_ = true;
@@ -215,13 +215,13 @@ bool URLDatabase::InitURLEnumeratorForEverything(URLEnumerator* enumerator) {
}
bool URLDatabase::IsFavIconUsed(FavIconID favicon_id) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "SELECT id FROM urls WHERE favicon_id=? LIMIT 1");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "SELECT id FROM urls WHERE favicon_id=? LIMIT 1"));
+ if (!statement)
return false;
- statement->bind_int64(0, favicon_id);
- return statement->step() == SQLITE_ROW;
+ statement.BindInt64(0, favicon_id);
+ return statement.Step();
}
void URLDatabase::AutocompleteForPrefix(const std::wstring& prefix,
@@ -231,12 +231,12 @@ void URLDatabase::AutocompleteForPrefix(const std::wstring& prefix,
// as bookmarks is no longer part of the db we no longer include the order
// by clause.
results->clear();
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT" HISTORY_URL_ROW_FIELDS "FROM urls "
"WHERE url >= ? AND url < ? AND hidden = 0 "
"ORDER BY typed_count DESC, visit_count DESC, last_visit_time DESC "
- "LIMIT ?");
- if (!statement.is_valid())
+ "LIMIT ?"));
+ if (!statement)
return;
// We will find all strings between "prefix" and this string, which is prefix
@@ -247,13 +247,13 @@ void URLDatabase::AutocompleteForPrefix(const std::wstring& prefix,
std::string end_query(prefix_utf8);
end_query.push_back(std::numeric_limits<unsigned char>::max());
- statement->bind_string(0, prefix_utf8);
- statement->bind_string(1, end_query);
- statement->bind_int(2, static_cast<int>(max_results));
+ statement.BindString(0, prefix_utf8);
+ statement.BindString(1, end_query);
+ statement.BindInt(2, static_cast<int>(max_results));
- while (statement->step() == SQLITE_ROW) {
+ while (statement.Step()) {
history::URLRow info;
- FillURLRow(*statement, &info);
+ FillURLRow(statement, &info);
if (info.url().is_valid())
results->push_back(info);
}
@@ -277,18 +277,18 @@ bool URLDatabase::FindShortestURLFromBase(const std::string& base,
sql.append(" ? AND url < :end AND url = substr(:end, 1, length(url)) "
"AND hidden = 0 AND visit_count >= ? AND typed_count >= ? "
"ORDER BY url LIMIT 1");
- SQLStatement statement;
- if (statement.prepare(GetDB(), sql.c_str()) != SQLITE_OK) {
- NOTREACHED() << "select statement prep failed";
+ sql::Statement statement(GetDB().GetUniqueStatement(sql.c_str()));
+ if (!statement) {
+ NOTREACHED() << GetDB().GetErrorMessage();
return false;
}
- statement.bind_string(0, base);
- statement.bind_string(1, url); // :end
- statement.bind_int(2, min_visits);
- statement.bind_int(3, min_typed);
+ statement.BindString(0, base);
+ statement.BindString(1, url); // :end
+ statement.BindInt(2, min_visits);
+ statement.BindInt(3, min_typed);
- if (statement.step() != SQLITE_ROW)
+ if (!statement.Step())
return false;
DCHECK(info);
@@ -298,33 +298,29 @@ bool URLDatabase::FindShortestURLFromBase(const std::string& base,
bool URLDatabase::InitKeywordSearchTermsTable() {
has_keyword_search_terms_ = true;
- if (!DoesSqliteTableExist(GetDB(), "keyword_search_terms")) {
- if (sqlite3_exec(GetDB(), "CREATE TABLE keyword_search_terms ("
+ if (!GetDB().DoesTableExist("keyword_search_terms")) {
+ if (!GetDB().Execute("CREATE TABLE keyword_search_terms ("
"keyword_id INTEGER NOT NULL," // ID of the TemplateURL.
"url_id INTEGER NOT NULL," // ID of the url.
"lower_term LONGVARCHAR NOT NULL," // The search term, in lower case.
- "term LONGVARCHAR NOT NULL)", // The actual search term.
- NULL, NULL, NULL) != SQLITE_OK)
+ "term LONGVARCHAR NOT NULL)")) // The actual search term.
return false;
}
// For searching.
- sqlite3_exec(GetDB(), "CREATE INDEX keyword_search_terms_index1 ON "
- "keyword_search_terms (keyword_id, lower_term)",
- NULL, NULL, NULL);
+ GetDB().Execute("CREATE INDEX keyword_search_terms_index1 ON "
+ "keyword_search_terms (keyword_id, lower_term)");
// For deletion.
- sqlite3_exec(GetDB(), "CREATE INDEX keyword_search_terms_index2 ON "
- "keyword_search_terms (url_id)",
- NULL, NULL, NULL);
+ GetDB().Execute("CREATE INDEX keyword_search_terms_index2 ON "
+ "keyword_search_terms (url_id)");
return true;
}
bool URLDatabase::DropKeywordSearchTermsTable() {
// This will implicitly delete the indices over the table.
- return sqlite3_exec(GetDB(), "DROP TABLE keyword_search_terms",
- NULL, NULL, NULL) == SQLITE_OK;
+ return GetDB().Execute("DROP TABLE keyword_search_terms");
}
bool URLDatabase::SetKeywordSearchTermsForURL(URLID url_id,
@@ -332,39 +328,39 @@ bool URLDatabase::SetKeywordSearchTermsForURL(URLID url_id,
const std::wstring& term) {
DCHECK(url_id && keyword_id && !term.empty());
- SQLITE_UNIQUE_STATEMENT(exist_statement, GetStatementCache(),
+ sql::Statement exist_statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT term FROM keyword_search_terms "
- "WHERE keyword_id = ? AND url_id = ?");
- if (!exist_statement.is_valid())
+ "WHERE keyword_id = ? AND url_id = ?"));
+ if (!exist_statement)
return false;
- exist_statement->bind_int64(0, keyword_id);
- exist_statement->bind_int64(1, url_id);
- if (exist_statement->step() == SQLITE_ROW)
+ exist_statement.BindInt64(0, keyword_id);
+ exist_statement.BindInt64(1, url_id);
+ if (exist_statement.Step())
return true; // Term already exists, no need to add it.
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"INSERT INTO keyword_search_terms (keyword_id, url_id, lower_term, term) "
- "VALUES (?,?,?,?)");
- if (!statement.is_valid())
+ "VALUES (?,?,?,?)"));
+ if (!statement)
return false;
- statement->bind_int64(0, keyword_id);
- statement->bind_int64(1, url_id);
- statement->bind_wstring(2, l10n_util::ToLower(term));
- statement->bind_wstring(3, term);
- return (statement->step() == SQLITE_DONE);
+ statement.BindInt64(0, keyword_id);
+ statement.BindInt64(1, url_id);
+ statement.BindString(2, UTF16ToUTF8(l10n_util::ToLower(WideToUTF16(term))));
+ statement.BindString(3, WideToUTF8(term));
+ return statement.Run();
}
void URLDatabase::DeleteAllSearchTermsForKeyword(
TemplateURL::IDType keyword_id) {
DCHECK(keyword_id);
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "DELETE FROM keyword_search_terms WHERE keyword_id=?");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "DELETE FROM keyword_search_terms WHERE keyword_id=?"));
+ if (!statement)
return;
- statement->bind_int64(0, keyword_id);
- statement->step();
+ statement.BindInt64(0, keyword_id);
+ statement.Run();
}
void URLDatabase::GetMostRecentKeywordSearchTerms(
@@ -379,30 +375,30 @@ void URLDatabase::GetMostRecentKeywordSearchTerms(
return;
DCHECK(!prefix.empty());
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT DISTINCT kv.term, u.last_visit_time "
"FROM keyword_search_terms kv "
"JOIN urls u ON kv.url_id = u.id "
"WHERE kv.keyword_id = ? AND kv.lower_term >= ? AND kv.lower_term < ? "
- "ORDER BY u.last_visit_time DESC LIMIT ?");
- if (!statement.is_valid())
+ "ORDER BY u.last_visit_time DESC LIMIT ?"));
+ if (!statement)
return;
// NOTE: Keep this ToLower() call in sync with search_provider.cc.
- const std::wstring lower_prefix = l10n_util::ToLower(prefix);
+ string16 lower_prefix = l10n_util::ToLower(WideToUTF16(prefix));
// This magic gives us a prefix search.
- std::wstring next_prefix = lower_prefix;
+ string16 next_prefix = lower_prefix;
next_prefix[next_prefix.size() - 1] =
next_prefix[next_prefix.size() - 1] + 1;
- statement->bind_int64(0, keyword_id);
- statement->bind_wstring(1, lower_prefix);
- statement->bind_wstring(2, next_prefix);
- statement->bind_int(3, max_count);
+ statement.BindInt64(0, keyword_id);
+ statement.BindString(1, UTF16ToUTF8(lower_prefix));
+ statement.BindString(2, UTF16ToUTF8(next_prefix));
+ statement.BindInt(3, max_count);
KeywordSearchTermVisit visit;
- while (statement->step() == SQLITE_ROW) {
- visit.term = statement->column_wstring(0);
- visit.time = Time::FromInternalValue(statement->column_int64(1));
+ while (statement.Step()) {
+ visit.term = UTF8ToWide(statement.ColumnString(0));
+ visit.time = base::Time::FromInternalValue(statement.ColumnInt64(1));
matches->push_back(visit);
}
}
@@ -417,7 +413,7 @@ bool URLDatabase::MigrateFromVersion11ToVersion12() {
}
bool URLDatabase::DropStarredIDFromURLs() {
- if (!DoesSqliteColumnExist(GetDB(), "urls", "starred_id", NULL))
+ if (!GetDB().DoesColumnExist("urls", "starred_id"))
return true; // urls is already updated, no need to continue.
// Create a temporary table to contain the new URLs table.
@@ -427,13 +423,12 @@ bool URLDatabase::DropStarredIDFromURLs() {
}
// Copy the contents.
- const char* insert_statement =
+ if (!GetDB().Execute(
"INSERT INTO temp_urls (id, url, title, visit_count, typed_count, "
"last_visit_time, hidden, favicon_id) "
"SELECT id, url, title, visit_count, typed_count, last_visit_time, "
- "hidden, favicon_id FROM urls";
- if (sqlite3_exec(GetDB(), insert_statement, NULL, NULL, NULL) != SQLITE_OK) {
- NOTREACHED();
+ "hidden, favicon_id FROM urls")) {
+ NOTREACHED() << GetDB().GetErrorMessage();
return false;
}
@@ -448,7 +443,7 @@ bool URLDatabase::DropStarredIDFromURLs() {
bool URLDatabase::CreateURLTable(bool is_temporary) {
const char* name = is_temporary ? "temp_urls" : "urls";
- if (DoesSqliteTableExist(GetDB(), name))
+ if (GetDB().DoesTableExist(name))
return true;
std::string sql;
@@ -464,21 +459,18 @@ bool URLDatabase::CreateURLTable(bool is_temporary) {
"hidden INTEGER DEFAULT 0 NOT NULL,"
"favicon_id INTEGER DEFAULT 0 NOT NULL)");
- return sqlite3_exec(GetDB(), sql.c_str(), NULL, NULL, NULL) == SQLITE_OK;
+ return GetDB().Execute(sql.c_str());
}
void URLDatabase::CreateMainURLIndex() {
// Index over URLs so we can quickly look up based on URL. Ignore errors as
// this likely already exists (and the same below).
- sqlite3_exec(GetDB(), "CREATE INDEX urls_url_index ON urls (url)", NULL, NULL,
- NULL);
+ GetDB().Execute("CREATE INDEX urls_url_index ON urls (url)");
}
void URLDatabase::CreateSupplimentaryURLIndices() {
// Add a favicon index. This is useful when we delete urls.
- sqlite3_exec(GetDB(),
- "CREATE INDEX urls_favicon_id_INDEX ON urls (favicon_id)",
- NULL, NULL, NULL);
+ GetDB().Execute("CREATE INDEX urls_favicon_id_INDEX ON urls (favicon_id)");
}
} // namespace history
diff --git a/chrome/browser/history/url_database.h b/chrome/browser/history/url_database.h
index e44108f..6e2eca1 100644
--- a/chrome/browser/history/url_database.h
+++ b/chrome/browser/history/url_database.h
@@ -1,78 +1,25 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
-#ifndef CHROME_BROWSER_HISTORY_URL_DATABASE_H__
-#define CHROME_BROWSER_HISTORY_URL_DATABASE_H__
+#ifndef CHROME_BROWSER_HISTORY_URL_DATABASE_H_
+#define CHROME_BROWSER_HISTORY_URL_DATABASE_H_
+#include "app/sql/statement.h"
#include "base/basictypes.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/search_engines/template_url.h"
-#include "chrome/common/sqlite_utils.h"
-
-// Temporary until DBCloseScoper moves elsewhere.
-#include "chrome/common/sqlite_compiled_statement.h"
class GURL;
-struct sqlite3;
-class SqliteStatementCache;
+
+namespace sql {
+class Connection;
+}
namespace history {
class VisitDatabase; // For friend statement.
-// This class is here temporarily.
-// TODO(brettw) Figure out a better place for this or obsolete it.
-//
-// Helper class that closes the DB, deletes the statement cache, and zeros out
-// the pointer when it goes out of scope, does nothing once success is called.
-//
-// Can either be used by the owner of the DB to automatically close it, or
-// during initialization so that it is automatically closed on failure.
-//
-// properly maintained by Init() on failure. If |statement_cache| is non NULL,
-// it is assumed to be bound with |db| and will be cleaned up before the
-// database is closed.
-class DBCloseScoper {
- public:
- DBCloseScoper() : db_(NULL), statement_cache_(NULL) {
- }
-
- // The statement cache must be allocated on the heap. The DB must be
- // allocated by sqlite.
- DBCloseScoper(sqlite3** db, SqliteStatementCache** statement_cache)
- : db_(db),
- statement_cache_(statement_cache) {
- }
-
- ~DBCloseScoper() {
- if (db_) {
- if (*statement_cache_) {
- delete *statement_cache_;
- *statement_cache_ = NULL;
- }
-
- sqlite3_close(*db_);
- *db_ = NULL;
- }
- }
-
- void Attach(sqlite3** db, SqliteStatementCache** statement_cache) {
- DCHECK(db_ == NULL && statement_cache_ == NULL);
- db_ = db;
- statement_cache_ = statement_cache;
- }
-
- void Detach() {
- db_ = NULL;
- statement_cache_ = NULL;
- }
-
- private:
- sqlite3** db_;
- SqliteStatementCache** statement_cache_;
-};
-
// Encapsulates an SQL database that holds URL info. This is a subset of the
// full history data. We split this class' functionality out from the larger
// HistoryDatabase class to support maintaining separate databases of URLs with
@@ -172,7 +119,7 @@ class URLDatabase {
friend class URLDatabase;
bool initialized_;
- SQLStatement statement_;
+ sql::Statement statement_;
};
// Initializes the given enumerator to enumerator all URLs in the database
@@ -277,20 +224,18 @@ class URLDatabase {
// Convenience to fill a history::URLRow. Must be in sync with the fields in
// kHistoryURLRowFields.
- static void FillURLRow(SQLStatement& s, URLRow* i);
+ static void FillURLRow(sql::Statement& s, URLRow* i);
- // Returns the database and statement cache for the functions in this
- // interface. The decendent of this class implements these functions to
- // return its objects.
- virtual sqlite3* GetDB() = 0;
- virtual SqliteStatementCache& GetStatementCache() = 0;
+ // Returns the database for the functions in this interface. The decendent of
+ // this class implements these functions to return its objects.
+ virtual sql::Connection& GetDB() = 0;
private:
// True if InitKeywordSearchTermsTable() has been invoked. Not all subclasses
// have keyword search terms.
bool has_keyword_search_terms_;
- DISALLOW_EVIL_CONSTRUCTORS(URLDatabase);
+ DISALLOW_COPY_AND_ASSIGN(URLDatabase);
};
// The fields and order expected by FillURLRow(). ID is guaranteed to be first
@@ -306,4 +251,4 @@ class URLDatabase {
} // history
-#endif // CHROME_BROWSER_HISTORY_URL_DATABASE_H__
+#endif // CHROME_BROWSER_HISTORY_URL_DATABASE_H_
diff --git a/chrome/browser/history/url_database_unittest.cc b/chrome/browser/history/url_database_unittest.cc
index cb05019..0f0be54 100644
--- a/chrome/browser/history/url_database_unittest.cc
+++ b/chrome/browser/history/url_database_unittest.cc
@@ -1,14 +1,13 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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 "app/sql/connection.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "chrome/browser/history/url_database.h"
-#include "chrome/common/sqlite_compiled_statement.h"
-#include "chrome/common/sqlite_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::Time;
@@ -35,7 +34,7 @@ bool IsURLRowEqual(const URLRow& a,
class URLDatabaseTest : public testing::Test,
public URLDatabase {
public:
- URLDatabaseTest() : db_(NULL), statement_cache_(NULL) {
+ URLDatabaseTest() {
}
private:
@@ -45,8 +44,7 @@ class URLDatabaseTest : public testing::Test,
PathService::Get(base::DIR_TEMP, &temp_dir);
db_file_ = temp_dir.AppendASCII("URLTest.db");
- EXPECT_EQ(SQLITE_OK, OpenSqliteDb(db_file_, &db_));
- statement_cache_ = new SqliteStatementCache(db_);
+ EXPECT_TRUE(db_.Open(db_file_));
// Initialize the tables for this test.
CreateURLTable(false);
@@ -55,22 +53,17 @@ class URLDatabaseTest : public testing::Test,
InitKeywordSearchTermsTable();
}
void TearDown() {
- delete statement_cache_;
- sqlite3_close(db_);
+ db_.Close();
file_util::Delete(db_file_, false);
}
// Provided for URL/VisitDatabase.
- virtual sqlite3* GetDB() {
+ virtual sql::Connection& GetDB() {
return db_;
}
- virtual SqliteStatementCache& GetStatementCache() {
- return *statement_cache_;
- }
FilePath db_file_;
- sqlite3* db_;
- SqliteStatementCache* statement_cache_;
+ sql::Connection db_;
};
// Test add and query for the URL table in the HistoryDatabase
diff --git a/chrome/browser/history/visit_database.cc b/chrome/browser/history/visit_database.cc
index 862d574..2f4b591 100644
--- a/chrome/browser/history/visit_database.cc
+++ b/chrome/browser/history/visit_database.cc
@@ -1,21 +1,21 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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/visit_database.h"
+
#include <algorithm>
#include <limits>
#include <map>
#include <set>
-#include "chrome/browser/history/visit_database.h"
-#include "chrome/browser/history/visit_log.h"
-
+#include "app/sql/connection.h"
+#include "app/sql/statement.h"
#include "chrome/browser/history/url_database.h"
+#include "chrome/browser/history/visit_log.h"
#include "chrome/common/page_transition_types.h"
#include "chrome/common/url_constants.h"
-using base::Time;
-
// Rows, in order, of the visit table.
#define HISTORY_VISIT_ROW_FIELDS \
" id,url,visit_time,from_visit,transition,segment_id,is_indexed "
@@ -29,8 +29,8 @@ VisitDatabase::~VisitDatabase() {
}
bool VisitDatabase::InitVisitTable() {
- if (!DoesSqliteTableExist(GetDB(), "visits")) {
- if (sqlite3_exec(GetDB(), "CREATE TABLE visits("
+ if (!GetDB().DoesTableExist("visits")) {
+ if (!GetDB().Execute("CREATE TABLE visits("
"id INTEGER PRIMARY KEY,"
"url INTEGER NOT NULL," // key of the URL this corresponds to
"visit_time INTEGER NOT NULL,"
@@ -38,64 +38,56 @@ bool VisitDatabase::InitVisitTable() {
"transition INTEGER DEFAULT 0 NOT NULL,"
"segment_id INTEGER,"
// True when we have indexed data for this visit.
- "is_indexed BOOLEAN)",
- NULL, NULL, NULL) != SQLITE_OK)
+ "is_indexed BOOLEAN)"))
return false;
- } else if (!DoesSqliteColumnExist(GetDB(), "visits",
- "is_indexed", "BOOLEAN")) {
+ } else if (!GetDB().DoesColumnExist("visits", "is_indexed")) {
// Old versions don't have the is_indexed column, we can just add that and
// not worry about different database revisions, since old ones will
// continue to work.
//
// TODO(brettw) this should be removed once we think everybody has been
// updated (added early Mar 2008).
- if (sqlite3_exec(GetDB(),
- "ALTER TABLE visits ADD COLUMN is_indexed BOOLEAN",
- NULL, NULL, NULL) != SQLITE_OK)
+ if (!GetDB().Execute("ALTER TABLE visits ADD COLUMN is_indexed BOOLEAN"))
return false;
}
// Index over url so we can quickly find visits for a page. This will just
// fail if it already exists and we'll ignore it.
- sqlite3_exec(GetDB(), "CREATE INDEX visits_url_index ON visits (url)",
- NULL, NULL, NULL);
+ GetDB().Execute("CREATE INDEX visits_url_index ON visits (url)");
// Create an index over from visits so that we can efficiently find
// referrers and redirects. Ignore failures because it likely already exists.
- sqlite3_exec(GetDB(), "CREATE INDEX visits_from_index ON visits (from_visit)",
- NULL, NULL, NULL);
+ GetDB().Execute("CREATE INDEX visits_from_index ON visits (from_visit)");
// Create an index over time so that we can efficiently find the visits in a
// given time range (most history views are time-based). Ignore failures
// because it likely already exists.
- sqlite3_exec(GetDB(), "CREATE INDEX visits_time_index ON visits (visit_time)",
- NULL, NULL, NULL);
+ GetDB().Execute("CREATE INDEX visits_time_index ON visits (visit_time)");
return true;
}
bool VisitDatabase::DropVisitTable() {
// This will also drop the indices over the table.
- return sqlite3_exec(GetDB(), "DROP TABLE visits", NULL, NULL, NULL) ==
- SQLITE_OK;
+ return GetDB().Execute("DROP TABLE visits");
}
// Must be in sync with HISTORY_VISIT_ROW_FIELDS.
// static
-void VisitDatabase::FillVisitRow(SQLStatement& statement, VisitRow* visit) {
- visit->visit_id = statement.column_int64(0);
- visit->url_id = statement.column_int64(1);
- visit->visit_time = Time::FromInternalValue(statement.column_int64(2));
- visit->referring_visit = statement.column_int64(3);
- visit->transition = PageTransition::FromInt(statement.column_int(4));
- visit->segment_id = statement.column_int64(5);
- visit->is_indexed = !!statement.column_int(6);
+void VisitDatabase::FillVisitRow(sql::Statement& statement, VisitRow* visit) {
+ visit->visit_id = statement.ColumnInt64(0);
+ visit->url_id = statement.ColumnInt64(1);
+ visit->visit_time = base::Time::FromInternalValue(statement.ColumnInt64(2));
+ visit->referring_visit = statement.ColumnInt64(3);
+ visit->transition = PageTransition::FromInt(statement.ColumnInt(4));
+ visit->segment_id = statement.ColumnInt64(5);
+ visit->is_indexed = !!statement.ColumnInt(6);
}
// static
-void VisitDatabase::FillVisitVector(SQLStatement& statement,
+void VisitDatabase::FillVisitVector(sql::Statement& statement,
VisitVector* visits) {
- while (statement.step() == SQLITE_ROW) {
+ while (statement.Step()) {
history::VisitRow visit;
FillVisitRow(statement, &visit);
visits->push_back(visit);
@@ -103,62 +95,61 @@ void VisitDatabase::FillVisitVector(SQLStatement& statement,
}
VisitID VisitDatabase::AddVisit(VisitRow* visit) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"INSERT INTO visits "
"(url, visit_time, from_visit, transition, segment_id, is_indexed) "
- "VALUES (?,?,?,?,?,?)");
- if (!statement.is_valid())
+ "VALUES (?,?,?,?,?,?)"));
+ if (!statement)
return 0;
- statement->bind_int64(0, visit->url_id);
- statement->bind_int64(1, visit->visit_time.ToInternalValue());
- statement->bind_int64(2, visit->referring_visit);
- statement->bind_int64(3, visit->transition);
- statement->bind_int64(4, visit->segment_id);
- statement->bind_int64(5, visit->is_indexed);
+ statement.BindInt64(0, visit->url_id);
+ statement.BindInt64(1, visit->visit_time.ToInternalValue());
+ statement.BindInt64(2, visit->referring_visit);
+ statement.BindInt64(3, visit->transition);
+ statement.BindInt64(4, visit->segment_id);
+ statement.BindInt64(5, visit->is_indexed);
AddEventToVisitLog(VisitLog::ADD_VISIT);
- if (statement->step() != SQLITE_DONE)
+ if (!statement.Run())
return 0;
- visit->visit_id = sqlite3_last_insert_rowid(GetDB());
+ visit->visit_id = GetDB().GetLastInsertRowId();
return visit->visit_id;
}
void VisitDatabase::DeleteVisit(const VisitRow& visit) {
// Patch around this visit. Any visits that this went to will now have their
// "source" be the deleted visit's source.
- SQLITE_UNIQUE_STATEMENT(update_chain, GetStatementCache(),
- "UPDATE visits SET from_visit=? "
- "WHERE from_visit=?");
- if (!update_chain.is_valid())
+ sql::Statement update_chain(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "UPDATE visits SET from_visit=? WHERE from_visit=?"));
+ if (!update_chain)
return;
- update_chain->bind_int64(0, visit.referring_visit);
- update_chain->bind_int64(1, visit.visit_id);
+ update_chain.BindInt64(0, visit.referring_visit);
+ update_chain.BindInt64(1, visit.visit_id);
AddEventToVisitLog(VisitLog::UPDATE_VISIT);
- update_chain->step();
+ update_chain.Run();
// Now delete the actual visit.
- SQLITE_UNIQUE_STATEMENT(del, GetStatementCache(),
- "DELETE FROM visits WHERE id=?");
- if (!del.is_valid())
+ sql::Statement del(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "DELETE FROM visits WHERE id=?"));
+ if (!del)
return;
- del->bind_int64(0, visit.visit_id);
+ del.BindInt64(0, visit.visit_id);
AddEventToVisitLog(VisitLog::DELETE_VISIT);
- del->step();
+ del.Run();
}
bool VisitDatabase::GetRowForVisit(VisitID visit_id, VisitRow* out_visit) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits WHERE id=?");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits WHERE id=?"));
+ if (!statement)
return false;
- statement->bind_int64(0, visit_id);
+ statement.BindInt64(0, visit_id);
AddEventToVisitLog(VisitLog::SELECT_VISIT);
- if (statement->step() != SQLITE_ROW)
+ if (!statement.Step())
return false;
- FillVisitRow(*statement, out_visit);
+ FillVisitRow(statement, out_visit);
// We got a different visit than we asked for, something is wrong.
DCHECK_EQ(visit_id, out_visit->visit_id);
@@ -174,128 +165,130 @@ bool VisitDatabase::UpdateVisitRow(const VisitRow& visit) {
if (visit.visit_id == visit.referring_visit)
return false;
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"UPDATE visits SET "
"url=?,visit_time=?,from_visit=?,transition=?,segment_id=?,is_indexed=? "
- "WHERE id=?");
- if (!statement.is_valid())
+ "WHERE id=?"));
+ if (!statement)
return false;
- statement->bind_int64(0, visit.url_id);
- statement->bind_int64(1, visit.visit_time.ToInternalValue());
- statement->bind_int64(2, visit.referring_visit);
- statement->bind_int64(3, visit.transition);
- statement->bind_int64(4, visit.segment_id);
- statement->bind_int64(5, visit.is_indexed);
- statement->bind_int64(6, visit.visit_id);
+ statement.BindInt64(0, visit.url_id);
+ statement.BindInt64(1, visit.visit_time.ToInternalValue());
+ statement.BindInt64(2, visit.referring_visit);
+ statement.BindInt64(3, visit.transition);
+ statement.BindInt64(4, visit.segment_id);
+ statement.BindInt64(5, visit.is_indexed);
+ statement.BindInt64(6, visit.visit_id);
AddEventToVisitLog(VisitLog::UPDATE_VISIT);
- return statement->step() == SQLITE_DONE;
+ return statement.Run();
}
bool VisitDatabase::GetVisitsForURL(URLID url_id, VisitVector* visits) {
visits->clear();
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT" HISTORY_VISIT_ROW_FIELDS
"FROM visits "
"WHERE url=? "
- "ORDER BY visit_time ASC");
- if (!statement.is_valid())
+ "ORDER BY visit_time ASC"));
+ if (!statement)
return false;
- statement->bind_int64(0, url_id);
+ statement.BindInt64(0, url_id);
AddEventToVisitLog(VisitLog::SELECT_VISIT);
- FillVisitVector(*statement, visits);
+ FillVisitVector(statement, visits);
return true;
}
-void VisitDatabase::GetAllVisitsInRange(Time begin_time, Time end_time,
+void VisitDatabase::GetAllVisitsInRange(base::Time begin_time,
+ base::Time end_time,
int max_results,
VisitVector* visits) {
visits->clear();
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits "
"WHERE visit_time >= ? AND visit_time < ?"
- "ORDER BY visit_time LIMIT ?");
- if (!statement.is_valid())
+ "ORDER BY visit_time LIMIT ?"));
+ if (!statement)
return;
// See GetVisibleVisitsInRange for more info on how these times are bound.
int64 end = end_time.ToInternalValue();
- statement->bind_int64(0, begin_time.ToInternalValue());
- statement->bind_int64(1, end ? end : std::numeric_limits<int64>::max());
- statement->bind_int64(2,
+ statement.BindInt64(0, begin_time.ToInternalValue());
+ statement.BindInt64(1, end ? end : std::numeric_limits<int64>::max());
+ statement.BindInt64(2,
max_results ? max_results : std::numeric_limits<int64>::max());
AddEventToVisitLog(VisitLog::SELECT_VISIT);
- FillVisitVector(*statement, visits);
+ FillVisitVector(statement, visits);
}
void VisitDatabase::GetVisitsInRangeForTransition(
- Time begin_time,
- Time end_time,
+ base::Time begin_time,
+ base::Time end_time,
int max_results,
PageTransition::Type transition,
VisitVector* visits) {
DCHECK(visits);
visits->clear();
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits "
"WHERE visit_time >= ? AND visit_time < ? "
"AND (transition & ?) == ?"
- "ORDER BY visit_time LIMIT ?");
- if (!statement.is_valid())
+ "ORDER BY visit_time LIMIT ?"));
+ if (!statement)
return;
// See GetVisibleVisitsInRange for more info on how these times are bound.
int64 end = end_time.ToInternalValue();
- statement->bind_int64(0, begin_time.ToInternalValue());
- statement->bind_int64(1, end ? end : std::numeric_limits<int64>::max());
- statement->bind_int(2, PageTransition::CORE_MASK);
- statement->bind_int(3, transition);
- statement->bind_int64(4,
+ statement.BindInt64(0, begin_time.ToInternalValue());
+ statement.BindInt64(1, end ? end : std::numeric_limits<int64>::max());
+ statement.BindInt(2, PageTransition::CORE_MASK);
+ statement.BindInt(3, transition);
+ statement.BindInt64(4,
max_results ? max_results : std::numeric_limits<int64>::max());
AddEventToVisitLog(VisitLog::SELECT_VISIT);
- FillVisitVector(*statement, visits);
+ FillVisitVector(statement, visits);
}
-void VisitDatabase::GetVisibleVisitsInRange(Time begin_time, Time end_time,
+void VisitDatabase::GetVisibleVisitsInRange(base::Time begin_time,
+ base::Time end_time,
bool most_recent_visit_only,
int max_count,
VisitVector* visits) {
visits->clear();
// The visit_time values can be duplicated in a redirect chain, so we sort
// by id too, to ensure a consistent ordering just in case.
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits "
"WHERE visit_time >= ? AND visit_time < ? "
"AND (transition & ?) != 0 " // CHAIN_END
"AND (transition & ?) NOT IN (?, ?, ?) " // NO SUBFRAME or
// KEYWORD_GENERATED
- "ORDER BY visit_time DESC, id DESC");
- if (!statement.is_valid())
+ "ORDER BY visit_time DESC, id DESC"));
+ if (!statement)
return;
// Note that we use min/max values for querying unlimited ranges of time using
// the same statement. Since the time has an index, this will be about the
// same amount of work as just doing a query for everything with no qualifier.
int64 end = end_time.ToInternalValue();
- statement->bind_int64(0, begin_time.ToInternalValue());
- statement->bind_int64(1, end ? end : std::numeric_limits<int64>::max());
- statement->bind_int(2, PageTransition::CHAIN_END);
- statement->bind_int(3, PageTransition::CORE_MASK);
- statement->bind_int(4, PageTransition::AUTO_SUBFRAME);
- statement->bind_int(5, PageTransition::MANUAL_SUBFRAME);
- statement->bind_int(6, PageTransition::KEYWORD_GENERATED);
+ statement.BindInt64(0, begin_time.ToInternalValue());
+ statement.BindInt64(1, end ? end : std::numeric_limits<int64>::max());
+ statement.BindInt(2, PageTransition::CHAIN_END);
+ statement.BindInt(3, PageTransition::CORE_MASK);
+ statement.BindInt(4, PageTransition::AUTO_SUBFRAME);
+ statement.BindInt(5, PageTransition::MANUAL_SUBFRAME);
+ statement.BindInt(6, PageTransition::KEYWORD_GENERATED);
AddEventToVisitLog(VisitLog::SELECT_VISIT);
std::set<URLID> found_urls;
- while (statement->step() == SQLITE_ROW) {
+ while (statement.Step()) {
VisitRow visit;
- FillVisitRow(*statement, &visit);
+ FillVisitRow(statement, &visit);
if (most_recent_visit_only) {
// Make sure the URL this visit corresponds to is unique if required.
if (found_urls.find(visit.url_id) != found_urls.end())
@@ -313,24 +306,24 @@ VisitID VisitDatabase::GetMostRecentVisitForURL(URLID url_id,
VisitRow* visit_row) {
// The visit_time values can be duplicated in a redirect chain, so we sort
// by id too, to ensure a consistent ordering just in case.
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits "
"WHERE url=? "
"ORDER BY visit_time DESC, id DESC "
- "LIMIT 1");
- if (!statement.is_valid())
+ "LIMIT 1"));
+ if (!statement)
return 0;
- statement->bind_int64(0, url_id);
+ statement.BindInt64(0, url_id);
AddEventToVisitLog(VisitLog::SELECT_VISIT);
- if (statement->step() != SQLITE_ROW)
+ if (!statement.Step())
return 0; // No visits for this URL.
if (visit_row) {
- FillVisitRow(*statement, visit_row);
+ FillVisitRow(statement, visit_row);
return visit_row->visit_id;
}
- return statement->column_int64(0);
+ return statement.ColumnInt64(0);
}
bool VisitDatabase::GetMostRecentVisitsForURL(URLID url_id,
@@ -340,43 +333,43 @@ bool VisitDatabase::GetMostRecentVisitsForURL(URLID url_id,
// The visit_time values can be duplicated in a redirect chain, so we sort
// by id too, to ensure a consistent ordering just in case.
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT" HISTORY_VISIT_ROW_FIELDS
"FROM visits "
"WHERE url=? "
"ORDER BY visit_time DESC, id DESC "
- "LIMIT ?");
- if (!statement.is_valid())
+ "LIMIT ?"));
+ if (!statement)
return false;
- statement->bind_int64(0, url_id);
- statement->bind_int(1, max_results);
+ statement.BindInt64(0, url_id);
+ statement.BindInt(1, max_results);
AddEventToVisitLog(VisitLog::SELECT_VISIT);
- FillVisitVector(*statement, visits);
+ FillVisitVector(statement, visits);
return true;
}
bool VisitDatabase::GetRedirectFromVisit(VisitID from_visit,
VisitID* to_visit,
GURL* to_url) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT v.id,u.url "
"FROM visits v JOIN urls u ON v.url = u.id "
"WHERE v.from_visit = ? "
- "AND (v.transition & ?) != 0"); // IS_REDIRECT_MASK
- if (!statement.is_valid())
+ "AND (v.transition & ?) != 0")); // IS_REDIRECT_MASK
+ if (!statement)
return false;
- statement->bind_int64(0, from_visit);
- statement->bind_int(1, PageTransition::IS_REDIRECT_MASK);
+ statement.BindInt64(0, from_visit);
+ statement.BindInt(1, PageTransition::IS_REDIRECT_MASK);
AddEventToVisitLog(VisitLog::SELECT_VISIT);
- if (statement->step() != SQLITE_ROW)
+ if (!statement.Step())
return false; // No redirect from this visit.
if (to_visit)
- *to_visit = statement->column_int64(0);
+ *to_visit = statement.ColumnInt64(0);
if (to_url)
- *to_url = GURL(statement->column_string(1));
+ *to_url = GURL(statement.ColumnString(1));
return true;
}
@@ -391,24 +384,24 @@ bool VisitDatabase::GetRedirectToVisit(VisitID to_visit,
*from_visit = row.referring_visit;
if (from_url) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT u.url "
"FROM visits v JOIN urls u ON v.url = u.id "
- "WHERE v.id = ?");
- statement->bind_int64(0, row.referring_visit);
+ "WHERE v.id = ?"));
+ statement.BindInt64(0, row.referring_visit);
AddEventToVisitLog(VisitLog::SELECT_VISIT);
- if (statement->step() != SQLITE_ROW)
+ if (!statement.Step())
return false;
- *from_url = GURL(statement->column_string(0));
+ *from_url = GURL(statement.ColumnString(0));
}
return true;
}
bool VisitDatabase::GetVisitCountToHost(const GURL& url,
int* count,
- Time* first_visit) {
+ base::Time* first_visit) {
if (!url.SchemeIs(chrome::kHttpScheme) && !url.SchemeIs(chrome::kHttpsScheme))
return false;
@@ -428,38 +421,37 @@ bool VisitDatabase::GetVisitCountToHost(const GURL& url,
std::string host_query_max = host_query_min;
host_query_max[host_query_max.size() - 1] = '0';
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT MIN(v.visit_time), COUNT(*) "
"FROM visits v INNER JOIN urls u ON v.url = u.id "
- "WHERE (u.url >= ? AND u.url < ?)");
- if (!statement.is_valid())
+ "WHERE (u.url >= ? AND u.url < ?)"));
+ if (!statement)
return false;
- statement->bind_string(0, host_query_min);
- statement->bind_string(1, host_query_max);
+ statement.BindString(0, host_query_min);
+ statement.BindString(1, host_query_max);
AddEventToVisitLog(VisitLog::SELECT_VISIT);
- if (statement->step() != SQLITE_ROW) {
+ if (!statement.Step()) {
// We've never been to this page before.
*count = 0;
return true;
}
- *first_visit = Time::FromInternalValue(statement->column_int64(0));
- *count = statement->column_int(1);
+ *first_visit = base::Time::FromInternalValue(statement.ColumnInt64(0));
+ *count = statement.ColumnInt(1);
return true;
}
-bool VisitDatabase::GetStartDate(Time* first_visit) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "SELECT MIN(visit_time) FROM visits WHERE visit_time != 0");
+bool VisitDatabase::GetStartDate(base::Time* first_visit) {
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "SELECT MIN(visit_time) FROM visits WHERE visit_time != 0"));
AddEventToVisitLog(VisitLog::SELECT_VISIT);
- if (!statement.is_valid() || statement->step() != SQLITE_ROW ||
- statement->column_int64(0) == 0) {
- *first_visit = Time::Now();
+ if (!statement || !statement.Step() || statement.ColumnInt64(0) == 0) {
+ *first_visit = base::Time::Now();
return false;
}
- *first_visit = Time::FromInternalValue(statement->column_int64(0));
+ *first_visit = base::Time::FromInternalValue(statement.ColumnInt64(0));
return true;
}
diff --git a/chrome/browser/history/visit_database.h b/chrome/browser/history/visit_database.h
index 9fa4601..8613ace 100644
--- a/chrome/browser/history/visit_database.h
+++ b/chrome/browser/history/visit_database.h
@@ -1,15 +1,16 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
-#ifndef CHROME_BROWSER_HISTORY_VISIT_DATABASE_H__
-#define CHROME_BROWSER_HISTORY_VISIT_DATABASE_H__
+#ifndef CHROME_BROWSER_HISTORY_VISIT_DATABASE_H_
+#define CHROME_BROWSER_HISTORY_VISIT_DATABASE_H_
#include "chrome/browser/history/history_types.h"
-struct sqlite3;
-class SqliteStatementCache;
-class SQLStatement;
+namespace sql {
+class Connection;
+class Statement;
+}
namespace history {
@@ -144,11 +145,8 @@ class VisitDatabase {
bool GetStartDate(base::Time* first_visit);
protected:
- // Returns the database and statement cache for the functions in this
- // interface. The decendent of this class implements these functions to
- // return its objects.
- virtual sqlite3* GetDB() = 0;
- virtual SqliteStatementCache& GetStatementCache() = 0;
+ // Returns the database for the functions in this interface.
+ virtual sql::Connection& GetDB() = 0;
// Called by the derived classes on initialization to make sure the tables
// and indices are properly set up. Must be called before anything else.
@@ -156,16 +154,16 @@ class VisitDatabase {
// Convenience to fill a VisitRow. Assumes the visit values are bound starting
// at index 0.
- static void FillVisitRow(SQLStatement& statement, VisitRow* visit);
+ static void FillVisitRow(sql::Statement& statement, VisitRow* visit);
// Convenience to fill a VisitVector. Assumes that statement.step()
// hasn't happened yet.
- static void FillVisitVector(SQLStatement& statement, VisitVector* visits);
+ static void FillVisitVector(sql::Statement& statement, VisitVector* visits);
private:
- DISALLOW_EVIL_CONSTRUCTORS(VisitDatabase);
+ DISALLOW_COPY_AND_ASSIGN(VisitDatabase);
};
} // history
-#endif // CHROME_BROWSER_HISTORY_VISIT_DATABASE_H__
+#endif // CHROME_BROWSER_HISTORY_VISIT_DATABASE_H_
diff --git a/chrome/browser/history/visit_database_unittest.cc b/chrome/browser/history/visit_database_unittest.cc
index 65197d1..aedb9e9 100644
--- a/chrome/browser/history/visit_database_unittest.cc
+++ b/chrome/browser/history/visit_database_unittest.cc
@@ -1,15 +1,14 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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 "app/sql/connection.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "chrome/browser/history/url_database.h"
#include "chrome/browser/history/visit_database.h"
-#include "chrome/common/sqlite_compiled_statement.h"
-#include "chrome/common/sqlite_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -36,7 +35,7 @@ class VisitDatabaseTest : public PlatformTest,
public URLDatabase,
public VisitDatabase {
public:
- VisitDatabaseTest() : db_(NULL), statement_cache_(NULL) {
+ VisitDatabaseTest() {
}
private:
@@ -48,8 +47,7 @@ class VisitDatabaseTest : public PlatformTest,
db_file_ = temp_dir.AppendASCII("VisitTest.db");
file_util::Delete(db_file_, false);
- EXPECT_EQ(SQLITE_OK, OpenSqliteDb(db_file_, &db_));
- statement_cache_ = new SqliteStatementCache(db_);
+ EXPECT_TRUE(db_.Open(db_file_));
// Initialize the tables for this test.
CreateURLTable(false);
@@ -58,23 +56,18 @@ class VisitDatabaseTest : public PlatformTest,
InitVisitTable();
}
void TearDown() {
- delete statement_cache_;
- sqlite3_close(db_);
+ db_.Close();
file_util::Delete(db_file_, false);
PlatformTest::TearDown();
}
// Provided for URL/VisitDatabase.
- virtual sqlite3* GetDB() {
+ virtual sql::Connection& GetDB() {
return db_;
}
- virtual SqliteStatementCache& GetStatementCache() {
- return *statement_cache_;
- }
FilePath db_file_;
- sqlite3* db_;
- SqliteStatementCache* statement_cache_;
+ sql::Connection db_;
};
TEST_F(VisitDatabaseTest, Add) {
diff --git a/chrome/browser/history/visitsegment_database.cc b/chrome/browser/history/visitsegment_database.cc
index cf2cd3c..b18712b 100644
--- a/chrome/browser/history/visitsegment_database.cc
+++ b/chrome/browser/history/visitsegment_database.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
@@ -6,14 +6,12 @@
#include <math.h>
+#include "app/sql/connection.h"
+#include "app/sql/statement.h"
#include "base/logging.h"
#include "base/stl_util-inl.h"
#include "base/string_util.h"
#include "chrome/browser/history/page_usage_data.h"
-#include "chrome/common/sqlite_compiled_statement.h"
-#include "chrome/common/sqlite_utils.h"
-
-using base::Time;
// The following tables are used to store url segment information.
//
@@ -40,19 +38,17 @@ VisitSegmentDatabase::~VisitSegmentDatabase() {
bool VisitSegmentDatabase::InitSegmentTables() {
// Segments table.
- if (!DoesSqliteTableExist(GetDB(), "segments")) {
- if (sqlite3_exec(GetDB(), "CREATE TABLE segments ("
- "id INTEGER PRIMARY KEY,"
- "name VARCHAR,"
- "url_id INTEGER NON NULL,"
- "pres_index INTEGER DEFAULT -1 NOT NULL)",
- NULL, NULL, NULL) != SQLITE_OK) {
+ if (!GetDB().DoesTableExist("segments")) {
+ if (!GetDB().Execute("CREATE TABLE segments ("
+ "id INTEGER PRIMARY KEY,"
+ "name VARCHAR,"
+ "url_id INTEGER NON NULL,"
+ "pres_index INTEGER DEFAULT -1 NOT NULL)")) {
NOTREACHED();
return false;
}
- if (sqlite3_exec(GetDB(), "CREATE INDEX segments_name ON segments(name)",
- NULL, NULL, NULL) != SQLITE_OK) {
+ if (!GetDB().Execute("CREATE INDEX segments_name ON segments(name)")) {
NOTREACHED();
return false;
}
@@ -60,33 +56,29 @@ bool VisitSegmentDatabase::InitSegmentTables() {
// This was added later, so we need to try to create it even if the table
// already exists.
- sqlite3_exec(GetDB(), "CREATE INDEX segments_url_id ON segments(url_id)",
- NULL, NULL, NULL);
+ GetDB().Execute("CREATE INDEX segments_url_id ON segments(url_id)");
// Segment usage table.
- if (!DoesSqliteTableExist(GetDB(), "segment_usage")) {
- if (sqlite3_exec(GetDB(), "CREATE TABLE segment_usage ("
- "id INTEGER PRIMARY KEY,"
- "segment_id INTEGER NOT NULL,"
- "time_slot INTEGER NOT NULL,"
- "visit_count INTEGER DEFAULT 0 NOT NULL)",
- NULL, NULL, NULL) != SQLITE_OK) {
+ if (!GetDB().DoesTableExist("segment_usage")) {
+ if (!GetDB().Execute("CREATE TABLE segment_usage ("
+ "id INTEGER PRIMARY KEY,"
+ "segment_id INTEGER NOT NULL,"
+ "time_slot INTEGER NOT NULL,"
+ "visit_count INTEGER DEFAULT 0 NOT NULL)")) {
NOTREACHED();
return false;
}
- if (sqlite3_exec(GetDB(),
- "CREATE INDEX segment_usage_time_slot_segment_id ON "
- "segment_usage(time_slot, segment_id)",
- NULL, NULL, NULL) != SQLITE_OK) {
+ if (!GetDB().Execute(
+ "CREATE INDEX segment_usage_time_slot_segment_id ON "
+ "segment_usage(time_slot, segment_id)")) {
NOTREACHED();
return false;
}
}
// Added in a later version, so we always need to try to creat this index.
- sqlite3_exec(GetDB(), "CREATE INDEX segments_usage_seg_id "
- "ON segment_usage(segment_id)",
- NULL, NULL, NULL);
+ GetDB().Execute("CREATE INDEX segments_usage_seg_id "
+ "ON segment_usage(segment_id)");
// Presentation index table.
//
@@ -95,11 +87,10 @@ bool VisitSegmentDatabase::InitSegmentTables() {
// If you need to add more columns, keep in mind that rows are currently
// deleted when the presentation index is changed to -1.
// See SetPagePresentationIndex() in this file
- if (!DoesSqliteTableExist(GetDB(), "presentation")) {
- if (sqlite3_exec(GetDB(), "CREATE TABLE presentation("
- "url_id INTEGER PRIMARY KEY,"
- "pres_index INTEGER NOT NULL)",
- NULL, NULL, NULL) != SQLITE_OK)
+ if (!GetDB().DoesTableExist("presentation")) {
+ if (!GetDB().Execute("CREATE TABLE presentation("
+ "url_id INTEGER PRIMARY KEY,"
+ "pres_index INTEGER NOT NULL)"))
return false;
}
return true;
@@ -107,11 +98,8 @@ bool VisitSegmentDatabase::InitSegmentTables() {
bool VisitSegmentDatabase::DropSegmentTables() {
// Dropping the tables will implicitly delete the indices.
- return
- sqlite3_exec(GetDB(), "DROP TABLE segments", NULL, NULL, NULL) ==
- SQLITE_OK &&
- sqlite3_exec(GetDB(), "DROP TABLE segment_usage", NULL, NULL, NULL) ==
- SQLITE_OK;
+ return GetDB().Execute("DROP TABLE segments") &&
+ GetDB().Execute("DROP TABLE segment_usage");
}
// Note: the segment name is derived from the URL but is not a URL. It is
@@ -147,94 +135,94 @@ std::string VisitSegmentDatabase::ComputeSegmentName(const GURL& url) {
SegmentID VisitSegmentDatabase::GetSegmentNamed(
const std::string& segment_name) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "SELECT id FROM segments WHERE name = ?");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "SELECT id FROM segments WHERE name = ?"));
+ if (!statement)
return 0;
- statement->bind_string(0, segment_name);
- if (statement->step() == SQLITE_ROW)
- return statement->column_int64(0);
+ statement.BindString(0, segment_name);
+ if (statement.Step())
+ return statement.ColumnInt64(0);
return 0;
}
bool VisitSegmentDatabase::UpdateSegmentRepresentationURL(SegmentID segment_id,
URLID url_id) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "UPDATE segments SET url_id = ? WHERE id = ?");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "UPDATE segments SET url_id = ? WHERE id = ?"));
+ if (!statement)
return false;
- statement->bind_int64(0, url_id);
- statement->bind_int64(1, segment_id);
- return statement->step() == SQLITE_DONE;
+ statement.BindInt64(0, url_id);
+ statement.BindInt64(1, segment_id);
+ return statement.Run();
}
URLID VisitSegmentDatabase::GetSegmentRepresentationURL(SegmentID segment_id) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "SELECT url_id FROM segments WHERE id = ?");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "SELECT url_id FROM segments WHERE id = ?"));
+ if (!statement)
return 0;
- statement->bind_int64(0, segment_id);
- if (statement->step() == SQLITE_ROW)
- return statement->column_int64(0);
+ statement.BindInt64(0, segment_id);
+ if (statement.Step())
+ return statement.ColumnInt64(0);
return 0;
}
SegmentID VisitSegmentDatabase::CreateSegment(URLID url_id,
const std::string& segment_name) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "INSERT INTO segments (name, url_id) VALUES (?,?)");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "INSERT INTO segments (name, url_id) VALUES (?,?)"));
+ if (!statement)
return false;
- statement->bind_string(0, segment_name);
- statement->bind_int64(1, url_id);
- if (statement->step() == SQLITE_DONE)
- return sqlite3_last_insert_rowid(GetDB());
+ statement.BindString(0, segment_name);
+ statement.BindInt64(1, url_id);
+ if (statement.Run())
+ return GetDB().GetLastInsertRowId();
return false;
}
bool VisitSegmentDatabase::IncreaseSegmentVisitCount(SegmentID segment_id,
- const Time& ts,
+ base::Time ts,
int amount) {
- Time t = ts.LocalMidnight();
+ base::Time t = ts.LocalMidnight();
- SQLITE_UNIQUE_STATEMENT(select, GetStatementCache(),
+ sql::Statement select(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT id, visit_count FROM segment_usage "
- "WHERE time_slot = ? AND segment_id = ?");
- if (!select.is_valid())
+ "WHERE time_slot = ? AND segment_id = ?"));
+ if (!select)
return false;
- select->bind_int64(0, t.ToInternalValue());
- select->bind_int64(1, segment_id);
- if (select->step() == SQLITE_ROW) {
- SQLITE_UNIQUE_STATEMENT(update, GetStatementCache(),
- "UPDATE segment_usage SET visit_count = ? WHERE id = ?");
- if (!update.is_valid())
+ select.BindInt64(0, t.ToInternalValue());
+ select.BindInt64(1, segment_id);
+ if (select.Step()) {
+ sql::Statement update(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "UPDATE segment_usage SET visit_count = ? WHERE id = ?"));
+ if (!update)
return false;
- update->bind_int64(0, select->column_int64(1) + static_cast<int64>(amount));
- update->bind_int64(1, select->column_int64(0));
- return update->step() == SQLITE_DONE;
+ update.BindInt64(0, select.ColumnInt64(1) + static_cast<int64>(amount));
+ update.BindInt64(1, select.ColumnInt64(0));
+ return update.Run();
} else {
- SQLITE_UNIQUE_STATEMENT(insert, GetStatementCache(),
+ sql::Statement insert(GetDB().GetCachedStatement(SQL_FROM_HERE,
"INSERT INTO segment_usage "
- "(segment_id, time_slot, visit_count) VALUES (?, ?, ?)");
- if (!insert.is_valid())
+ "(segment_id, time_slot, visit_count) VALUES (?, ?, ?)"));
+ if (!insert)
return false;
- insert->bind_int64(0, segment_id);
- insert->bind_int64(1, t.ToInternalValue());
- insert->bind_int64(2, static_cast<int64>(amount));
- return insert->step() == SQLITE_DONE;
+ insert.BindInt64(0, segment_id);
+ insert.BindInt64(1, t.ToInternalValue());
+ insert.BindInt64(2, static_cast<int64>(amount));
+ return insert.Run();
}
}
void VisitSegmentDatabase::QuerySegmentUsage(
- const Time& from_time,
+ base::Time from_time,
int max_result_count,
std::vector<PageUsageData*>* results) {
// This function gathers the highest-ranked segments in two queries.
@@ -245,25 +233,25 @@ void VisitSegmentDatabase::QuerySegmentUsage(
// used to lock results into position. But the rest of our code currently
// does as well.
- // Gather all the segment scores:
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
+ // Gather all the segment scores.
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT segment_id, time_slot, visit_count "
"FROM segment_usage WHERE time_slot >= ? "
- "ORDER BY segment_id");
- if (!statement.is_valid()) {
- NOTREACHED();
+ "ORDER BY segment_id"));
+ if (!statement) {
+ NOTREACHED() << GetDB().GetErrorMessage();
return;
}
- Time ts = from_time.LocalMidnight();
- statement->bind_int64(0, ts.ToInternalValue());
+ base::Time ts = from_time.LocalMidnight();
+ statement.BindInt64(0, ts.ToInternalValue());
- const Time now = Time::Now();
+ base::Time now = base::Time::Now();
SegmentID last_segment_id = 0;
PageUsageData* pud = NULL;
float score = 0;
- while (statement->step() == SQLITE_ROW) {
- SegmentID segment_id = statement->column_int64(0);
+ while (statement.Step()) {
+ SegmentID segment_id = statement.ColumnInt64(0);
if (segment_id != last_segment_id) {
if (last_segment_id != 0) {
pud->SetScore(score);
@@ -275,8 +263,9 @@ void VisitSegmentDatabase::QuerySegmentUsage(
last_segment_id = segment_id;
}
- const Time timeslot = Time::FromInternalValue(statement->column_int64(1));
- const int visit_count = statement->column_int(2);
+ base::Time timeslot =
+ base::Time::FromInternalValue(statement.ColumnInt64(1));
+ int visit_count = statement.ColumnInt(2);
int days_ago = (now - timeslot).InDays();
// Score for this day in isolation.
@@ -304,89 +293,87 @@ void VisitSegmentDatabase::QuerySegmentUsage(
}
// Now fetch the details about the entries we care about.
- SQLITE_UNIQUE_STATEMENT(statement2, GetStatementCache(),
+ sql::Statement statement2(GetDB().GetCachedStatement(SQL_FROM_HERE,
"SELECT urls.url, urls.title FROM urls "
"JOIN segments ON segments.url_id = urls.id "
- "WHERE segments.id = ?");
- if (!statement2.is_valid()) {
- NOTREACHED();
+ "WHERE segments.id = ?"));
+ if (!statement2) {
+ NOTREACHED() << GetDB().GetErrorMessage();
return;
}
for (size_t i = 0; i < results->size(); ++i) {
PageUsageData* pud = (*results)[i];
- statement2->bind_int64(0, pud->GetID());
- if (statement2->step() == SQLITE_ROW) {
- std::string url;
- std::wstring title;
- statement2->column_string(0, &url);
- statement2->column_wstring(1, &title);
- pud->SetURL(GURL(url));
- pud->SetTitle(WideToUTF16(title));
+ statement2.BindInt64(0, pud->GetID());
+ if (statement2.Step()) {
+ pud->SetURL(GURL(statement2.ColumnString(0)));
+ pud->SetTitle(UTF8ToUTF16(statement2.ColumnString(1)));
}
- statement2->reset();
+ statement2.Reset();
}
}
-void VisitSegmentDatabase::DeleteSegmentData(const Time& older_than) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "DELETE FROM segment_usage WHERE time_slot < ?");
- if (!statement.is_valid())
+void VisitSegmentDatabase::DeleteSegmentData(base::Time older_than) {
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "DELETE FROM segment_usage WHERE time_slot < ?"));
+ if (!statement)
return;
- statement->bind_int64(0, older_than.LocalMidnight().ToInternalValue());
- if (statement->step() != SQLITE_DONE)
+ statement.BindInt64(0, older_than.LocalMidnight().ToInternalValue());
+ if (!statement.Run())
NOTREACHED();
}
void VisitSegmentDatabase::SetSegmentPresentationIndex(SegmentID segment_id,
int index) {
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "UPDATE segments SET pres_index = ? WHERE id = ?");
- if (!statement.is_valid())
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "UPDATE segments SET pres_index = ? WHERE id = ?"));
+ if (!statement)
return;
- statement->bind_int(0, index);
- statement->bind_int64(1, segment_id);
- if (statement->step() != SQLITE_DONE)
+ statement.BindInt(0, index);
+ statement.BindInt64(1, segment_id);
+ if (!statement.Run())
NOTREACHED();
+ else
+ DCHECK(GetDB().GetLastChangeCount() == 1);
}
bool VisitSegmentDatabase::DeleteSegmentForURL(URLID url_id) {
- SQLITE_UNIQUE_STATEMENT(select, GetStatementCache(),
- "SELECT id FROM segments WHERE url_id = ?");
- if (!select.is_valid())
+ sql::Statement select(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "SELECT id FROM segments WHERE url_id = ?"));
+ if (!select)
return false;
- SQLITE_UNIQUE_STATEMENT(delete_seg, GetStatementCache(),
- "DELETE FROM segments WHERE id = ?");
- if (!delete_seg.is_valid())
+ sql::Statement delete_seg(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "DELETE FROM segments WHERE id = ?"));
+ if (!delete_seg)
return false;
- SQLITE_UNIQUE_STATEMENT(delete_usage, GetStatementCache(),
- "DELETE FROM segment_usage WHERE segment_id = ?");
- if (!delete_usage.is_valid())
+ sql::Statement delete_usage(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "DELETE FROM segment_usage WHERE segment_id = ?"));
+ if (!delete_usage)
return false;
bool r = true;
- select->bind_int64(0, url_id);
+ select.BindInt64(0, url_id);
// In theory there could not be more than one segment using that URL but we
// loop anyway to cleanup any inconsistency.
- while (select->step() == SQLITE_ROW) {
- SegmentID segment_id = select->column_int64(0);
+ while (select.Step()) {
+ SegmentID segment_id = select.ColumnInt64(0);
- delete_usage->bind_int64(0, segment_id);
- if (delete_usage->step() != SQLITE_DONE) {
+ delete_usage.BindInt64(0, segment_id);
+ if (!delete_usage.Run()) {
NOTREACHED();
r = false;
}
- delete_seg->bind_int64(0, segment_id);
- if (delete_seg->step() != SQLITE_DONE) {
+ delete_seg.BindInt64(0, segment_id);
+ if (!delete_seg.Run()) {
NOTREACHED();
r = false;
}
- delete_usage->reset();
- delete_seg->reset();
+ delete_usage.Reset();
+ delete_seg.Reset();
}
return r;
}
diff --git a/chrome/browser/history/visitsegment_database.h b/chrome/browser/history/visitsegment_database.h
index 0eb0a36f..16f0417 100644
--- a/chrome/browser/history/visitsegment_database.h
+++ b/chrome/browser/history/visitsegment_database.h
@@ -1,16 +1,18 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
-#ifndef CHROME_BROWSER_HISTORY_VISITSEGMENT_DATABASE_H__
-#define CHROME_BROWSER_HISTORY_VISITSEGMENT_DATABASE_H__
+#ifndef CHROME_BROWSER_HISTORY_VISITSEGMENT_DATABASE_H_
+#define CHROME_BROWSER_HISTORY_VISITSEGMENT_DATABASE_H_
#include "base/basictypes.h"
#include "chrome/browser/history/history_types.h"
class PageUsageData;
-struct sqlite3;
-class SqliteStatementCache;
+
+namespace sql {
+class Connection;
+}
namespace history {
@@ -45,19 +47,19 @@ class VisitSegmentDatabase {
// Increase the segment visit count by the provided amount. Return true on
// success.
- bool IncreaseSegmentVisitCount(SegmentID segment_id, const base::Time& ts,
+ bool IncreaseSegmentVisitCount(SegmentID segment_id, base::Time ts,
int amount);
// Compute the segment usage since |from_time| using the provided aggregator.
// A PageUsageData is added in |result| for the highest-scored segments up to
// |max_result_count|.
- void QuerySegmentUsage(const base::Time& from_time,
+ void QuerySegmentUsage(base::Time from_time,
int max_result_count,
std::vector<PageUsageData*>* result);
// Delete all the segment usage data which is older than the provided time
// stamp.
- void DeleteSegmentData(const base::Time& older_than);
+ void DeleteSegmentData(base::Time older_than);
// Change the presentation id for the segment identified by |segment_id|
void SetSegmentPresentationIndex(SegmentID segment_id, int index);
@@ -67,11 +69,8 @@ class VisitSegmentDatabase {
bool DeleteSegmentForURL(URLID url_id);
protected:
- // Returns the database and statement cache for the functions in this
- // interface. The decendent of this class implements these functions to
- // return its objects.
- virtual sqlite3* GetDB() = 0;
- virtual SqliteStatementCache& GetStatementCache() = 0;
+ // Returns the database for the functions in this interface.
+ virtual sql::Connection& GetDB() = 0;
// Creates the tables used by this class if necessary. Returns true on
// success.
@@ -81,9 +80,9 @@ class VisitSegmentDatabase {
bool DropSegmentTables();
private:
- DISALLOW_EVIL_CONSTRUCTORS(VisitSegmentDatabase);
+ DISALLOW_COPY_AND_ASSIGN(VisitSegmentDatabase);
};
} // namespace history
-#endif // CHROME_BROWSER_HISTORY_VISITSEGMENT_DATABASE_H__
+#endif // CHROME_BROWSER_HISTORY_VISITSEGMENT_DATABASE_H_
diff --git a/chrome/browser/net/sqlite_persistent_cookie_store.cc b/chrome/browser/net/sqlite_persistent_cookie_store.cc
index d8ec074..700caac 100644
--- a/chrome/browser/net/sqlite_persistent_cookie_store.cc
+++ b/chrome/browser/net/sqlite_persistent_cookie_store.cc
@@ -330,7 +330,7 @@ bool InitTable(sql::Connection* db) {
bool SQLitePersistentCookieStore::Load(
std::vector<net::CookieMonster::KeyedCanonicalCookie>* cookies) {
scoped_ptr<sql::Connection> db(new sql::Connection);
- if (!db->Init(path_)) {
+ if (!db->Open(path_)) {
NOTREACHED() << "Unable to open cookie DB.";
return false;
}
diff --git a/chrome/browser/search_engines/edit_search_engine_controller.cc b/chrome/browser/search_engines/edit_search_engine_controller.cc
index 110af38..22140c8 100644
--- a/chrome/browser/search_engines/edit_search_engine_controller.cc
+++ b/chrome/browser/search_engines/edit_search_engine_controller.cc
@@ -4,11 +4,13 @@
#include "chrome/browser/search_engines/edit_search_engine_controller.h"
+#include "base/string_util.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_model.h"
+#include "googleurl/src/gurl.h"
EditSearchEngineController::EditSearchEngineController(
const TemplateURL* template_url,
diff --git a/chrome/browser/thumbnail_store.cc b/chrome/browser/thumbnail_store.cc
index 1e06bde..19cd9f3 100644
--- a/chrome/browser/thumbnail_store.cc
+++ b/chrome/browser/thumbnail_store.cc
@@ -7,6 +7,8 @@
#include <string.h>
#include <algorithm>
+#include "app/sql/statement.h"
+#include "app/sql/transaction.h"
#include "base/basictypes.h"
#include "base/file_util.h"
#include "base/gfx/jpeg_codec.h"
@@ -17,15 +19,12 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_service.h"
-#include "chrome/common/sqlite_utils.h"
#include "googleurl/src/gurl.h"
#include "third_party/skia/include/core/SkBitmap.h"
ThumbnailStore::ThumbnailStore()
: cache_(NULL),
- db_(NULL),
- statement_cache_(NULL),
hs_(NULL),
url_blacklist_(NULL),
disk_data_loaded_(false) {
@@ -294,24 +293,27 @@ void ThumbnailStore::CleanCacheData() {
void ThumbnailStore::CommitCacheToDB(
scoped_refptr<RefCountedVector<GURL> > urls_to_delete,
- Cache* data) const {
+ Cache* data) {
scoped_ptr<Cache> data_to_save(data);
- if (!db_)
+ if (!db_.is_open())
return;
base::TimeTicks db_start = base::TimeTicks::Now();
- int rv = sqlite3_exec(db_, "BEGIN TRANSACTION", NULL, NULL, NULL);
- DCHECK(rv == SQLITE_OK) << "Failed to begin transaction";
+ sql::Transaction transaction(&db_);
+ if (!transaction.Begin())
+ return;
// Delete old thumbnails.
if (urls_to_delete.get()) {
for (std::vector<GURL>::iterator it = urls_to_delete->data.begin();
it != urls_to_delete->data.end(); ++it) {
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "DELETE FROM thumbnails WHERE url=?");
- statement->bind_string(0, it->spec());
- if (statement->step() != SQLITE_DONE)
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
+ "DELETE FROM thumbnails WHERE url=?"));
+ if (!statement)
+ return;
+ statement.BindString(0, it->spec());
+ if (!statement.Run())
NOTREACHED();
}
}
@@ -320,26 +322,25 @@ void ThumbnailStore::CommitCacheToDB(
if (data_to_save.get()) {
for (Cache::iterator it = data_to_save->begin();
it != data_to_save->end(); ++it) {
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
"INSERT OR REPLACE INTO thumbnails "
"(url, boring_score, good_clipping, "
"at_top, time_taken, data) "
- "VALUES (?,?,?,?,?,?)");
- statement->bind_string(0, it->first.spec());
- statement->bind_double(1, it->second.score_.boring_score);
- statement->bind_bool(2, it->second.score_.good_clipping);
- statement->bind_bool(3, it->second.score_.at_top);
- statement->bind_int64(4, it->second.score_.time_at_snapshot.
- ToInternalValue());
- statement->bind_blob(5, &it->second.data_->data[0],
- static_cast<int>(it->second.data_->data.size()));
- if (statement->step() != SQLITE_DONE)
+ "VALUES (?,?,?,?,?,?)"));
+ statement.BindString(0, it->first.spec());
+ statement.BindDouble(1, it->second.score_.boring_score);
+ statement.BindBool(2, it->second.score_.good_clipping);
+ statement.BindBool(3, it->second.score_.at_top);
+ statement.BindInt64(4,
+ it->second.score_.time_at_snapshot.ToInternalValue());
+ statement.BindBlob(5, &it->second.data_->data[0],
+ static_cast<int>(it->second.data_->data.size()));
+ if (!statement.Run())
DLOG(WARNING) << "Unable to insert thumbnail for URL";
}
}
- rv = sqlite3_exec(db_, "COMMIT", NULL, NULL, NULL);
- DCHECK(rv == SQLITE_OK) << "Failed to commit transaction";
+ transaction.Commit();
base::TimeDelta delta = base::TimeTicks::Now() - db_start;
HISTOGRAM_TIMES("ThumbnailStore.WriteDBToDisk", delta);
@@ -347,39 +348,23 @@ void ThumbnailStore::CommitCacheToDB(
void ThumbnailStore::InitializeFromDB(const FilePath& db_name,
MessageLoop* cb_loop) {
- if (OpenSqliteDb(db_name, &db_) != SQLITE_OK)
+ db_.set_page_size(4096);
+ db_.set_cache_size(64);
+ db_.set_exclusive_locking();
+ if (!db_.Open(db_name))
return;
- // Use a large page size since the thumbnails we are storing are typically
- // large, a small cache size since we cache in memory and don't go to disk
- // often, and take exclusive access since nobody else uses this db.
- sqlite3_exec(db_, "PRAGMA page_size=4096 "
- "PRAGMA cache_size=64 "
- "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, NULL);
-
- statement_cache_ = new SqliteStatementCache;
-
- // Use local DBCloseScoper so that if we cannot create the table and
- // need to return, the |db_| and |statement_cache_| are closed properly.
- history::DBCloseScoper scoper(&db_, &statement_cache_);
-
- if (!DoesSqliteTableExist(db_, "thumbnails")) {
- if (sqlite3_exec(db_, "CREATE TABLE thumbnails ("
+ if (!db_.DoesTableExist("thumbnails")) {
+ if (!db_.Execute("CREATE TABLE thumbnails ("
"url LONGVARCHAR PRIMARY KEY,"
"boring_score DOUBLE DEFAULT 1.0,"
"good_clipping INTEGER DEFAULT 0,"
"at_top INTEGER DEFAULT 0,"
"time_taken INTEGER DEFAULT 0,"
- "data BLOB)", NULL, NULL, NULL) != SQLITE_OK)
+ "data BLOB)"))
return;
}
- statement_cache_->set_db(db_);
-
- // Now we can use a DBCloseScoper at the object scope.
- scoper.Detach();
- close_scoper_.Attach(&db_, &statement_cache_);
-
if (cb_loop)
GetAllThumbnailsFromDisk(cb_loop);
}
@@ -387,24 +372,26 @@ void ThumbnailStore::InitializeFromDB(const FilePath& db_name,
void ThumbnailStore::GetAllThumbnailsFromDisk(MessageLoop* cb_loop) {
Cache* cache = new Cache;
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "SELECT * FROM thumbnails");
+ sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
+ "SELECT * FROM thumbnails"));
+ if (!statement)
+ return;
- while (statement->step() == SQLITE_ROW) {
+ while (statement.Step()) {
// The URL
- GURL url(statement->column_string(0));
+ GURL url(statement.ColumnString(0));
// The score.
- ThumbnailScore score(statement->column_double(1), // Boring score
- statement->column_bool(2), // Good clipping
- statement->column_bool(3), // At top
+ ThumbnailScore score(statement.ColumnDouble(1), // Boring score
+ statement.ColumnBool(2), // Good clipping
+ statement.ColumnBool(3), // At top
base::Time::FromInternalValue(
- statement->column_int64(4))); // Time taken
+ statement.ColumnInt64(4))); // Time taken
// The image.
scoped_refptr<RefCountedBytes> data = new RefCountedBytes;
- if (statement->column_blob_as_vector(5, &data->data))
- (*cache)[url] = CacheEntry(data, score, false);
+ statement.ColumnBlobAsVector(5, &data->data);
+ (*cache)[url] = CacheEntry(data, score, false);
}
cb_loop->PostTask(FROM_HERE,
diff --git a/chrome/browser/thumbnail_store.h b/chrome/browser/thumbnail_store.h
index 143cbce..d54c5d4 100644
--- a/chrome/browser/thumbnail_store.h
+++ b/chrome/browser/thumbnail_store.h
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "app/sql/connection.h"
#include "base/file_path.h"
#include "base/message_loop.h"
#include "base/ref_counted.h"
@@ -19,7 +20,6 @@
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/ref_counted_util.h"
-#include "chrome/common/sqlite_compiled_statement.h"
#include "chrome/common/thumbnail_score.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
@@ -154,7 +154,7 @@ class ThumbnailStore : public base::RefCountedThreadSafe<ThumbnailStore>,
// cache entries to the DB.
void CommitCacheToDB(
scoped_refptr<RefCountedVector<GURL> > urls_to_delete,
- Cache* data) const;
+ Cache* data);
// Decide whether to store data ---------------------------------------------
@@ -175,9 +175,7 @@ class ThumbnailStore : public base::RefCountedThreadSafe<ThumbnailStore>,
scoped_ptr<Cache> cache_;
// The database holding the thumbnails on disk.
- sqlite3* db_;
- SqliteStatementCache* statement_cache_;
- history::DBCloseScoper close_scoper_;
+ sql::Connection db_;
// We hold a reference to the history service to query for most visited URLs
// and redirect information.
diff --git a/chrome/browser/thumbnail_store_unittest.cc b/chrome/browser/thumbnail_store_unittest.cc
index cd8f146..cd249f3 100644
--- a/chrome/browser/thumbnail_store_unittest.cc
+++ b/chrome/browser/thumbnail_store_unittest.cc
@@ -9,6 +9,8 @@
#include "chrome/browser/thumbnail_store.h"
+#include "app/sql/connection.h"
+#include "app/sql/statement.h"
#include "base/time.h"
#include "base/file_path.h"
#include "base/file_util.h"
@@ -18,8 +20,6 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/ref_counted_util.h"
#include "chrome/common/thumbnail_score.h"
-#include "chrome/common/sqlite_compiled_statement.h"
-#include "chrome/common/sqlite_utils.h"
#include "chrome/tools/profiles/thumbnail-inl.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -186,17 +186,17 @@ TEST_F(ThumbnailStoreTest, RetrieveFromDisk) {
store_->cache_->clear(); // Clear it from the cache.
// Read from the DB.
- SQLITE_UNIQUE_STATEMENT(statement, *store_->statement_cache_,
- "SELECT * FROM thumbnails");
- EXPECT_TRUE(statement->step() == SQLITE_ROW);
- GURL url(statement->column_string(0));
- ThumbnailScore score(statement->column_double(1),
- statement->column_bool(2),
- statement->column_bool(3),
+ sql::Statement statement(store_->db_.GetUniqueStatement(
+ "SELECT * FROM thumbnails"));
+ EXPECT_TRUE(statement.Step());
+ GURL url(statement.ColumnString(0));
+ ThumbnailScore score(statement.ColumnDouble(1),
+ statement.ColumnBool(2),
+ statement.ColumnBool(3),
base::Time::FromInternalValue(
- statement->column_int64(4)));
+ statement.ColumnInt64(4)));
scoped_refptr<RefCountedBytes> data = new RefCountedBytes;
- EXPECT_TRUE(statement->column_blob_as_vector(5, &data->data));
+ statement.ColumnBlobAsVector(5, &data->data);
EXPECT_TRUE(url == url_);
EXPECT_TRUE(score.Equals(score_));
diff --git a/chrome/browser/webdata/web_database.cc b/chrome/browser/webdata/web_database.cc
index a704173..a4db1c9 100644
--- a/chrome/browser/webdata/web_database.cc
+++ b/chrome/browser/webdata/web_database.cc
@@ -147,7 +147,7 @@ bool WebDatabase::Init(const FilePath& db_name) {
// database while we're running, and this will give somewhat improved perf.
db_.set_exclusive_locking();
- if (!db_.Init(db_name))
+ if (!db_.Open(db_name))
return false;
// Initialize various tables
diff --git a/chrome/browser/webdata/web_database.h b/chrome/browser/webdata/web_database.h
index b966938..acc8fbf 100644
--- a/chrome/browser/webdata/web_database.h
+++ b/chrome/browser/webdata/web_database.h
@@ -11,9 +11,7 @@
#include "app/sql/connection.h"
#include "app/sql/meta_table.h"
#include "base/basictypes.h"
-#include "chrome/browser/meta_table_helper.h"
#include "chrome/browser/search_engines/template_url.h"
-#include "chrome/common/sqlite_utils.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
#include "webkit/glue/autofill_form.h"