Merge branch 'master' of github.sec.samsung.net:appfw/pkgmgr-info into tizen
authorIlho Kim <ilho159.kim@samsung.com>
Mon, 28 Jun 2021 09:10:40 +0000 (18:10 +0900)
committerIlho Kim <ilho159.kim@samsung.com>
Mon, 28 Jun 2021 10:32:02 +0000 (19:32 +0900)
Change-Id: I404ed720f12f81f00ca8c5cf1acf27370bee14ee
Signed-off-by: Ilho Kim <ilho159.kim@samsung.com>
27 files changed:
1  2 
packaging/pkgmgr-info.spec
src/CMakeLists.txt
src/common/parcel/abstract_parcelable.hh
src/common/parcel/pkginfo_parcelable.cc
src/common/parcel/pkginfo_parcelable.hh
src/common/parcel/query_parcelable.cc
src/common/parcel/query_parcelable.hh
src/manager/pkginfo_manager.cc
src/pkgmgrinfo_appinfo.c
src/pkgmgrinfo_pkginfo.c
src/pkgmgrinfo_private.c
src/pkgmgrinfo_private.h
src/pkgmgrinfo_updateinfo.c
src/server/CMakeLists.txt
src/server/appinfo_internal.c
src/server/database/query_handler.cc
src/server/database/query_handler.hh
src/server/pkginfo_internal.c
src/server/request_handler/command_request_handler.cc
src/server/request_handler/create_db_request_handler.cc
src/server/request_handler/query_request_handler.cc
src/server/request_handler/set_cert_request_handler.cc
src/server/request_handler/set_pkginfo_request_handler.cc
test/unit_tests/CMakeLists.txt
test/unit_tests/parcel_utils.cc
test/unit_tests/test_parcel.cc
test/unit_tests/test_parser_db_handlers.cc

Simple merge
Simple merge
@@@ -27,39 -27,23 +27,37 @@@ namespace parcel 
  
  QueryParcelable::QueryParcelable()
      : AbstractParcelable(0, ParcelableType::Query),
-     db_type_(AbstractDBHandler::DBType::DB_TYPE_NONE),
-     op_type_(AbstractDBHandler::OperationType::OPERATION_TYPE_NONE) {}
+     db_type_(DBType::DB_TYPE_NONE),
+     op_type_(DBOperationType::OPERATION_TYPE_NONE) {}
  
  QueryParcelable::QueryParcelable(uid_t uid,
 -    QueryArgs query_args,
 -    DBType db_type,
 -    DBOperationType op_type)
 -    : AbstractParcelable(0, ParcelableType::Query),
 -    query_args_(std::vector<QueryArgs>{query_args}),
 -    db_type_(db_type), op_type_(op_type) {}
 +    const std::pair<int, std::vector<const char*>>& query_args,
-     AbstractDBHandler::DBType db_type,
-     AbstractDBHandler::OperationType op_type)
++    DBType db_type, DBOperationType op_type)
 +    : AbstractParcelable(uid, ParcelableType::Query),
 +    db_type_(db_type), op_type_(op_type) {
 +  query_args_.emplace_back(CreateQueryArgs(query_args));
 +}
  
  QueryParcelable::QueryParcelable(uid_t uid,
 -    std::vector<QueryArgs> query_args,
 -    DBType db_type,
 -    DBOperationType op_type)
 +    const std::vector<std::pair<int, std::vector<const char*>>>& query_args,
-     AbstractDBHandler::DBType db_type,
-     AbstractDBHandler::OperationType op_type)
++    DBType db_type, DBOperationType op_type)
      : AbstractParcelable(uid, ParcelableType::Query),
 -    query_args_(std::move(query_args)), db_type_(db_type), op_type_(op_type) {}
 +    db_type_(db_type), op_type_(op_type) {
 +  for (const auto& arg : query_args)
 +    query_args_.emplace_back(CreateQueryArgs(arg));
 +}
 +
 +QueryArgs QueryParcelable::CreateQueryArgs(
 +    const std::pair<int, std::vector<const char*>>& args) {
 +  StrArgs vt;
 +  for (const char* param : args.second) {
 +      if (param)
 +        vt.emplace_back(param);
 +      else
 +        vt.emplace_back(std::nullopt);
 +  }
 +  return std::make_pair(args.first, std::move(vt));
 +}
  
  void QueryParcelable::WriteToParcel(tizen_base::Parcel* parcel) const {
    AbstractParcelable::WriteToParcel(parcel);
      WriteInt(parcel, query_info.first);
      WriteInt(parcel, query_info.second.size());
      for (const auto& args : query_info.second)
 -      parcel->WriteString(args);
 +      WriteString(parcel, args);
    }
-   WriteInt(parcel, db_type_);
-   WriteInt(parcel, op_type_);
+   WriteInt(parcel, static_cast<int>(db_type_));
+   WriteInt(parcel, static_cast<int>(op_type_));
  }
  
  void QueryParcelable::ReadFromParcel(tizen_base::Parcel* parcel) {
      query_args_.push_back(QueryArgs(index, std::move(args)));
    }
    ReadInt(parcel, &db_type);
-   db_type_ = static_cast<AbstractDBHandler::DBType>(db_type);
+   db_type_ = static_cast<DBType>(db_type);
    ReadInt(parcel, &op_type);
