Add package paremeter to application filter
[platform/core/appfw/pkgmgr-info.git] / src / server / database / db_handle_provider.cc
index 79a0312..258862e 100644 (file)
@@ -33,7 +33,6 @@
 #include "pkgmgr-info.h"
 #include "pkgmgrinfo_debug.h"
 #include "pkgmgrinfo_internal.h"
-#include "pkgmgrinfo_internal.hh"
 #include "pkgmgrinfo_private.h"
 
 #ifdef LOG_TAG
@@ -337,14 +336,14 @@ bool DBHandleProvider::IsWriter(pid_t pid) {
   return writer_pid_list_.find(pid) != writer_pid_list_.end();
 }
 
-int DBHandleProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write,
-    const std::string& locale) {
+int DBHandleProvider::UpdateCache(const tizen_base::Database& db, pid_t pid,
+    uid_t uid, bool write, const std::string& locale) {
   pkg_map_.clear();
   app_map_.clear();
   pending_pkg_.clear();
   pkg_app_map_.clear();
 
-  const char* dbpath = sqlite3_db_filename(db, "main");
+  const char* dbpath = sqlite3_db_filename(db.GetRaw(), "main");
   bool is_inmemory_db = false;
   if (dbpath == nullptr || strlen(dbpath) == 0) {
     LOG(INFO) << "database is inmemory db";
@@ -356,31 +355,15 @@ int DBHandleProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write,
   if (!is_inmemory_db && !GetModifiedTime(dbpath, &start_time))
     return PMINFO_R_ERROR;
 
-  GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal);
-  if (list == nullptr) {
-    LOG(ERROR) << "Out of memory";
-    return PMINFO_R_ERROR;
-  }
-
   pkgmgrinfo_filter_x tmp_filter = { 0, };
   tmp_filter.cache_flag = true;
-  int ret = pkginfo_internal_filter_get_list(db, &tmp_filter, uid_,
-                                             locale.c_str(), list);
+  std::map<std::string, std::shared_ptr<package_x>> pkgs;
+  int ret = internal::GetPkgInfo(db, &tmp_filter, uid_, locale, pkgs);
   if (ret == PMINFO_R_OK) {
-    GHashTableIter iter;
-    gpointer value;
-    g_hash_table_iter_init(&iter, list);
-    while (g_hash_table_iter_next(&iter, nullptr, &value)) {
-      auto* pkg = reinterpret_cast<package_x*>(value);
-      std::string pkgid = pkg->package;
-      AddPackage(std::move(pkgid), pkg);
-    }
+    for (auto& [key, val] : pkgs)
+      AddPackage(std::move(key), std::move(val));
   }
 
-  g_hash_table_destroy(list);
-  if (ret == PMINFO_R_ERROR)
-    return ret;
-
   if (!is_inmemory_db && !GetModifiedTime(dbpath, &end_time))
     return PMINFO_R_ERROR;
 
@@ -391,8 +374,7 @@ int DBHandleProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write,
   }
 
   std::vector<std::shared_ptr<application_x>> app_list;
-  ret = pkgmgr_server::internal::appinfo_internal_filter_get_list(db,
-      &tmp_filter, uid_, uid, locale.c_str(), app_list);
+  ret = internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, app_list);
 
   if (!is_inmemory_db && !GetModifiedTime(dbpath, &end_time))
     return PMINFO_R_ERROR;
@@ -422,8 +404,26 @@ int DBHandleProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write,
   return ret;
 }
 
