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