tizen beta release
[framework/web/wrt-plugins-common.git] / src / modules / tizen / WidgetInterfaceDAO / WidgetInterfaceDAO.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 /*
17  * @author      Lukasz Marek (l.marek@samsung.com)
18  * @version     0.1
19  * @brief
20  */
21
22 #include "WidgetInterfaceDAO.h"
23 #include <string>
24 #include <sstream>
25 #include <fstream>
26 #include <sys/stat.h>
27 #include <dpl/db/sql_connection.h>
28 #include <dpl/log/log.h>
29 #include <dpl/foreach.h>
30 #include <dpl/string.h>
31 #include <Commons/Exception.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 <dpl/wrt-dao-ro/global_config.h>
37 #include "orm_generator_widget_interface.h"
38 namespace {
39 DPL::DB::SqlConnection::Flag::Type DATABASE_FLAGS =
40     DPL::DB::SqlConnection::Flag::UseLucene;
41 const char *KEY_WIDGET_ARG = "widget_arg";
42 }
43
44 namespace WrtDeviceApis {
45
46 WidgetInterfaceDAO::WidgetInterfaceDAO(int widgetHandle) :
47     m_widgetHandle(widgetHandle),
48     m_databaseInterface(databaseFileName(widgetHandle), DATABASE_FLAGS)
49 {
50     if (!checkDatabase()) {
51         LogError("There is a problem with database");
52     }
53     m_databaseInterface.AttachToThread();
54 }
55
56 WidgetInterfaceDAO::~WidgetInterfaceDAO()
57 {
58     m_databaseInterface.DetachFromThread();
59 }
60
61 bool WidgetInterfaceDAO::checkDatabase()
62 {
63     using namespace WrtDB::GlobalConfig;
64     std::string databaseFile = databaseFileName(m_widgetHandle);
65     struct stat buffer;
66     if (stat(databaseFile.c_str(), &buffer) != 0) {
67
68         //Create fresh database
69
70         LogInfo("Creating database " << databaseFile);
71
72         std::fstream file;
73         file.open(GetWrtWidgetInterfaceDatabaseFilePath(), std::ios_base::in);
74         if (!file) {
75             LogError("Cannot create database. SQL file is missing.");
76             return false;
77         }
78
79         std::stringstream buffer;
80         buffer << file.rdbuf();
81
82         file.close();
83
84         Try
85         {
86             DPL::DB::SqlConnection con(databaseFile);
87             con.ExecCommand(buffer.str().c_str());
88         }
89         Catch(DPL::DB::SqlConnection::Exception::Base)
90         {
91             LogError("Cannot create database");
92             return false;
93         }
94         copyPropertiesFromWrtDatabase();
95     }
96     return true;
97 }
98
99 bool WidgetInterfaceDAO::copyPropertiesFromWrtDatabase()
100 {
101     using namespace DPL::DB::ORM;
102     using namespace DPL::DB::ORM::widget_interface;
103
104     bool result = true;
105     WrtDB::WrtDatabase::attachToThread();
106     m_databaseInterface.AttachToThread();
107
108     Try
109     {
110         WrtDB::PropertyDAOReadOnly::WidgetPreferenceList existing =
111             WrtDB::PropertyDAOReadOnly::GetPropertyList(m_widgetHandle);
112
113         Try
114         {
115             //save all properties read from config.xml
116             FOREACH(prop, existing) {
117                 std::string key = DPL::ToUTF8String(prop->key_name);
118                 if (key != KEY_WIDGET_ARG) {
119                     std::string value;
120                     if (!prop->key_value.IsNull()) {
121                         value = DPL::ToUTF8String(*(prop->key_value));
122                     }
123                     bool readonly =
124                         !prop->readonly.IsNull() && (*prop->readonly);
125                     setItem(key, value, readonly, true);
126                 }
127             }
128         }
129         Catch(Commons::Exception)
130         {
131             LogError("Cannot copy properties read from config.xml");
132             result = false;
133         }
134     }
135     Catch(DPL::DB::SqlConnection::Exception::Base)
136     {
137         LogError("Cannot copy properties read from config.xml");
138         result = false;
139     }
140     WrtDB::WrtDatabase::detachFromThread();
141     m_databaseInterface.DetachFromThread();
142     return result;
143 }
144
145 void WidgetInterfaceDAO::setItem(const std::string& key,
146                                  const std::string& value,
147                                  bool readOnly)
148 {
149     setItem(key, value, readOnly, false);
150 }
151
152 void WidgetInterfaceDAO::setItem(const std::string& key,
153                                  const std::string& value,
154                                  bool readOnly,
155                                  bool fromConfigXml)
156 {
157     using namespace DPL::DB::ORM;
158     using namespace DPL::DB::ORM::widget_interface;
159
160     Try
161     {
162         ScopedTransaction tran(&m_databaseInterface);
163         //check if key exists
164         Properties::Select select(&m_databaseInterface);
165         select.Where(
166             Equals<Properties::key>(DPL::FromASCIIString(key)));
167         std::list<Properties::Row> rows = select.GetRowList();
168
169         if (rows.size() == 0) {
170             Properties::Insert insert(&m_databaseInterface);
171             Properties::Row row;
172             row.Set_key(DPL::FromASCIIString(key));
173             row.Set_value(DPL::FromASCIIString(value));
174             row.Set_readonly(readOnly ? 1 : 0);
175             row.Set_configxml(fromConfigXml ? 1 : 0);
176             insert.Values(row);
177             insert.Execute();
178         }
179         else {
180             Assert(rows.size() == 1);
181             Properties::Row row = rows.front();
182             if (row.Get_readonly() != 0) {
183                 Throw(Commons::LocalStorageValueNoModifableException);
184             }
185             row.Set_value(DPL::FromASCIIString(value));
186             row.Set_readonly(readOnly ? 1 : 0);
187             Properties::Update update(&m_databaseInterface);
188             update.Where(Equals<Properties::key>(DPL::FromASCIIString(key)));
189             update.Values(row);
190             update.Execute();
191         }
192         tran.Commit();
193     }
194     Catch(DPL::DB::SqlConnection::Exception::Base)
195     {
196         LogError("Cannot set item " << key << " with value " << value);
197         ReThrow(Commons::PlatformException);
198     }
199
200 }
201
202 void WidgetInterfaceDAO::removeItem(const std::string& key)
203 {
204     using namespace DPL::DB::ORM;
205     using namespace DPL::DB::ORM::widget_interface;
206
207     Try
208     {
209         Properties::Select select(&m_databaseInterface);
210         select.Where(Equals<Properties::key>(DPL::FromASCIIString(key)));
211         bool readonly = select.GetSingleValue<Properties::readonly>();
212         if (readonly) {
213             ThrowMsg(Commons::LocalStorageValueNoModifableException,
214                 "Cannot delete item. Item is readonly");
215         }
216         Properties::Delete deleteItem(&m_databaseInterface);
217         deleteItem.Where(Equals<Properties::key>(DPL::FromASCIIString(key)));
218         deleteItem.Execute();
219     }
220     Catch(DPL::DB::SqlConnection::Exception::Base)
221     {
222         LogError("Cannot delete item " << key);
223         ReThrow(Commons::PlatformException);
224     }
225 }
226
227 DPL::Optional<std::string> WidgetInterfaceDAO::getValue(
228         const std::string& key) const
229 {
230     using namespace DPL::DB::ORM;
231     using namespace DPL::DB::ORM::widget_interface;
232
233     Try
234     {
235         Properties::Select select(&m_databaseInterface);
236         select.Where(Equals<Properties::key>(DPL::FromASCIIString(key)));
237         std::list<DPL::String> value = select.GetValueList<Properties::value>();
238         if (value.size() == 0) {
239             return DPL::Optional<std::string>();
240         }
241         return DPL::Optional<std::string>(DPL::ToUTF8String(value.front()));
242     }
243     Catch(DPL::DB::SqlConnection::Exception::Base)
244     {
245         LogError("Not found item " << key);
246         ReThrow(Commons::PlatformException);
247     }
248     return std::string();
249 }
250
251 void WidgetInterfaceDAO::clear(bool removeReadOnly)
252 {
253     using namespace DPL::DB::ORM;
254     using namespace DPL::DB::ORM::widget_interface;
255     Try
256     {
257         Properties::Delete deleteItem(&m_databaseInterface);
258         if (!removeReadOnly) {
259             deleteItem.Where(Equals<Properties::readonly>(0));
260         }
261         deleteItem.Execute();
262     }
263     Catch(DPL::DB::SqlConnection::Exception::Base)
264     {
265         LogError("Cannot delete all items");
266         ReThrow(Commons::PlatformException);
267     }
268 }
269
270 size_t WidgetInterfaceDAO::getStorageSize() const
271 {
272     using namespace DPL::DB::ORM;
273     using namespace DPL::DB::ORM::widget_interface;
274
275     Try
276     {
277         Properties::Select select(&m_databaseInterface);
278         std::list<DPL::String> list =
279             select.GetValueList<Properties::key>();
280         return list.size();
281     }
282     Catch(DPL::DB::SqlConnection::Exception::Base)
283     {
284         LogError("Cannot get item count");
285         ReThrow(Commons::PlatformException);
286     }
287     return 0;
288 }
289
290 std::string WidgetInterfaceDAO::getValueByIndex(size_t index) const
291 {
292     using namespace DPL::DB::ORM;
293     using namespace DPL::DB::ORM::widget_interface;
294
295     Try
296     {
297         Properties::Select select(&m_databaseInterface);
298         select.OrderBy("key");
299         std::list<DPL::String> list =
300             select.GetValueList<Properties::value>();
301         if (index >= list.size()) {
302             Throw(Commons::InvalidArgumentException);
303         }
304         for (size_t i = 0; i < index; ++i) {
305             list.pop_front();
306         }
307         return DPL::ToUTF8String(list.front());
308     }
309     Catch(DPL::DB::SqlConnection::Exception::Base)
310     {
311         LogError("Cannot get item count");
312         ReThrow(Commons::PlatformException);
313     }
314     return std::string();
315 }
316
317 std::string WidgetInterfaceDAO::databaseFileName(int widgetHandle)
318 {
319     using namespace DPL::DB::ORM;
320     using namespace WrtDB::WidgetConfig;
321     using namespace WrtDB::GlobalConfig;
322
323     WrtDB::WrtDatabase::attachToThread();
324
325     std::stringstream filename;
326     Try
327     {
328         WrtDB::WidgetDAOReadOnly widgetDAO(widgetHandle);
329         DPL::Optional<DPL::String> pkgname = widgetDAO.getPkgname();
330
331         filename << GetWidgetPersistentStoragePath(*pkgname)
332                  << "/"
333                  << GetWidgetInterfaceDatabaseFile();
334     }
335     Catch(DPL::DB::SqlConnection::Exception::Base)
336     {
337         LogError("Cannot get item count");
338         ReThrow(Commons::PlatformException);
339     }
340     WrtDB::WrtDatabase::detachFromThread();
341     return filename.str();
342 }
343
344 }