1 // Copyright (c) 2014 Intel Corporation. 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.
5 #include "xwalk/application/extension/application_widget_storage.h"
9 #include "base/file_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "sql/statement.h"
12 #include "sql/transaction.h"
13 #include "xwalk/application/common/application_manifest_constants.h"
14 #include "xwalk/application/common/manifest_handlers/widget_handler.h"
18 namespace widget_keys = xwalk::application_widget_keys;
20 const char kPreferences[] = "preferences";
21 const char kPreferencesName[] = "name";
22 const char kPreferencesValue[] = "value";
23 const char kPreferencesReadonly[] = "readonly";
25 const char kStorageTableName[] = "widget_storage";
27 const char kCreateStorageTableOp[] =
28 "CREATE TABLE widget_storage ("
29 "key TEXT NOT NULL UNIQUE PRIMARY KEY,"
30 "value TEXT NOT NULL,"
31 "read_only INTEGER )";
33 const char kClearStorageTableWithBindOp[] =
34 "DELETE FROM widget_storage WHERE read_only = ? ";
36 const char kInsertItemWithBindOp[] =
37 "INSERT INTO widget_storage (value, read_only, key) "
40 const char kUpdateItemWithBindOp[] =
41 "UPDATE widget_storage SET value = ? , read_only = ? "
44 const char kRemoveItemWithBindOp[] =
45 "DELETE FROM widget_storage WHERE key = ?";
47 const char kSelectTableLength[] =
48 "SELECT count(*) FROM widget_storage ";
50 const char kSelectCountWithBindOp[] =
51 "SELECT count(*) FROM widget_storage "
54 const char kSelectAllItem[] =
55 "SELECT key, value FROM widget_storage ";
57 const char kSelectReadOnlyWithBindOp[] =
58 "SELECT read_only FROM widget_storage "
63 namespace application {
65 AppWidgetStorage::AppWidgetStorage(Application* application,
66 const base::FilePath& data_dir)
67 : application_(application),
68 db_initialized_(false),
69 data_path_(data_dir) {
70 sqlite_db_.reset(new sql::Connection);
73 LOG(ERROR) << "Initialize widget storage failed.";
78 AppWidgetStorage::~AppWidgetStorage() {
81 bool AppWidgetStorage::Init() {
82 if (!sqlite_db_->Open(data_path_)) {
83 LOG(ERROR) << "Unable to open widget storage DB.";
86 sqlite_db_->Preload();
88 if (!InitStorageTable()) {
89 LOG(ERROR) << "Unable to init widget storage table.";
92 return db_initialized_;
95 bool AppWidgetStorage::SaveConfigInfoItem(base::DictionaryValue* dict) {
99 bool read_only = false;
100 dict->GetString(kPreferencesName, &key);
101 dict->GetString(kPreferencesValue, &value);
102 dict->GetBoolean(kPreferencesReadonly, &read_only);
103 return AddEntry(key, value, read_only);
106 bool AppWidgetStorage::SaveConfigInfoInDB() {
108 static_cast<WidgetInfo*>(
109 application_->data()->GetManifestData(widget_keys::kWidgetKey));
110 base::DictionaryValue* widget_info = info->GetWidgetInfo();
112 LOG(ERROR) << "Fail to get parsed widget information.";
116 base::Value* pref_value = NULL;
117 widget_info->Get(kPreferences, &pref_value);
119 if (pref_value && pref_value->IsType(base::Value::TYPE_DICTIONARY)) {
120 base::DictionaryValue* dict;
121 pref_value->GetAsDictionary(&dict);
122 return SaveConfigInfoItem(dict);
123 } else if (pref_value && pref_value->IsType(base::Value::TYPE_LIST)) {
124 base::ListValue* list;
125 pref_value->GetAsList(&list);
127 for (base::ListValue::iterator it = list->begin();
128 it != list->end(); ++it) {
129 base::DictionaryValue* dict;
130 (*it)->GetAsDictionary(&dict);
131 if (!SaveConfigInfoItem(dict))
135 LOG(INFO) << "No widget preferences or preference type is not supported.";
141 bool AppWidgetStorage::InitStorageTable() {
142 if (sqlite_db_->DoesTableExist(kStorageTableName)) {
143 db_initialized_ = (sqlite_db_ && sqlite_db_->is_open());
147 sql::Transaction transaction(sqlite_db_.get());
149 if (!sqlite_db_->Execute(kCreateStorageTableOp))
151 if (!transaction.Commit())
154 db_initialized_ = (sqlite_db_ && sqlite_db_->is_open());
155 SaveConfigInfoInDB();
160 bool AppWidgetStorage::EntryExists(const std::string& key) const {
161 sql::Transaction transaction(sqlite_db_.get());
162 if (!transaction.Begin())
165 sql::Statement stmt(sqlite_db_->GetUniqueStatement(
166 kSelectCountWithBindOp));
167 stmt.BindString(0, key);
169 LOG(ERROR) << "An error occured when selecting count from DB.";
173 if (!transaction.Commit())
176 int exist = stmt.ColumnInt(0);
180 bool AppWidgetStorage::IsReadOnly(const std::string& key) {
181 sql::Transaction transaction(sqlite_db_.get());
182 if (!transaction.Begin())
185 sql::Statement stmt(sqlite_db_->GetUniqueStatement(
186 kSelectReadOnlyWithBindOp));
187 stmt.BindString(0, key);
189 LOG(ERROR) << "An error occured when selecting count from DB.";
193 if (!transaction.Commit())
196 return stmt.ColumnBool(0);
199 bool AppWidgetStorage::AddEntry(const std::string& key,
200 const std::string& value,
202 if (!db_initialized_ && !Init())
205 std::string operation;
206 if (!EntryExists(key)) {
207 operation = kInsertItemWithBindOp;
208 } else if (!IsReadOnly(key)) {
209 operation = kUpdateItemWithBindOp;
211 LOG(ERROR) << "Could not set read only item " << key;
215 sql::Transaction transaction(sqlite_db_.get());
216 if (!transaction.Begin())
219 sql::Statement stmt(sqlite_db_->GetUniqueStatement(
221 stmt.BindString(0, value);
222 stmt.BindBool(1, read_only);
223 stmt.BindString(2, key);
225 LOG(ERROR) << "An error occured when set item into DB.";
229 return transaction.Commit();
232 bool AppWidgetStorage::RemoveEntry(const std::string& key) {
233 if (!db_initialized_ && !Init())
236 if (IsReadOnly(key)) {
237 LOG(ERROR) << "Could not remove read only item " << key;
241 sql::Transaction transaction(sqlite_db_.get());
242 if (!transaction.Begin())
245 sql::Statement stmt(sqlite_db_->GetUniqueStatement(
246 kRemoveItemWithBindOp));
247 stmt.BindString(0, key);
250 LOG(ERROR) << "An error occured when removing item into DB.";
254 return transaction.Commit();
257 bool AppWidgetStorage::Clear() {
258 if (!db_initialized_ && !Init())
261 sql::Transaction transaction(sqlite_db_.get());
264 sql::Statement stmt(sqlite_db_->GetUniqueStatement(
265 kClearStorageTableWithBindOp));
266 stmt.BindBool(0, false);
269 LOG(ERROR) << "An error occured when removing item into DB.";
273 return transaction.Commit();
276 bool AppWidgetStorage::GetAllEntries(base::DictionaryValue* result) {
281 if (!db_initialized_ && !Init())
284 sql::Statement stmt(sqlite_db_->GetUniqueStatement(kSelectAllItem));
285 while (stmt.Step()) {
286 key = stmt.ColumnString(0);
287 value = stmt.ColumnString(1);
288 result->SetString(key, value);
294 } // namespace application