From: Ilho Kim Date: Wed, 19 Oct 2022 08:18:35 +0000 (+0900) Subject: Improve handling of cache X-Git-Tag: accepted/tizen/unified/20221104.082302~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4e6159f4c76ffb285c52ec5089f9b09ae9bf60d3;hp=615470bfe11b0a8dd11ed45a0e99cf7cad42dd1a;p=platform%2Fcore%2Fappfw%2Fpkgmgr-info.git Improve handling of cache After writing the package information, entire cache is removed and created This is an inefficient process so change to update only cache that needs to be updated Change-Id: I6e7eea3e23ae392765dd9cbf53cf2bc09f06f0f7 Signed-off-by: Ilho Kim --- diff --git a/src/server/database/db_handle_provider.cc b/src/server/database/db_handle_provider.cc index 375c3eb..07b6105 100644 --- a/src/server/database/db_handle_provider.cc +++ b/src/server/database/db_handle_provider.cc @@ -296,8 +296,6 @@ void DBHandleProvider::UnsetMemoryMode(pid_t pid) { is_user_memdb_set_ = false; is_global_memdb_set_ = false; - TrimCache(); - LOG(DEBUG) << "Set Memory mode : File"; } @@ -327,6 +325,8 @@ void DBHandleProvider::ReleaseCache() { app_map_.clear(); pkg_map_.clear(); + pending_pkg_.clear(); + pkg_app_map_.clear(); CacheFlag::SetStatus(CacheFlag::Status::UNPREPARED); released_ = true; @@ -341,6 +341,8 @@ int DBHandleProvider::UpdateCache(sqlite3* 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"); bool is_inmemory_db = false; @@ -403,12 +405,13 @@ int DBHandleProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write, if (ret == PMINFO_R_OK) { for (auto& app : app_list) { - if (pkg_map_.find(app->package) == pkg_map_.end()) { + auto it = pkg_map_.find(app->package); + if (it == pkg_map_.end()) { LOG(ERROR) << "Can not find package from pkg_map"; return PMINFO_R_ERROR; } - app->privileges = pkg_map_[app->package].front()->privileges; + app->privileges = it->second->privileges; std::string appid = app->appid; AddApplication(std::move(appid), std::move(app)); } @@ -419,13 +422,23 @@ int DBHandleProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write, return ret; } +inline bool CheckPkgFilters(pkgmgrinfo_filter_x* filter, + const std::shared_ptr& info) { + for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) { + auto node = reinterpret_cast(it->data); + auto* checker = FilterCheckerProvider::GetInst(). + GetPkgFilterChecker(node->prop); + if (!checker->CheckFilter(node, info.get())) + return false; + } + + return true; +} + std::vector> DBHandleProvider::GetPackages( pid_t pid, pkgmgrinfo_filter_x* filter, const std::string& package) { std::vector> ret; - auto map_it = pkg_map_.find(package); - if (map_it == pkg_map_.end()) - return ret; if (__check_package_storage_status(filter)) { if (pkgmgrinfo_pkginfo_filter_add_bool(filter, @@ -434,20 +447,15 @@ std::vector> DBHandleProvider::GetPackages( return {}; } } - - for (auto& info : map_it->second) { - bool pass = true; - for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) { - auto node = reinterpret_cast(it->data); - auto* checker = FilterCheckerProvider::GetInst(). - GetPkgFilterChecker(node->prop); - if (!checker->CheckFilter(node, info.get())) { - pass = false; - break; - } + if (package.empty()) { + for (auto& info : pkg_map_) { + if (CheckPkgFilters(filter, info.second)) + ret.push_back(info.second); } - if (pass) - ret.push_back(info); + } else { + auto map_it = pkg_map_.find(package); + if (map_it != pkg_map_.end() && CheckPkgFilters(filter, map_it->second)) + ret.push_back(map_it->second); } return ret; @@ -455,8 +463,39 @@ std::vector> DBHandleProvider::GetPackages( void DBHandleProvider::AddPackage(std::string package, package_x* info) { auto ptr = std::shared_ptr(info, pkgmgrinfo_basic_free_package); - pkg_map_[package].push_back(ptr); - pkg_map_[""].push_back(std::move(ptr)); + pkg_map_[package] = std::move(ptr); +} + +inline bool CheckAppFilters(pkgmgrinfo_filter_x* filter, + const std::shared_ptr& info, + const std::unordered_map& metadata_map) { + for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) { + auto node = reinterpret_cast(it->data); + auto* checker = FilterCheckerProvider::GetInst(). + GetAppFilterChecker(node->prop); + if (!checker->CheckFilter(node, 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(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 pass; } std::vector> DBHandleProvider::GetApplications( @@ -473,10 +512,6 @@ std::vector> DBHandleProvider::GetApplications( } std::vector> ret; - auto map_it = app_map_.find(app); - if (map_it == app_map_.end()) - return ret; - if (pkgmgr_server::internal::check_app_storage_status(filter)) { if (pkgmgrinfo_appinfo_filter_add_bool(filter, PMINFO_APPINFO_PROP_APP_CHECK_STORAGE, true) != PMINFO_R_OK) { @@ -485,48 +520,25 @@ std::vector> DBHandleProvider::GetApplications( } } - for (auto& info : map_it->second) { - bool pass = true; - for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) { - auto node = reinterpret_cast(it->data); - auto* checker = FilterCheckerProvider::GetInst(). - GetAppFilterChecker(node->prop); - if (!checker->CheckFilter(node, info.get())) { - pass = false; - break; - } - } - if (!pass) - continue; - - if (!metadata_map.empty()) { - pass = false; - for (auto* it = info->metadata; it != nullptr; it = g_list_next(it)) { - auto* node = reinterpret_cast(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) { - pass = true; - break; - } - } - } + if (app.empty()) { + for (auto& info : app_map_) { + if (CheckAppFilters(filter, info.second, metadata_map)) + ret.push_back(info.second); } - - if (pass) - ret.push_back(info); + } else { + auto map_it = app_map_.find(app); + if (map_it != app_map_.end() && + CheckAppFilters(filter, map_it->second, metadata_map)) + ret.push_back(map_it->second); } + return ret; } -void DBHandleProvider::AddApplication(std::string app, std::shared_ptr info) { - app_map_[app].push_back(info); - app_map_[""].push_back(std::move(info)); +void DBHandleProvider::AddApplication(std::string app, + std::shared_ptr info) { + pkg_app_map_[info->package].emplace(app); + app_map_[app] = std::move(info); } void DBHandleProvider::InsertPID(pid_t pid) { @@ -541,5 +553,195 @@ bool DBHandleProvider::ErasePID(pid_t pid) { return writer_pid_list_.erase(pid) == 1; } +void DBHandleProvider::RegisterPendingPackageInfo( + package_x* info, pid_t pid) { + if (!info || !info->package) + return; + + pending_pkg_[pid].emplace(info->package); +} + +bool DBHandleProvider::UpdatePendingPackageInfo(sqlite3* db, + pid_t pid, uid_t uid, const std::string& locale) { + auto it = pending_pkg_.find(pid); + if (it == pending_pkg_.end()) { + LOG(WARNING) << "There is no package that is pending by the pid : " << pid; + return true; + } + + 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); + for (const auto& pkg : it->second) { + pkg_map_.erase(pkg); + for (auto& appid : pkg_app_map_[pkg]) { + app_map_.erase(appid); + } + + pkg_app_map_.erase(pkg); + node.value = const_cast(pkg.c_str()); + pkginfo_internal_filter_get_list(db, &tmp_filter, + uid_, locale.c_str(), list); + } + g_slist_free(tmp_filter.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(value); + std::string pkgid = pkg->package; + AddPackage(std::move(pkgid), pkg); + } + + 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(value); + node.value = pkg->package; + std::vector> app_list; + pkgmgr_server::internal::appinfo_internal_filter_get_list( + db, &tmp_filter, uid_, uid, locale.c_str(), app_list); + + for (auto& app : app_list) { + app->privileges = pkg->privileges; + std::string appid = app->appid; + AddApplication(std::move(appid), std::move(app)); + } + } + + g_hash_table_destroy(list); + pending_pkg_.erase(pid); + return true; +} + +bool DBHandleProvider::UpdateCachePkg(sqlite3* 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, + .value = const_cast(pkgid.c_str()) + }; + 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(value); + std::string pkgid = pkg->package; + AddPackage(pkgid, pkg); + + for (auto& appid : pkg_app_map_[pkgid]) { + app_map_.erase(appid); + } + + pkg_app_map_.erase(pkgid); + + std::vector> app_list; + node.prop = E_PMINFO_APPINFO_PROP_APP_PACKAGE; + node.value = const_cast(pkgid.c_str()); + + pkgmgr_server::internal::appinfo_internal_filter_get_list( + db, &tmp_filter, uid_, uid, locale.c_str(), app_list); + + for (auto& app : app_list) { + app->privileges = pkg->privileges; + std::string appid = app->appid; + AddApplication(std::move(appid), std::move(app)); + } + } + + g_slist_free(tmp_filter.list); + return true; +} + +bool DBHandleProvider::UpdateCacheApp(sqlite3* db, uid_t uid, + const std::string& appid, const std::string& locale) { + pkgmgrinfo_filter_x tmp_filter = { 0, }; + pkgmgrinfo_node_x node = { + .prop = E_PMINFO_APPINFO_PROP_APP_ID, + .value = const_cast(appid.c_str()) + }; + tmp_filter.cache_flag = true; + tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node); + + std::vector> app_list; + app_map_.erase(appid); + pkgmgr_server::internal::appinfo_internal_filter_get_list(db, + &tmp_filter, uid_, uid, locale.c_str(), app_list); + g_slist_free(tmp_filter.list); + + for (auto& app : app_list) { + auto it = pkg_map_.find(app->package); + if (it == pkg_map_.end()) { + LOG(ERROR) << "Can not find package from pkg_map"; + return false; + } + + pkg_app_map_[app->package].erase(app->appid); + app->privileges = it->second->privileges; + std::string appid = app->appid; + AddApplication(std::move(appid), std::move(app)); + } + + return true; +} + +bool DBHandleProvider::UpdateCacheAppByPkgid(sqlite3* 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"; + return false; + } + + auto& pkg = it->second; + pkgmgrinfo_filter_x tmp_filter = { 0, }; + pkgmgrinfo_node_x node = { + .prop = E_PMINFO_APPINFO_PROP_APP_PACKAGE, + .value = pkg->package + }; + + tmp_filter.cache_flag = true; + tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node); + + std::vector> app_list; + pkgmgr_server::internal::appinfo_internal_filter_get_list( + db, &tmp_filter, uid_, uid, locale.c_str(), app_list); + + for (auto& appid : pkg_app_map_[pkgid]) { + app_map_.erase(appid); + } + pkg_app_map_.erase(pkgid); + + for (auto& app : app_list) { + app->privileges = pkg->privileges; + std::string appid = app->appid; + AddApplication(std::move(appid), std::move(app)); + } + + g_slist_free(tmp_filter.list); + return true; +} + } // namespace database } // namespace pkgmgr_server diff --git a/src/server/database/db_handle_provider.hh b/src/server/database/db_handle_provider.hh index f5df1e3..6f54d0b 100644 --- a/src/server/database/db_handle_provider.hh +++ b/src/server/database/db_handle_provider.hh @@ -60,6 +60,15 @@ class EXPORT_API DBHandleProvider { pid_t pid, pkgmgrinfo_filter_x* filter, const std::string& app); void TrimCache(); + void RegisterPendingPackageInfo(package_x* info, pid_t pid); + bool UpdatePendingPackageInfo(sqlite3* db, + pid_t pid, uid_t uid, const std::string& locale); + bool UpdateCachePkg(sqlite3* db, uid_t uid, const std::string& pkgid, + const std::string& locale); + bool UpdateCacheApp(sqlite3* db, uid_t uid, const std::string& appid, + const std::string& locale); + bool UpdateCacheAppByPkgid(sqlite3* db, uid_t uid, const std::string& pkgid, + const std::string& locale); private: explicit DBHandleProvider(uid_t uid); @@ -93,10 +102,10 @@ class EXPORT_API DBHandleProvider { std::string user_parser_memdb_path_; std::string user_parser_filedb_path_; bool released_ = true; - std::unordered_map>> - pkg_map_; - std::unordered_map>> - app_map_; + std::unordered_map> pkg_map_; + std::unordered_map> app_map_; + std::unordered_map> pkg_app_map_; + std::unordered_map> pending_pkg_; }; } // namespace database diff --git a/src/server/database/pkg_set_db_handler.cc b/src/server/database/pkg_set_db_handler.cc index 9c8d0b9..58348c0 100644 --- a/src/server/database/pkg_set_db_handler.cc +++ b/src/server/database/pkg_set_db_handler.cc @@ -18,6 +18,7 @@ #include +#include "cache_flag.hh" #include "db_handle_provider.hh" #include "utils/logging.hh" @@ -72,9 +73,14 @@ int PkgSetDBHandler::Execute() { else LOG(ERROR) << "Unknown db write type"; - if (ret != PM_PARSER_R_OK) + if (is_offline_ || ret != PMINFO_R_OK) return ret; + auto lock = CacheFlag::GetWriterLock(); + if (CacheFlag::GetStatus() == CacheFlag::Status::PREPARED) + DBHandleProvider::GetInst(uid_) + .RegisterPendingPackageInfo(package_, GetPID()); + return ret; } diff --git a/src/server/database/query_handler.cc b/src/server/database/query_handler.cc index f85dcee..b34a2dc 100644 --- a/src/server/database/query_handler.cc +++ b/src/server/database/query_handler.cc @@ -17,9 +17,11 @@ #include "query_handler.hh" #include +#include #include #include "utils/logging.hh" +#include "cache_flag.hh" #include "db_handle_provider.hh" #include "pkgmgrinfo_debug.h" @@ -147,38 +149,39 @@ constexpr const char query_unregister_all_pkg_update_info[] = class QueryMaker { public: - std::vector query_raw_ = { - query_appinfo_get_localed_label, - query_appinfo_get_datacontrol_info, - query_appinfo_get_datacontrol_appid, - query_appinfo_get_datacontrol_trusted_info, - query_appinfo_get_datacontrol_privileges, - query_appinfo_get_appcontrol_privileges, - query_plugininfo_get_appids, - query_get_pkg_updateinfo_1, - query_get_pkg_updateinfo_2, - query_pkginfo_set_usr_installed_storage_1, - query_pkginfo_set_usr_installed_storage_2, - query_certinfo_compare_pkg_certinfo, - query_certinfo_compare_app_certinfo, - query_pkginfo_delete_certinfo, - - query_insert_package_plugin_execution_info, - query_delete_package_plugin_execution_info, - query_update_global_app_disable, - query_update_app_disable_info, - query_update_pkg_disable_info, - query_update_global_app_splash_screen_display_info, - query_update_app_splash_screen_display_info, - query_update_app_label_info, - query_update_app_icon_info, - query_update_tep_info, - query_register_pkg_update_info, - query_unregister_pkg_update_info, - query_unregister_all_pkg_update_info, + using CacheChangeFlag = pkgmgr_server::database::CacheChangeFlag; + std::vector> query_raw_ = { + { query_appinfo_get_localed_label, CacheChangeFlag::NONE, 0 }, + { query_appinfo_get_datacontrol_info, CacheChangeFlag::NONE, 0 }, + { query_appinfo_get_datacontrol_appid, CacheChangeFlag::NONE, 0 }, + { query_appinfo_get_datacontrol_trusted_info, CacheChangeFlag::NONE, 0 }, + { query_appinfo_get_datacontrol_privileges, CacheChangeFlag::NONE, 0 }, + { query_appinfo_get_appcontrol_privileges, CacheChangeFlag::NONE, 0 }, + { query_plugininfo_get_appids, CacheChangeFlag::NONE, 0 }, + { query_get_pkg_updateinfo_1, CacheChangeFlag::NONE, 0 }, + { query_get_pkg_updateinfo_2, CacheChangeFlag::NONE, 0 }, + { query_pkginfo_set_usr_installed_storage_1, CacheChangeFlag::PKG, 2 }, + { query_pkginfo_set_usr_installed_storage_2, CacheChangeFlag::APPBYPKG, 2 }, + { query_certinfo_compare_pkg_certinfo, CacheChangeFlag::NONE, 0 }, + { query_certinfo_compare_app_certinfo, CacheChangeFlag::NONE, 0 }, + { query_pkginfo_delete_certinfo, CacheChangeFlag::NONE, 0 }, + + { query_insert_package_plugin_execution_info, CacheChangeFlag::PKG, 0 }, + { query_delete_package_plugin_execution_info, CacheChangeFlag::PKG, 0 }, + { query_update_global_app_disable, CacheChangeFlag::APP, 0 }, + { query_update_app_disable_info, CacheChangeFlag::APP, 1 }, + { query_update_pkg_disable_info, CacheChangeFlag::PKG, 1 }, + { query_update_global_app_splash_screen_display_info, CacheChangeFlag::APP, 0 }, + { query_update_app_splash_screen_display_info, CacheChangeFlag::APP, 1 }, + { query_update_app_label_info, CacheChangeFlag::APP, 1 }, + { query_update_app_icon_info, CacheChangeFlag::APP, 1 }, + { query_update_tep_info, CacheChangeFlag::PKG, 1 }, + { query_register_pkg_update_info, CacheChangeFlag::NONE, 0 }, + { query_unregister_pkg_update_info, CacheChangeFlag::NONE, 0 }, + { query_unregister_all_pkg_update_info, CacheChangeFlag::NONE, 0 }, }; - const char* GetQuery(int index) { + const std::tuple& GetQueryInfo(int index) { return query_raw_[index]; } }; @@ -262,7 +265,8 @@ int QueryHandler::ExecuteReadQuery(GList* queries, GList* args_list) { return ret; } -int QueryHandler::ExecuteWriteQuery(GList* queries, GList* args_list) { +int QueryHandler::ExecuteWriteQuery(GList* queries, GList* args_list, + const std::vector>& changes) { std::unique_lock u(lock_); if (!Connect()) { LOG(ERROR) << "Failed to connect database"; @@ -271,6 +275,7 @@ int QueryHandler::ExecuteWriteQuery(GList* queries, GList* args_list) { std::vector> conn_list = GetConnection(); int ret = PMINFO_R_ERROR; + bool is_writer = DBHandleProvider::IsWriter(GetPID()); for (auto& conn : conn_list) { ret = execute_write_queries(conn.first, queries, args_list); if (ret != PMINFO_R_OK) { @@ -278,15 +283,58 @@ int QueryHandler::ExecuteWriteQuery(GList* queries, GList* args_list) { break; } } - database::DBHandleProvider::GetInst(GetUID()).TrimCache(); - return ret; + + if (ret != PMINFO_R_OK || is_writer || changes.size() == 0 || + CacheFlag::GetStatus() != CacheFlag::Status::PREPARED) + return ret; + + bool success = true; + CacheFlag::SetStatus(CacheFlag::Status::PREPARING); + auto lock = CacheFlag::GetWriterLock(); + for (auto& conn : conn_list) { + auto& provider = database::DBHandleProvider::GetInst(conn.second); + for (const auto& [flag, name] : changes) { + switch (flag) { + case CacheChangeFlag::PKG: + success = provider.UpdateCachePkg(conn.first, uid_, name, GetLocale()); + break; + case CacheChangeFlag::APP: + success = provider.UpdateCacheApp(conn.first, uid_, name, GetLocale()); + break; + case CacheChangeFlag::APPBYPKG: + success = + provider.UpdateCacheAppByPkgid(conn.first, uid_, name, GetLocale()); + break; + default: + break; + } + + if (!success) { + LOG(ERROR) << "Write query failed. " << static_cast(flag) << ' ' + << name; + break; + } + } + + if (!success) { + provider.TrimCache(); + break; + } + } + + CacheFlag::SetStatus(success ? + CacheFlag::Status::PREPARED : CacheFlag::Status::UNPREPARED); + + return PMINFO_R_OK; } int QueryHandler::Execute() { GList* queries = nullptr; GList* args_list = nullptr; - for (auto& i : query_args_) { - const char* query = __query_maker.GetQuery(i.first); + std::vector> changes; + for (auto& [queryIndex, args] : query_args_) { + const auto& query_info = __query_maker.GetQueryInfo(queryIndex); + const char* query = std::get<0>(query_info); if (query == nullptr) { LOG(ERROR) << "Failed to get query"; __free_query_list(queries, args_list); @@ -301,13 +349,33 @@ int QueryHandler::Execute() { __free_query_list(queries, args_list); return PMINFO_R_ERROR; } - arg->len = i.second.size(); - for (auto& argument : i.second) { + arg->len = args.size(); + for (auto& argument : args) { arg->argument = g_list_append(arg->argument, gpointer(argument ? (*argument).c_str() : nullptr)); } args_list = g_list_append(args_list, arg); + + if (GetOpType() == pkgmgr_common::DBOperationType::OPERATION_TYPE_READ) + continue; + + CacheChangeFlag flag = std::get<1>(query_info); + if (flag == CacheChangeFlag::NONE) + continue; + + /* Cache changed query steps */ + unsigned int idx = std::get<2>(query_info); + if (args.size() <= idx) { + LOG(ERROR) << "Invalid query argument"; + __free_query_list(queries, args_list); + return PMINFO_R_ERROR; + } + + if (!args[idx]) + continue; + + changes.emplace_back(std::make_pair(flag, *args[idx])); } if (GetOpType() == pkgmgr_common::DBOperationType::OPERATION_TYPE_READ) { @@ -315,7 +383,7 @@ int QueryHandler::Execute() { __free_query_list(queries, args_list); return ret; } else { - int ret = ExecuteWriteQuery(queries, args_list); + int ret = ExecuteWriteQuery(queries, args_list, changes); __free_query_list(queries, args_list); return ret; } diff --git a/src/server/database/query_handler.hh b/src/server/database/query_handler.hh index b060508..9ba3738 100644 --- a/src/server/database/query_handler.hh +++ b/src/server/database/query_handler.hh @@ -35,6 +35,13 @@ namespace database { #define EXPORT_API __attribute__((visibility("default"))) #endif +enum class CacheChangeFlag { + NONE, + PKG, + APP, + APPBYPKG +}; + class EXPORT_API QueryHandler : public AbstractDBHandler { public: QueryHandler(uid_t uid, int pid); @@ -50,7 +57,8 @@ class EXPORT_API QueryHandler : public AbstractDBHandler { private: int ExecuteReadQuery(GList* queries, GList* args_list); - int ExecuteWriteQuery(GList* queries, GList* args_list); + int ExecuteWriteQuery(GList* queries, GList* args_list, + const std::vector>& changes); uid_t uid_; std::vector query_; diff --git a/src/server/database/remove_cache_db_handler.cc b/src/server/database/remove_cache_db_handler.cc index d4ca31a..f12cb48 100644 --- a/src/server/database/remove_cache_db_handler.cc +++ b/src/server/database/remove_cache_db_handler.cc @@ -16,19 +16,44 @@ #include "remove_cache_db_handler.hh" +#include "cache_flag.hh" #include "db_handle_provider.hh" namespace pkgmgr_server { namespace database { RemoveCacheDBHandler::RemoveCacheDBHandler(uid_t uid, int pid) - : AbstractDBHandler(uid, pid) {} + : AbstractDBHandler(uid, pid), uid_(uid) {} int RemoveCacheDBHandler::Execute() { std::unique_lock u(lock_); + SetOpType(pkgmgr_common::DBOperationType::OPERATION_TYPE_READ); + SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB); database::DBHandleProvider::GetInst(GetUID()).UnsetMemoryMode(GetPID()); - database::DBHandleProvider::GetInst(GetUID()).TrimCache(); + + if (!Connect()) { + database::DBHandleProvider::GetInst(GetUID()).TrimCache(); + return PMINFO_R_ERROR; + } + + std::vector> conn_list = GetConnection(); + auto lock = CacheFlag::GetWriterLock(); + if (CacheFlag::GetStatus() != CacheFlag::Status::PREPARED) + return PMINFO_R_OK; + CacheFlag::SetStatus(CacheFlag::Status::PREPARING); + bool success = true; + for (auto& conn : conn_list) { + auto& provider = database::DBHandleProvider::GetInst(conn.second); + success = provider.UpdatePendingPackageInfo(conn.first, + GetPID(), uid_, GetLocale()); + if (!success) { + provider.TrimCache(); + break; + } + } + CacheFlag::SetStatus(success ? + CacheFlag::Status::PREPARED : CacheFlag::Status::UNPREPARED); return PMINFO_R_OK; } diff --git a/src/server/database/remove_cache_db_handler.hh b/src/server/database/remove_cache_db_handler.hh index 65f56cf..b33dcea 100644 --- a/src/server/database/remove_cache_db_handler.hh +++ b/src/server/database/remove_cache_db_handler.hh @@ -32,6 +32,9 @@ class EXPORT_API RemoveCacheDBHandler : public AbstractDBHandler { public: RemoveCacheDBHandler(uid_t uid, int pid); int Execute() override; + + private: + uid_t uid_; }; } // namespace database diff --git a/src/server/request_handler/command_request_handler.cc b/src/server/request_handler/command_request_handler.cc index d98e4a4..458b3a8 100644 --- a/src/server/request_handler/command_request_handler.cc +++ b/src/server/request_handler/command_request_handler.cc @@ -43,6 +43,7 @@ bool CommandRequestHandler::HandleRequest(unsigned char* data, size_t size, if (parcel->GetCmd() == CommandType::RemoveCache) { database::RemoveCacheDBHandler db(parcel->GetUid(), GetPID()); + db.SetLocale(locale); int ret = db.Execute(); result_ = std::make_shared( ret, std::vector{});