Remove using removed vconf key
[platform/core/appfw/pkgmgr-info.git] / parser / pkgmgr_parser_resource_db.c
1 /*
2  * pkgmgr-info
3  *
4  * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7  * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <unistd.h>
29 #include <db-util.h>
30 #include <glib.h>
31 #include <dlfcn.h>
32 #include <bundle.h>
33
34 #include "pkgmgr-info.h"
35 #include "pkgmgr-info-debug.h"
36 #include "pkgmgr_parser_db.h"
37 #include "pkgmgr_parser_internal.h"
38 #include "pkgmgr_parser_resource.h"
39 #include "pkgmgr_parser_resource_db.h"
40
41 #ifdef LOG_TAG
42 #undef LOG_TAG
43 #endif
44
45 #define LOG_TAG "PKGMGR_PARSER"
46
47 #define BUF_SIZE 1024
48 #define PKGMGR_PARSER_DB_FILE tzplatform_mkpath(TZ_USER_DB, ".pkgmgr_parser.db")
49
50 enum {
51         NODE_ATTR_MIN = 0,
52         NODE_ATTR_SCREEN_DPI,
53         NODE_ATTR_SCREEN_DPI_RANGE,
54         NODE_ATTR_SCREEN_WIDTH_RANGE,
55         NODE_ATTR_SCREEN_LARGE,
56         NODE_ATTR_SCREEN_BPP,
57         NODE_ATTR_PLATFORM_VER,
58         NODE_ATTR_LANGUAGE,
59         NODE_ATTR_MAX,
60 };
61
62 static int _get_attr_val(bundle *b, char **attr_name, const char **attr_val, int attr_index)
63 {
64         char *buf = NULL;
65         if (b == NULL) {
66                 _LOGE("bundle is null");
67                 return PMINFO_R_EINVAL;
68         }
69
70         buf = malloc(BUF_SIZE);
71         if (buf == NULL) {
72                 _LOGE("malloc failed");
73                 return PMINFO_R_ERROR;
74         }
75         memset(buf, '\0', BUF_SIZE);
76         switch (attr_index) {
77         case NODE_ATTR_SCREEN_DPI:
78                 snprintf(buf, BUF_SIZE, "%s", RSC_NODE_ATTR_SCREEN_DPI);
79                 *attr_val = bundle_get_val(b, RSC_NODE_ATTR_SCREEN_DPI);
80                 break;
81         case NODE_ATTR_SCREEN_DPI_RANGE:
82                 snprintf(buf, BUF_SIZE, "%s", RSC_NODE_ATTR_SCREEN_DPI_RANGE);
83                 *attr_val = bundle_get_val(b, RSC_NODE_ATTR_SCREEN_DPI_RANGE);
84                 break;
85         case NODE_ATTR_SCREEN_WIDTH_RANGE:
86                 snprintf(buf, BUF_SIZE, "%s", RSC_NODE_ATTR_SCREEN_WIDTH_RANGE);
87                 *attr_val = bundle_get_val(b, RSC_NODE_ATTR_SCREEN_WIDTH_RANGE);
88                 break;
89         case NODE_ATTR_SCREEN_LARGE:
90                 snprintf(buf, BUF_SIZE, "%s", RSC_NODE_ATTR_SCREEN_LARGE);
91                 *attr_val = bundle_get_val(b, RSC_NODE_ATTR_SCREEN_LARGE);
92                 break;
93         case NODE_ATTR_SCREEN_BPP:
94                 snprintf(buf, BUF_SIZE, "%s", RSC_NODE_ATTR_SCREEN_BPP);
95                 *attr_val = bundle_get_val(b, RSC_NODE_ATTR_SCREEN_BPP);
96                 break;
97         case NODE_ATTR_PLATFORM_VER:
98                 snprintf(buf, BUF_SIZE, "%s", RSC_NODE_ATTR_PLATFORM_VER);
99                 *attr_val = bundle_get_val(b, RSC_NODE_ATTR_PLATFORM_VER);
100                 break;
101         case NODE_ATTR_LANGUAGE:
102                 snprintf(buf, BUF_SIZE, "%s", RSC_NODE_ATTR_LANGUAGE);
103                 *attr_val = bundle_get_val(b, RSC_NODE_ATTR_LANGUAGE);
104                 break;
105         default:
106                 _LOGE("unidentified index[%d]", attr_index);
107                 free(buf);
108                 buf = NULL;
109                 return PMINFO_R_ERROR;
110         }
111
112         if (buf != NULL && strlen(buf) != 0)
113                 *attr_name = buf;
114
115         return PMINFO_R_OK;
116 }
117
118 static int _insert_node_data_into_db(sqlite3 *pkginfo, const char *package, char *group_type, GList *node_list)
119 {
120         char *query = NULL;
121         resource_node_t *rsc_node = NULL;
122         GList *tmp_node_list = NULL;
123         bundle *b = NULL;
124         const char *attr_val = NULL;
125         char *attr_name = NULL;
126         int i;
127         int ret = -1;
128
129         if (pkginfo == NULL || package == NULL || strlen(package) == 0 || group_type == NULL || strlen(group_type) == 0 || node_list == NULL)
130                 return PMINFO_R_EINVAL;
131
132         tmp_node_list = g_list_first(node_list);
133
134         if (tmp_node_list == NULL) {
135                 _LOGE("list is null");
136                 return PMINFO_R_ERROR;
137         }
138
139         while (tmp_node_list != NULL) {
140                 rsc_node = (resource_node_t *)tmp_node_list->data;
141                 if (rsc_node == NULL) {
142                         _LOGE("node is null");
143                         return PMINFO_R_ERROR;
144                 }
145
146                 /*get bundle for each nodes*/
147                 b = rsc_node->attr;
148                 if (b == NULL) {
149                         _LOGE("bundle is null");
150                         return PMINFO_R_ERROR;
151                 }
152
153                 for (i = NODE_ATTR_MIN + 1; i < NODE_ATTR_MAX; i++) {
154                         ret = _get_attr_val(b, &attr_name, &attr_val, i);
155                         if (ret != 0) {
156                                 _LOGE("get attribute from bundle failed");
157                                 return ret;
158                         }
159
160                         if (attr_name == NULL || attr_val == NULL)
161                                 continue;
162                         query = sqlite3_mprintf("insert into package_resource_data(id, node_folder, attr_name, attr_value) VALUES(" \
163                                 "(select rowid from package_resource_info where pkg_id=%Q and group_type=%Q), %Q, %Q, %Q)", package, group_type, rsc_node->folder, attr_name, attr_val);
164
165                         /*Begin transaction*/
166                         ret = sqlite3_exec(pkginfo, query, NULL, NULL, NULL);
167                         if (ret != SQLITE_OK)
168                                 _LOGE("Failed to insert into package_resource_data, attr_name[%s], attr_val[%s]", attr_name, attr_val);
169                         sqlite3_free(query);
170                         query = NULL;
171                         free(attr_name);
172                         attr_name = NULL;
173                         attr_val = NULL;
174                 }
175                 tmp_node_list = g_list_next(tmp_node_list);
176         }
177
178         return ret;
179 }
180
181 int pkgmgr_parser_resource_db_remove(const char *package)
182 {
183         sqlite3 *pkginfo = NULL;
184         char *query = NULL;
185         int ret = -1;
186
187         if (package == NULL) {
188                 _LOGE("parameter is NULL");
189                 return PMINFO_R_EINVAL;
190         }
191
192         /*db open*/
193         ret = db_util_open(PKGMGR_PARSER_DB_FILE, &pkginfo, 0);
194         retvm_if(ret != SQLITE_OK, PMINFO_R_ERROR, "connect db [%s] failed!", PKGMGR_PARSER_DB_FILE);
195
196         /*Begin transaction*/
197         ret = sqlite3_exec(pkginfo, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
198         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Failed to begin transaction\n");
199         _LOGD("Transaction Begin\n");
200
201         /*delete data from package_resource_data*/
202         query = sqlite3_mprintf("delete from package_resource_data where id in (select rowid from package_resource_info where pkg_id=%Q)", package);
203         ret = sqlite3_exec(pkginfo, query, NULL, NULL, NULL);
204         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Failed to delete from package_resource_info");
205         sqlite3_free(query);
206         query = NULL;
207
208         /*delete data from package_resource_info*/
209         query = sqlite3_mprintf("delete from package_resource_info where pkg_id=%Q", package);
210         ret = sqlite3_exec(pkginfo, query, NULL, NULL, NULL);
211         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Failed to delete from package_resource_info");
212
213         /*Commit transaction*/
214         ret = sqlite3_exec(pkginfo, "COMMIT", NULL, NULL, NULL);
215         if (ret != SQLITE_OK) {
216                 _LOGE("Failed to commit transaction. Rollback now\n");
217                 ret = sqlite3_exec(pkginfo, "ROLLBACK", NULL, NULL, NULL);
218                 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
219         }
220         _LOGD("Transaction Commit and End\n");
221
222         ret = PMINFO_R_OK;
223 catch:
224         sqlite3_close(pkginfo);
225         sqlite3_free(query);
226
227         return ret;
228 }
229
230 int pkgmgr_parser_resource_db_save(const char *package, resource_data_t *data)
231 {
232         sqlite3 *pkginfo = NULL;
233         char *query = NULL;
234         int ret = -1;
235         GList *group_list = NULL;
236         GList *node_list = NULL;
237         resource_group_t *rsc_group = NULL;
238
239         if (package == NULL || strlen(package) == 0 || data == NULL) {
240                 _LOGE("invalid parameter");
241                 return -1;
242         }
243
244         ret = pkgmgr_parser_check_and_create_db(getuid());
245         if (ret == 0)
246                 ret = pkgmgr_parser_initialize_db();
247         if (ret < 0) {
248                 _LOGE("db initialization failed");
249                 goto catch;
250         }
251
252
253         group_list = g_list_first(data->group_list);
254         /*db open*/
255         ret = db_util_open(PKGMGR_PARSER_DB_FILE, &pkginfo, 0);
256         retvm_if(ret != SQLITE_OK, PMINFO_R_ERROR, "connect db [%s] failed!", PKGMGR_PARSER_DB_FILE);
257
258         /*Begin transaction*/
259         ret = sqlite3_exec(pkginfo, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
260         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Failed to begin transaction\n");
261         _LOGD("Transaction Begin\n");
262
263         while (group_list != NULL) {
264                 rsc_group = NULL;
265                 node_list = NULL;
266
267                 rsc_group = (resource_group_t *)group_list->data;
268                 node_list = g_list_first(rsc_group->node_list);
269
270                 if (rsc_group == NULL || node_list == NULL) {
271                         _LOGE("value is null");
272                         ret = -1;
273                         goto catch;
274                 }
275
276                 query = sqlite3_mprintf("insert into package_resource_info(pkg_id, group_folder, group_type) VALUES(%Q, %Q, %Q)", \
277                         package, rsc_group->folder, rsc_group->type);
278
279                 /*Begin transaction*/
280                 ret = sqlite3_exec(pkginfo, query, NULL, NULL, NULL);
281                 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Failed to insert into package_resource_info");
282                 sqlite3_free(query);
283                 query = NULL;
284
285                 ret = _insert_node_data_into_db(pkginfo, package, rsc_group->type, node_list);
286
287                 group_list = g_list_next(group_list);
288         }
289
290         /*Commit transaction*/
291         ret = sqlite3_exec(pkginfo, "COMMIT", NULL, NULL, NULL);
292         if (ret != SQLITE_OK) {
293                 _LOGE("Failed to commit transaction. Rollback now\n");
294                 ret = sqlite3_exec(pkginfo, "ROLLBACK", NULL, NULL, NULL);
295                 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
296         }
297         _LOGD("Transaction Commit and End\n");
298
299         ret = PMINFO_R_OK;
300
301
302 catch:
303         pkgmgr_parser_close_db();
304         sqlite3_close(pkginfo);
305         sqlite3_free(query);
306
307         return ret;
308
309 }
310
311 static gint _find_group_type(void *group, void *data)
312 {
313         resource_group_t *rsc_group = (resource_group_t *)group;
314
315         return strcmp(rsc_group->type, (char *)data);
316 }
317
318 static gint _find_node_folder(void *node, void *data)
319 {
320         resource_node_t *rsc_node = (resource_node_t *)node;
321         char *str = (char *)data;
322
323         return strcmp(rsc_node->folder, str);
324 }
325
326 static int _init_node(char *node_folder, resource_node_t **rsc_node)
327 {
328         resource_node_t *tmp_node = NULL;
329
330         if (node_folder == NULL) {
331                 _LOGE("invalid parameter");
332                 return PMINFO_R_EINVAL;
333         }
334
335         tmp_node = malloc(sizeof(resource_node_t));
336         if (tmp_node == NULL) {
337                 _LOGE("malloc failed");
338                 return PMINFO_R_ERROR;
339         }
340
341         tmp_node->folder = strdup(node_folder);
342         tmp_node->attr = bundle_create();
343         *rsc_node = tmp_node;
344
345         return PMINFO_R_OK;
346 }
347
348 static int _init_group(char *group_type, resource_group_t **rsc_group)
349 {
350         resource_group_t *tmp_group = NULL;
351
352         if (group_type == NULL) {
353                 _LOGE("invalid parameter");
354                 return PMINFO_R_EINVAL;
355         }
356
357         tmp_group = malloc(sizeof(resource_group_t));
358         if (tmp_group == NULL) {
359                 _LOGE("malloc failed");
360                 return PMINFO_R_ERROR;
361         }
362
363         tmp_group->type = strdup(group_type);
364         tmp_group->node_list = NULL;
365         *rsc_group = tmp_group;
366
367         return PMINFO_R_OK;
368 }
369
370 int pkgmgr_parser_resource_db_load(const char *package, resource_data_t **data)
371 {
372         sqlite3 *pkginfo = NULL;
373         sqlite3_stmt *stmt = NULL;
374         char *query = NULL;
375         char *colname = NULL;
376         char *group_type = NULL;
377         char *group_folder = NULL;
378         char *node_folder = NULL;
379         char *attr_name = NULL;
380         char *attr_value = NULL;
381         int ret = -1;
382         int cols = 0;
383         int i;
384         resource_data_t *rsc_data = NULL;
385         resource_group_t *rsc_group = NULL;
386         resource_node_t *rsc_node = NULL;
387         GList *group_list = NULL;
388         GList *node_list = NULL;
389         GList *tmp_group_list = NULL;
390         GList *tmp_node_list = NULL;
391
392         ret = db_util_open(PKGMGR_PARSER_DB_FILE, &pkginfo, 0);
393         retvm_if(ret != SQLITE_OK, PMINFO_R_ERROR, "connect db [%s] failed!", PKGMGR_PARSER_DB_FILE);
394         query = sqlite3_mprintf("select " \
395                 "package_resource_info.group_type, package_resource_info.group_folder, package_resource_data.node_folder, package_resource_data.attr_name, package_resource_data.attr_value " \
396                 "from package_resource_info, package_resource_data where " \
397                 "package_resource_info.rowid=package_resource_data.id and " \
398                 "package_resource_info.pkg_id=%Q order by package_resource_data.rowid asc", \
399                 package);
400         ret = sqlite3_prepare_v2(pkginfo, query, strlen(query), &stmt, NULL);
401         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "sqlite3_prepare_v2 query = %s\n", query);
402         cols = sqlite3_column_count(stmt);
403
404         while (1) {
405                 ret = sqlite3_step(stmt);
406                 if (ret != SQLITE_ROW)
407                         break;
408                 tmp_group_list = NULL;
409                 tmp_node_list = NULL;
410                 rsc_group = NULL;
411                 rsc_node = NULL;
412
413                 for (i = 0; i < cols; i++) {
414                         colname = (char *)sqlite3_column_name(stmt, i);
415                         if (strcmp(colname, "group_type") == 0) {
416                                 /*group_type*/
417                                 group_type = (char *)sqlite3_column_text(stmt, i);
418                                 tmp_group_list = g_list_find_custom(group_list, group_type, (GCompareFunc)_find_group_type);
419                                 if (tmp_group_list == NULL) {
420                                         ret = _init_group(group_type, &rsc_group);
421                                         if (ret != PMINFO_R_OK) {
422                                                 _LOGE("group initialization failed[%d]", ret);
423                                                 goto catch;
424                                         }
425                                         group_list = g_list_append(group_list, rsc_group);
426                                         node_list = NULL;
427                                 } else {
428                                         rsc_group = (resource_group_t *)tmp_group_list->data;
429                                         node_list = rsc_group->node_list;
430                                 }
431                         } else if (strcmp(colname, "group_folder") == 0) {
432                                 /*group_folder*/
433                                 group_folder = (char *)sqlite3_column_text(stmt, i);
434                                 if (rsc_group->folder != NULL && strcmp(rsc_group->folder, group_folder) == 0)
435                                         continue;
436                                 else if (rsc_group != NULL && group_folder != NULL)
437                                         rsc_group->folder = strdup(group_folder);
438                                 else {
439                                         _LOGE("rsc_group and group_folder should not be null");
440                                         ret = PMINFO_R_ERROR;
441                                         goto catch;
442                                 }
443                         } else if (strcmp(colname, "node_folder") == 0) {
444                                 /*node_folder*/
445                                 node_folder = (char *)sqlite3_column_text(stmt, i);
446                                 tmp_node_list = g_list_find_custom(node_list, node_folder, (GCompareFunc)_find_node_folder);
447                                 if (tmp_node_list == NULL) {
448                                         ret = _init_node(node_folder, &rsc_node);
449                                         /*initialize new node*/
450                                         if (ret != PMINFO_R_OK) {
451                                                 _LOGE("node initialization failed[%d]", ret);
452                                                 goto catch;
453                                         }
454                                         node_list = g_list_append(node_list, rsc_node);
455                                         if (rsc_group->node_list == NULL)
456                                                 rsc_group->node_list = node_list;
457                                 } else
458                                         rsc_node = (resource_node_t *)tmp_node_list->data;
459                         } else if (strcmp(colname, "attr_name") == 0) {
460                                 /*attr_name*/
461                                 attr_name = (char *)sqlite3_column_text(stmt, i);
462                         } else if (strcmp(colname, "attr_value") == 0) {
463                                 /*attr_value*/
464                                 attr_value = (char *)sqlite3_column_text(stmt, i);
465                                 if (rsc_node != NULL && attr_name != NULL && attr_value != NULL) {
466                                         if (rsc_node->attr != NULL)
467                                                 bundle_add(rsc_node->attr, attr_name, attr_value);
468                                         else {
469                                                 _LOGE("bundle is not initialized");
470                                                 ret = PMINFO_R_ERROR;
471                                                 goto catch;
472                                         }
473                                 } else {
474                                         _LOGE("error happened");
475                                         ret = PMINFO_R_ERROR;
476                                         goto catch;
477                                 }
478                         } else {
479                                 /*error handling*/
480                                 _LOGE("unexpected column name detected:[%s]", colname);
481                                 ret = PMINFO_R_ERROR;
482                                 goto catch;
483                         }
484                 }
485         }
486         if (ret == SQLITE_DONE)
487                 ret = PMINFO_R_OK;
488
489         rsc_data = malloc(sizeof(resource_data_t));
490         if (rsc_data == NULL) {
491                 _LOGD("malloc failed");
492                 ret = PMINFO_R_ERROR;
493                 goto catch;
494         }
495         rsc_data->group_list = group_list;
496         rsc_data->package = strdup(package);
497         /*set return data*/
498         *data = rsc_data;
499 catch:
500         sqlite3_close(pkginfo);
501         sqlite3_free(query);
502
503         return ret;
504 }