diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-02 05:01:42 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-02 05:01:42 +0000 |
commit | 765b445022c7f2a24bc862b45d48ece4ca9a77e1 (patch) | |
tree | 9f351b1203bbfd02fae7018a1f11e2f15b6eeacb /chrome/browser/history/thumbnail_database.cc | |
parent | eb6f2c542d7405788d668a762282b66655836e1d (diff) | |
download | chromium_src-765b445022c7f2a24bc862b45d48ece4ca9a77e1.zip chromium_src-765b445022c7f2a24bc862b45d48ece4ca9a77e1.tar.gz chromium_src-765b445022c7f2a24bc862b45d48ece4ca9a77e1.tar.bz2 |
Convert history to use new sql wrappers. Enhance wrappers in several ways to
support the needs of history.
BUG=none
TEST=covered by unit tests
Review URL: http://codereview.chromium.org/246053
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27832 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/history/thumbnail_database.cc')
-rw-r--r-- | chrome/browser/history/thumbnail_database.cc | 296 |
1 files changed, 132 insertions, 164 deletions
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). |