Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(526)

Side by Side Diff: chrome/browser/history/top_sites_database.cc

Issue 39053005: Adding last_forced column to thumbnails database. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Answered Brett's comments. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/file_util.h" 5 #include "base/file_util.h"
6 #include "base/memory/ref_counted.h" 6 #include "base/memory/ref_counted.h"
7 #include "base/strings/string_split.h" 7 #include "base/strings/string_split.h"
8 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
9 #include "chrome/browser/history/history_types.h" 9 #include "chrome/browser/history/history_types.h"
10 #include "chrome/browser/history/top_sites.h" 10 #include "chrome/browser/history/top_sites.h"
11 #include "chrome/browser/history/top_sites_database.h" 11 #include "chrome/browser/history/top_sites_database.h"
12 #include "chrome/common/thumbnail_score.h"
12 #include "sql/connection.h" 13 #include "sql/connection.h"
13 #include "sql/transaction.h" 14 #include "sql/transaction.h"
14 15
16 // Description of database table:
17 //
18 // thumbnails
19 // url URL of the sites for which we have a thumbnail.
20 // url_rank Index of the URL in that thumbnail, 0-based. The thumbnail
21 // with the highest rank will be the next one evicted. Forced
22 // thumbnails have a rank of -1.
23 // title The title to display under that thumbnail.
24 // redirects A space separated list of URLs that are known to redirect
25 // to this url.
26 // boring_score How "boring" that thumbnail is. See ThumbnailScore.
27 // good_clipping True if the thumbnail was clipped from the bottom, keeping
28 // the entire width of the window. See ThumbnailScore.
29 // at_top True if the thumbnail was captured at the top of the
30 // website.
31 // last_updated The time at which this thumbnail was last updated.
32 // load_completed True if the thumbnail was captured after the page load was
33 // completed.
34 // last_forced If this is a forced thumbnail, records the last time it
35 // was forced. If it's not a forced thumbnail, 0.
36
15 namespace history { 37 namespace history {
16 38
39 // TODO(beaudoin): Fill revision/date details of Version 3 after landing.
40 // Version 3: by beaudoin@chromium.org
17 // Version 2: eb0b24e6/r87284 by satorux@chromium.org on 2011-05-31 41 // Version 2: eb0b24e6/r87284 by satorux@chromium.org on 2011-05-31
18 // Version 1: 809cc4d8/r64072 by sky@chromium.org on 2010-10-27 42 // Version 1: 809cc4d8/r64072 by sky@chromium.org on 2010-10-27
19 43
20 // From the version 1 to 2, one column was added. Old versions of Chrome 44 // From the version 1 to 2, one column was added. Old versions of Chrome
21 // should be able to read version 2 files just fine. 45 // should be able to read version 2 files just fine. Same thing for version 2
46 // to 3.
22 // NOTE(shess): When changing the version, add a new golden file for 47 // NOTE(shess): When changing the version, add a new golden file for
23 // the new version and a test to verify that Init() works with it. 48 // the new version and a test to verify that Init() works with it.
24 static const int kVersionNumber = 2; 49 static const int kVersionNumber = 3;
25 50
26 TopSitesDatabase::TopSitesDatabase() { 51 TopSitesDatabase::TopSitesDatabase() {
27 } 52 }
28 53
29 TopSitesDatabase::~TopSitesDatabase() { 54 TopSitesDatabase::~TopSitesDatabase() {
30 } 55 }
31 56
32 bool TopSitesDatabase::Init(const base::FilePath& db_name) { 57 bool TopSitesDatabase::Init(const base::FilePath& db_name) {
33 bool file_existed = base::PathExists(db_name); 58 bool file_existed = base::PathExists(db_name);
34 59
(...skipping 27 matching lines...) Expand all
62 if (!InitThumbnailTable()) 87 if (!InitThumbnailTable())
63 return false; 88 return false;
64 89
65 if (meta_table_.GetVersionNumber() == 1) { 90 if (meta_table_.GetVersionNumber() == 1) {
66 if (!UpgradeToVersion2()) { 91 if (!UpgradeToVersion2()) {
67 LOG(WARNING) << "Unable to upgrade top sites database to version 2."; 92 LOG(WARNING) << "Unable to upgrade top sites database to version 2.";
68 return false; 93 return false;
69 } 94 }
70 } 95 }
71 96
97 if (meta_table_.GetVersionNumber() == 2) {
98 if (!UpgradeToVersion3()) {
99 LOG(WARNING) << "Unable to upgrade top sites database to version 3.";
100 return false;
101 }
102 }
103
72 // Version check. 104 // Version check.
73 if (meta_table_.GetVersionNumber() != kVersionNumber) 105 if (meta_table_.GetVersionNumber() != kVersionNumber)
74 return false; 106 return false;
75 107
76 // Initialization is complete. 108 // Initialization is complete.
77 if (!transaction.Commit()) 109 if (!transaction.Commit())
78 return false; 110 return false;
79 111
80 return true; 112 return true;
81 } 113 }
82 114
83 bool TopSitesDatabase::InitThumbnailTable() { 115 bool TopSitesDatabase::InitThumbnailTable() {
84 if (!db_->DoesTableExist("thumbnails")) { 116 if (!db_->DoesTableExist("thumbnails")) {
85 if (!db_->Execute("CREATE TABLE thumbnails (" 117 if (!db_->Execute("CREATE TABLE thumbnails ("
86 "url LONGVARCHAR PRIMARY KEY," 118 "url LONGVARCHAR PRIMARY KEY,"
87 "url_rank INTEGER ," 119 "url_rank INTEGER,"
88 "title LONGVARCHAR," 120 "title LONGVARCHAR,"
89 "thumbnail BLOB," 121 "thumbnail BLOB,"
90 "redirects LONGVARCHAR," 122 "redirects LONGVARCHAR,"
91 "boring_score DOUBLE DEFAULT 1.0, " 123 "boring_score DOUBLE DEFAULT 1.0,"
92 "good_clipping INTEGER DEFAULT 0, " 124 "good_clipping INTEGER DEFAULT 0,"
93 "at_top INTEGER DEFAULT 0, " 125 "at_top INTEGER DEFAULT 0,"
94 "last_updated INTEGER DEFAULT 0, " 126 "last_updated INTEGER DEFAULT 0,"
95 "load_completed INTEGER DEFAULT 0) ")) { 127 "load_completed INTEGER DEFAULT 0,"
128 "last_forced INTEGER DEFAULT 0)")) {
96 LOG(WARNING) << db_->GetErrorMessage(); 129 LOG(WARNING) << db_->GetErrorMessage();
97 return false; 130 return false;
98 } 131 }
99 } 132 }
100 return true; 133 return true;
101 } 134 }
102 135
103 bool TopSitesDatabase::UpgradeToVersion2() { 136 bool TopSitesDatabase::UpgradeToVersion2() {
104 // Add 'load_completed' column. 137 // Add 'load_completed' column.
105 if (!db_->Execute( 138 if (!db_->Execute(
106 "ALTER TABLE thumbnails ADD load_completed INTEGER DEFAULT 0")) { 139 "ALTER TABLE thumbnails ADD load_completed INTEGER DEFAULT 0")) {
107 NOTREACHED(); 140 NOTREACHED();
108 return false; 141 return false;
109 } 142 }
110 meta_table_.SetVersionNumber(2); 143 meta_table_.SetVersionNumber(2);
111 return true; 144 return true;
112 } 145 }
113 146
147 bool TopSitesDatabase::UpgradeToVersion3() {
148 // Add 'last_forced' column.
149 if (!db_->Execute(
150 "ALTER TABLE thumbnails ADD last_forced INTEGER DEFAULT 0")) {
151 NOTREACHED();
152 return false;
153 }
154 meta_table_.SetVersionNumber(3);
155 return true;
156 }
157
114 void TopSitesDatabase::GetPageThumbnails(MostVisitedURLList* urls, 158 void TopSitesDatabase::GetPageThumbnails(MostVisitedURLList* urls,
115 URLToImagesMap* thumbnails) { 159 URLToImagesMap* thumbnails) {
116 sql::Statement statement(db_->GetCachedStatement( 160 sql::Statement statement(db_->GetCachedStatement(
117 SQL_FROM_HERE, 161 SQL_FROM_HERE,
118 "SELECT url, url_rank, title, thumbnail, redirects, " 162 "SELECT url, url_rank, title, thumbnail, redirects, "
119 "boring_score, good_clipping, at_top, last_updated, load_completed " 163 "boring_score, good_clipping, at_top, last_updated, load_completed, "
120 "FROM thumbnails ORDER BY url_rank ")); 164 "last_forced FROM thumbnails ORDER BY url_rank, last_forced"));
121 165
122 if (!statement.is_valid()) { 166 if (!statement.is_valid()) {
123 LOG(WARNING) << db_->GetErrorMessage(); 167 LOG(WARNING) << db_->GetErrorMessage();
124 return; 168 return;
125 } 169 }
126 170
127 urls->clear(); 171 urls->clear();
128 thumbnails->clear(); 172 thumbnails->clear();
129 173
130 while (statement.Step()) { 174 while (statement.Step()) {
131 // Results are sorted by url_rank. 175 // Results are sorted by url_rank. For forced thumbnails with url_rank = -1,
176 // thumbnails are sorted by last_forced.
132 MostVisitedURL url; 177 MostVisitedURL url;
133 GURL gurl(statement.ColumnString(0)); 178 GURL gurl(statement.ColumnString(0));
134 url.url = gurl; 179 url.url = gurl;
135 url.title = statement.ColumnString16(2); 180 url.title = statement.ColumnString16(2);
181 url.last_forced_time =
182 base::Time::FromInternalValue(statement.ColumnInt64(10));
136 std::string redirects = statement.ColumnString(4); 183 std::string redirects = statement.ColumnString(4);
137 SetRedirects(redirects, &url); 184 SetRedirects(redirects, &url);
138 urls->push_back(url); 185 urls->push_back(url);
139 186
140 std::vector<unsigned char> data; 187 std::vector<unsigned char> data;
141 statement.ColumnBlobAsVector(3, &data); 188 statement.ColumnBlobAsVector(3, &data);
142 Images thumbnail; 189 Images thumbnail;
143 if (!data.empty()) 190 if (!data.empty())
144 thumbnail.thumbnail = base::RefCountedBytes::TakeVector(&data); 191 thumbnail.thumbnail = base::RefCountedBytes::TakeVector(&data);
145 thumbnail.thumbnail_score.boring_score = statement.ColumnDouble(5); 192 thumbnail.thumbnail_score.boring_score = statement.ColumnDouble(5);
146 thumbnail.thumbnail_score.good_clipping = statement.ColumnBool(6); 193 thumbnail.thumbnail_score.good_clipping = statement.ColumnBool(6);
147 thumbnail.thumbnail_score.at_top = statement.ColumnBool(7); 194 thumbnail.thumbnail_score.at_top = statement.ColumnBool(7);
148 thumbnail.thumbnail_score.time_at_snapshot = 195 thumbnail.thumbnail_score.time_at_snapshot =
149 base::Time::FromInternalValue(statement.ColumnInt64(8)); 196 base::Time::FromInternalValue(statement.ColumnInt64(8));
150 thumbnail.thumbnail_score.load_completed = statement.ColumnBool(9); 197 thumbnail.thumbnail_score.load_completed = statement.ColumnBool(9);
151
152 (*thumbnails)[gurl] = thumbnail; 198 (*thumbnails)[gurl] = thumbnail;
153 } 199 }
154 } 200 }
155 201
156 // static 202 // static
157 std::string TopSitesDatabase::GetRedirects(const MostVisitedURL& url) { 203 std::string TopSitesDatabase::GetRedirects(const MostVisitedURL& url) {
158 std::vector<std::string> redirects; 204 std::vector<std::string> redirects;
159 for (size_t i = 0; i < url.redirects.size(); i++) 205 for (size_t i = 0; i < url.redirects.size(); i++)
160 redirects.push_back(url.redirects[i].spec()); 206 redirects.push_back(url.redirects[i].spec());
161 return JoinString(redirects, ' '); 207 return JoinString(redirects, ' ');
162 } 208 }
163 209
164 // static 210 // static
165 void TopSitesDatabase::SetRedirects(const std::string& redirects, 211 void TopSitesDatabase::SetRedirects(const std::string& redirects,
166 MostVisitedURL* url) { 212 MostVisitedURL* url) {
167 std::vector<std::string> redirects_vector; 213 std::vector<std::string> redirects_vector;
168 base::SplitStringAlongWhitespace(redirects, &redirects_vector); 214 base::SplitStringAlongWhitespace(redirects, &redirects_vector);
169 for (size_t i = 0; i < redirects_vector.size(); ++i) 215 for (size_t i = 0; i < redirects_vector.size(); ++i)
170 url->redirects.push_back(GURL(redirects_vector[i])); 216 url->redirects.push_back(GURL(redirects_vector[i]));
171 } 217 }
172 218
173 void TopSitesDatabase::SetPageThumbnail(const MostVisitedURL& url, 219 void TopSitesDatabase::SetPageThumbnail(const MostVisitedURL& url,
174 int new_rank, 220 int new_rank,
175 const Images& thumbnail) { 221 const Images& thumbnail) {
176 sql::Transaction transaction(db_.get()); 222 sql::Transaction transaction(db_.get());
177 transaction.Begin(); 223 transaction.Begin();
178 224
179 int rank = GetURLRank(url); 225 int rank = GetURLRank(url);
180 if (rank == -1) { 226 if (rank == kRankOfNonExistingURL) {
181 AddPageThumbnail(url, new_rank, thumbnail); 227 AddPageThumbnail(url, new_rank, thumbnail);
182 } else { 228 } else {
183 UpdatePageRankNoTransaction(url, new_rank); 229 UpdatePageRankNoTransaction(url, new_rank);
184 UpdatePageThumbnail(url, thumbnail); 230 UpdatePageThumbnail(url, thumbnail);
185 } 231 }
186 232
187 transaction.Commit(); 233 transaction.Commit();
188 } 234 }
189 235
190 bool TopSitesDatabase::UpdatePageThumbnail( 236 bool TopSitesDatabase::UpdatePageThumbnail(
191 const MostVisitedURL& url, const Images& thumbnail) { 237 const MostVisitedURL& url, const Images& thumbnail) {
192 sql::Statement statement(db_->GetCachedStatement( 238 sql::Statement statement(db_->GetCachedStatement(
193 SQL_FROM_HERE, 239 SQL_FROM_HERE,
194 "UPDATE thumbnails SET " 240 "UPDATE thumbnails SET "
195 "title = ?, thumbnail = ?, redirects = ?, " 241 "title = ?, thumbnail = ?, redirects = ?, "
196 "boring_score = ?, good_clipping = ?, at_top = ?, last_updated = ?, " 242 "boring_score = ?, good_clipping = ?, at_top = ?, last_updated = ?, "
197 "load_completed = ? " 243 "load_completed = ?, last_forced = ?"
198 "WHERE url = ? ")); 244 "WHERE url = ? "));
199 statement.BindString16(0, url.title); 245 statement.BindString16(0, url.title);
200 if (thumbnail.thumbnail.get() && thumbnail.thumbnail->front()) { 246 if (thumbnail.thumbnail.get() && thumbnail.thumbnail->front()) {
201 statement.BindBlob(1, thumbnail.thumbnail->front(), 247 statement.BindBlob(1, thumbnail.thumbnail->front(),
202 static_cast<int>(thumbnail.thumbnail->size())); 248 static_cast<int>(thumbnail.thumbnail->size()));
203 } 249 }
204 statement.BindString(2, GetRedirects(url)); 250 statement.BindString(2, GetRedirects(url));
205 const ThumbnailScore& score = thumbnail.thumbnail_score; 251 const ThumbnailScore& score = thumbnail.thumbnail_score;
206 statement.BindDouble(3, score.boring_score); 252 statement.BindDouble(3, score.boring_score);
207 statement.BindBool(4, score.good_clipping); 253 statement.BindBool(4, score.good_clipping);
208 statement.BindBool(5, score.at_top); 254 statement.BindBool(5, score.at_top);
209 statement.BindInt64(6, score.time_at_snapshot.ToInternalValue()); 255 statement.BindInt64(6, score.time_at_snapshot.ToInternalValue());
210 statement.BindBool(7, score.load_completed); 256 statement.BindBool(7, score.load_completed);
211 statement.BindString(8, url.url.spec()); 257 statement.BindInt64(8, url.last_forced_time.ToInternalValue());
258 statement.BindString(9, url.url.spec());
212 259
213 return statement.Run(); 260 return statement.Run();
214 } 261 }
215 262
216 void TopSitesDatabase::AddPageThumbnail(const MostVisitedURL& url, 263 void TopSitesDatabase::AddPageThumbnail(const MostVisitedURL& url,
217 int new_rank, 264 int new_rank,
218 const Images& thumbnail) { 265 const Images& thumbnail) {
219 int count = GetRowCount();
220
221 sql::Statement statement(db_->GetCachedStatement( 266 sql::Statement statement(db_->GetCachedStatement(
222 SQL_FROM_HERE, 267 SQL_FROM_HERE,
223 "INSERT OR REPLACE INTO thumbnails " 268 "INSERT OR REPLACE INTO thumbnails "
224 "(url, url_rank, title, thumbnail, redirects, " 269 "(url, url_rank, title, thumbnail, redirects, "
225 "boring_score, good_clipping, at_top, last_updated, load_completed) " 270 "boring_score, good_clipping, at_top, last_updated, load_completed, "
226 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); 271 "last_forced) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
227 statement.BindString(0, url.url.spec()); 272 statement.BindString(0, url.url.spec());
228 statement.BindInt(1, count); // Make it the last url. 273 statement.BindInt(1, kRankOfForcedURL); // Fist make it a forced thumbnail.
229 statement.BindString16(2, url.title); 274 statement.BindString16(2, url.title);
230 if (thumbnail.thumbnail.get() && thumbnail.thumbnail->front()) { 275 if (thumbnail.thumbnail.get() && thumbnail.thumbnail->front()) {
231 statement.BindBlob(3, thumbnail.thumbnail->front(), 276 statement.BindBlob(3, thumbnail.thumbnail->front(),
232 static_cast<int>(thumbnail.thumbnail->size())); 277 static_cast<int>(thumbnail.thumbnail->size()));
233 } 278 }
234 statement.BindString(4, GetRedirects(url)); 279 statement.BindString(4, GetRedirects(url));
235 const ThumbnailScore& score = thumbnail.thumbnail_score; 280 const ThumbnailScore& score = thumbnail.thumbnail_score;
236 statement.BindDouble(5, score.boring_score); 281 statement.BindDouble(5, score.boring_score);
237 statement.BindBool(6, score.good_clipping); 282 statement.BindBool(6, score.good_clipping);
238 statement.BindBool(7, score.at_top); 283 statement.BindBool(7, score.at_top);
239 statement.BindInt64(8, score.time_at_snapshot.ToInternalValue()); 284 statement.BindInt64(8, score.time_at_snapshot.ToInternalValue());
240 statement.BindBool(9, score.load_completed); 285 statement.BindBool(9, score.load_completed);
286 int64 last_forced = url.last_forced_time.ToInternalValue();
287 DCHECK((last_forced == 0) == (new_rank != kRankOfForcedURL))
288 << "Thumbnail without a forced time stamp has a forced rank, or the "
289 << "opposite.";
290 statement.BindInt64(10, last_forced);
241 if (!statement.Run()) 291 if (!statement.Run())
242 return; 292 return;
243 293
244 UpdatePageRankNoTransaction(url, new_rank); 294 // Update rank if this is not a forced thumbnail.
295 if (new_rank != kRankOfForcedURL)
296 UpdatePageRankNoTransaction(url, new_rank);
245 } 297 }
246 298
247 void TopSitesDatabase::UpdatePageRank(const MostVisitedURL& url, 299 void TopSitesDatabase::UpdatePageRank(const MostVisitedURL& url,
248 int new_rank) { 300 int new_rank) {
301 DCHECK((url.last_forced_time.ToInternalValue() == 0) ==
302 (new_rank != kRankOfForcedURL))
303 << "Thumbnail without a forced time stamp has a forced rank, or the "
304 << "opposite.";
249 sql::Transaction transaction(db_.get()); 305 sql::Transaction transaction(db_.get());
250 transaction.Begin(); 306 transaction.Begin();
251 UpdatePageRankNoTransaction(url, new_rank); 307 UpdatePageRankNoTransaction(url, new_rank);
252 transaction.Commit(); 308 transaction.Commit();
253 } 309 }
254 310
255 // Caller should have a transaction open. 311 // Caller should have a transaction open.
256 void TopSitesDatabase::UpdatePageRankNoTransaction( 312 void TopSitesDatabase::UpdatePageRankNoTransaction(
257 const MostVisitedURL& url, int new_rank) { 313 const MostVisitedURL& url, int new_rank) {
258 DCHECK_GT(db_->transaction_nesting(), 0); 314 DCHECK_GT(db_->transaction_nesting(), 0);
315
259 int prev_rank = GetURLRank(url); 316 int prev_rank = GetURLRank(url);
260 if (prev_rank == -1) { 317 if (prev_rank == kRankOfNonExistingURL) {
261 LOG(WARNING) << "Updating rank of an unknown URL: " << url.url.spec(); 318 LOG(WARNING) << "Updating rank of an unknown URL: " << url.url.spec();
262 return; 319 return;
263 } 320 }
264 321
265 // Shift the ranks. 322 // Shift the ranks.
266 if (prev_rank > new_rank) { 323 if (prev_rank > new_rank) {
267 // Shift up 324 if (new_rank == kRankOfForcedURL) {
268 sql::Statement shift_statement(db_->GetCachedStatement( 325 // From non-forced to forced, shift down.
269 SQL_FROM_HERE, 326 // Example: 2 -> -1
270 "UPDATE thumbnails " 327 // -1, -1, -1, 0, 1, [2 -> -1], [3 -> 2], [4 -> 3]
271 "SET url_rank = url_rank + 1 " 328 sql::Statement shift_statement(db_->GetCachedStatement(
272 "WHERE url_rank >= ? AND url_rank < ?")); 329 SQL_FROM_HERE,
273 shift_statement.BindInt(0, new_rank); 330 "UPDATE thumbnails "
274 shift_statement.BindInt(1, prev_rank); 331 "SET url_rank = url_rank - 1 "
275 shift_statement.Run(); 332 "WHERE url_rank > ?"));
333 shift_statement.BindInt(0, prev_rank);
334 shift_statement.Run();
335 } else {
336 // From non-forced to non-forced, shift up.
337 // Example: 3 -> 1
338 // -1, -1, -1, 0, [1 -> 2], [2 -> 3], [3 -> 1], 4
339 sql::Statement shift_statement(db_->GetCachedStatement(
340 SQL_FROM_HERE,
341 "UPDATE thumbnails "
342 "SET url_rank = url_rank + 1 "
343 "WHERE url_rank >= ? AND url_rank < ?"));
344 shift_statement.BindInt(0, new_rank);
345 shift_statement.BindInt(1, prev_rank);
346 shift_statement.Run();
347 }
276 } else if (prev_rank < new_rank) { 348 } else if (prev_rank < new_rank) {
277 // Shift down 349 if (prev_rank == kRankOfForcedURL) {
278 sql::Statement shift_statement(db_->GetCachedStatement( 350 // From non-forced to forced, shift up.
279 SQL_FROM_HERE, 351 // Example: -1 -> 2
280 "UPDATE thumbnails " 352 // -1, [-1 -> 2], -1, 0, 1, [2 -> 3], [3 -> 4], [4 -> 5]
281 "SET url_rank = url_rank - 1 " 353 sql::Statement shift_statement(db_->GetCachedStatement(
282 "WHERE url_rank > ? AND url_rank <= ?")); 354 SQL_FROM_HERE,
283 shift_statement.BindInt(0, prev_rank); 355 "UPDATE thumbnails "
284 shift_statement.BindInt(1, new_rank); 356 "SET url_rank = url_rank + 1 "
285 shift_statement.Run(); 357 "WHERE url_rank >= ?"));
358 shift_statement.BindInt(0, new_rank);
359 shift_statement.Run();
360 } else {
361 // From non-forced to non-forced, shift down.
362 // Example: 1 -> 3.
363 // -1, -1, -1, 0, [1 -> 3], [2 -> 1], [3 -> 2], 4
364 sql::Statement shift_statement(db_->GetCachedStatement(
365 SQL_FROM_HERE,
366 "UPDATE thumbnails "
367 "SET url_rank = url_rank - 1 "
368 "WHERE url_rank > ? AND url_rank <= ?"));
369 shift_statement.BindInt(0, prev_rank);
370 shift_statement.BindInt(1, new_rank);
371 shift_statement.Run();
372 }
286 } 373 }
287 374
288 // Set the url's rank. 375 // Set the url's rank and last_forced, since the latter changes when a URL
376 // goes from forced to non-forced and vice-versa.
289 sql::Statement set_statement(db_->GetCachedStatement( 377 sql::Statement set_statement(db_->GetCachedStatement(
290 SQL_FROM_HERE, 378 SQL_FROM_HERE,
291 "UPDATE thumbnails " 379 "UPDATE thumbnails "
292 "SET url_rank = ? " 380 "SET url_rank = ?, last_forced = ? "
293 "WHERE url == ?")); 381 "WHERE url == ?"));
294 set_statement.BindInt(0, new_rank); 382 set_statement.BindInt(0, new_rank);
295 set_statement.BindString(1, url.url.spec()); 383 set_statement.BindInt64(1, url.last_forced_time.ToInternalValue());
384 set_statement.BindString(2, url.url.spec());
296 set_statement.Run(); 385 set_statement.Run();
297 } 386 }
298 387
299 bool TopSitesDatabase::GetPageThumbnail(const GURL& url, 388 bool TopSitesDatabase::GetPageThumbnail(const GURL& url,
300 Images* thumbnail) { 389 Images* thumbnail) {
301 sql::Statement statement(db_->GetCachedStatement( 390 sql::Statement statement(db_->GetCachedStatement(
302 SQL_FROM_HERE, 391 SQL_FROM_HERE,
303 "SELECT thumbnail, boring_score, good_clipping, at_top, last_updated " 392 "SELECT thumbnail, boring_score, good_clipping, at_top, last_updated "
304 "FROM thumbnails WHERE url=?")); 393 "FROM thumbnails WHERE url=?"));
305 statement.BindString(0, url.spec()); 394 statement.BindString(0, url.spec());
306 if (!statement.Step()) 395 if (!statement.Step())
307 return false; 396 return false;
308 397
309 std::vector<unsigned char> data; 398 std::vector<unsigned char> data;
310 statement.ColumnBlobAsVector(0, &data); 399 statement.ColumnBlobAsVector(0, &data);
311 thumbnail->thumbnail = base::RefCountedBytes::TakeVector(&data); 400 thumbnail->thumbnail = base::RefCountedBytes::TakeVector(&data);
312 thumbnail->thumbnail_score.boring_score = statement.ColumnDouble(1); 401 thumbnail->thumbnail_score.boring_score = statement.ColumnDouble(1);
313 thumbnail->thumbnail_score.good_clipping = statement.ColumnBool(2); 402 thumbnail->thumbnail_score.good_clipping = statement.ColumnBool(2);
314 thumbnail->thumbnail_score.at_top = statement.ColumnBool(3); 403 thumbnail->thumbnail_score.at_top = statement.ColumnBool(3);
315 thumbnail->thumbnail_score.time_at_snapshot = 404 thumbnail->thumbnail_score.time_at_snapshot =
316 base::Time::FromInternalValue(statement.ColumnInt64(4)); 405 base::Time::FromInternalValue(statement.ColumnInt64(4));
317 return true; 406 return true;
318 } 407 }
319 408
320 int TopSitesDatabase::GetRowCount() {
321 sql::Statement select_statement(db_->GetCachedStatement(
322 SQL_FROM_HERE,
323 "SELECT COUNT (url) FROM thumbnails"));
324 if (select_statement.Step())
325 return select_statement.ColumnInt(0);
326
327 return 0;
328 }
329
330 int TopSitesDatabase::GetURLRank(const MostVisitedURL& url) { 409 int TopSitesDatabase::GetURLRank(const MostVisitedURL& url) {
331 sql::Statement select_statement(db_->GetCachedStatement( 410 sql::Statement select_statement(db_->GetCachedStatement(
332 SQL_FROM_HERE, 411 SQL_FROM_HERE,
333 "SELECT url_rank " 412 "SELECT url_rank "
334 "FROM thumbnails WHERE url=?")); 413 "FROM thumbnails WHERE url=?"));
335 select_statement.BindString(0, url.url.spec()); 414 select_statement.BindString(0, url.url.spec());
336 if (select_statement.Step()) 415 if (select_statement.Step())
337 return select_statement.ColumnInt(0); 416 return select_statement.ColumnInt(0);
338 417
339 return -1; 418 return kRankOfNonExistingURL;
340 } 419 }
341 420
342 // Remove the record for this URL. Returns true iff removed successfully. 421 // Remove the record for this URL. Returns true iff removed successfully.
343 bool TopSitesDatabase::RemoveURL(const MostVisitedURL& url) { 422 bool TopSitesDatabase::RemoveURL(const MostVisitedURL& url) {
344 int old_rank = GetURLRank(url); 423 int old_rank = GetURLRank(url);
345 if (old_rank < 0) 424 if (old_rank == kRankOfNonExistingURL)
346 return false; 425 return false;
347 426
348 sql::Transaction transaction(db_.get()); 427 sql::Transaction transaction(db_.get());
349 transaction.Begin(); 428 transaction.Begin();
350 // Decrement all following ranks. 429 if (old_rank != kRankOfForcedURL) {
351 sql::Statement shift_statement(db_->GetCachedStatement( 430 // Decrement all following ranks.
352 SQL_FROM_HERE, 431 sql::Statement shift_statement(db_->GetCachedStatement(
353 "UPDATE thumbnails " 432 SQL_FROM_HERE,
354 "SET url_rank = url_rank - 1 " 433 "UPDATE thumbnails "
355 "WHERE url_rank > ?")); 434 "SET url_rank = url_rank - 1 "
356 shift_statement.BindInt(0, old_rank); 435 "WHERE url_rank > ?"));
436 shift_statement.BindInt(0, old_rank);
357 437
358 if (!shift_statement.Run()) 438 if (!shift_statement.Run())
359 return false; 439 return false;
440 }
360 441
361 sql::Statement delete_statement( 442 sql::Statement delete_statement(
362 db_->GetCachedStatement(SQL_FROM_HERE, 443 db_->GetCachedStatement(SQL_FROM_HERE,
363 "DELETE FROM thumbnails WHERE url = ?")); 444 "DELETE FROM thumbnails WHERE url = ?"));
364 delete_statement.BindString(0, url.url.spec()); 445 delete_statement.BindString(0, url.url.spec());
365 446
366 if (!delete_statement.Run()) 447 if (!delete_statement.Run())
367 return false; 448 return false;
368 449
369 return transaction.Commit(); 450 return transaction.Commit();
370 } 451 }
371 452
372 sql::Connection* TopSitesDatabase::CreateDB(const base::FilePath& db_name) { 453 sql::Connection* TopSitesDatabase::CreateDB(const base::FilePath& db_name) {
373 scoped_ptr<sql::Connection> db(new sql::Connection()); 454 scoped_ptr<sql::Connection> db(new sql::Connection());
374 // Settings copied from ThumbnailDatabase. 455 // Settings copied from ThumbnailDatabase.
375 db->set_histogram_tag("TopSites"); 456 db->set_histogram_tag("TopSites");
376 db->set_page_size(4096); 457 db->set_page_size(4096);
377 db->set_cache_size(32); 458 db->set_cache_size(32);
378 459
379 if (!db->Open(db_name)) { 460 if (!db->Open(db_name)) {
380 LOG(ERROR) << db->GetErrorMessage(); 461 LOG(ERROR) << db->GetErrorMessage();
381 return NULL; 462 return NULL;
382 } 463 }
383 464
384 return db.release(); 465 return db.release();
385 } 466 }
386 467
387 } // namespace history 468 } // namespace history
OLDNEW
« no previous file with comments | « chrome/browser/history/top_sites_database.h ('k') | chrome/browser/history/top_sites_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698