-   op_type_ = static_cast<AbstractDBHandler::OperationType>(op_type);
+   op_type_ = static_cast<DBOperationType>(op_type);
  }
  
 -const std::vector<QueryArgs>& QueryParcelable::GetQueryArgs() {
 -  return query_args_;
 +std::vector<QueryArgs> QueryParcelable::ExtractQueryArgs() {
 +  return std::move(query_args_);
  }
  
AbstractDBHandler::DBType QueryParcelable::GetDBType() {
+ DBType QueryParcelable::GetDBType() {
    return db_type_;
  }
  
@@@ -2,9 -2,7 +2,8 @@@
  #define QUERY_PARCELABLE_HH_
  
  #include "abstract_parcelable.hh"
- #include "abstract_db_handler.hh"
  
 +#include <optional>
  #include <vector>
  
  #include "pkgmgrinfo_private.h"
@@@ -24,28 -21,21 +23,26 @@@ using QueryArgs = std::pair<int, StrArg
  class EXPORT_API QueryParcelable : public AbstractParcelable {
   public:
    QueryParcelable();
 -  QueryParcelable(uid_t uid, QueryArgs query_args,
 +  QueryParcelable(uid_t uid,
 +      const std::pair<int, std::vector<const char*>>& query_args,
-       AbstractDBHandler::DBType db_type,
-       AbstractDBHandler::OperationType op_type);
+       DBType db_type, DBOperationType op_type);
 -  QueryParcelable(uid_t uid, std::vector<QueryArgs> query_args,
 +  QueryParcelable(uid_t uid,
 +      const std::vector<std::pair<int, std::vector<const char*>>>& query_args,
-       AbstractDBHandler::DBType db_type,
-       AbstractDBHandler::OperationType op_type);
+       DBType db_type, DBOperationType op_type);
 -  const std::vector<QueryArgs>& GetQueryArgs();
 +  std::vector<QueryArgs> ExtractQueryArgs();
-   AbstractDBHandler::DBType GetDBType();
-   AbstractDBHandler::OperationType GetOpType();
+   DBType GetDBType();
+   DBOperationType GetOpType();
  
    void WriteToParcel(tizen_base::Parcel* parcel) const override;
    void ReadFromParcel(tizen_base::Parcel* parcel) override;
  
   private:
 +  QueryArgs CreateQueryArgs(
 +      const std::pair<int, std::vector<const char*>>& args);
 +
    std::vector<QueryArgs> query_args_;
-   AbstractDBHandler::DBType db_type_;
-   AbstractDBHandler::OperationType op_type_;
+   DBType db_type_;
+   DBOperationType op_type_;
  };
  
  }  // namespace parcel
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -1,23 -1,36 +1,36 @@@
  ## build pkginfo-server binary
  SET(PKGINFO_SERVER "pkginfo-server")
  
- AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} PKGINFO_SERVER_SRCS)
- INCLUDE_DIRECTORIES(
-   ${CMAKE_CURRENT_SOURCE_DIR}/../
-   ${CMAKE_CURRENT_SOURCE_DIR}/../common/database
-   ${CMAKE_CURRENT_SOURCE_DIR}/../common/socket
-   ${CMAKE_CURRENT_SOURCE_DIR}/../common/parcel
-   ${CMAKE_CURRENT_SOURCE_DIR}/../common/request_handler
+ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SERVER_SRCS)
+ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/cynara_checker CYNARA_CHECKER_SRCS)
+ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/database DATABASE_SRCS)
+ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/request_handler REQUEST_HANDLER_SRCS)
+ ADD_LIBRARY(pkgmgr-info-server SHARED
+   ${CYNARA_CHECKER_SRCS}
+   ${SERVER_SRCS}
+   ${DATABASE_SRCS}
+   ${REQUEST_HANDLER_SRCS}
  )
  
