Rewrite certinfo apis
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_db.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <ctype.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <grp.h>
9 #include <dirent.h>
10 #include <libgen.h>
11
12 #include <sqlite3.h>
13
14 #include <tzplatform_config.h>
15 #include <db-util.h>
16
17 #include "pkgmgr-info.h"
18 #include "pkgmgrinfo_debug.h"
19 #include "pkgmgrinfo_private.h"
20 #include "pkgmgr_parser.h"
21 #include "pkgmgr_parser_internal.h"
22
23 #define QUERY_CREATE_TABLE_PACKAGE_CERT_INDEX_INFO \
24         "CREATE TABLE IF NOT EXISTS package_cert_index_info( " \
25         " cert_info TEXT UNIQUE, " \
26         " cert_id INTEGER PRIMARY_KEY, " \
27         " cert_ref_count INTEGER NOT NULL)"
28
29 #define QUERY_CREATE_TABLE_PACKAGE_CERT_INFO \
30         "CREATE TABLE IF NOT EXISTS package_cert_info( " \
31         " package TEXT PRIMARY KEY, " \
32         " author_root_cert INTEGER NOT NULL, " \
33         " author_im_cert INTEGER NOT NULL, " \
34         " author_signer_cert INTEGER NOT NULL, " \
35         " dist_root_cert INTEGER NOT NULL, " \
36         " dist_im_cert INTEGER NOT NULL, " \
37         " dist_signer_cert INTEGER NOT NULL, " \
38         " dist2_root_cert INTEGER NOT NULL, " \
39         " dist2_im_cert INTEGER NOT NULL, " \
40         " dist2_signer_cert INTEGER NOT NULL)"
41
42 #define QUERY_CREATE_TRIGGER_DELETE_CERT_INFO \
43         "CREATE TRIGGER IF NOT EXISTS delete_cert_info " \
44         "AFTER DELETE ON package_cert_info " \
45         "BEGIN" \
46         " UPDATE package_cert_index_info SET" \
47         "  cert_ref_count = cert_ref_count - 1" \
48         " WHERE cert_id = OLD.author_root_cert" \
49         "  OR cert_id = OLD.author_im_cert" \
50         "  OR cert_id = OLD.author_signer_cert" \
51         "  OR cert_id = OLD.dist_root_cert" \
52         "  OR cert_id = OLD.dist_im_cert" \
53         "  OR cert_id = OLD.dist_signer_cert" \
54         "  OR cert_id = OLD.dist2_root_cert" \
55         "  OR cert_id = OLD.dist2_im_cert" \
56         "  OR cert_id = OLD.dist2_signer_cert;" \
57         "END;"
58
59 #define QUERY_CREATE_TRIGGER_UPDATE_CERT_INDEX_INFO \
60         "CREATE TRIGGER IF NOT EXISTS update_cert_index_info " \
61         "AFTER UPDATE ON package_cert_index_info " \
62         "WHEN ((SELECT cert_ref_count FROM package_cert_index_info " \
63         "       WHERE cert_id = OLD.cert_id) = 0) "\
64         "BEGIN" \
65         " DELETE FROM package_cert_index_info WHERE cert_id = OLD.cert_id;" \
66         "END;"
67 __thread db_handle manifest_db;
68 __thread db_handle cert_db;
69
70 typedef int (*sqlite_query_callback)(void *data, int ncols, char **coltxt, char **colname);
71
72 static int _mkdir_for_user(const char* dir, uid_t uid, gid_t gid)
73 {
74         int ret;
75         char *fullpath;
76         char *subpath;
77
78         fullpath = strdup(dir);
79         if (fullpath == NULL)
80                 return -1;
81         subpath = dirname(fullpath);
82         if (strlen(subpath) > 1 && strcmp(subpath, fullpath) != 0) {
83                 ret = _mkdir_for_user(fullpath, uid, gid);
84                 if (ret == -1) {
85                         free(fullpath);
86                         return ret;
87                 }
88         }
89
90         ret = mkdir(dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
91         if (ret && errno != EEXIST) {
92                 free(fullpath);
93                 return ret;
94         } else if (ret && errno == EEXIST) {
95                 free(fullpath);
96                 return 0;
97         }
98
99         if (getuid() == ROOT_UID) {
100                 ret = chown(dir, uid, gid);
101                 if (ret == -1)
102                         _LOGE("FAIL : chown %s %d.%d, because %s", dir, uid,
103                                         gid, strerror(errno));
104         }
105
106         free(fullpath);
107
108         return 0;
109 }
110
111 static const char *_get_db_path(uid_t uid) {
112         const char *db_path = NULL;
113         if (uid != GLOBAL_USER && uid != ROOT_UID) {
114                 tzplatform_set_user(uid);
115                 db_path = tzplatform_getenv(TZ_USER_DB);
116                 tzplatform_reset_user();
117         } else {
118                 db_path = tzplatform_getenv(TZ_SYS_DB);
119         }
120         return db_path;
121 }
122
123 static int __attach_and_create_view(sqlite3 *handle, const char *db, const char *tables[], uid_t uid)
124 {
125         int i;
126         char *err;
127         char query[MAX_QUERY_LEN];
128
129         if (uid != GLOBAL_USER && uid != ROOT_UID) {
130                 snprintf(query, sizeof(query), "ATTACH DATABASE '%s' AS Global", db);
131                 if (SQLITE_OK != sqlite3_exec(handle, query, NULL, NULL, &err)) {
132                         _LOGD("Don't execute query = %s error message = %s\n", query, err);
133                         sqlite3_free(err);
134                         return SQLITE_ERROR;
135                 }
136         }
137
138         for (i = 0; tables[i]; i++) {
139                 if (uid != GLOBAL_USER && uid != ROOT_UID)
140                         snprintf(query, sizeof(query), "CREATE TEMP VIEW '%s' AS SELECT * \
141                                         FROM (SELECT *,0 AS for_all_users FROM main.'%s' UNION \
142                                         SELECT *,1 AS for_all_users FROM Global.'%s')",
143                                         tables[i], tables[i], tables[i]);
144                 else
145                         snprintf(query, sizeof(query), "CREATE TEMP VIEW '%s' AS SELECT * \
146                                         FROM (SELECT *,1 AS for_all_users FROM main.'%s')",
147                                         tables[i], tables[i]);
148                 if (SQLITE_OK != sqlite3_exec(handle, query, NULL, NULL, &err)) {
149                         _LOGD("Don't execute query = %s error message = %s\n", query, err);
150                         sqlite3_free(err);
151                 }
152         }
153
154         return SQLITE_OK;
155 }
156
157 static int __exec_db_query(sqlite3 *db, char *query, sqlite_query_callback callback, void *data)
158 {
159         char *error_message = NULL;
160         int ret = sqlite3_exec(db, query, callback, data, &error_message);
161         if (SQLITE_OK != ret) {
162                 _LOGE("Don't execute query = %s error message = %s   ret = %d\n", query,
163                        error_message, ret);
164                 sqlite3_free(error_message);
165                 return -1;
166         }
167         sqlite3_free(error_message);
168         return 0;
169 }
170
171 int _check_create_cert_db(sqlite3 *certdb)
172 {
173         int ret = 0;
174         ret = __exec_db_query(certdb, QUERY_CREATE_TABLE_PACKAGE_CERT_INDEX_INFO, NULL, NULL);
175         if (ret < 0)
176                 return ret;
177         ret = __exec_db_query(certdb, QUERY_CREATE_TABLE_PACKAGE_CERT_INFO, NULL, NULL);
178         if (ret < 0)
179                 return ret;
180         ret = __exec_db_query(certdb, QUERY_CREATE_TRIGGER_DELETE_CERT_INFO, NULL, NULL);
181         if (ret < 0)
182                 return ret;
183         ret = __exec_db_query(certdb, QUERY_CREATE_TRIGGER_UPDATE_CERT_INDEX_INFO, NULL, NULL);
184         return ret;
185 }
186 static gid_t _get_gid(const char *name)
187 {
188         char buf[BUFSIZE];
189         struct group entry;
190         struct group *ge;
191         int ret;
192
193         ret = getgrnam_r(name, &entry, buf, sizeof(buf), &ge);
194         if (ret || ge == NULL) {
195                 _LOGE("fail to get gid of %s", name);
196                 return -1;
197         }
198
199         return entry.gr_gid;
200 }
201
202 API const char *getIconPath(uid_t uid)
203 {
204         const char *path = NULL;
205         uid_t uid_caller = getuid();
206         gid_t gid = ROOT_UID;
207
208         if (uid != GLOBAL_USER && uid != ROOT_UID) {
209                 tzplatform_set_user(uid);
210                 path = tzplatform_mkpath(TZ_USER_ICONS, "/");
211                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
212                 tzplatform_reset_user();
213         } else {
214                 path = tzplatform_mkpath(TZ_SYS_RW_ICONS, "/");
215         }
216
217         // just allow certain users to create the icon directory if needed.
218         if (uid_caller == ROOT_UID || uid_caller == uid)
219                 _mkdir_for_user(path, uid, gid);
220
221         return path;
222 }
223
224 API const char *getUserPkgParserDBPath(void)
225 {
226         return getUserPkgParserDBPathUID(GLOBAL_USER);
227 }
228
229 API const char *getUserPkgParserDBPathUID(uid_t uid)
230 {
231         const char *pkgmgr_parser_db = NULL;
232         uid_t uid_caller = getuid();
233         gid_t gid = ROOT_UID;
234
235         if (uid != GLOBAL_USER && uid != ROOT_UID) {
236                 tzplatform_set_user(uid);
237                 pkgmgr_parser_db = tzplatform_mkpath(TZ_USER_DB, ".pkgmgr_parser.db");
238                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
239                 tzplatform_reset_user();
240         } else {
241                 pkgmgr_parser_db = tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_parser.db");
242         }
243
244         // just allow certain users to create the dbspace directory if needed.
245         if (uid_caller == ROOT_UID || uid_caller == uid) {
246                 const char *db_path = _get_db_path(uid);
247                 _mkdir_for_user(db_path, uid, gid);
248         }
249
250         return pkgmgr_parser_db;
251 }
252
253 API const char *getUserPkgCertDBPath(void)
254 {
255          return getUserPkgCertDBPathUID(GLOBAL_USER);
256 }
257
258 API const char *getUserPkgCertDBPathUID(uid_t uid)
259 {
260         const char *pkgmgr_cert_db = NULL;
261         uid_t uid_caller = getuid();
262         gid_t gid = ROOT_UID;
263
264         if (uid != GLOBAL_USER && uid != ROOT_UID) {
265                 tzplatform_set_user(uid);
266                 pkgmgr_cert_db = tzplatform_mkpath(TZ_USER_DB, ".pkgmgr_cert.db");
267                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
268                 tzplatform_reset_user();
269         } else {
270                 pkgmgr_cert_db = tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_cert.db");
271         }
272
273         // just allow certain users to create the dbspace directory if needed.
274         if (uid_caller == ROOT_UID || uid_caller == uid) {
275                 const char *db_path = _get_db_path(uid);
276                 _mkdir_for_user(db_path, uid, gid);
277         }
278
279         return pkgmgr_cert_db;
280 }
281
282 API const char *getUserDesktopPath(uid_t uid)
283 {
284         const char *path = NULL;
285         uid_t uid_caller = getuid();
286         gid_t gid = ROOT_UID;
287
288         if (uid != GLOBAL_USER && uid != ROOT_UID) {
289                 tzplatform_set_user(uid);
290                 path = tzplatform_mkpath(TZ_USER_DESKTOP, "/");
291                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
292                 tzplatform_reset_user();
293         } else {
294                 path = tzplatform_mkpath(TZ_SYS_RW_DESKTOP_APP, "/");
295         }
296
297         // just allow certain users to create the icon directory if needed.
298         if (uid_caller == ROOT_UID || uid_caller == uid)
299                 _mkdir_for_user(path, uid, gid);
300
301         return path;
302 }
303
304 API const char *getUserManifestPath(uid_t uid)
305 {
306         const char *path = NULL;
307         uid_t uid_caller = getuid();
308         gid_t gid = ROOT_UID;
309
310         if (uid != GLOBAL_USER && uid != ROOT_UID) {
311                 tzplatform_set_user(uid);
312                 path = tzplatform_mkpath(TZ_USER_PACKAGES, "/");
313                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
314                 tzplatform_reset_user();
315         } else {
316                 path = tzplatform_mkpath(TZ_SYS_RW_PACKAGES, "/");
317         }
318
319         // just allow certain users to create the icon directory if needed.
320         if (uid_caller == ROOT_UID || uid_caller == uid)
321                 _mkdir_for_user(path, uid, gid);
322
323         return path;
324 }
325
326 int __close_manifest_db(void)
327 {
328         if (manifest_db.ref) {
329                 if (--manifest_db.ref == 0)
330                         sqlite3_close(GET_DB(manifest_db));
331                 return 0;
332         }
333         return -1;
334 }
335
336 static const char *parserdb_tables[] = {
337         "package_app_app_category",
338         "package_app_info",
339         "package_app_app_control",
340         "package_app_localized_info",
341         "package_app_app_metadata",
342         "package_app_share_allowed",
343         "package_app_app_permission",
344         "package_app_share_request",
345         "package_info",
346         "package_app_data_control",
347         "package_localized_info",
348         "package_app_icon_section_info",
349         "package_privilege_info",
350         "package_app_image_info",
351         NULL
352 };
353
354 int __open_manifest_db(uid_t uid, bool readonly)
355 {
356         int ret;
357         const char *user_pkg_parser;
358         int flags;
359
360         if (manifest_db.ref) {
361                 manifest_db.ref ++;
362                 return 0;
363         }
364
365         user_pkg_parser = getUserPkgParserDBPathUID(uid);
366         if (access(user_pkg_parser, F_OK) != 0) {
367                 _LOGE("Manifest DB does not exists !!");
368                 return -1;
369         }
370
371         flags = readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE;
372         ret = db_util_open_with_options(user_pkg_parser, &GET_DB(manifest_db),
373                         flags, NULL);
374         retvm_if(ret != SQLITE_OK, -1, "connect db [%s] failed!\n",
375                         user_pkg_parser);
376         manifest_db.ref++;
377         if (readonly) {
378                 ret = __attach_and_create_view(GET_DB(manifest_db), MANIFEST_DB,
379                                 parserdb_tables, uid);
380                 retvm_if(ret != SQLITE_OK, -1, "attach db [%s] failed!\n",
381                                 user_pkg_parser);
382         }
383         return 0;
384 }
385
386 int __close_cert_db(void)
387 {
388         if (cert_db.ref) {
389                 if (--cert_db.ref == 0)
390                         sqlite3_close_v2(GET_DB(cert_db));
391                         return 0;
392         }
393         _LOGE("Certificate DB is already closed !!\n");
394         return -1;
395 }
396
397 static const char *certdb_tables[] = {
398         "package_cert_index_info",
399         "package_cert_info",
400         NULL
401 };
402
403 int __open_cert_db(uid_t uid, bool readonly)
404 {
405         int ret;
406         const char *user_cert_parser;
407         int flags;
408
409         if (cert_db.ref) {
410                 cert_db.ref ++;
411                 return 0;
412         }
413
414         user_cert_parser = getUserPkgCertDBPathUID(uid);
415         if (access(user_cert_parser, F_OK) != 0) {
416                 _LOGE("Cert DB does not exists !!");
417                 return -1;
418         }
419
420         flags = readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE;
421         ret = db_util_open_with_options(user_cert_parser, &GET_DB(cert_db),
422                         flags, NULL);
423         retvm_if(ret != SQLITE_OK, -1, "connect db [%s] failed!",
424                         user_cert_parser);
425         cert_db.ref++;
426         if (readonly) {
427                 ret = __attach_and_create_view(GET_DB(cert_db), CERT_DB,
428                                 certdb_tables, uid);
429                 retvm_if(ret != SQLITE_OK, -1, "attach db [%s] failed!",
430                                 user_cert_parser);
431         }
432         return 0;
433 }
434
435 void _save_column_int(sqlite3_stmt *stmt, int idx, int *i)
436 {
437         *i = sqlite3_column_int(stmt, idx);
438 }
439
440 void _save_column_str(sqlite3_stmt *stmt, int idx, const char **str)
441 {
442         const char *val;
443
444         val = (const char *)sqlite3_column_text(stmt, idx);
445         if (val)
446                 *str = strdup(val);
447 }
448
449 API int pkgmgrinfo_pkginfo_set_state_enabled(const char *pkgid, bool enabled)
450 {
451         /* Should be implemented later */
452         return 0;
453 }
454
455 API int pkgmgrinfo_appinfo_set_usr_state_enabled(const char *appid, bool enabled, uid_t uid)
456 {
457         int ret;
458         char query[MAX_QUERY_LEN] = {'\0'};
459         char *error_message;
460
461         retvm_if(appid == NULL, PMINFO_R_EINVAL, "appid is NULL\n");
462
463         /* Open db.*/
464         ret = __open_manifest_db(uid, false);
465         if (ret != SQLITE_OK) {
466                 _LOGE("connect db [%s] failed!\n", getUserPkgParserDBPathUID(uid));
467                 return PMINFO_R_ERROR;
468         }
469
470         /*Begin transaction*/
471         ret = sqlite3_exec(GET_DB(manifest_db), "BEGIN EXCLUSIVE", NULL, NULL, NULL);
472         if (ret != SQLITE_OK) {
473                 _LOGE("Failed to begin transaction\n");
474                 __close_manifest_db();
475                 return PMINFO_R_ERROR;
476         }
477         _LOGD("Transaction Begin\n");
478
479         memset(query, '\0', MAX_QUERY_LEN);
480         snprintf(query, MAX_QUERY_LEN,
481                 "update package_app_info set app_enabled='%s' where app_id='%s'", enabled?"true":"false", appid);
482
483         if (SQLITE_OK !=
484             sqlite3_exec(GET_DB(manifest_db), query, NULL, NULL, &error_message)) {
485                 _LOGE("Don't execute query = %s error message = %s\n", query,
486                        error_message);
487                 sqlite3_free(error_message);
488                 return PMINFO_R_ERROR;
489         }
490         sqlite3_free(error_message);
491
492         /*Commit transaction*/
493         ret = sqlite3_exec(GET_DB(manifest_db), "COMMIT", NULL, NULL, NULL);
494         if (ret != SQLITE_OK) {
495                 _LOGE("Failed to commit transaction. Rollback now\n");
496                 sqlite3_exec(GET_DB(manifest_db), "ROLLBACK", NULL, NULL, NULL);
497                 __close_manifest_db();
498                 return PMINFO_R_ERROR;
499         }
500         _LOGD("Transaction Commit and End\n");
501         __close_manifest_db();
502         return PMINFO_R_OK;
503 }
504
505 API int pkgmgrinfo_appinfo_set_state_enabled(const char *appid, bool enabled)
506 {
507         return pkgmgrinfo_appinfo_set_usr_state_enabled(appid, enabled, GLOBAL_USER);
508 }
509
510 API int pkgmgrinfo_appinfo_set_usr_default_label(const char *appid, const char *label, uid_t uid)
511 {
512         int ret;
513         char query[MAX_QUERY_LEN] = {'\0'};
514         char *error_message;
515
516         retvm_if(appid == NULL, PMINFO_R_EINVAL, "appid is NULL\n");
517
518         ret = __open_manifest_db(uid, false);
519         if (ret == -1) {
520                 _LOGE("Fail to open manifest DB\n");
521                 return PMINFO_R_ERROR;
522         }
523
524         /*Begin transaction*/
525         ret = sqlite3_exec(GET_DB(manifest_db), "BEGIN EXCLUSIVE", NULL, NULL, NULL);
526         if (ret != SQLITE_OK) {
527                 _LOGE("Failed to begin transaction\n");
528                 __close_manifest_db();
529                 return PMINFO_R_ERROR;
530         }
531         _LOGD("Transaction Begin\n");
532
533         memset(query, '\0', MAX_QUERY_LEN);
534         snprintf(query, MAX_QUERY_LEN,
535                 "update package_app_localized_info set app_label='%s' where app_id='%s' and app_locale='No Locale'", label, appid);
536
537         if (SQLITE_OK !=
538             sqlite3_exec(GET_DB(manifest_db), query, NULL, NULL, &error_message)) {
539                 _LOGE("Don't execute query = %s error message = %s\n", query,
540                        error_message);
541                 sqlite3_free(error_message);
542                 return PMINFO_R_ERROR;
543         }
544
545         /*Commit transaction*/
546         ret = sqlite3_exec(GET_DB(manifest_db), "COMMIT", NULL, NULL, NULL);
547         if (ret != SQLITE_OK) {
548                 _LOGE("Failed to commit transaction. Rollback now\n");
549                 sqlite3_exec(GET_DB(manifest_db), "ROLLBACK", NULL, NULL, NULL);
550                 __close_manifest_db();
551                 return PMINFO_R_ERROR;
552         }
553         _LOGD("Transaction Commit and End\n");
554         __close_manifest_db();
555         return PMINFO_R_OK;
556 }
557
558 API int pkgmgrinfo_appinfo_set_default_label(const char *appid, const char *label)
559 {
560         return pkgmgrinfo_appinfo_set_usr_default_label(appid, label, GLOBAL_USER);
561 }
562
563 API int pkgmgrinfo_appinfo_set_usr_guestmode_visibility(pkgmgrinfo_appinfo_h handle, uid_t uid, bool status)
564 {
565         const char *val;
566         int ret;
567         char query[MAX_QUERY_LEN] = {'\0'};
568         char *errmsg;
569         sqlite3 *pkgmgr_parser_db;
570
571         retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL\n");
572
573         pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
574         val = info->app_info->guestmode_visibility;
575         if (val) {
576                 ret = db_util_open_with_options(getUserPkgParserDBPathUID(uid), &pkgmgr_parser_db,
577                                 SQLITE_OPEN_READWRITE, NULL);
578                 if (ret != SQLITE_OK) {
579                         _LOGE("DB Open Failed\n");
580                         return PMINFO_R_ERROR;
581                 }
582
583                 /*TODO: Write to DB here*/
584                 if (status == true)
585                         snprintf(query, MAX_QUERY_LEN, "update package_app_info set app_guestmodevisibility = 'true' where app_id = '%s'", (char *)info->app_info->appid);
586                 else
587                         snprintf(query, MAX_QUERY_LEN, "update package_app_info set app_guestmodevisibility = 'false' where app_id = '%s'", (char *)info->app_info->appid);
588
589                 ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, &errmsg);
590                 sqlite3_close(pkgmgr_parser_db);
591                 if (ret != SQLITE_OK) {
592                         _LOGE("DB update [%s] failed, error message = %s\n", query, errmsg);
593                         free(errmsg);
594                         return PMINFO_R_ERROR;
595                 }
596         }
597         return PMINFO_R_OK;
598 }
599
600 API int pkgmgrinfo_appinfo_set_guestmode_visibility(pkgmgrinfo_appinfo_h handle, bool status)
601 {
602         return pkgmgrinfo_appinfo_set_usr_guestmode_visibility(handle, GLOBAL_USER, status);
603 }
604
605 API int pkgmgrinfo_pkginfo_set_usr_installed_storage(const char *pkgid, INSTALL_LOCATION location, uid_t uid)
606 {
607         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "pkgid is NULL\n");
608         int ret = -1;
609         int exist = 0;
610         sqlite3 *pkgmgr_parser_db = NULL;
611         char *query = NULL;
612
613         ret = db_util_open_with_options(getUserPkgParserDBPathUID(uid), &pkgmgr_parser_db,
614                         SQLITE_OPEN_READWRITE, NULL);
615         retvm_if(ret != SQLITE_OK, PMINFO_R_ERROR, "connect db failed!");
616
617         /*Begin transaction*/
618         // Setting Manifest DB
619         ret = sqlite3_exec(pkgmgr_parser_db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
620         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Failed to begin transaction\n");
621         _LOGD("Transaction Begin\n");
622
623         // pkgcakge_info table
624         query = sqlite3_mprintf("update package_info set installed_storage=%Q where package=%Q", location?"installed_external":"installed_internal", pkgid);
625
626         ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, NULL);
627         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
628         sqlite3_free(query);
629
630         // package_app_info table
631         query = sqlite3_mprintf("update package_app_info set app_installed_storage=%Q where package=%Q", location?"installed_external":"installed_internal", pkgid);
632
633         ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, NULL);
634         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
635
636         /*Commit transaction*/
637         ret = sqlite3_exec(pkgmgr_parser_db, "COMMIT", NULL, NULL, NULL);
638         if (ret != SQLITE_OK) {
639                 _LOGE("Failed to commit transaction. Rollback now\n");
640                 ret = sqlite3_exec(pkgmgr_parser_db, "ROLLBACK", NULL, NULL, NULL);
641                 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
642         }
643         _LOGD("Transaction Commit and End\n");
644
645         ret = PMINFO_R_OK;
646 catch:
647         sqlite3_close(pkgmgr_parser_db);
648         sqlite3_free(query);
649         return ret;
650 }
651
652 API int pkgmgrinfo_pkginfo_set_installed_storage(const char *pkgid, INSTALL_LOCATION location)
653 {
654         return pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid, location, GLOBAL_USER);
655 }