15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/webdata/web_apps_table.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_database.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/webdata/common/web_database.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/statement.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/codec/png_codec.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebDatabaseTable::TypeKey GetKey() { 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We just need a unique constant. Use the address of a static that 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // COMDAT folding won't touch in an optimizing linker. 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static int table_key = 0; 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return reinterpret_cast<void*>(&table_key); 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebAppsTable* WebAppsTable::FromWebDatabase(WebDatabase* db) { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return static_cast<WebAppsTable*>(db->GetTable(GetKey())); 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebDatabaseTable::TypeKey WebAppsTable::GetTypeKey() const { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetKey(); 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool WebAppsTable::CreateTablesIfNecessary() { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (InitWebAppIconsTable() && InitWebAppsTable()); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebAppsTable::IsSyncable() { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WebAppsTable::MigrateToVersion(int version, 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* update_compatible_version) { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebAppsTable::InitWebAppIconsTable() { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->DoesTableExist("web_app_icons")) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->Execute("CREATE TABLE web_app_icons (" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "url LONGVARCHAR," 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "width int," 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "height int," 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "image BLOB, UNIQUE (url, width, height))")) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebAppsTable::InitWebAppsTable() { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->DoesTableExist("web_apps")) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->Execute("CREATE TABLE web_apps (" 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "url LONGVARCHAR UNIQUE," 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "has_all_images INTEGER NOT NULL)")) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->Execute("CREATE INDEX web_apps_url_index ON web_apps (url)")) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebAppsTable::SetWebAppImage(const GURL& url, const SkBitmap& image) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't bother with a cached statement since this will be a relatively 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // infrequent operation. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement s(db_->GetUniqueStatement( 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "INSERT OR REPLACE INTO web_app_icons " 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "(url, width, height, image) VALUES (?, ?, ?, ?)")); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<unsigned char> image_data; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::PNGCodec::EncodeBGRASkBitmap(image, false, &image_data); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url)); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindInt(1, image.width()); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindInt(2, image.height()); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindBlob(3, &image_data.front(), static_cast<int>(image_data.size())); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s.Run(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebAppsTable::GetWebAppImages(const GURL& url, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SkBitmap>* images) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement s(db_->GetUniqueStatement( 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SELECT image FROM web_app_icons WHERE url=?")); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url)); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (s.Step()) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap image; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int col_bytes = s.ColumnByteLength(0); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (col_bytes > 0) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gfx::PNGCodec::Decode( 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const unsigned char*>(s.ColumnBlob(0)), 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) col_bytes, &image)) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) images->push_back(image); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should only have valid image data in the db. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s.Succeeded(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebAppsTable::SetWebAppHasAllImages(const GURL& url, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_all_images) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement s(db_->GetUniqueStatement( 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "INSERT OR REPLACE INTO web_apps (url, has_all_images) VALUES (?, ?)")); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url)); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindInt(1, has_all_images ? 1 : 0); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s.Run(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebAppsTable::GetWebAppHasAllImages(const GURL& url) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement s(db_->GetUniqueStatement( 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SELECT has_all_images FROM web_apps WHERE url=?")); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url)); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (s.Step() && s.ColumnInt(0) == 1); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebAppsTable::RemoveWebApp(const GURL& url) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement delete_s(db_->GetUniqueStatement( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "DELETE FROM web_app_icons WHERE url = ?")); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete_s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url)); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!delete_s.Run()) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement delete_s2(db_->GetUniqueStatement( 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "DELETE FROM web_apps WHERE url = ?")); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete_s2.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url)); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return delete_s2.Run(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 148