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(m_widgetHandle);
132 //save all properties read from config.xml
133 FOREACH(prop, existing) {
134 std::string key = DPL::ToUTF8String(prop->key_name);
135 if (key != KEY_WIDGET_ARG) {
137 if (!prop->key_value.IsNull()) {
138 value = DPL::ToUTF8String(*(prop->key_value));
140 bool readonly = !prop->readonly.IsNull() && (*prop->readonly);
141 setItem(key, value, readonly, true);
145 SQL_CONNECTION_EXCEPTION_HANDLER_END(
146 "Cannot copy properties read from config.xml");
148 WrtDB::WrtDatabase::detachFromThread();
149 m_databaseInterface.DetachFromThread();
152 void WidgetInterfaceDAO::setItem(const std::string& key,
153 const std::string& value,
156 setItem(key, value, readOnly, false);
159 void WidgetInterfaceDAO::setItem(const std::string& key,
160 const std::string& value,
164 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
166 ScopedTransaction tran(&m_databaseInterface);
167 //check if key exists
168 Properties::Select select(&m_databaseInterface);
169 select.Where(Equals<Properties::key>(DPL::FromUTF8String(key)));
170 std::list<Properties::Row> rows = select.GetRowList();
173 Properties::Insert insert(&m_databaseInterface);
175 row.Set_key(DPL::FromUTF8String(key));
176 row.Set_value(DPL::FromUTF8String(value));
177 row.Set_readonly(readOnly ? 1 : 0);
178 row.Set_configxml(fromConfigXml ? 1 : 0);
182 Assert(rows.size() == 1);
183 Properties::Row row = rows.front();
184 if (row.Get_readonly() != 0) {
185 Throw(Exception::LocalStorageValueNoModifableException);
187 row.Set_value(DPL::FromUTF8String(value));
188 row.Set_readonly(readOnly ? 1 : 0);
189 Properties::Update update(&m_databaseInterface);
190 update.Where(Equals<Properties::key>(DPL::FromUTF8String(key)));
196 SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot set item");
199 void WidgetInterfaceDAO::removeItem(const std::string& key)
201 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
203 Properties::Select select(&m_databaseInterface);
204 select.Where(Equals<Properties::key>(DPL::FromUTF8String(key)));
205 bool readonly = select.GetSingleValue<Properties::readonly>();
207 ThrowMsg(Exception::LocalStorageValueNoModifableException,
208 "Cannot delete item. Item is readonly");
210 Properties::Delete deleteItem(&m_databaseInterface);
211 deleteItem.Where(Equals<Properties::key>(DPL::FromUTF8String(key)));
212 deleteItem.Execute();
214 SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot delete item");
217 DPL::Optional<std::string> WidgetInterfaceDAO::getValue(
218 const std::string& key) const
220 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
222 Properties::Select select(&m_databaseInterface);
223 select.Where(Equals<Properties::key>(DPL::FromUTF8String(key)));
224 std::list<DPL::String> value =
225 select.GetValueList<Properties::value>();
227 return DPL::Optional<std::string>();
229 return DPL::Optional<std::string>(DPL::ToUTF8String(value.front()));
231 SQL_CONNECTION_EXCEPTION_HANDLER_END("Not found item");
234 void WidgetInterfaceDAO::clear(bool removeReadOnly)
236 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
238 Properties::Delete deleteItem(&m_databaseInterface);
239 if (!removeReadOnly) {
240 deleteItem.Where(Equals<Properties::readonly>(0));
242 deleteItem.Execute();
244 SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot delete all items");
247 size_t WidgetInterfaceDAO::getStorageSize() const
249 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
251 Properties::Select select(&m_databaseInterface);
252 std::list<DPL::String> list =
253 select.GetValueList<Properties::key>();
256 SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot get item count");
259 std::string WidgetInterfaceDAO::getKeyByIndex(size_t index) const
261 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
263 Properties::Select select(&m_databaseInterface);
264 select.OrderBy("key");
265 std::list<DPL::String> list = select.GetValueList<Properties::key>();
266 if (index >= list.size()) {
267 Throw(Exception::InvalidArgumentException);
269 for (size_t i = 0; i < index; ++i) {
272 return DPL::ToUTF8String(list.front());
274 SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot get item count");
277 std::string WidgetInterfaceDAO::databaseFileName(int widgetHandle)
279 using namespace DPL::DB::ORM;
280 using namespace WrtDB::WidgetConfig;
282 WrtDB::WrtDatabase::attachToThreadRO();
283 std::stringstream filename;
284 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
286 WrtDB::WidgetDAOReadOnly widgetDAO(widgetHandle);
287 WrtDB::TizenPkgId pkgid = widgetDAO.getTizenPkgId();
289 filename << GetWidgetPersistentStoragePath(pkgid)
293 SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot get item count");
294 WrtDB::WrtDatabase::detachFromThread();
295 return filename.str();
297 } // namespace WidgetInterfaceDB