| Index: chrome/browser/history/thumbnail_database.cc
|
| diff --git a/chrome/browser/history/thumbnail_database.cc b/chrome/browser/history/thumbnail_database.cc
|
| index d9462ada00ae4b5b1ce8bef8a5a18c56d1f07aeb..6ce585a72d7ebb90f0380d7e698197ad2ed9d6f5 100644
|
| --- a/chrome/browser/history/thumbnail_database.cc
|
| +++ b/chrome/browser/history/thumbnail_database.cc
|
| @@ -10,6 +10,8 @@
|
| #include "base/command_line.h"
|
| #include "base/file_util.h"
|
| #include "base/memory/ref_counted_memory.h"
|
| +#include "base/string_number_conversions.h"
|
| +#include "base/string_tokenizer.h"
|
| #include "base/string_util.h"
|
| #include "base/time.h"
|
| #include "base/utf_string_conversions.h"
|
| @@ -71,8 +73,6 @@
|
| // width Pixel width of |image_data|.
|
| // height Pixel height of |image_data|.
|
|
|
| -
|
| -
|
| static void FillIconMapping(const sql::Statement& statement,
|
| const GURL& page_url,
|
| history::IconMapping* icon_mapping) {
|
| @@ -80,6 +80,7 @@ static void FillIconMapping(const sql::Statement& statement,
|
| icon_mapping->icon_id = statement.ColumnInt64(1);
|
| icon_mapping->icon_type =
|
| static_cast<history::IconType>(statement.ColumnInt(2));
|
| + icon_mapping->icon_url = GURL(statement.ColumnString(3));
|
| icon_mapping->page_url = page_url;
|
| }
|
|
|
| @@ -103,7 +104,7 @@ bool ThumbnailDatabase::IconMappingEnumerator::GetNextIconMapping(
|
| IconMapping* icon_mapping) {
|
| if (!statement_.Step())
|
| return false;
|
| - FillIconMapping(statement_, GURL(statement_.ColumnString(3)), icon_mapping);
|
| + FillIconMapping(statement_, GURL(statement_.ColumnString(4)), icon_mapping);
|
| return true;
|
| }
|
|
|
| @@ -447,6 +448,26 @@ bool ThumbnailDatabase::ThumbnailScoreForId(URLID id,
|
| return true;
|
| }
|
|
|
| +bool ThumbnailDatabase::GetFaviconBitmapIDSizeList(
|
| + FaviconID icon_id,
|
| + std::vector<FaviconBitmapIDSize>* bitmap_id_size_list) {
|
| + DCHECK(icon_id);
|
| + sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
|
| + "SELECT id, width, height FROM favicon_bitmaps WHERE icon_id=?"));
|
| + statement.BindInt64(0, icon_id);
|
| +
|
| + bool result = false;
|
| + while (statement.Step()) {
|
| + result = true;
|
| + FaviconBitmapIDSize bitmap_id_size;
|
| + bitmap_id_size.bitmap_id = statement.ColumnInt(0);
|
| + bitmap_id_size.pixel_size = gfx::Size(statement.ColumnInt(1),
|
| + statement.ColumnInt(2));
|
| + bitmap_id_size_list->push_back(bitmap_id_size);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| bool ThumbnailDatabase::GetFaviconBitmaps(
|
| FaviconID icon_id,
|
| std::vector<FaviconBitmap>* favicon_bitmaps) {
|
| @@ -479,6 +500,36 @@ bool ThumbnailDatabase::GetFaviconBitmaps(
|
| return result;
|
| }
|
|
|
| +bool ThumbnailDatabase::GetFaviconBitmap(
|
| + FaviconBitmapID bitmap_id,
|
| + base::Time* last_updated,
|
| + scoped_refptr<base::RefCountedMemory>* png_icon_data,
|
| + gfx::Size* pixel_size) {
|
| + DCHECK(bitmap_id);
|
| + sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
|
| + "SELECT last_updated, image_data, width, height FROM favicon_bitmaps "
|
| + "WHERE id=?"));
|
| + statement.BindInt64(0, bitmap_id);
|
| +
|
| + if (!statement.Step())
|
| + return false;
|
| +
|
| + if (last_updated)
|
| + *last_updated = base::Time::FromTimeT(statement.ColumnInt64(0));
|
| +
|
| + if (png_icon_data && statement.ColumnByteLength(1) > 0) {
|
| + scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes());
|
| + statement.ColumnBlobAsVector(2, &data->data());
|
| + *png_icon_data = data;
|
| + }
|
| +
|
| + if (pixel_size) {
|
| + *pixel_size = gfx::Size(statement.ColumnInt(2),
|
| + statement.ColumnInt(3));
|
| + }
|
| + return true;
|
| +}
|
| +
|
| FaviconBitmapID ThumbnailDatabase::AddFaviconBitmap(
|
| FaviconID icon_id,
|
| const scoped_refptr<base::RefCountedMemory>& icon_data,
|
| @@ -504,18 +555,40 @@ FaviconBitmapID ThumbnailDatabase::AddFaviconBitmap(
|
| return db_.GetLastInsertRowId();
|
| }
|
|
|
| -bool ThumbnailDatabase::DeleteFaviconBitmapsForFavicon(FaviconID icon_id) {
|
| +bool ThumbnailDatabase::SetFaviconBitmap(
|
| + FaviconBitmapID bitmap_id,
|
| + scoped_refptr<base::RefCountedMemory> icon_data,
|
| + base::Time time) {
|
| + DCHECK(bitmap_id);
|
| + sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
|
| + "UPDATE favicon_bitmaps SET image_data=?, last_updated=? WHERE id=?"));
|
| + if (icon_data.get() && icon_data->size()) {
|
| + statement.BindBlob(0, icon_data->front(),
|
| + static_cast<int>(icon_data->size()));
|
| + } else {
|
| + statement.BindNull(0);
|
| + }
|
| + statement.BindInt64(1, time.ToTimeT());
|
| + statement.BindInt64(2, bitmap_id);
|
| +
|
| + return statement.Run();
|
| +}
|
| +
|
| +bool ThumbnailDatabase::DeleteFaviconBitmap(FaviconBitmapID bitmap_id) {
|
| sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
|
| - "DELETE FROM favicon_bitmaps WHERE icon_id=?"));
|
| - statement.BindInt64(0, icon_id);
|
| + "DELETE FROM favicon_bitmaps WHERE id=?"));
|
| + statement.BindInt64(0, bitmap_id);
|
| return statement.Run();
|
| }
|
|
|
| bool ThumbnailDatabase::SetFaviconSizes(FaviconID icon_id,
|
| - const std::string& sizes) {
|
| + const std::vector<gfx::Size>& sizes) {
|
| + std::string sizes_as_string;
|
| + FaviconSizesToDatabaseString(sizes, &sizes_as_string);
|
| +
|
| sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
|
| "UPDATE favicons SET sizes=? WHERE id=?"));
|
| - statement.BindString(0, sizes);
|
| + statement.BindString(0, sizes_as_string);
|
| statement.BindInt64(1, icon_id);
|
|
|
| return statement.Run();
|
| @@ -531,50 +604,23 @@ bool ThumbnailDatabase::SetFaviconOutOfDate(FaviconID icon_id) {
|
| }
|
|
|
| FaviconID ThumbnailDatabase::GetFaviconIDForFaviconURL(const GURL& icon_url,
|
| - int required_icon_type,
|
| - IconType* icon_type) {
|
| + int required_icon_type) {
|
| sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
|
| - "SELECT id, icon_type FROM favicons WHERE url=? AND (icon_type & ? > 0) "
|
| + "SELECT id FROM favicons WHERE url=? AND (icon_type & ? > 0) "
|
| "ORDER BY icon_type DESC"));
|
| statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url));
|
| statement.BindInt(1, required_icon_type);
|
|
|
| if (!statement.Step())
|
| return 0; // not cached
|
| -
|
| - if (icon_type)
|
| - *icon_type = static_cast<IconType>(statement.ColumnInt(1));
|
| return statement.ColumnInt64(0);
|
| }
|
|
|
| -bool ThumbnailDatabase::GetFavicon(
|
| - FaviconID icon_id,
|
| - base::Time* last_updated,
|
| - scoped_refptr<base::RefCountedMemory>* png_icon_data,
|
| - GURL* icon_url,
|
| - IconType* icon_type) {
|
| - DCHECK(icon_id);
|
| -
|
| - std::vector<FaviconBitmap> favicon_bitmaps;
|
| - if (!GetFaviconBitmaps(icon_id, &favicon_bitmaps))
|
| - return false;
|
| -
|
| - if (favicon_bitmaps.empty())
|
| - return false;
|
| -
|
| - if (last_updated)
|
| - *last_updated = favicon_bitmaps[0].last_updated;
|
| -
|
| - *png_icon_data = favicon_bitmaps[0].bitmap_data;
|
| -
|
| - return GetFaviconHeader(icon_id, icon_url, icon_type, NULL);
|
| -}
|
| -
|
| bool ThumbnailDatabase::GetFaviconHeader(
|
| FaviconID icon_id,
|
| GURL* icon_url,
|
| IconType* icon_type,
|
| - std::string* sizes) {
|
| + std::vector<gfx::Size>* sizes) {
|
| DCHECK(icon_id);
|
|
|
| sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
|
| @@ -588,8 +634,10 @@ bool ThumbnailDatabase::GetFaviconHeader(
|
| *icon_url = GURL(statement.ColumnString(0));
|
| if (icon_type)
|
| *icon_type = static_cast<history::IconType>(statement.ColumnInt(1));
|
| - if (sizes)
|
| - *sizes = statement.ColumnString(2);
|
| + if (sizes) {
|
| + if (!DatabaseStringToFaviconSizes(statement.ColumnString(2), sizes))
|
| + return false;
|
| + }
|
|
|
| return true;
|
| }
|
| @@ -610,7 +658,7 @@ FaviconID ThumbnailDatabase::AddFavicon(const GURL& icon_url,
|
| FaviconID ThumbnailDatabase::AddFavicon(
|
| const GURL& icon_url,
|
| IconType icon_type,
|
| - const std::string& sizes,
|
| + const std::vector<gfx::Size>& sizes,
|
| const scoped_refptr<base::RefCountedMemory>& icon_data,
|
| base::Time time,
|
| const gfx::Size& pixel_size) {
|
| @@ -637,30 +685,33 @@ bool ThumbnailDatabase::DeleteFavicon(FaviconID id) {
|
| return statement.Run();
|
| }
|
|
|
| -bool ThumbnailDatabase::GetIconMappingForPageURL(const GURL& page_url,
|
| - IconType required_icon_type,
|
| - IconMapping* icon_mapping) {
|
| - std::vector<IconMapping> icon_mappings;
|
| - if (!GetIconMappingsForPageURL(page_url, &icon_mappings))
|
| +bool ThumbnailDatabase::GetIconMappingsForPageURL(
|
| + const GURL& page_url,
|
| + int required_icon_types,
|
| + std::vector<IconMapping>* filtered_mapping_data) {
|
| + std::vector<IconMapping> mapping_data;
|
| + if (!GetIconMappingsForPageURL(page_url, &mapping_data))
|
| return false;
|
|
|
| - for (std::vector<IconMapping>::iterator m = icon_mappings.begin();
|
| - m != icon_mappings.end(); ++m) {
|
| - if (m->icon_type == required_icon_type) {
|
| - if (icon_mapping != NULL)
|
| - *icon_mapping = *m;
|
| - return true;
|
| + bool result = false;
|
| + for (std::vector<IconMapping>::iterator m = mapping_data.begin();
|
| + m != mapping_data.end(); ++m) {
|
| + if (m->icon_type & required_icon_types) {
|
| + result = true;
|
| + if (filtered_mapping_data == NULL)
|
| + return result;
|
| + filtered_mapping_data->push_back(*m);
|
| }
|
| }
|
| -
|
| - return false;
|
| + return result;
|
| }
|
|
|
| bool ThumbnailDatabase::GetIconMappingsForPageURL(
|
| const GURL& page_url,
|
| std::vector<IconMapping>* mapping_data) {
|
| sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
|
| - "SELECT icon_mapping.id, icon_mapping.icon_id, favicons.icon_type "
|
| + "SELECT icon_mapping.id, icon_mapping.icon_id, favicons.icon_type, "
|
| + "favicons.url "
|
| "FROM icon_mapping "
|
| "INNER JOIN favicons "
|
| "ON icon_mapping.icon_id = favicons.id "
|
| @@ -704,6 +755,14 @@ bool ThumbnailDatabase::DeleteIconMappings(const GURL& page_url) {
|
| return statement.Run();
|
| }
|
|
|
| +bool ThumbnailDatabase::DeleteIconMapping(IconMappingID mapping_id) {
|
| + sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
|
| + "DELETE FROM icon_mapping WHERE id=?"));
|
| + statement.BindInt64(0, mapping_id);
|
| +
|
| + return statement.Run();
|
| +}
|
| +
|
| bool ThumbnailDatabase::HasMappingFor(FaviconID id) {
|
| sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
|
| "SELECT id FROM icon_mapping "
|
| @@ -713,8 +772,8 @@ bool ThumbnailDatabase::HasMappingFor(FaviconID id) {
|
| return statement.Step();
|
| }
|
|
|
| -bool ThumbnailDatabase::CloneIconMapping(const GURL& old_page_url,
|
| - const GURL& new_page_url) {
|
| +bool ThumbnailDatabase::CloneIconMappings(const GURL& old_page_url,
|
| + const GURL& new_page_url) {
|
| sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
|
| "SELECT icon_id FROM icon_mapping "
|
| "WHERE page_url=?"));
|
| @@ -743,7 +802,7 @@ bool ThumbnailDatabase::InitIconMappingEnumerator(
|
| enumerator->statement_.Assign(db_.GetCachedStatement(
|
| SQL_FROM_HERE,
|
| "SELECT icon_mapping.id, icon_mapping.icon_id, favicons.icon_type, "
|
| - "icon_mapping.page_url "
|
| + "favicons.url, icon_mapping.page_url "
|
| "FROM icon_mapping JOIN favicons ON ("
|
| "icon_mapping.icon_id = favicons.id) "
|
| "WHERE favicons.icon_type = ?"));
|
| @@ -1017,4 +1076,41 @@ bool ThumbnailDatabase::UpgradeToVersion6() {
|
| return true;
|
| }
|
|
|
| +// static
|
| +void ThumbnailDatabase::FaviconSizesToDatabaseString(
|
| + const FaviconSizes& sizes,
|
| + std::string* sizes_string) {
|
| + std::vector<std::string> parts;
|
| + for (std::vector<gfx::Size>::const_iterator it = sizes.begin();
|
| + it != sizes.end(); ++it) {
|
| + parts.push_back(base::IntToString(it->width()));
|
| + parts.push_back(base::IntToString(it->height()));
|
| + }
|
| + *sizes_string = JoinString(parts, ' ');
|
| +}
|
| +
|
| +// static
|
| +bool ThumbnailDatabase::DatabaseStringToFaviconSizes(
|
| + const std::string sizes_string,
|
| + FaviconSizes* sizes) {
|
| + bool no_errors = true;
|
| +
|
| + StringTokenizer t(sizes_string, " ");
|
| + while (t.GetNext() && no_errors) {
|
| + int width, height = 0;
|
| + no_errors &= base::StringToInt(t.token(), &width);
|
| + if (!t.GetNext()) {
|
| + no_errors = false;
|
| + break;
|
| + }
|
| + no_errors &= base::StringToInt(t.token(), &height);
|
| + sizes->push_back(gfx::Size(width, height));
|
| + }
|
| +
|
| + if (!no_errors)
|
| + sizes->clear();
|
| +
|
| + return no_errors;
|
| +}
|
| +
|
| } // namespace history
|
|
|