web_apps_table.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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 "googleurl/src/gurl.h"
11#include "sql/statement.h"
12#include "third_party/skia/include/core/SkBitmap.h"
13#include "ui/gfx/codec/png_codec.h"
14
15namespace {
16
17WebDatabaseTable::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
26WebAppsTable* WebAppsTable::FromWebDatabase(WebDatabase* db) {
27  return static_cast<WebAppsTable*>(db->GetTable(GetKey()));
28}
29
30WebDatabaseTable::TypeKey WebAppsTable::GetTypeKey() const {
31  return GetKey();
32}
33
34bool WebAppsTable::Init(sql::Connection* db, sql::MetaTable* meta_table) {
35  WebDatabaseTable::Init(db, meta_table);
36
37  return (InitWebAppIconsTable() && InitWebAppsTable());
38}
39
40bool WebAppsTable::IsSyncable() {
41  return true;
42}
43
44bool WebAppsTable::MigrateToVersion(int version,
45                                    bool* update_compatible_version) {
46  return true;
47}
48
49bool 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
63bool 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
79bool 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
95bool 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
118bool 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
128bool 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
136bool 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