summaryrefslogtreecommitdiffstats
path: root/chrome/browser/history/thumbnail_database.cc
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-02 05:01:42 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-02 05:01:42 +0000
commit765b445022c7f2a24bc862b45d48ece4ca9a77e1 (patch)
tree9f351b1203bbfd02fae7018a1f11e2f15b6eeacb /chrome/browser/history/thumbnail_database.cc
parenteb6f2c542d7405788d668a762282b66655836e1d (diff)
downloadchromium_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.cc296
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).