The download UI application is added.
[apps/web/download-manager.git] / src / download-manager-history-db.cpp
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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 /**
18  * @file        download-manager-history-db.cpp
19  * @author      Jungki Kwak (jungki.kwak@samsung.com)
20  * @brief       Manager for a download history DB
21  */
22
23 #include <sstream>
24 #include "download-manager-common.h"
25 #include "download-manager-history-db.h"
26
27 #define FINALIZE_ON_ERROR( stmt ) { \
28         DP_LOG("SQL error: %d", ret);\
29         if (sqlite3_finalize(stmt) != SQLITE_OK)\
30                 DP_LOGE("sqlite3_finalize is failed.");\
31         close();\
32         return false; \
33 }
34
35 sqlite3 *DownloadHistoryDB::historyDb = NULL;
36
37 DownloadHistoryDB::DownloadHistoryDB()
38 {
39 }
40
41 DownloadHistoryDB::~DownloadHistoryDB()
42 {
43 }
44
45 bool DownloadHistoryDB::open()
46 {
47         int ret = 0;
48
49         DP_LOGD_FUNC();
50
51         close();
52
53         ret = db_util_open(DBDATADIR"/"HISTORYDB, &historyDb,
54                 DB_UTIL_REGISTER_HOOK_METHOD);
55
56         if (ret != SQLITE_OK) {
57                 DP_LOGE("open fail");
58                 db_util_close(historyDb);
59                 historyDb = NULL;
60                 return false;
61         }
62
63         return isOpen();
64 }
65
66 void DownloadHistoryDB::close()
67 {
68         DP_LOGD_FUNC();
69         if (historyDb) {
70                 db_util_close(historyDb);
71                 historyDb = NULL;
72         }
73 }
74
75 /* FIXME : Hitory entry limitation ?? */
76 bool DownloadHistoryDB::addToHistoryDB(Item *item)
77 {
78         int ret = 0;
79         sqlite3_stmt *stmt = NULL;
80
81         DP_LOG_FUNC();
82
83         if (!item) {
84                 DP_LOGE("Item is NULL");
85                 return false;
86         }
87
88         if (item->historyId() < 0) {
89                 DP_LOGE("Cannot add to DB. Because historyId is invaild");
90                 return false;
91         }
92
93         if (!open()) {
94                 DP_LOGE("historyDB is NULL");
95                 return false;
96         }
97
98         const string statement = "insert into history (historyid, downloadtype,\
99                 contenttype, state, err, name, path, url, cookie, date) \
100                 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
101
102         ret = sqlite3_prepare_v2(historyDb, statement.c_str(), -1, &stmt, NULL);
103
104         if (ret != SQLITE_OK)
105                 FINALIZE_ON_ERROR(stmt);
106         /* binding values */
107         if (sqlite3_bind_int(stmt, 1, item->historyId()) != SQLITE_OK)
108                 DP_LOGE("sqlite3_bind_int is failed.");
109         if (sqlite3_bind_int(stmt, 2, item->downloadType()) != SQLITE_OK)
110                 DP_LOGE("sqlite3_bind_int is failed.");
111         if (sqlite3_bind_int(stmt, 3, item->contentType()) != SQLITE_OK)
112                 DP_LOGE("sqlite3_bind_int is failed.");
113         if (sqlite3_bind_int(stmt, 4, item->state()) != SQLITE_OK)
114                 DP_LOGE("sqlite3_bind_int is failed.");
115         if (sqlite3_bind_int(stmt, 5, item->errorCode()) != SQLITE_OK)
116                 DP_LOGE("sqlite3_bind_int is failed.");
117         if (sqlite3_bind_text(stmt, 6, item->title().c_str(), -1, NULL) != SQLITE_OK)
118                 DP_LOGE("sqlite3_bind_text is failed.");
119         if (sqlite3_bind_text(
120                         stmt, 7, item->registeredFilePath().c_str(), -1, NULL) != SQLITE_OK)
121                 DP_LOGE("sqlite3_bind_text is failed.");
122         if (sqlite3_bind_text(stmt, 8, item->url().c_str(), -1, NULL) != SQLITE_OK)
123                 DP_LOGE("sqlite3_bind_text is failed.");
124         if (sqlite3_bind_text(stmt, 9, item->cookie().c_str(), -1, NULL) != SQLITE_OK)
125                 DP_LOGE("sqlite3_bind_text is failed.");
126         if (sqlite3_bind_double(stmt, 10, item->finishedTime()) != SQLITE_OK)
127                 DP_LOGE("sqlite3_bind_double is failed.");
128         ret = sqlite3_step(stmt);
129
130         DP_LOGD("SQL return: %s", (ret == SQLITE_ROW || ret == SQLITE_OK)?"Success":"Fail");
131
132         close();
133
134         return ret == SQLITE_DONE;
135 }
136
137 bool DownloadHistoryDB::getCountOfHistory(int *count)
138 {
139         int ret = 0;
140         sqlite3_stmt *stmt = NULL;
141
142         DP_LOG_FUNC();
143
144         if (!open()) {
145                 DP_LOGE("historyDB is NULL");
146                 return false;
147         }
148         ret = sqlite3_prepare_v2(historyDb, "select COUNT(*) from history", -1, &stmt, NULL);
149         if (ret != SQLITE_OK)
150                 FINALIZE_ON_ERROR(stmt);
151
152         ret = sqlite3_step(stmt);
153         DP_LOGD("SQL return: %s", (ret == SQLITE_ROW || ret == SQLITE_OK)?"Success":"Fail");
154         if (ret == SQLITE_ROW) {
155                 *count = sqlite3_column_int(stmt,0);
156                 DP_LOGD("count[%d]",*count);
157         } else {
158                 DP_LOGE("SQL query error");
159                 *count = 0;
160         }
161
162         if (sqlite3_finalize(stmt) != SQLITE_OK)
163                 DP_LOGE("sqlite3_finalize is failed.");
164         close();
165         return true;
166 }
167
168 bool DownloadHistoryDB::createRemainedItemsFromHistoryDB(int limit, int offset)
169 {
170         int ret = 0;
171         stringstream limitStr;
172         stringstream offsetStr;
173         sqlite3_stmt *stmt = NULL;
174         string tmp;
175
176         DP_LOG_FUNC();
177
178         if (!open()) {
179                 DP_LOGE("historyDB is NULL");
180                 return false;
181         }
182         limitStr << limit;
183         offsetStr << offset;
184
185         tmp.append("select historyid, downloadtype, contenttype, state, err, ");
186         tmp.append("name, path, url, cookie, date from history order by ");
187         tmp.append("date DESC limit ");
188         tmp.append(limitStr.str());
189         tmp.append(" offset ");
190         tmp.append(offsetStr.str());
191         ret = sqlite3_prepare_v2(historyDb, tmp.c_str(), -1, &stmt, NULL);
192         if (ret != SQLITE_OK)
193                 FINALIZE_ON_ERROR(stmt);
194
195         for (;;) {
196                 ret = sqlite3_step(stmt);
197                 if (ret == SQLITE_ROW) {
198                         const char *tempStr = NULL;
199                         string arg;
200                         string url;
201                         string cookie;
202                         Item *item = Item::createHistoryItem();
203                         if (!item) {
204                                 DP_LOGE("Fail to create item");
205                                 break;
206                         }
207                         item->setHistoryId(sqlite3_column_int(stmt,0));
208                         item->setDownloadType((DL_TYPE::TYPE)sqlite3_column_int(stmt,1));
209                         item->setContentType(sqlite3_column_int(stmt,2));
210                         item->setState((ITEM::STATE)sqlite3_column_int(stmt,3));
211                         item->setErrorCode((ERROR::CODE)sqlite3_column_int(stmt,4));
212                         tempStr = (const char *)(sqlite3_column_text(stmt,5));
213                         if (tempStr)
214                                 arg = tempStr;
215                         else
216                                 arg = string();
217                         item->setTitle(arg);
218                         tempStr = (const char *)(sqlite3_column_text(stmt,6));
219                         if (tempStr)
220                                 arg = tempStr;
221                         else
222                                 arg = string();
223                         item->setRegisteredFilePath(arg);
224                         tempStr = (const char *)(sqlite3_column_text(stmt,7));
225                         if (tempStr)
226                                 url = tempStr;
227                         else
228                                 url = string();
229                         tempStr = (const char *)(sqlite3_column_text(stmt,8));
230                         if (tempStr)
231                                 cookie = tempStr;
232                         else
233                                 cookie = string();
234                         item->setFinishedTime(sqlite3_column_double(stmt,9));
235                         item->attachHistoryItem();
236                         item->setRetryData(url, cookie);
237                 } else
238                         break;
239         }
240         DP_LOGD("SQL error: %d", ret);
241
242         if (sqlite3_finalize(stmt) != SQLITE_OK)
243                 DP_LOGE("sqlite3_finalize is failed.");
244
245         close();
246
247         if (ret == SQLITE_DONE || ret == SQLITE_ROW)
248                 return true;
249         else
250                 return false;
251 }
252
253 bool DownloadHistoryDB::createItemsFromHistoryDB()
254 {
255         int ret = 0;
256         sqlite3_stmt *stmt = NULL;
257         string tmp;
258         stringstream limitStr;
259
260         DP_LOG_FUNC();
261
262         if (!open()) {
263                 DP_LOGE("historyDB is NULL");
264                 return false;
265         }
266         limitStr << LOAD_HISTORY_COUNT;
267         tmp.append("select historyid, downloadtype, contenttype, state, err, ");
268         tmp.append("name, path, url, cookie, date from history order by ");
269         tmp.append("date DESC limit ");
270         tmp.append(limitStr.str());
271         ret = sqlite3_prepare_v2(historyDb, tmp.c_str(), -1, &stmt, NULL);
272         if (ret != SQLITE_OK)
273                 FINALIZE_ON_ERROR(stmt);
274
275         for (;;) {
276                 ret = sqlite3_step(stmt);
277                 if (ret == SQLITE_ROW) {
278                         const char *tempStr = NULL;
279                         string arg = string();
280                         string url = string();
281                         string cookie = string();
282                         Item *item = Item::createHistoryItem();
283                         if (!item) {
284                                 DP_LOGE("Fail to create item");
285                                 break;
286                         }
287                         item->setHistoryId(sqlite3_column_int(stmt,0));
288                         item->setDownloadType((DL_TYPE::TYPE)sqlite3_column_int(stmt,1));
289                         item->setContentType(sqlite3_column_int(stmt,2));
290                         item->setState((ITEM::STATE)sqlite3_column_int(stmt,3));
291                         item->setErrorCode((ERROR::CODE)sqlite3_column_int(stmt,4));
292                         tempStr = (const char *)(sqlite3_column_text(stmt,5));
293                         if (tempStr) {
294                                 arg = tempStr;
295                                 item->setTitle(arg);
296                         }
297                         tempStr = (const char *)(sqlite3_column_text(stmt,6));
298                         if (tempStr)
299                                 arg = tempStr;
300                         item->setRegisteredFilePath(arg);
301                         tempStr = (const char *)(sqlite3_column_text(stmt,7));
302                         if (tempStr)
303                                 url = tempStr;
304                         tempStr = (const char *)(sqlite3_column_text(stmt,8));
305                         if (tempStr)
306                                 cookie = tempStr;
307                         item->setFinishedTime(sqlite3_column_double(stmt,9));
308                         item->attachHistoryItem();
309                         item->setRetryData(url, cookie);
310                 } else
311                         break;
312         }
313         DP_LOGD("SQL error: %d", ret);
314
315         if (sqlite3_finalize(stmt) != SQLITE_OK)
316                 DP_LOGE("sqlite3_finalize is failed.");
317         close();
318
319         if (ret == SQLITE_DONE || ret == SQLITE_ROW)
320                 return true;
321         else
322                 return false;
323 }
324
325 bool DownloadHistoryDB::deleteItem(unsigned int historyId)
326 {
327         int ret = 0;
328         sqlite3_stmt *stmt = NULL;
329
330         DP_LOG_FUNC();
331
332         if (!open()) {
333                 DP_LOGE("historyDB is NULL");
334                 return false;
335         }
336
337         ret = sqlite3_prepare_v2(historyDb, "delete from history where historyid=?",
338                 -1, &stmt, NULL);
339
340         if (ret != SQLITE_OK)
341                 FINALIZE_ON_ERROR(stmt);
342         if (sqlite3_bind_int(stmt, 1, historyId) != SQLITE_OK)
343                 DP_LOGE("sqlite3_bind_int is failed.");
344         ret = sqlite3_step(stmt);
345         if (ret != SQLITE_OK && ret != SQLITE_DONE)
346                 FINALIZE_ON_ERROR(stmt);
347
348         if (sqlite3_finalize(stmt) != SQLITE_OK)
349                 DP_LOGE("sqlite3_finalize is failed.");
350         close();
351         return true;
352 }
353
354 bool DownloadHistoryDB::deleteMultipleItem(queue <unsigned int> &q)
355 {
356         int ret = 0;
357         unsigned int historyId = -1;
358         sqlite3_stmt *stmt = NULL;
359         char *errmsg = NULL;
360
361         DP_LOG_FUNC();
362
363         if (!open()) {
364                 DP_LOGE("historyDB is NULL");
365                 return false;
366         }
367         ret = sqlite3_exec(historyDb, "PRAGMA synchronous=OFF;\
368                 PRAGMA count_changes=OFF; PRAGMA temp_store=memory;",
369                 NULL, NULL, &errmsg);
370         if (SQLITE_OK != ret) {
371                 sqlite3_free(errmsg);
372                 close();
373                 return false;
374         }
375
376         DP_LOGD("queue size[%d]",q.size());
377         while (!q.empty()) {
378                 ret = sqlite3_prepare_v2(historyDb, "delete from history where historyid=?",
379                         -1, &stmt, NULL);
380                 if (ret != SQLITE_OK)
381                         FINALIZE_ON_ERROR(stmt);
382                 historyId = q.front();
383                 q.pop();
384                 if (sqlite3_bind_int(stmt, 1, historyId) != SQLITE_OK)
385                         DP_LOGE("sqlite3_bind_int is failed.");
386                 ret = sqlite3_step(stmt);
387                 if (ret != SQLITE_OK && ret != SQLITE_DONE)
388                         FINALIZE_ON_ERROR(stmt);
389         }
390
391         if (sqlite3_finalize(stmt) != SQLITE_OK)
392                 DP_LOGE("sqlite3_finalize is failed.");
393         close();
394         return true;
395 }
396
397 bool DownloadHistoryDB::clearData(void)
398 {
399         int ret = 0;
400         sqlite3_stmt *stmt = NULL;
401
402         DP_LOG_FUNC();
403
404         if (!open()) {
405                 DP_LOGE("historyDB is NULL");
406                 return false;
407         }
408
409         ret = sqlite3_prepare_v2(historyDb, "delete from history", -1, &stmt, NULL);
410         if (ret != SQLITE_OK)
411                 FINALIZE_ON_ERROR(stmt);
412
413         ret = sqlite3_step(stmt);
414         if (ret != SQLITE_DONE)
415                 FINALIZE_ON_ERROR(stmt);
416
417         if (sqlite3_finalize(stmt) != SQLITE_OK)
418                 DP_LOGE("sqlite3_finalize is failed.");
419         close();
420         return true;
421 }
422