summaryrefslogtreecommitdiffstats
path: root/chrome/browser/history/top_sites_database.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/history/top_sites_database.cc')
-rw-r--r--chrome/browser/history/top_sites_database.cc219
1 files changed, 150 insertions, 69 deletions
diff --git a/chrome/browser/history/top_sites_database.cc b/chrome/browser/history/top_sites_database.cc
index 5c1939f..db9156d 100644
--- a/chrome/browser/history/top_sites_database.cc
+++ b/chrome/browser/history/top_sites_database.cc
@@ -9,19 +9,44 @@
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/history/top_sites.h"
#include "chrome/browser/history/top_sites_database.h"
+#include "chrome/common/thumbnail_score.h"
#include "sql/connection.h"
#include "sql/transaction.h"
+// Description of database table:
+//
+// thumbnails
+// url URL of the sites for which we have a thumbnail.
+// url_rank Index of the URL in that thumbnail, 0-based. The thumbnail
+// with the highest rank will be the next one evicted. Forced
+// thumbnails have a rank of -1.
+// title The title to display under that thumbnail.
+// redirects A space separated list of URLs that are known to redirect
+// to this url.
+// boring_score How "boring" that thumbnail is. See ThumbnailScore.
+// good_clipping True if the thumbnail was clipped from the bottom, keeping
+// the entire width of the window. See ThumbnailScore.
+// at_top True if the thumbnail was captured at the top of the
+// website.
+// last_updated The time at which this thumbnail was last updated.
+// load_completed True if the thumbnail was captured after the page load was
+// completed.
+// last_forced If this is a forced thumbnail, records the last time it
+// was forced. If it's not a forced thumbnail, 0.
+
namespace history {
+// TODO(beaudoin): Fill revision/date details of Version 3 after landing.
+// Version 3: by beaudoin@chromium.org
// Version 2: eb0b24e6/r87284 by satorux@chromium.org on 2011-05-31
// Version 1: 809cc4d8/r64072 by sky@chromium.org on 2010-10-27
// From the version 1 to 2, one column was added. Old versions of Chrome
-// should be able to read version 2 files just fine.
+// should be able to read version 2 files just fine. Same thing for version 2
+// to 3.
// NOTE(shess): When changing the version, add a new golden file for
// the new version and a test to verify that Init() works with it.
-static const int kVersionNumber = 2;
+static const int kVersionNumber = 3;
TopSitesDatabase::TopSitesDatabase() {
}
@@ -69,6 +94,13 @@ bool TopSitesDatabase::Init(const base::FilePath& db_name) {
}
}
+ if (meta_table_.GetVersionNumber() == 2) {
+ if (!UpgradeToVersion3()) {
+ LOG(WARNING) << "Unable to upgrade top sites database to version 3.";
+ return false;
+ }
+ }
+
// Version check.
if (meta_table_.GetVersionNumber() != kVersionNumber)
return false;
@@ -84,15 +116,16 @@ bool TopSitesDatabase::InitThumbnailTable() {
if (!db_->DoesTableExist("thumbnails")) {
if (!db_->Execute("CREATE TABLE thumbnails ("
"url LONGVARCHAR PRIMARY KEY,"
- "url_rank INTEGER ,"
+ "url_rank INTEGER,"
"title LONGVARCHAR,"
"thumbnail BLOB,"
"redirects LONGVARCHAR,"
- "boring_score DOUBLE DEFAULT 1.0, "
- "good_clipping INTEGER DEFAULT 0, "
- "at_top INTEGER DEFAULT 0, "
- "last_updated INTEGER DEFAULT 0, "
- "load_completed INTEGER DEFAULT 0) ")) {
+ "boring_score DOUBLE DEFAULT 1.0,"
+ "good_clipping INTEGER DEFAULT 0,"
+ "at_top INTEGER DEFAULT 0,"
+ "last_updated INTEGER DEFAULT 0,"
+ "load_completed INTEGER DEFAULT 0,"
+ "last_forced INTEGER DEFAULT 0)")) {
LOG(WARNING) << db_->GetErrorMessage();
return false;
}
@@ -111,13 +144,24 @@ bool TopSitesDatabase::UpgradeToVersion2() {
return true;
}
+bool TopSitesDatabase::UpgradeToVersion3() {
+ // Add 'last_forced' column.
+ if (!db_->Execute(
+ "ALTER TABLE thumbnails ADD last_forced INTEGER DEFAULT 0")) {
+ NOTREACHED();
+ return false;
+ }
+ meta_table_.SetVersionNumber(3);
+ return true;
+}
+
void TopSitesDatabase::GetPageThumbnails(MostVisitedURLList* urls,
URLToImagesMap* thumbnails) {
sql::Statement statement(db_->GetCachedStatement(
SQL_FROM_HERE,
"SELECT url, url_rank, title, thumbnail, redirects, "
- "boring_score, good_clipping, at_top, last_updated, load_completed "
- "FROM thumbnails ORDER BY url_rank "));
+ "boring_score, good_clipping, at_top, last_updated, load_completed, "
+ "last_forced FROM thumbnails ORDER BY url_rank, last_forced"));
if (!statement.is_valid()) {
LOG(WARNING) << db_->GetErrorMessage();
@@ -128,11 +172,14 @@ void TopSitesDatabase::GetPageThumbnails(MostVisitedURLList* urls,
thumbnails->clear();
while (statement.Step()) {
- // Results are sorted by url_rank.
+ // Results are sorted by url_rank. For forced thumbnails with url_rank = -1,
+ // thumbnails are sorted by last_forced.
MostVisitedURL url;
GURL gurl(statement.ColumnString(0));
url.url = gurl;
url.title = statement.ColumnString16(2);
+ url.last_forced_time =
+ base::Time::FromInternalValue(statement.ColumnInt64(10));
std::string redirects = statement.ColumnString(4);
SetRedirects(redirects, &url);
urls->push_back(url);
@@ -148,7 +195,6 @@ void TopSitesDatabase::GetPageThumbnails(MostVisitedURLList* urls,
thumbnail.thumbnail_score.time_at_snapshot =
base::Time::FromInternalValue(statement.ColumnInt64(8));
thumbnail.thumbnail_score.load_completed = statement.ColumnBool(9);
-
(*thumbnails)[gurl] = thumbnail;
}
}
@@ -171,13 +217,13 @@ void TopSitesDatabase::SetRedirects(const std::string& redirects,
}
void TopSitesDatabase::SetPageThumbnail(const MostVisitedURL& url,
- int new_rank,
- const Images& thumbnail) {
+ int new_rank,
+ const Images& thumbnail) {
sql::Transaction transaction(db_.get());
transaction.Begin();
int rank = GetURLRank(url);
- if (rank == -1) {
+ if (rank == kRankOfNonExistingURL) {
AddPageThumbnail(url, new_rank, thumbnail);
} else {
UpdatePageRankNoTransaction(url, new_rank);
@@ -194,7 +240,7 @@ bool TopSitesDatabase::UpdatePageThumbnail(
"UPDATE thumbnails SET "
"title = ?, thumbnail = ?, redirects = ?, "
"boring_score = ?, good_clipping = ?, at_top = ?, last_updated = ?, "
- "load_completed = ? "
+ "load_completed = ?, last_forced = ?"
"WHERE url = ? "));
statement.BindString16(0, url.title);
if (thumbnail.thumbnail.get() && thumbnail.thumbnail->front()) {
@@ -208,24 +254,23 @@ bool TopSitesDatabase::UpdatePageThumbnail(
statement.BindBool(5, score.at_top);
statement.BindInt64(6, score.time_at_snapshot.ToInternalValue());
statement.BindBool(7, score.load_completed);
- statement.BindString(8, url.url.spec());
+ statement.BindInt64(8, url.last_forced_time.ToInternalValue());
+ statement.BindString(9, url.url.spec());
return statement.Run();
}
void TopSitesDatabase::AddPageThumbnail(const MostVisitedURL& url,
- int new_rank,
- const Images& thumbnail) {
- int count = GetRowCount();
-
+ int new_rank,
+ const Images& thumbnail) {
sql::Statement statement(db_->GetCachedStatement(
SQL_FROM_HERE,
"INSERT OR REPLACE INTO thumbnails "
"(url, url_rank, title, thumbnail, redirects, "
- "boring_score, good_clipping, at_top, last_updated, load_completed) "
- "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
+ "boring_score, good_clipping, at_top, last_updated, load_completed, "
+ "last_forced) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
statement.BindString(0, url.url.spec());
- statement.BindInt(1, count); // Make it the last url.
+ statement.BindInt(1, kRankOfForcedURL); // Fist make it a forced thumbnail.
statement.BindString16(2, url.title);
if (thumbnail.thumbnail.get() && thumbnail.thumbnail->front()) {
statement.BindBlob(3, thumbnail.thumbnail->front(),
@@ -238,14 +283,25 @@ void TopSitesDatabase::AddPageThumbnail(const MostVisitedURL& url,
statement.BindBool(7, score.at_top);
statement.BindInt64(8, score.time_at_snapshot.ToInternalValue());
statement.BindBool(9, score.load_completed);
+ int64 last_forced = url.last_forced_time.ToInternalValue();
+ DCHECK((last_forced == 0) == (new_rank != kRankOfForcedURL))
+ << "Thumbnail without a forced time stamp has a forced rank, or the "
+ << "opposite.";
+ statement.BindInt64(10, last_forced);
if (!statement.Run())
return;
- UpdatePageRankNoTransaction(url, new_rank);
+ // Update rank if this is not a forced thumbnail.
+ if (new_rank != kRankOfForcedURL)
+ UpdatePageRankNoTransaction(url, new_rank);
}
void TopSitesDatabase::UpdatePageRank(const MostVisitedURL& url,
- int new_rank) {
+ int new_rank) {
+ DCHECK((url.last_forced_time.ToInternalValue() == 0) ==
+ (new_rank != kRankOfForcedURL))
+ << "Thumbnail without a forced time stamp has a forced rank, or the "
+ << "opposite.";
sql::Transaction transaction(db_.get());
transaction.Begin();
UpdatePageRankNoTransaction(url, new_rank);
@@ -256,43 +312,76 @@ void TopSitesDatabase::UpdatePageRank(const MostVisitedURL& url,
void TopSitesDatabase::UpdatePageRankNoTransaction(
const MostVisitedURL& url, int new_rank) {
DCHECK_GT(db_->transaction_nesting(), 0);
+
int prev_rank = GetURLRank(url);
- if (prev_rank == -1) {
+ if (prev_rank == kRankOfNonExistingURL) {
LOG(WARNING) << "Updating rank of an unknown URL: " << url.url.spec();
return;
}
// Shift the ranks.
if (prev_rank > new_rank) {
- // Shift up
- sql::Statement shift_statement(db_->GetCachedStatement(
- SQL_FROM_HERE,
- "UPDATE thumbnails "
- "SET url_rank = url_rank + 1 "
- "WHERE url_rank >= ? AND url_rank < ?"));
- shift_statement.BindInt(0, new_rank);
- shift_statement.BindInt(1, prev_rank);
- shift_statement.Run();
+ if (new_rank == kRankOfForcedURL) {
+ // From non-forced to forced, shift down.
+ // Example: 2 -> -1
+ // -1, -1, -1, 0, 1, [2 -> -1], [3 -> 2], [4 -> 3]
+ sql::Statement shift_statement(db_->GetCachedStatement(
+ SQL_FROM_HERE,
+ "UPDATE thumbnails "
+ "SET url_rank = url_rank - 1 "
+ "WHERE url_rank > ?"));
+ shift_statement.BindInt(0, prev_rank);
+ shift_statement.Run();
+ } else {
+ // From non-forced to non-forced, shift up.
+ // Example: 3 -> 1
+ // -1, -1, -1, 0, [1 -> 2], [2 -> 3], [3 -> 1], 4
+ sql::Statement shift_statement(db_->GetCachedStatement(
+ SQL_FROM_HERE,
+ "UPDATE thumbnails "
+ "SET url_rank = url_rank + 1 "
+ "WHERE url_rank >= ? AND url_rank < ?"));
+ shift_statement.BindInt(0, new_rank);
+ shift_statement.BindInt(1, prev_rank);
+ shift_statement.Run();
+ }
} else if (prev_rank < new_rank) {
- // Shift down
- sql::Statement shift_statement(db_->GetCachedStatement(
- SQL_FROM_HERE,
- "UPDATE thumbnails "
- "SET url_rank = url_rank - 1 "
- "WHERE url_rank > ? AND url_rank <= ?"));
- shift_statement.BindInt(0, prev_rank);
- shift_statement.BindInt(1, new_rank);
- shift_statement.Run();
+ if (prev_rank == kRankOfForcedURL) {
+ // From non-forced to forced, shift up.
+ // Example: -1 -> 2
+ // -1, [-1 -> 2], -1, 0, 1, [2 -> 3], [3 -> 4], [4 -> 5]
+ sql::Statement shift_statement(db_->GetCachedStatement(
+ SQL_FROM_HERE,
+ "UPDATE thumbnails "
+ "SET url_rank = url_rank + 1 "
+ "WHERE url_rank >= ?"));
+ shift_statement.BindInt(0, new_rank);
+ shift_statement.Run();
+ } else {
+ // From non-forced to non-forced, shift down.
+ // Example: 1 -> 3.
+ // -1, -1, -1, 0, [1 -> 3], [2 -> 1], [3 -> 2], 4
+ sql::Statement shift_statement(db_->GetCachedStatement(
+ SQL_FROM_HERE,
+ "UPDATE thumbnails "
+ "SET url_rank = url_rank - 1 "
+ "WHERE url_rank > ? AND url_rank <= ?"));
+ shift_statement.BindInt(0, prev_rank);
+ shift_statement.BindInt(1, new_rank);
+ shift_statement.Run();
+ }
}
- // Set the url's rank.
+ // Set the url's rank and last_forced, since the latter changes when a URL
+ // goes from forced to non-forced and vice-versa.
sql::Statement set_statement(db_->GetCachedStatement(
SQL_FROM_HERE,
"UPDATE thumbnails "
- "SET url_rank = ? "
+ "SET url_rank = ?, last_forced = ? "
"WHERE url == ?"));
set_statement.BindInt(0, new_rank);
- set_statement.BindString(1, url.url.spec());
+ set_statement.BindInt64(1, url.last_forced_time.ToInternalValue());
+ set_statement.BindString(2, url.url.spec());
set_statement.Run();
}
@@ -317,16 +406,6 @@ bool TopSitesDatabase::GetPageThumbnail(const GURL& url,
return true;
}
-int TopSitesDatabase::GetRowCount() {
- sql::Statement select_statement(db_->GetCachedStatement(
- SQL_FROM_HERE,
- "SELECT COUNT (url) FROM thumbnails"));
- if (select_statement.Step())
- return select_statement.ColumnInt(0);
-
- return 0;
-}
-
int TopSitesDatabase::GetURLRank(const MostVisitedURL& url) {
sql::Statement select_statement(db_->GetCachedStatement(
SQL_FROM_HERE,
@@ -336,27 +415,29 @@ int TopSitesDatabase::GetURLRank(const MostVisitedURL& url) {
if (select_statement.Step())
return select_statement.ColumnInt(0);
- return -1;
+ return kRankOfNonExistingURL;
}
// Remove the record for this URL. Returns true iff removed successfully.
bool TopSitesDatabase::RemoveURL(const MostVisitedURL& url) {
int old_rank = GetURLRank(url);
- if (old_rank < 0)
+ if (old_rank == kRankOfNonExistingURL)
return false;
sql::Transaction transaction(db_.get());
transaction.Begin();
- // Decrement all following ranks.
- sql::Statement shift_statement(db_->GetCachedStatement(
- SQL_FROM_HERE,
- "UPDATE thumbnails "
- "SET url_rank = url_rank - 1 "
- "WHERE url_rank > ?"));
- shift_statement.BindInt(0, old_rank);
+ if (old_rank != kRankOfForcedURL) {
+ // Decrement all following ranks.
+ sql::Statement shift_statement(db_->GetCachedStatement(
+ SQL_FROM_HERE,
+ "UPDATE thumbnails "
+ "SET url_rank = url_rank - 1 "
+ "WHERE url_rank > ?"));
+ shift_statement.BindInt(0, old_rank);
- if (!shift_statement.Run())
- return false;
+ if (!shift_statement.Run())
+ return false;
+ }
sql::Statement delete_statement(
db_->GetCachedStatement(SQL_FROM_HERE,