1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/thumbnail_database.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <algorithm> 872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <string> 972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/sql/statement.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/sql/transaction.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/command_line.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted_memory.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/diagnostics/sqlite_diagnostics.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history_publisher.h" 203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/history/top_sites.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/url_database.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/thumbnail_score.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/skia/include/core/SkBitmap.h" 2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/codec/jpeg_codec.h" 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#if defined(OS_MACOSX) 273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/mac/mac_util.h" 283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif 293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic void FillIconMapping(const sql::Statement& statement, 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& page_url, 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen history::IconMapping* icon_mapping) { 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen icon_mapping->mapping_id = statement.ColumnInt64(0); 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen icon_mapping->icon_id = statement.ColumnInt64(1); 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen icon_mapping->icon_type = 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static_cast<history::IconType>(statement.ColumnInt(2)); 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen icon_mapping->page_url = page_url; 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace history { 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Version number of the database. 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const int kCurrentVersionNumber = 4; 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const int kCompatibleVersionNumber = 4; 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenThumbnailDatabase::ThumbnailDatabase() 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : history_publisher_(NULL), 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen use_top_sites_(false) { 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochThumbnailDatabase::~ThumbnailDatabase() { 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The DBCloseScoper will delete the DB and the cache. 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochsql::InitStatus ThumbnailDatabase::Init( 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FilePath& db_name, 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const HistoryPublisher* history_publisher, 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen URLDatabase* url_db) { 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history_publisher_ = history_publisher; 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::InitStatus status = OpenDatabase(&db_, db_name); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (status != sql::INIT_OK) 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return status; 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Scope initialization in a transaction so we can't be partially initialized. 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Transaction transaction(&db_); 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch transaction.Begin(); 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX) 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Exclude the thumbnails file and its journal from backups. 703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::mac::SetFileBackupExclusion(db_name, true); 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath::StringType db_name_string(db_name.value()); 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_name_string += "-journal"; 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath db_journal_name(db_name_string); 743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::mac::SetFileBackupExclusion(db_journal_name, true); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create the tables. 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!meta_table_.Init(&db_, kCurrentVersionNumber, 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kCompatibleVersionNumber) || 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !InitThumbnailTable() || 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !InitFaviconsTable(&db_, false) || 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !InitIconMappingTable(&db_, false)) { 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.Close(); 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_FAILURE; 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen InitFaviconsIndex(); 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen InitIconMappingIndex(); 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Version check. We should not encounter a database too old for us to handle 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // in the wild, so we try to continue in that case. 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Thumbnail database is too new."; 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_TOO_NEW; 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int cur_version = meta_table_.GetVersionNumber(); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cur_version == 2) { 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!UpgradeToVersion3()) { 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Unable to update to thumbnail database to version 3."; 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.Close(); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_FAILURE; 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++cur_version; 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (cur_version == 3) { 107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!UpgradeToVersion4() || !MigrateIconMappingData(url_db)) { 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(WARNING) << "Unable to update to thumbnail database to version 4."; 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen db_.Close(); 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return sql::INIT_FAILURE; 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ++cur_version; 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG_IF(WARNING, cur_version < kCurrentVersionNumber) << 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Thumbnail database version " << cur_version << " is too old to handle."; 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Initialization is complete. 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!transaction.Commit()) { 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.Close(); 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_FAILURE; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_OK; 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochsql::InitStatus ThumbnailDatabase::OpenDatabase(sql::Connection* db, 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FilePath& db_name) { 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the exceptional sqlite error handler. 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db->set_error_delegate(GetErrorHandlerForThumbnailDb()); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 132513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Thumbnails db now only stores favicons, so we don't need that big a page 133513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // size or cache. 134513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch db->set_page_size(2048); 135513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch db->set_cache_size(32); 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Run the database in exclusive mode. Nobody else should be accessing the 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // database while we're running, and this will give somewhat improved perf. 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db->set_exclusive_locking(); 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db->Open(db_name)) 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_FAILURE; 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_OK; 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::InitThumbnailTable() { 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.DoesTableExist("thumbnails")) { 14972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen use_top_sites_ = true; 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::UpgradeToVersion3() { 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (use_top_sites_) { 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch meta_table_.SetVersionNumber(3); 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch meta_table_.SetCompatibleVersionNumber( 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::min(3, kCompatibleVersionNumber)); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; // Not needed after migration to TopSites. 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // sqlite doesn't like the "ALTER TABLE xxx ADD (column_one, two, 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // three)" syntax, so list out the commands we need to execute: 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* alterations[] = { 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ALTER TABLE thumbnails ADD boring_score DOUBLE DEFAULT 1.0", 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ALTER TABLE thumbnails ADD good_clipping INTEGER DEFAULT 0", 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ALTER TABLE thumbnails ADD at_top INTEGER DEFAULT 0", 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ALTER TABLE thumbnails ADD last_updated INTEGER DEFAULT 0", 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; alterations[i] != NULL; ++i) { 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.Execute(alterations[i])) { 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch meta_table_.SetVersionNumber(3); 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch meta_table_.SetCompatibleVersionNumber(std::min(3, kCompatibleVersionNumber)); 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::RecreateThumbnailTable() { 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (use_top_sites_) 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; // Not needed after migration to TopSites. 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.Execute("DROP TABLE thumbnails")) 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return InitThumbnailTable(); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::InitFaviconsTable(sql::Connection* db, 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_temporary) { 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: if you update the schema, don't forget to update 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // CopyToTemporaryFaviconTable as well. 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* name = is_temporary ? "temp_favicons" : "favicons"; 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db->DoesTableExist(name)) { 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string sql; 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql.append("CREATE TABLE "); 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql.append(name); 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql.append("(" 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "id INTEGER PRIMARY KEY," 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url LONGVARCHAR NOT NULL," 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "last_updated INTEGER DEFAULT 0," 206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "image_data BLOB," 207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "icon_type INTEGER DEFAULT 1)"); // Set the default as FAVICON 208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // to be consistent with table 209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // upgrade in 210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // UpgradeToVersion4(). 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db->Execute(sql.c_str())) 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThumbnailDatabase::InitFaviconsIndex() { 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add an index on the url column. We ignore errors. Since this is always 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // called during startup, the index will normally already exist. 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.Execute("CREATE INDEX favicons_url ON favicons(url)"); 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ThumbnailDatabase::BeginTransaction() { 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.BeginTransaction(); 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ThumbnailDatabase::CommitTransaction() { 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.CommitTransaction(); 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ThumbnailDatabase::Vacuum() { 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(db_.transaction_nesting() == 0) << 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Can not have a transaction when vacuuming."; 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.Execute("VACUUM"); 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ThumbnailDatabase::SetPageThumbnail( 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLID id, 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const SkBitmap& thumbnail, 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ThumbnailScore& score, 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time time) { 2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (use_top_sites_) { 2443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(WARNING) << "Use TopSites instead."; 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; // Not possible after migration to TopSites. 2463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!thumbnail.isNull()) { 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool add_thumbnail = true; 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ThumbnailScore current_score; 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ThumbnailScoreForId(id, ¤t_score)) { 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch add_thumbnail = ShouldReplaceThumbnailWith(current_score, score); 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (add_thumbnail) { 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "INSERT OR REPLACE INTO thumbnails " 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "(url_id, boring_score, good_clipping, at_top, last_updated, data) " 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "VALUES (?,?,?,?,?,?)")); 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We use 90 quality (out of 100) which is pretty high, because 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we're very sensitive to artifacts for these small sized, 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // highly detailed images. 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<unsigned char> jpeg_data; 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkAutoLockPixels thumbnail_lock(thumbnail); 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool encoded = gfx::JPEGCodec::Encode( 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<unsigned char*>(thumbnail.getAddr32(0, 0)), 270731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick gfx::JPEGCodec::FORMAT_SkBitmap, thumbnail.width(), 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thumbnail.height(), 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(thumbnail.rowBytes()), 90, 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &jpeg_data); 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (encoded) { 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, id); 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindDouble(1, score.boring_score); 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindBool(2, score.good_clipping); 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindBool(3, score.at_top); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(4, score.time_at_snapshot.ToTimeT()); 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindBlob(5, &jpeg_data[0], 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(jpeg_data.size())); 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Run()) 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << db_.GetErrorMessage(); 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Publish the thumbnail to any indexers listening to us. 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The tests may send an invalid url. Hence avoid publishing those. 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (url.is_valid() && history_publisher_ != NULL) 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history_publisher_->PublishPageThumbnail(jpeg_data, url, time); 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!DeleteThumbnail(id) ) 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DLOG(WARNING) << "Unable to delete thumbnail"; 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::GetPageThumbnail(URLID id, 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<unsigned char>* data) { 3003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (use_top_sites_) { 3013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(WARNING) << "Use TopSites instead."; 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; // Not possible after migration to TopSites. 3033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT data FROM thumbnails WHERE url_id=?")); 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, id); 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Step()) 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; // don't have a thumbnail for this ID 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.ColumnBlobAsVector(0, data); 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::DeleteThumbnail(URLID id) { 3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (use_top_sites_) { 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; // Not possible after migration to TopSites. 3213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "DELETE FROM thumbnails WHERE url_id = ?")); 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, id); 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return statement.Run(); 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::ThumbnailScoreForId(URLID id, 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ThumbnailScore* score) { 3343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (use_top_sites_) { 3353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(WARNING) << "Use TopSites instead."; 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; // Not possible after migration to TopSites. 3373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Fetch the current thumbnail's information to make sure we 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // aren't replacing a good thumbnail with one that's worse. 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement select_statement(db_.GetCachedStatement(SQL_FROM_HERE, 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT boring_score, good_clipping, at_top, last_updated " 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "FROM thumbnails WHERE url_id=?")); 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!select_statement) { 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Couldn't build select statement!"; 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch select_statement.BindInt64(0, id); 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (select_statement.Step()) { 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch double current_boring_score = select_statement.ColumnDouble(0); 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool current_clipping = select_statement.ColumnBool(1); 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool current_at_top = select_statement.ColumnBool(2); 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time last_updated = 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time::FromTimeT(select_statement.ColumnInt64(3)); 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *score = ThumbnailScore(current_boring_score, current_clipping, 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current_at_top, last_updated); 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::SetFavicon(URLID icon_id, 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<RefCountedMemory> icon_data, 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time time) { 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(icon_id); 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (icon_data->size()) { 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "UPDATE favicons SET image_data=?, last_updated=? WHERE id=?")); 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindBlob(0, icon_data->front(), 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(icon_data->size())); 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(1, time.ToTimeT()); 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(2, icon_id); 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return statement.Run(); 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "UPDATE favicons SET image_data=NULL, last_updated=? WHERE id=?")); 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, time.ToTimeT()); 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(1, icon_id); 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return statement.Run(); 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::SetFaviconLastUpdateTime(FaviconID icon_id, 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time time) { 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "UPDATE favicons SET last_updated=? WHERE id=?")); 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, time.ToTimeT()); 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(1, icon_id); 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return statement.Run(); 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenFaviconID ThumbnailDatabase::GetFaviconIDForFaviconURL(const GURL& icon_url, 403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int required_icon_type, 404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IconType* icon_type) { 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "SELECT id, icon_type FROM favicons WHERE url=? AND (icon_type & ? > 0) " 407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "ORDER BY icon_type DESC")); 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url)); 412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen statement.BindInt(1, required_icon_type); 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Step()) 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; // not cached 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (icon_type) 417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *icon_type = static_cast<IconType>(statement.ColumnInt(1)); 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return statement.ColumnInt64(0); 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::GetFavicon( 422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FaviconID icon_id, 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time* last_updated, 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<unsigned char>* png_icon_data, 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL* icon_url) { 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(icon_id); 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT last_updated, image_data, url FROM favicons WHERE id=?")); 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, icon_id); 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Step()) 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; // No entry for the id. 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *last_updated = base::Time::FromTimeT(statement.ColumnInt64(0)); 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (statement.ColumnByteLength(1) > 0) 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.ColumnBlobAsVector(1, png_icon_data); 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (icon_url) 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *icon_url = GURL(statement.ColumnString(2)); 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenFaviconID ThumbnailDatabase::AddFavicon(const GURL& icon_url, 448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IconType icon_type) { 449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "INSERT INTO favicons (url, icon_type) VALUES (?, ?)")); 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url)); 456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen statement.BindInt(1, icon_type); 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Run()) 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return db_.GetLastInsertRowId(); 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::DeleteFavicon(FaviconID id) { 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "DELETE FROM favicons WHERE id = ?")); 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, id); 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return statement.Run(); 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::GetIconMappingForPageURL(const GURL& page_url, 473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IconType required_icon_type, 474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IconMapping* icon_mapping) { 475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<IconMapping> icon_mappings; 476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!GetIconMappingsForPageURL(page_url, &icon_mappings)) 477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); 480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen m != icon_mappings.end(); ++m) { 481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (m->icon_type == required_icon_type) { 482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (icon_mapping != NULL) 483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *icon_mapping = *m; 484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::GetIconMappingsForPageURL( 492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& page_url, 493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<IconMapping>* mapping_data) { 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "SELECT icon_mapping.id, icon_mapping.icon_id, favicons.icon_type " 496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "FROM icon_mapping " 497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "INNER JOIN favicons " 498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "ON icon_mapping.icon_id = favicons.id " 499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "WHERE icon_mapping.page_url=? " 500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "ORDER BY favicons.icon_type DESC")); 501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!statement) 502ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 503ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 504ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen statement.BindString(0, URLDatabase::GURLToDatabaseURL(page_url)); 505ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool result = false; 507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen while (statement.Step()) { 508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result = true; 509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!mapping_data) 510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result; 511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IconMapping icon_mapping; 513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FillIconMapping(statement, page_url, &icon_mapping); 514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen mapping_data->push_back(icon_mapping); 515ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 516ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result; 517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 518ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 519ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenIconMappingID ThumbnailDatabase::AddIconMapping(const GURL& page_url, 520ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FaviconID icon_id) { 521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return AddIconMapping(page_url, icon_id, false); 522ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 523ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::UpdateIconMapping(IconMappingID mapping_id, 525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FaviconID icon_id) { 526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 527ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "UPDATE icon_mapping SET icon_id=? WHERE id=?")); 528ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!statement) 529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return 0; 530ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 531ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen statement.BindInt64(0, icon_id); 532ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen statement.BindInt64(1, mapping_id); 533ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return statement.Run(); 534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::DeleteIconMappings(const GURL& page_url) { 537ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "DELETE FROM icon_mapping WHERE page_url = ?")); 539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!statement) 540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen statement.BindString(0, URLDatabase::GURLToDatabaseURL(page_url)); 543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return statement.Run(); 544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::HasMappingFor(FaviconID id) { 547ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "SELECT id FROM icon_mapping " 549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "WHERE icon_id=?")); 550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!statement) 551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 552ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 553ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen statement.BindInt64(0, id); 554ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return statement.Step(); 555ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 557ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::MigrateIconMappingData(URLDatabase* url_db) { 558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen URLDatabase::IconMappingEnumerator e; 559ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!url_db->InitIconMappingEnumeratorForEverything(&e)) 560ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IconMapping info; 563ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen while (e.GetNextIconMapping(&info)) { 564ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO: Using bulk insert to improve the performance. 565ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!AddIconMapping(info.page_url, info.icon_id)) 566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 567ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 568ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 569ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenIconMappingID ThumbnailDatabase::AddToTemporaryIconMappingTable( 572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& page_url, const FaviconID icon_id) { 573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return AddIconMapping(page_url, icon_id, true); 574ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 575ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::CommitTemporaryIconMappingTable() { 577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Delete the old icon_mapping table. 578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!db_.Execute("DROP TABLE icon_mapping")) 579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 580ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 581ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Rename the temporary one. 582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!db_.Execute("ALTER TABLE temp_icon_mapping RENAME TO icon_mapping")) 583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The renamed table needs the index (the temporary table doesn't have one). 586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen InitIconMappingIndex(); 587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenFaviconID ThumbnailDatabase::CopyToTemporaryFaviconTable(FaviconID source) { 592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "INSERT INTO temp_favicons (url, last_updated, image_data, icon_type)" 594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "SELECT url, last_updated, image_data, icon_type " 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "FROM favicons WHERE id = ?")); 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, source); 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Run()) 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We return the ID of the newly inserted favicon. 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return db_.GetLastInsertRowId(); 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::CommitTemporaryFaviconTable() { 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Delete the old favicons table. 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.Execute("DROP TABLE favicons")) 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Rename the temporary one. 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.Execute("ALTER TABLE temp_favicons RENAME TO favicons")) 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The renamed table needs the index (the temporary table doesn't have one). 616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen InitFaviconsIndex(); 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::NeedsMigrationToTopSites() { 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return !use_top_sites_; 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::RenameAndDropThumbnails(const FilePath& old_db_file, 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FilePath& new_db_file) { 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Init favicons table - same schema as the thumbnails. 627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Connection favicons; 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (OpenDatabase(&favicons, new_db_file) != sql::INIT_OK) 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!InitFaviconsTable(&favicons, false) || 632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !InitIconMappingTable(&favicons, false)) { 633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED() << "Couldn't init favicons and icon-mapping table."; 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch favicons.Close(); 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch favicons.Close(); 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Can't attach within a transaction. 6403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (transaction_nesting()) 6413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CommitTransaction(); 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Attach new DB. 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This block is needed because otherwise the attach statement is 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // never cleared from cache and we can't close the DB :P 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement attach(db_.GetUniqueStatement("ATTACH ? AS new_favicons")); 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!attach) { 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Unable to attach database."; 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Keep the transaction open, even though we failed. 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BeginTransaction(); 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_POSIX) 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch attach.BindString(0, new_db_file.value()); 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch attach.BindString(0, WideToUTF8(new_db_file.value())); 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!attach.Run()) { 662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << db_.GetErrorMessage(); 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BeginTransaction(); 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Move favicons to the new DB. 669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.Execute("INSERT OR REPLACE INTO new_favicons.favicons " 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT * FROM favicons")) { 671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Unable to copy favicons."; 672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BeginTransaction(); 673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.Execute("DETACH new_favicons")) { 677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Unable to detach database."; 678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BeginTransaction(); 679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.Close(); 683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reset the DB to point to new file. 685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (OpenDatabase(&db_, new_db_file) != sql::INIT_OK) 686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch file_util::Delete(old_db_file, false); 689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 690ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen InitFaviconsIndex(); 691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reopen the transaction. 693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BeginTransaction(); 694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch use_top_sites_ = true; 695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 698ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::InitIconMappingTable(sql::Connection* db, 699ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool is_temporary) { 700ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const char* name = is_temporary ? "temp_icon_mapping" : "icon_mapping"; 701ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!db->DoesTableExist(name)) { 702ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string sql; 703ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql.append("CREATE TABLE "); 704ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql.append(name); 705ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql.append("(" 706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "id INTEGER PRIMARY KEY," 707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "page_url LONGVARCHAR NOT NULL," 708ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "icon_id INTEGER)"); 709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!db->Execute(sql.c_str())) 710ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 714ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 715ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThumbnailDatabase::InitIconMappingIndex() { 716ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Add an index on the url column. We ignore errors. Since this is always 717ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // called during startup, the index will normally already exist. 718ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen db_.Execute("CREATE INDEX icon_mapping_page_url_idx" 719ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen " ON icon_mapping(page_url)"); 720ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen db_.Execute("CREATE INDEX icon_mapping_icon_id_idx ON icon_mapping(icon_id)"); 721ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 722ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 723ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenIconMappingID ThumbnailDatabase::AddIconMapping(const GURL& page_url, 724ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FaviconID icon_id, 725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool is_temporary) { 726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const char* name = is_temporary ? "temp_icon_mapping" : "icon_mapping"; 727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const char* statement_name = 728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen is_temporary ? "add_temp_icon_mapping" : "add_icon_mapping"; 729ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 730ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string sql; 731ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql.append("INSERT INTO "); 732ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql.append(name); 733ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql.append("(page_url, icon_id) VALUES (?, ?)"); 734ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 735ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql::Statement statement( 736ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen db_.GetCachedStatement(sql::StatementID(statement_name), sql.c_str())); 737ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!statement) 738ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return 0; 739ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 740ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen statement.BindString(0, URLDatabase::GURLToDatabaseURL(page_url)); 741ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen statement.BindInt64(1, icon_id); 742ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 743ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!statement.Run()) 744ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return 0; 745ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 746ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return db_.GetLastInsertRowId(); 747ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 748ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 749ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThumbnailDatabase::UpgradeToVersion4() { 750ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Set the default icon type as favicon, so the current data are set 751ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // correctly. 752ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!db_.Execute("ALTER TABLE favicons ADD icon_type INTEGER DEFAULT 1")) { 753ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 754ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 755ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 756ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen meta_table_.SetVersionNumber(4); 757ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen meta_table_.SetCompatibleVersionNumber(std::min(4, kCompatibleVersionNumber)); 758ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 759ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 760ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace history 762