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::CreateTablesIfNecessary() {
     35   return (InitWebAppIconsTable() && InitWebAppsTable());
     36 }
     37 
     38 bool WebAppsTable::IsSyncable() {
     39   return true;
     40 }
     41 
     42 bool WebAppsTable::MigrateToVersion(int version,
     43                                     bool* update_compatible_version) {
     44   return true;
     45 }
     46 
     47 bool WebAppsTable::InitWebAppIconsTable() {
     48   if (!db_->DoesTableExist("web_app_icons")) {
     49     if (!db_->Execute("CREATE TABLE web_app_icons ("
     50                       "url LONGVARCHAR,"
     51                       "width int,"
     52                       "height int,"
     53                       "image BLOB, UNIQUE (url, width, height))")) {
     54       NOTREACHED();
     55       return false;
     56     }
     57   }
     58   return true;
     59 }
     60 
     61 bool WebAppsTable::InitWebAppsTable() {
     62   if (!db_->DoesTableExist("web_apps")) {
     63     if (!db_->Execute("CREATE TABLE web_apps ("
     64                       "url LONGVARCHAR UNIQUE,"
     65                       "has_all_images INTEGER NOT NULL)")) {
     66       NOTREACHED();
     67       return false;
     68     }
     69     if (!db_->Execute("CREATE INDEX web_apps_url_index ON web_apps (url)")) {
     70       NOTREACHED();
     71       return false;
     72     }
     73   }
     74   return true;
     75 }
     76 
     77 bool WebAppsTable::SetWebAppImage(const GURL& url, const SkBitmap& image) {
     78   // Don't bother with a cached statement since this will be a relatively
     79   // infrequent operation.
     80   sql::Statement s(db_->GetUniqueStatement(
     81       "INSERT OR REPLACE INTO web_app_icons "
     82       "(url, width, height, image) VALUES (?, ?, ?, ?)"));
     83   std::vector<unsigned char> image_data;
     84   gfx::PNGCodec::EncodeBGRASkBitmap(image, false, &image_data);
     85   s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url));
     86   s.BindInt(1, image.width());
     87   s.BindInt(2, image.height());
     88   s.BindBlob(3, &image_data.front(), static_cast<int>(image_data.size()));
     89 
     90   return s.Run();
     91 }
     92 
     93 bool WebAppsTable::GetWebAppImages(const GURL& url,
     94                                   std::vector<SkBitmap>* images) {
     95   sql::Statement s(db_->GetUniqueStatement(
     96       "SELECT image FROM web_app_icons WHERE url=?"));
     97   s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url));
     98 
     99   while (s.Step()) {
    100     SkBitmap image;
    101     int col_bytes = s.ColumnByteLength(0);
    102     if (col_bytes > 0) {
    103       if (gfx::PNGCodec::Decode(
    104               reinterpret_cast<const unsigned char*>(s.ColumnBlob(0)),
    105               col_bytes, &image)) {
    106         images->push_back(image);
    107       } else {
    108         // Should only have valid image data in the db.
    109         NOTREACHED();
    110       }
    111     }
    112   }
    113   return s.Succeeded();
    114 }
    115 
    116 bool WebAppsTable::SetWebAppHasAllImages(const GURL& url,
    117                                         bool has_all_images) {
    118   sql::Statement s(db_->GetUniqueStatement(
    119       "INSERT OR REPLACE INTO web_apps (url, has_all_images) VALUES (?, ?)"));
    120   s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url));
    121   s.BindInt(1, has_all_images ? 1 : 0);
    122 
    123   return s.Run();
    124 }
    125 
    126 bool WebAppsTable::GetWebAppHasAllImages(const GURL& url) {
    127   sql::Statement s(db_->GetUniqueStatement(
    128       "SELECT has_all_images FROM web_apps WHERE url=?"));
    129   s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url));
    130 
    131   return (s.Step() && s.ColumnInt(0) == 1);
    132 }
    133 
    134 bool WebAppsTable::RemoveWebApp(const GURL& url) {
    135   sql::Statement delete_s(db_->GetUniqueStatement(
    136       "DELETE FROM web_app_icons WHERE url = ?"));
    137   delete_s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url));
    138 
    139   if (!delete_s.Run())
    140     return false;
    141 
    142   sql::Statement delete_s2(db_->GetUniqueStatement(
    143       "DELETE FROM web_apps WHERE url = ?"));
    144   delete_s2.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url));
    145 
    146   return delete_s2.Run();
    147 }
    148