diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-05 18:09:03 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-05 18:09:03 +0000 |
commit | 391c3fc84713b5f8256571aa9330fa527c6d5241 (patch) | |
tree | b4ce862fe45102d807b4a31e3b4e202dd3b4d124 /chrome/browser/safe_browsing/safe_browsing_store_file.cc | |
parent | 7c78370cbfa49a8fa064d97c0fed1d63bd205464 (diff) | |
download | chromium_src-391c3fc84713b5f8256571aa9330fa527c6d5241.zip chromium_src-391c3fc84713b5f8256571aa9330fa527c6d5241.tar.gz chromium_src-391c3fc84713b5f8256571aa9330fa527c6d5241.tar.bz2 |
On-the-fly migration from SafeBrowsingStoreSqlite -> *File.
BUG=none
TEST=none
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=40605
Review URL: http://codereview.chromium.org/666001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40749 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/safe_browsing/safe_browsing_store_file.cc')
-rw-r--r-- | chrome/browser/safe_browsing/safe_browsing_store_file.cc | 90 |
1 files changed, 81 insertions, 9 deletions
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_file.cc b/chrome/browser/safe_browsing/safe_browsing_store_file.cc index 7186388..207a607 100644 --- a/chrome/browser/safe_browsing/safe_browsing_store_file.cc +++ b/chrome/browser/safe_browsing/safe_browsing_store_file.cc @@ -7,6 +7,9 @@ #include "base/callback.h" #include "base/md5.h" +// TODO(shess): Remove after migration. +#include "chrome/browser/safe_browsing/safe_browsing_store_sqlite.h" + namespace { // NOTE(shess): kFileMagic should not be a byte-wise palindrome, so @@ -206,6 +209,17 @@ bool SafeBrowsingStoreFile::Delete() { return false; } + // Also make sure any SQLite data is deleted. This should only be + // needed if a journal file is left from a crash and the database is + // reset before SQLite gets a chance to straighten things out. + // TODO(shess): Remove after migration. + SafeBrowsingStoreSqlite old_store; + old_store.Init( + filename_, + NewCallback(this, &SafeBrowsingStoreFile::HandleCorruptDatabase)); + if (!old_store.Delete()) + return false; + return true; } @@ -229,11 +243,12 @@ bool SafeBrowsingStoreFile::Close() { // Make sure the files are closed. file_.reset(); new_file_.reset(); + old_store_.reset(); return true; } bool SafeBrowsingStoreFile::BeginUpdate() { - DCHECK(!file_.get() && !new_file_.get()); + DCHECK(!file_.get() && !new_file_.get() && !old_store_.get()); // Structures should all be clear unless something bad happened. DCHECK(add_chunks_cache_.empty()); @@ -267,8 +282,34 @@ bool SafeBrowsingStoreFile::BeginUpdate() { if (!ReadArray(&header, 1, file.get(), NULL)) return OnCorruptDatabase(); - if (header.magic != kFileMagic || header.version != kFileVersion) - return OnCorruptDatabase(); + if (header.magic != kFileMagic || header.version != kFileVersion) { + // Something about having the file open causes a problem with + // SQLite opening it. Perhaps PRAGMA locking_mode = EXCLUSIVE? + file.reset(); + + // Magic numbers didn't match, maybe it's a SQLite database. + scoped_ptr<SafeBrowsingStoreSqlite> + sqlite_store(new SafeBrowsingStoreSqlite()); + sqlite_store->Init( + filename_, + NewCallback(this, &SafeBrowsingStoreFile::HandleCorruptDatabase)); + if (!sqlite_store->BeginUpdate()) + return OnCorruptDatabase(); + + // Pull chunks-seen data into local structures, rather than + // optionally wiring various calls through to the SQLite store. + std::vector<int32> chunks; + sqlite_store->GetAddChunks(&chunks); + add_chunks_cache_.insert(chunks.begin(), chunks.end()); + + sqlite_store->GetSubChunks(&chunks); + sub_chunks_cache_.insert(chunks.begin(), chunks.end()); + + new_file_.swap(new_file); + old_store_.swap(sqlite_store); + + return true; + } // Check that the file size makes sense given the header. This is a // cheap way to protect against header corruption while deferring @@ -333,7 +374,7 @@ bool SafeBrowsingStoreFile::DoUpdate( const std::vector<SBAddFullHash>& pending_adds, std::vector<SBAddPrefix>* add_prefixes_result, std::vector<SBAddFullHash>* add_full_hashes_result) { - DCHECK(file_.get() || empty_); + DCHECK(old_store_.get() || file_.get() || empty_); DCHECK(new_file_.get()); std::vector<SBAddPrefix> add_prefixes; @@ -341,8 +382,30 @@ bool SafeBrowsingStoreFile::DoUpdate( std::vector<SBAddFullHash> add_full_hashes; std::vector<SBSubFullHash> sub_full_hashes; - // Read |file_| into the vectors. - if (!empty_) { + // Read |old_store_| into the vectors. + if (old_store_.get()) { + // Push deletions to |old_store_| so they can be applied to the + // data being read. + for (base::hash_set<int32>::const_iterator iter = add_del_cache_.begin(); + iter != add_del_cache_.end(); ++iter) { + old_store_->DeleteAddChunk(*iter); + } + for (base::hash_set<int32>::const_iterator iter = sub_del_cache_.begin(); + iter != sub_del_cache_.end(); ++iter) { + old_store_->DeleteSubChunk(*iter); + } + + if (!old_store_->ReadAddPrefixes(&add_prefixes) || + !old_store_->ReadSubPrefixes(&sub_prefixes) || + !old_store_->ReadAddHashes(&add_full_hashes) || + !old_store_->ReadSubHashes(&sub_full_hashes)) + return OnCorruptDatabase(); + + // Do not actually update the old store. + if (!old_store_->CancelUpdate()) + return OnCorruptDatabase(); + } else if (!empty_) { + // Read |file_| into the vectors. DCHECK(file_.get()); if (!FileRewind(file_.get())) @@ -479,9 +542,16 @@ bool SafeBrowsingStoreFile::DoUpdate( // Close the file handle and swizzle the file into place. new_file_.reset(); - if (!file_util::Delete(filename_, false) && - file_util::PathExists(filename_)) - return false; + if (old_store_.get()) { + const bool deleted = old_store_->Delete(); + old_store_.reset(); + if (!deleted) + return false; + } else { + if (!file_util::Delete(filename_, false) && + file_util::PathExists(filename_)) + return false; + } const FilePath new_filename = TemporaryFileForFilename(filename_); if (!file_util::Move(new_filename, filename_)) @@ -508,10 +578,12 @@ bool SafeBrowsingStoreFile::FinishUpdate( DCHECK(!new_file_.get()); DCHECK(!file_.get()); + DCHECK(!old_store_.get()); return Close(); } bool SafeBrowsingStoreFile::CancelUpdate() { + old_store_.reset(); return Close(); } |