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

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

Issue 10815068: Changes favicon database to support storing bitmaps of different sizes for the same icon_url (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moved some of the android stuff to 10831341 Created 8 years, 4 months 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 "chrome/browser/history/thumbnail_database.h" 5 #include "chrome/browser/history/thumbnail_database.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 21 matching lines...) Expand all
32 icon_mapping->mapping_id = statement.ColumnInt64(0); 32 icon_mapping->mapping_id = statement.ColumnInt64(0);
33 icon_mapping->icon_id = statement.ColumnInt64(1); 33 icon_mapping->icon_id = statement.ColumnInt64(1);
34 icon_mapping->icon_type = 34 icon_mapping->icon_type =
35 static_cast<history::IconType>(statement.ColumnInt(2)); 35 static_cast<history::IconType>(statement.ColumnInt(2));
36 icon_mapping->page_url = page_url; 36 icon_mapping->page_url = page_url;
37 } 37 }
38 38
39 namespace history { 39 namespace history {
40 40
41 // Version number of the database. 41 // Version number of the database.
42 static const int kCurrentVersionNumber = 5; 42 static const int kCurrentVersionNumber = 6;
43 static const int kCompatibleVersionNumber = 5; 43 static const int kCompatibleVersionNumber = 6;
44 44
45 // Use 90 quality (out of 100) which is pretty high, because we're very 45 // Use 90 quality (out of 100) which is pretty high, because we're very
46 // sensitive to artifacts for these small sized, highly detailed images. 46 // sensitive to artifacts for these small sized, highly detailed images.
47 static const int kImageQuality = 90; 47 static const int kImageQuality = 90;
48 48
49 ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() { 49 ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() {
50 } 50 }
51 51
52 ThumbnailDatabase::IconMappingEnumerator::~IconMappingEnumerator() { 52 ThumbnailDatabase::IconMappingEnumerator::~IconMappingEnumerator() {
53 } 53 }
54 54
55 bool ThumbnailDatabase::IconMappingEnumerator::GetNextIconMapping( 55 bool ThumbnailDatabase::IconMappingEnumerator::GetNextIconMapping(
56 IconMapping* icon_mapping) { 56 IconMapping* icon_mapping) {
57 if (!statement_.Step()) 57 if (!statement_.Step())
58 return false; 58 return false;
59 FillIconMapping(statement_, GURL(statement_.ColumnString(3)), icon_mapping); 59 FillIconMapping(statement_, GURL(statement_.ColumnString(3)), icon_mapping);
60 return true; 60 return true;
61 } 61 }
62 62
63 ThumbnailDatabase::ThumbnailDatabase() 63 ThumbnailDatabase::ThumbnailDatabase()
64 : history_publisher_(NULL), 64 : history_publisher_(NULL),
65 use_top_sites_(false) { 65 use_top_sites_(false) {
66 } 66 }
67 67
68 sql::InitStatus ThumbnailDatabase::CantUpgradeToVersion(int cur_version) { 68 sql::InitStatus ThumbnailDatabase::CantUpgradeToVersion(int cur_version) {
69 LOG(WARNING) << "Unable to update to thumbnail database to version 4" << 69 LOG(WARNING) << "Unable to update to thumbnail database to version " <<
70 cur_version << "."; 70 cur_version << ".";
71 db_.Close(); 71 db_.Close();
72 return sql::INIT_FAILURE; 72 return sql::INIT_FAILURE;
73 } 73 }
74 74
75 ThumbnailDatabase::~ThumbnailDatabase() { 75 ThumbnailDatabase::~ThumbnailDatabase() {
76 // The DBCloseScoper will delete the DB and the cache. 76 // The DBCloseScoper will delete the DB and the cache.
77 } 77 }
78 78
79 sql::InitStatus ThumbnailDatabase::Init( 79 sql::InitStatus ThumbnailDatabase::Init(
(...skipping 11 matching lines...) Expand all
91 91
92 #if defined(OS_MACOSX) 92 #if defined(OS_MACOSX)
93 // Exclude the thumbnails file from backups. 93 // Exclude the thumbnails file from backups.
94 base::mac::SetFileBackupExclusion(db_name); 94 base::mac::SetFileBackupExclusion(db_name);
95 #endif 95 #endif
96 96
97 // Create the tables. 97 // Create the tables.
98 if (!meta_table_.Init(&db_, kCurrentVersionNumber, 98 if (!meta_table_.Init(&db_, kCurrentVersionNumber,
99 kCompatibleVersionNumber) || 99 kCompatibleVersionNumber) ||
100 !InitThumbnailTable() || 100 !InitThumbnailTable() ||
101 !InitFaviconBitmapsTable(&db_, false) ||
102 !InitFaviconBitmapsIndex() ||
101 !InitFaviconsTable(&db_, false) || 103 !InitFaviconsTable(&db_, false) ||
102 !InitFaviconsIndex() || 104 !InitFaviconsIndex() ||
103 !InitIconMappingTable(&db_, false) || 105 !InitIconMappingTable(&db_, false) ||
104 !InitIconMappingIndex()) { 106 !InitIconMappingIndex()) {
105 db_.Close(); 107 db_.Close();
106 return sql::INIT_FAILURE; 108 return sql::INIT_FAILURE;
107 } 109 }
108 110
109 // Version check. We should not encounter a database too old for us to handle 111 // Version check. We should not encounter a database too old for us to handle
110 // in the wild, so we try to continue in that case. 112 // in the wild, so we try to continue in that case.
111 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { 113 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
112 LOG(WARNING) << "Thumbnail database is too new."; 114 LOG(WARNING) << "Thumbnail database is too new.";
113 return sql::INIT_TOO_NEW; 115 return sql::INIT_TOO_NEW;
114 } 116 }
115 117
116 int cur_version = meta_table_.GetVersionNumber(); 118 int cur_version = meta_table_.GetVersionNumber();
117 if (cur_version == 2) { 119 if (cur_version == 2) {
118 ++cur_version; 120 ++cur_version;
119 if (!UpgradeToVersion3()) 121 if (!UpgradeToVersion3())
120 return CantUpgradeToVersion(cur_version); 122 return CantUpgradeToVersion(cur_version);
121 } 123 }
122 124
123 if (cur_version == 3) { 125 if (cur_version == 3) {
124 ++cur_version; 126 ++cur_version;
125 if (!UpgradeToVersion4() || !MigrateIconMappingData(url_db)) 127 if (!UpgradeToVersion4() || !MigrateIconMappingData(url_db))
126 return CantUpgradeToVersion(cur_version); 128 return CantUpgradeToVersion(cur_version);
127 } 129 }
128 130
129 if (cur_version == 4) { 131 if (cur_version == 4) {
132 ++cur_version;
130 if (!UpgradeToVersion5()) 133 if (!UpgradeToVersion5())
131 return CantUpgradeToVersion(cur_version); 134 return CantUpgradeToVersion(cur_version);
132 } 135 }
133 136
137 if (cur_version == 5) {
138 ++cur_version;
139 if (!UpgradeToVersion6())
140 return CantUpgradeToVersion(cur_version);
141 }
142
134 LOG_IF(WARNING, cur_version < kCurrentVersionNumber) << 143 LOG_IF(WARNING, cur_version < kCurrentVersionNumber) <<
135 "Thumbnail database version " << cur_version << " is too old to handle."; 144 "Thumbnail database version " << cur_version << " is too old to handle.";
136 145
137 // Initialization is complete. 146 // Initialization is complete.
138 if (!transaction.Commit()) { 147 if (!transaction.Commit()) {
139 db_.Close(); 148 db_.Close();
140 return sql::INIT_FAILURE; 149 return sql::INIT_FAILURE;
141 } 150 }
142 151
143 return sql::INIT_OK; 152 return sql::INIT_OK;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 // Note: if you update the schema, don't forget to update 222 // Note: if you update the schema, don't forget to update
214 // CopyToTemporaryFaviconTable as well. 223 // CopyToTemporaryFaviconTable as well.
215 const char* name = is_temporary ? "temp_favicons" : "favicons"; 224 const char* name = is_temporary ? "temp_favicons" : "favicons";
216 if (!db->DoesTableExist(name)) { 225 if (!db->DoesTableExist(name)) {
217 std::string sql; 226 std::string sql;
218 sql.append("CREATE TABLE "); 227 sql.append("CREATE TABLE ");
219 sql.append(name); 228 sql.append(name);
220 sql.append("(" 229 sql.append("("
221 "id INTEGER PRIMARY KEY," 230 "id INTEGER PRIMARY KEY,"
222 "url LONGVARCHAR NOT NULL," 231 "url LONGVARCHAR NOT NULL,"
223 "last_updated INTEGER DEFAULT 0,"
224 "image_data BLOB,"
225 // Set the default icon_type as FAVICON to be consistent with 232 // Set the default icon_type as FAVICON to be consistent with
226 // table upgrade in UpgradeToVersion4(). 233 // table upgrade in UpgradeToVersion4().
227 "icon_type INTEGER DEFAULT 1," 234 "icon_type INTEGER DEFAULT 1,"
228 "sizes LONGVARCHAR)"); 235 "sizes LONGVARCHAR DEFAULT '0 0')");
sky 2012/08/16 16:12:57 why 0 0 as a default?
pkotwicz 2012/08/16 19:22:46 The default is 0x0 because it is a very recognizab
sky 2012/08/16 20:01:41 0x0 implies there is one known size, 0x0. That isn
229 if (!db->Execute(sql.c_str())) 236 if (!db->Execute(sql.c_str()))
230 return false; 237 return false;
231 } 238 }
232 return true; 239 return true;
233 } 240 }
234 241
235 bool ThumbnailDatabase::InitFaviconsIndex() { 242 bool ThumbnailDatabase::InitFaviconsIndex() {
236 // Add an index on the url column. 243 // Add an index on the url column.
237 return 244 return
238 db_.Execute("CREATE INDEX IF NOT EXISTS favicons_url ON favicons(url)"); 245 db_.Execute("CREATE INDEX IF NOT EXISTS favicons_url ON favicons(url)");
239 } 246 }
240 247
248 bool ThumbnailDatabase::InitFaviconBitmapsTable(sql::Connection* db,
249 bool is_temporary) {
250 // Note: if you update the schema, don't forget to update
251 // CopyFaviconAndFaviconBitmapsToTemporaryTables as well.
252 const char* name = is_temporary ? "temp_favicon_bitmaps" : "favicon_bitmaps";
253 if (!db->DoesTableExist(name)) {
254 std::string sql;
255 sql.append("CREATE TABLE ");
256 sql.append(name);
257 sql.append("("
258 "id INTEGER PRIMARY KEY,"
259 "icon_id INTEGER,"
260 "last_updated INTEGER DEFAULT 0,"
261 "image_data BLOB,"
262 "width INTEGER DEFAULT 0,"
263 "height INTEGER DEFAULT 0)");
264 if (!db->Execute(sql.c_str()))
265 return false;
266 }
267 return true;
268 }
269
270 bool ThumbnailDatabase::InitFaviconBitmapsIndex() {
271 // Add an index on the icon_id column.
272 return db_.Execute("CREATE INDEX IF NOT EXISTS favicon_bitmaps_icon_id ON "
273 "favicon_bitmaps(icon_id)");
274 }
275
241 void ThumbnailDatabase::BeginTransaction() { 276 void ThumbnailDatabase::BeginTransaction() {
242 db_.BeginTransaction(); 277 db_.BeginTransaction();
243 } 278 }
244 279
245 void ThumbnailDatabase::CommitTransaction() { 280 void ThumbnailDatabase::CommitTransaction() {
246 db_.CommitTransaction(); 281 db_.CommitTransaction();
247 } 282 }
248 283
249 void ThumbnailDatabase::RollbackTransaction() { 284 void ThumbnailDatabase::RollbackTransaction() {
250 db_.RollbackTransaction(); 285 db_.RollbackTransaction();
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 double current_boring_score = select_statement.ColumnDouble(0); 393 double current_boring_score = select_statement.ColumnDouble(0);
359 bool current_clipping = select_statement.ColumnBool(1); 394 bool current_clipping = select_statement.ColumnBool(1);
360 bool current_at_top = select_statement.ColumnBool(2); 395 bool current_at_top = select_statement.ColumnBool(2);
361 base::Time last_updated = 396 base::Time last_updated =
362 base::Time::FromTimeT(select_statement.ColumnInt64(3)); 397 base::Time::FromTimeT(select_statement.ColumnInt64(3));
363 *score = ThumbnailScore(current_boring_score, current_clipping, 398 *score = ThumbnailScore(current_boring_score, current_clipping,
364 current_at_top, last_updated); 399 current_at_top, last_updated);
365 return true; 400 return true;
366 } 401 }
367 402
368 bool ThumbnailDatabase::SetFavicon( 403 bool ThumbnailDatabase::GetFaviconBitmaps(
369 URLID icon_id, 404 FaviconID icon_id,
405 std::vector<FaviconBitmap>* favicon_bitmaps) {
406 DCHECK(icon_id);
407 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
408 "SELECT id, last_updated, image_data, width, height FROM favicon_bitmaps "
409 "WHERE icon_id=?"));
410 statement.BindInt64(0, icon_id);
411
412 bool result = false;
sky 2012/08/16 16:12:57 Why do we need a return value here? Can't they che
pkotwicz 2012/08/16 19:22:46 We use return values in ThumbnailDatabase so that
413 while (statement.Step()) {
414 result = true;
415 if (!favicon_bitmaps)
416 return result;
417
418 FaviconBitmap favicon_bitmap;
419 favicon_bitmap.bitmap_id = statement.ColumnInt64(0);
420 favicon_bitmap.icon_id = icon_id;
421 favicon_bitmap.last_updated =
422 base::Time::FromTimeT(statement.ColumnInt64(1));
423 if (statement.ColumnByteLength(2) > 0) {
424 scoped_refptr<base::RefCountedBytes> data = new base::RefCountedBytes();
425 statement.ColumnBlobAsVector(2, &data->data());
426 favicon_bitmap.bitmap_data = data;
427 }
428 favicon_bitmap.pixel_size = gfx::Size(statement.ColumnInt(3),
429 statement.ColumnInt(4));
430 favicon_bitmaps->push_back(favicon_bitmap);
431 }
432 return result;
433 }
434
435 FaviconBitmapID ThumbnailDatabase::AddFaviconBitmap(
436 FaviconID icon_id,
437 scoped_refptr<base::RefCountedMemory> icon_data,
438 base::Time time,
439 const gfx::Size& pixel_size) {
440 DCHECK(icon_id);
441 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
442 "INSERT INTO favicon_bitmaps (icon_id, image_data, last_updated, width, "
443 "height) VALUES (?, ?, ?, ?, ?)"));
444 statement.BindInt64(0, icon_id);
445 if (icon_data->size()) {
446 statement.BindBlob(1, icon_data->front(),
447 static_cast<int>(icon_data->size()));
448 } else {
449 statement.BindNull(1);
450 }
451 statement.BindInt64(2, time.ToTimeT());
452 statement.BindInt(3, pixel_size.width());
453 statement.BindInt(4, pixel_size.height());
454
455 if (!statement.Run())
456 return 0;
457 return db_.GetLastInsertRowId();
458 }
459
460 bool ThumbnailDatabase::SetFaviconBitmap(
461 FaviconID icon_id,
370 scoped_refptr<base::RefCountedMemory> icon_data, 462 scoped_refptr<base::RefCountedMemory> icon_data,
371 base::Time time) { 463 base::Time time) {
372 DCHECK(icon_id); 464 DCHECK(icon_id);
373 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 465 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
374 "UPDATE favicons SET image_data=?, last_updated=? WHERE id=?")); 466 "UPDATE favicon_bitmaps SET image_data=?, last_updated=? "
sky 2012/08/16 16:12:57 This might reset multiple rows. Shouldn't the wher
pkotwicz 2012/08/16 19:22:46 Changed this to remove and insert as you suggested
467 "WHERE icon_id=?"));
375 if (icon_data->size()) { 468 if (icon_data->size()) {
376 statement.BindBlob(0, icon_data->front(), 469 statement.BindBlob(0, icon_data->front(),
377 static_cast<int>(icon_data->size())); 470 static_cast<int>(icon_data->size()));
378 } else { 471 } else {
379 statement.BindNull(0); 472 statement.BindNull(0);
380 } 473 }
381 statement.BindInt64(1, time.ToTimeT()); 474 statement.BindInt64(1, time.ToTimeT());
382 statement.BindInt64(2, icon_id); 475 statement.BindInt64(2, icon_id);
383 476
384 return statement.Run(); 477 return statement.Run();
385 } 478 }
386 479
387 bool ThumbnailDatabase::SetFaviconLastUpdateTime(FaviconID icon_id, 480 bool ThumbnailDatabase::SetFaviconSizes(FaviconID icon_id,
388 base::Time time) { 481 const std::string& sizes) {
389 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 482 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
390 "UPDATE favicons SET last_updated=? WHERE id=?")); 483 "UPDATE favicons SET sizes=? WHERE id=?"));
391 statement.BindInt64(0, time.ToTimeT()); 484 statement.BindString(0, sizes);
392 statement.BindInt64(1, icon_id); 485 statement.BindInt64(1, icon_id);
393 486
394 return statement.Run(); 487 return statement.Run();
488 }
489
490 bool ThumbnailDatabase::SetFaviconOutOfDate(FaviconID icon_id) {
491 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
492 "UPDATE favicon_bitmaps SET last_updated=? WHERE icon_id=?"));
493 statement.BindInt64(0, 0);
494 statement.BindInt64(1, icon_id);
495
496 return statement.Run();
395 } 497 }
396 498
397 FaviconID ThumbnailDatabase::GetFaviconIDForFaviconURL(const GURL& icon_url, 499 FaviconID ThumbnailDatabase::GetFaviconIDForFaviconURL(const GURL& icon_url,
398 int required_icon_type, 500 int required_icon_type,
399 IconType* icon_type) { 501 IconType* icon_type) {
400 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 502 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
401 "SELECT id, icon_type FROM favicons WHERE url=? AND (icon_type & ? > 0) " 503 "SELECT id, icon_type FROM favicons WHERE url=? AND (icon_type & ? > 0) "
402 "ORDER BY icon_type DESC")); 504 "ORDER BY icon_type DESC"));
403 statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url)); 505 statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url));
404 statement.BindInt(1, required_icon_type); 506 statement.BindInt(1, required_icon_type);
405 507
406 if (!statement.Step()) 508 if (!statement.Step())
407 return 0; // not cached 509 return 0; // not cached
408 510
409 if (icon_type) 511 if (icon_type)
410 *icon_type = static_cast<IconType>(statement.ColumnInt(1)); 512 *icon_type = static_cast<IconType>(statement.ColumnInt(1));
411 return statement.ColumnInt64(0); 513 return statement.ColumnInt64(0);
412 } 514 }
413 515
414 bool ThumbnailDatabase::GetFavicon( 516 bool ThumbnailDatabase::GetFavicon(
415 FaviconID icon_id, 517 FaviconID icon_id,
416 base::Time* last_updated, 518 base::Time* last_updated,
417 std::vector<unsigned char>* png_icon_data, 519 scoped_refptr<base::RefCountedMemory>* png_icon_data,
418 GURL* icon_url, 520 GURL* icon_url,
419 IconType* icon_type) { 521 IconType* icon_type) {
420 DCHECK(icon_id); 522 DCHECK(icon_id);
421 523
524 std::vector<FaviconBitmap> favicon_bitmaps;
525 if (!GetFaviconBitmaps(icon_id, &favicon_bitmaps))
526 return false;
527
528 if (favicon_bitmaps.size() == 0)
sky 2012/08/16 16:12:57 empty
pkotwicz 2012/08/16 19:22:46 Done.
529 return false;
530
531 if (last_updated)
532 *last_updated = favicon_bitmaps[0].last_updated;
533
534 *png_icon_data = favicon_bitmaps[0].bitmap_data;
535
536 return GetFaviconHeader(icon_id, icon_url, icon_type, NULL);
537 }
538
539 bool ThumbnailDatabase::GetFaviconHeader(
540 FaviconID icon_id,
541 GURL* icon_url,
542 IconType* icon_type,
543 std::string* sizes) {
544 DCHECK(icon_id);
545
422 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 546 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
423 "SELECT last_updated, image_data, url, icon_type " 547 "SELECT url, icon_type, sizes FROM favicons WHERE id=?"));
424 "FROM favicons WHERE id=?"));
425 statement.BindInt64(0, icon_id); 548 statement.BindInt64(0, icon_id);
426 549
427 if (!statement.Step()) 550 if (!statement.Step())
428 return false; // No entry for the id. 551 return false; // No entry for the id.
429 552
430 if (last_updated)
431 *last_updated = base::Time::FromTimeT(statement.ColumnInt64(0));
432 if (statement.ColumnByteLength(1) > 0)
433 statement.ColumnBlobAsVector(1, png_icon_data);
434 if (icon_url) 553 if (icon_url)
435 *icon_url = GURL(statement.ColumnString(2)); 554 *icon_url = GURL(statement.ColumnString(0));
436 if (icon_type) 555 if (icon_type)
437 *icon_type = static_cast<history::IconType>(statement.ColumnInt(3)); 556 *icon_type = static_cast<history::IconType>(statement.ColumnInt(1));
557 if (sizes)
558 *sizes = statement.ColumnString(2);
438 559
439 return true; 560 return true;
440 } 561 }
441 562
442 FaviconID ThumbnailDatabase::AddFavicon(const GURL& icon_url, 563 FaviconID ThumbnailDatabase::AddFavicon(const GURL& icon_url,
443 IconType icon_type) { 564 IconType icon_type) {
444 565
445 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 566 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
446 "INSERT INTO favicons (url, icon_type) VALUES (?, ?)")); 567 "INSERT INTO favicons (url, icon_type) VALUES (?, ?)"));
447 statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url)); 568 statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url));
448 statement.BindInt(1, icon_type); 569 statement.BindInt(1, icon_type);
449 570
450 if (!statement.Run()) 571 if (!statement.Run())
451 return 0; 572 return 0;
452 return db_.GetLastInsertRowId(); 573 return db_.GetLastInsertRowId();
453 } 574 }
454 575
576 FaviconID ThumbnailDatabase::AddFavicon(
577 const GURL& icon_url,
578 IconType icon_type,
579 const std::string& sizes,
580 scoped_refptr<base::RefCountedMemory> icon_data,
581 base::Time time,
582 const gfx::Size& pixel_size) {
583 FaviconID icon_id = AddFavicon(icon_url, icon_type);
584 if (!icon_id ||
585 !SetFaviconSizes(icon_id, sizes) ||
586 !AddFaviconBitmap(icon_id, icon_data, time, pixel_size)) {
587 return 0;
588 }
589 return icon_id;
590 }
591
455 bool ThumbnailDatabase::DeleteFavicon(FaviconID id) { 592 bool ThumbnailDatabase::DeleteFavicon(FaviconID id) {
456 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 593 sql::Statement statement;
594 statement.Assign(db_.GetCachedStatement(SQL_FROM_HERE,
457 "DELETE FROM favicons WHERE id = ?")); 595 "DELETE FROM favicons WHERE id = ?"));
458 statement.BindInt64(0, id); 596 statement.BindInt64(0, id);
597 if (!statement.Run())
598 return false;
459 599
600 statement.Assign(db_.GetCachedStatement(SQL_FROM_HERE,
601 "DELETE FROM favicon_bitmaps WHERE icon_id = ?"));
602 statement.BindInt64(0, id);
460 return statement.Run(); 603 return statement.Run();
461 } 604 }
462 605
463 bool ThumbnailDatabase::GetIconMappingForPageURL(const GURL& page_url, 606 bool ThumbnailDatabase::GetIconMappingForPageURL(const GURL& page_url,
464 IconType required_icon_type, 607 IconType required_icon_type,
465 IconMapping* icon_mapping) { 608 IconMapping* icon_mapping) {
466 std::vector<IconMapping> icon_mappings; 609 std::vector<IconMapping> icon_mappings;
467 if (!GetIconMappingsForPageURL(page_url, &icon_mappings)) 610 if (!GetIconMappingsForPageURL(page_url, &icon_mappings))
468 return false; 611 return false;
469 612
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 724
582 IconMapping info; 725 IconMapping info;
583 while (e.GetNextIconMapping(&info)) { 726 while (e.GetNextIconMapping(&info)) {
584 // TODO: Using bulk insert to improve the performance. 727 // TODO: Using bulk insert to improve the performance.
585 if (!AddIconMapping(info.page_url, info.icon_id)) 728 if (!AddIconMapping(info.page_url, info.icon_id))
586 return false; 729 return false;
587 } 730 }
588 return true; 731 return true;
589 } 732 }
590 733
734 bool ThumbnailDatabase::InitTemporaryTables() {
735 return InitIconMappingTable(&db_, true) &&
736 InitFaviconsTable(&db_, true) &&
737 InitFaviconBitmapsTable(&db_, true);
738 }
739
740 bool ThumbnailDatabase::CommitTemporaryTables() {
741 const char* main_tables[] = { "icon_mapping",
742 "favicons",
743 "favicon_bitmaps" };
744 const char* temporary_tables[] = { "temp_icon_mapping",
745 "temp_favicons",
746 "temp_favicon_bitmaps" };
747
sky 2012/08/16 16:12:57 DCHECK_EQ(arraysize(main_tables), arraysize(tempor
pkotwicz 2012/08/16 19:22:46 Done.
748 for (size_t i = 0; i < arraysize(main_tables); ++i) {
749 // Delete the main table.
750 std::string sql;
751 sql.append("DROP TABLE ");
752 sql.append(main_tables[i]);
753 if (!db_.Execute(sql.c_str()))
754 return false;
755
756 // Rename the temporary table.
757 sql.clear();
758 sql.append("ALTER TABLE ");
759 sql.append(temporary_tables[i]);
760 sql.append(" RENAME TO ");
761 sql.append(main_tables[i]);
762 if (!db_.Execute(sql.c_str()))
763 return false;
764 }
765
766 // The renamed tables needs indices (the temporary tables don't have any).
767 return InitIconMappingIndex() &&
768 InitFaviconsIndex() &&
769 InitFaviconBitmapsIndex();
770 }
771
591 IconMappingID ThumbnailDatabase::AddToTemporaryIconMappingTable( 772 IconMappingID ThumbnailDatabase::AddToTemporaryIconMappingTable(
592 const GURL& page_url, const FaviconID icon_id) { 773 const GURL& page_url, const FaviconID icon_id) {
593 return AddIconMapping(page_url, icon_id, true); 774 return AddIconMapping(page_url, icon_id, true);
594 } 775 }
595 776
596 bool ThumbnailDatabase::CommitTemporaryIconMappingTable() { 777 FaviconID ThumbnailDatabase::CopyFaviconAndFaviconBitmapsToTemporaryTables(
597 // Delete the old icon_mapping table. 778 FaviconID source) {
598 if (!db_.Execute("DROP TABLE icon_mapping")) 779 sql::Statement statement;
599 return false; 780 statement.Assign(db_.GetCachedStatement(SQL_FROM_HERE,
600 781 "INSERT INTO temp_favicons (url, icon_type, sizes) "
601 // Rename the temporary one. 782 "SELECT url, icon_type, sizes FROM favicons WHERE id = ?"));
602 if (!db_.Execute("ALTER TABLE temp_icon_mapping RENAME TO icon_mapping"))
603 return false;
604
605 // The renamed table needs the index (the temporary table doesn't have one).
606 return InitIconMappingIndex();
607 }
608
609 FaviconID ThumbnailDatabase::CopyToTemporaryFaviconTable(FaviconID source) {
610 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
611 "INSERT INTO temp_favicons (url, last_updated, image_data, icon_type)"
612 "SELECT url, last_updated, image_data, icon_type "
613 "FROM favicons WHERE id = ?"));
614 statement.BindInt64(0, source); 783 statement.BindInt64(0, source);
615 784
616 if (!statement.Run()) 785 if (!statement.Run())
617 return 0; 786 return 0;
618 787
619 // We return the ID of the newly inserted favicon. 788 FaviconID new_favicon_id = db_.GetLastInsertRowId();
620 return db_.GetLastInsertRowId();
621 }
622 789
623 bool ThumbnailDatabase::CommitTemporaryFaviconTable() { 790 statement.Assign(db_.GetCachedStatement(SQL_FROM_HERE,
624 // Delete the old favicons table. 791 "INSERT INTO temp_favicon_bitmaps (icon_id, last_updated, image_data, "
625 if (!db_.Execute("DROP TABLE favicons")) 792 "width, height) "
626 return false; 793 "SELECT ?, last_updated, image_data, width, height "
794 "FROM favicon_bitmaps WHERE icon_id = ?"));
795 statement.BindInt64(0, new_favicon_id);
796 statement.BindInt64(1, source);
797 if (!statement.Run())
798 return 0;
627 799
628 // Rename the temporary one. 800 return new_favicon_id;
629 if (!db_.Execute("ALTER TABLE temp_favicons RENAME TO favicons"))
630 return false;
631
632 // The renamed table needs the index (the temporary table doesn't have one).
633 return InitFaviconsIndex();
634 } 801 }
635 802
636 bool ThumbnailDatabase::NeedsMigrationToTopSites() { 803 bool ThumbnailDatabase::NeedsMigrationToTopSites() {
637 return !use_top_sites_; 804 return !use_top_sites_;
638 } 805 }
639 806
640 bool ThumbnailDatabase::RenameAndDropThumbnails(const FilePath& old_db_file, 807 bool ThumbnailDatabase::RenameAndDropThumbnails(const FilePath& old_db_file,
641 const FilePath& new_db_file) { 808 const FilePath& new_db_file) {
642 // Init favicons table - same schema as the thumbnails. 809 // Init favicons tables - same schema as the thumbnails.
643 sql::Connection favicons; 810 sql::Connection favicons;
644 if (OpenDatabase(&favicons, new_db_file) != sql::INIT_OK) 811 if (OpenDatabase(&favicons, new_db_file) != sql::INIT_OK)
645 return false; 812 return false;
646 813
647 if (!InitFaviconsTable(&favicons, false) || 814 if (!InitFaviconBitmapsTable(&favicons, false) ||
815 !InitFaviconsTable(&favicons, false) ||
648 !InitIconMappingTable(&favicons, false)) { 816 !InitIconMappingTable(&favicons, false)) {
649 favicons.Close(); 817 favicons.Close();
650 return false; 818 return false;
651 } 819 }
652 favicons.Close(); 820 favicons.Close();
653 821
654 // Can't attach within a transaction. 822 // Can't attach within a transaction.
655 if (transaction_nesting()) 823 if (transaction_nesting())
656 CommitTransaction(); 824 CommitTransaction();
657 825
(...skipping 13 matching lines...) Expand all
671 #else 839 #else
672 attach.BindString(0, WideToUTF8(new_db_file.value())); 840 attach.BindString(0, WideToUTF8(new_db_file.value()));
673 #endif 841 #endif
674 842
675 if (!attach.Run()) { 843 if (!attach.Run()) {
676 BeginTransaction(); 844 BeginTransaction();
677 return false; 845 return false;
678 } 846 }
679 } 847 }
680 848
681 // Move favicons to the new DB. 849 // Move favicons and favicon_bitmaps to new DB.
682 if (!db_.Execute("INSERT OR REPLACE INTO new_favicons.favicons " 850 bool successfully_moved_data =
683 "SELECT * FROM favicons")) { 851 db_.Execute("INSERT OR REPLACE INTO new_favicons.favicon_bitmaps "
684 DLOG(FATAL) << "Unable to copy favicons."; 852 "SELECT * FROM favicon_bitmaps") &&
853 db_.Execute("INSERT OR REPLACE INTO new_favicons.favicons "
854 "SELECT * FROM favicons");
855 if (!successfully_moved_data) {
856 DLOG(FATAL) << "Unable to copy favicons and bitmap_bitmaps.";
685 BeginTransaction(); 857 BeginTransaction();
686 return false; 858 return false;
687 } 859 }
688 860
689 if (!db_.Execute("DETACH new_favicons")) { 861 if (!db_.Execute("DETACH new_favicons")) {
690 DLOG(FATAL) << "Unable to detach database."; 862 DLOG(FATAL) << "Unable to detach database.";
691 BeginTransaction(); 863 BeginTransaction();
692 return false; 864 return false;
693 } 865 }
694 866
695 db_.Close(); 867 db_.Close();
696 868
697 // Reset the DB to point to new file. 869 // Reset the DB to point to new file.
698 if (OpenDatabase(&db_, new_db_file) != sql::INIT_OK) 870 if (OpenDatabase(&db_, new_db_file) != sql::INIT_OK)
699 return false; 871 return false;
700 872
701 file_util::Delete(old_db_file, false); 873 file_util::Delete(old_db_file, false);
702 874
703 meta_table_.Reset(); 875 meta_table_.Reset();
704 if (!meta_table_.Init(&db_, kCurrentVersionNumber, kCompatibleVersionNumber)) 876 if (!meta_table_.Init(&db_, kCurrentVersionNumber, kCompatibleVersionNumber))
705 return false; 877 return false;
706 878
707 if (!InitFaviconsIndex()) 879 if (!InitFaviconBitmapsIndex() || !InitFaviconsIndex())
708 return false; 880 return false;
709 881
710 // Reopen the transaction. 882 // Reopen the transaction.
711 BeginTransaction(); 883 BeginTransaction();
712 use_top_sites_ = true; 884 use_top_sites_ = true;
713 return true; 885 return true;
714 } 886 }
715 887
716 bool ThumbnailDatabase::InitIconMappingTable(sql::Connection* db, 888 bool ThumbnailDatabase::InitIconMappingTable(sql::Connection* db,
717 bool is_temporary) { 889 bool is_temporary) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 951
780 bool ThumbnailDatabase::UpgradeToVersion5() { 952 bool ThumbnailDatabase::UpgradeToVersion5() {
781 if (!db_.Execute("ALTER TABLE favicons ADD sizes LONGVARCHAR")) { 953 if (!db_.Execute("ALTER TABLE favicons ADD sizes LONGVARCHAR")) {
782 return false; 954 return false;
783 } 955 }
784 meta_table_.SetVersionNumber(5); 956 meta_table_.SetVersionNumber(5);
785 meta_table_.SetCompatibleVersionNumber(std::min(5, kCompatibleVersionNumber)); 957 meta_table_.SetCompatibleVersionNumber(std::min(5, kCompatibleVersionNumber));
786 return true; 958 return true;
787 } 959 }
788 960
961 bool ThumbnailDatabase::UpgradeToVersion6() {
962 bool success =
963 db_.Execute("INSERT INTO favicon_bitmaps (icon_id, last_updated, "
964 "image_data)"
965 "SELECT id, last_updated, image_data FROM favicons") &&
sky 2012/08/16 16:12:57 Don't you need to set the width/height?
pkotwicz 2012/08/16 19:22:46 Done.
966 db_.Execute("CREATE TABLE temp_favicons ("
967 "id INTEGER PRIMARY KEY,"
968 "url LONGVARCHAR NOT NULL,"
969 "icon_type INTEGER DEFAULT 1,"
sky 2012/08/16 16:12:57 Document what 1 is here.
pkotwicz 2012/08/16 19:22:46 Done.
970 "sizes LONGVARCHAR DEFAULT '0 0')") &&
sky 2012/08/16 16:12:57 Why default to 0x0?
pkotwicz 2012/08/16 19:22:46 The default is 0x0 because it is a very recognizab
971 db_.Execute("INSERT INTO temp_favicons (id, url, icon_type) "
972 "SELECT id, url, icon_type FROM favicons") &&
973 db_.Execute("DROP TABLE favicons") &&
974 db_.Execute("ALTER TABLE temp_favicons RENAME TO favicons");
975
976 meta_table_.SetVersionNumber(6);
sky 2012/08/16 16:12:57 Early return if execute fails on the previous line
pkotwicz 2012/08/16 19:22:46 Done.
977 meta_table_.SetCompatibleVersionNumber(std::min(6, kCompatibleVersionNumber));
978 return success;
979 }
980
789 } // namespace history 981 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698