summaryrefslogtreecommitdiffstats
path: root/chrome/browser/history
diff options
context:
space:
mode:
authorsky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-21 15:20:33 +0000
committersky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-21 15:20:33 +0000
commitf25387b62a3cccde48622d0b7fca57cd6fb16ab7 (patch)
tree06ac2c1972d6608fb65979c3a279a6d214fecc6c /chrome/browser/history
parentbcc682fc4f5050ac911635ab649fbd30002fc2b4 (diff)
downloadchromium_src-f25387b62a3cccde48622d0b7fca57cd6fb16ab7.zip
chromium_src-f25387b62a3cccde48622d0b7fca57cd6fb16ab7.tar.gz
chromium_src-f25387b62a3cccde48622d0b7fca57cd6fb16ab7.tar.bz2
Moves bookmarks out of history into its own file (JSON).
Interesting points: . Migration was a bit atypical. Here is the approach I took: . If the URL db contains bookmarks it writes the bookmarks to a temporary file. . When the bookmark bar model is loaded it assumes bookmarks are stored in a file. If the bookmarks file doesn't exist it then attempts to load from history, after waiting for history to finish processing tasks. . I've broken having the omnibox query for starred only. This patch was already too ginormous for me to contemplate this too. I'll return to it after I land this. . Similarly the history page isn't searching for starred titles now. As we discussed with Glen, that is probably fine for now. . I've converted NOTIFY_STARRED_FAVICON_CHANGED to NOTIFY_FAVICON_CHANGED and it is notified ANY time a favicon changes. I'm mildly concerned about the extra notifications, but without having history know about starred it's the best I can do for now. . Autocomplete (specifically URLDatabase::AutocompleteForPrefix) previously sorted by starred. It can no longer do this. I don't think I can get this functionality back:( Luckily it only mattered if you had a starred and non-starred URL with the same type count that matched a query. Probably pretty rare. What's left: . Fix up HistoryContentsProvider to query for starred entries titles. . Clean up the delete all case. I basically just made it compile; it can be greatly simplified. . Rename BookmarkBarModel to BookmarksModel. BUG=1256202 TEST=this is a huge change to bookmarks. Thanfully it's pretty well covered by tests, none-the-less make sure you exercise bookmarks pretty heavily to make sure nothing is busted. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1153 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/history')
-rw-r--r--chrome/browser/history/archived_database.cc46
-rw-r--r--chrome/browser/history/archived_database.h9
-rw-r--r--chrome/browser/history/expire_history_backend.cc25
-rw-r--r--chrome/browser/history/expire_history_backend.h7
-rw-r--r--chrome/browser/history/expire_history_backend_unittest.cc131
-rw-r--r--chrome/browser/history/history.cc56
-rw-r--r--chrome/browser/history/history.h75
-rw-r--r--chrome/browser/history/history_backend.cc264
-rw-r--r--chrome/browser/history/history_backend.h31
-rw-r--r--chrome/browser/history/history_backend_unittest.cc34
-rw-r--r--chrome/browser/history/history_database.cc24
-rw-r--r--chrome/browser/history/history_database.h11
-rw-r--r--chrome/browser/history/history_marshaling.h16
-rw-r--r--chrome/browser/history/history_notifications.h12
-rw-r--r--chrome/browser/history/history_querying_unittest.cc33
-rw-r--r--chrome/browser/history/history_types.cc3
-rw-r--r--chrome/browser/history/history_types.h45
-rw-r--r--chrome/browser/history/history_unittest.cc73
-rw-r--r--chrome/browser/history/in_memory_history_backend.cc22
-rw-r--r--chrome/browser/history/in_memory_history_backend.h3
-rw-r--r--chrome/browser/history/starred_url_database.cc469
-rw-r--r--chrome/browser/history/starred_url_database.h151
-rw-r--r--chrome/browser/history/starred_url_database_unittest.cc392
-rw-r--r--chrome/browser/history/text_database.h2
-rw-r--r--chrome/browser/history/text_database_manager.h2
-rw-r--r--chrome/browser/history/url_database.cc68
-rw-r--r--chrome/browser/history/url_database.h9
-rw-r--r--chrome/browser/history/url_database_unittest.cc3
28 files changed, 351 insertions, 1665 deletions
diff --git a/chrome/browser/history/archived_database.cc b/chrome/browser/history/archived_database.cc
index 19f6436..40ba38b 100644
--- a/chrome/browser/history/archived_database.cc
+++ b/chrome/browser/history/archived_database.cc
@@ -34,7 +34,7 @@ namespace history {
namespace {
-static const int kDatabaseVersion = 1;
+static const int kCurrentVersionNumber = 2;
} // namespace
@@ -73,15 +73,8 @@ bool ArchivedDatabase::Init(const std::wstring& file_name) {
BeginTransaction();
// Version check.
- if (!meta_table_.Init(std::string(), kDatabaseVersion, db_))
+ if (!meta_table_.Init(std::string(), kCurrentVersionNumber, db_))
return false;
- if (meta_table_.GetCompatibleVersionNumber() > kDatabaseVersion) {
- // We ignore this error and just run without the database. Normally, if
- // the user is running two versions, the main history DB will give a
- // warning about a version from the future.
- LOG(WARNING) << "Archived database is a future version.";
- return false;
- }
// Create the tables.
if (!CreateURLTable(false) || !InitVisitTable() ||
@@ -89,6 +82,9 @@ bool ArchivedDatabase::Init(const std::wstring& file_name) {
return false;
CreateMainURLIndex();
+ if (EnsureCurrentVersion() != INIT_OK)
+ return false;
+
// Succeeded: keep the DB open by detaching the auto-closer.
scoper.Detach();
db_closer_.Attach(&db_, &statement_cache_);
@@ -123,4 +119,36 @@ SqliteStatementCache& ArchivedDatabase::GetStatementCache() {
return *statement_cache_;
}
+// Migration -------------------------------------------------------------------
+
+InitStatus ArchivedDatabase::EnsureCurrentVersion() {
+ // We can't read databases newer than we were designed for.
+ if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber)
+ return INIT_TOO_NEW;
+
+ // NOTICE: If you are changing structures for things shared with the archived
+ // history file like URLs, visits, or downloads, that will need migration as
+ // well. Instead of putting such migration code in this class, it should be
+ // in the corresponding file (url_database.cc, etc.) and called from here and
+ // from the archived_database.cc.
+
+ // When the version is too old, we just try to continue anyway, there should
+ // not be a released product that makes a database too old for us to handle.
+ int cur_version = meta_table_.GetVersionNumber();
+
+ // Put migration code here
+
+ if (cur_version == 1) {
+ if (!DropStarredIDFromURLs())
+ return INIT_FAILURE;
+ cur_version = 2;
+ meta_table_.SetVersionNumber(cur_version);
+ meta_table_.SetCompatibleVersionNumber(cur_version);
+ }
+
+ LOG_IF(WARNING, cur_version < kCurrentVersionNumber) <<
+ "Archived database version " << cur_version << " is too old to handle.";
+
+ return INIT_OK;
+}
} // namespace history
diff --git a/chrome/browser/history/archived_database.h b/chrome/browser/history/archived_database.h
index 985dd35..d6617ff 100644
--- a/chrome/browser/history/archived_database.h
+++ b/chrome/browser/history/archived_database.h
@@ -67,6 +67,15 @@ class ArchivedDatabase : public URLDatabase,
virtual sqlite3* GetDB();
virtual SqliteStatementCache& GetStatementCache();
+ // Makes sure the version is up-to-date, updating if necessary. If the
+ // database is too old to migrate, the user will be notified. In this case, or
+ // for other errors, false will be returned. True means it is up-to-date and
+ // ready for use.
+ //
+ // 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();
+
// The database.
//
// The close scoper will free the database and delete the statement cache in
diff --git a/chrome/browser/history/expire_history_backend.cc b/chrome/browser/history/expire_history_backend.cc
index ba42e07..e8065ff 100644
--- a/chrome/browser/history/expire_history_backend.cc
+++ b/chrome/browser/history/expire_history_backend.cc
@@ -124,8 +124,8 @@ void ExpireHistoryBackend::DeleteURL(const GURL& url) {
text_db_->DeleteURLFromUncommitted(url);
// Collect all the visits and delete them. Note that we don't give up if
- // there are no visits, since the URL could still have an entry (for example,
- // if it's starred) that we should delete.
+ // there are no visits, since the URL could still have an entry that we should
+ // delete.
// TODO(brettw): bug 1171148: We should also delete from the archived DB.
VisitVector visits;
main_db_->GetVisitsForURL(url_row.id(), &visits);
@@ -205,14 +205,6 @@ void ExpireHistoryBackend::DeleteFaviconsIfPossible(
void ExpireHistoryBackend::BroadcastDeleteNotifications(
DeleteDependencies* dependencies) {
- // Broadcast the "unstarred" notification.
- if (!dependencies->unstarred_urls.empty()) {
- URLsStarredDetails* unstarred_details = new URLsStarredDetails(false);
- unstarred_details->changed_urls.swap(dependencies->unstarred_urls);
- unstarred_details->star_entries.swap(dependencies->unstarred_entries);
- delegate_->BroadcastNotifications(NOTIFY_URLS_STARRED, unstarred_details);
- }
-
if (!dependencies->deleted_urls.empty()) {
// Broadcast the URL deleted notification. Note that we also broadcast when
// we were requested to delete everything even if that was a NOP, since
@@ -284,15 +276,6 @@ void ExpireHistoryBackend::DeleteOneURL(
thumb_db_->DeleteThumbnail(url_row.id());
main_db_->DeleteSegmentForURL(url_row.id());
- // The starred table may need to have its corresponding item deleted.
- if (url_row.star_id()) {
- // Note that this will update the URLRow's starred field, but our variable
- // won't be updated correspondingly.
- main_db_->DeleteStarredEntry(url_row.star_id(),
- &dependencies->unstarred_urls,
- &dependencies->unstarred_entries);
- }
-
// Collect shared information.
if (url_row.favicon_id())
dependencies->affected_favicons.insert(url_row.favicon_id());
@@ -362,8 +345,8 @@ void ExpireHistoryBackend::ExpireURLsForVisits(
else
url_row.set_last_visit(Time());
- // Don't delete starred URLs or ones with visits still in the DB.
- if (url_row.starred() || !url_row.last_visit().is_null()) {
+ // Don't delete URLs with visits still in the DB.
+ if (!url_row.last_visit().is_null()) {
// We're not deleting the URL, update its counts when we're deleting those
// visits.
// NOTE: The calls to std::max() below are a backstop, but they should
diff --git a/chrome/browser/history/expire_history_backend.h b/chrome/browser/history/expire_history_backend.h
index 4862f9a..0ed5676 100644
--- a/chrome/browser/history/expire_history_backend.h
+++ b/chrome/browser/history/expire_history_backend.h
@@ -81,8 +81,7 @@ class ExpireHistoryBackend {
// will continue until the object is deleted.
void StartArchivingOldStuff(TimeDelta expiration_threshold);
- // Deletes everything associated with a URL, regardless of whether it is
- // starred or not.
+ // Deletes everything associated with a URL.
void DeleteURL(const GURL& url);
// Removes all visits in the given time range, updating the URLs accordingly.
@@ -128,10 +127,6 @@ class ExpireHistoryBackend {
// that we will need to check when the delete operations are complete.
std::set<FavIconID> affected_favicons;
- // URLs that were unstarred as a result of the delete.
- std::set<GURL> unstarred_urls;
- std::vector<StarredEntry> unstarred_entries;
-
// Tracks the set of databases that have changed so we can optimize when
// when we're done.
TextDatabaseManager::ChangeSet text_db_changes;
diff --git a/chrome/browser/history/expire_history_backend_unittest.cc b/chrome/browser/history/expire_history_backend_unittest.cc
index 0cd12da..28d90ab 100644
--- a/chrome/browser/history/expire_history_backend_unittest.cc
+++ b/chrome/browser/history/expire_history_backend_unittest.cc
@@ -111,7 +111,7 @@ class ExpireHistoryTest : public testing::Test,
std::wstring history_name(dir_);
file_util::AppendToPath(&history_name, L"History");
main_db_.reset(new HistoryDatabase);
- if (main_db_->Init(history_name) != INIT_OK)
+ if (main_db_->Init(history_name, std::wstring()) != INIT_OK)
main_db_.reset();
std::wstring archived_name(dir_);
@@ -460,32 +460,6 @@ TEST_F(ExpireHistoryTest, DeleteURLWithoutFavicon) {
EXPECT_TRUE(HasFavIcon(last_row.favicon_id()));
}
-// DeletdeURL should delete URLs that are starred.
-TEST_F(ExpireHistoryTest, DeleteStarredURL) {
- URLID url_ids[3];
- Time visit_times[4];
- AddExampleData(url_ids, visit_times);
-
- URLRow url_row;
- ASSERT_TRUE(main_db_->GetURLRow(url_ids[2], &url_row));
-
- // Star the last URL.
- StarredEntry starred;
- starred.type = StarredEntry::URL;
- starred.url = url_row.url();
- starred.url_id = url_row.id();
- starred.parent_group_id = HistoryService::kBookmarkBarID;
- ASSERT_TRUE(main_db_->CreateStarredEntry(&starred));
- ASSERT_TRUE(main_db_->GetURLRow(url_ids[2], &url_row));
-
- // Now delete it, this should delete it even though it's starred.
- expirer_.DeleteURL(url_row.url());
-
- // All the normal data + the favicon should be gone.
- EnsureURLInfoGone(url_row);
- EXPECT_FALSE(HasFavIcon(url_row.favicon_id()));
-}
-
// Expires all URLs more recent than a given time, with no starred items.
// Our time threshold is such that one URL should be updated (we delete one of
// the two visits) and one is deleted.
@@ -540,62 +514,6 @@ TEST_F(ExpireHistoryTest, FlushRecentURLsUnstarred) {
EXPECT_FALSE(HasFavIcon(url_row2.favicon_id()));
}
-// Expire a starred URL, it shouldn't get deleted and its visit counts should
-// be updated properly.
-TEST_F(ExpireHistoryTest, FlushRecentURLsStarred) {
- URLID url_ids[3];
- Time visit_times[4];
- AddExampleData(url_ids, visit_times);
-
- URLRow url_row1, url_row2;
- ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &url_row1));
- ASSERT_TRUE(main_db_->GetURLRow(url_ids[2], &url_row2));
-
- // Star the last two URLs.
- StarredEntry starred1;
- starred1.type = StarredEntry::URL;
- starred1.url = url_row1.url();
- starred1.url_id = url_row1.id();
- starred1.parent_group_id = HistoryService::kBookmarkBarID;
- ASSERT_TRUE(main_db_->CreateStarredEntry(&starred1));
- ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &url_row1));
-
- StarredEntry starred2;
- starred2.type = StarredEntry::URL;
- starred2.url = url_row2.url();
- starred2.url_id = url_row2.id();
- starred2.parent_group_id = HistoryService::kBookmarkBarID;
- ASSERT_TRUE(main_db_->CreateStarredEntry(&starred2));
- ASSERT_TRUE(main_db_->GetURLRow(url_ids[2], &url_row2));
-
- // This should delete the last two visits.
- expirer_.ExpireHistoryBetween(visit_times[2], Time());
-
- // The URL rows should still exist.
- URLRow new_url_row1, new_url_row2;
- ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &new_url_row1));
- ASSERT_TRUE(main_db_->GetURLRow(url_ids[2], &new_url_row2));
-
- // The visit times should be updated.
- EXPECT_TRUE(new_url_row1.last_visit() == visit_times[1]);
- EXPECT_TRUE(new_url_row2.last_visit().is_null()); // No last visit time.
-
- // Visit counts should be updated.
- EXPECT_EQ(0, new_url_row1.typed_count());
- EXPECT_EQ(1, new_url_row1.visit_count());
- EXPECT_EQ(0, new_url_row2.typed_count());
- EXPECT_EQ(0, new_url_row2.visit_count());
-
- // Thumbnails and favicons should still exist. Note that we keep thumbnails
- // that may have been updated since the time threshold. Since the URL still
- // exists in history, this should not be a privacy problem, we only update
- // the visit counts in this case for consistency anyway.
- EXPECT_TRUE(HasFavIcon(new_url_row1.favicon_id()));
- EXPECT_TRUE(HasThumbnail(new_url_row1.id()));
- EXPECT_TRUE(HasFavIcon(new_url_row2.favicon_id()));
- EXPECT_TRUE(HasThumbnail(new_url_row2.id()));
-}
-
TEST_F(ExpireHistoryTest, ArchiveHistoryBeforeUnstarred) {
URLID url_ids[3];
Time visit_times[4];
@@ -634,53 +552,6 @@ TEST_F(ExpireHistoryTest, ArchiveHistoryBeforeUnstarred) {
EXPECT_EQ(1, archived_visits.size());
}
-TEST_F(ExpireHistoryTest, ArchiveHistoryBeforeStarred) {
- URLID url_ids[3];
- Time visit_times[4];
- AddExampleData(url_ids, visit_times);
-
- URLRow url_row0, url_row1;
- ASSERT_TRUE(main_db_->GetURLRow(url_ids[0], &url_row0));
- ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &url_row1));
-
- // Star the URLs. We use fake star IDs here, but that doesn't matter.
- url_row0.set_star_id(1);
- main_db_->UpdateURLRow(url_row0.id(), url_row0);
- url_row1.set_star_id(2);
- main_db_->UpdateURLRow(url_row1.id(), url_row1);
-
- // Now archive the first three visits (first two URLs). The first two visits
- // should be, the thirddeleted, but the URL records should not.
- expirer_.ArchiveHistoryBefore(visit_times[2]);
-
- // The first URL should have its visit deleted, but it should still be present
- // in the main DB and not in the archived one since it is starred.
- URLRow temp_row;
- ASSERT_TRUE(main_db_->GetURLRow(url_ids[0], &temp_row));
- // Note that the ID is different in the archived DB, so look up by URL.
- EXPECT_FALSE(archived_db_->GetRowForURL(temp_row.url(), NULL));
- VisitVector visits;
- main_db_->GetVisitsForURL(temp_row.id(), &visits);
- EXPECT_EQ(0, visits.size());
-
- // The second URL should have its first visit deleted and its second visit
- // archived. It should be present in both the main DB (because it's starred)
- // and the archived DB (for the archived visit).
- ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &temp_row));
- main_db_->GetVisitsForURL(temp_row.id(), &visits);
- EXPECT_EQ(0, visits.size());
-
- // Note that the ID is different in the archived DB, so look up by URL.
- ASSERT_TRUE(archived_db_->GetRowForURL(temp_row.url(), &temp_row));
- archived_db_->GetVisitsForURL(temp_row.id(), &visits);
- ASSERT_EQ(1, visits.size());
- EXPECT_TRUE(visit_times[2] == visits[0].visit_time);
-
- // The third URL should be unchanged.
- EXPECT_TRUE(main_db_->GetURLRow(url_ids[2], &temp_row));
- EXPECT_FALSE(archived_db_->GetRowForURL(temp_row.url(), NULL));
-}
-
// Tests the return values from ArchiveSomeOldHistory. The rest of the
// functionality of this function is tested by the ArchiveHistoryBefore*
// tests which use this function internally.
diff --git a/chrome/browser/history/history.cc b/chrome/browser/history/history.cc
index d4e6879..bebc348 100644
--- a/chrome/browser/history/history.cc
+++ b/chrome/browser/history/history.cc
@@ -241,6 +241,13 @@ HistoryService::Handle HistoryService::ScheduleDBTask(
request);
}
+HistoryService::Handle HistoryService::ScheduleEmptyCallback(
+ CancelableRequestConsumerBase* consumer,
+ EmptyHistoryCallback* callback) {
+ return Schedule(PRIORITY_UI, &HistoryBackend::ProcessEmptyRequest,
+ consumer, new history::EmptyHistoryRequest(callback));
+}
+
HistoryService::Handle HistoryService::QuerySegmentUsageSince(
CancelableRequestConsumerBase* consumer,
const Time from_time,
@@ -435,55 +442,6 @@ void HistoryService::SetImportedFavicons(
&HistoryBackend::SetImportedFavicons, favicon_usage);
}
-HistoryService::Handle HistoryService::GetAllStarredEntries(
- CancelableRequestConsumerBase* consumer,
- GetStarredEntriesCallback* callback) {
- return Schedule(PRIORITY_UI, &HistoryBackend::GetAllStarredEntries,
- consumer,
- new history::GetStarredEntriesRequest(callback));
-}
-
-void HistoryService::UpdateStarredEntry(const history::StarredEntry& entry) {
- ScheduleAndForget(PRIORITY_UI, &HistoryBackend::UpdateStarredEntry, entry);
-}
-
-HistoryService::Handle HistoryService::CreateStarredEntry(
- const history::StarredEntry& entry,
- CancelableRequestConsumerBase* consumer,
- CreateStarredEntryCallback* callback) {
- DCHECK(entry.type != history::StarredEntry::BOOKMARK_BAR &&
- entry.type != history::StarredEntry::OTHER);
- if (!consumer) {
- ScheduleTask(PRIORITY_UI,
- NewRunnableMethod(history_backend_.get(),
- &HistoryBackend::CreateStarredEntry,
- scoped_refptr<history::CreateStarredEntryRequest>(),
- entry));
- return 0;
- }
- return Schedule(PRIORITY_UI, &HistoryBackend::CreateStarredEntry, consumer,
- new history::CreateStarredEntryRequest(callback), entry);
-}
-
-void HistoryService::DeleteStarredGroup(history::UIStarID group_id) {
- ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::DeleteStarredGroup,
- group_id);
-}
-
-void HistoryService::DeleteStarredURL(const GURL& url) {
- ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::DeleteStarredURL, url);
-}
-
-HistoryService::Handle HistoryService::GetMostRecentStarredEntries(
- int max_count,
- CancelableRequestConsumerBase* consumer,
- GetMostRecentStarredEntriesCallback* callback) {
- return Schedule(PRIORITY_UI, &HistoryBackend::GetMostRecentStarredEntries,
- consumer,
- new history::GetMostRecentStarredEntriesRequest(callback),
- max_count);
-}
-
void HistoryService::IterateURLs(URLEnumerator* enumerator) {
ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::IterateURLs, enumerator);
}
diff --git a/chrome/browser/history/history.h b/chrome/browser/history/history.h
index 9dca73a..3db1e23 100644
--- a/chrome/browser/history/history.h
+++ b/chrome/browser/history/history.h
@@ -393,29 +393,6 @@ class HistoryService : public CancelableRequestProvider,
void SetImportedFavicons(
const std::vector<history::ImportedFavIconUsage>& favicon_usage);
- // Starring ------------------------------------------------------------------
-
- // Starring mutation methods are private, go through the BookmarkBarModel
- // instead.
- //
- // The typedefs are public to allow template magic to work.
-
- typedef Callback2<Handle, std::vector<history::StarredEntry>* >::Type
- GetStarredEntriesCallback;
-
- typedef Callback2<Handle, history::StarID>::Type CreateStarredEntryCallback;
-
- typedef Callback2<Handle, std::vector<history::StarredEntry>* >::Type
- GetMostRecentStarredEntriesCallback;
-
- // Fetches up to max_count starred entries of type URL.
- // The results are ordered by date added in descending order (most recent
- // first).
- Handle GetMostRecentStarredEntries(
- int max_count,
- CancelableRequestConsumerBase* consumer,
- GetMostRecentStarredEntriesCallback* callback);
-
// Database management operations --------------------------------------------
// Delete all the information related to a single url.
@@ -544,6 +521,13 @@ class HistoryService : public CancelableRequestProvider,
Handle ScheduleDBTask(HistoryDBTask* task,
CancelableRequestConsumerBase* consumer);
+ typedef Callback1<Handle>::Type EmptyHistoryCallback;
+
+ // Schedules a task that does nothing on the backend. This can be used to get
+ // notification when then history backend is done processing requests.
+ Handle ScheduleEmptyCallback(CancelableRequestConsumerBase* consumer,
+ EmptyHistoryCallback* callback);
+
// Testing -------------------------------------------------------------------
// Designed for unit tests, this passes the given task on to the history
@@ -597,51 +581,6 @@ class HistoryService : public CancelableRequestProvider,
friend class HistoryOperation;
friend class HistoryURLProviderTest;
- // Starring ------------------------------------------------------------------
-
- // These are private as they should only be invoked from the bookmark bar
- // model.
-
- // Fetches all the starred entries (both groups and entries).
- Handle GetAllStarredEntries(
- CancelableRequestConsumerBase* consumer,
- GetStarredEntriesCallback* callback);
-
- // Updates the title, parent and visual order of the specified entry. The key
- // used to identify the entry is NOT entry.id, rather it is the url (if the
- // type is URL), or the group_id (if the type is other than URL).
- //
- // This can NOT be used to change the type of an entry.
- //
- // After updating the entry, NOTIFY_STAR_ENTRY_CHANGED is sent.
- void UpdateStarredEntry(const history::StarredEntry& entry);
-
- // Creates a starred entry at the specified position. This can be used
- // for creating groups and nodes.
- //
- // If the entry is a URL and the URL is already starred, this behaves the
- // same as invoking UpdateStarredEntry. If the entry is a URL and the URL is
- // not starred, the URL is starred appropriately.
- //
- // This honors the title, parent_group_id, visual_order and url (for URL
- // nodes) of the specified entry. All other attributes are ignored.
- //
- // NOTE: consumer and callback may be null, in which case the request
- // isn't cancelable and 0 is returned.
- Handle CreateStarredEntry(const history::StarredEntry& entry,
- CancelableRequestConsumerBase* consumer,
- CreateStarredEntryCallback* callback);
-
- // Deletes the specified starred group. All children groups are deleted and
- // starred descendants unstarred. If successful, this sends out the
- // notification NOTIFY_URLS_STARRED. To delete a starred URL, do
- // DeletedStarredEntry(id).
- void DeleteStarredGroup(history::UIStarID group_id);
-
- // Deletes the specified starred URL. If successful, this sends out the
- // notification NOTIFY_URLS_STARRED.
- void DeleteStarredURL(const GURL& url);
-
// Implementation of NotificationObserver.
virtual void Observe(NotificationType type,
const NotificationSource& source,
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc
index d9ef224..88e40ed 100644
--- a/chrome/browser/history/history_backend.cc
+++ b/chrome/browser/history/history_backend.cc
@@ -268,10 +268,13 @@ void HistoryBackend::Init() {
file_util::AppendToPath(&history_name, chrome::kHistoryFilename);
std::wstring thumbnail_name = GetThumbnailFileName();
std::wstring archived_name = GetArchivedFileName();
+ std::wstring tmp_bookmarks_file = history_dir_;
+ file_util::AppendToPath(&tmp_bookmarks_file,
+ chrome::kHistoryBookmarksFileName);
// History database.
db_.reset(new HistoryDatabase());
- switch (db_->Init(history_name)) {
+ switch (db_->Init(history_name, tmp_bookmarks_file)) {
case INIT_OK:
break;
case INIT_FAILURE:
@@ -995,16 +998,6 @@ void HistoryBackend::QueryHistory(scoped_refptr<QueryHistoryRequest> request,
if (db_.get()) {
if (text_query.empty()) {
- if (options.begin_time.is_null() && options.end_time.is_null() &&
- options.only_starred && options.max_count == 0) {
- DLOG(WARNING) << "Querying for all bookmarks. You should probably use "
- "the dedicated starring functions which will also report unvisited "
- "bookmarks and will be faster.";
- // If this case is needed and the starring functions aren't right, we
- // can optimize the case where we're just querying for starred URLs
- // and remove the warning.
- }
-
// Basic history query for the main database.
QueryHistoryBasic(db_.get(), db_.get(), options, &request->value);
@@ -1060,14 +1053,8 @@ void HistoryBackend::QueryHistoryBasic(URLDatabase* url_db,
// catch any interesting stuff. This will update it if it exists in the
// main DB, and do nothing otherwise.
db_->GetRowForURL(url_result.url(), &url_result);
- } else {
- // URLs not in the main DB can't be starred, reset this just in case.
- url_result.set_star_id(0);
}
- if (!url_result.starred() && options.only_starred)
- continue; // Want non-starred items filtered out.
-
url_result.set_visit_time(visit.visit_time);
// We don't set any of the query-specific parts of the URLResult, since
@@ -1076,62 +1063,6 @@ void HistoryBackend::QueryHistoryBasic(URLDatabase* url_db,
}
}
-void HistoryBackend::QueryStarredEntriesByText(
- URLQuerier* querier,
- const std::wstring& text_query,
- const QueryOptions& options,
- QueryResults* results) {
- // Collect our prepends so we can bulk add them at the end. It is more
- // efficient to bluk prepend the URLs than to do one at a time.
- QueryResults our_results;
-
- // We can use only the main DB (not archived) for this operation since we know
- // that all currently starred URLs will be in the main DB.
- std::set<URLID> ids;
- db_->GetURLsForTitlesMatching(text_query, &ids);
-
- VisitRow visit;
- PageVisit page_visit;
- URLResult url_result;
- for (std::set<URLID>::iterator i = ids.begin(); i != ids.end(); ++i) {
- // Turn the ID (associated with the main DB) into a visit row.
- if (!db_->GetURLRow(*i, &url_result))
- continue; // Not found, some crazy error.
-
- // Make sure we haven't already reported this URL and don't add it if so.
- if (querier->HasURL(url_result.url()))
- continue;
-
- // Consistency check, all URLs should be valid and starred.
- if (!url_result.url().is_valid() || !url_result.starred())
- continue;
-
- db_->GetStarredEntry(url_result.star_id(), &url_result.starred_entry_);
-
- // Use the last visit time as the visit time for this result.
- // TODO(brettw) when we are not querying for the most recent visit only,
- // we should get all the visits in the time range for the given URL and add
- // separate results for each of them. Until then, just treat as unique:
- //
- // Just add this one visit for the last time they visited it, except for
- // starred only queries which have no visit times.
- if (options.only_starred) {
- url_result.set_visit_time(Time());
- } else {
- url_result.set_visit_time(url_result.last_visit());
- }
- our_results.AppendURLBySwapping(&url_result);
- }
-
- // Now prepend all of the bookmark matches we found. We do this by appending
- // the old values to the new ones and swapping the results.
- if (our_results.size() > 0) {
- our_results.AppendResultsBySwapping(results,
- options.most_recent_visit_only);
- our_results.Swap(results);
- }
-}
-
void HistoryBackend::QueryHistoryFTS(const std::wstring& text_query,
const QueryOptions& options,
QueryResults* result) {
@@ -1162,8 +1093,6 @@ void HistoryBackend::QueryHistoryFTS(const std::wstring& text_query,
if (!url_result.url().is_valid())
continue; // Don't report invalid URLs in case of corruption.
- if (options.only_starred && !url_result.star_id())
- continue; // Don't add this unstarred item.
// Copy over the FTS stuff that the URLDatabase doesn't know about.
// We do this with swap() to avoid copying, since we know we don't
@@ -1179,21 +1108,10 @@ void HistoryBackend::QueryHistoryFTS(const std::wstring& text_query,
// has the time, we can avoid an extra query of the visits table.
url_result.set_visit_time(fts_matches[i].time);
- if (options.only_starred) {
- // When querying for starred pages fetch the starred entry.
- DCHECK(url_result.star_id());
- db_->GetStarredEntry(url_result.star_id(), &url_result.starred_entry_);
- } else {
- url_result.ResetStarredEntry();
- }
-
// Add it to the vector, this will clear our |url_row| object as a
// result of the swap.
result->AppendURLBySwapping(&url_result);
}
-
- if (options.include_all_starred)
- QueryStarredEntriesByText(&querier, text_query, options, result);
}
// Frontend to GetMostRecentRedirectsFrom from the history thread.
@@ -1399,7 +1317,7 @@ void HistoryBackend::SetImportedFavicons(
Time now = Time::Now();
// Track all starred URLs that had their favicons set or updated.
- std::set<GURL> starred_favicons_changed;
+ std::set<GURL> favicons_changed;
for (size_t i = 0; i < favicon_usage.size(); i++) {
FavIconID favicon_id = thumbnail_db_->GetFavIconIDForFavIconURL(
@@ -1422,16 +1340,15 @@ void HistoryBackend::SetImportedFavicons(
url_row.set_favicon_id(favicon_id);
db_->UpdateURLRow(url_row.id(), url_row);
- if (url_row.starred())
- starred_favicons_changed.insert(*url);
+ favicons_changed.insert(*url);
}
}
- if (!starred_favicons_changed.empty()) {
+ if (!favicons_changed.empty()) {
// Send the notification about the changed favicons for starred URLs.
FavIconChangeDetails* changed_details = new FavIconChangeDetails;
- changed_details->urls.swap(starred_favicons_changed);
- BroadcastNotifications(NOTIFY_STARRED_FAVICON_CHANGED, changed_details);
+ changed_details->urls.swap(favicons_changed);
+ BroadcastNotifications(NOTIFY_FAVICON_CHANGED, changed_details);
}
}
@@ -1544,7 +1461,7 @@ void HistoryBackend::SetFavIconMapping(const GURL& page_url,
redirects = &dummy_list;
}
- std::set<GURL> starred_favicons_changed;
+ std::set<GURL> favicons_changed;
// Save page <-> favicon association.
for (HistoryService::RedirectList::const_iterator i(redirects->begin());
@@ -1569,147 +1486,15 @@ void HistoryBackend::SetFavIconMapping(const GURL& page_url,
thumbnail_db_->DeleteFavIcon(old_id);
}
- if (row.starred())
- starred_favicons_changed.insert(row.url());
- }
-
- if (!starred_favicons_changed.empty()) {
- // Send the notification about the changed favicons for starred URLs.
- FavIconChangeDetails* changed_details = new FavIconChangeDetails;
- changed_details->urls.swap(starred_favicons_changed);
- BroadcastNotifications(NOTIFY_STARRED_FAVICON_CHANGED, changed_details);
- }
-
- ScheduleCommit();
-}
-
-void HistoryBackend::GetAllStarredEntries(
- scoped_refptr<GetStarredEntriesRequest> request) {
- if (request->canceled())
- return;
- // Only query for the entries if the starred table is valid. If the starred
- // table isn't valid, we may get back garbage which could cause the UI grief.
- //
- // TODO(sky): bug 1207654: this is temporary, the UI should really query for
- // valid state than avoid GetAllStarredEntries if not valid.
- if (db_.get() && db_->is_starred_valid())
- db_->GetStarredEntries(0, &(request->value));
- request->ForwardResult(
- GetStarredEntriesRequest::TupleType(request->handle(),
- &(request->value)));
-}
-
-void HistoryBackend::UpdateStarredEntry(const StarredEntry& new_entry) {
- if (!db_.get())
- return;
-
- StarredEntry resulting_entry = new_entry;
- if (!db_->UpdateStarredEntry(&resulting_entry) || !delegate_.get())
- return;
-
- ScheduleCommit();
-
- // Send out notification that the star entry changed.
- StarredEntryDetails* entry_details = new StarredEntryDetails();
- entry_details->entry = resulting_entry;
- BroadcastNotifications(NOTIFY_STAR_ENTRY_CHANGED, entry_details);
-}
-
-void HistoryBackend::CreateStarredEntry(
- scoped_refptr<CreateStarredEntryRequest> request,
- const StarredEntry& entry) {
- // This method explicitly allows request to be NULL.
- if (request.get() && request->canceled())
- return;
-
- StarID id = 0;
- StarredEntry resulting_entry(entry);
- if (db_.get()) {
- if (entry.type == StarredEntry::USER_GROUP) {
- id = db_->CreateStarredEntry(&resulting_entry);
- if (id) {
- // Broadcast group created notifications.
- StarredEntryDetails* entry_details = new StarredEntryDetails;
- entry_details->entry = resulting_entry;
- BroadcastNotifications(NOTIFY_STAR_GROUP_CREATED, entry_details);
- }
- } else if (entry.type == StarredEntry::URL) {
- // Currently, we only allow one starred entry for this URL. Therefore, we
- // check for an existing starred entry for this URL and update it if it
- // exists.
- if (!db_->GetStarIDForEntry(resulting_entry)) {
- // Adding a new starred URL.
- id = db_->CreateStarredEntry(&resulting_entry);
-
- // Broadcast starred notification.
- URLsStarredDetails* details = new URLsStarredDetails(true);
- details->changed_urls.insert(resulting_entry.url);
- details->star_entries.push_back(resulting_entry);
- BroadcastNotifications(NOTIFY_URLS_STARRED, details);
- } else {
- // Updating an existing one.
- db_->UpdateStarredEntry(&resulting_entry);
-
- // Broadcast starred update notification.
- StarredEntryDetails* entry_details = new StarredEntryDetails;
- entry_details->entry = resulting_entry;
- BroadcastNotifications(NOTIFY_STAR_ENTRY_CHANGED, entry_details);
- }
- } else {
- NOTREACHED();
- }
- }
-
- ScheduleCommit();
-
- if (request.get()) {
- request->ForwardResult(
- CreateStarredEntryRequest::TupleType(request->handle(), id));
+ favicons_changed.insert(row.url());
}
-}
-void HistoryBackend::DeleteStarredGroup(UIStarID group_id) {
- if (!db_.get())
- return;
-
- DeleteStarredEntry(db_->GetStarIDForGroupID(group_id));
-}
-
-void HistoryBackend::DeleteStarredURL(const GURL& url) {
- if (!db_.get())
- return;
-
- history::StarredEntry entry;
- entry.url = url;
- DeleteStarredEntry(db_->GetStarIDForEntry(entry));
-}
-
-void HistoryBackend::DeleteStarredEntry(history::StarID star_id) {
- if (!star_id) {
- NOTREACHED() << "Deleting a nonexistent entry";
- return;
- }
-
- // Delete the entry.
- URLsStarredDetails* details = new URLsStarredDetails(false);
- db_->DeleteStarredEntry(star_id, &details->changed_urls,
- &details->star_entries);
+ // Send the notification about the changed favicons.
+ FavIconChangeDetails* changed_details = new FavIconChangeDetails;
+ changed_details->urls.swap(favicons_changed);
+ BroadcastNotifications(NOTIFY_FAVICON_CHANGED, changed_details);
ScheduleCommit();
-
- BroadcastNotifications(NOTIFY_URLS_STARRED, details);
-}
-
-void HistoryBackend::GetMostRecentStarredEntries(
- scoped_refptr<GetMostRecentStarredEntriesRequest> request,
- int max_count) {
- if (request->canceled())
- return;
- if (db_.get())
- db_->GetMostRecentStarredEntries(max_count, &(request->value));
- request->ForwardResult(
- GetMostRecentStarredEntriesRequest::TupleType(request->handle(),
- &(request->value)));
}
void HistoryBackend::Commit() {
@@ -1859,6 +1644,11 @@ void HistoryBackend::ProcessDBTask(
}
}
+void HistoryBackend::ProcessEmptyRequest(
+ scoped_refptr<EmptyHistoryRequest> request) {
+ request->ForwardResult(EmptyHistoryRequest::TupleType());
+}
+
void HistoryBackend::BroadcastNotifications(
NotificationType type,
HistoryDetails* details_deleted) {
@@ -1887,7 +1677,6 @@ void HistoryBackend::DeleteAllHistory() {
// Get starred entries and their corresponding URL rows.
std::vector<StarredEntry> starred_entries;
- db_->GetStarredEntries(0, &starred_entries);
std::vector<URLRow> kept_urls;
for (size_t i = 0; i < starred_entries.size(); i++) {
@@ -2032,19 +1821,6 @@ bool HistoryBackend::ClearAllMainHistory(
if (!db_->CommitTemporaryURLTable())
return false;
- // The starred table references the old URL IDs. We need to fix it up to refer
- // to the new ones.
- for (std::vector<StarredEntry>::iterator i = starred_entries->begin();
- i != starred_entries->end();
- ++i) {
- if (i->type != StarredEntry::URL)
- continue;
-
- DCHECK(old_to_new.find(i->url_id) != old_to_new.end());
- i->url_id = old_to_new[i->url_id];
- db_->UpdateURLIDForStar(i->id, i->url_id);
- }
-
// Delete the old tables and recreate them empty.
db_->RecreateAllButStarAndURLTables();
diff --git a/chrome/browser/history/history_backend.h b/chrome/browser/history/history_backend.h
index c1136de..f73e653 100644
--- a/chrome/browser/history/history_backend.h
+++ b/chrome/browser/history/history_backend.h
@@ -205,26 +205,6 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
void SetImportedFavicons(
const std::vector<ImportedFavIconUsage>& favicon_usage);
- // Starring ------------------------------------------------------------------
-
- void GetAllStarredEntries(
- scoped_refptr<GetStarredEntriesRequest> request);
-
- void UpdateStarredEntry(const StarredEntry& new_entry);
-
- void CreateStarredEntry(scoped_refptr<CreateStarredEntryRequest> request,
- const StarredEntry& entry);
-
- void DeleteStarredGroup(UIStarID group_id);
-
- void DeleteStarredURL(const GURL& url);
-
- void DeleteStarredEntry(history::StarID star_id);
-
- void GetMostRecentStarredEntries(
- scoped_refptr<GetMostRecentStarredEntriesRequest> request,
- int max_count);
-
// Downloads -----------------------------------------------------------------
void QueryDownloads(scoped_refptr<DownloadQueryRequest> request);
@@ -263,6 +243,8 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
void ProcessDBTask(scoped_refptr<HistoryDBTaskRequest> request);
+ void ProcessEmptyRequest(scoped_refptr<EmptyHistoryRequest> request);
+
// Deleting ------------------------------------------------------------------
void DeleteURL(const GURL& url);
@@ -338,15 +320,6 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
const QueryOptions& options,
QueryResults* result);
- // Queries the starred database for all URL entries whose title contains the
- // specified text. This is called as necessary from QueryHistoryFTS. The
- // matches will be added to the beginning of the result vector in no
- // particular order.
- void QueryStarredEntriesByText(URLQuerier* querier,
- const std::wstring& text_query,
- const QueryOptions& options,
- QueryResults* results);
-
// Committing ----------------------------------------------------------------
// We always keep a transaction open on the history database so that multiple
diff --git a/chrome/browser/history/history_backend_unittest.cc b/chrome/browser/history/history_backend_unittest.cc
index e1e6ffe..68bfc19 100644
--- a/chrome/browser/history/history_backend_unittest.cc
+++ b/chrome/browser/history/history_backend_unittest.cc
@@ -205,14 +205,6 @@ TEST_F(HistoryBackendTest, DeleteAll) {
JPEGCodec::Decode(kWeewarThumbnail, sizeof(kWeewarThumbnail)));
backend_->thumbnail_db_->SetPageThumbnail(row2_id, *weewar_bitmap, score);
- // Mark one of the URLs bookmarked.
- StarredEntry entry;
- entry.type = StarredEntry::URL;
- entry.url = row1.url();
- entry.parent_group_id = HistoryService::kBookmarkBarID;
- StarID star_id = backend_->db_->CreateStarredEntry(&entry);
- ASSERT_TRUE(star_id);
-
// Set full text index for each one.
backend_->text_database_->AddPageData(row1.url(), row1_id, visit1_id,
row1.last_visit(),
@@ -224,12 +216,8 @@ TEST_F(HistoryBackendTest, DeleteAll) {
// Now finally clear all history.
backend_->DeleteAllHistory();
- // The first URL should be preserved, along with its visits, but the time
- // should be cleared.
- EXPECT_TRUE(backend_->db_->GetRowForURL(row1.url(), &outrow1));
- EXPECT_EQ(2, outrow1.visit_count());
- EXPECT_EQ(1, outrow1.typed_count());
- EXPECT_TRUE(Time() == outrow1.last_visit());
+ // The first URL should be deleted.
+ EXPECT_FALSE(backend_->db_->GetRowForURL(row1.url(), &outrow1));
// The second row should be deleted.
URLRow outrow2;
@@ -246,27 +234,15 @@ TEST_F(HistoryBackendTest, DeleteAll) {
&out_data));
EXPECT_FALSE(backend_->thumbnail_db_->GetPageThumbnail(row2_id, &out_data));
- // We should have a favicon for the first URL only. We look them up by favicon
- // URL since the IDs may hav changed.
+ // Make sure the favicons were deleted.
+ // TODO(sky): would be nice if this didn't happen.
FavIconID out_favicon1 = backend_->thumbnail_db_->
GetFavIconIDForFavIconURL(favicon_url1);
- EXPECT_TRUE(out_favicon1);
+ EXPECT_FALSE(out_favicon1);
FavIconID out_favicon2 = backend_->thumbnail_db_->
GetFavIconIDForFavIconURL(favicon_url2);
EXPECT_FALSE(out_favicon2) << "Favicon not deleted";
- // The remaining URL should still reference the same favicon, even if its
- // ID has changed.
- EXPECT_EQ(out_favicon1, outrow1.favicon_id());
-
- // The first URL should still be bookmarked and have an entry. The star ID
- // must not have changed.
- EXPECT_TRUE(outrow1.starred());
- StarredEntry outentry;
- EXPECT_TRUE(backend_->db_->GetStarredEntry(star_id, &outentry));
- EXPECT_EQ(outrow1.id(), outentry.url_id);
- EXPECT_TRUE(outrow1.url() == outentry.url);
-
// The full text database should have no data.
std::vector<TextDatabase::Match> text_matches;
Time first_time_searched;
diff --git a/chrome/browser/history/history_database.cc b/chrome/browser/history/history_database.cc
index e606aeb..d79d14a 100644
--- a/chrome/browser/history/history_database.cc
+++ b/chrome/browser/history/history_database.cc
@@ -43,7 +43,7 @@ namespace history {
namespace {
// Current version number.
-const int kCurrentVersionNumber = 15;
+const int kCurrentVersionNumber = 16;
} // namespace
@@ -55,7 +55,8 @@ HistoryDatabase::HistoryDatabase()
HistoryDatabase::~HistoryDatabase() {
}
-InitStatus HistoryDatabase::Init(const std::wstring& history_name) {
+InitStatus HistoryDatabase::Init(const std::wstring& history_name,
+ const std::wstring& bookmarks_path) {
// Open the history database, using the narrow version of open indicates to
// sqlite that we want the database to be in UTF-8 if it doesn't already
// exist.
@@ -94,18 +95,16 @@ InitStatus HistoryDatabase::Init(const std::wstring& history_name) {
return INIT_FAILURE;
if (!CreateURLTable(false) || !InitVisitTable() ||
!InitKeywordSearchTermsTable() || !InitDownloadTable() ||
- !InitSegmentTables() || !InitStarTable())
+ !InitSegmentTables())
return INIT_FAILURE;
CreateMainURLIndex();
CreateSupplimentaryURLIndices();
// Version check.
- InitStatus version_status = EnsureCurrentVersion();
+ InitStatus version_status = EnsureCurrentVersion(bookmarks_path);
if (version_status != INIT_OK)
return version_status;
- EnsureStarredIntegrity();
-
// Succeeded: keep the DB open by detaching the auto-closer.
scoper.Detach();
db_closer_.Attach(&db_, &statement_cache_);
@@ -222,7 +221,8 @@ SqliteStatementCache& HistoryDatabase::GetStatementCache() {
// Migration -------------------------------------------------------------------
-InitStatus HistoryDatabase::EnsureCurrentVersion() {
+InitStatus HistoryDatabase::EnsureCurrentVersion(
+ const std::wstring& tmp_bookmarks_path) {
// We can't read databases newer than we were designed for.
if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber)
return INIT_TOO_NEW;
@@ -239,6 +239,16 @@ InitStatus HistoryDatabase::EnsureCurrentVersion() {
// Put migration code here
+ if (cur_version == 15) {
+ if (!MigrateBookmarksToFile(tmp_bookmarks_path))
+ return INIT_FAILURE;
+ if (!DropStarredIDFromURLs())
+ return INIT_FAILURE;
+ cur_version = 16;
+ meta_table_.SetVersionNumber(cur_version);
+ meta_table_.SetCompatibleVersionNumber(cur_version);
+ }
+
LOG_IF(WARNING, cur_version < kCurrentVersionNumber) <<
"History database version " << cur_version << " is too old to handle.";
diff --git a/chrome/browser/history/history_database.h b/chrome/browser/history/history_database.h
index 92c356d..f386a2a 100644
--- a/chrome/browser/history/history_database.h
+++ b/chrome/browser/history/history_database.h
@@ -56,6 +56,9 @@ class TextDatabaseManager;
// as the storage interface. Logic for manipulating this storage layer should
// be in HistoryBackend.cc.
class HistoryDatabase : public DownloadDatabase,
+ // TODO(sky): See if we can nuke StarredURLDatabase and just create on the
+ // stack for migration. Then HistoryDatabase would directly descend from
+ // URLDatabase.
public StarredURLDatabase,
public VisitDatabase,
public VisitSegmentDatabase {
@@ -84,7 +87,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 std::wstring& history_name);
+ InitStatus Init(const std::wstring& history_name,
+ const std::wstring& 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
@@ -141,6 +145,9 @@ class HistoryDatabase : public DownloadDatabase,
// visit id wasn't found.
SegmentID GetSegmentID(VisitID visit_id);
+ // Drops the starred table and star_id from urls.
+ bool MigrateFromVersion15ToVersion16();
+
private:
// Implemented for URLDatabase.
virtual sqlite3* GetDB();
@@ -161,7 +168,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();
+ InitStatus EnsureCurrentVersion(const std::wstring& tmp_bookmarks_path);
// ---------------------------------------------------------------------------
diff --git a/chrome/browser/history/history_marshaling.h b/chrome/browser/history/history_marshaling.h
index d1c4501..d0722e4 100644
--- a/chrome/browser/history/history_marshaling.h
+++ b/chrome/browser/history/history_marshaling.h
@@ -102,19 +102,6 @@ typedef CancelableRequest<HistoryService::ThumbnailDataCallback>
typedef CancelableRequest<HistoryService::FavIconDataCallback>
GetFavIconRequest;
-// Starring -------------------------------------------------------------------
-
-typedef CancelableRequest1<HistoryService::GetStarredEntriesCallback,
- std::vector<history::StarredEntry> >
- GetStarredEntriesRequest;
-
-typedef CancelableRequest1<HistoryService::GetMostRecentStarredEntriesCallback,
- std::vector<history::StarredEntry> >
- GetMostRecentStarredEntriesRequest;
-
-typedef CancelableRequest<HistoryService::CreateStarredEntryCallback>
- CreateStarredEntryRequest;
-
// Downloads ------------------------------------------------------------------
typedef CancelableRequest1<HistoryService::DownloadQueryCallback,
@@ -155,6 +142,9 @@ typedef CancelableRequest1<HistoryService::HistoryDBTaskCallback,
scoped_refptr<HistoryDBTask> >
HistoryDBTaskRequest;
+typedef CancelableRequest<HistoryService::EmptyHistoryCallback>
+ EmptyHistoryRequest;
+
} // namespace history
#endif // CHROME_BROWSER_HISTORY_HISTORY_MARSHALING_H__
diff --git a/chrome/browser/history/history_notifications.h b/chrome/browser/history/history_notifications.h
index d5146ea..66379fd 100644
--- a/chrome/browser/history/history_notifications.h
+++ b/chrome/browser/history/history_notifications.h
@@ -72,7 +72,6 @@ struct URLsDeletedDetails : public HistoryDetails {
// Details for NOTIFY_URLS_STARRED.
struct URLsStarredDetails : public HistoryDetails {
-
URLsStarredDetails(bool being_starred) : starred(being_starred) {}
// The new starred state of the list of URLs. True when they are being
@@ -81,18 +80,9 @@ struct URLsStarredDetails : public HistoryDetails {
// The list of URLs that are changing.
std::set<GURL> changed_urls;
-
- // The star entries that were added or removed as the result of starring
- // the entry. This may be empty.
- std::vector<StarredEntry> star_entries;
-};
-
-// Details for NOTIFY_STAR_ENTRY_CHANGED and others.
-struct StarredEntryDetails : public HistoryDetails {
- StarredEntry entry;
};
-// Details for NOTIFY_STARRED_FAVICON_CHANGED.
+// Details for NOTIFY_FAVICON_CHANGED.
struct FavIconChangeDetails : public HistoryDetails {
std::set<GURL> urls;
};
diff --git a/chrome/browser/history/history_querying_unittest.cc b/chrome/browser/history/history_querying_unittest.cc
index 9d5f74d..7f4c7d5 100644
--- a/chrome/browser/history/history_querying_unittest.cc
+++ b/chrome/browser/history/history_querying_unittest.cc
@@ -132,19 +132,6 @@ class HistoryQueryTest : public testing::Test {
history_->SetPageTitle(url, test_entries[i].title);
history_->SetPageContents(url, test_entries[i].body);
}
-
- // Set one of the pages starred.
- history::StarredEntry entry;
- entry.id = 5;
- entry.title = L"Some starred page";
- entry.date_added = Time::Now();
- entry.parent_group_id = StarredEntry::BOOKMARK_BAR;
- entry.group_id = 0;
- entry.visual_order = 0;
- entry.type = history::StarredEntry::URL;
- entry.url = GURL(test_entries[0].url);
- entry.date_group_modified = Time::Now();
- history_->CreateStarredEntry(entry, NULL, NULL);
}
virtual void TearDown() {
@@ -189,9 +176,6 @@ TEST_F(HistoryQueryTest, Basic) {
EXPECT_TRUE(NthResultIs(results, 3, 1));
EXPECT_TRUE(NthResultIs(results, 4, 0));
- // Check that the starred one is marked starred.
- EXPECT_TRUE(results[4].starred());
-
// Next query a time range. The beginning should be inclusive, the ending
// should be exclusive.
options.begin_time = test_entries[3].time;
@@ -247,11 +231,10 @@ TEST_F(HistoryQueryTest, FTS) {
// this query will return the starred item twice since we requested all
// starred entries and no de-duping.
QueryHistory(std::wstring(L"some"), options, &results);
- EXPECT_EQ(4, results.size());
- EXPECT_TRUE(NthResultIs(results, 0, 4)); // Starred item.
- EXPECT_TRUE(NthResultIs(results, 1, 2));
- EXPECT_TRUE(NthResultIs(results, 2, 3));
- EXPECT_TRUE(NthResultIs(results, 3, 1));
+ EXPECT_EQ(3, results.size());
+ EXPECT_TRUE(NthResultIs(results, 0, 2));
+ EXPECT_TRUE(NthResultIs(results, 1, 3));
+ EXPECT_TRUE(NthResultIs(results, 2, 1));
// Do a query that should only match one of them.
QueryHistory(std::wstring(L"PAGETWO"), options, &results);
@@ -262,7 +245,6 @@ TEST_F(HistoryQueryTest, FTS) {
// should be exclusive.
options.begin_time = test_entries[1].time;
options.end_time = test_entries[3].time;
- options.include_all_starred = false;
QueryHistory(std::wstring(L"some"), options, &results);
EXPECT_EQ(1, results.size());
EXPECT_TRUE(NthResultIs(results, 0, 1));
@@ -295,10 +277,9 @@ TEST_F(HistoryQueryTest, FTSCount) {
// get the N most recent entries.
options.max_count = 2;
QueryHistory(std::wstring(L"some"), options, &results);
- EXPECT_EQ(3, results.size());
- EXPECT_TRUE(NthResultIs(results, 0, 4));
- EXPECT_TRUE(NthResultIs(results, 1, 2));
- EXPECT_TRUE(NthResultIs(results, 2, 3));
+ EXPECT_EQ(2, results.size());
+ EXPECT_TRUE(NthResultIs(results, 0, 2));
+ EXPECT_TRUE(NthResultIs(results, 1, 3));
// Now query a subset of the pages and limit by N items. "FOO" should match
// the 2nd & 3rd pages, but we should only get the 3rd one because of the one
diff --git a/chrome/browser/history/history_types.cc b/chrome/browser/history/history_types.cc
index 920b0bc..758a166 100644
--- a/chrome/browser/history/history_types.cc
+++ b/chrome/browser/history/history_types.cc
@@ -43,7 +43,6 @@ void URLRow::Swap(URLRow* other) {
std::swap(typed_count_, other->typed_count_);
std::swap(last_visit_, other->last_visit_);
std::swap(hidden_, other->hidden_);
- std::swap(star_id_, other->star_id_);
std::swap(favicon_id_, other->favicon_id_);
}
@@ -54,7 +53,6 @@ void URLRow::Initialize() {
last_visit_ = Time();
hidden_ = false;
favicon_id_ = 0;
- star_id_ = 0;
}
// VisitRow --------------------------------------------------------------------
@@ -113,7 +111,6 @@ void URLResult::Swap(URLResult* other) {
std::swap(visit_time_, other->visit_time_);
snippet_.Swap(&other->snippet_);
title_match_positions_.swap(other->title_match_positions_);
- starred_entry_.Swap(&other->starred_entry_);
}
// QueryResults ----------------------------------------------------------------
diff --git a/chrome/browser/history/history_types.h b/chrome/browser/history/history_types.h
index 738eda02..cbbd1f7 100644
--- a/chrome/browser/history/history_types.h
+++ b/chrome/browser/history/history_types.h
@@ -136,14 +136,6 @@ class URLRow {
hidden_ = hidden;
}
- StarID star_id() const { return star_id_; }
- void set_star_id(StarID star_id) {
- star_id_ = star_id;
- }
-
- // Simple boolean query to see if the page is starred.
- bool starred() const { return (star_id_ != 0); }
-
// ID of the favicon. A value of 0 means the favicon isn't known yet.
FavIconID favicon_id() const { return favicon_id_; }
void set_favicon_id(FavIconID favicon_id) {
@@ -190,13 +182,6 @@ class URLRow {
// is usually for subframes.
bool hidden_;
- // ID of the starred entry.
- //
- // NOTE: This is ignored by Add/UpdateURL. To modify the starred state you
- // must invoke SetURLStarred.
- // TODO: revisit this to see if this limitation can be removed.
- StarID star_id_;
-
// The ID of the favicon for this url.
FavIconID favicon_id_;
@@ -372,11 +357,6 @@ class URLResult : public URLRow {
virtual void Swap(URLResult* other);
- // Returns the starred entry for this url. This is only set if the query
- // was configured to search for starred only entries (only_starred is true).
- const StarredEntry& starred_entry() const { return starred_entry_; }
- void ResetStarredEntry() { starred_entry_ = StarredEntry(); }
-
private:
friend class HistoryBackend;
@@ -387,9 +367,6 @@ class URLResult : public URLRow {
Snippet snippet_;
Snippet::MatchPositions title_match_positions_;
- // See comment above getter.
- StarredEntry starred_entry_;
-
// We support the implicit copy constructor and operator=.
};
@@ -488,8 +465,6 @@ class QueryResults {
struct QueryOptions {
QueryOptions()
: most_recent_visit_only(false),
- only_starred(false),
- include_all_starred(true),
max_count(0) {
}
@@ -521,26 +496,6 @@ struct QueryOptions {
// Defaults to false (all visits).
bool most_recent_visit_only;
- // Indicates if only starred items should be matched.
- //
- // Defaults to false.
- bool only_starred;
-
- // When true, and we're doing a full text query, starred entries that have
- // never been visited or have been visited outside of the given time range
- // will also be included in the results. These items will appear at the
- // beginning of the result set. Non-full-text queries won't check this flag
- // and will never return unvisited bookmarks.
- //
- // When false, full text queries will not return unvisited bookmarks, they
- // will only be included when they were visited in the given time range.
- //
- // You probably want to use this in conjunction with most_recent_visit_only
- // since it will cause duplicates otherwise.
- //
- // Defaults to true.
- bool include_all_starred;
-
// The maximum number of results to return. The results will be sorted with
// the most recent first, so older results may not be returned if there is not
// enough room. When 0, this will return everything (the default).
diff --git a/chrome/browser/history/history_unittest.cc b/chrome/browser/history/history_unittest.cc
index 37b9179..cc0bfb4 100644
--- a/chrome/browser/history/history_unittest.cc
+++ b/chrome/browser/history/history_unittest.cc
@@ -120,12 +120,6 @@ class BackendDelegate : public HistoryBackend::Delegate {
HistoryTest* history_test_;
};
-bool IsURLStarred(URLDatabase* db, const GURL& url) {
- URLRow row;
- EXPECT_TRUE(db->GetRowForURL(url, &row)) << "URL not found";
- return row.starred();
-}
-
} // namespace
// This must be outside the anonymous namespace for the friend statement in
@@ -272,21 +266,6 @@ class HistoryTest : public testing::Test {
MessageLoop::current()->Quit();
}
- void SetURLStarred(const GURL& url, bool starred) {
- history::StarredEntry entry;
- entry.type = history::StarredEntry::URL;
- entry.url = url;
- history::StarID star_id = db_->GetStarIDForEntry(entry);
- if (star_id && !starred) {
- // Unstar.
- backend_->DeleteStarredEntry(star_id);
- } else if (!star_id && starred) {
- // Star.
- entry.parent_group_id = HistoryService::kBookmarkBarID;
- backend_->CreateStarredEntry(NULL, entry);
- }
- }
-
// PageUsageData vector to test segments.
ScopedVector<PageUsageData> page_usage_data_;
@@ -870,56 +849,4 @@ TEST_F(HistoryTest, HistoryDBTaskCanceled) {
ASSERT_FALSE(task->done_invoked);
}
-TEST_F(HistoryTest, Starring) {
- CreateBackendAndDatabase();
-
- // Add one page and star it.
- GURL simple_page("http://google.com");
- scoped_refptr<HistoryAddPageArgs> args(MakeAddArgs(simple_page));
- backend_->AddPage(args);
- EXPECT_FALSE(IsURLStarred(db_, simple_page));
- EXPECT_FALSE(IsURLStarred(in_mem_backend_->db(), simple_page));
- SetURLStarred(simple_page, true);
-
- // The URL should be starred in both the main and memory DBs.
- EXPECT_TRUE(IsURLStarred(db_, simple_page));
- EXPECT_TRUE(IsURLStarred(in_mem_backend_->db(), simple_page));
-
- // Unstar it.
- SetURLStarred(simple_page, false);
- EXPECT_FALSE(IsURLStarred(db_, simple_page));
- EXPECT_FALSE(IsURLStarred(in_mem_backend_->db(), simple_page));
-}
-
-TEST_F(HistoryTest, SetStarredOnPageWithTypeCount0) {
- CreateBackendAndDatabase();
-
- // Add a page to the backend.
- const GURL url(L"http://google.com/");
- scoped_refptr<HistoryAddPageArgs> args(new HistoryAddPageArgs(
- url, Time::Now(), NULL, 1, GURL(), HistoryService::RedirectList(),
- PageTransition::LINK));
- backend_->AddPage(args);
-
- // Now fetch the URLInfo from the in memory db, it should not be there since
- // it was not typed.
- URLRow url_info;
- EXPECT_EQ(0, in_mem_backend_->db()->GetRowForURL(url, &url_info));
-
- // Mark the URL starred.
- SetURLStarred(url, true);
-
- // The type count is 0, so the page shouldn't be starred in the in memory
- // db.
- EXPECT_EQ(0, in_mem_backend_->db()->GetRowForURL(url, &url_info));
- EXPECT_TRUE(IsURLStarred(db_, url));
-
- // Now unstar it.
- SetURLStarred(url, false);
-
- // Make sure both the back end and in memory DB think it is unstarred.
- EXPECT_EQ(0, in_mem_backend_->db()->GetRowForURL(url, &url_info));
- EXPECT_FALSE(IsURLStarred(db_, url));
-}
-
} // namespace history
diff --git a/chrome/browser/history/in_memory_history_backend.cc b/chrome/browser/history/in_memory_history_backend.cc
index b3619a9..d745423 100644
--- a/chrome/browser/history/in_memory_history_backend.cc
+++ b/chrome/browser/history/in_memory_history_backend.cc
@@ -54,7 +54,6 @@ InMemoryHistoryBackend::~InMemoryHistoryBackend() {
service->RemoveObserver(this, NOTIFY_HISTORY_URL_VISITED, source);
service->RemoveObserver(this, NOTIFY_HISTORY_TYPED_URLS_MODIFIED, source);
service->RemoveObserver(this, NOTIFY_HISTORY_URLS_DELETED, source);
- service->RemoveObserver(this, NOTIFY_URLS_STARRED, source);
}
}
@@ -87,7 +86,6 @@ void InMemoryHistoryBackend::AttachToHistoryService(Profile* profile) {
service->AddObserver(this, NOTIFY_HISTORY_URL_VISITED, source);
service->AddObserver(this, NOTIFY_HISTORY_TYPED_URLS_MODIFIED, source);
service->AddObserver(this, NOTIFY_HISTORY_URLS_DELETED, source);
- service->AddObserver(this, NOTIFY_URLS_STARRED, source);
}
void InMemoryHistoryBackend::Observe(NotificationType type,
@@ -110,9 +108,6 @@ void InMemoryHistoryBackend::Observe(NotificationType type,
case NOTIFY_HISTORY_URLS_DELETED:
OnURLsDeleted(*Details<history::URLsDeletedDetails>(details).ptr());
break;
- case NOTIFY_URLS_STARRED:
- OnURLsStarred(*Details<history::URLsStarredDetails>(details).ptr());
- break;
default:
// For simplicity, the unit tests send us all notifications, even when
// we haven't registered for them, so don't assert here.
@@ -164,21 +159,4 @@ void InMemoryHistoryBackend::OnURLsDeleted(const URLsDeletedDetails& details) {
}
}
-void InMemoryHistoryBackend::OnURLsStarred(
- const history::URLsStarredDetails& details) {
- DCHECK(db_.get());
-
- for (std::set<GURL>::const_iterator i = details.changed_urls.begin();
- i != details.changed_urls.end(); ++i) {
- URLRow row;
- if (db_->GetRowForURL(*i, &row)) {
- // NOTE: We currently don't care about the star id from the in memory
- // db, so that we use a fake value. If this does become a problem,
- // then the notification will have to propagate the star id.
- row.set_star_id(details.starred ? kBogusStarredID : 0);
- db_->UpdateURLRow(row.id(), row);
- }
- }
-}
-
} // namespace history
diff --git a/chrome/browser/history/in_memory_history_backend.h b/chrome/browser/history/in_memory_history_backend.h
index 9134bf0..c86ea56 100644
--- a/chrome/browser/history/in_memory_history_backend.h
+++ b/chrome/browser/history/in_memory_history_backend.h
@@ -85,9 +85,6 @@ class InMemoryHistoryBackend : public NotificationObserver {
// Handler for NOTIFY_HISTORY_URLS_DELETED.
void OnURLsDeleted(const URLsDeletedDetails& details);
- // Handler for NOTIFY_URLS_STARRED.
- void OnURLsStarred(const URLsStarredDetails& details);
-
scoped_ptr<InMemoryDatabase> db_;
// The profile that this object is attached. May be NULL before
diff --git a/chrome/browser/history/starred_url_database.cc b/chrome/browser/history/starred_url_database.cc
index 7294222..950cee3 100644
--- a/chrome/browser/history/starred_url_database.cc
+++ b/chrome/browser/history/starred_url_database.cc
@@ -29,7 +29,11 @@
#include "chrome/browser/history/starred_url_database.h"
+#include "base/file_util.h"
#include "base/logging.h"
+#include "base/json_writer.h"
+#include "chrome/browser/bookmark_bar_model.h"
+#include "chrome/browser/bookmark_codec.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/history/query_parser.h"
#include "chrome/browser/meta_table_helper.h"
@@ -102,181 +106,35 @@ void FillInStarredEntry(SQLStatement* s, StarredEntry* entry) {
} // namespace
-StarredURLDatabase::StarredURLDatabase()
- : is_starred_valid_(true), check_starred_integrity_on_mutation_(true) {
+StarredURLDatabase::StarredURLDatabase() {
}
StarredURLDatabase::~StarredURLDatabase() {
}
-bool StarredURLDatabase::InitStarTable() {
- if (!DoesSqliteTableExist(GetDB(), "starred")) {
- if (sqlite3_exec(GetDB(), "CREATE TABLE starred ("
- "id INTEGER PRIMARY KEY,"
- "type INTEGER NOT NULL DEFAULT 0,"
- "url_id INTEGER NOT NULL DEFAULT 0,"
- "group_id INTEGER NOT NULL DEFAULT 0,"
- "title VARCHAR,"
- "date_added INTEGER NOT NULL,"
- "visual_order INTEGER DEFAULT 0,"
- "parent_id INTEGER DEFAULT 0,"
- "date_modified INTEGER DEFAULT 0 NOT NULL)",
- NULL, NULL, NULL) != SQLITE_OK) {
- NOTREACHED();
- return false;
- }
- if (sqlite3_exec(GetDB(), "CREATE INDEX starred_index "
- "ON starred(id,url_id)", NULL, NULL, NULL)) {
- NOTREACHED();
- return false;
- }
- // Add an entry that represents the bookmark bar. The title is ignored in
- // the UI.
- StarID bookmark_id = CreateStarredEntryRow(
- 0, HistoryService::kBookmarkBarID, 0, L"bookmark-bar", Time::Now(), 0,
- history::StarredEntry::BOOKMARK_BAR);
- if (bookmark_id != HistoryService::kBookmarkBarID) {
- NOTREACHED();
- return false;
- }
-
- // Add an entry that represents other. The title is ignored in the UI.
- StarID other_id = CreateStarredEntryRow(
- 0, HistoryService::kBookmarkBarID + 1, 0, L"other", Time::Now(), 0,
- history::StarredEntry::OTHER);
- if (!other_id) {
- NOTREACHED();
- return false;
- }
- }
-
- sqlite3_exec(GetDB(), "CREATE INDEX starred_group_index"
- "ON starred(group_id)", NULL, NULL, NULL);
- return true;
-}
-
-bool StarredURLDatabase::EnsureStarredIntegrity() {
- if (!is_starred_valid_)
- return false;
-
- // Assume invalid, we'll set to true if succesful.
- is_starred_valid_ = false;
-
- std::set<StarredNode*> roots;
- std::set<StarID> groups_with_duplicate_ids;
- std::set<StarredNode*> unparented_urls;
- std::set<StarID> empty_url_ids;
-
- if (!BuildStarNodes(&roots, &groups_with_duplicate_ids, &unparented_urls,
- &empty_url_ids)) {
- return false;
- }
-
- // The table may temporarily get into an invalid state while updating the
- // integrity.
- bool org_check_starred_integrity_on_mutation =
- check_starred_integrity_on_mutation_;
- check_starred_integrity_on_mutation_ = false;
- is_starred_valid_ =
- EnsureStarredIntegrityImpl(&roots, groups_with_duplicate_ids,
- &unparented_urls, empty_url_ids);
- check_starred_integrity_on_mutation_ =
- org_check_starred_integrity_on_mutation;
-
- STLDeleteElements(&roots);
- STLDeleteElements(&unparented_urls);
- return is_starred_valid_;
-}
-
-StarID StarredURLDatabase::GetStarIDForEntry(const StarredEntry& entry) {
- if (entry.type == StarredEntry::URL) {
- URLRow url_row;
- URLID url_id = GetRowForURL(entry.url, &url_row);
- if (!url_id)
- return 0;
- return url_row.star_id();
- }
- return GetStarIDForGroupID(entry.group_id);
-}
-
-StarID StarredURLDatabase::GetStarIDForGroupID(UIStarID group_id) {
- DCHECK(group_id);
-
- SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
- "SELECT id FROM starred WHERE group_id = ?");
- if (!statement.is_valid())
- return false;
-
- statement->bind_int64(0, group_id);
- if (statement->step() == SQLITE_ROW)
- return statement->column_int64(0);
- return 0;
-}
-
-void StarredURLDatabase::DeleteStarredEntry(
- StarID star_id,
- std::set<GURL>* unstarred_urls,
- std::vector<StarredEntry>* deleted_entries) {
- DeleteStarredEntryImpl(star_id, unstarred_urls, deleted_entries);
- if (check_starred_integrity_on_mutation_)
- CheckStarredIntegrity();
-}
+bool StarredURLDatabase::MigrateBookmarksToFile(const std::wstring& path) {
+ if (!DoesSqliteTableExist(GetDB(), "starred"))
+ return true;
-bool StarredURLDatabase::UpdateStarredEntry(StarredEntry* entry) {
- // Determine the ID used by the database.
- const StarID id = GetStarIDForEntry(*entry);
- if (!id) {
- NOTREACHED() << "request to update unknown star entry";
+ if (EnsureStarredIntegrity() && !MigrateBookmarksToFileImpl(path)) {
+ NOTREACHED() << " Bookmarks migration failed";
return false;
}
- StarredEntry original_entry;
- if (!GetStarredEntry(id, &original_entry)) {
- NOTREACHED() << "Unknown star entry";
+ if (sqlite3_exec(GetDB(), "DROP TABLE starred", NULL, NULL,
+ NULL) != SQLITE_OK) {
+ NOTREACHED() << "Unable to drop starred table";
return false;
}
-
- if (entry->parent_group_id != original_entry.parent_group_id) {
- // Parent has changed.
- if (original_entry.parent_group_id) {
- AdjustStarredVisualOrder(original_entry.parent_group_id,
- original_entry.visual_order, -1);
- }
- if (entry->parent_group_id) {
- AdjustStarredVisualOrder(entry->parent_group_id, entry->visual_order, 1);
- }
- } else if (entry->visual_order != original_entry.visual_order &&
- entry->parent_group_id) {
- // Same parent, but visual order changed.
- // Shift everything down from the old location.
- AdjustStarredVisualOrder(original_entry.parent_group_id,
- original_entry.visual_order, -1);
- // Make room for new location by shifting everything up from the new
- // location.
- AdjustStarredVisualOrder(original_entry.parent_group_id,
- entry->visual_order, 1);
- }
-
- // And update title, parent and visual order.
- UpdateStarredEntryRow(id, entry->title, entry->parent_group_id,
- entry->visual_order, entry->date_group_modified);
- entry->url_id = original_entry.url_id;
- entry->date_added = original_entry.date_added;
- entry->id = original_entry.id;
- if (check_starred_integrity_on_mutation_)
- CheckStarredIntegrity();
return true;
}
-bool StarredURLDatabase::GetStarredEntries(
- UIStarID parent_group_id,
+bool StarredURLDatabase::GetAllStarredEntries(
std::vector<StarredEntry>* entries) {
DCHECK(entries);
std::string sql = "SELECT ";
sql.append(kHistoryStarFields);
sql.append("FROM starred LEFT JOIN urls ON starred.url_id = urls.id ");
- if (parent_group_id)
- sql += "WHERE starred.parent_id = ? ";
sql += "ORDER BY parent_id, visual_order";
SQLStatement s;
@@ -284,8 +142,6 @@ bool StarredURLDatabase::GetStarredEntries(
NOTREACHED() << "Statement prepare failed";
return false;
}
- if (parent_group_id)
- s.bind_int64(0, parent_group_id);
history::StarredEntry entry;
while (s.step() == SQLITE_ROW) {
@@ -299,6 +155,25 @@ bool StarredURLDatabase::GetStarredEntries(
return true;
}
+bool StarredURLDatabase::EnsureStarredIntegrity() {
+ std::set<StarredNode*> roots;
+ std::set<StarID> groups_with_duplicate_ids;
+ std::set<StarredNode*> unparented_urls;
+ std::set<StarID> empty_url_ids;
+
+ if (!BuildStarNodes(&roots, &groups_with_duplicate_ids, &unparented_urls,
+ &empty_url_ids)) {
+ return false;
+ }
+
+ bool valid = EnsureStarredIntegrityImpl(&roots, groups_with_duplicate_ids,
+ &unparented_urls, empty_url_ids);
+
+ STLDeleteElements(&roots);
+ STLDeleteElements(&unparented_urls);
+ return valid;
+}
+
bool StarredURLDatabase::UpdateStarredEntryRow(StarID star_id,
const std::wstring& title,
UIStarID parent_group_id,
@@ -380,8 +255,6 @@ StarID StarredURLDatabase::CreateStarredEntryRow(URLID url_id,
}
bool StarredURLDatabase::DeleteStarredEntryRow(StarID star_id) {
- if (check_starred_integrity_on_mutation_)
- DCHECK(star_id && star_id != HistoryService::kBookmarkBarID);
SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
"DELETE FROM starred WHERE id=?");
if (!statement.is_valid())
@@ -433,11 +306,6 @@ StarID StarredURLDatabase::CreateStarredEntry(StarredEntry* entry) {
url_row.set_hidden(false);
entry->url_id = this->AddURL(url_row);
} else {
- // Update the existing row for this URL.
- if (url_row.starred()) {
- DCHECK(false) << "We are starring an already-starred URL";
- return 0;
- }
entry->url_id = url_row.id(); // The caller doesn't have to set this.
}
@@ -447,7 +315,6 @@ StarID StarredURLDatabase::CreateStarredEntry(StarredEntry* entry) {
entry->visual_order, entry->type);
// Update the URL row to refer to this new starred entry.
- url_row.set_star_id(entry->id);
UpdateURLRow(entry->url_id, url_row);
break;
}
@@ -456,119 +323,9 @@ StarID StarredURLDatabase::CreateStarredEntry(StarredEntry* entry) {
NOTREACHED();
break;
}
- if (check_starred_integrity_on_mutation_)
- CheckStarredIntegrity();
return entry->id;
}
-void StarredURLDatabase::GetMostRecentStarredEntries(
- int max_count,
- std::vector<StarredEntry>* entries) {
- DCHECK(max_count && entries);
- SQLITE_UNIQUE_STATEMENT(s, GetStatementCache(),
- "SELECT" STAR_FIELDS "FROM starred "
- "LEFT JOIN urls ON starred.url_id = urls.id "
- "WHERE starred.type=0 ORDER BY starred.date_added DESC, "
- "starred.id DESC " // This is for testing, when the dates are
- // typically the same.
- "LIMIT ?");
- if (!s.is_valid())
- return;
- s->bind_int(0, max_count);
-
- while (s->step() == SQLITE_ROW) {
- history::StarredEntry entry;
- FillInStarredEntry(s.statement(), &entry);
- entries->push_back(entry);
- }
-}
-
-void StarredURLDatabase::GetURLsForTitlesMatching(const std::wstring& query,
- std::set<URLID>* ids) {
- QueryParser parser;
- ScopedVector<QueryNode> nodes;
- parser.ParseQuery(query, &nodes.get());
- if (nodes.empty())
- return;
-
- SQLITE_UNIQUE_STATEMENT(s, GetStatementCache(),
- "SELECT url_id, title FROM starred WHERE type=?");
- if (!s.is_valid())
- return;
-
- s->bind_int(0, static_cast<int>(StarredEntry::URL));
- while (s->step() == SQLITE_ROW) {
- if (parser.DoesQueryMatch(s->column_string16(1), nodes.get()))
- ids->insert(s->column_int64(0));
- }
-}
-
-bool StarredURLDatabase::UpdateURLIDForStar(StarID star_id, URLID new_url_id) {
- SQLITE_UNIQUE_STATEMENT(s, GetStatementCache(),
- "UPDATE starred SET url_id=? WHERE id=?");
- if (!s.is_valid())
- return false;
- s->bind_int64(0, new_url_id);
- s->bind_int64(1, star_id);
- return s->step() == SQLITE_DONE;
-}
-
-void StarredURLDatabase::DeleteStarredEntryImpl(
- StarID star_id,
- std::set<GURL>* unstarred_urls,
- std::vector<StarredEntry>* deleted_entries) {
-
- StarredEntry deleted_entry;
- if (!GetStarredEntry(star_id, &deleted_entry))
- return; // Couldn't find information on the entry.
-
- if (deleted_entry.type == StarredEntry::BOOKMARK_BAR ||
- deleted_entry.type == StarredEntry::OTHER) {
- return;
- }
-
- if (deleted_entry.parent_group_id != 0) {
- // This entry has a parent. All siblings after this entry need to be shifted
- // down by 1.
- AdjustStarredVisualOrder(deleted_entry.parent_group_id,
- deleted_entry.visual_order, -1);
- }
-
- deleted_entries->push_back(deleted_entry);
-
- switch (deleted_entry.type) {
- case StarredEntry::URL: {
- unstarred_urls->insert(deleted_entry.url);
-
- // Need to unmark the starred flag in the URL database.
- URLRow url_row;
- if (GetURLRow(deleted_entry.url_id, &url_row)) {
- url_row.set_star_id(0);
- UpdateURLRow(deleted_entry.url_id, url_row);
- }
- break;
- }
-
- case StarredEntry::USER_GROUP: {
- // Need to delete all the children of the group. Use the db version which
- // avoids shifting the visual order.
- std::vector<StarredEntry> descendants;
- GetStarredEntries(deleted_entry.group_id, &descendants);
- for (std::vector<StarredEntry>::iterator i =
- descendants.begin(); i != descendants.end(); ++i) {
- // Recurse down into the child.
- DeleteStarredEntryImpl(i->id, unstarred_urls, deleted_entries);
- }
- break;
- }
-
- default:
- NOTREACHED();
- break;
- }
- DeleteStarredEntryRow(star_id);
-}
-
UIStarID StarredURLDatabase::GetMaxGroupID() {
SQLStatement max_group_id_statement;
if (max_group_id_statement.prepare(GetDB(),
@@ -589,7 +346,7 @@ bool StarredURLDatabase::BuildStarNodes(
std::set<StarredNode*>* unparented_urls,
std::set<StarID>* empty_url_ids) {
std::vector<StarredEntry> star_entries;
- if (!GetStarredEntries(0, &star_entries)) {
+ if (!GetAllStarredEntries(&star_entries)) {
NOTREACHED() << "Unable to get bookmarks from database";
return false;
}
@@ -699,11 +456,9 @@ bool StarredURLDatabase::EnsureStarredIntegrityImpl(
if (!bookmark_node) {
LOG(WARNING) << "No bookmark bar folder in database";
// If there is no bookmark bar entry in the db things are really
- // screwed. The UI assumes the bookmark bar entry has a particular
- // ID which is hard to enforce when creating a new entry. As this
- // shouldn't happen, we take the drastic route of recreating the
- // entire table.
- return RecreateStarredEntries();
+ // screwed. Return false, which won't trigger migration and we'll just
+ // drop the tables.
+ return false;
}
// Make sure the other node exists.
@@ -803,86 +558,96 @@ bool StarredURLDatabase::Move(StarredNode* source, StarredNode* new_parent) {
return true;
}
-bool StarredURLDatabase::RecreateStarredEntries() {
- if (sqlite3_exec(GetDB(), "DROP TABLE starred", NULL, NULL,
- NULL) != SQLITE_OK) {
- NOTREACHED() << "Unable to drop starred table";
+bool StarredURLDatabase::MigrateBookmarksToFileImpl(const std::wstring& path) {
+ std::vector<history::StarredEntry> entries;
+ if (!GetAllStarredEntries(&entries))
return false;
- }
- if (!InitStarTable()) {
- NOTREACHED() << "Unable to create starred table";
- return false;
- }
-
- if (sqlite3_exec(GetDB(), "UPDATE urls SET starred_id=0", NULL, NULL,
- NULL) != SQLITE_OK) {
- NOTREACHED() << "Unable to mark all URLs as unstarred";
- return false;
+ // Create the bookmark bar and other folder nodes.
+ history::StarredEntry entry;
+ entry.type = history::StarredEntry::BOOKMARK_BAR;
+ BookmarkBarNode bookmark_bar_node(NULL, GURL());
+ bookmark_bar_node.Reset(entry);
+ entry.type = history::StarredEntry::OTHER;
+ BookmarkBarNode other_node(NULL, GURL());
+ other_node.Reset(entry);
+
+ std::map<history::UIStarID, history::StarID> group_id_to_id_map;
+ typedef std::map<history::StarID, BookmarkBarNode*> IDToNodeMap;
+ IDToNodeMap id_to_node_map;
+
+ history::UIStarID other_folder_group_id = 0;
+ history::StarID other_folder_id = 0;
+
+ // Iterate through the entries building a mapping between group_id and id.
+ for (std::vector<history::StarredEntry>::const_iterator i = entries.begin();
+ i != entries.end(); ++i) {
+ if (i->type != history::StarredEntry::URL) {
+ group_id_to_id_map[i->group_id] = i->id;
+ if (i->type == history::StarredEntry::OTHER) {
+ other_folder_id = i->id;
+ other_folder_group_id = i->group_id;
+ }
+ }
}
- return true;
-}
-void StarredURLDatabase::CheckVisualOrder(StarredNode* node) {
- for (int i = 0; i < node->GetChildCount(); ++i) {
- DCHECK(i == node->GetChild(i)->value.visual_order);
- CheckVisualOrder(node->GetChild(i));
- }
-}
+ // Register the bookmark bar and other folder nodes in the maps.
+ id_to_node_map[HistoryService::kBookmarkBarID] = &bookmark_bar_node;
+ group_id_to_id_map[HistoryService::kBookmarkBarID] =
+ HistoryService::kBookmarkBarID;
+ if (other_folder_group_id) {
+ id_to_node_map[other_folder_id] = &other_node;
+ group_id_to_id_map[other_folder_group_id] = other_folder_id;
+ }
+
+ // Iterate through the entries again creating the nodes.
+ for (std::vector<history::StarredEntry>::iterator i = entries.begin();
+ i != entries.end(); ++i) {
+ if (!i->parent_group_id) {
+ DCHECK(i->type == history::StarredEntry::BOOKMARK_BAR ||
+ i->type == history::StarredEntry::OTHER);
+ // Only entries with no parent should be the bookmark bar and other
+ // bookmarks folders.
+ continue;
+ }
-void StarredURLDatabase::CheckStarredIntegrity() {
-#ifndef NDEBUG
- std::set<StarredNode*> roots;
- std::set<StarID> groups_with_duplicate_ids;
- std::set<StarredNode*> unparented_urls;
- std::set<StarID> empty_url_ids;
+ BookmarkBarNode* node = id_to_node_map[i->id];
+ if (!node) {
+ // Creating a node results in creating the parent. As such, it is
+ // possible for the node representing a group to have been created before
+ // encountering the details.
- if (!BuildStarNodes(&roots, &groups_with_duplicate_ids, &unparented_urls,
- &empty_url_ids)) {
- return;
- }
+ // The created nodes are owned by the root node.
+ node = new BookmarkBarNode(NULL, i->url);
+ id_to_node_map[i->id] = node;
+ }
+ node->Reset(*i);
+
+ DCHECK(group_id_to_id_map.find(i->parent_group_id) !=
+ group_id_to_id_map.end());
+ history::StarID parent_id = group_id_to_id_map[i->parent_group_id];
+ BookmarkBarNode* parent = id_to_node_map[parent_id];
+ if (!parent) {
+ // Haven't encountered the parent yet, create it now.
+ parent = new BookmarkBarNode(NULL, GURL());
+ id_to_node_map[parent_id] = parent;
+ }
- // There must be root and bookmark bar nodes.
- if (!GetNodeByType(roots, StarredEntry::BOOKMARK_BAR))
- NOTREACHED() << "No bookmark bar folder in starred";
- else
- CheckVisualOrder(GetNodeByType(roots, StarredEntry::BOOKMARK_BAR));
-
- if (!GetNodeByType(roots, StarredEntry::OTHER))
- NOTREACHED() << "No other bookmarks folder in starred";
- else
- CheckVisualOrder(GetNodeByType(roots, StarredEntry::OTHER));
-
- // The only roots should be the bookmark bar and other nodes. Also count how
- // many bookmark bar and other folders exists.
- int bookmark_bar_count = 0;
- int other_folder_count = 0;
- for (std::set<StarredNode*>::const_iterator i = roots.begin();
- i != roots.end(); ++i) {
- if ((*i)->value.type == StarredEntry::USER_GROUP)
- NOTREACHED() << "Bookmark folder not in bookmark bar or other folders";
- else if ((*i)->value.type == StarredEntry::BOOKMARK_BAR)
- bookmark_bar_count++;
- else if ((*i)->value.type == StarredEntry::OTHER)
- other_folder_count++;
+ // Add the node to its parent. |entries| is ordered by parent then
+ // visual order so that we know we maintain visual order by always adding
+ // to the end.
+ parent->Add(parent->GetChildCount(), node);
}
- DCHECK(bookmark_bar_count == 1) << "Should be only one bookmark bar entry";
- DCHECK(other_folder_count == 1) << "Should be only one other folder entry";
- // There shouldn't be any folders with the same group id.
- if (!groups_with_duplicate_ids.empty())
- NOTREACHED() << "Bookmark folder with duplicate ids exist";
+ // Save to file.
+ BookmarkCodec encoder;
+ scoped_ptr<Value> encoded_bookmarks(
+ encoder.Encode(&bookmark_bar_node, &other_node));
+ std::string content;
+ JSONWriter::Write(encoded_bookmarks.get(), true, &content);
- // And all URLs should be parented.
- if (!unparented_urls.empty())
- NOTREACHED() << "Bookmarks not on the bookmark/'other folder' exist";
-
- if (!empty_url_ids.empty())
- NOTREACHED() << "Bookmarks with no corresponding URL exist";
-
- STLDeleteElements(&roots);
- STLDeleteElements(&unparented_urls);
-#endif NDEBUG
+ return (file_util::WriteFile(path, content.c_str(),
+ static_cast<int>(content.length())) != -1);
}
} // namespace history
diff --git a/chrome/browser/history/starred_url_database.h b/chrome/browser/history/starred_url_database.h
index d58571d..e7a774f 100644
--- a/chrome/browser/history/starred_url_database.h
+++ b/chrome/browser/history/starred_url_database.h
@@ -44,12 +44,9 @@ class SqliteStatementCache;
namespace history {
-// Encapsulates a URL database plus starred information.
-//
-// WARNING: many of the following methods allow you to update, delete or
-// insert starred entries specifying a visual order. These methods do NOT
-// adjust the visual order of surrounding entries. You must explicitly do
-// it yourself using AdjustStarredVisualOrder as appropriate.
+// Bookmarks were originally part of the url database, they have since been
+// moved to a separate file. This file exists purely for historical reasons and
+// contains just enough to allow migration.
class StarredURLDatabase : public URLDatabase {
public:
// Must call InitStarTable() AND any additional init functions provided by
@@ -57,87 +54,22 @@ class StarredURLDatabase : public URLDatabase {
StarredURLDatabase();
virtual ~StarredURLDatabase();
- // Returns the id of the starred entry. This does NOT return entry.id,
- // rather the database is queried for the id based on entry.url or
- // entry.group_id.
- StarID GetStarIDForEntry(const StarredEntry& entry);
-
- // Returns the internal star ID for the externally-generated group ID.
- StarID GetStarIDForGroupID(UIStarID group_id);
-
- // Gets the details for the specified star entry in entry.
- bool GetStarredEntry(StarID star_id, StarredEntry* entry);
-
- // Creates a starred entry with the requested information. The structure will
- // be updated with the ID of the newly created entry. The URL table will be
- // updated to point to the entry. The URL row will be created if it doesn't
- // exist.
- //
- // We currently only support one entry per URL. This URL should not already be
- // starred when calling this function or it will fail and will return 0.
- StarID CreateStarredEntry(StarredEntry* entry);
-
- // Returns starred entries.
- // This returns three different result types:
- // only_on_bookmark_bar == true: only those entries on the bookmark bar are
- // returned.
- // only_on_bookmark_bar == false and parent_id == 0: all starred
- // entries/groups.
- // otherwise only the direct children (groups and entries) of parent_id are
- // returned.
- bool GetStarredEntries(UIStarID parent_group_id,
- std::vector<StarredEntry>* entries);
-
- // Deletes a starred entry. This adjusts the visual order of all siblings
- // after the entry. The deleted entry(s) will be *appended* to
- // |*deleted_entries| (so delete can be called more than once with the same
- // list) and deleted URLs will additionally be added to the set.
- //
- // This function invokes DeleteStarredEntryImpl to do the actual work, which
- // recurses.
- void DeleteStarredEntry(StarID star_id,
- std::set<GURL>* unstarred_urls,
- std::vector<StarredEntry>* deleted_entries);
-
- // Implementation to update the database for UpdateStarredEntry. Returns true
- // on success. If successful, the parent_id, url_id, id and date_added fields
- // of the entry are reset from that of the database.
- bool UpdateStarredEntry(StarredEntry* entry);
-
- // Gets up to max_count starred entries of type URL adding them to entries.
- // The results are ordered by date added in descending order (most recent
- // first).
- void GetMostRecentStarredEntries(int max_count,
- std::vector<StarredEntry>* entries);
-
- // Gets the URLIDs for all starred entries of type URL whose title matches
- // the specified query.
- void GetURLsForTitlesMatching(const std::wstring& query,
- std::set<URLID>* ids);
-
- // Returns true if the starred table is in a sane state. If false, the starred
- // table is likely corrupt and shouldn't be used.
- bool is_starred_valid() const { return is_starred_valid_; }
-
- // Updates the URL ID for the given starred entry. This is used by the expirer
- // when URL IDs change. It can't use UpdateStarredEntry since that doesn't
- // set the URLID, and it does a bunch of other logic that we don't need.
- bool UpdateURLIDForStar(StarID star_id, URLID new_url_id);
-
protected:
// The unit tests poke our innards.
friend class HistoryTest;
+ friend class StarredURLDatabaseTest;
FRIEND_TEST(HistoryTest, CreateStarGroup);
+ // Writes bookmarks to the specified file.
+ bool MigrateBookmarksToFile(const std::wstring& path);
+
// Returns the database and statement cache for the functions in this
// interface. The decendent of this class implements these functions to
// return its objects.
virtual sqlite3* GetDB() = 0;
virtual SqliteStatementCache& GetStatementCache() = 0;
- // Creates the starred tables if necessary.
- bool InitStarTable();
-
+ private:
// Makes sure the starred table is in a sane state. This does the following:
// . Makes sure there is a bookmark bar and other nodes. If no bookmark bar
// node is found, the table is dropped and recreated.
@@ -155,17 +87,8 @@ class StarredURLDatabase : public URLDatabase {
// This should be invoked after migration.
bool EnsureStarredIntegrity();
- // Creates a starred entry with the specified parameters in the database.
- // Returns the newly created id, or 0 on failure.
- //
- // WARNING: Does not update the visual order.
- StarID CreateStarredEntryRow(URLID url_id,
- UIStarID group_id,
- UIStarID parent_group_id,
- const std::wstring& title,
- const Time& date_added,
- int visual_order,
- StarredEntry::Type type);
+ // Gets all the starred entries.
+ bool GetAllStarredEntries(std::vector<StarredEntry>* entries);
// Sets the title, parent_id, parent_group_id, visual_order and date_modifed
// of the specified star entry.
@@ -185,26 +108,39 @@ class StarredURLDatabase : public URLDatabase {
int start_visual_order,
int delta);
+ // Creates a starred entry with the specified parameters in the database.
+ // Returns the newly created id, or 0 on failure.
+ //
+ // WARNING: Does not update the visual order.
+ StarID CreateStarredEntryRow(URLID url_id,
+ UIStarID group_id,
+ UIStarID parent_group_id,
+ const std::wstring& title,
+ const Time& date_added,
+ int visual_order,
+ StarredEntry::Type type);
+
// Deletes the entry from the starred database base on the starred id (NOT
// the url id).
//
// WARNING: Does not update the visual order.
bool DeleteStarredEntryRow(StarID star_id);
- // Should the integrity of the starred table be checked on every mutation?
- // Default is true. Set to false when running tests that need to allow the
- // table to be in an invalid state while testing.
- bool check_starred_integrity_on_mutation_;
+ // Gets the details for the specified star entry in entry.
+ bool GetStarredEntry(StarID star_id, StarredEntry* entry);
+
+ // Creates a starred entry with the requested information. The structure will
+ // be updated with the ID of the newly created entry. The URL table will be
+ // updated to point to the entry. The URL row will be created if it doesn't
+ // exist.
+ //
+ // We currently only support one entry per URL. This URL should not already be
+ // starred when calling this function or it will fail and will return 0.
+ StarID CreateStarredEntry(StarredEntry* entry);
- private:
// Used when checking integrity of starred table.
typedef ChromeViews::TreeNodeWithValue<history::StarredEntry> StarredNode;
- // Implementation of DeleteStarredEntryImpl.
- void DeleteStarredEntryImpl(StarID star_id,
- std::set<GURL>* unstarred_urls,
- std::vector<StarredEntry>* deleted_entries);
-
// Returns the max group id, or 0 if there is an error.
UIStarID GetMaxGroupID();
@@ -262,24 +198,9 @@ class StarredURLDatabase : public URLDatabase {
// needs to be moved.
bool Move(StarredNode* source, StarredNode* new_parent);
- // Drops and recreates the starred table as well as marking all URLs as
- // unstarred. This is used as a last resort if the bookmarks table is
- // totally corrupt.
- bool RecreateStarredEntries();
-
- // Iterates through the children of node make sure the visual order matches
- // the order in node's children. DCHECKs if the order differs. This recurses.
- void CheckVisualOrder(StarredNode* node);
-
- // Makes sure the starred table is in a sane state, if not this DCHECKs.
- // This is invoked internally after any mutation to the starred table.
- //
- // This is a no-op in release builds.
- void CheckStarredIntegrity();
-
- // True if the starred table is valid. This is initialized in
- // EnsureStarredIntegrityImpl.
- bool is_starred_valid_;
+ // Does the work of migrating bookmarks to a temporary file that
+ // BookmarkStorage will read from.
+ bool MigrateBookmarksToFileImpl(const std::wstring& path);
DISALLOW_EVIL_CONSTRUCTORS(StarredURLDatabase);
};
diff --git a/chrome/browser/history/starred_url_database_unittest.cc b/chrome/browser/history/starred_url_database_unittest.cc
index aca91d9..c59c122 100644
--- a/chrome/browser/history/starred_url_database_unittest.cc
+++ b/chrome/browser/history/starred_url_database_unittest.cc
@@ -34,6 +34,7 @@
#include "base/string_util.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/history/starred_url_database.h"
+#include "chrome/common/chrome_paths.h"
#include "chrome/common/sqlite_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -51,18 +52,6 @@ class StarredURLDatabaseTest : public testing::Test,
EXPECT_TRUE(AddURL(row));
}
- StarredEntry GetStarredEntryByURL(const GURL& url) {
- std::vector<StarredEntry> starred;
- EXPECT_TRUE(GetStarredEntries(0, &starred));
- for (std::vector<StarredEntry>::iterator i = starred.begin();
- i != starred.end(); ++i) {
- if (i->url == url)
- return *i;
- }
- EXPECT_TRUE(false);
- return StarredEntry();
- }
-
void CompareEntryByID(const StarredEntry& entry) {
DCHECK(entry.id != 0);
StarredEntry db_value;
@@ -82,43 +71,20 @@ class StarredURLDatabaseTest : public testing::Test,
int GetStarredEntryCount() {
DCHECK(db_);
std::vector<StarredEntry> entries;
- GetStarredEntries(0, &entries);
+ GetAllStarredEntries(&entries);
return static_cast<int>(entries.size());
}
- bool GetURLStarred(const GURL& url) {
- URLRow row;
- if (GetRowForURL(url, &row))
- return row.starred();
- return false;
+ StarID CreateStarredEntry(StarredEntry* entry) {
+ return StarredURLDatabase::CreateStarredEntry(entry);
+ }
+
+ bool GetStarredEntry(StarID star_id, StarredEntry* entry) {
+ return StarredURLDatabase::GetStarredEntry(star_id, entry);
}
- void VerifyInitialState() {
- std::vector<StarredEntry> star_entries;
- EXPECT_TRUE(GetStarredEntries(0, &star_entries));
- EXPECT_EQ(2, star_entries.size());
-
- int bb_index = -1;
- size_t other_index = -1;
- if (star_entries[0].type == history::StarredEntry::BOOKMARK_BAR) {
- bb_index = 0;
- other_index = 1;
- } else {
- bb_index = 1;
- other_index = 0;
- }
- EXPECT_EQ(HistoryService::kBookmarkBarID, star_entries[bb_index].id);
- EXPECT_EQ(HistoryService::kBookmarkBarID, star_entries[bb_index].group_id);
- EXPECT_EQ(0, star_entries[bb_index].parent_group_id);
- EXPECT_EQ(StarredEntry::BOOKMARK_BAR, star_entries[bb_index].type);
-
- EXPECT_TRUE(star_entries[other_index].id != HistoryService::kBookmarkBarID
- && star_entries[other_index].id != 0);
- EXPECT_TRUE(star_entries[other_index].group_id !=
- HistoryService::kBookmarkBarID &&
- star_entries[other_index].group_id != 0);
- EXPECT_EQ(0, star_entries[other_index].parent_group_id);
- EXPECT_EQ(StarredEntry::OTHER, star_entries[other_index].type);
+ bool EnsureStarredIntegrity() {
+ return StarredURLDatabase::EnsureStarredIntegrity();
}
private:
@@ -129,13 +95,19 @@ class StarredURLDatabaseTest : public testing::Test,
db_file_.append(L"VisitTest.db");
file_util::Delete(db_file_, false);
+ // Copy db file over that contains starred table.
+ std::wstring old_history_path;
+ PathService::Get(chrome::DIR_TEST_DATA, &old_history_path);
+ file_util::AppendToPath(&old_history_path, L"bookmarks");
+ file_util::AppendToPath(&old_history_path, L"History_with_empty_starred");
+ file_util::CopyFile(old_history_path, db_file_);
+
EXPECT_EQ(SQLITE_OK, sqlite3_open(WideToUTF8(db_file_).c_str(), &db_));
statement_cache_ = new SqliteStatementCache(db_);
// Initialize the tables for this test.
CreateURLTable(false);
CreateMainURLIndex();
- InitStarTable();
EnsureStarredIntegrity();
}
void TearDown() {
@@ -159,307 +131,7 @@ class StarredURLDatabaseTest : public testing::Test,
//-----------------------------------------------------------------------------
-TEST_F(StarredURLDatabaseTest, CreateStarredEntryUnstarred) {
- StarredEntry entry;
- entry.title = L"blah";
- entry.date_added = Time::Now();
- entry.url = GURL("http://www.google.com");
- entry.parent_group_id = HistoryService::kBookmarkBarID;
-
- StarID id = CreateStarredEntry(&entry);
-
- EXPECT_NE(0, id);
- EXPECT_EQ(id, entry.id);
- CompareEntryByID(entry);
-}
-
-TEST_F(StarredURLDatabaseTest, UpdateStarredEntry) {
- const int initial_count = GetStarredEntryCount();
- StarredEntry entry;
- entry.title = L"blah";
- entry.date_added = Time::Now();
- entry.url = GURL("http://www.google.com");
- entry.parent_group_id = HistoryService::kBookmarkBarID;
-
- StarID id = CreateStarredEntry(&entry);
- EXPECT_NE(0, id);
- EXPECT_EQ(id, entry.id);
- CompareEntryByID(entry);
-
- // Now invoke create again, as the URL hasn't changed this should just
- // update the title.
- EXPECT_TRUE(UpdateStarredEntry(&entry));
- CompareEntryByID(entry);
-
- // There should only be two entries (one for the url we created, one for the
- // bookmark bar).
- EXPECT_EQ(initial_count + 1, GetStarredEntryCount());
-}
-
-TEST_F(StarredURLDatabaseTest, DeleteStarredGroup) {
- const int initial_count = GetStarredEntryCount();
- StarredEntry entry;
- entry.type = StarredEntry::USER_GROUP;
- entry.title = L"blah";
- entry.date_added = Time::Now();
- entry.group_id = 10;
- entry.parent_group_id = HistoryService::kBookmarkBarID;
-
- StarID id = CreateStarredEntry(&entry);
- EXPECT_NE(0, id);
- EXPECT_NE(HistoryService::kBookmarkBarID, id);
- CompareEntryByID(entry);
-
- EXPECT_EQ(initial_count + 1, GetStarredEntryCount());
-
- // Now delete it.
- std::set<GURL> unstarred_urls;
- std::vector<StarredEntry> deleted_entries;
- DeleteStarredEntry(entry.id, &unstarred_urls, &deleted_entries);
- ASSERT_EQ(0, unstarred_urls.size());
- ASSERT_EQ(1, deleted_entries.size());
- EXPECT_EQ(deleted_entries[0].id, id);
-
- // Should only have the bookmark bar.
- EXPECT_EQ(initial_count, GetStarredEntryCount());
-}
-
-TEST_F(StarredURLDatabaseTest, DeleteStarredGroupWithChildren) {
- const int initial_count = GetStarredEntryCount();
-
- StarredEntry entry;
- entry.type = StarredEntry::USER_GROUP;
- entry.title = L"blah";
- entry.date_added = Time::Now();
- entry.group_id = 10;
- entry.parent_group_id = HistoryService::kBookmarkBarID;
-
- StarID id = CreateStarredEntry(&entry);
- EXPECT_NE(0, id);
- EXPECT_NE(HistoryService::kBookmarkBarID, id);
- CompareEntryByID(entry);
-
- EXPECT_EQ(initial_count + 1, GetStarredEntryCount());
-
- // Create a child of the group.
- StarredEntry url_entry1;
- url_entry1.parent_group_id = entry.group_id;
- url_entry1.title = L"blah";
- url_entry1.date_added = Time::Now();
- url_entry1.url = GURL("http://www.google.com");
- StarID url_id1 = CreateStarredEntry(&url_entry1);
- EXPECT_NE(0, url_id1);
- CompareEntryByID(url_entry1);
-
- // Create a sibling of the group.
- StarredEntry url_entry2;
- url_entry2.parent_group_id = HistoryService::kBookmarkBarID;
- url_entry2.title = L"blah";
- url_entry2.date_added = Time::Now();
- url_entry2.url = GURL("http://www.google2.com");
- url_entry2.visual_order = 1;
- StarID url_id2 = CreateStarredEntry(&url_entry2);
- EXPECT_NE(0, url_id2);
- CompareEntryByID(url_entry2);
-
- EXPECT_EQ(initial_count + 3, GetStarredEntryCount());
-
- // Now delete the group, which should delete url_entry1 and shift down the
- // visual order of url_entry2.
- std::set<GURL> unstarred_urls;
- std::vector<StarredEntry> deleted_entries;
- DeleteStarredEntry(entry.id, &unstarred_urls, &deleted_entries);
- EXPECT_EQ(2, deleted_entries.size());
- EXPECT_EQ(1, unstarred_urls.size());
- EXPECT_TRUE((deleted_entries[0].id == id) || (deleted_entries[1].id == id));
- EXPECT_TRUE((deleted_entries[0].id == url_id1) ||
- (deleted_entries[1].id == url_id1));
-
- url_entry2.visual_order--;
- CompareEntryByID(url_entry2);
-
- // Should have the bookmark bar, and url_entry2.
- EXPECT_EQ(initial_count + 1, GetStarredEntryCount());
-}
-
-TEST_F(StarredURLDatabaseTest, InitialState) {
- VerifyInitialState();
-}
-
-TEST_F(StarredURLDatabaseTest, CreateStarGroup) {
- const int initial_count = GetStarredEntryCount();
- std::wstring title(L"title");
- Time time(Time::Now());
- int visual_order = 0;
-
- UIStarID ui_group_id = 10;
- UIStarID ui_parent_group_id = HistoryService::kBookmarkBarID;
-
- StarredEntry entry;
- entry.type = StarredEntry::USER_GROUP;
- entry.group_id = ui_group_id;
- entry.parent_group_id = ui_parent_group_id;
- entry.title = title;
- entry.date_added = time;
- entry.visual_order = visual_order;
- StarID group_id = CreateStarredEntry(&entry);
-
- EXPECT_NE(0, group_id);
- EXPECT_NE(HistoryService::kBookmarkBarID, group_id);
-
- EXPECT_EQ(group_id, GetStarIDForGroupID(ui_group_id));
-
- StarredEntry group_entry;
- EXPECT_TRUE(GetStarredEntry(group_id, &group_entry));
- EXPECT_EQ(ui_group_id, group_entry.group_id);
- EXPECT_EQ(ui_parent_group_id, group_entry.parent_group_id);
- EXPECT_TRUE(group_entry.title == title);
- // Don't use Time.== here as the conversion to time_t when writing to the db
- // is lossy.
- EXPECT_TRUE(group_entry.date_added.ToTimeT() == time.ToTimeT());
- EXPECT_EQ(visual_order, group_entry.visual_order);
-
- // Update the date modified.
- Time date_modified = Time::Now();
- entry.date_group_modified = date_modified;
- UpdateStarredEntry(&group_entry);
- EXPECT_TRUE(GetStarredEntry(group_id, &group_entry));
- EXPECT_TRUE(entry.date_group_modified.ToTimeT() == date_modified.ToTimeT());
-}
-
-TEST_F(StarredURLDatabaseTest, UpdateStarredEntryChangeVisualOrder) {
- const int initial_count = GetStarredEntryCount();
- GURL url1(L"http://google.com/1");
- GURL url2(L"http://google.com/2");
-
- // Star url1, making it a child of the bookmark bar.
- StarredEntry entry;
- entry.url = url1;
- entry.title = L"FOO";
- entry.parent_group_id = HistoryService::kBookmarkBarID;
- CreateStarredEntry(&entry);
-
- // Make sure it was created correctly.
- entry = GetStarredEntryByURL(url1);
- EXPECT_EQ(GetRowForURL(url1, NULL), entry.url_id);
- CompareEntryByID(entry);
-
- // Star url2, making it a child of the bookmark bar, placing it after url2.
- StarredEntry entry2;
- entry2.url = url2;
- entry2.visual_order = 1;
- entry2.title = std::wstring();
- entry2.parent_group_id = HistoryService::kBookmarkBarID;
- CreateStarredEntry(&entry2);
- entry2 = GetStarredEntryByURL(url2);
- EXPECT_EQ(GetRowForURL(url2, NULL), entry2.url_id);
- CompareEntryByID(entry2);
-
- // Move url2 to be before url1.
- entry2.visual_order = 0;
- UpdateStarredEntry(&entry2);
- CompareEntryByID(entry2);
-
- // URL1's visual order should have shifted by one to accommodate URL2.
- entry.visual_order = 1;
- CompareEntryByID(entry);
-
- // Now move URL1 to position 0, which will move url2 to position 1.
- entry.visual_order = 0;
- UpdateStarredEntry(&entry);
- CompareEntryByID(entry);
-
- entry2.visual_order = 1;
- CompareEntryByID(entry2);
-
- // Create a new group between url1 and url2.
- StarredEntry g_entry;
- g_entry.group_id = 10;
- g_entry.parent_group_id = HistoryService::kBookmarkBarID;
- g_entry.title = L"blah";
- g_entry.visual_order = 1;
- g_entry.date_added = Time::Now();
- g_entry.type = StarredEntry::USER_GROUP;
- g_entry.id = CreateStarredEntry(&g_entry);
- EXPECT_NE(0, g_entry.id);
- CompareEntryByID(g_entry);
-
- // URL2 should have shifted to position 2.
- entry2.visual_order = 2;
- CompareEntryByID(entry2);
-
- // Move url2 inside of group 1.
- entry2.visual_order = 0;
- entry2.parent_group_id = g_entry.group_id;
- UpdateStarredEntry(&entry2);
- CompareEntryByID(entry2);
-
- // Move url1 to be a child of group 1 at position 0.
- entry.parent_group_id = g_entry.group_id;
- entry.visual_order = 0;
- UpdateStarredEntry(&entry);
- CompareEntryByID(entry);
-
- // url2 should have moved to position 1.
- entry2.visual_order = 1;
- CompareEntryByID(entry2);
-
- // And the group should have shifted to position 0.
- g_entry.visual_order = 0;
- CompareEntryByID(g_entry);
-
- EXPECT_EQ(initial_count + 3, GetStarredEntryCount());
-
- // Delete the group, which should unstar url1 and url2.
- std::set<GURL> unstarred_urls;
- std::vector<StarredEntry> deleted_entries;
- DeleteStarredEntry(g_entry.id, &unstarred_urls, &deleted_entries);
- EXPECT_EQ(initial_count, GetStarredEntryCount());
- URLRow url_row;
- GetRowForURL(url1, &url_row);
- EXPECT_EQ(0, url_row.star_id());
- GetRowForURL(url2, &url_row);
- EXPECT_EQ(0, url_row.star_id());
-}
-
-TEST_F(StarredURLDatabaseTest, GetMostRecentStarredEntries) {
- // Initially there shouldn't be any entries (only the bookmark bar, which
- // isn't returned by GetMostRecentStarredEntries).
- std::vector<StarredEntry> starred_entries;
- GetMostRecentStarredEntries(10, &starred_entries);
- EXPECT_EQ(0, starred_entries.size());
-
- // Star url1.
- GURL url1(L"http://google.com/1");
- StarredEntry entry1;
- entry1.type = StarredEntry::URL;
- entry1.url = url1;
- entry1.parent_group_id = HistoryService::kBookmarkBarID;
- CreateStarredEntry(&entry1);
-
- // Get the recent ones.
- GetMostRecentStarredEntries(10, &starred_entries);
- ASSERT_EQ(1, starred_entries.size());
- EXPECT_TRUE(starred_entries[0].url == url1);
-
- // Add url2 and star it.
- GURL url2(L"http://google.com/2");
- StarredEntry entry2;
- entry2.type = StarredEntry::URL;
- entry2.url = url2;
- entry2.parent_group_id = HistoryService::kBookmarkBarID;
- CreateStarredEntry(&entry2);
-
- starred_entries.clear();
- GetMostRecentStarredEntries(10, &starred_entries);
- ASSERT_EQ(2, starred_entries.size());
- EXPECT_TRUE(starred_entries[0].url == url2);
- EXPECT_TRUE(starred_entries[1].url == url1);
-}
-
TEST_F(StarredURLDatabaseTest, FixOrphanedGroup) {
- check_starred_integrity_on_mutation_ = false;
-
const size_t initial_count = GetStarredEntryCount();
// Create a group that isn't parented to the other/bookmark folders.
@@ -482,8 +154,6 @@ TEST_F(StarredURLDatabaseTest, FixOrphanedGroup) {
}
TEST_F(StarredURLDatabaseTest, FixOrphanedBookmarks) {
- check_starred_integrity_on_mutation_ = false;
-
const size_t initial_count = GetStarredEntryCount();
// Create two bookmarks that aren't in a random folder no on the bookmark bar.
@@ -516,8 +186,6 @@ TEST_F(StarredURLDatabaseTest, FixOrphanedBookmarks) {
}
TEST_F(StarredURLDatabaseTest, FixGroupCycleDepth0) {
- check_starred_integrity_on_mutation_ = false;
-
const size_t initial_count = GetStarredEntryCount();
// Create a group that is parented to itself.
@@ -540,8 +208,6 @@ TEST_F(StarredURLDatabaseTest, FixGroupCycleDepth0) {
}
TEST_F(StarredURLDatabaseTest, FixGroupCycleDepth1) {
- check_starred_integrity_on_mutation_ = false;
-
const size_t initial_count = GetStarredEntryCount();
StarredEntry entry1;
@@ -574,8 +240,6 @@ TEST_F(StarredURLDatabaseTest, FixGroupCycleDepth1) {
}
TEST_F(StarredURLDatabaseTest, FixVisualOrder) {
- check_starred_integrity_on_mutation_ = false;
-
const size_t initial_count = GetStarredEntryCount();
// Star two urls.
@@ -607,29 +271,7 @@ TEST_F(StarredURLDatabaseTest, FixVisualOrder) {
CompareEntryByID(entry2);
}
-TEST_F(StarredURLDatabaseTest, RestoreOtherAndBookmarkBar) {
- std::vector<StarredEntry> entries;
- GetStarredEntries(0, &entries);
-
- check_starred_integrity_on_mutation_ = false;
-
- for (std::vector<StarredEntry>::iterator i = entries.begin();
- i != entries.end(); ++i) {
- if (i->type != StarredEntry::USER_GROUP) {
- // Use this directly, otherwise we assert trying to delete other/bookmark
- // bar.
- DeleteStarredEntryRow(i->id);
-
- ASSERT_TRUE(EnsureStarredIntegrity());
-
- VerifyInitialState();
- }
- }
-}
-
TEST_F(StarredURLDatabaseTest, FixDuplicateGroupIDs) {
- check_starred_integrity_on_mutation_ = false;
-
const size_t initial_count = GetStarredEntryCount();
// Create two groups with the same group id.
diff --git a/chrome/browser/history/text_database.h b/chrome/browser/history/text_database.h
index f04f8c0..4bcccd0 100644
--- a/chrome/browser/history/text_database.h
+++ b/chrome/browser/history/text_database.h
@@ -142,8 +142,6 @@ class TextDatabase {
// Querying ------------------------------------------------------------------
// Executes the given query. See QueryOptions for more info on input.
- // Note that the options.only_starred is ignored since this database does not
- // have access to star information.
//
// The results are appended to any existing ones in |*results|, and the first
// time considered for the output is in |first_time_searched|
diff --git a/chrome/browser/history/text_database_manager.h b/chrome/browser/history/text_database_manager.h
index 2506835..7685135b 100644
--- a/chrome/browser/history/text_database_manager.h
+++ b/chrome/browser/history/text_database_manager.h
@@ -165,8 +165,6 @@ class TextDatabaseManager {
void OptimizeChangedDatabases(const ChangeSet& change_set);
// Executes the given query. See QueryOptions for more info on input.
- // Note that the options.only_starred is ignored since this database does not
- // have access to star information.
//
// The results are filled into |results|, and the first time considered for
// the output is in |first_time_searched| (see QueryResults for more).
diff --git a/chrome/browser/history/url_database.cc b/chrome/browser/history/url_database.cc
index 0ce8072..899f04c 100644
--- a/chrome/browser/history/url_database.cc
+++ b/chrome/browser/history/url_database.cc
@@ -74,7 +74,6 @@ void URLDatabase::FillURLRow(SQLStatement& s, history::URLRow* i) {
i->last_visit_ = Time::FromInternalValue(s.column_int64(5));
i->hidden_ = s.column_int(6) != 0;
i->favicon_id_ = s.column_int64(7);
- i->star_id_ = s.column_int64(8);
}
bool URLDatabase::GetURLRow(URLID url_id, URLRow* info) {
@@ -115,7 +114,7 @@ bool URLDatabase::UpdateURLRow(URLID url_id,
const history::URLRow& info) {
SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
"UPDATE urls SET title=?,visit_count=?,typed_count=?,last_visit_time=?,"
- "hidden=?,starred_id=?,favicon_id=?"
+ "hidden=?,favicon_id=?"
"WHERE id=?");
if (!statement.is_valid())
return false;
@@ -125,9 +124,8 @@ bool URLDatabase::UpdateURLRow(URLID url_id,
statement->bind_int(2, info.typed_count());
statement->bind_int64(3, info.last_visit().ToInternalValue());
statement->bind_int(4, info.hidden() ? 1 : 0);
- statement->bind_int64(5, info.star_id());
- statement->bind_int64(6, info.favicon_id());
- statement->bind_int64(7, url_id);
+ statement->bind_int64(5, info.favicon_id());
+ statement->bind_int64(6, url_id);
return statement->step() == SQLITE_DONE;
}
@@ -139,8 +137,8 @@ URLID URLDatabase::AddURLInternal(const history::URLRow& info,
// invalid in the insert syntax.
#define ADDURL_COMMON_SUFFIX \
"(url,title,visit_count,typed_count,"\
- "last_visit_time,hidden,starred_id,favicon_id)"\
- "VALUES(?,?,?,?,?,?,?,?)"
+ "last_visit_time,hidden,favicon_id)"\
+ "VALUES(?,?,?,?,?,?,?)"
const char* statement_name;
const char* statement_sql;
if (is_temporary) {
@@ -163,8 +161,7 @@ URLID URLDatabase::AddURLInternal(const history::URLRow& info,
statement->bind_int(3, info.typed_count());
statement->bind_int64(4, info.last_visit().ToInternalValue());
statement->bind_int(5, info.hidden() ? 1 : 0);
- statement->bind_int64(6, info.star_id());
- statement->bind_int64(7, info.favicon_id());
+ statement->bind_int64(6, info.favicon_id());
if (statement->step() != SQLITE_DONE)
return 0;
@@ -250,21 +247,15 @@ bool URLDatabase::IsFavIconUsed(FavIconID favicon_id) {
}
void URLDatabase::AutocompleteForPrefix(const std::wstring& prefix,
- size_t max_results,
- std::vector<history::URLRow>* results) {
+ size_t max_results,
+ std::vector<history::URLRow>* results) {
+ // TODO(sky): this query should order by starred as the second order by
+ // clause.
results->clear();
-
- // NOTE: Sorting by "starred_id == 0" is subtle. First we do the comparison,
- // and, according to the SQLite docs, get a numeric result (all binary
- // operators except "||" result in a numeric value), which is either 1 or 0
- // (implied by documentation showing the results of various comparison
- // operations to always be 1 or 0). Now we sort ascending, meaning all 0s go
- // first -- so, all URLs where "starred_id == 0" is 0, i.e. all starred URLs.
SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(),
"SELECT" HISTORY_URL_ROW_FIELDS "FROM urls "
"WHERE url >= ? AND url < ? AND hidden = 0 "
- "ORDER BY typed_count DESC, starred_id == 0, visit_count DESC, "
- "last_visit_time DESC "
+ "ORDER BY typed_count DESC, visit_count DESC, last_visit_time DESC "
"LIMIT ?");
if (!statement.is_valid())
return;
@@ -443,6 +434,36 @@ bool URLDatabase::MigrateFromVersion11ToVersion12() {
return true;
}
+bool URLDatabase::DropStarredIDFromURLs() {
+ if (!DoesSqliteColumnExist(GetDB(), "urls", "starred_id", NULL))
+ return true; // urls is already updated, no need to continue.
+
+ // Create a temporary table to contain the new URLs table.
+ if (!CreateTemporaryURLTable()) {
+ NOTREACHED();
+ return false;
+ }
+
+ // Copy the contents.
+ const char* insert_statement =
+ "INSERT INTO temp_urls (id, url, title, visit_count, typed_count, "
+ "last_visit_time, hidden, favicon_id) "
+ "SELECT id, url, title, visit_count, typed_count, last_visit_time, "
+ "hidden, favicon_id FROM urls";
+ if (sqlite3_exec(GetDB(), insert_statement, NULL, NULL, NULL) != SQLITE_OK) {
+ NOTREACHED();
+ return false;
+ }
+
+ // Rename/commit the tmp table.
+ CommitTemporaryURLTable();
+
+ // This isn't created by CommitTemporaryURLTable.
+ CreateSupplimentaryURLIndices();
+
+ return true;
+}
+
bool URLDatabase::CreateURLTable(bool is_temporary) {
const char* name = is_temporary ? "temp_urls" : "urls";
if (DoesSqliteTableExist(GetDB(), name))
@@ -459,8 +480,7 @@ bool URLDatabase::CreateURLTable(bool is_temporary) {
"typed_count INTEGER DEFAULT 0 NOT NULL,"
"last_visit_time INTEGER NOT NULL,"
"hidden INTEGER DEFAULT 0 NOT NULL,"
- "favicon_id INTEGER DEFAULT 0 NOT NULL,"
- "starred_id INTEGER DEFAULT 0 NOT NULL)");
+ "favicon_id INTEGER DEFAULT 0 NOT NULL)");
return sqlite3_exec(GetDB(), sql.c_str(), NULL, NULL, NULL) == SQLITE_OK;
}
@@ -476,10 +496,6 @@ void URLDatabase::CreateSupplimentaryURLIndices() {
// Add a favicon index. This is useful when we delete urls.
sqlite3_exec(GetDB(), "CREATE INDEX urls_favicon_id_INDEX ON urls (favicon_id)",
NULL, NULL, NULL);
-
- // Index on starred_id.
- sqlite3_exec(GetDB(), "CREATE INDEX urls_starred_id_INDEX ON urls "
- "(starred_id)", NULL, NULL, NULL);
}
} // namespace history
diff --git a/chrome/browser/history/url_database.h b/chrome/browser/history/url_database.h
index 300c05b..f27c4b9 100644
--- a/chrome/browser/history/url_database.h
+++ b/chrome/browser/history/url_database.h
@@ -247,6 +247,8 @@ class URLDatabase {
int max_count,
std::vector<KeywordSearchTermVisit>* matches);
+ // Migration -----------------------------------------------------------------
+
// Do to a bug we were setting the favicon of about:blank. This forces
// about:blank to have no icon or title. Returns true on success, false if
// the favicon couldn't be updated.
@@ -263,6 +265,11 @@ class URLDatabase {
// fields following kURLRowFields.
static const int kNumURLRowFields;
+ // Drops the starred_id column from urls, returning true on success. This does
+ // nothing (and returns true) if the urls doesn't contain the starred_id
+ // column.
+ bool DropStarredIDFromURLs();
+
// Initialization functions. The indexing functions are separate from the
// table creation functions so the in-memory database and the temporary tables
// used when clearing history can populate the table and then create the
@@ -319,7 +326,7 @@ class URLDatabase {
// string dynamically anyway, use the constant, it will save space.
#define HISTORY_URL_ROW_FIELDS \
" urls.id, urls.url, urls.title, urls.visit_count, urls.typed_count, " \
- "urls.last_visit_time, urls.hidden, urls.favicon_id, urls.starred_id "
+ "urls.last_visit_time, urls.hidden, urls.favicon_id "
} // history
diff --git a/chrome/browser/history/url_database_unittest.cc b/chrome/browser/history/url_database_unittest.cc
index 7f2bdae..4983a5d 100644
--- a/chrome/browser/history/url_database_unittest.cc
+++ b/chrome/browser/history/url_database_unittest.cc
@@ -48,8 +48,7 @@ bool IsURLRowEqual(const URLRow& a,
a.visit_count() == b.visit_count() &&
a.typed_count() == b.typed_count() &&
a.last_visit() - b.last_visit() <= TimeDelta::FromSeconds(1) &&
- a.hidden() == b.hidden() &&
- a.starred() == b.starred();
+ a.hidden() == b.hidden();
}
class URLDatabaseTest : public testing::Test,