thumbnail_database.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2009 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" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/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 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace history { 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Version number of the database. 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kCurrentVersionNumber = 3; 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kCompatibleVersionNumber = 3; 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochThumbnailDatabase::ThumbnailDatabase() : history_publisher_(NULL), 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch use_top_sites_(false) { 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochThumbnailDatabase::~ThumbnailDatabase() { 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The DBCloseScoper will delete the DB and the cache. 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochsql::InitStatus ThumbnailDatabase::Init( 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FilePath& db_name, 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HistoryPublisher* history_publisher) { 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history_publisher_ = history_publisher; 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::InitStatus status = OpenDatabase(&db_, db_name); 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (status != sql::INIT_OK) 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return status; 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Scope initialization in a transaction so we can't be partially initialized. 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Transaction transaction(&db_); 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch transaction.Begin(); 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX) 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Exclude the thumbnails file and its journal from backups. 583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::mac::SetFileBackupExclusion(db_name, true); 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath::StringType db_name_string(db_name.value()); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_name_string += "-journal"; 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath db_journal_name(db_name_string); 623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::mac::SetFileBackupExclusion(db_journal_name, true); 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create the tables. 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!meta_table_.Init(&db_, kCurrentVersionNumber, 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kCompatibleVersionNumber) || 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !InitThumbnailTable() || 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !InitFavIconsTable(&db_, false)) { 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.Close(); 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_FAILURE; 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InitFavIconsIndex(); 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Version check. We should not encounter a database too old for us to handle 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // in the wild, so we try to continue in that case. 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Thumbnail database is too new."; 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_TOO_NEW; 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int cur_version = meta_table_.GetVersionNumber(); 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cur_version == 2) { 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!UpgradeToVersion3()) { 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Unable to update to thumbnail database to version 3."; 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.Close(); 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_FAILURE; 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++cur_version; 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG_IF(WARNING, cur_version < kCurrentVersionNumber) << 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Thumbnail database version " << cur_version << " is too old to handle."; 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Initialization is complete. 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!transaction.Commit()) { 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.Close(); 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_FAILURE; 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_OK; 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochsql::InitStatus ThumbnailDatabase::OpenDatabase(sql::Connection* db, 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FilePath& db_name) { 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the exceptional sqlite error handler. 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db->set_error_delegate(GetErrorHandlerForThumbnailDb()); 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 109513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Thumbnails db now only stores favicons, so we don't need that big a page 110513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // size or cache. 111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch db->set_page_size(2048); 112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch db->set_cache_size(32); 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Run the database in exclusive mode. Nobody else should be accessing the 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // database while we're running, and this will give somewhat improved perf. 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db->set_exclusive_locking(); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db->Open(db_name)) 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_FAILURE; 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sql::INIT_OK; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::InitThumbnailTable() { 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.DoesTableExist("thumbnails")) { 12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen use_top_sites_ = true; 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::UpgradeToVersion3() { 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (use_top_sites_) { 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch meta_table_.SetVersionNumber(3); 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch meta_table_.SetCompatibleVersionNumber( 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::min(3, kCompatibleVersionNumber)); 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; // Not needed after migration to TopSites. 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // sqlite doesn't like the "ALTER TABLE xxx ADD (column_one, two, 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // three)" syntax, so list out the commands we need to execute: 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* alterations[] = { 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ALTER TABLE thumbnails ADD boring_score DOUBLE DEFAULT 1.0", 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ALTER TABLE thumbnails ADD good_clipping INTEGER DEFAULT 0", 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ALTER TABLE thumbnails ADD at_top INTEGER DEFAULT 0", 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "ALTER TABLE thumbnails ADD last_updated INTEGER DEFAULT 0", 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; alterations[i] != NULL; ++i) { 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.Execute(alterations[i])) { 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch meta_table_.SetVersionNumber(3); 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch meta_table_.SetCompatibleVersionNumber(std::min(3, kCompatibleVersionNumber)); 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::RecreateThumbnailTable() { 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (use_top_sites_) 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; // Not needed after migration to TopSites. 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.Execute("DROP TABLE thumbnails")) 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return InitThumbnailTable(); 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::InitFavIconsTable(sql::Connection* db, 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_temporary) { 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note: if you update the schema, don't forget to update 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // CopyToTemporaryFaviconTable as well. 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* name = is_temporary ? "temp_favicons" : "favicons"; 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db->DoesTableExist(name)) { 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string sql; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql.append("CREATE TABLE "); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql.append(name); 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql.append("(" 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "id INTEGER PRIMARY KEY," 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "url LONGVARCHAR NOT NULL," 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "last_updated INTEGER DEFAULT 0," 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "image_data BLOB)"); 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db->Execute(sql.c_str())) 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ThumbnailDatabase::InitFavIconsIndex() { 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add an index on the url column. We ignore errors. Since this is always 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // called during startup, the index will normally already exist. 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.Execute("CREATE INDEX favicons_url ON favicons(url)"); 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ThumbnailDatabase::BeginTransaction() { 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.BeginTransaction(); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ThumbnailDatabase::CommitTransaction() { 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.CommitTransaction(); 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ThumbnailDatabase::Vacuum() { 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(db_.transaction_nesting() == 0) << 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Can not have a transaction when vacuuming."; 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.Execute("VACUUM"); 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ThumbnailDatabase::SetPageThumbnail( 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLID id, 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const SkBitmap& thumbnail, 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ThumbnailScore& score, 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time time) { 2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (use_top_sites_) { 2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(WARNING) << "Use TopSites instead."; 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; // Not possible after migration to TopSites. 2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!thumbnail.isNull()) { 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool add_thumbnail = true; 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ThumbnailScore current_score; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ThumbnailScoreForId(id, ¤t_score)) { 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch add_thumbnail = ShouldReplaceThumbnailWith(current_score, score); 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (add_thumbnail) { 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "INSERT OR REPLACE INTO thumbnails " 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "(url_id, boring_score, good_clipping, at_top, last_updated, data) " 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "VALUES (?,?,?,?,?,?)")); 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We use 90 quality (out of 100) which is pretty high, because 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we're very sensitive to artifacts for these small sized, 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // highly detailed images. 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<unsigned char> jpeg_data; 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkAutoLockPixels thumbnail_lock(thumbnail); 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool encoded = gfx::JPEGCodec::Encode( 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<unsigned char*>(thumbnail.getAddr32(0, 0)), 243731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick gfx::JPEGCodec::FORMAT_SkBitmap, thumbnail.width(), 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thumbnail.height(), 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(thumbnail.rowBytes()), 90, 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &jpeg_data); 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (encoded) { 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, id); 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindDouble(1, score.boring_score); 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindBool(2, score.good_clipping); 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindBool(3, score.at_top); 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(4, score.time_at_snapshot.ToTimeT()); 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindBlob(5, &jpeg_data[0], 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(jpeg_data.size())); 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Run()) 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << db_.GetErrorMessage(); 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Publish the thumbnail to any indexers listening to us. 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The tests may send an invalid url. Hence avoid publishing those. 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (url.is_valid() && history_publisher_ != NULL) 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history_publisher_->PublishPageThumbnail(jpeg_data, url, time); 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!DeleteThumbnail(id) ) 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DLOG(WARNING) << "Unable to delete thumbnail"; 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::GetPageThumbnail(URLID id, 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<unsigned char>* data) { 2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (use_top_sites_) { 2743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(WARNING) << "Use TopSites instead."; 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; // Not possible after migration to TopSites. 2763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT data FROM thumbnails WHERE url_id=?")); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, id); 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Step()) 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; // don't have a thumbnail for this ID 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.ColumnBlobAsVector(0, data); 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::DeleteThumbnail(URLID id) { 2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (use_top_sites_) { 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; // Not possible after migration to TopSites. 2943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "DELETE FROM thumbnails WHERE url_id = ?")); 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, id); 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return statement.Run(); 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::ThumbnailScoreForId(URLID id, 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ThumbnailScore* score) { 3073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (use_top_sites_) { 3083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(WARNING) << "Use TopSites instead."; 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; // Not possible after migration to TopSites. 3103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Fetch the current thumbnail's information to make sure we 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // aren't replacing a good thumbnail with one that's worse. 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement select_statement(db_.GetCachedStatement(SQL_FROM_HERE, 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT boring_score, good_clipping, at_top, last_updated " 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "FROM thumbnails WHERE url_id=?")); 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!select_statement) { 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Couldn't build select statement!"; 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch select_statement.BindInt64(0, id); 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (select_statement.Step()) { 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch double current_boring_score = select_statement.ColumnDouble(0); 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool current_clipping = select_statement.ColumnBool(1); 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool current_at_top = select_statement.ColumnBool(2); 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time last_updated = 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time::FromTimeT(select_statement.ColumnInt64(3)); 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *score = ThumbnailScore(current_boring_score, current_clipping, 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current_at_top, last_updated); 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::SetFavIcon(URLID icon_id, 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<RefCountedMemory> icon_data, 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time time) { 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(icon_id); 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (icon_data->size()) { 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "UPDATE favicons SET image_data=?, last_updated=? WHERE id=?")); 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindBlob(0, icon_data->front(), 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(icon_data->size())); 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(1, time.ToTimeT()); 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(2, icon_id); 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return statement.Run(); 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "UPDATE favicons SET image_data=NULL, last_updated=? WHERE id=?")); 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, time.ToTimeT()); 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(1, icon_id); 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return statement.Run(); 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::SetFavIconLastUpdateTime(FavIconID icon_id, 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time time) { 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "UPDATE favicons SET last_updated=? WHERE id=?")); 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, time.ToTimeT()); 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(1, icon_id); 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return statement.Run(); 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFavIconID ThumbnailDatabase::GetFavIconIDForFavIconURL(const GURL& icon_url) { 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT id FROM favicons WHERE url=?")); 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url)); 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Step()) 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; // not cached 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return statement.ColumnInt64(0); 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::GetFavIcon( 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FavIconID icon_id, 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time* last_updated, 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<unsigned char>* png_icon_data, 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL* icon_url) { 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(icon_id); 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT last_updated, image_data, url FROM favicons WHERE id=?")); 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, icon_id); 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Step()) 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; // No entry for the id. 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *last_updated = base::Time::FromTimeT(statement.ColumnInt64(0)); 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (statement.ColumnByteLength(1) > 0) 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.ColumnBlobAsVector(1, png_icon_data); 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (icon_url) 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *icon_url = GURL(statement.ColumnString(2)); 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFavIconID ThumbnailDatabase::AddFavIcon(const GURL& icon_url) { 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "INSERT INTO favicons (url) VALUES (?)")); 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url)); 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Run()) 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return db_.GetLastInsertRowId(); 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::DeleteFavIcon(FavIconID id) { 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "DELETE FROM favicons WHERE id = ?")); 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, id); 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return statement.Run(); 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFavIconID ThumbnailDatabase::CopyToTemporaryFavIconTable(FavIconID source) { 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "INSERT INTO temp_favicons (url, last_updated, image_data)" 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT url, last_updated, image_data " 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "FROM favicons WHERE id = ?")); 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(0, source); 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Run()) 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We return the ID of the newly inserted favicon. 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return db_.GetLastInsertRowId(); 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::CommitTemporaryFavIconTable() { 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Delete the old favicons table. 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.Execute("DROP TABLE favicons")) 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Rename the temporary one. 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.Execute("ALTER TABLE temp_favicons RENAME TO favicons")) 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The renamed table needs the index (the temporary table doesn't have one). 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InitFavIconsIndex(); 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::NeedsMigrationToTopSites() { 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return !use_top_sites_; 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ThumbnailDatabase::RenameAndDropThumbnails(const FilePath& old_db_file, 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FilePath& new_db_file) { 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Init favicons table - same schema as the thumbnails. 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Connection favicons; 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (OpenDatabase(&favicons, new_db_file) != sql::INIT_OK) 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!InitFavIconsTable(&favicons, false)) { 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Couldn't init favicons table."; 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch favicons.Close(); 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch favicons.Close(); 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Can't attach within a transaction. 4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (transaction_nesting()) 4843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CommitTransaction(); 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Attach new DB. 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This block is needed because otherwise the attach statement is 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // never cleared from cache and we can't close the DB :P 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement attach(db_.GetUniqueStatement("ATTACH ? AS new_favicons")); 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!attach) { 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Unable to attach database."; 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Keep the transaction open, even though we failed. 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BeginTransaction(); 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_POSIX) 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch attach.BindString(0, new_db_file.value()); 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch attach.BindString(0, WideToUTF8(new_db_file.value())); 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!attach.Run()) { 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << db_.GetErrorMessage(); 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BeginTransaction(); 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Move favicons to the new DB. 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.Execute("INSERT OR REPLACE INTO new_favicons.favicons " 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT * FROM favicons")) { 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Unable to copy favicons."; 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BeginTransaction(); 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db_.Execute("DETACH new_favicons")) { 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Unable to detach database."; 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BeginTransaction(); 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db_.Close(); 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reset the DB to point to new file. 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (OpenDatabase(&db_, new_db_file) != sql::INIT_OK) 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch file_util::Delete(old_db_file, false); 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InitFavIconsIndex(); 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reopen the transaction. 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BeginTransaction(); 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch use_top_sites_ = true; 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace history 542