summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-18 00:19:44 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-18 00:19:44 +0000
commitb3b2d6e76a2cfbb02933298c565d3718b0288774 (patch)
tree548c4d8fe0b7c7d22c44e045a61c7719977359cc /chrome
parent5786d3d3a7cd151fb5dc0aa2f1f0d84460fb6cdf (diff)
downloadchromium_src-b3b2d6e76a2cfbb02933298c565d3718b0288774.zip
chromium_src-b3b2d6e76a2cfbb02933298c565d3718b0288774.tar.gz
chromium_src-b3b2d6e76a2cfbb02933298c565d3718b0288774.tar.bz2
Fixes two related bugs:
. If we can't init the web db a dialog is shown to the user. . If we can't init the web db the default search provider no longer becomes NULL. BUG=28374 TEST=none Review URL: http://codereview.chromium.org/501090 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34901 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/history/archived_database.cc10
-rw-r--r--chrome/browser/history/archived_database.h3
-rw-r--r--chrome/browser/history/expire_history_backend_unittest.cc5
-rw-r--r--chrome/browser/history/history_backend.cc8
-rw-r--r--chrome/browser/history/history_database.cc26
-rw-r--r--chrome/browser/history/history_database.h7
-rw-r--r--chrome/browser/history/history_types.h11
-rw-r--r--chrome/browser/history/thumbnail_database.cc17
-rw-r--r--chrome/browser/history/thumbnail_database.h5
-rw-r--r--chrome/browser/history/thumbnail_database_unittest.cc10
-rw-r--r--chrome/browser/search_engines/template_url_model.cc8
-rw-r--r--chrome/browser/search_engines/template_url_model.h7
-rw-r--r--chrome/browser/search_engines/template_url_model_unittest.cc22
-rw-r--r--chrome/browser/webdata/web_data_service.cc29
-rw-r--r--chrome/browser/webdata/web_data_service.h12
-rw-r--r--chrome/browser/webdata/web_database.cc14
-rw-r--r--chrome/browser/webdata/web_database.h5
-rw-r--r--chrome/browser/webdata/web_database_unittest.cc20
18 files changed, 133 insertions, 86 deletions
diff --git a/chrome/browser/history/archived_database.cc b/chrome/browser/history/archived_database.cc
index b7cd8bd..1b9e010 100644
--- a/chrome/browser/history/archived_database.cc
+++ b/chrome/browser/history/archived_database.cc
@@ -64,7 +64,7 @@ bool ArchivedDatabase::Init(const FilePath& file_name) {
}
CreateMainURLIndex();
- if (EnsureCurrentVersion() != INIT_OK) {
+ if (EnsureCurrentVersion() != sql::INIT_OK) {
db_.Close();
return false;
}
@@ -86,11 +86,11 @@ sql::Connection& ArchivedDatabase::GetDB() {
// Migration -------------------------------------------------------------------
-InitStatus ArchivedDatabase::EnsureCurrentVersion() {
+sql::InitStatus ArchivedDatabase::EnsureCurrentVersion() {
// We can't read databases newer than we were designed for.
if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
LOG(WARNING) << "Archived database is too new.";
- return INIT_TOO_NEW;
+ return sql::INIT_TOO_NEW;
}
// NOTICE: If you are changing structures for things shared with the archived
@@ -103,7 +103,7 @@ InitStatus ArchivedDatabase::EnsureCurrentVersion() {
if (cur_version == 1) {
if (!DropStarredIDFromURLs()) {
LOG(WARNING) << "Unable to update archived database to version 2.";
- return INIT_FAILURE;
+ return sql::INIT_FAILURE;
}
++cur_version;
meta_table_.SetVersionNumber(cur_version);
@@ -118,6 +118,6 @@ InitStatus ArchivedDatabase::EnsureCurrentVersion() {
LOG_IF(WARNING, cur_version < kCurrentVersionNumber) <<
"Archived database version " << cur_version << " is too old to handle.";
- return INIT_OK;
+ return sql::INIT_OK;
}
} // namespace history
diff --git a/chrome/browser/history/archived_database.h b/chrome/browser/history/archived_database.h
index 13bc562..c9d8757 100644
--- a/chrome/browser/history/archived_database.h
+++ b/chrome/browser/history/archived_database.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_HISTORY_ARCHIVED_DATABASE_H_
#include "app/sql/connection.h"
+#include "app/sql/init_status.h"
#include "app/sql/meta_table.h"
#include "base/basictypes.h"
#include "chrome/browser/history/url_database.h"
@@ -48,7 +49,7 @@ class ArchivedDatabase : public URLDatabase,
//
// This assumes it is called from the init function inside a transaction. It
// may commit the transaction and start a new one if migration requires it.
- InitStatus EnsureCurrentVersion();
+ sql::InitStatus EnsureCurrentVersion();
// The database.
sql::Connection db_;
diff --git a/chrome/browser/history/expire_history_backend_unittest.cc b/chrome/browser/history/expire_history_backend_unittest.cc
index 2ccab9b61..03c4eef 100644
--- a/chrome/browser/history/expire_history_backend_unittest.cc
+++ b/chrome/browser/history/expire_history_backend_unittest.cc
@@ -113,8 +113,7 @@ class ExpireHistoryTest : public testing::Test,
FilePath history_name = dir_.Append(kHistoryFile);
main_db_.reset(new HistoryDatabase);
- if (main_db_->Init(history_name, FilePath()) !=
- INIT_OK)
+ if (main_db_->Init(history_name, FilePath()) != sql::INIT_OK)
main_db_.reset();
FilePath archived_name = dir_.Append(kArchivedHistoryFile);
@@ -124,7 +123,7 @@ class ExpireHistoryTest : public testing::Test,
FilePath thumb_name = dir_.Append(kThumbnailFile);
thumb_db_.reset(new ThumbnailDatabase);
- if (thumb_db_->Init(thumb_name, NULL) != INIT_OK)
+ if (thumb_db_->Init(thumb_name, NULL) != sql::INIT_OK)
thumb_db_.reset();
text_db_.reset(new TextDatabaseManager(dir_,
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc
index 9734d4f..4fdcef8 100644
--- a/chrome/browser/history/history_backend.cc
+++ b/chrome/browser/history/history_backend.cc
@@ -504,15 +504,15 @@ void HistoryBackend::InitImpl() {
// History database.
db_.reset(new HistoryDatabase());
switch (db_->Init(history_name, tmp_bookmarks_file)) {
- case INIT_OK:
+ case sql::INIT_OK:
break;
- case INIT_FAILURE:
+ case sql::INIT_FAILURE:
// A NULL db_ will cause all calls on this object to notice this error
// and to not continue.
delegate_->NotifyProfileError(IDS_COULDNT_OPEN_PROFILE_ERROR);
db_.reset();
return;
- case INIT_TOO_NEW:
+ case sql::INIT_TOO_NEW:
delegate_->NotifyProfileError(IDS_PROFILE_TOO_NEW_ERROR);
db_.reset();
return;
@@ -557,7 +557,7 @@ void HistoryBackend::InitImpl() {
// Thumbnail database.
thumbnail_db_.reset(new ThumbnailDatabase());
if (thumbnail_db_->Init(thumbnail_name,
- history_publisher_.get()) != INIT_OK) {
+ history_publisher_.get()) != sql::INIT_OK) {
// Unlike the main database, we don't error out when the database is too
// new because this error is much less severe. Generally, this shouldn't
// happen since the thumbnail and main datbase versions should be in sync.
diff --git a/chrome/browser/history/history_database.cc b/chrome/browser/history/history_database.cc
index 37296b0..21a271b 100644
--- a/chrome/browser/history/history_database.cc
+++ b/chrome/browser/history/history_database.cc
@@ -60,8 +60,8 @@ HistoryDatabase::HistoryDatabase()
HistoryDatabase::~HistoryDatabase() {
}
-InitStatus HistoryDatabase::Init(const FilePath& history_name,
- const FilePath& bookmarks_path) {
+sql::InitStatus HistoryDatabase::Init(const FilePath& history_name,
+ const FilePath& bookmarks_path) {
// Set the exceptional sqlite error handler.
db_.set_error_delegate(GetErrorHandlerForHistoryDb());
@@ -82,13 +82,13 @@ InitStatus HistoryDatabase::Init(const FilePath& history_name,
// mode to start out for the in-memory backend to read the data).
if (!db_.Open(history_name))
- return INIT_FAILURE;
+ return sql::INIT_FAILURE;
// Wrap the rest of init in a tranaction. This will prevent the database from
// getting corrupted if we crash in the middle of initialization or migration.
sql::Transaction committer(&db_);
if (!committer.Begin())
- return INIT_FAILURE;
+ return sql::INIT_FAILURE;
#if defined(OS_MACOSX)
// Exclude the history file and its journal from backups.
@@ -106,21 +106,21 @@ InitStatus HistoryDatabase::Init(const FilePath& history_name,
// NOTE: If you add something here, also add it to
// RecreateAllButStarAndURLTables.
if (!meta_table_.Init(&db_, kCurrentVersionNumber, kCompatibleVersionNumber))
- return INIT_FAILURE;
+ return sql::INIT_FAILURE;
if (!CreateURLTable(false) || !InitVisitTable() ||
!InitKeywordSearchTermsTable() || !InitDownloadTable() ||
!InitSegmentTables())
- return INIT_FAILURE;
+ return sql::INIT_FAILURE;
CreateMainURLIndex();
CreateSupplimentaryURLIndices();
// Version check.
- InitStatus version_status = EnsureCurrentVersion(bookmarks_path);
- if (version_status != INIT_OK)
+ sql::InitStatus version_status = EnsureCurrentVersion(bookmarks_path);
+ if (version_status != sql::INIT_OK)
return version_status;
ComputeDatabaseMetrics(history_name, db_);
- return committer.Commit() ? INIT_OK : INIT_FAILURE;
+ return committer.Commit() ? sql::INIT_OK : sql::INIT_FAILURE;
}
void HistoryDatabase::BeginExclusiveMode() {
@@ -229,12 +229,12 @@ sql::Connection& HistoryDatabase::GetDB() {
// Migration -------------------------------------------------------------------
-InitStatus HistoryDatabase::EnsureCurrentVersion(
+sql::InitStatus HistoryDatabase::EnsureCurrentVersion(
const FilePath& tmp_bookmarks_path) {
// We can't read databases newer than we were designed for.
if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
LOG(WARNING) << "History database is too new.";
- return INIT_TOO_NEW;
+ return sql::INIT_TOO_NEW;
}
// NOTICE: If you are changing structures for things shared with the archived
@@ -251,7 +251,7 @@ InitStatus HistoryDatabase::EnsureCurrentVersion(
if (!MigrateBookmarksToFile(tmp_bookmarks_path) ||
!DropStarredIDFromURLs()) {
LOG(WARNING) << "Unable to update history database to version 16.";
- return INIT_FAILURE;
+ return sql::INIT_FAILURE;
}
++cur_version;
meta_table_.SetVersionNumber(cur_version);
@@ -278,7 +278,7 @@ InitStatus HistoryDatabase::EnsureCurrentVersion(
LOG_IF(WARNING, cur_version < kCurrentVersionNumber) <<
"History database version " << cur_version << " is too old to handle.";
- return INIT_OK;
+ return sql::INIT_OK;
}
#if !defined(OS_WIN)
diff --git a/chrome/browser/history/history_database.h b/chrome/browser/history/history_database.h
index 3bb8520..5bfda56 100644
--- a/chrome/browser/history/history_database.h
+++ b/chrome/browser/history/history_database.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_HISTORY_HISTORY_DATABASE_H_
#include "app/sql/connection.h"
+#include "app/sql/init_status.h"
#include "app/sql/meta_table.h"
#include "build/build_config.h"
#include "chrome/browser/history/download_database.h"
@@ -61,8 +62,8 @@ class HistoryDatabase : public DownloadDatabase,
// Must call this function to complete initialization. Will return true on
// success. On false, no other function should be called. You may want to call
// BeginExclusiveMode after this when you are ready.
- InitStatus Init(const FilePath& history_name,
- const FilePath& tmp_bookmarks_path);
+ sql::InitStatus Init(const FilePath& history_name,
+ const FilePath& tmp_bookmarks_path);
// Call to set the mode on the database to exclusive. The default locking mode
// is "normal" but we want to run in exclusive mode for slightly better
@@ -152,7 +153,7 @@ class HistoryDatabase : public DownloadDatabase,
//
// This assumes it is called from the init function inside a transaction. It
// may commit the transaction and start a new one if migration requires it.
- InitStatus EnsureCurrentVersion(const FilePath& tmp_bookmarks_path);
+ sql::InitStatus EnsureCurrentVersion(const FilePath& tmp_bookmarks_path);
#if !defined(OS_WIN)
// Converts the time epoch in the database from being 1970-based to being
diff --git a/chrome/browser/history/history_types.h b/chrome/browser/history/history_types.h
index 89d3851..b35f432 100644
--- a/chrome/browser/history/history_types.h
+++ b/chrome/browser/history/history_types.h
@@ -37,17 +37,6 @@ typedef int64 DownloadID; // Identifier for a download.
typedef int64 FavIconID; // For FavIcons.
typedef int64 SegmentID; // URL segments for the most visited view.
-// Used as the return value for some databases' init function.
-enum InitStatus {
- INIT_OK,
-
- // Some error, usually I/O related opening the file.
- INIT_FAILURE,
-
- // The database is from a future version of the app and can not be read.
- INIT_TOO_NEW,
-};
-
// URLRow ---------------------------------------------------------------------
typedef int64 URLID;
diff --git a/chrome/browser/history/thumbnail_database.cc b/chrome/browser/history/thumbnail_database.cc
index 60b8985..4e6f372 100644
--- a/chrome/browser/history/thumbnail_database.cc
+++ b/chrome/browser/history/thumbnail_database.cc
@@ -32,8 +32,9 @@ ThumbnailDatabase::~ThumbnailDatabase() {
// The DBCloseScoper will delete the DB and the cache.
}
-InitStatus ThumbnailDatabase::Init(const FilePath& db_name,
- const HistoryPublisher* history_publisher) {
+sql::InitStatus ThumbnailDatabase::Init(
+ const FilePath& db_name,
+ const HistoryPublisher* history_publisher) {
history_publisher_ = history_publisher;
// Set the exceptional sqlite error handler.
@@ -60,7 +61,7 @@ InitStatus ThumbnailDatabase::Init(const FilePath& db_name,
db_.set_exclusive_locking();
if (!db_.Open(db_name))
- return INIT_FAILURE;
+ return sql::INIT_FAILURE;
// Scope initialization in a transaction so we can't be partially initialized.
sql::Transaction transaction(&db_);
@@ -81,7 +82,7 @@ InitStatus ThumbnailDatabase::Init(const FilePath& db_name,
!InitThumbnailTable() ||
!InitFavIconsTable(false)) {
db_.Close();
- return INIT_FAILURE;
+ return sql::INIT_FAILURE;
}
InitFavIconsIndex();
@@ -89,7 +90,7 @@ InitStatus ThumbnailDatabase::Init(const FilePath& db_name,
// in the wild, so we try to continue in that case.
if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
LOG(WARNING) << "Thumbnail database is too new.";
- return INIT_TOO_NEW;
+ return sql::INIT_TOO_NEW;
}
int cur_version = meta_table_.GetVersionNumber();
@@ -97,7 +98,7 @@ InitStatus ThumbnailDatabase::Init(const FilePath& db_name,
if (!UpgradeToVersion3()) {
LOG(WARNING) << "Unable to update to thumbnail database to version 3.";
db_.Close();
- return INIT_FAILURE;
+ return sql::INIT_FAILURE;
}
++cur_version;
}
@@ -108,10 +109,10 @@ InitStatus ThumbnailDatabase::Init(const FilePath& db_name,
// Initialization is complete.
if (!transaction.Commit()) {
db_.Close();
- return INIT_FAILURE;
+ return sql::INIT_FAILURE;
}
- return INIT_OK;
+ return sql::INIT_OK;
}
bool ThumbnailDatabase::InitThumbnailTable() {
diff --git a/chrome/browser/history/thumbnail_database.h b/chrome/browser/history/thumbnail_database.h
index 7fd9202..362edec 100644
--- a/chrome/browser/history/thumbnail_database.h
+++ b/chrome/browser/history/thumbnail_database.h
@@ -8,6 +8,7 @@
#include <vector>
#include "app/sql/connection.h"
+#include "app/sql/init_status.h"
#include "app/sql/meta_table.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/history/url_database.h" // For DBCloseScoper.
@@ -40,8 +41,8 @@ class ThumbnailDatabase {
// Must be called after creation but before any other methods are called.
// When not INIT_OK, no other functions should be called.
- InitStatus Init(const FilePath& db_name,
- const HistoryPublisher* history_publisher);
+ sql::InitStatus Init(const FilePath& db_name,
+ const HistoryPublisher* history_publisher);
// Transactions on the database.
void BeginTransaction();
diff --git a/chrome/browser/history/thumbnail_database_unittest.cc b/chrome/browser/history/thumbnail_database_unittest.cc
index 83d67cf..2b63e43 100644
--- a/chrome/browser/history/thumbnail_database_unittest.cc
+++ b/chrome/browser/history/thumbnail_database_unittest.cc
@@ -69,7 +69,7 @@ class ThumbnailDatabaseTest : public testing::Test {
TEST_F(ThumbnailDatabaseTest, AddDelete) {
ThumbnailDatabase db;
- ASSERT_TRUE(db.Init(file_name_, NULL) == INIT_OK);
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_name_, NULL));
// Add one page & verify it got added.
ThumbnailScore boring(kBoringness, true, true);
@@ -112,7 +112,7 @@ TEST_F(ThumbnailDatabaseTest, AddDelete) {
TEST_F(ThumbnailDatabaseTest, UseLessBoringThumbnails) {
ThumbnailDatabase db;
Time now = Time::Now();
- ASSERT_TRUE(db.Init(file_name_, NULL) == INIT_OK);
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_name_, NULL));
// Add one page & verify it got added.
ThumbnailScore boring(kBoringness, true, true);
@@ -146,7 +146,7 @@ TEST_F(ThumbnailDatabaseTest, UseLessBoringThumbnails) {
TEST_F(ThumbnailDatabaseTest, UseAtTopThumbnails) {
ThumbnailDatabase db;
Time now = Time::Now();
- ASSERT_TRUE(db.Init(file_name_, NULL) == INIT_OK);
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_name_, NULL));
// Add one page & verify it got added. Note that it doesn't have
// |good_clipping| and isn't |at_top|.
@@ -222,7 +222,7 @@ TEST_F(ThumbnailDatabaseTest, ThumbnailTimeDegradation) {
const double kBaseBoringness = 0.305;
const double kWorseBoringness = 0.345;
- ASSERT_TRUE(db.Init(file_name_, NULL) == INIT_OK);
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_name_, NULL));
// add one page & verify it got added.
ThumbnailScore base_boringness(kBaseBoringness, true, true, kFiveHoursAgo);
@@ -261,7 +261,7 @@ TEST_F(ThumbnailDatabaseTest, NeverAcceptTotallyBoringThumbnail) {
// thumbnail is totally boring.
ThumbnailDatabase db;
Time now = Time::Now();
- ASSERT_TRUE(db.Init(file_name_, NULL) == INIT_OK);
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_name_, NULL));
std::vector<unsigned char> jpeg_data;
ThumbnailScore score_out;
diff --git a/chrome/browser/search_engines/template_url_model.cc b/chrome/browser/search_engines/template_url_model.cc
index cbad64a..a356ad0 100644
--- a/chrome/browser/search_engines/template_url_model.cc
+++ b/chrome/browser/search_engines/template_url_model.cc
@@ -59,6 +59,7 @@ class TemplateURLModel::LessWithPrefix {
TemplateURLModel::TemplateURLModel(Profile* profile)
: profile_(profile),
loaded_(false),
+ load_failed_(false),
load_handle_(0),
default_search_provider_(NULL),
next_id_(1) {
@@ -70,6 +71,7 @@ TemplateURLModel::TemplateURLModel(const Initializer* initializers,
const int count)
: profile_(NULL),
loaded_(true),
+ load_failed_(false),
load_handle_(0),
service_(NULL),
default_search_provider_(NULL),
@@ -521,7 +523,7 @@ void TemplateURLModel::SetDefaultSearchProvider(const TemplateURL* url) {
}
const TemplateURL* TemplateURLModel::GetDefaultSearchProvider() {
- if (loaded_)
+ if (loaded_ && !load_failed_)
return default_search_provider_;
if (!prefs_default_search_provider_.get()) {
@@ -576,8 +578,10 @@ void TemplateURLModel::OnWebDataServiceRequestDone(
load_handle_ = 0;
if (!result) {
- // Results are null if the database went away.
+ // Results are null if the database went away or (most likely) wasn't
+ // loaded.
loaded_ = true;
+ load_failed_ = true;
NotifyLoaded();
return;
}
diff --git a/chrome/browser/search_engines/template_url_model.h b/chrome/browser/search_engines/template_url_model.h
index 044ec23..5b76234 100644
--- a/chrome/browser/search_engines/template_url_model.h
+++ b/chrome/browser/search_engines/template_url_model.h
@@ -320,6 +320,9 @@ class TemplateURLModel : public WebDataServiceConsumer,
// Whether the keywords have been loaded.
bool loaded_;
+ // Did loading fail? This is only valid if loaded_ is true.
+ bool load_failed_;
+
// If non-zero, we're waiting on a load.
WebDataService::Handle load_handle_;
@@ -340,8 +343,8 @@ class TemplateURLModel : public WebDataServiceConsumer,
const TemplateURL* default_search_provider_;
// The default search provider from preferences. This is only valid if
- // GetDefaultSearchProvider is invoked and we haven't been loaded. Once loaded
- // this is not used.
+ // GetDefaultSearchProvider is invoked and we haven't been loaded or loading
+ // failed. If loading was successful this is not used.
scoped_ptr<TemplateURL> prefs_default_search_provider_;
// ID assigned to next TemplateURL added to this model. This is an ever
diff --git a/chrome/browser/search_engines/template_url_model_unittest.cc b/chrome/browser/search_engines/template_url_model_unittest.cc
index 1edad67..1c50fc1 100644
--- a/chrome/browser/search_engines/template_url_model_unittest.cc
+++ b/chrome/browser/search_engines/template_url_model_unittest.cc
@@ -31,7 +31,7 @@ class QuitTask2 : public Task {
// Subclass the TestingProfile so that it can return a WebDataService.
class TemplateURLModelTestingProfile : public TestingProfile {
public:
- TemplateURLModelTestingProfile() : TestingProfile() { }
+ TemplateURLModelTestingProfile() : TestingProfile() {}
void SetUp() {
// Name a subdirectory of the temp directory.
@@ -87,7 +87,7 @@ class TestingTemplateURLModel : public TemplateURLModel {
private:
std::wstring search_term_;
- DISALLOW_EVIL_CONSTRUCTORS(TestingTemplateURLModel);
+ DISALLOW_COPY_AND_ASSIGN(TestingTemplateURLModel);
};
class TemplateURLModelTest : public testing::Test,
@@ -739,3 +739,21 @@ TEST_F(TemplateURLModelTest, MergeDeletesUnusedProviders) {
// Don't remove |t_url3|; we'd need to make it non-default first, and why
// bother when the model shutdown will clean it up for us.
}
+
+// Simulates failing to load the webdb and makes sure the default search
+// provider is valid.
+TEST_F(TemplateURLModelTest, FailedInit) {
+ VerifyLoad();
+
+ model_.reset(NULL);
+
+ profile_->GetWebDataService(Profile::EXPLICIT_ACCESS)->UnloadDatabase();
+ profile_->GetWebDataService(Profile::EXPLICIT_ACCESS)->set_failed_init(true);
+
+ ResetModel(false);
+ model_->Load();
+ BlockTillServiceProcessesRequests();
+
+ ASSERT_TRUE(model_->GetDefaultSearchProvider());
+}
+
diff --git a/chrome/browser/webdata/web_data_service.cc b/chrome/browser/webdata/web_data_service.cc
index 1b81ac2..5ca9c31 100644
--- a/chrome/browser/webdata/web_data_service.cc
+++ b/chrome/browser/webdata/web_data_service.cc
@@ -14,6 +14,8 @@
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
#include "webkit/glue/password_form.h"
////////////////////////////////////////////////////////////////////////////////
@@ -26,11 +28,13 @@ using base::Time;
using webkit_glue::FormField;
using webkit_glue::PasswordForm;
-WebDataService::WebDataService() : thread_(NULL),
- db_(NULL),
- failed_init_(false),
- should_commit_(false),
- next_request_handle_(1) {
+WebDataService::WebDataService()
+ : thread_(NULL),
+ db_(NULL),
+ failed_init_(false),
+ should_commit_(false),
+ next_request_handle_(1),
+ main_loop_(MessageLoop::current()) {
}
WebDataService::~WebDataService() {
@@ -407,6 +411,14 @@ WebDataService::Handle WebDataService::GetBlacklistLogins(
return request->GetHandle();
}
+void WebDataService::DBInitFailed(sql::InitStatus init_status) {
+ Source<WebDataService> source(this);
+ int message_id = (init_status == sql::INIT_FAILURE) ?
+ IDS_COULDNT_OPEN_PROFILE_ERROR : IDS_PROFILE_TOO_NEW_ERROR;
+ NotificationService::current()->Notify(NotificationType::PROFILE_ERROR,
+ source, Details<int>(&message_id));
+}
+
////////////////////////////////////////////////////////////////////////////////
//
// The following methods are executed in Chrome_WebDataThread.
@@ -433,10 +445,15 @@ void WebDataService::InitializeDatabaseIfNecessary() {
// we only set db_ to the created database if creation is successful. That
// way other methods won't do anything as db_ is still NULL.
WebDatabase* db = new WebDatabase();
- if (!db->Init(path_)) {
+ sql::InitStatus init_status = db->Init(path_);
+ if (init_status != sql::INIT_OK) {
NOTREACHED() << "Cannot initialize the web database";
failed_init_ = true;
delete db;
+ if (main_loop_) {
+ main_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &WebDataService::DBInitFailed, init_status));
+ }
return;
}
diff --git a/chrome/browser/webdata/web_data_service.h b/chrome/browser/webdata/web_data_service.h
index b87803c..3a6c83b 100644
--- a/chrome/browser/webdata/web_data_service.h
+++ b/chrome/browser/webdata/web_data_service.h
@@ -8,6 +8,7 @@
#include <map>
#include <vector>
+#include "app/sql/init_status.h"
#include "base/file_path.h"
#include "base/lock.h"
#include "base/ref_counted.h"
@@ -401,6 +402,11 @@ class WebDataService : public base::RefCountedThreadSafe<WebDataService> {
void RemoveFormValueForElementName(const string16& name,
const string16& value);
+ // Testing
+#ifdef UNIT_TEST
+ void set_failed_init(bool value) { failed_init_ = value; }
+#endif
+
protected:
friend class TemplateURLModelTest;
friend class TemplateURLModelTestingProfile;
@@ -430,6 +436,9 @@ class WebDataService : public base::RefCountedThreadSafe<WebDataService> {
~WebDataService();
+ // Invoked on the main thread if initializing the db fails.
+ void DBInitFailed(sql::InitStatus init_status);
+
// Initialize the database, if it hasn't already been initialized.
void InitializeDatabaseIfNecessary();
@@ -534,6 +543,9 @@ class WebDataService : public base::RefCountedThreadSafe<WebDataService> {
typedef std::map<Handle, WebDataRequest*> RequestMap;
RequestMap pending_requests_;
+ // MessageLoop the WebDataService is created on.
+ MessageLoop* main_loop_;
+
DISALLOW_EVIL_CONSTRUCTORS(WebDataService);
};
diff --git a/chrome/browser/webdata/web_database.cc b/chrome/browser/webdata/web_database.cc
index 41d5e8b..edeb0d6 100644
--- a/chrome/browser/webdata/web_database.cc
+++ b/chrome/browser/webdata/web_database.cc
@@ -136,7 +136,7 @@ void WebDatabase::CommitTransaction() {
db_.CommitTransaction();
}
-bool WebDatabase::Init(const FilePath& db_name) {
+sql::InitStatus WebDatabase::Init(const FilePath& db_name) {
// Set the exceptional sqlite error handler.
db_.set_error_delegate(GetErrorHandlerForWebDb());
@@ -154,19 +154,19 @@ bool WebDatabase::Init(const FilePath& db_name) {
db_.set_exclusive_locking();
if (!db_.Open(db_name))
- return false;
+ return sql::INIT_FAILURE;
// Initialize various tables
sql::Transaction transaction(&db_);
if (!transaction.Begin())
- return false;
+ return sql::INIT_FAILURE;
// Version check.
if (!meta_table_.Init(&db_, kCurrentVersionNumber, kCompatibleVersionNumber))
- return false;
+ return sql::INIT_FAILURE;
if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
LOG(WARNING) << "Web database is too new.";
- return false;
+ return sql::INIT_TOO_NEW;
}
// Initialize the tables.
@@ -174,13 +174,13 @@ bool WebDatabase::Init(const FilePath& db_name) {
!InitWebAppsTable() || !InitAutofillTable() ||
!InitAutofillDatesTable()) {
LOG(WARNING) << "Unable to initialize the web database.";
- return false;
+ return sql::INIT_FAILURE;
}
// If the file on disk is an older database version, bring it up to date.
MigrateOldVersionsAsNeeded();
- return transaction.Commit();
+ return transaction.Commit() ? sql::INIT_OK : sql::INIT_FAILURE;
}
bool WebDatabase::SetWebAppImage(const GURL& url, const SkBitmap& image) {
diff --git a/chrome/browser/webdata/web_database.h b/chrome/browser/webdata/web_database.h
index f5451ab..24bba2d 100644
--- a/chrome/browser/webdata/web_database.h
+++ b/chrome/browser/webdata/web_database.h
@@ -8,6 +8,7 @@
#include <vector>
#include "app/sql/connection.h"
+#include "app/sql/init_status.h"
#include "app/sql/meta_table.h"
#include "chrome/browser/search_engines/template_url.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -40,8 +41,8 @@ class WebDatabase {
~WebDatabase();
// Initialize the database given a name. The name defines where the sqlite
- // file is. If false is returned, no other method should be called.
- bool Init(const FilePath& db_name);
+ // file is. If this returns an error code, no other method should be called.
+ sql::InitStatus Init(const FilePath& db_name);
// Transactions management
void BeginTransaction();
diff --git a/chrome/browser/webdata/web_database_unittest.cc b/chrome/browser/webdata/web_database_unittest.cc
index eb94e4f..ef62933 100644
--- a/chrome/browser/webdata/web_database_unittest.cc
+++ b/chrome/browser/webdata/web_database_unittest.cc
@@ -113,7 +113,7 @@ class WebDatabaseTest : public testing::Test {
TEST_F(WebDatabaseTest, Keywords) {
WebDatabase db;
- ASSERT_TRUE(db.Init(file_));
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_));
TemplateURL template_url;
template_url.set_short_name(L"short_name");
@@ -174,7 +174,7 @@ TEST_F(WebDatabaseTest, Keywords) {
TEST_F(WebDatabaseTest, KeywordMisc) {
WebDatabase db;
- ASSERT_TRUE(db.Init(file_));
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_));
ASSERT_EQ(0, db.GetDefaulSearchProviderID());
ASSERT_EQ(0, db.GetBuitinKeywordVersion());
@@ -189,7 +189,7 @@ TEST_F(WebDatabaseTest, KeywordMisc) {
TEST_F(WebDatabaseTest, UpdateKeyword) {
WebDatabase db;
- ASSERT_TRUE(db.Init(file_));
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_));
TemplateURL template_url;
template_url.set_short_name(L"short_name");
@@ -251,7 +251,7 @@ TEST_F(WebDatabaseTest, UpdateKeyword) {
TEST_F(WebDatabaseTest, KeywordWithNoFavicon) {
WebDatabase db;
- ASSERT_TRUE(db.Init(file_));
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_));
TemplateURL template_url;
template_url.set_short_name(L"short_name");
@@ -278,7 +278,7 @@ TEST_F(WebDatabaseTest, KeywordWithNoFavicon) {
TEST_F(WebDatabaseTest, Logins) {
WebDatabase db;
- ASSERT_TRUE(db.Init(file_));
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_));
std::vector<PasswordForm*> result;
@@ -411,7 +411,7 @@ TEST_F(WebDatabaseTest, Logins) {
TEST_F(WebDatabaseTest, Autofill) {
WebDatabase db;
- ASSERT_TRUE(db.Init(file_));
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_));
Time t1 = Time::Now();
@@ -645,7 +645,7 @@ static void ClearResults(std::vector<PasswordForm*>* results) {
TEST_F(WebDatabaseTest, ClearPrivateData_SavedPasswords) {
WebDatabase db;
- ASSERT_TRUE(db.Init(file_));
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_));
std::vector<PasswordForm*> result;
@@ -687,7 +687,7 @@ TEST_F(WebDatabaseTest, ClearPrivateData_SavedPasswords) {
TEST_F(WebDatabaseTest, BlacklistedLogins) {
WebDatabase db;
- ASSERT_TRUE(db.Init(file_));
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_));
std::vector<PasswordForm*> result;
// Verify the database is empty.
@@ -726,7 +726,7 @@ TEST_F(WebDatabaseTest, BlacklistedLogins) {
TEST_F(WebDatabaseTest, WebAppHasAllImages) {
WebDatabase db;
- ASSERT_TRUE(db.Init(file_));
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_));
GURL url("http://google.com/");
// Initial value for unknown web app should be false.
@@ -744,7 +744,7 @@ TEST_F(WebDatabaseTest, WebAppHasAllImages) {
TEST_F(WebDatabaseTest, WebAppImages) {
WebDatabase db;
- ASSERT_TRUE(db.Init(file_));
+ ASSERT_EQ(sql::INIT_OK, db.Init(file_));
GURL url("http://google.com/");
// Web app should initially have no images.