diff options
author | nshkrob@chromium.org <nshkrob@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-30 21:46:09 +0000 |
---|---|---|
committer | nshkrob@chromium.org <nshkrob@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-30 21:46:09 +0000 |
commit | f33b82f2e0be4b3c739f3e51f34b680080e0150e (patch) | |
tree | 8cb4ad562fdef2e2b95809b06be9af697b61d410 /chrome/browser | |
parent | 6472ca20fbcf08b42dfb8cc20a5066910f038404 (diff) | |
download | chromium_src-f33b82f2e0be4b3c739f3e51f34b680080e0150e.zip chromium_src-f33b82f2e0be4b3c739f3e51f34b680080e0150e.tar.gz chromium_src-f33b82f2e0be4b3c739f3e51f34b680080e0150e.tar.bz2 |
Rename the Thumbnails database file to Favicons.
The database will no longer store the thumbnails - TopSites is storing it's own thumbnails.
BUG=None
TEST=ThumbnailDatabaseTest
Review URL: http://codereview.chromium.org/2842034
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@51294 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/history/history.cc | 3 | ||||
-rw-r--r-- | chrome/browser/history/history_backend.cc | 15 | ||||
-rw-r--r-- | chrome/browser/history/history_backend.h | 7 | ||||
-rw-r--r-- | chrome/browser/history/history_backend_unittest.cc | 2 | ||||
-rw-r--r-- | chrome/browser/history/thumbnail_database.cc | 147 | ||||
-rw-r--r-- | chrome/browser/history/thumbnail_database.h | 24 | ||||
-rw-r--r-- | chrome/browser/history/thumbnail_database_unittest.cc | 52 |
7 files changed, 188 insertions, 62 deletions
diff --git a/chrome/browser/history/history.cc b/chrome/browser/history/history.cc index 61d0ae0..b7586f9 100644 --- a/chrome/browser/history/history.cc +++ b/chrome/browser/history/history.cc @@ -756,5 +756,6 @@ void HistoryService::StartTopSitesMigration() { } void HistoryService::OnTopSitesReady() { - ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::DeleteThumbnailsDatabase); + ScheduleAndForget(PRIORITY_NORMAL, + &HistoryBackend::MigrateThumbnailsDatabase); } diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc index 742f458..3eb7c76 100644 --- a/chrome/browser/history/history_backend.cc +++ b/chrome/browser/history/history_backend.cc @@ -273,6 +273,10 @@ FilePath HistoryBackend::GetThumbnailFileName() const { return history_dir_.Append(chrome::kThumbnailsFilename); } +FilePath HistoryBackend::GetFaviconsFileName() const { + return history_dir_.Append(chrome::kFaviconsFilename); +} + FilePath HistoryBackend::GetArchivedFileName() const { return history_dir_.Append(chrome::kArchivedHistoryFilename); } @@ -578,6 +582,12 @@ void HistoryBackend::InitImpl() { // Thumbnail database. thumbnail_db_.reset(new ThumbnailDatabase()); + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kTopSites)) { + if (!file_util::PathExists(thumbnail_name)) { + // No convertion needed - use new filename right away. + thumbnail_name = GetFaviconsFileName(); + } + } if (thumbnail_db_->Init(thumbnail_name, history_publisher_.get()) != sql::INIT_OK) { // Unlike the main database, we don't error out when the database is too @@ -2146,8 +2156,9 @@ BookmarkService* HistoryBackend::GetBookmarkService() { return bookmark_service_; } -void HistoryBackend::DeleteThumbnailsDatabase() { - thumbnail_db_->DropThumbnailsTable(); +void HistoryBackend::MigrateThumbnailsDatabase() { + thumbnail_db_->RenameAndDropThumbnails(GetThumbnailFileName(), + GetFaviconsFileName()); } } // namespace history diff --git a/chrome/browser/history/history_backend.h b/chrome/browser/history/history_backend.h index 16119cc..cbda2e9 100644 --- a/chrome/browser/history/history_backend.h +++ b/chrome/browser/history/history_backend.h @@ -194,7 +194,7 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>, const GURL& page_url, scoped_refptr<RefCountedBytes>* data); - void DeleteThumbnailsDatabase(); + void MigrateThumbnailsDatabase(); // Favicon ------------------------------------------------------------------- @@ -317,6 +317,11 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>, // Computes the name of the specified database on disk. FilePath GetThumbnailFileName() const; + + // Returns the name of the Favicons database. This is the new name + // of the Thumbnails database. + // See ThumbnailDatabase::RenameAndDropThumbnails. + FilePath GetFaviconsFileName() const; FilePath GetArchivedFileName() const; class URLQuerier; diff --git a/chrome/browser/history/history_backend_unittest.cc b/chrome/browser/history/history_backend_unittest.cc index 9af5662..24cc1cd 100644 --- a/chrome/browser/history/history_backend_unittest.cc +++ b/chrome/browser/history/history_backend_unittest.cc @@ -168,7 +168,7 @@ void HistoryBackendTestDelegate::DBLoaded() { } void HistoryBackendTestDelegate::StartTopSitesMigration() { - test_->backend_->DeleteThumbnailsDatabase(); + test_->backend_->MigrateThumbnailsDatabase(); } TEST_F(HistoryBackendTest, Loaded) { diff --git a/chrome/browser/history/thumbnail_database.cc b/chrome/browser/history/thumbnail_database.cc index a6c75e3..02781a9 100644 --- a/chrome/browser/history/thumbnail_database.cc +++ b/chrome/browser/history/thumbnail_database.cc @@ -14,6 +14,7 @@ #include "base/ref_counted_memory.h" #include "base/time.h" #include "base/string_util.h" +#include "base/utf_string_conversions.h" #include "chrome/browser/diagnostics/sqlite_diagnostics.h" #include "chrome/browser/history/history_publisher.h" #include "chrome/browser/history/url_database.h" @@ -39,32 +40,9 @@ sql::InitStatus ThumbnailDatabase::Init( const FilePath& db_name, const HistoryPublisher* history_publisher) { history_publisher_ = history_publisher; - - // Set the exceptional sqlite error handler. - db_.set_error_delegate(GetErrorHandlerForThumbnailDb()); - - // 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. - 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 - // and so caching won't save a significant percentage of it for us, - // 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. - 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. - db_.set_exclusive_locking(); - - if (!db_.Open(db_name)) - return sql::INIT_FAILURE; + sql::InitStatus status = OpenDatabase(&db_, db_name); + if (status != sql::INIT_OK) + return status; // Scope initialization in a transaction so we can't be partially initialized. sql::Transaction transaction(&db_); @@ -83,7 +61,7 @@ sql::InitStatus ThumbnailDatabase::Init( if (!meta_table_.Init(&db_, kCurrentVersionNumber, kCompatibleVersionNumber) || !InitThumbnailTable() || - !InitFavIconsTable(false)) { + !InitFavIconsTable(&db_, false)) { db_.Close(); return sql::INIT_FAILURE; } @@ -118,6 +96,37 @@ sql::InitStatus ThumbnailDatabase::Init( return sql::INIT_OK; } +sql::InitStatus ThumbnailDatabase::OpenDatabase(sql::Connection* db, + const FilePath& db_name) { + // Set the exceptional sqlite error handler. + db->set_error_delegate(GetErrorHandlerForThumbnailDb()); + + // 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. + 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 + // and so caching won't save a significant percentage of it for us, + // 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. + 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. + db->set_exclusive_locking(); + + if (!db->Open(db_name)) + return sql::INIT_FAILURE; + + return sql::INIT_OK; +} + bool ThumbnailDatabase::InitThumbnailTable() { if (!db_.DoesTableExist("thumbnails")) { if (CommandLine::ForCurrentProcess()-> HasSwitch(switches::kTopSites)) @@ -163,11 +172,12 @@ bool ThumbnailDatabase::RecreateThumbnailTable() { return InitThumbnailTable(); } -bool ThumbnailDatabase::InitFavIconsTable(bool is_temporary) { +bool ThumbnailDatabase::InitFavIconsTable(sql::Connection* db, + 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 (!db_.DoesTableExist(name)) { + if (!db->DoesTableExist(name)) { std::string sql; sql.append("CREATE TABLE "); sql.append(name); @@ -176,7 +186,7 @@ bool ThumbnailDatabase::InitFavIconsTable(bool is_temporary) { "url LONGVARCHAR NOT NULL," "last_updated INTEGER DEFAULT 0," "image_data BLOB)"); - if (!db_.Execute(sql.c_str())) + if (!db->Execute(sql.c_str())) return false; } return true; @@ -437,18 +447,79 @@ bool ThumbnailDatabase::CommitTemporaryFavIconTable() { return true; } -bool ThumbnailDatabase::DropThumbnailsTable() { - DCHECK(NeedsMigrationToTopSites()); - if (!db_.Execute("DROP TABLE thumbnails")) +bool ThumbnailDatabase::NeedsMigrationToTopSites() { + return db_.DoesTableExist("thumbnails"); +} + +bool ThumbnailDatabase::RenameAndDropThumbnails(const FilePath& old_db_file, + const FilePath& new_db_file) { + // Init favicons table - same schema as the thumbnails. + sql::Connection favicons; + if (OpenDatabase(&favicons, new_db_file) != sql::INIT_OK) return false; + + if (!InitFavIconsTable(&favicons, false)) { + NOTREACHED() << "Couldn't init favicons table."; + favicons.Close(); + return false; + } + favicons.Close(); + + // Can't attach within a transaction. CommitTransaction(); - Vacuum(); + + // Attach new DB. + { + // This block is needed because otherwise the attach statement is + // never cleared from cache and we can't close the DB :P + sql::Statement attach(db_.GetUniqueStatement("ATTACH ? AS new_favicons")); + if (!attach) { + NOTREACHED() << "Unable to attach database."; + // Keep the transaction open, even though we failed. + BeginTransaction(); + return false; + } + +#if defined(OS_POSIX) + attach.BindString(0, new_db_file.value()); +#else + attach.BindString(0, WideToUTF8(new_db_file.value())); +#endif + + if (!attach.Run()) { + NOTREACHED() << db_.GetErrorMessage(); + BeginTransaction(); + return false; + } + } + + // Move favicons to the new DB. + if (!db_.Execute("INSERT OR REPLACE INTO new_favicons.favicons " + "SELECT * FROM favicons")) { + NOTREACHED() << "Unable to copy favicons."; + BeginTransaction(); + return false; + } + + if (!db_.Execute("DETACH new_favicons")) { + NOTREACHED() << "Unable to detach database."; + BeginTransaction(); + return false; + } + + db_.Close(); + + // Reset the DB to point to new file. + if (OpenDatabase(&db_, new_db_file) != sql::INIT_OK) + return false; + + file_util::Delete(old_db_file, false); + + InitFavIconsIndex(); + + // Reopen the transaction. BeginTransaction(); return true; } -bool ThumbnailDatabase::NeedsMigrationToTopSites() { - return db_.DoesTableExist("thumbnails"); -} - } // namespace history diff --git a/chrome/browser/history/thumbnail_database.h b/chrome/browser/history/thumbnail_database.h index fba8ca0..4312a06 100644 --- a/chrome/browser/history/thumbnail_database.h +++ b/chrome/browser/history/thumbnail_database.h @@ -12,7 +12,6 @@ #include "app/sql/meta_table.h" #include "base/ref_counted.h" #include "chrome/browser/history/history_types.h" -#include "chrome/browser/history/url_database.h" // For DBCloseScoper. class FilePath; class RefCountedMemory; @@ -45,6 +44,13 @@ class ThumbnailDatabase { sql::InitStatus Init(const FilePath& db_name, const HistoryPublisher* history_publisher); + // Open database on a given filename. If the file does not exist, + // it is created. + // |db| is the database to open. + // |db_name| is a path to the database file. + static sql::InitStatus OpenDatabase(sql::Connection* db, + const FilePath& db_name); + // Transactions on the database. void BeginTransaction(); void CommitTransaction(); @@ -119,7 +125,7 @@ class ThumbnailDatabase { // will be dropped, leaving only those copied favicons remaining. This is // used to quickly delete most of the favicons when clearing history. bool InitTemporaryFavIconsTable() { - return InitFavIconsTable(true); + return InitFavIconsTable(&db_, true); } // Copies the given favicon from the "main" favicon table to the temporary @@ -137,12 +143,11 @@ class ThumbnailDatabase { // Returns true iff the thumbnails table exists. // Migrating to TopSites is dropping the thumbnails table. - // (TODO(nshkrob): renaming to favicons??) bool NeedsMigrationToTopSites(); - // Drops thumbnails table. Returns true iff the table was dropped - // successfully. False may mean that the table was already dropped. - bool DropThumbnailsTable(); + // Renames the database file and drops the Thumbnails table. + bool RenameAndDropThumbnails(const FilePath& old_db_file, + const FilePath& new_db_file); private: friend class ExpireHistoryBackend; @@ -152,10 +157,13 @@ class ThumbnailDatabase { bool InitThumbnailTable(); // Creates the favicon table, returning true if the table already exists, - // or was successfully created. is_temporary will be false when generating + // or was successfully created. |is_temporary| will be false when generating // the "regular" favicons table. The expirer sets this to true to generate the // temporary table, which will have a different name but the same schema. - bool InitFavIconsTable(bool is_temporary); + // |db| is the connection to use for initializing the table. + // A different connection is used in RenameAndDropThumbnails, when we + // need to copy the favicons between two database files. + bool InitFavIconsTable(sql::Connection* db, bool is_temporary); // Adds support for the new metadata on web page thumbnails. bool UpgradeToVersion3(); diff --git a/chrome/browser/history/thumbnail_database_unittest.cc b/chrome/browser/history/thumbnail_database_unittest.cc index 1542033..4d2c2bf 100644 --- a/chrome/browser/history/thumbnail_database_unittest.cc +++ b/chrome/browser/history/thumbnail_database_unittest.cc @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <algorithm> +#include <vector> + #include "base/basictypes.h" #include "base/file_path.h" #include "base/file_util.h" #include "base/path_service.h" +#include "base/ref_counted_memory.h" +#include "base/scoped_temp_dir.h" #include "chrome/browser/history/thumbnail_database.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/thumbnail_score.h" @@ -46,25 +51,22 @@ class ThumbnailDatabaseTest : public testing::Test { } protected: - // testing::Test virtual void SetUp() { - // get an empty file for the test DB - FilePath test_data_dir; - PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); - file_name_ = test_data_dir.AppendASCII("TestThumbnails.db"); - file_util::Delete(file_name_, false); + // Get a temporary directory for the test DB files. + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + + file_name_ = temp_dir_.path().AppendASCII("TestThumbnails.db"); + new_file_name_ = temp_dir_.path().AppendASCII("TestFavicons.db"); google_bitmap_.reset( gfx::JPEGCodec::Decode(kGoogleThumbnail, sizeof(kGoogleThumbnail))); } - virtual void TearDown() { - file_util::Delete(file_name_, false); - } - scoped_ptr<SkBitmap> google_bitmap_; + ScopedTempDir temp_dir_; FilePath file_name_; + FilePath new_file_name_; }; TEST_F(ThumbnailDatabaseTest, AddDelete) { @@ -334,8 +336,36 @@ TEST_F(ThumbnailDatabaseTest, NeedsMigrationToTopSites) { ASSERT_EQ(sql::INIT_OK, db.Init(file_name_, NULL)); db.BeginTransaction(); EXPECT_TRUE(db.NeedsMigrationToTopSites()); - EXPECT_TRUE(db.DropThumbnailsTable()); + EXPECT_TRUE(db.RenameAndDropThumbnails(file_name_, new_file_name_)); EXPECT_FALSE(db.NeedsMigrationToTopSites()); + EXPECT_FALSE(file_util::PathExists(file_name_)); + EXPECT_TRUE(file_util::PathExists(new_file_name_)); +} + +TEST_F(ThumbnailDatabaseTest, GetFaviconAfterMigrationToTopSites) { + ThumbnailDatabase db; + ASSERT_EQ(sql::INIT_OK, db.Init(file_name_, NULL)); + db.BeginTransaction(); + + std::vector<unsigned char> data(blob1, blob1 + sizeof(blob1)); + scoped_refptr<RefCountedBytes> favicon(new RefCountedBytes(data)); + + GURL url("http://google.com"); + FavIconID id = db.AddFavIcon(url); + base::Time time = base::Time::Now(); + db.SetFavIcon(id, favicon, time); + EXPECT_TRUE(db.RenameAndDropThumbnails(file_name_, new_file_name_)); + + base::Time time_out; + std::vector<unsigned char> favicon_out; + GURL url_out; + EXPECT_TRUE(db.GetFavIcon(id, &time_out, &favicon_out, &url_out)); + EXPECT_EQ(url, url_out); + EXPECT_EQ(time.ToTimeT(), time_out.ToTimeT()); + ASSERT_EQ(data.size(), favicon_out.size()); + EXPECT_TRUE(std::equal(data.begin(), + data.end(), + favicon_out.begin())); } } // namespace history |