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