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 5513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "app/sql/connection.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/sql/transaction.h" 7513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/file_util.h" 84a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/string_split.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/diagnostics/sqlite_diagnostics.h" 113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/history/history_types.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/top_sites.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/top_sites_database.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace history { 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstatic const int kVersionNumber = 1; 18513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 19513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTopSitesDatabase::TopSitesDatabase() : may_need_history_migration_(false) { 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTopSitesDatabase::~TopSitesDatabase() { 233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 25513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool TopSitesDatabase::Init(const FilePath& db_name) { 26513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool file_existed = file_util::PathExists(db_name); 27513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 28513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!file_existed) 29513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch may_need_history_migration_ = true; 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch db_.reset(CreateDB(db_name)); 32513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!db_.get()) 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 34513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 35513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool does_meta_exist = sql::MetaTable::DoesTableExist(db_.get()); 36513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!does_meta_exist && file_existed) { 37513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch may_need_history_migration_ = true; 38513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 39513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // If the meta file doesn't exist, this version is old. We could remove all 40513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // the entries as they are no longer applicable, but it's safest to just 41513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // remove the file and start over. 42513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch db_.reset(NULL); 43513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!file_util::Delete(db_name, false) && 44513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch !file_util::Delete(db_name, false)) { 45513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Try to delete twice. If we can't, fail. 46513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(ERROR) << "unable to delete old TopSites file"; 47513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 48513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 49513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch db_.reset(CreateDB(db_name)); 50513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!db_.get()) 51513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 54513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!meta_table_.Init(db_.get(), kVersionNumber, kVersionNumber)) 55513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 56513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 57513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!InitThumbnailTable()) 58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 59513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 60513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Version check. 61513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (meta_table_.GetVersionNumber() != kVersionNumber) 62513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 64513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return true; 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool TopSitesDatabase::InitThumbnailTable() { 68513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!db_->DoesTableExist("thumbnails")) { 69513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!db_->Execute("CREATE TABLE thumbnails (" 70513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "url LONGVARCHAR PRIMARY KEY," 71513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "url_rank INTEGER ," 72513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "title LONGVARCHAR," 73513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "thumbnail BLOB," 74513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "redirects LONGVARCHAR," 75513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "boring_score DOUBLE DEFAULT 1.0, " 76513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "good_clipping INTEGER DEFAULT 0, " 77513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "at_top INTEGER DEFAULT 0, " 78513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "last_updated INTEGER DEFAULT 0) ")) { 79513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(WARNING) << db_->GetErrorMessage(); 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSitesDatabase::GetPageThumbnails(MostVisitedURLList* urls, 87513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch URLToImagesMap* thumbnails) { 88513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch sql::Statement statement(db_->GetCachedStatement( 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SQL_FROM_HERE, 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT url, url_rank, title, thumbnail, redirects, " 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "boring_score, good_clipping, at_top, last_updated " 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "FROM thumbnails ORDER BY url_rank ")); 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) { 95513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(WARNING) << db_->GetErrorMessage(); 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch urls->clear(); 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thumbnails->clear(); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (statement.Step()) { 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Results are sorted by url_rank. 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MostVisitedURL url; 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL gurl(statement.ColumnString(0)); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url.url = gurl; 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url.title = statement.ColumnString16(2); 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string redirects = statement.ColumnString(4); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetRedirects(redirects, &url); 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch urls->push_back(url); 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<unsigned char> data; 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.ColumnBlobAsVector(3, &data); 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Images thumbnail; 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thumbnail.thumbnail = RefCountedBytes::TakeVector(&data); 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thumbnail.thumbnail_score.boring_score = statement.ColumnDouble(5); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thumbnail.thumbnail_score.good_clipping = statement.ColumnBool(6); 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thumbnail.thumbnail_score.at_top = statement.ColumnBool(7); 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thumbnail.thumbnail_score.time_at_snapshot = 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time::FromInternalValue(statement.ColumnInt64(8)); 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*thumbnails)[gurl] = thumbnail; 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 127513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstd::string TopSitesDatabase::GetRedirects(const MostVisitedURL& url) { 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string> redirects; 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < url.redirects.size(); i++) 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch redirects.push_back(url.redirects[i].spec()); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return JoinString(redirects, ' '); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 135513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSitesDatabase::SetRedirects(const std::string& redirects, 136513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MostVisitedURL* url) { 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string> redirects_vector; 1384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch base::SplitStringAlongWhitespace(redirects, &redirects_vector); 1394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch for (size_t i = 0; i < redirects_vector.size(); ++i) 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url->redirects.push_back(GURL(redirects_vector[i])); 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 143513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSitesDatabase::SetPageThumbnail(const MostVisitedURL& url, 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int new_rank, 1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const Images& thumbnail) { 146513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch sql::Transaction transaction(db_.get()); 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch transaction.Begin(); 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rank = GetURLRank(url); 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rank == -1) { 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddPageThumbnail(url, new_rank, thumbnail); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdatePageRankNoTransaction(url, new_rank); 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdatePageThumbnail(url, thumbnail); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch transaction.Commit(); 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 160513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSitesDatabase::UpdatePageThumbnail( 1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const MostVisitedURL& url, const Images& thumbnail) { 162513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch sql::Statement statement(db_->GetCachedStatement( 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SQL_FROM_HERE, 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "UPDATE thumbnails SET " 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "title = ?, thumbnail = ?, redirects = ?, " 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "boring_score = ?, good_clipping = ?, at_top = ?, last_updated = ? " 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "WHERE url = ? ")); 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindString16(0, url.title); 172513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (thumbnail.thumbnail.get() && thumbnail.thumbnail->front()) { 173513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch statement.BindBlob(1, thumbnail.thumbnail->front(), 174513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch static_cast<int>(thumbnail.thumbnail->size())); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindString(2, GetRedirects(url)); 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ThumbnailScore& score = thumbnail.thumbnail_score; 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindDouble(3, score.boring_score); 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindBool(4, score.good_clipping); 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindBool(5, score.at_top); 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(6, score.time_at_snapshot.ToInternalValue()); 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindString(7, url.url.spec()); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Run()) 184513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NOTREACHED() << db_->GetErrorMessage(); 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 187513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSitesDatabase::AddPageThumbnail(const MostVisitedURL& url, 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int new_rank, 1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const Images& thumbnail) { 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int count = GetRowCount(); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 192513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch sql::Statement statement(db_->GetCachedStatement( 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SQL_FROM_HERE, 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "INSERT OR REPLACE INTO thumbnails " 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "(url, url_rank, title, thumbnail, redirects, " 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "boring_score, good_clipping, at_top, last_updated) " 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindString(0, url.url.spec()); 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt(1, count); // Make it the last url. 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindString16(2, url.title); 204513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (thumbnail.thumbnail.get() && thumbnail.thumbnail->front()) { 205513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch statement.BindBlob(3, thumbnail.thumbnail->front(), 206513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch static_cast<int>(thumbnail.thumbnail->size())); 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindString(4, GetRedirects(url)); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ThumbnailScore& score = thumbnail.thumbnail_score; 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindDouble(5, score.boring_score); 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindBool(6, score.good_clipping); 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindBool(7, score.at_top); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindInt64(8, score.time_at_snapshot.ToInternalValue()); 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Run()) 215513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NOTREACHED() << db_->GetErrorMessage(); 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdatePageRankNoTransaction(url, new_rank); 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 220513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSitesDatabase::UpdatePageRank(const MostVisitedURL& url, 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int new_rank) { 222513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch sql::Transaction transaction(db_.get()); 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch transaction.Begin(); 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdatePageRankNoTransaction(url, new_rank); 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch transaction.Commit(); 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Caller should have a transaction open. 229513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSitesDatabase::UpdatePageRankNoTransaction( 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const MostVisitedURL& url, int new_rank) { 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int prev_rank = GetURLRank(url); 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (prev_rank == -1) { 2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(WARNING) << "Updating rank of an unknown URL: " << url.url.spec(); 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Shift the ranks. 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (prev_rank > new_rank) { 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Shift up 240513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch sql::Statement shift_statement(db_->GetCachedStatement( 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SQL_FROM_HERE, 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "UPDATE thumbnails " 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SET url_rank = url_rank + 1 " 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "WHERE url_rank >= ? AND url_rank < ?")); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch shift_statement.BindInt(0, new_rank); 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch shift_statement.BindInt(1, prev_rank); 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (shift_statement) 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch shift_statement.Run(); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (prev_rank < new_rank) { 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Shift down 251513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch sql::Statement shift_statement(db_->GetCachedStatement( 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SQL_FROM_HERE, 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "UPDATE thumbnails " 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SET url_rank = url_rank - 1 " 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "WHERE url_rank > ? AND url_rank <= ?")); 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch shift_statement.BindInt(0, prev_rank); 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch shift_statement.BindInt(1, new_rank); 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (shift_statement) 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch shift_statement.Run(); 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the url's rank. 263513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch sql::Statement set_statement(db_->GetCachedStatement( 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SQL_FROM_HERE, 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "UPDATE thumbnails " 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SET url_rank = ? " 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "WHERE url == ?")); 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch set_statement.BindInt(0, new_rank); 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch set_statement.BindString(1, url.url.spec()); 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (set_statement) 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch set_statement.Run(); 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 274513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool TopSitesDatabase::GetPageThumbnail(const GURL& url, 2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Images* thumbnail) { 276513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch sql::Statement statement(db_->GetCachedStatement( 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SQL_FROM_HERE, 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT thumbnail, boring_score, good_clipping, at_top, last_updated " 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "FROM thumbnails WHERE url=?")); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement) { 282513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(WARNING) << db_->GetErrorMessage(); 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.BindString(0, url.spec()); 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!statement.Step()) 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<unsigned char> data; 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch statement.ColumnBlobAsVector(0, &data); 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thumbnail->thumbnail = RefCountedBytes::TakeVector(&data); 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thumbnail->thumbnail_score.boring_score = statement.ColumnDouble(1); 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thumbnail->thumbnail_score.good_clipping = statement.ColumnBool(2); 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thumbnail->thumbnail_score.at_top = statement.ColumnBool(3); 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thumbnail->thumbnail_score.time_at_snapshot = 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time::FromInternalValue(statement.ColumnInt64(4)); 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 301513209b27ff55e2841eac0e4120199c23acce758Ben Murdochint TopSitesDatabase::GetRowCount() { 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int result = 0; 303513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch sql::Statement select_statement(db_->GetCachedStatement( 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SQL_FROM_HERE, 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT COUNT (url) FROM thumbnails")); 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!select_statement) { 307513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(WARNING) << db_->GetErrorMessage(); 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result; 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (select_statement.Step()) 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result = select_statement.ColumnInt(0); 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result; 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 317513209b27ff55e2841eac0e4120199c23acce758Ben Murdochint TopSitesDatabase::GetURLRank(const MostVisitedURL& url) { 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int result = -1; 319513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch sql::Statement select_statement(db_->GetCachedStatement( 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SQL_FROM_HERE, 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SELECT url_rank " 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "FROM thumbnails WHERE url=?")); 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!select_statement) { 324513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(WARNING) << db_->GetErrorMessage(); 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result; 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch select_statement.BindString(0, url.url.spec()); 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (select_statement.Step()) 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result = select_statement.ColumnInt(0); 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result; 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Remove the record for this URL. Returns true iff removed successfully. 336513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool TopSitesDatabase::RemoveURL(const MostVisitedURL& url) { 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int old_rank = GetURLRank(url); 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (old_rank < 0) 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 341513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch sql::Transaction transaction(db_.get()); 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch transaction.Begin(); 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Decrement all following ranks. 344513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch sql::Statement shift_statement(db_->GetCachedStatement( 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SQL_FROM_HERE, 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "UPDATE thumbnails " 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "SET url_rank = url_rank - 1 " 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "WHERE url_rank > ?")); 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!shift_statement) 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch shift_statement.BindInt(0, old_rank); 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch shift_statement.Run(); 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sql::Statement delete_statement( 355513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch db_->GetCachedStatement(SQL_FROM_HERE, 356513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "DELETE FROM thumbnails WHERE url = ?")); 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!delete_statement) 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete_statement.BindString(0, url.url.spec()); 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete_statement.Run(); 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return transaction.Commit(); 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 365513209b27ff55e2841eac0e4120199c23acce758Ben Murdochsql::Connection* TopSitesDatabase::CreateDB(const FilePath& db_name) { 366513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<sql::Connection> db(new sql::Connection()); 367513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Settings copied from ThumbnailDatabase. 368513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch db->set_error_delegate(GetErrorHandlerForThumbnailDb()); 369513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch db->set_page_size(4096); 370513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch db->set_cache_size(32); 371513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 372513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!db->Open(db_name)) { 373513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(ERROR) << db->GetErrorMessage(); 374513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return NULL; 375513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 376513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 377513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return db.release(); 378513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 379513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace history 381