Home | History | Annotate | Download | only in webdata
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/webdata/web_apps_table.h"
      6 
      7 #include "base/logging.h"
      8 #include "chrome/browser/history/history_database.h"
      9 #include "components/webdata/common/web_database.h"
     10 #include "sql/statement.h"
     11 #include "third_party/skia/include/core/SkBitmap.h"
     12 #include "ui/gfx/codec/png_codec.h"
     13 #include "url/gurl.h"
     14 
     15 namespace {
     16 
     17 WebDatabaseTable::TypeKey GetKey() {
     18   // We just need a unique constant. Use the address of a static that
     19   // COMDAT folding won't touch in an optimizing linker.
     20   static int table_key = 0;
     21   return reinterpret_cast<void*>(&table_key);
     22 }
     23 
     24 }  // namespace
     25 
     26 WebAppsTable* WebAppsTable::FromWebDatabase(WebDatabase* db) {
     27   return static_cast<WebAppsTable*>(db->GetTable(GetKey()));
     28 }
     29 
     30 WebDatabaseTable::TypeKey WebAppsTable::GetTypeKey() const {
     31   return GetKey();
     32 }
     33 
     34 bool WebAppsTable::Init(sql::Connection* db, sql::MetaTable* meta_table) {
     35   WebDatabaseTable::Init(db, meta_table);
     36 
     37   return (InitWebAppIconsTable() && InitWebAppsTable());
     38 }
     39 
     40 bool WebAppsTable::IsSyncable() {
     41   return true;
     42 }
     43 
     44 bool WebAppsTable::MigrateToVersion(int version,
     45                                     bool* update_compatible_version) {
     46   return true;
     47 }
     48 
     49 bool WebAppsTable::InitWebAppIconsTable() {
     50   if (!db_->DoesTableExist("web_app_icons")) {
     51     if (!db_->Execute("CREATE TABLE web_app_icons ("
     52                       "url LONGVARCHAR,"
     53                       "width int,"
     54                       "height int,"
     55                       "image BLOB, UNIQUE (url, width, height))")) {
     56       NOTREACHED();
     57       return false;
     58     }
     59   }
     60   return true;
     61 }
     62 
     63 bool WebAppsTable::InitWebAppsTable() {
     64   if (!db_->DoesTableExist("web_apps")) {
     65     if (!db_->Execute("CREATE TABLE web_apps ("
     66                       "url LONGVARCHAR UNIQUE,"
     67                       "has_all_images INTEGER NOT NULL)")) {
     68       NOTREACHED();
     69       return false;
     70     }
     71     if (!db_->Execute("CREATE INDEX web_apps_url_index ON web_apps (url)")) {
     72       NOTREACHED();
     73       return false;
     74     }
     75   }
     76   return true;
     77 }
     78 
     79 bool WebAppsTable::SetWebAppImage(const GURL& url, const SkBitmap& image) {
     80   // Don't bother with a cached statement since this will be a relatively
     81   // infrequent operation.
     82   sql::Statement s(db_->GetUniqueStatement(
     83       "INSERT OR REPLACE INTO web_app_icons "
     84       "(url, width, height, image) VALUES (?, ?, ?, ?)"));
     85   std::vector<unsigned char> image_data;
     86   gfx::PNGCodec::EncodeBGRASkBitmap(image, false, &image_data);
     87   s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url));
     88   s.BindInt(1, image.width());
     89   s.BindInt(2, image.height());
     90   s.BindBlob(3, &image_data.front(), static_cast<int>(image_data.size()));
     91 
     92   return s.Run();
     93 }
     94 
     95 bool WebAppsTable::GetWebAppImages(const GURL& url,
     96                                   std::vector<SkBitmap>* images) {
     97   sql::Statement s(db_->GetUniqueStatement(
     98       "SELECT image FROM web_app_icons WHERE url=?"));
     99   s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url));
    100 
    101   while (s.Step()) {
    102     SkBitmap image;
    103     int col_bytes = s.ColumnByteLength(0);
    104     if (col_bytes > 0) {
    105       if (gfx::PNGCodec::Decode(
    106               reinterpret_cast<const unsigned char*>(s.ColumnBlob(0)),
    107               col_bytes, &image)) {
    108         images->push_back(image);
    109       } else {
    110         // Should only have valid image data in the db.
    111         NOTREACHED();
    112       }
    113     }
    114   }
    115   return s.Succeeded();
    116 }
    117 
    118 bool WebAppsTable::SetWebAppHasAllImages(const GURL& url,
    119                                         bool has_all_images) {
    120   sql::Statement s(db_->GetUniqueStatement(
    121       "INSERT OR REPLACE INTO web_apps (url, has_all_images) VALUES (?, ?)"));
    122   s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url));
    123   s.BindInt(1, has_all_images ? 1 : 0);
    124 
    125   return s.Run();
    126 }
    127 
    128 bool WebAppsTable::GetWebAppHasAllImages(const GURL& url) {
    129   sql::Statement s(db_->GetUniqueStatement(
    130       "SELECT has_all_images FROM web_apps WHERE url=?"));
    131   s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url));
    132 
    133   return (s.Step() && s.ColumnInt(0) == 1);
    134 }
    135 
    136 bool WebAppsTable::RemoveWebApp(const GURL& url) {
    137   sql::Statement delete_s(db_->GetUniqueStatement(
    138       "DELETE FROM web_app_icons WHERE url = ?"));
    139   delete_s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url));
    140 
    141   if (!delete_s.Run())
    142     return false;
    143 
    144   sql::Statement delete_s2(db_->GetUniqueStatement(
    145       "DELETE FROM web_apps WHERE url = ?"));
    146   delete_s2.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url));
    147 
    148   return delete_s2.Run();
    149 }
    150