- ADD_EXECUTABLE(${PKGINFO_SERVER} ${PKGINFO_SERVER_SRCS})
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fpic -std=c++17 -pthread -fPIE")
- SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie")
+ ADD_DEFINITIONS("-DSYSCONFDIR=\"${SYSCONFDIR}\"")
+ SET_TARGET_PROPERTIES(pkgmgr-info-server PROPERTIES SOVERSION ${MAJORVER})
+ SET_TARGET_PROPERTIES(pkgmgr-info-server PROPERTIES VERSION ${FULLVER})
+ TARGET_LINK_LIBRARIES(pkgmgr-info-server pkgmgr-info ${libpkgs_server_LDFLAGS})
+ INSTALL(TARGETS pkgmgr-info-server DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+ ADD_EXECUTABLE(${PKGINFO_SERVER} main.cc)
+ SET_TARGET_PROPERTIES(${PKGINFO_SERVER} PROPERTIES COMPILE_FLAGS ${CFLAGS} "-fPIE")
+ SET_TARGET_PROPERTIES(${PKGINFO_SERVER} PROPERTIES LINK_FLAGS "-pie")
 -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fpic -std=c++14 -pthread")
++SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fpic -std=c++17 -pthread")
  
- TARGET_LINK_LIBRARIES(${PKGINFO_SERVER} PRIVATE ${libpkgs_LDFLAGS})
- TARGET_LINK_LIBRARIES(${PKGINFO_SERVER} PRIVATE ${libpkgmgr-parser_LDFLAGS})
- TARGET_LINK_LIBRARIES(${PKGINFO_SERVER} PUBLIC pkgmgr-info pthread)
+ TARGET_LINK_LIBRARIES(${PKGINFO_SERVER} ${libpkgs_LDFLAGS})
+ TARGET_LINK_LIBRARIES(${PKGINFO_SERVER} ${libpkgmgr-parser_LDFLAGS})
+ TARGET_LINK_LIBRARIES(${PKGINFO_SERVER} PUBLIC pkgmgr-info-server pthread)
  
  SET_TARGET_PROPERTIES(${PKGINFO_SERVER} PROPERTIES LINKER_LANGUAGE CXX)
  INSTALL(TARGETS ${PKGINFO_SERVER} DESTINATION bin)
Simple merge
@@@ -204,7 -204,7 +204,7 @@@ QueryHandler::QueryHandler(uid_t uid, i
  QueryHandler::~QueryHandler() {}
  
  void QueryHandler::SetQueryArgs(
-     std::vector<parcel::QueryArgs> query_args) {
 -    std::vector<std::pair<int, std::vector<std::string>>> query_args) {
++    std::vector<pkgmgr_common::parcel::QueryArgs> query_args) {
    query_args_ = std::move(query_args);
  }
  
@@@ -212,7 -212,7 +212,7 @@@ std::string QueryHandler::GetString() 
  int QueryHandler::GetInt() { return 0; }
  int QueryHandler::GetRecordCount() { return 0; }
  
- std::vector<parcel::StrArgs> QueryHandler::GetResult() {
 -std::vector<std::vector<std::string>> QueryHandler::GetResult() {
++std::vector<pkgmgr_common::parcel::StrArgs> QueryHandler::GetResult() {
    return std::move(result_);
  }
  
@@@ -251,35 -249,34 +251,37 @@@ int QueryHandler::Execute() 
  
    std::vector<std::pair<sqlite3*, uid_t>> conn_list = GetConnection();
    int ret;
-   if (GetOpType() == OPERATION_TYPE_READ) {
+   if (GetOpType() == pkgmgr_common::DBOperationType::OPERATION_TYPE_READ) {
      for (auto& conn : conn_list) {
-       GList* list = nullptr;
-       int row = 0;
-       int col = 0;
-       query_args* params = (query_args*)args_list->data;
-       ret = get_query_result(conn.first, (const char *)queries->data,
-           params->argument, &list, &row, &col);
-       if (ret == PMINFO_R_ERROR) {
-         _LOGE("Failed to execute query");
-         __free_query_list(queries, args_list);
-         return ret;
-       }
+       for (GList* it = args_list; it; it = it->next) {
+         GList* list = nullptr;
+         int row = 0;
+         int col = 0;
+         query_args* params = (query_args*)it->data;
+         ret = get_query_result(conn.first, (const char *)queries->data,
+             params->argument, &list, &row, &col);
+         if (ret == PMINFO_R_ERROR) {
+           _LOGE("Failed to execute query");
+           __free_query_list(queries, args_list);
+           return ret;
+         }
  
-       GList* tmp = list;
-       for (int i = 0; i < row; ++i) {
-         parcel::StrArgs vt;
-         for (int j = 0; j < col; ++j) {
-           if (!tmp->data)
-             vt.emplace_back(std::nullopt);
-           else
-             vt.emplace_back(reinterpret_cast<char *>(tmp->data));
-           tmp = tmp->next;
+         GList* tmp = list;
+         for (int i = 0; i < row; ++i) {
 -          std::vector<std::string> vt;
++          pkgmgr_common::parcel::StrArgs vt;
+           for (int j = 0; j < col; ++j) {
 -            vt.emplace_back(reinterpret_cast<char *>(tmp->data));
++            if (!tmp->data)
++              vt.emplace_back(std::nullopt);
++            else
++              vt.emplace_back(reinterpret_cast<char *>(tmp->data));
+             tmp = tmp->next;
+           }
+           result_.emplace_back(std::move(vt));
          }
-         result_.emplace_back(std::move(vt));
-       }
  
-       g_list_free_full(list, free);
+         g_list_free_full(list, free);
+       }
      }
      __free_query_list(queries, args_list);
  
  #include <sys/types.h>
  
  #include "abstract_db_handler.hh"
+ #include "db_type.hh"
  #include "pkgmgrinfo_basic.h"
  #include "pkgmgrinfo_private.h"
 +#include "query_parcelable.hh"
  
- namespace pkgmgr_common {
+ namespace pkgmgr_server {
  namespace database {
  
  #ifndef EXPORT_API
@@@ -38,20 -38,20 +39,20 @@@ class EXPORT_API QueryHandler : public 
   public:
    QueryHandler(uid_t uid, int pid);
    ~QueryHandler();
-   void SetQueryArgs(std::vector<parcel::QueryArgs> query_args);
 -  void SetQueryArgs(std::vector<std::pair<int, std::vector<std::string>>> query_args);
++  void SetQueryArgs(std::vector<pkgmgr_common::parcel::QueryArgs> query_args);
    bool BindString(std::string value);
    bool BindInt(int value);
    std::string GetString();
    int GetInt();
    int GetRecordCount();
    int Execute() override;
-   std::vector<parcel::StrArgs> GetResult();
 -  std::vector<std::vector<std::string>> GetResult();
++  std::vector<pkgmgr_common::parcel::StrArgs> GetResult();
  
   private:
    uid_t uid_;
    std::vector<std::string> query_;
-   std::vector<parcel::QueryArgs> query_args_;
-   std::vector<parcel::StrArgs> result_;
 -  std::vector<std::pair<int, std::vector<std::string>>> query_args_;
 -  std::vector<std::vector<std::string>> result_;
++  std::vector<pkgmgr_common::parcel::QueryArgs> query_args_;
++  std::vector<pkgmgr_common::parcel::StrArgs> result_;
  };
  
  }  // namespace database
Simple merge
@@@ -40,10 -40,10 +40,10 @@@ bool CommandRequestHandler::HandleReque
    }
  
    if (parcel->GetCmd() == CommandType::RemoveCache) {
-     pkgmgr_common::DBHandleProvider::GetInst(
-         parcel->GetUid()).SetMemoryMode(GetPID(), false);
+     database::DBHandleProvider::GetInst(
+         parcel->GetUid()).UnsetMemoryMode(GetPID());
      result_ = std::make_shared<pcp::ResultParcelable>(
 -        PMINFO_R_OK, std::vector<std::vector<std::string>>{});
 +        PMINFO_R_OK, std::vector<pcp::StrArgs>{});
      return true;
    }
  
index 0000000,8eab01c..7d86c62
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,70 +1,70 @@@
 -        PM_PARSER_R_ERROR, std::vector<std::vector<std::string>>{});
+ // Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ // Use of this source code is governed by an apache-2.0 license that can be
+ // found in the LICENSE file.
+ #include "create_db_request_handler.hh"
+ #include <string>
+ #include "parcelable_factory.hh"
+ #include "create_db_parcelable.hh"
+ #include "create_db_handler.hh"
+ #include "db_type.hh"
+ #include "pkgmgr_parser.h"
+ #include "pkgmgrinfo_debug.h"
+ namespace pcp = pkgmgr_common::parcel;
+ namespace psd = pkgmgr_server::database;
+ namespace pkgmgr_server {
+ namespace request_handler {
+ bool CreateDBRequestHandler::HandleRequest(unsigned char* data, int size,
+                                            const std::string& locale) {
+   auto abstract_parcel =
+       pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
+   if (abstract_parcel == nullptr ||
+       abstract_parcel->GetType() != pcp::ParcelableType::CreateDB) {
+     _LOGE("Invalid parcel or type");
+     result_ = std::make_shared<pcp::ResultParcelable>(
 -        PM_PARSER_R_ERROR, std::vector<std::vector<std::string>>{});
++        PM_PARSER_R_ERROR, std::vector<pcp::StrArgs>{});
+     return false;
+   }
+   auto* parcel = dynamic_cast<pcp::CreateDBParcelable*>(abstract_parcel.get());
+   if (parcel == nullptr) {
+     _LOGE("Parcel is empty");
+     result_ = std::make_shared<pcp::ResultParcelable>(
 -      ret, std::vector<std::vector<std::string>>{});
++        PM_PARSER_R_ERROR, std::vector<pcp::StrArgs>{});
+     return false;
+   }
+   psd::CreateDBHandler db(parcel->GetUid(), GetPID());
+   db.SetOpType(pkgmgr_common::DBOperationType::OPERATION_TYPE_CREATE);
+   int ret = PM_PARSER_R_ERROR;
+   ret = db.Execute();
+   result_ = std::make_shared<pcp::ResultParcelable>(
++      ret, std::vector<pcp::StrArgs>{});
+   return true;
+ }
+ std::vector<uint8_t> CreateDBRequestHandler::ExtractResult() {
+   tizen_base::Parcel parcel;
+   parcel.WriteParcelable(*result_);
+   std::vector<uint8_t> raw = parcel.GetRaw();
+   result_.reset();
+   return raw;
+ }
+ }  // namespace request_handler
+ }  // namespace pkgmgr_server
@@@ -39,9 -39,9 +39,9 @@@ bool QueryRequestHandler::HandleRequest
      return false;
    }
  
-   pcd::QueryHandler db(parcel->GetUid(), GetPID());
+   psd::QueryHandler db(parcel->GetUid(), GetPID());
    db.SetLocale(locale);
 -  db.SetQueryArgs(parcel->GetQueryArgs());
 +  db.SetQueryArgs(parcel->ExtractQueryArgs());
    db.SetDBType(parcel->GetDBType());
    db.SetOpType(parcel->GetOpType());
    int ret = db.Execute();
@@@ -25,8 -30,15 +30,15 @@@ TARGET_LINK_LIBRARIES(${TARGET_PKGMGR_I
  SET_TARGET_PROPERTIES(${TARGET_PKGMGR_INFO_UNIT_TEST} PROPERTIES COMPILE_FLAGS ${CFLAGS} "-fPIE -fpic")
  SET_TARGET_PROPERTIES(${TARGET_PKGMGR_INFO_UNIT_TEST} PROPERTIES LINK_FLAGS "-pie")
  set_target_properties(${TARGET_PKGMGR_INFO_UNIT_TEST} PROPERTIES COMPILE_FLAGS "${unit_test_pkgs_CFLAGS_str}")
 -target_link_libraries(${TARGET_PKGMGR_INFO_UNIT_TEST} ${unit_test_pkgs_LDFLAGS})
 +target_link_libraries(${TARGET_PKGMGR_INFO_UNIT_TEST} PRIVATE ${unit_test_pkgs_LDFLAGS})
  
+ SET_TARGET_PROPERTIES(${TARGET_PKGMGR_INFO_UNIT_TEST} PROPERTIES
+   LINK_FLAGS "-Wl,\
+ --wrap=fopen,\
+ --wrap=fopen64,\
+ --wrap=fgets,\
+ --wrap=fclose")
  ADD_TEST(
    NAME ${TARGET_PKGMGR_INFO_UNIT_TEST}
    COMMAND ${TARGET_PKGMGR_INFO_UNIT_TEST}
@@@ -69,8 -67,7 +67,7 @@@ application_x* GetTestApplication(std::
    application->guestmode_visibility = strdup("test_guestmode_visibility");
    application->component = strdup("test_component");
    application->permission_type = strdup("test_permission_type");
--  application->component_type = strdup("test_component_type");
++  application->component_type = strdup("test_component");
    application->preload = strdup("test_preload");
    application->submode = strdup("test_submode");
    application->submode_mainid = strdup("test_submode_mainid");
@@@ -406,6 -434,6 +444,8 @@@ package_x* GetTestPackage(std::string p
    package->backend_installer = strdup("test_backend_installer");
    package->external_path = strdup("test_external_path");
    package->use_system_certs = strdup("test_use_system_certs");
++  package->res_type = strdup("test_res_type");
++  package->res_version = strdup("test_res_version");
  
    icon_x* icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
    icon->text = strdup("test_text");
@@@ -628,47 -690,18 +713,40 @@@ bool IsEqualPackage(package_x* packageA
      STR_EQ(dependency_a->type, dependency_b->type);
    }
  
-   INT_EQ(g_list_length(packageA->plugin), g_list_length(packageB->plugin));
-   for (GList *a = packageA->plugin, *b = packageB->plugin;
-       a && b; a = a->next, b = b->next) {
-     plugin_x *plugin_a = reinterpret_cast<plugin_x *>(a->data);
-     plugin_x *plugin_b = reinterpret_cast<plugin_x *>(b->data);
-     STR_EQ(plugin_a->appid, plugin_b->appid);
-     STR_EQ(plugin_a->pkgid, plugin_b->pkgid);
-     STR_EQ(plugin_a->plugin_name, plugin_b->plugin_name);
-     STR_EQ(plugin_a->plugin_type, plugin_b->plugin_type);
-   }
 +  INT_EQ(g_list_length(packageA->res_allowed_packages),
 +      g_list_length(packageB->res_allowed_packages));
 +  for (GList* a = packageA->res_allowed_packages,
 +      *b = packageB->res_allowed_packages; a && b; a = a->next, b = b->next) {
 +    res_allowed_package_x* allowed_package_a =
 +        reinterpret_cast<res_allowed_package_x*>(a->data);
 +    res_allowed_package_x* allowed_package_b =
 +        reinterpret_cast<res_allowed_package_x*>(b->data);
 +    STR_EQ(allowed_package_a->allowed_package,
 +        allowed_package_b->allowed_package);
 +
 +    INT_EQ(g_list_length(allowed_package_a->required_privileges),
 +        g_list_length(allowed_package_b->required_privileges));
 +
 +    for (GList* a = allowed_package_a->required_privileges,
 +        *b = allowed_package_b->required_privileges; a && b;
 +        a = a->next, b = b->next) {
 +      STR_EQ(reinterpret_cast<char*>(a->data),
 +          reinterpret_cast<char*>(b->data));
 +    }
 +  }
 +
-   INT_EQ(g_list_length(packageA->application),
-       g_list_length(packageB->application));
-   for (GList *a = packageA->application, *b = packageB->application;
-       a && b; a = a->next, b = b->next) {
-     application_x *application_a = reinterpret_cast<application_x *>(a->data);
-     application_x *application_b = reinterpret_cast<application_x *>(b->data);
+   return true;
+ }
  
-     if (!IsEqualApplication(application_a, application_b))
+ bool IsEqualPackagesStructure(const std::vector<package_x*>& packagesA,
+     const std::vector<package_x*>&packagesB) {
+   if (packagesA.size() != packagesB.size())
+     return false;
+   for (unsigned int i = 0; i < packagesA.size(); ++i) {
+     if (!IsEqualPackage(packagesA[i], packagesB[i]))
+       return false;
+     if (!IsEqualPackageExtraInfo(packagesA[i], packagesB[i]))
        return false;
    }
  
@@@ -197,15 -177,14 +195,15 @@@ TEST_F(ParcelTest, ResultParcelable) 
  
  TEST_F(ParcelTest, QueryParcelable) {
    tizen_base::Parcel parcel;
 -  std::vector<std::pair<int, std::vector<std::string>>> query_args = {
 +  std::vector<std::pair<int, std::vector<const char*>>> query_args = {
      { 0, { "arg1", "arg2" } },
 -    { 1, { "arg1" } }
 +    { 1, { "arg1" } },
 +    { 2, { nullptr, "arg2" } }
    };
  
 -  pp::QueryParcelable origin_parcelable(0, query_args,
 +  pp::QueryParcelable origin_parcelable(0, std::move(query_args),
-       pcb::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
-       pcb::AbstractDBHandler::OperationType::OPERATION_TYPE_READ);
+       pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB,
+       pkgmgr_common::DBOperationType::OPERATION_TYPE_READ);
    pp::QueryParcelable new_parcelable;
    parcel.WriteParcelable(origin_parcelable);
    parcel.ReadParcelable(&new_parcelable);
index 0000000,6ec9b58..5ed0ccd
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,474 +1,474 @@@
 -      std::vector<std::pair<int, std::vector<std::string>>>{
+ /*
+  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  * http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ #include <gmock/gmock.h>
+ #include <gtest/gtest.h>
+ #include <cstdio>
+ #include "appinfo_db_handler.hh"
+ #include "create_db_handler.hh"
+ #include "depinfo_db_handler.hh"
+ #include "db_type.hh"
+ #include "parcel_utils.hh"
+ #include "pkg_get_db_handler.hh"
+ #include "pkg_set_db_handler.hh"
+ #include "query_handler.hh"
+ #include "mock/file_mock.h"
+ #include "mock/test_fixture.h"
+ #include "mock/system_info_mock.h"
+ #include "pkgmgr-info.h"
+ #include "pkgmgr_query_index.h"
+ #include "pkgmgrinfo_basic.h"
+ #define TEST_PARSER_DB "test.pkgmgr_parser.db"
+ namespace psd = pkgmgr_server::database;
+ namespace pc = pkgmgr_common;
+ class CreateParserDBHandlerMock : public psd::CreateDBHandler {
+  public:
+   CreateParserDBHandlerMock(uid_t uid, int pid)
+       : psd::CreateDBHandler(uid, pid) {}
+   MOCK_METHOD0(Connect, bool());
+   MOCK_METHOD0(GetConnection, std::vector<std::pair<sqlite3*, uid_t>>());
+ };
+ class PkgSetDBHandlerMock : public psd::PkgSetDBHandler {
+  public:
+   PkgSetDBHandlerMock(uid_t uid, int pid) : psd::PkgSetDBHandler(uid, pid) {}
+   MOCK_METHOD0(Connect, bool());
+   MOCK_METHOD0(GetConnection, std::vector<std::pair<sqlite3*, uid_t>>());
+ };
+ class PkgGetDBHandlerMock : public psd::PkgGetDBHandler {
+  public:
+   PkgGetDBHandlerMock(uid_t uid, int pid) : psd::PkgGetDBHandler(uid, pid) {}
+   MOCK_METHOD0(Connect, bool());
+   MOCK_METHOD0(GetConnection, std::vector<std::pair<sqlite3*, uid_t>>());
+ };
+ class AppInfoDBHandlerMock : public psd::AppInfoDBHandler {
+  public:
+   AppInfoDBHandlerMock(uid_t uid, int pid) : psd::AppInfoDBHandler(uid, pid) {}
+   MOCK_METHOD0(Connect, bool());
+   MOCK_METHOD0(GetConnection, std::vector<std::pair<sqlite3*, uid_t>>());
+ };
+ class DepInfoGetDBHandlerMock : public psd::DepInfoGetDBHandler {
+  public:
+   DepInfoGetDBHandlerMock(uid_t uid, int pid) :
+       psd::DepInfoGetDBHandler(uid, pid) {}
+   MOCK_METHOD0(Connect, bool());
+   MOCK_METHOD0(GetConnection, std::vector<std::pair<sqlite3*, uid_t>>());
+ };
+ class QueryHandlerMock : public psd::QueryHandler {
+  public:
+   QueryHandlerMock(uid_t uid, int pid) :
+       psd::QueryHandler(uid, pid) {}
+   MOCK_METHOD0(Connect, bool());
+   MOCK_METHOD0(GetConnection, std::vector<std::pair<sqlite3*, uid_t>>());
+ };
+ class Mocks : public ::testing::NiceMock<SystemInfoMock> {};
+ class ParserDBHandlerTest : public TestFixture {
+  public:
+   ParserDBHandlerTest() : TestFixture(std::make_unique<Mocks>()) {}
+   virtual ~ParserDBHandlerTest() {}
+   virtual void SetUp() {
+     sqlite3 *db;
+     ASSERT_EQ(sqlite3_open_v2(TEST_PARSER_DB, &db,
+         SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL), SQLITE_OK);
+     SetDBHandles(
+         std::vector<std::pair<sqlite3*, uid_t>> { std::make_pair(db, 0) });
+     CreateParserDBHandlerMock create_db_handler(0, 0);
+     EXPECT_CALL(create_db_handler, Connect())
+         .Times(2).WillRepeatedly(testing::Return(true));
+     EXPECT_CALL(create_db_handler, GetConnection())
+         .Times(2).WillRepeatedly(testing::Return(GetDBHandles()));
+     EXPECT_CALL(GetMock<SystemInfoMock>(),
+       system_info_get_platform_int(testing::_, testing::_))
+           .WillRepeatedly(testing::DoAll(
+                   testing::SetArgPointee<1>(120), testing::Return(0)));
+     fopen_mock_setup(true);
+     ASSERT_EQ(create_db_handler.Execute(), 0);
+     fopen_mock_setup(false);
+   }
+   virtual void TearDown() {
+     for (auto& handle : db_handles_)
+       sqlite3_close_v2(handle.first);
+     ASSERT_EQ(remove(TEST_PARSER_DB), 0);
+     std::string journal_path(TEST_PARSER_DB);
+     journal_path += "-journal";
+     ASSERT_EQ(remove(journal_path.c_str()), 0);
+   }
+   const std::vector<std::pair<sqlite3*, uid_t>>& GetDBHandles() {
+     return db_handles_;
+   }
+  private:
+   void SetDBHandles(std::vector<std::pair<sqlite3*, uid_t>>&& db_handles) {
+     db_handles_ = db_handles;
+   }
+   std::vector<std::pair<sqlite3*, uid_t>> db_handles_;
+ };
+ TEST_F(ParserDBHandlerTest, PkgSetDBHandlerTest) {
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage("pkgA"), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
+ }
+ TEST_F(ParserDBHandlerTest, PkgGetDBHandlerTest) {
+   std::string pkgid = "pkgA";
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage(pkgid), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
+   pkgmgrinfo_pkginfo_filter_h filter;
+   ASSERT_EQ(pkgmgrinfo_pkginfo_filter_create(&filter), PMINFO_R_OK);
+   std::unique_ptr<pkgmgrinfo_filter_x, decltype(
+       pkgmgrinfo_pkginfo_filter_destroy)*> filter_ptr(
+           reinterpret_cast<pkgmgrinfo_filter_x *>(filter),
+               pkgmgrinfo_pkginfo_filter_destroy);
+   ASSERT_EQ(pkgmgrinfo_pkginfo_filter_add_string(filter,
+       PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid.c_str()), PMINFO_R_OK);
+   ASSERT_EQ(pkgmgrinfo_pkginfo_filter_add_bool(filter,
+       PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false), PMINFO_R_OK);
+   PkgGetDBHandlerMock pkg_get_db_handler(0, 0);
+   pkg_get_db_handler.SetFilter(filter_ptr.get());
+   pkg_get_db_handler.SetLocale("test_lang");
+   EXPECT_CALL(pkg_get_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_get_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_get_db_handler.Execute(), 0);
+   auto lpkginfo_list = pkg_get_db_handler.GetPkgHandle();
+   ASSERT_EQ(lpkginfo_list.size(), 1);
+   auto test_pkginfo = GetTestPackage(pkgid);
+   std::vector<package_x*> rpkginfo_list;
+   rpkginfo_list.emplace_back(test_pkginfo);
+   ASSERT_EQ(IsEqualPackagesInfo(lpkginfo_list, rpkginfo_list), true);
+ }
+ TEST_F(ParserDBHandlerTest, AppInfoDBHandlerTest) {
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage("test_package"), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
+   pkgmgrinfo_appinfo_filter_h filter;
+   std::string appid = "test_app1";
+   ASSERT_EQ(pkgmgrinfo_appinfo_filter_create(&filter), PMINFO_R_OK);
+   std::unique_ptr<pkgmgrinfo_filter_x, decltype(
+       pkgmgrinfo_appinfo_filter_destroy)*> filter_ptr(
+           reinterpret_cast<pkgmgrinfo_filter_x *>(filter),
+               pkgmgrinfo_appinfo_filter_destroy);
+   ASSERT_EQ(pkgmgrinfo_appinfo_filter_add_string(filter,
+       PMINFO_APPINFO_PROP_APP_ID, appid.c_str()), PMINFO_R_OK);
+   ASSERT_EQ(pkgmgrinfo_appinfo_filter_add_bool(filter,
+       PMINFO_APPINFO_PROP_APP_DISABLE, false), PMINFO_R_OK);
+   AppInfoDBHandlerMock appinfo_db_handler(0, 0);
+   appinfo_db_handler.SetFilter(filter_ptr.get());
+   EXPECT_CALL(appinfo_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(appinfo_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   appinfo_db_handler.SetLocale("test_lang");
+   ASSERT_EQ(appinfo_db_handler.Execute(), 0);
+   auto lappinfo_list = appinfo_db_handler.GetAppHandle();
+   ASSERT_EQ(lappinfo_list.size(), 1);
+   auto test_appinfo = GetTestApplication(appid);
+   std::vector<application_x*> rappinfo_list;
+   rappinfo_list.emplace_back(test_appinfo);
+   ASSERT_EQ(IsEqualApplicationsInfo(lappinfo_list, rappinfo_list), true);
+ }
+ TEST_F(ParserDBHandlerTest, DepInfoDBHandlerTest) {
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage("test_package"), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
+   DepInfoGetDBHandlerMock depinfo_get_db_handler(0, 0);
+   depinfo_get_db_handler.SetPkgID("depends_on_pkgid");
+   EXPECT_CALL(depinfo_get_db_handler,
+       Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(depinfo_get_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(depinfo_get_db_handler.Execute(), 0);
+   auto depinfo_from_db = depinfo_get_db_handler.GetDependencyList();
+   ASSERT_EQ(depinfo_from_db.size(), 1);
+   std::vector<dependency_x*> depinfo_list;
+   depinfo_list.emplace_back(GetTestDepInfo("test_package"));
+   EXPECT_TRUE(IsEqualDepInfo(depinfo_list, depinfo_from_db));
+ }
+ TEST_F(ParserDBHandlerTest, QueryDBHandler_PluginInfoTest) {
+   const std::string pkgid = "test_pkgid";
+   const std::string appid = "test_appid";
+   const std::string plugin_type = "test_plugin_type";
+   const std::string plugin_name = "test_plugin_name";
+   QueryHandlerMock set_query_handler(0, 0);
+   set_query_handler.SetQueryArgs(
 -              std::vector<std::string>{
++      std::vector<std::pair<int, std::vector<std::optional<std::string>>>>{
+           std::make_pair(
+               QUERY_INDEX_INSERT_PACKAGE_PLUGIN_EXECUTION_INFO,
 -      std::vector<std::pair<int, std::vector<std::string>>>{
++              std::vector<std::optional<std::string>>{
+                   pkgid, appid, plugin_type, plugin_name})});
+   set_query_handler.SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB);
+   set_query_handler.SetOpType(
+       pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE);
+   EXPECT_CALL(set_query_handler,
+       Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(set_query_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(set_query_handler.Execute(), 0);
+   QueryHandlerMock get_query_handler(0, 0);
+   get_query_handler.SetQueryArgs(
 -              std::vector<std::string>{pkgid, plugin_type, plugin_name})});
++      std::vector<std::pair<int, std::vector<std::optional<std::string>>>>{
+           std::make_pair(
+               QUERY_INDEX_PLUGININFO_GET_APPIDS,
 -  std::vector<std::pair<int, std::vector<std::string>>> query_args;
 -  std::vector<std::vector<std::string>> expected_label;
++              std::vector<std::optional<std::string>>{pkgid, plugin_type, plugin_name})});
+   get_query_handler.SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB);
+   get_query_handler.SetOpType(
+       pkgmgr_common::DBOperationType::OPERATION_TYPE_READ);
+   EXPECT_CALL(get_query_handler,
+       Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(get_query_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(get_query_handler.Execute(), 0);
+   auto result = get_query_handler.GetResult();
+   ASSERT_EQ(result.size(), 1);
+   ASSERT_EQ(result[0].size(), 1);
+   ASSERT_EQ(appid, result[0][0]);
+ }
+ TEST_F(ParserDBHandlerTest, QueryDBHandler_GetLocaledLabelTest) {
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage("test_package"), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
 -          std::vector<std::string>{app->appid, label->lang}));
 -      expected_label.emplace_back(std::vector<std::string>{label->text});
++  std::vector<std::pair<int, std::vector<std::optional<std::string>>>> query_args;
++  std::vector<std::vector<std::optional<std::string>>> expected_label;
+   for (GList* app_list = ptr.get()->application; app_list;
+       app_list = app_list->next) {
+     application_x* app = reinterpret_cast<application_x*>(app_list->data);
+     ASSERT_NE(app, nullptr);
+     ASSERT_NE(app->appid, nullptr);
+     ASSERT_NE(app->label, nullptr);
+     for (GList* label_list = app->label; label_list;
+         label_list = label_list->next) {
+       label_x* label = reinterpret_cast<label_x*>(label_list->data);
+       ASSERT_NE(label, nullptr);
+       ASSERT_NE(label->lang, nullptr);
+       ASSERT_NE(label->text, nullptr);
+       query_args.emplace_back(std::make_pair(
+           QUERY_INDEX_APPINFO_GET_LOCALED_LABEL,
 -  std::vector<std::pair<int, std::vector<std::string>>> query_args;
 -  std::vector<std::vector<std::string>> expected_label;
++          std::vector<std::optional<std::string>>{app->appid, label->lang}));
++      expected_label.emplace_back(std::vector<std::optional<std::string>>{label->text});
+     }
+   }
+   QueryHandlerMock query_handler(0, 0);
+   query_handler.SetQueryArgs(std::move(query_args));
+   query_handler.SetDBType(pc::DBType::DB_TYPE_FILE_PKGDB);
+   query_handler.SetOpType(pc::DBOperationType::OPERATION_TYPE_READ);
+   EXPECT_CALL(query_handler,
+       Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(query_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(query_handler.Execute(), 0);
+   auto result = query_handler.GetResult();
+   ASSERT_EQ(result, expected_label);
+ }
+ TEST_F(ParserDBHandlerTest, QueryDBHandler_GetDataControlTest) {
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage("test_package"), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
 -          std::vector<std::string>{dc->providerid, dc->type}));
++  std::vector<std::pair<int, std::vector<std::optional<std::string>>>> query_args;
++  std::vector<std::vector<std::optional<std::string>>> expected_label;
+   for (GList* app_list = ptr.get()->application; app_list;
+       app_list = app_list->next) {
+     application_x* app = reinterpret_cast<application_x*>(app_list->data);
+     ASSERT_NE(app, nullptr);
+     ASSERT_NE(app->appid, nullptr);
+     ASSERT_NE(app->datacontrol, nullptr);
+     for (GList* dc_list = app->datacontrol; dc_list; dc_list = dc_list->next) {
+       datacontrol_x* dc = reinterpret_cast<datacontrol_x*>(dc_list->data);
+       ASSERT_NE(dc, nullptr);
+       ASSERT_NE(dc->providerid, nullptr);
+       ASSERT_NE(dc->type, nullptr);
+       ASSERT_NE(dc->access, nullptr);
+       query_args.emplace_back(std::make_pair(
+           QUERY_INDEX_APPINFO_GET_DATACONTROL_INFO,
 -          std::vector<std::string>{app->appid, dc->access});
++          std::vector<std::optional<std::string>>{dc->providerid, dc->type}));
+       expected_label.emplace_back(
 -  std::vector<std::pair<int, std::vector<std::string>>> query_args;
 -  std::vector<std::vector<std::string>> expected_appids;
 -  std::map<std::string, std::vector<std::string>> provider_map;
++          std::vector<std::optional<std::string>>{app->appid, dc->access});
+     }
+   }
+   QueryHandlerMock query_handler(0, 0);
+   query_handler.SetQueryArgs(std::move(query_args));
+   query_handler.SetDBType(pc::DBType::DB_TYPE_FILE_PKGDB);
+   query_handler.SetOpType(pc::DBOperationType::OPERATION_TYPE_READ);
+   EXPECT_CALL(query_handler,
+       Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(query_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(query_handler.Execute(), 0);
+   auto result = query_handler.GetResult();
+   ASSERT_EQ(result, expected_label);
+ }
+ TEST_F(ParserDBHandlerTest, QueryDBHandler_GetDataControlAppIdTest) {
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage("test_package"), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
 -        std::vector<std::string>{std::move(it.first)}));
++  std::vector<std::pair<int, std::vector<std::optional<std::string>>>> query_args;
++  std::vector<std::vector<std::optional<std::string>>> expected_appids;
++  std::map<std::string, std::vector<std::optional<std::string>>> provider_map;
+   for (GList* app_list = ptr.get()->application; app_list;
+       app_list = app_list->next) {
+     application_x* app = reinterpret_cast<application_x*>(app_list->data);
+     ASSERT_NE(app, nullptr);
+     ASSERT_NE(app->appid, nullptr);
+     ASSERT_NE(app->datacontrol, nullptr);
+     for (GList* dc_list = app->datacontrol; dc_list; dc_list = dc_list->next) {
+       datacontrol_x* dc = reinterpret_cast<datacontrol_x*>(dc_list->data);
+       ASSERT_NE(dc, nullptr);
+       ASSERT_NE(dc->providerid, nullptr);
+       ASSERT_NE(dc->type, nullptr);
+       ASSERT_NE(dc->access, nullptr);
+       provider_map[dc->providerid].emplace_back(app->appid);
+     }
+   }
+   for (auto& it : provider_map) {
+     query_args.emplace_back(std::make_pair(
+         QUERY_INDEX_APPINFO_GET_DATACONTROL_APPID,
++        std::vector<std::optional<std::string>>{std::move(it.first)}));
+     expected_appids.emplace_back(std::move(it.second));
+   }
+   QueryHandlerMock query_handler(0, 0);
+   query_handler.SetQueryArgs(std::move(query_args));
+   query_handler.SetDBType(pc::DBType::DB_TYPE_FILE_PKGDB);
+   query_handler.SetOpType(pc::DBOperationType::OPERATION_TYPE_READ);
+   EXPECT_CALL(query_handler,
+       Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(query_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(query_handler.Execute(), 0);
+   auto result = query_handler.GetResult();
+   ASSERT_NE(result.size(), 0);
+   for (auto& it : result)
+     std::sort(it.begin(), it.end());
+   for (auto& it : expected_appids)
+     std::sort(it.begin(), it.end());
+   ASSERT_EQ(result, expected_appids);
+ }