diff options
Diffstat (limited to 'chrome/browser')
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" |