Implement dependency handler, parcelable, dbhandler (#101)
[platform/core/appfw/pkgmgr-info.git] / src / manager / pkginfo_manager.cc
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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 "manager/pkginfo_manager.h"
18
19 #include <sys/types.h>
20
21 #include <string>
22
23 #include "sqlite3.h"
24 #include "glib.h"
25
26 #include "pkgmgrinfo_private.h"
27
28 #include "logging.hh"
29 #include "common/database/abstract_db_handler.hh"
30 #include "common/database/pkg_set_db_handler.hh"
31 #include "common/parcel/appinfo_parcelable.hh"
32 #include "common/parcel/depinfo_parcelable.hh"
33 #include "common/parcel/filter_parcelable.hh"
34 #include "common/parcel/pkginfo_parcelable.hh"
35 #include "common/parcel/query_parcelable.hh"
36 #include "common/parcel/result_parcelable.hh"
37
38 #include "client/pkginfo_client.hh"
39
40 #include <parcel.hh>
41
42 #ifdef LOG_TAG
43 #undef LOG_TAG
44 #endif
45 #define LOG_TAG "PKGMGR_INFO"
46
47 #ifdef EXPORT_API
48 #undef EXPORT_API
49 #endif
50 #define EXPORT_API __attribute__((visibility("default")))
51
52 extern "C" EXPORT_API int _pkginfo_get_packages(uid_t uid,
53             pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
54         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
55                         new pkgmgr_common::parcel::FilterParcelable(uid,
56                                         static_cast<pkgmgrinfo_filter_x*>(filter), flag));
57
58         pkgmgr_client::PkgInfoClient client(parcelable, uid,
59                         pkgmgr_common::ReqType::GET_PKG_INFO);
60         if (!client.SendRequest())
61       return PMINFO_R_ERROR;
62
63         std::shared_ptr<pkgmgr_common::parcel::PkgInfoParcelable> return_parcel(
64                         std::static_pointer_cast<pkgmgr_common::parcel::PkgInfoParcelable>(
65                                         client.GetResultParcel()));
66
67         tizen_base::Parcel parcel;
68         parcel.ReadParcelable(return_parcel.get());
69
70         auto result_list = return_parcel->GetPkgInfo();
71         // TODO: check noentry error has returned if size of result_list is 0
72         for (auto& pkginfo : result_list)
73                 g_hash_table_insert(packages, (gpointer)pkginfo->package,
74                                 (gpointer)pkginfo);
75
76         return PMINFO_R_OK;
77 }
78
79 extern "C" EXPORT_API int _pkginfo_get_depends_on(uid_t uid,
80                 const char *pkgid, GList **dependencies) {
81         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
82                         new pkgmgr_common::parcel::DepInfoParcelable(std::string(pkgid)));
83
84         pkgmgr_client::PkgInfoClient client(parcelable, uid,
85                         pkgmgr_common::ReqType::GET_PKG_DEP_INFO);
86         if (!client.SendRequest())
87       return PMINFO_R_ERROR;
88
89         std::shared_ptr<pkgmgr_common::parcel::DepInfoParcelable> return_parcel(
90                         std::static_pointer_cast<pkgmgr_common::parcel::DepInfoParcelable>(
91                                         client.GetResultParcel()));
92
93         tizen_base::Parcel parcel;
94         parcel.ReadParcelable(return_parcel.get());
95
96         auto dependency_list = return_parcel->GetDependencyInfo();
97         for (auto& dependency : dependency_list)
98                 *dependencies = g_list_prepend(*dependencies, dependency);
99         return PMINFO_R_OK;
100 }
101
102 // TODO: Need to add target db uid to identify which database to be searched
103 extern "C" EXPORT_API int _appinfo_get_applications(uid_t db_uid, uid_t uid,
104                 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
105         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
106                         new pkgmgr_common::parcel::FilterParcelable(uid,
107                                         static_cast<pkgmgrinfo_filter_x*>(filter), flag));
108
109         pkgmgr_client::PkgInfoClient client(parcelable, uid, pkgmgr_common::ReqType::GET_APP_INFO);
110         if (!client.SendRequest())
111       return PMINFO_R_ERROR;
112
113         std::shared_ptr<pkgmgr_common::parcel::AppInfoParcelable> return_parcel(
114                         std::static_pointer_cast<pkgmgr_common::parcel::AppInfoParcelable>(
115                                         client.GetResultParcel()));
116
117         tizen_base::Parcel parcel;
118         parcel.ReadParcelable(return_parcel.get());
119         auto result_list = return_parcel->GetAppInfo();
120         for (auto& appinfo : result_list)
121                 g_hash_table_insert(packages, (gpointer)appinfo->appid,
122                                 (gpointer)appinfo);
123
124         return PMINFO_R_OK;
125 }
126
127 extern "C" EXPORT_API char *_appinfo_get_localed_label(
128                 const char *appid, const char *locale, uid_t uid) {
129         char *query = nullptr;
130     query = sqlite3_mprintf(
131                         "SELECT COALESCE((SELECT app_label FROM package_app_localized_info "
132                         "WHERE app_id=%Q AND app_locale=%Q),"
133                         "(SELECT app_label FROM package_app_localized_info WHERE "
134                         "app_id=%Q AND app_locale='No Locale'))", appid, locale, appid);
135         if (query == nullptr) {
136                 LOG(ERROR) << "Out of memory";
137                 return nullptr;
138         }
139
140         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
141                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
142           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
143           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
144
145         pkgmgr_client::PkgInfoClient client(parcelable, uid,
146                         pkgmgr_common::ReqType::QUERY);
147         if (!client.SendRequest()) {
148                 sqlite3_free(query);
149                 return nullptr;
150         }
151
152         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
153                                 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
154                                                 client.GetResultParcel()));
155         tizen_base::Parcel parcel;
156         parcel.ReadParcelable(return_parcel.get());
157         sqlite3_free(query);
158         // result_list is vector of string vector
159         char *label = nullptr;
160         auto result_list = return_parcel->GetResult();
161         for (auto result : result_list) {
162                 // result is string vector
163                 // it only has one string or not.
164                 if (result.front().empty() || result.front().length() == 0)
165                         return nullptr;
166                 label = strdup(result.front().c_str());
167                 if (label == nullptr) {
168                         LOG(ERROR) << "Out of memory";
169                         return nullptr;
170                 }
171                 return label;
172         }
173
174         return label;
175 }
176
177 extern "C" EXPORT_API int _appinfo_get_datacontrol_info(
178                 const char *providerid, const char *type, uid_t uid,
179                 char **appid, char **access) {
180         char *query = nullptr;
181         query = sqlite3_mprintf("SELECT app_id, access FROM "
182                         "package_app_data_control WHERE "
183                         "providerid=%Q AND type=%Q", providerid, type);
184         if (query == nullptr) {
185                 LOG(ERROR) << "Out of memory";
186                 return PMINFO_R_ERROR;
187         }
188
189         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
190                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
191           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
192           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
193
194         pkgmgr_client::PkgInfoClient client(parcelable, uid,
195                         pkgmgr_common::ReqType::QUERY);
196         if (!client.SendRequest()) {
197                 sqlite3_free(query);
198                 return PMINFO_R_ERROR;
199         }
200
201         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
202                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
203                                         client.GetResultParcel()));
204         tizen_base::Parcel parcel;
205         parcel.ReadParcelable(return_parcel.get());
206         sqlite3_free(query);
207         // result_list is vector of string vector
208         auto result_list = return_parcel->GetResult();
209         if (result_list.size() == 0)
210                 return PMINFO_R_ENOENT;
211         for (auto result : result_list) {
212                 if (result.size() != 2)
213                         return PMINFO_R_ERROR;
214                 if (result.front().empty() || result.front().size() == 0 ||
215                                 result.back().empty() || result.back().size() == 0)
216                         return PMINFO_R_ERROR;
217                 *appid = strdup(result.front().c_str());
218                 *access = strdup(result.back().c_str());
219                 if (*appid == nullptr || *access == nullptr) {
220                         LOG(ERROR) << "Out of memory";
221                         return PMINFO_R_ERROR;
222                 }
223         }
224
225         return PMINFO_R_OK;
226 }
227
228 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
229                 const char *providerid, uid_t uid, char **appid) {
230         char *query = nullptr;
231
232         query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
233                 "WHERE providerid=%Q", providerid);
234         if (query == nullptr) {
235                 LOGE("Out of memory");
236                 return PMINFO_R_ERROR;
237         }
238         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
239                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
240           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
241           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
242
243         pkgmgr_client::PkgInfoClient client(parcelable, uid,
244                         pkgmgr_common::ReqType::QUERY);
245         if (!client.SendRequest()) {
246                 sqlite3_free(query);
247                 return PMINFO_R_ERROR;
248         }
249         // TODO: deliver rawdata to reqhandler directly if server is not working
250
251         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
252                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
253                                         client.GetResultParcel()));
254         tizen_base::Parcel parcel;
255         parcel.ReadParcelable(return_parcel.get());
256         sqlite3_free(query);
257
258         // result_list is vector of string vector
259         auto result_list = return_parcel->GetResult();
260         if (result_list.size() == 0)
261                 return PMINFO_R_ENOENT;
262         for (auto result : result_list) {
263                 if (result.size() != 1)
264                         return PMINFO_R_ERROR;
265                 if (result.front().empty() || result.front().size() == 0)
266                         return PMINFO_R_ERROR;
267                 *appid = strdup(result.front().c_str());
268                 if (*appid == nullptr) {
269                         LOG(ERROR) << "Out of memory";
270                         return PMINFO_R_ERROR;
271                 }
272         }
273
274         return PMINFO_R_OK;
275 }
276
277 extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
278                 const char *providerid, const char *type, uid_t uid,
279                 char **appid, char **trusted) {
280         char *query = nullptr;
281         query = sqlite3_mprintf(
282                         "SELECT app_id, trusted FROM package_app_data_control "
283                         "WHERE providerid=%Q AND type=%Q", providerid, type);
284         if (query == nullptr) {
285                 LOGE("Out of memory");
286                 return PMINFO_R_ERROR;
287         }
288
289         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
290                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
291           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
292           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
293
294         pkgmgr_client::PkgInfoClient client(parcelable, uid,
295                         pkgmgr_common::ReqType::QUERY);
296         if (!client.SendRequest()) {
297                 sqlite3_free(query);
298                 return PMINFO_R_ERROR;
299         }
300         // TODO: deliver rawdata to reqhandler directly if server is not working
301
302         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
303                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
304                                         client.GetResultParcel()));
305         tizen_base::Parcel parcel;
306         parcel.ReadParcelable(return_parcel.get());
307         sqlite3_free(query);
308         // result_list is vector of string vector
309         auto result_list = return_parcel->GetResult();
310         if (result_list.size() == 0)
311                 return PMINFO_R_ENOENT;
312         for (auto result : result_list) {
313                 if (result.size() != 2)
314                         return PMINFO_R_ERROR;
315                 if (result.front().empty() || result.front().size() == 0 ||
316                                 result.back().empty() || result.back().size() == 0)
317                         return PMINFO_R_ERROR;
318                 *appid = strdup(result.front().c_str());
319                 *trusted = strdup(result.back().c_str());
320                 if (*appid == nullptr || *trusted == nullptr) {
321                         LOG(ERROR) << "Out of memory";
322                         return PMINFO_R_ERROR;
323                 }
324         }
325
326         return PMINFO_R_OK;
327 }
328
329 extern "C" EXPORT_API int _appinfo_get_datacontrol_privileges(
330                 const char *providerid, const char *type, uid_t uid,
331                 GList **privileges) {
332         char *query = nullptr;
333         query = sqlite3_mprintf(
334                         "SELECT privilege FROM package_app_data_control_privilege "
335                         "WHERE providerid=%Q AND type=%Q", providerid, type);
336         if (query == nullptr) {
337                 LOGE("Out of memory");
338                 return PMINFO_R_ERROR;
339         }
340
341         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
342                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
343           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
344           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
345
346         pkgmgr_client::PkgInfoClient client(parcelable, uid,
347                         pkgmgr_common::ReqType::QUERY);
348         if (!client.SendRequest()) {
349                 sqlite3_free(query);
350                 return PMINFO_R_ERROR;
351         }
352         // TODO: deliver rawdata to reqhandler directly if server is not working
353
354         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
355                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
356                                         client.GetResultParcel()));
357         tizen_base::Parcel parcel;
358         parcel.ReadParcelable(return_parcel.get());
359         sqlite3_free(query);
360         // result_list is vector of string vector
361         auto result_list = return_parcel->GetResult();
362         if (result_list.size() == 0)
363                 return PMINFO_R_ENOENT;
364
365         for (auto result : result_list) {
366                 if (result.size() != 1)
367                         return PMINFO_R_ERROR;
368                 if (result.front().empty() || result.front().size() == 0)
369                         return PMINFO_R_ERROR;
370                 char *privilege = strdup(result.front().c_str());
371                 if (privilege == nullptr) {
372                         LOG(ERROR) << "Out of memory";
373                         return PMINFO_R_ERROR;
374                 }
375                 *privileges = g_list_append(*privileges, privilege);
376         }
377
378         return PMINFO_R_OK;
379 }
380
381 extern "C" EXPORT_API int _appinfo_get_appcontrol_privileges(
382                 const char *appid, const char *operation, uid_t uid, GList **privileges) {
383         char *query = nullptr;
384         query = sqlite3_mprintf(
385                 "SELECT app_control, privilege FROM package_app_app_control_privilege "
386                 "WHERE app_id=%Q", appid);
387         if (query == nullptr) {
388                 LOG(ERROR) << "Out of memory";
389                 return PMINFO_R_ERROR;
390         }
391
392         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
393                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
394           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
395           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
396
397         pkgmgr_client::PkgInfoClient client(parcelable, uid,
398                         pkgmgr_common::ReqType::QUERY);
399         if (!client.SendRequest()) {
400                 sqlite3_free(query);
401                 return PMINFO_R_ERROR;
402         }
403         // TODO: deliver rawdata to reqhandler directly if server is not working
404
405         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
406                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
407                                         client.GetResultParcel()));
408         tizen_base::Parcel parcel;
409         parcel.ReadParcelable(return_parcel.get());
410         sqlite3_free(query);
411         // result_list is vector of string vector
412         auto result_list = return_parcel->GetResult();
413         if (result_list.size() == 0)
414                 return PMINFO_R_ENOENT;
415
416         for (auto result : result_list) {
417                 if (result.size() != 2)
418                         return PMINFO_R_ERROR;
419                 if (result.front().empty() || result.front().size() == 0 ||
420                                 result.back().empty() || result.back().size() == 0)
421                         return PMINFO_R_ERROR;
422                 std::string app_control = result.front();
423                 std::stringstream ss(app_control);
424                 std::string token;
425                 while (std::getline(ss, token, '|')) {
426                         if (token.compare(std::string(operation))) {
427                                 char *privilege = strdup(result.back().c_str());
428                                 if (privilege == nullptr) {
429                                         LOG(ERROR) << "Out of memory";
430                                         return PMINFO_R_ERROR;
431                                 }
432                                 *privileges = g_list_append(*privileges, privilege);
433                         }
434                 }
435         }
436         return PMINFO_R_OK;
437 }
438
439 extern "C" EXPORT_API int _plugininfo_get_appids(
440                 const char *pkgid, const char *plugin_type,
441                 const char *plugin_name, GList **list) {
442         if (!pkgid || !plugin_type || !plugin_name || !list) {
443                 LOG(ERROR) << "Invalid parameter";
444                 return PMINFO_R_EINVAL;
445         }
446
447         char *query = nullptr;
448         query = sqlite3_mprintf(
449                         "SELECT appid FROM "
450                         "package_plugin_info WHERE pkgid=%Q AND "
451                         "plugin_type=%Q AND plugin_name=%Q",
452       pkgid, plugin_type, plugin_name);
453         if (query == nullptr) {
454                 LOG(ERROR) << "Out of memory";
455                 return PMINFO_R_ERROR;
456         }
457
458         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
459                         new pkgmgr_common::parcel::QueryParcelable(_getuid(), std::string(query),
460           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
461           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
462         sqlite3_free(query);
463
464         pkgmgr_client::PkgInfoClient client(parcelable, _getuid(),
465                         pkgmgr_common::ReqType::QUERY);
466         if (!client.SendRequest()) {
467                 return PMINFO_R_ERROR;
468         }
469
470         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
471                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
472                                         client.GetResultParcel()));
473   if (return_parcel->GetCol() != 1) {
474     LOG(ERROR) << "Invalid result";
475     return PMINFO_R_ERROR;
476   }
477         // result_list is vector of string vector
478         auto& result_list = return_parcel->GetResult();
479         if (result_list.size() == 0)
480                 return PMINFO_R_ENOENT;
481
482         for (auto result : result_list) {
483     if (result.size() != 1) {
484       LOG(ERROR) << "Invalid result";
485       g_list_free_full(*list, free);
486       return PMINFO_R_ERROR;
487     }
488     *list = g_list_append(*list, strdup(result[0].c_str()));
489   }
490
491   return PMINFO_R_OK;
492 }
493
494 static int __convert_update_type(const char *type, pkgmgrinfo_updateinfo_update_type *convert_type)
495 {
496         if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_NONE,
497                         strlen(PMINFO_UPDATEINFO_TYPE_NONE)) == 0)
498                 *convert_type = PMINFO_UPDATEINFO_NONE;
499         else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_FORCE,
500                         strlen(PMINFO_UPDATEINFO_TYPE_FORCE)) == 0)
501                 *convert_type = PMINFO_UPDATEINFO_FORCE;
502         else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_OPTIONAL,
503                         strlen(PMINFO_UPDATEINFO_TYPE_OPTIONAL)) == 0)
504                 *convert_type = PMINFO_UPDATEINFO_OPTIONAL;
505         else
506                 return -1;
507         return 0;
508 }
509
510 static void __free_update_info(gpointer data)
511 {
512         updateinfo_x *update_info = (updateinfo_x *)data;
513         if (update_info == nullptr)
514                 return;
515
516         if (update_info->pkgid)
517                 free((void *)update_info->pkgid);
518         if (update_info->version)
519                 free((void *)update_info->version);
520         free((void *)update_info);
521
522 }
523
524 extern "C" EXPORT_API int _get_pkg_updateinfo(const char *pkgid,
525                 GSList **update_info_list, uid_t uid)
526 {
527         char *query = nullptr;
528         int ret;
529
530         if (pkgid == nullptr)
531                 query = sqlite3_mprintf(
532                                                 "SELECT package, update_version, update_type "
533                                                 "FROM package_update_info");
534         else
535                 query = sqlite3_mprintf(
536                                                 "SELECT package, update_version, update_type "
537                                                 "FROM package_update_info WHERE package=%Q",
538                                                 pkgid);
539         if (query == nullptr) {
540                 LOG(ERROR) << "Out of memory";
541                 return PMINFO_R_ERROR;
542         }
543
544         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
545                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
546           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
547           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
548         sqlite3_free(query);
549
550         pkgmgr_client::PkgInfoClient client(parcelable, uid,
551                         pkgmgr_common::ReqType::QUERY);
552         if (!client.SendRequest()) {
553                 return PMINFO_R_ERROR;
554         }
555
556         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
557                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
558                                         client.GetResultParcel()));
559   if (return_parcel->GetCol() != 3) {
560     LOG(ERROR) << "Invalid result";
561     return PMINFO_R_ERROR;
562   }
563
564         auto result_list = return_parcel->GetResult();
565         if (result_list.size() == 0)
566                 return PMINFO_R_ENOENT;
567
568         for (auto result : result_list) {
569     if (result.size() != 3) {
570       LOG(ERROR) << "Invalid result";
571       g_slist_free_full(*update_info_list, __free_update_info);
572       return PMINFO_R_ERROR;
573     }
574     updateinfo_x *update_info = reinterpret_cast<updateinfo_x *>(calloc(1, sizeof(updateinfo_x)));
575                 if (update_info == nullptr) {
576                         LOG(ERROR) << "Out of memory";
577                         return PMINFO_R_ERROR;
578                 }
579     update_info->pkgid = strdup(result[0].c_str());
580     update_info->version = strdup(result[1].c_str());
581           pkgmgrinfo_updateinfo_update_type convert_type;
582                 ret = __convert_update_type(result[2].c_str(), &convert_type);
583                 if (ret != 0) {
584                         __free_update_info(update_info);
585       g_slist_free_full(*update_info_list, __free_update_info);
586                         return PMINFO_R_ERROR;
587                 }
588                 update_info->type = static_cast<int>(convert_type);
589                 *update_info_list = g_slist_prepend(*update_info_list,
590                                 update_info);
591   }
592
593         return PMINFO_R_OK;
594 }
595
596 extern "C" EXPORT_API int _pkginfo_set_usr_installed_storage(const char *pkgid,
597                 INSTALL_LOCATION location, const char *external_pkg_path,
598                 uid_t uid)
599 {
600         char *query = nullptr;
601         const char *location_str;
602         std::vector<std::string> queries;
603
604         if (location == INSTALL_INTERNAL)
605                 location_str = "installed_internal";
606         else if (location == INSTALL_EXTERNAL)
607                 location_str = "installed_external";
608         else
609                 location_str = "installed_extended";
610         /* pkgcakge_info table */
611         query = sqlite3_mprintf(
612                         "update package_info set installed_storage=%Q, external_path=%Q where package=%Q",
613                         location_str, external_pkg_path, pkgid);
614         queries.emplace_back(query);
615         sqlite3_free(query);
616
617         /* package_app_info table */
618         query = sqlite3_mprintf(
619                         "update package_app_info set app_installed_storage=%Q, app_external_path=%Q where package=%Q",
620                         location_str, external_pkg_path, pkgid);
621         queries.emplace_back(query);
622         sqlite3_free(query);
623
624         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
625                         new pkgmgr_common::parcel::QueryParcelable(uid, queries,
626                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
627                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
628
629         pkgmgr_client::PkgInfoClient client(parcelable, uid,
630                         pkgmgr_common::ReqType::QUERY);
631         if (!client.SendRequest()) {
632                 return PMINFO_R_ERROR;
633         }
634
635         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
636                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
637                                         client.GetResultParcel()));
638
639         auto result_list = return_parcel->GetResult();
640         if (result_list.size() != 1) {
641                 LOG(ERROR) << "Invalid result";
642                 return PMINFO_R_ERROR;
643         }
644
645         if (result_list[0].size() != 1) {
646                 LOG(ERROR) << "Invalid result";
647                 return PMINFO_R_ERROR;
648         }
649
650         LOG(ERROR) << "result : " << result_list[0][0];
651         if (result_list[0][0] != "SUCCESS")
652                 return PMINFO_R_ERROR;
653
654         return PMINFO_R_OK;
655 }
656
657 extern "C" EXPORT_API int _parser_execute_write_query(const char *query, uid_t uid)
658 {
659         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
660                         new pkgmgr_common::parcel::QueryParcelable(uid, query,
661                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
662                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
663
664         pkgmgr_client::PkgInfoClient client(parcelable, uid,
665                         pkgmgr_common::ReqType::QUERY);
666         if (!client.SendRequest()) {
667                 return -1;
668         }
669
670         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
671                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
672                                         client.GetResultParcel()));
673
674         auto result_list = return_parcel->GetResult();
675         if (result_list.size() != 1) {
676                 LOG(ERROR) << "Invalid result";
677                 return -1;
678         }
679
680         if (result_list[0].size() != 1) {
681                 LOG(ERROR) << "Invalid result";
682                 return -1;
683         }
684
685         LOG(ERROR) << "result : " << result_list[0][0];
686         if (result_list[0][0] != "SUCCESS")
687                 return -1;
688
689         return 0;
690 }
691
692 extern "C" EXPORT_API int _parser_execute_write_queries(const char **queries, int len, uid_t uid)
693 {
694         std::vector<std::string> query_vt;
695         for (int i = 0; i < len; ++i)
696                 query_vt.emplace_back(queries[i]);
697
698         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
699                         new pkgmgr_common::parcel::QueryParcelable(uid, query_vt,
700                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
701                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
702
703         pkgmgr_client::PkgInfoClient client(parcelable, uid,
704                         pkgmgr_common::ReqType::QUERY);
705         if (!client.SendRequest()) {
706                 return -1;
707         }
708
709         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
710                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
711                                         client.GetResultParcel()));
712
713         auto result_list = return_parcel->GetResult();
714         if (result_list.size() != 1) {
715                 LOG(ERROR) << "Invalid result";
716                 return -1;
717         }
718
719         if (result_list[0].size() != 1) {
720                 LOG(ERROR) << "Invalid result";
721                 return -1;
722         }
723
724         LOG(ERROR) << "result : " << result_list[0][0];
725         if (result_list[0][0] != "SUCCESS")
726                 return -1;
727
728         return 0;
729 }
730
731 extern "C" EXPORT_API int _parser_insert_manifest_info(manifest_x *mfx, uid_t uid)
732 {
733         std::vector<package_x *> vt { mfx };
734
735         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
736                         new pkgmgr_common::parcel::PkgInfoParcelable(uid, std::move(vt), WriteType::Insert));
737
738         pkgmgr_client::PkgInfoClient client(parcelable, uid,
739                         pkgmgr_common::ReqType::SET_PKG_INFO);
740         if (!client.SendRequest()) {
741                 return -1;
742         }
743
744         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
745                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
746                                         client.GetResultParcel()));
747
748         auto result_list = return_parcel->GetResult();
749         if (result_list.size() != 1) {
750                 LOG(ERROR) << "Invalid result";
751                 return -1;
752         }
753
754         if (result_list[0].size() != 1) {
755                 LOG(ERROR) << "Invalid result";
756                 return -1;
757         }
758
759         LOG(ERROR) << "result : " << result_list[0][0];
760         if (result_list[0][0] != "SUCCESS")
761                 return -1;
762
763         return 0;
764 }
765
766 extern "C" EXPORT_API int _parser_update_manifest_info(manifest_x *mfx, uid_t uid)
767 {
768         std::vector<package_x *> vt { mfx };
769
770         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
771                         new pkgmgr_common::parcel::PkgInfoParcelable(uid, std::move(vt), WriteType::Update));
772
773         pkgmgr_client::PkgInfoClient client(parcelable, uid,
774                         pkgmgr_common::ReqType::SET_PKG_INFO);
775         if (!client.SendRequest()) {
776                 return -1;
777         }
778
779         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
780                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
781                                         client.GetResultParcel()));
782
783         auto result_list = return_parcel->GetResult();
784         if (result_list.size() != 1) {
785                 LOG(ERROR) << "Invalid result";
786                 return -1;
787         }
788
789         if (result_list[0].size() != 1) {
790                 LOG(ERROR) << "Invalid result";
791                 return -1;
792         }
793
794         LOG(ERROR) << "result : " << result_list[0][0];
795         if (result_list[0][0] != "SUCCESS")
796                 return -1;
797
798         return 0;
799 }
800
801 extern "C" EXPORT_API int _parser_delete_manifest_info(manifest_x *mfx, uid_t uid)
802 {
803         std::vector<package_x *> vt { mfx };
804
805         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
806                         new pkgmgr_common::parcel::PkgInfoParcelable(uid, std::move(vt), WriteType::Delete));
807
808         pkgmgr_client::PkgInfoClient client(parcelable, uid,
809                         pkgmgr_common::ReqType::SET_PKG_INFO);
810         if (!client.SendRequest()) {
811                 return -1;
812         }
813
814         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
815                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
816                                         client.GetResultParcel()));
817
818         auto result_list = return_parcel->GetResult();
819         if (result_list.size() != 1) {
820                 LOG(ERROR) << "Invalid result";
821                 return -1;
822         }
823
824         if (result_list[0].size() != 1) {
825                 LOG(ERROR) << "Invalid result";
826                 return -1;
827         }
828
829         LOG(ERROR) << "result : " << result_list[0][0];
830         if (result_list[0][0] != "SUCCESS")
831                 return -1;
832
833         return 0;
834 }