is_user_memdb_set_ = false;
is_global_memdb_set_ = false;
- TrimCache();
-
LOG(DEBUG) << "Set Memory mode : File";
}
app_map_.clear();
pkg_map_.clear();
+ pending_pkg_.clear();
+ pkg_app_map_.clear();
CacheFlag::SetStatus(CacheFlag::Status::UNPREPARED);
released_ = true;
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;
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));
}
return ret;
}
+inline bool CheckPkgFilters(pkgmgrinfo_filter_x* filter,
+ const std::shared_ptr<package_x>& info) {
+ 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().
+ GetPkgFilterChecker(node->prop);
+ if (!checker->CheckFilter(node, info.get()))
+ return false;
+ }
+
+ return true;
+}
+
std::vector<std::shared_ptr<package_x>> DBHandleProvider::GetPackages(
pid_t pid, pkgmgrinfo_filter_x* filter,
const std::string& package) {
std::vector<std::shared_ptr<package_x>> 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,
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<pkgmgrinfo_node_x*>(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;
void DBHandleProvider::AddPackage(std::string package, package_x* info) {
auto ptr = std::shared_ptr<package_x>(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<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;
+ }
+
+ 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;
+ }
+ }
+ }
+
+ return pass;
}
std::vector<std::shared_ptr<application_x>> DBHandleProvider::GetApplications(
}
std::vector<std::shared_ptr<application_x>> 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) {
}
}
- 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<pkgmgrinfo_node_x*>(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<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) {
- 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<application_x> info) {
- app_map_[app].push_back(info);
- app_map_[""].push_back(std::move(info));
+void DBHandleProvider::AddApplication(std::string app,
+ std::shared_ptr<application_x> info) {
+ pkg_app_map_[info->package].emplace(app);
+ app_map_[app] = std::move(info);
}
void DBHandleProvider::InsertPID(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<char*>(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<package_x*>(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<package_x*>(value);
+ node.value = pkg->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);
+
+ 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<char*>(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<package_x*>(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<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);
+
+ 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<char*>(appid.c_str())
+ };
+ tmp_filter.cache_flag = true;
+ tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node);
+
+ 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);
+ 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<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);
+
+ 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
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);
std::string user_parser_memdb_path_;
std::string user_parser_filedb_path_;
bool released_ = true;
- std::unordered_map<std::string, std::vector<std::shared_ptr<package_x>>>
- pkg_map_;
- std::unordered_map<std::string, std::vector<std::shared_ptr<application_x>>>
- app_map_;
+ std::unordered_map<std::string, std::shared_ptr<package_x>> pkg_map_;
+ std::unordered_map<std::string, std::shared_ptr<application_x>> app_map_;
+ std::unordered_map<std::string, std::unordered_set<std::string>> pkg_app_map_;
+ std::unordered_map<pid_t, std::unordered_set<std::string>> pending_pkg_;
};
} // namespace database
#include <vector>
+#include "cache_flag.hh"
#include "db_handle_provider.hh"
#include "utils/logging.hh"
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;
}
#include "query_handler.hh"
#include <shared_mutex>
+#include <tuple>
#include <vector>
#include "utils/logging.hh"
+#include "cache_flag.hh"
#include "db_handle_provider.hh"
#include "pkgmgrinfo_debug.h"
class QueryMaker {
public:
- std::vector<const char*> 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<std::tuple<const char*, CacheChangeFlag, int>> 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<const char*, CacheChangeFlag, int>& GetQueryInfo(int index) {
return query_raw_[index];
}
};
return ret;
}
-int QueryHandler::ExecuteWriteQuery(GList* queries, GList* args_list) {
+int QueryHandler::ExecuteWriteQuery(GList* queries, GList* args_list,
+ const std::vector<std::pair<CacheChangeFlag, std::string>>& changes) {
std::unique_lock<std::shared_mutex> u(lock_);
if (!Connect()) {
LOG(ERROR) << "Failed to connect database";
std::vector<std::pair<sqlite3*, uid_t>> 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) {
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<int>(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<std::pair<CacheChangeFlag, std::string>> 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);
__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) {
__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;
}
#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);
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<std::pair<CacheChangeFlag, std::string>>& changes);
uid_t uid_;
std::vector<std::string> query_;
#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<std::shared_mutex> 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<std::pair<sqlite3*, uid_t>> 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;
}
public:
RemoveCacheDBHandler(uid_t uid, int pid);
int Execute() override;
+
+ private:
+ uid_t uid_;
};
} // namespace database
if (parcel->GetCmd() == CommandType::RemoveCache) {
database::RemoveCacheDBHandler db(parcel->GetUid(), GetPID());
+ db.SetLocale(locale);
int ret = db.Execute();
result_ = std::make_shared<pcp::ResultParcelable>(
ret, std::vector<pcp::StrArgs>{});