+inline bool CheckMetadataFilter(GList* metadata_list,
+    const std::unordered_map<std::string, std::string>& metadata_map) {
+  for (auto* it = metadata_list; it != nullptr; it = g_list_next(it)) {
+    auto* node = reinterpret_cast<metadata_x*>(it->data);
+    if (node->key != nullptr) {
+      auto metadata = metadata_map.find(node->key);
+      if (metadata == metadata_map.end())
+        continue;
+
+      if (metadata->second.empty() ||
+          strcmp(node->value ? node->value : "", metadata->second.c_str()) == 0)
+        return true;
+    }
+  }
+  return false;
+}
+
 inline bool CheckPkgFilters(pkgmgrinfo_filter_x* filter,
-    const std::shared_ptr<package_x>& info) {
+    const std::shared_ptr<package_x>& info,
+    const std::unordered_map<std::string, std::string>& metadata_map) {
   for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) {
     auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
     auto* checker = FilterCheckerProvider::GetInst().
@@ -432,7 +432,11 @@ inline bool CheckPkgFilters(pkgmgrinfo_filter_x* filter,
       return false;
   }
 
-  return true;
+  bool pass = true;
+  if (!metadata_map.empty())
+    pass = CheckMetadataFilter(info->metadata, metadata_map);
+
+  return pass;
 }
 
 std::vector<std::shared_ptr<package_x>> DBHandleProvider::GetPackages(
@@ -440,7 +444,18 @@ std::vector<std::shared_ptr<package_x>> DBHandleProvider::GetPackages(
     const std::string& package) {
   std::vector<std::shared_ptr<package_x>> ret;
 
-  if (__check_package_storage_status(filter)) {
+  /* make metadata filter map */
+  std::unordered_map<std::string, std::string> metadata_map;
+  for (auto* it = filter->list_pkg_metadata; it != nullptr;
+      it = g_slist_next(it)) {
+    auto node = reinterpret_cast<pkgmgrinfo_metadata_node_x*>(it->data);
+    if (node->key == nullptr)
+      continue;
+    LOG(ERROR) << "add metadata filter";
+    metadata_map[node->key] = (node->value ? node->value : "");
+  }
+
+  if (internal::CheckPackageStorageStatus(filter)) {
     if (pkgmgrinfo_pkginfo_filter_add_bool(filter,
         PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE, true) != PMINFO_R_OK) {
       LOG(ERROR) << "Fail to add check storage value to filter";
@@ -449,53 +464,49 @@ std::vector<std::shared_ptr<package_x>> DBHandleProvider::GetPackages(
   }
   if (package.empty()) {
     for (auto& info : pkg_map_) {
-      if (CheckPkgFilters(filter, info.second))
+      if (CheckPkgFilters(filter, info.second, metadata_map))
         ret.push_back(info.second);
     }
   } else {
     auto map_it = pkg_map_.find(package);
-    if (map_it != pkg_map_.end() && CheckPkgFilters(filter, map_it->second))
+    if (map_it != pkg_map_.end() && CheckPkgFilters(filter, map_it->second,
+        metadata_map))
       ret.push_back(map_it->second);
   }
 
   return ret;
 }
 
-void DBHandleProvider::AddPackage(std::string package, package_x* info) {
-  auto ptr = std::shared_ptr<package_x>(info, pkgmgrinfo_basic_free_package);
-  pkg_map_[package] = std::move(ptr);
+void DBHandleProvider::AddPackage(std::string package,
+    std::shared_ptr<package_x> info) {
+  pkg_map_[package] = std::move(info);
 }
 
 inline bool CheckAppFilters(pkgmgrinfo_filter_x* filter,
-    const std::shared_ptr<application_x>& info,
-    const std::unordered_map<std::string, std::string>& metadata_map) {
-    for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) {
-      auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
-      auto* checker = FilterCheckerProvider::GetInst().
-          GetAppFilterChecker(node->prop);
-      if (!checker->CheckFilter(node, info.get()))
-        return false;
-    }
+  const std::shared_ptr<application_x>& app_info,
+  const std::shared_ptr<package_x>& pkg_info,
+  const std::unordered_map<std::string, std::string>& metadata_map) {
+  for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) {
+    auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
+    auto* checker = FilterCheckerProvider::GetInst().
+        GetAppFilterChecker(node->prop);
+    if (!checker->CheckFilter(node, app_info.get(), pkg_info.get()))
+      return false;
+  }
 
-    bool pass = true;
-    if (!metadata_map.empty()) {
-      pass = false;
-      for (auto* it = info->metadata; it != nullptr; it = g_list_next(it)) {
-        auto* node = reinterpret_cast<metadata_x*>(it->data);
-        if (node->key != nullptr) {
-          auto metadata = metadata_map.find(node->key);
-          if (metadata == metadata_map.end())
-            continue;
-
-          if (metadata->second.empty() ||
-              strcmp(node->value ? node->value : "",
-                  metadata->second.c_str()) == 0)
-            return true;
-        }
-      }
-    }
+  bool pass = true;
+  if (!metadata_map.empty())
+    pass = CheckMetadataFilter(app_info->metadata, metadata_map);
+  return pass;
+}
+
+std::shared_ptr<package_x> DBHandleProvider::GetPackageByApp(
+    const char* appid) {
+  auto it = pkg_map_.find(appid);
+  if (it == pkg_map_.end())
+    return nullptr;
 
-    return pass;
+  return it->second;
 }
 
 std::vector<std::shared_ptr<application_x>> DBHandleProvider::GetApplications(
@@ -512,7 +523,7 @@ std::vector<std::shared_ptr<application_x>> DBHandleProvider::GetApplications(
   }
 
   std::vector<std::shared_ptr<application_x>> ret;
-  if (pkgmgr_server::internal::check_app_storage_status(filter)) {
+  if (internal::CheckAppStorageStatus(filter)) {
     if (pkgmgrinfo_appinfo_filter_add_bool(filter,
         PMINFO_APPINFO_PROP_APP_CHECK_STORAGE, true) != PMINFO_R_OK) {
       LOG(ERROR) << "Fail to add check storage value to filter";
@@ -522,13 +533,15 @@ std::vector<std::shared_ptr<application_x>> DBHandleProvider::GetApplications(
 
   if (app.empty()) {
     for (auto& info : app_map_) {
-      if (CheckAppFilters(filter, info.second, metadata_map))
+      if (CheckAppFilters(filter, info.second,
+          GetPackageByApp(info.second->package), metadata_map))
         ret.push_back(info.second);
     }
   } else {
     auto map_it = app_map_.find(app);
     if (map_it != app_map_.end() &&
-        CheckAppFilters(filter, map_it->second, metadata_map))
+        CheckAppFilters(filter, map_it->second,
+            GetPackageByApp(map_it->second->package), metadata_map))
       ret.push_back(map_it->second);
   }
 
@@ -560,20 +573,15 @@ void DBHandleProvider::RegisterPendingPackageInfo(package_x* info) {
   pending_pkg_.emplace(info->package);
 }
 
-bool DBHandleProvider::UpdatePendingPackageInfo(sqlite3* db,
+void DBHandleProvider::UpdatePendingPackageInfo(const tizen_base::Database& db,
     pid_t pid, uid_t uid, const std::string& locale) {
-  GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal);
-  if (list == nullptr) {
-    LOG(ERROR) << "Out of memory";
-    return false;
-  }
-
   pkgmgrinfo_filter_x tmp_filter = { 0, };
   pkgmgrinfo_node_x node = {
     .prop = E_PMINFO_PKGINFO_PROP_PACKAGE_ID
   };
   tmp_filter.cache_flag = true;
   tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node);
+  std::map<std::string, std::shared_ptr<package_x>> pkgs;
   for (const auto& pkg : pending_pkg_) {
     pkg_map_.erase(pkg);
     for (auto& appid : pkg_app_map_[pkg]) {
@@ -582,49 +590,31 @@ bool DBHandleProvider::UpdatePendingPackageInfo(sqlite3* db,
 
     pkg_app_map_.erase(pkg);
     node.value = const_cast<char*>(pkg.c_str());
-    pkginfo_internal_filter_get_list(db, &tmp_filter,
-        uid_, locale.c_str(), list);
+    internal::GetPkgInfo(db, &tmp_filter, uid_, locale, pkgs);
   }
 
-  GHashTableIter iter;
-  gpointer value;
-  g_hash_table_iter_init(&iter, list);
-  while (g_hash_table_iter_next(&iter, nullptr, &value)) {
-    auto* pkg = reinterpret_cast<package_x*>(value);
-    std::string pkgid = pkg->package;
-    AddPackage(std::move(pkgid), pkg);
-  }
+  for (auto& [key, val] : pkgs)
+    AddPackage(key, val);
 
-  g_hash_table_iter_init(&iter, list);
   node.prop = E_PMINFO_APPINFO_PROP_APP_PACKAGE;
-  while (g_hash_table_iter_next(&iter, nullptr, &value)) {
-    auto* pkg = reinterpret_cast<package_x*>(value);
-    node.value = pkg->package;
+  for (auto& [key, val] : pkgs) {
+    node.value = val->package;
     std::vector<std::shared_ptr<application_x>> app_list;
-    pkgmgr_server::internal::appinfo_internal_filter_get_list(
-        db, &tmp_filter, uid_, uid, locale.c_str(), app_list);
+    internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, app_list);
 
     for (auto& app : app_list) {
-      app->privileges = pkg->privileges;
+      app->privileges = val->privileges;
       std::string appid = app->appid;
       AddApplication(std::move(appid), std::move(app));
     }
   }
 
-  g_hash_table_destroy(list);
   g_slist_free(tmp_filter.list);
   pending_pkg_.clear();
-  return true;
 }
 
-bool DBHandleProvider::UpdateCachePkg(sqlite3* db, uid_t uid,
+bool DBHandleProvider::UpdateCachePkg(const tizen_base::Database& db, uid_t uid,
     const std::string& pkgid, const std::string& locale) {
-  GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal);
-  if (list == nullptr) {
-    LOG(ERROR) << "Out of memory";
-    return false;
-  }
-
   pkgmgrinfo_filter_x tmp_filter = { 0, };
   pkgmgrinfo_node_x node = {
     .prop = E_PMINFO_PKGINFO_PROP_PACKAGE_ID,
@@ -632,43 +622,30 @@ bool DBHandleProvider::UpdateCachePkg(sqlite3* db, uid_t uid,
   };
   tmp_filter.cache_flag = true;
   tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node);
-  pkginfo_internal_filter_get_list(db, &tmp_filter,
-      uid_, locale.c_str(), list);
-
-  GHashTableIter iter;
-  gpointer value;
-  g_hash_table_iter_init(&iter, list);
-  while (g_hash_table_iter_next(&iter, nullptr, &value)) {
-    auto* pkg = reinterpret_cast<package_x*>(value);
-    std::string pkgid = pkg->package;
-    AddPackage(pkgid, pkg);
-
-    for (auto& appid : pkg_app_map_[pkgid]) {
+  std::map<std::string, std::shared_ptr<package_x>> pkgs;
+  internal::GetPkgInfo(db, &tmp_filter, uid_, locale, pkgs);
+  for (auto& [key, val] : pkgs) {
+    AddPackage(key, val);
+    for (auto& appid : pkg_app_map_[key]) {
       app_map_.erase(appid);
     }
 
-    pkg_app_map_.erase(pkgid);
-
+    pkg_app_map_.erase(key);
     std::vector<std::shared_ptr<application_x>> app_list;
     node.prop = E_PMINFO_APPINFO_PROP_APP_PACKAGE;
-    node.value = const_cast<char*>(pkgid.c_str());
-
-    pkgmgr_server::internal::appinfo_internal_filter_get_list(
-        db, &tmp_filter, uid_, uid, locale.c_str(), app_list);
-
+    node.value = const_cast<char*>(key.c_str());
+    internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, app_list);
     for (auto& app : app_list) {
-      app->privileges = pkg->privileges;
+      app->privileges = val->privileges;
       std::string appid = app->appid;
       AddApplication(std::move(appid), std::move(app));
     }
   }
 
-  g_hash_table_destroy(list);
-  g_slist_free(tmp_filter.list);
   return true;
 }
 
-bool DBHandleProvider::UpdateCacheApp(sqlite3* db, uid_t uid,
+bool DBHandleProvider::UpdateCacheApp(const tizen_base::Database& db, uid_t uid,
     const std::string& appid, const std::string& locale) {
   pkgmgrinfo_filter_x tmp_filter = { 0, };
   pkgmgrinfo_node_x node = {
@@ -680,8 +657,7 @@ bool DBHandleProvider::UpdateCacheApp(sqlite3* db, uid_t uid,
 
   std::vector<std::shared_ptr<application_x>> app_list;
   app_map_.erase(appid);
-  pkgmgr_server::internal::appinfo_internal_filter_get_list(db,
-      &tmp_filter, uid_, uid, locale.c_str(), app_list);
+  internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, app_list);
   g_slist_free(tmp_filter.list);
 
   for (auto& app : app_list) {
@@ -700,8 +676,8 @@ bool DBHandleProvider::UpdateCacheApp(sqlite3* db, uid_t uid,
   return true;
 }
 
-bool DBHandleProvider::UpdateCacheAppByPkgid(sqlite3* db, uid_t uid,
-    const std::string& pkgid, const std::string& locale) {
+bool DBHandleProvider::UpdateCacheAppByPkgid(const tizen_base::Database& db,
+    uid_t uid, const std::string& pkgid, const std::string& locale) {
   auto it = pkg_map_.find(pkgid);
   if (it == pkg_map_.end()) {
     LOG(ERROR) << "Can not find package from pkg_map";
@@ -719,8 +695,7 @@ bool DBHandleProvider::UpdateCacheAppByPkgid(sqlite3* db, uid_t uid,
   tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node);
 
   std::vector<std::shared_ptr<application_x>> app_list;
-  pkgmgr_server::internal::appinfo_internal_filter_get_list(
-      db, &tmp_filter, uid_, uid, locale.c_str(), app_list);
+  internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, app_list);
 
   for (auto& appid : pkg_app_map_[pkgid]) {
     app_map_.erase(appid);