| Index: webkit/browser/appcache/appcache_database.cc
|
| diff --git a/webkit/browser/appcache/appcache_database.cc b/webkit/browser/appcache/appcache_database.cc
|
| index 0980973d49ef04a31b20c2ff15ee8401571552b2..076f090c4e047f3fd56a829f3eadac0eb6f5ac4e 100644
|
| --- a/webkit/browser/appcache/appcache_database.cc
|
| +++ b/webkit/browser/appcache/appcache_database.cc
|
| @@ -5,11 +5,14 @@
|
| #include "webkit/browser/appcache/appcache_database.h"
|
|
|
| #include "base/auto_reset.h"
|
| +#include "base/bind.h"
|
| #include "base/command_line.h"
|
| #include "base/file_util.h"
|
| #include "base/logging.h"
|
| +#include "base/rand_util.h" // just for local testing, not for commit
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "sql/connection.h"
|
| +#include "sql/error_delegate_util.h"
|
| #include "sql/meta_table.h"
|
| #include "sql/statement.h"
|
| #include "sql/transaction.h"
|
| @@ -200,7 +203,8 @@ AppCacheDatabase::NamespaceRecord::~NamespaceRecord() {
|
|
|
|
|
| AppCacheDatabase::AppCacheDatabase(const base::FilePath& path)
|
| - : db_file_path_(path), is_disabled_(false), is_recreating_(false) {
|
| + : db_file_path_(path), is_disabled_(false),
|
| + is_recreating_(false), was_corruption_detected_(false) {
|
| }
|
|
|
| AppCacheDatabase::~AppCacheDatabase() {
|
| @@ -1036,6 +1040,9 @@ bool AppCacheDatabase::LazyOpen(bool create_if_needed) {
|
| }
|
|
|
| AppCacheHistograms::CountInitResult(AppCacheHistograms::INIT_OK);
|
| + was_corruption_detected_ = false;
|
| + db_->set_error_callback(
|
| + base::Bind(&AppCacheDatabase::OnDatabaseError, base::Unretained(this)));
|
| return true;
|
| }
|
|
|
| @@ -1195,13 +1202,14 @@ bool AppCacheDatabase::DeleteExistingAndCreateNewDatabase() {
|
|
|
| // This also deletes the disk cache data.
|
| base::FilePath directory = db_file_path_.DirName();
|
| - if (!base::DeleteFile(directory, true) ||
|
| - !base::CreateDirectory(directory)) {
|
| + if (!base::DeleteFile(directory, true))
|
| return false;
|
| - }
|
|
|
| // Make sure the steps above actually deleted things.
|
| - if (base::PathExists(db_file_path_))
|
| + if (base::PathExists(directory))
|
| + return false;
|
| +
|
| + if (!base::CreateDirectory(directory))
|
| return false;
|
|
|
| // So we can't go recursive.
|
| @@ -1212,4 +1220,24 @@ bool AppCacheDatabase::DeleteExistingAndCreateNewDatabase() {
|
| return LazyOpen(true);
|
| }
|
|
|
| +void AppCacheDatabase::OnDatabaseError(int err, sql::Statement* stmt) {
|
| + was_corruption_detected_ |= sql::IsErrorCatastrophic(err);
|
| +
|
| + // Retain the default handling which is to assert on debug and to
|
| + // ignore on release.
|
| + if (!db_->ShouldIgnoreSqliteError(err))
|
| + DLOG(ERROR) << db_->GetErrorMessage();
|
| +
|
| + // Note to self?
|
| + // Maybe use non-catostrophic errors to trigger a full integrity check?
|
| +}
|
| +
|
| +bool AppCacheDatabase::was_corruption_dectected() {
|
| + // for local testing, inject spurious errors and see wha' happens
|
| + //uint64 kSynthesizedErrorRate = 10; // percent
|
| + //was_corruption_detected_ |=
|
| + // (base::RandGenerator(100) < kSynthesizedErrorRate);
|
| + return was_corruption_detected_;
|
| +}
|
| +
|
| } // namespace appcache
|
|
|