Rewrite db operation code
[platform/core/appfw/librua.git] / src / rua_internal.c
1 /*
2  * Copyright (c) 2016 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 #include <stdio.h>
18 #include <sys/types.h>
19 #include <unistd.h>
20
21 #include <aul.h>
22 #include <dlog.h>
23 #include <sqlite3.h>
24
25 #include "rua_internal.h"
26 #include "db-schema.h"
27 #include "rua_util.h"
28 #include "rua_dbus.h"
29 #include "rua_private.h"
30
31 static int __exec(sqlite3 *db, char *query)
32 {
33         int r;
34         char *errmsg = NULL;
35
36         if (db == NULL)
37                 return -1;
38
39         r = sqlite3_exec(db, query, NULL, NULL, &errmsg);
40
41         if (r != SQLITE_OK) {
42                 sqlite3_free(errmsg);
43                 return -1;
44         }
45
46         return 0;
47 }
48
49 static int __create_table(sqlite3 *db)
50 {
51         int r;
52
53         r = __exec(db, CREATE_RUA_HISTORY_TABLE);
54         if (r == -1)
55                 return -1;
56
57         return 0;
58 }
59
60 static sqlite3 *__db_init(uid_t uid)
61 {
62         int r;
63         sqlite3 *db = NULL;
64
65         r = _rua_util_open_db(&db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
66                         uid, RUA_DB_NAME);
67         if (r != SQLITE_OK)
68                 return NULL;
69
70         r = __create_table(db);
71         if (r) {
72                 sqlite3_close_v2(db);
73                 return NULL;
74         }
75
76         return db;
77 }
78
79 static int __delete_history_with_pkg_name(sqlite3 *db, const char *pkg_name,
80                 const char *instance_id)
81 {
82         static const char query[] =
83                 "DELETE FROM rua_history WHERE pkg_name=? AND instance_id=?";
84         sqlite3_stmt *stmt;
85         int r;
86         int idx = 1;
87
88         r = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
89         if (r != SQLITE_OK) {
90                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
91                 sqlite3_close_v2(db);
92                 return -1;
93         }
94
95         __BIND_TEXT(db, stmt, idx++, pkg_name);
96         __BIND_TEXT(db, stmt, idx++, instance_id);
97
98         r = sqlite3_step(stmt);
99         if (r != SQLITE_DONE) {
100                 LOGE("step failed: %s", sqlite3_errmsg(db));
101                 sqlite3_finalize(stmt);
102                 return -1;
103         }
104
105         sqlite3_finalize(stmt);
106
107         return 0;
108 }
109
110 static int __delete_history_with_app_path(sqlite3 *db, const char *app_path,
111                 const char *instance_id)
112 {
113         static const char query[] =
114                 "DELETE FROM rua_history WHERE app_path=? AND instance_id=?";
115         sqlite3_stmt *stmt;
116         int r;
117         int idx = 1;
118
119         r = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
120         if (r != SQLITE_OK) {
121                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
122                 sqlite3_close_v2(db);
123                 return -1;
124         }
125
126         __BIND_TEXT(db, stmt, idx++, app_path);
127         __BIND_TEXT(db, stmt, idx++, instance_id);
128
129         r = sqlite3_step(stmt);
130         if (r != SQLITE_DONE) {
131                 LOGE("step failed: %s", sqlite3_errmsg(db));
132                 sqlite3_finalize(stmt);
133                 return -1;
134         }
135
136         sqlite3_finalize(stmt);
137
138         return 0;
139 }
140
141 API int rua_usr_db_delete_history(bundle *b, uid_t uid)
142 {
143         int r;
144         sqlite3 *db;
145         char *pkg_name = NULL;
146         char *app_path = NULL;
147         char *instance_id = NULL;
148
149         db = __db_init(uid);
150         if (db == NULL) {
151                 LOGE("Error db null");
152                 return -1;
153         }
154
155         if (b != NULL) {
156                 bundle_get_str(b, AUL_K_RUA_PKGNAME, &pkg_name);
157                 bundle_get_str(b, AUL_K_RUA_APPPATH, &app_path);
158                 bundle_get_str(b, AUL_K_RUA_INSTANCE_ID, &instance_id);
159         }
160
161         if (pkg_name) {
162                 LOGI("rua_delete_history_from_db : %s", pkg_name);
163                 r = __delete_history_with_pkg_name(db, pkg_name, instance_id);
164         } else if (app_path) {
165                 LOGI("rua_delete_history_from_db : %s", app_path);
166                 r = __delete_history_with_app_path(db, app_path, instance_id);
167         } else {
168                 LOGE("No data to delete history");
169                 return -1;
170         }
171
172         sqlite3_close_v2(db);
173
174         r = rua_dbus_send_update_signal(DELETE);
175         if (r == -1) {
176                 LOGE("[RUA SEND SIGNAL ERROR] \n");
177                 return -1;
178         }
179
180         return 0;
181 }
182
183 API int rua_db_delete_history(bundle *b)
184 {
185         return rua_usr_db_delete_history(b, getuid());
186 }
187
188 static int __insert_history(sqlite3 *db, struct rua_rec *rec)
189 {
190         static const char query[] =
191                 "INSERT OR REPLACE INTO rua_history ("
192                 "  pkg_name, app_path, arg, launch_time,"
193                 "  instance_id, instance_name, icon, uri) "
194                 "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
195         int r;
196         sqlite3_stmt *stmt;
197         int idx = 1;
198
199         r = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
200         if (r != SQLITE_OK) {
201                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
202                 return -1;
203         }
204
205         __BIND_TEXT(db, stmt, idx++, rec->pkg_name);
206         __BIND_TEXT(db, stmt, idx++, rec->app_path);
207         __BIND_TEXT(db, stmt, idx++, rec->arg ? rec->arg : "");
208         __BIND_INT(db, stmt, idx++, (int)rec->launch_time);
209         __BIND_TEXT(db, stmt, idx++, rec->instance_id ? rec->instance_id : "");
210         __BIND_TEXT(db, stmt, idx++,
211                         rec->instance_name ? rec->instance_name : "");
212         __BIND_TEXT(db, stmt, idx++, rec->icon ? rec->icon : "");
213         __BIND_TEXT(db, stmt, idx++, rec->uri ? rec->uri : "");
214
215         r = sqlite3_step(stmt);
216         if (r != SQLITE_DONE) {
217                 LOGE("step failed: %s", sqlite3_errmsg(db));
218                 sqlite3_finalize(stmt);
219                 return -1;
220         }
221
222         sqlite3_finalize(stmt);
223
224         return 0;
225 }
226
227 static int __update_history(sqlite3 *db, struct rua_rec *rec)
228 {
229         static const char query[] =
230                 "UPDATE rua_history SET launch_time=? "
231                 "WHERE pkg_name=? AND instance_id=?";
232         int r;
233         sqlite3_stmt *stmt;
234         int idx = 1;
235
236         r = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
237         if (r != SQLITE_OK) {
238                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
239                 return -1;
240         }
241
242         __BIND_INT(db, stmt, idx++, (int)rec->launch_time);
243         __BIND_TEXT(db, stmt, idx++, rec->pkg_name);
244         __BIND_TEXT(db, stmt, idx++, rec->instance_id);
245
246         r = sqlite3_step(stmt);
247         if (r != SQLITE_DONE) {
248                 LOGE("step failed: %s", sqlite3_errmsg(db));
249                 sqlite3_finalize(stmt);
250                 return -1;
251         }
252
253         sqlite3_finalize(stmt);
254
255         return 0;
256 }
257
258 API int rua_usr_db_add_history(struct rua_rec *rec, uid_t uid)
259 {
260         int r;
261         sqlite3 *db;
262
263         if (rec == NULL || rec->pkg_name == NULL || rec->app_path == NULL) {
264                 LOGE("Invalid parameter");
265                 return -1;
266         }
267
268         db = __db_init(uid);
269         if (db == NULL) {
270                 LOGE("Error db null");
271                 return -1;
272         }
273
274         if (rec->instance_id &&
275                         (rec->instance_name == NULL || rec->icon == NULL ||
276                          rec->uri == NULL))
277                 r = __update_history(db, rec);
278         else
279                 r = __insert_history(db, rec);
280
281         r = rua_dbus_send_update_signal(ADD);
282         if (r == -1) {
283                 LOGE("[RUA SEND SIGNAL ERROR] \n");
284                 sqlite3_close_v2(db);
285                 return -1;
286         }
287
288         sqlite3_close_v2(db);
289         return r;
290 }
291
292 API int rua_db_add_history(struct rua_rec *rec)
293 {
294         return rua_usr_db_add_history(rec, getuid());
295 }