Chromium Code Reviews| OLD | NEW |
|---|---|
| 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" |
| 11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
| 12 #include "base/memory/ref_counted_memory.h" | 12 #include "base/memory/ref_counted_memory.h" |
| 13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 14 #include "base/time.h" | 14 #include "base/time.h" |
| 15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
| 16 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" | 16 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" |
| 17 #include "chrome/browser/history/history_publisher.h" | 17 #include "chrome/browser/history/history_publisher.h" |
| 18 #include "chrome/browser/history/top_sites.h" | 18 #include "chrome/browser/history/top_sites.h" |
| 19 #include "chrome/browser/history/url_database.h" | 19 #include "chrome/browser/history/url_database.h" |
| 20 #include "chrome/common/thumbnail_score.h" | 20 #include "chrome/common/thumbnail_score.h" |
| 21 #include "sql/statement.h" | 21 #include "sql/statement.h" |
| 22 #include "sql/transaction.h" | 22 #include "sql/transaction.h" |
| 23 #include "ui/gfx/favicon_size.h" | |
| 23 #include "ui/gfx/image/image_util.h" | 24 #include "ui/gfx/image/image_util.h" |
| 24 | 25 |
| 25 #if defined(OS_MACOSX) | 26 #if defined(OS_MACOSX) |
| 26 #include "base/mac/mac_util.h" | 27 #include "base/mac/mac_util.h" |
| 27 #endif | 28 #endif |
| 28 | 29 |
| 29 static void FillIconMapping(const sql::Statement& statement, | 30 static void FillIconMapping(const sql::Statement& statement, |
| 30 const GURL& page_url, | 31 const GURL& page_url, |
| 31 history::IconMapping* icon_mapping) { | 32 history::IconMapping* icon_mapping) { |
| 32 icon_mapping->mapping_id = statement.ColumnInt64(0); | 33 icon_mapping->mapping_id = statement.ColumnInt64(0); |
| 33 icon_mapping->icon_id = statement.ColumnInt64(1); | 34 icon_mapping->icon_id = statement.ColumnInt64(1); |
| 34 icon_mapping->icon_type = | 35 icon_mapping->icon_type = |
| 35 static_cast<history::IconType>(statement.ColumnInt(2)); | 36 static_cast<history::IconType>(statement.ColumnInt(2)); |
| 36 icon_mapping->page_url = page_url; | 37 icon_mapping->page_url = page_url; |
| 37 } | 38 } |
| 38 | 39 |
| 39 namespace history { | 40 namespace history { |
| 40 | 41 |
| 41 // Version number of the database. | 42 // Version number of the database. |
| 42 static const int kCurrentVersionNumber = 5; | 43 static const int kCurrentVersionNumber = 6; |
| 43 static const int kCompatibleVersionNumber = 5; | 44 static const int kCompatibleVersionNumber = 6; |
| 44 | 45 |
| 45 // Use 90 quality (out of 100) which is pretty high, because we're very | 46 // 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. | 47 // sensitive to artifacts for these small sized, highly detailed images. |
| 47 static const int kImageQuality = 90; | 48 static const int kImageQuality = 90; |
| 48 | 49 |
| 49 ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() { | 50 ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() { |
| 50 } | 51 } |
| 51 | 52 |
| 52 ThumbnailDatabase::IconMappingEnumerator::~IconMappingEnumerator() { | 53 ThumbnailDatabase::IconMappingEnumerator::~IconMappingEnumerator() { |
| 53 } | 54 } |
| 54 | 55 |
| 55 bool ThumbnailDatabase::IconMappingEnumerator::GetNextIconMapping( | 56 bool ThumbnailDatabase::IconMappingEnumerator::GetNextIconMapping( |
| 56 IconMapping* icon_mapping) { | 57 IconMapping* icon_mapping) { |
| 57 if (!statement_.Step()) | 58 if (!statement_.Step()) |
| 58 return false; | 59 return false; |
| 59 FillIconMapping(statement_, GURL(statement_.ColumnString(3)), icon_mapping); | 60 FillIconMapping(statement_, GURL(statement_.ColumnString(3)), icon_mapping); |
| 60 return true; | 61 return true; |
| 61 } | 62 } |
| 62 | 63 |
| 63 ThumbnailDatabase::ThumbnailDatabase() | 64 ThumbnailDatabase::ThumbnailDatabase() |
| 64 : history_publisher_(NULL), | 65 : history_publisher_(NULL), |
| 65 use_top_sites_(false) { | 66 use_top_sites_(false) { |
| 66 } | 67 } |
| 67 | 68 |
| 68 sql::InitStatus ThumbnailDatabase::CantUpgradeToVersion(int cur_version) { | 69 sql::InitStatus ThumbnailDatabase::CantUpgradeToVersion(int cur_version) { |
| 69 LOG(WARNING) << "Unable to update to thumbnail database to version 4" << | 70 LOG(WARNING) << "Unable to update to thumbnail database to version " << |
| 70 cur_version << "."; | 71 cur_version << "."; |
| 71 db_.Close(); | 72 db_.Close(); |
| 72 return sql::INIT_FAILURE; | 73 return sql::INIT_FAILURE; |
| 73 } | 74 } |
| 74 | 75 |
| 75 ThumbnailDatabase::~ThumbnailDatabase() { | 76 ThumbnailDatabase::~ThumbnailDatabase() { |
| 76 // The DBCloseScoper will delete the DB and the cache. | 77 // The DBCloseScoper will delete the DB and the cache. |
| 77 } | 78 } |
| 78 | 79 |
| 79 sql::InitStatus ThumbnailDatabase::Init( | 80 sql::InitStatus ThumbnailDatabase::Init( |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 return CantUpgradeToVersion(cur_version); | 121 return CantUpgradeToVersion(cur_version); |
| 121 } | 122 } |
| 122 | 123 |
| 123 if (cur_version == 3) { | 124 if (cur_version == 3) { |
| 124 ++cur_version; | 125 ++cur_version; |
| 125 if (!UpgradeToVersion4() || !MigrateIconMappingData(url_db)) | 126 if (!UpgradeToVersion4() || !MigrateIconMappingData(url_db)) |
| 126 return CantUpgradeToVersion(cur_version); | 127 return CantUpgradeToVersion(cur_version); |
| 127 } | 128 } |
| 128 | 129 |
| 129 if (cur_version == 4) { | 130 if (cur_version == 4) { |
| 131 ++cur_version; | |
| 130 if (!UpgradeToVersion5()) | 132 if (!UpgradeToVersion5()) |
| 131 return CantUpgradeToVersion(cur_version); | 133 return CantUpgradeToVersion(cur_version); |
| 132 } | 134 } |
| 133 | 135 |
| 136 if (cur_version == 5) { | |
| 137 ++cur_version; | |
| 138 if (!UpgradeToVersion6()) | |
| 139 return CantUpgradeToVersion(cur_version); | |
| 140 } | |
| 141 | |
| 134 LOG_IF(WARNING, cur_version < kCurrentVersionNumber) << | 142 LOG_IF(WARNING, cur_version < kCurrentVersionNumber) << |
| 135 "Thumbnail database version " << cur_version << " is too old to handle."; | 143 "Thumbnail database version " << cur_version << " is too old to handle."; |
| 136 | 144 |
| 137 // Initialization is complete. | 145 // Initialization is complete. |
| 138 if (!transaction.Commit()) { | 146 if (!transaction.Commit()) { |
| 139 db_.Close(); | 147 db_.Close(); |
| 140 return sql::INIT_FAILURE; | 148 return sql::INIT_FAILURE; |
| 141 } | 149 } |
| 142 | 150 |
| 143 return sql::INIT_OK; | 151 return sql::INIT_OK; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 sql.append("CREATE TABLE "); | 226 sql.append("CREATE TABLE "); |
| 219 sql.append(name); | 227 sql.append(name); |
| 220 sql.append("(" | 228 sql.append("(" |
| 221 "id INTEGER PRIMARY KEY," | 229 "id INTEGER PRIMARY KEY," |
| 222 "url LONGVARCHAR NOT NULL," | 230 "url LONGVARCHAR NOT NULL," |
| 223 "last_updated INTEGER DEFAULT 0," | 231 "last_updated INTEGER DEFAULT 0," |
| 224 "image_data BLOB," | 232 "image_data BLOB," |
| 225 // Set the default icon_type as FAVICON to be consistent with | 233 // Set the default icon_type as FAVICON to be consistent with |
| 226 // table upgrade in UpgradeToVersion4(). | 234 // table upgrade in UpgradeToVersion4(). |
| 227 "icon_type INTEGER DEFAULT 1," | 235 "icon_type INTEGER DEFAULT 1," |
| 228 "sizes LONGVARCHAR)"); | 236 "size INTEGER)"); |
|
sky
2012/07/24 04:38:47
Doesn't this assume the size is a rectangle?
| |
| 229 if (!db->Execute(sql.c_str())) | 237 if (!db->Execute(sql.c_str())) |
| 230 return false; | 238 return false; |
| 231 } | 239 } |
| 232 return true; | 240 return true; |
| 233 } | 241 } |
| 234 | 242 |
| 235 bool ThumbnailDatabase::InitFaviconsIndex() { | 243 bool ThumbnailDatabase::InitFaviconsIndex() { |
| 236 // Add an index on the url column. | 244 // Add an index on the url column. |
| 237 return | 245 return |
| 238 db_.Execute("CREATE INDEX IF NOT EXISTS favicons_url ON favicons(url)"); | 246 db_.Execute("CREATE INDEX IF NOT EXISTS favicons_url ON favicons(url)"); |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 436 if (icon_type) | 444 if (icon_type) |
| 437 *icon_type = static_cast<history::IconType>(statement.ColumnInt(3)); | 445 *icon_type = static_cast<history::IconType>(statement.ColumnInt(3)); |
| 438 | 446 |
| 439 return true; | 447 return true; |
| 440 } | 448 } |
| 441 | 449 |
| 442 FaviconID ThumbnailDatabase::AddFavicon(const GURL& icon_url, | 450 FaviconID ThumbnailDatabase::AddFavicon(const GURL& icon_url, |
| 443 IconType icon_type) { | 451 IconType icon_type) { |
| 444 | 452 |
| 445 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 453 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
| 446 "INSERT INTO favicons (url, icon_type) VALUES (?, ?)")); | 454 "INSERT INTO favicons (url, icon_type, size) VALUES (?, ?, ?)")); |
| 447 statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url)); | 455 statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url)); |
| 448 statement.BindInt(1, icon_type); | 456 statement.BindInt(1, icon_type); |
| 457 statement.BindInt(2, icon_type == FAVICON ? gfx::kFaviconSize : 0); | |
| 449 | 458 |
| 450 if (!statement.Run()) | 459 if (!statement.Run()) |
| 451 return 0; | 460 return 0; |
| 452 return db_.GetLastInsertRowId(); | 461 return db_.GetLastInsertRowId(); |
| 453 } | 462 } |
| 454 | 463 |
| 455 bool ThumbnailDatabase::DeleteFavicon(FaviconID id) { | 464 bool ThumbnailDatabase::DeleteFavicon(FaviconID id) { |
| 456 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 465 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
| 457 "DELETE FROM favicons WHERE id = ?")); | 466 "DELETE FROM favicons WHERE id = ?")); |
| 458 statement.BindInt64(0, id); | 467 statement.BindInt64(0, id); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 601 // Rename the temporary one. | 610 // Rename the temporary one. |
| 602 if (!db_.Execute("ALTER TABLE temp_icon_mapping RENAME TO icon_mapping")) | 611 if (!db_.Execute("ALTER TABLE temp_icon_mapping RENAME TO icon_mapping")) |
| 603 return false; | 612 return false; |
| 604 | 613 |
| 605 // The renamed table needs the index (the temporary table doesn't have one). | 614 // The renamed table needs the index (the temporary table doesn't have one). |
| 606 return InitIconMappingIndex(); | 615 return InitIconMappingIndex(); |
| 607 } | 616 } |
| 608 | 617 |
| 609 FaviconID ThumbnailDatabase::CopyToTemporaryFaviconTable(FaviconID source) { | 618 FaviconID ThumbnailDatabase::CopyToTemporaryFaviconTable(FaviconID source) { |
| 610 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 619 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
| 611 "INSERT INTO temp_favicons (url, last_updated, image_data, icon_type)" | 620 "INSERT INTO temp_favicons (url, last_updated, image_data, icon_type, " |
| 612 "SELECT url, last_updated, image_data, icon_type " | 621 "size)" |
| 622 "SELECT url, last_updated, image_data, icon_type, size " | |
| 613 "FROM favicons WHERE id = ?")); | 623 "FROM favicons WHERE id = ?")); |
| 614 statement.BindInt64(0, source); | 624 statement.BindInt64(0, source); |
| 615 | 625 |
| 616 if (!statement.Run()) | 626 if (!statement.Run()) |
| 617 return 0; | 627 return 0; |
| 618 | 628 |
| 619 // We return the ID of the newly inserted favicon. | 629 // We return the ID of the newly inserted favicon. |
| 620 return db_.GetLastInsertRowId(); | 630 return db_.GetLastInsertRowId(); |
| 621 } | 631 } |
| 622 | 632 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 779 | 789 |
| 780 bool ThumbnailDatabase::UpgradeToVersion5() { | 790 bool ThumbnailDatabase::UpgradeToVersion5() { |
| 781 if (!db_.Execute("ALTER TABLE favicons ADD sizes LONGVARCHAR")) { | 791 if (!db_.Execute("ALTER TABLE favicons ADD sizes LONGVARCHAR")) { |
| 782 return false; | 792 return false; |
| 783 } | 793 } |
| 784 meta_table_.SetVersionNumber(5); | 794 meta_table_.SetVersionNumber(5); |
| 785 meta_table_.SetCompatibleVersionNumber(std::min(5, kCompatibleVersionNumber)); | 795 meta_table_.SetCompatibleVersionNumber(std::min(5, kCompatibleVersionNumber)); |
| 786 return true; | 796 return true; |
| 787 } | 797 } |
| 788 | 798 |
| 799 bool ThumbnailDatabase::UpgradeToVersion6() { | |
| 800 bool success = | |
| 801 db_.Execute("CREATE TABLE favicons_temp (" | |
| 802 "id INTEGER PRIMARY KEY," | |
| 803 "url LONGVARCHAR NOT NULL," | |
| 804 "last_updated INTEGER DEFAULT 0," | |
| 805 "image_data BLOB," | |
| 806 "icon_type INTEGER DEFAULT 1," | |
| 807 "size INTEGER DEFAULT 0)") && | |
| 808 db_.Execute("INSERT INTO favicons_temp (id, url, last_updated, " | |
| 809 "image_data, icon_type)" | |
| 810 "SELECT id, url, last_updated, image_data, icon_type FROM " | |
| 811 "favicons") && | |
| 812 db_.Execute("DROP TABLE favicons") && | |
| 813 db_.Execute("ALTER TABLE favicons_temp RENAME TO favicons"); | |
| 814 | |
| 815 // In version 4 & 5 of the database, favicons of type FAVICON are assumed to | |
| 816 // be 16px in size. | |
| 817 success &= db_.Execute( | |
| 818 "UPDATE favicons SET size = '16' WHERE icon_type = '1'"); | |
| 819 | |
| 820 meta_table_.SetVersionNumber(6); | |
| 821 meta_table_.SetCompatibleVersionNumber(std::min(6, kCompatibleVersionNumber)); | |
| 822 return success; | |
| 823 } | |
| 824 | |
| 789 } // namespace history | 825 } // namespace history |
| OLD | NEW |