2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @author Lukasz Marek (l.marek@samsung.com)
22 #include <wrt-commons/widget-interface-dao/widget_interface_dao.h>
28 #include <dpl/db/sql_connection.h>
29 #include <dpl/log/log.h>
30 #include <dpl/foreach.h>
31 #include <dpl/string.h>
32 #include <dpl/wrt-dao-ro/property_dao_read_only.h>
33 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
34 #include <dpl/wrt-dao-ro/WrtDatabase.h>
35 #include <dpl/wrt-dao-ro/widget_config.h>
36 #include "orm_generator_widget_interface.h"
38 namespace WidgetInterfaceDB {
39 using namespace DPL::DB::ORM;
40 using namespace DPL::DB::ORM::widget_interface;
42 #define SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN Try
43 #define SQL_CONNECTION_EXCEPTION_HANDLER_END(message) \
44 Catch(DPL::DB::SqlConnection::Exception::Base) { \
46 ReThrowMsg(WidgetInterfaceDAO::Exception::DatabaseError, \
51 DPL::DB::SqlConnection::Flag::Type DATABASE_FLAG =
52 DPL::DB::SqlConnection::Flag::UseLucene;
53 DPL::DB::SqlConnection::Flag::Option DATABASE_OPTION =
54 DPL::DB::SqlConnection::Flag::RW;
55 const char *KEY_WIDGET_ARG = "widget_arg";
57 const char* const DATABASE_NAME = ".widget_interface.db";
58 const char* const DATABASE_FILE_PATH =
59 "/usr/share/wrt-engine/widget_interface_db.sql";
60 const char* const DATABASE_JOURNAL_FILENAME = "-journal";
62 const int APP_UID = 5000;
63 const int APP_GUID = 5000;
64 } // anonymous namespace
66 WidgetInterfaceDAO::WidgetInterfaceDAO(int widgetHandle) :
67 m_widgetHandle(widgetHandle),
68 m_databaseInterface(databaseFileName(widgetHandle), DATABASE_FLAG)
71 m_databaseInterface.AttachToThread(DATABASE_OPTION);
74 WidgetInterfaceDAO::~WidgetInterfaceDAO()
76 m_databaseInterface.DetachFromThread();
79 void WidgetInterfaceDAO::checkDatabase()
81 std::string databaseFile = databaseFileName(m_widgetHandle);
83 if (stat(databaseFile.c_str(), &buffer) != 0) {
84 //Create fresh database
85 LogDebug("Creating database " << databaseFile);
88 file.open(DATABASE_FILE_PATH, std::ios_base::in);
90 ThrowMsg(WidgetInterfaceDAO::Exception::DatabaseError,
91 "Cannot create database. SQL file is missing.");
94 std::stringstream stream;
95 stream << file.rdbuf();
99 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
101 DPL::DB::SqlConnection con(databaseFile,
104 con.ExecCommand(stream.str().c_str());
105 copyPropertiesFromWrtDatabase();
107 SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot create database")
109 if(chown(databaseFile.c_str(), APP_UID, APP_GUID) != 0) {
110 ThrowMsg(WidgetInterfaceDAO::Exception::DatabaseError,
111 "Fail to change uid/guid");
113 std::string databaseJournal =
114 databaseFile + DATABASE_JOURNAL_FILENAME;
115 if(chown(databaseJournal.c_str(), APP_UID, APP_GUID) != 0) {
116 ThrowMsg(WidgetInterfaceDAO::Exception::DatabaseError,
117 "Fail to change uid/guid");
122 void WidgetInterfaceDAO::copyPropertiesFromWrtDatabase()
124 WrtDB::WrtDatabase::attachToThreadRO();
125 m_databaseInterface.AttachToThread(DPL::DB::SqlConnection::Flag::RW);
127 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
129 WrtDB::PropertyDAOReadOnly::WidgetPreferenceList existing =
130 WrtDB::PropertyDAOReadOnly::GetPropertyList(
131 WrtDB::WidgetDAOReadOnly::getTizenAppId(m_widgetHandle)
134 //save all properties read from config.xml
135 FOREACH(prop, existing) {
136 std::string key = DPL::ToUTF8String(prop->key_name);
137 if (key != KEY_WIDGET_ARG) {
139 if (!prop->key_value.IsNull()) {
140 value = DPL::ToUTF8String(*(prop->key_value));
142 bool readonly = !prop->readonly.IsNull() && (*prop->readonly);
143 setItem(key, value, readonly, true);
147 SQL_CONNECTION_EXCEPTION_HANDLER_END(
148 "Cannot copy properties read from config.xml");
150 WrtDB::WrtDatabase::detachFromThread();
151 m_databaseInterface.DetachFromThread();
154 void WidgetInterfaceDAO::setItem(const std::string& key,
155 const std::string& value,
158 setItem(key, value, readOnly, false);
161 void WidgetInterfaceDAO::setItem(const std::string& key,
162 const std::string& value,
166 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
168 ScopedTransaction tran(&m_databaseInterface);
169 //check if key exists
170 Properties::Select select(&m_databaseInterface);
171 select.Where(Equals<Properties::key>(DPL::FromUTF8String(key)));
172 std::list<Properties::Row> rows = select.GetRowList();
175 Properties::Insert insert(&m_databaseInterface);
177 row.Set_key(DPL::FromUTF8String(key));
178 row.Set_value(DPL::FromUTF8String(value));
179 row.Set_readonly(readOnly ? 1 : 0);
180 row.Set_configxml(fromConfigXml ? 1 : 0);
184 Assert(rows.size() == 1);
185 Properties::Row row = rows.front();
186 if (row.Get_readonly() != 0) {
187 Throw(Exception::LocalStorageValueNoModifableException);
189 row.Set_value(DPL::FromUTF8String(value));
190 row.Set_readonly(readOnly ? 1 : 0);
191 Properties::Update update(&m_databaseInterface);
192 update.Where(Equals<Properties::key>(DPL::FromUTF8String(key)));
198 SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot set item");
201 void WidgetInterfaceDAO::removeItem(const std::string& key)
203 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
205 Properties::Select select(&m_databaseInterface);
206 select.Where(Equals<Properties::key>(DPL::FromUTF8String(key)));
207 bool readonly = select.GetSingleValue<Properties::readonly>();
209 ThrowMsg(Exception::LocalStorageValueNoModifableException,
210 "Cannot delete item. Item is readonly");
212 Properties::Delete deleteItem(&m_databaseInterface);
213 deleteItem.Where(Equals<Properties::key>(DPL::FromUTF8String(key)));
214 deleteItem.Execute();
216 SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot delete item");
219 DPL::Optional<std::string> WidgetInterfaceDAO::getValue(
220 const std::string& key) const
222 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
224 Properties::Select select(&m_databaseInterface);
225 select.Where(Equals<Properties::key>(DPL::FromUTF8String(key)));
226 std::list<DPL::String> value =
227 select.GetValueList<Properties::value>();
229 return DPL::Optional<std::string>();
231 return DPL::Optional<std::string>(DPL::ToUTF8String(value.front()));
233 SQL_CONNECTION_EXCEPTION_HANDLER_END("Not found item");
236 void WidgetInterfaceDAO::clear(bool removeReadOnly)
238 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
240 Properties::Delete deleteItem(&m_databaseInterface);
241 if (!removeReadOnly) {
242 deleteItem.Where(Equals<Properties::readonly>(0));
244 deleteItem.Execute();
246 SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot delete all items");
249 size_t WidgetInterfaceDAO::getStorageSize() const
251 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
253 Properties::Select select(&m_databaseInterface);
254 std::list<DPL::String> list =
255 select.GetValueList<Properties::key>();
258 SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot get item count");
261 std::string WidgetInterfaceDAO::getKeyByIndex(size_t index) const
263 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
265 Properties::Select select(&m_databaseInterface);
266 select.OrderBy("key");
267 std::list<DPL::String> list = select.GetValueList<Properties::key>();
268 if (index >= list.size()) {
269 Throw(Exception::InvalidArgumentException);
271 for (size_t i = 0; i < index; ++i) {
274 return DPL::ToUTF8String(list.front());
276 SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot get item count");
279 std::string WidgetInterfaceDAO::databaseFileName(int widgetHandle)
281 using namespace DPL::DB::ORM;
282 using namespace WrtDB::WidgetConfig;
284 WrtDB::WrtDatabase::attachToThreadRO();
285 std::stringstream filename;
286 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
288 WrtDB::WidgetDAOReadOnly widgetDAO(widgetHandle);
289 WrtDB::TizenPkgId pkgid = widgetDAO.getTizenPkgId();
291 filename << GetWidgetPersistentStoragePath(pkgid)
295 SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot get item count");
296 WrtDB::WrtDatabase::detachFromThread();
297 return filename.str();
299 } // namespace WidgetInterfaceDB