Implement pkgmgrinfo_pkginfo_set_installed_storage
authorIlho Kim <ilho159.kim@samsung.com>
Sun, 28 Feb 2021 03:57:34 +0000 (12:57 +0900)
committer김일호/Tizen Platform Lab(SR)/Engineer/삼성전자 <ilho159.kim@samsung.com>
Wed, 3 Mar 2021 10:27:40 +0000 (19:27 +0900)
Signed-off-by: Ilho Kim <ilho159.kim@samsung.com>
13 files changed:
src/common/database/abstract_db_handler.cc
src/common/database/abstract_db_handler.hh
src/common/database/query_handler.cc
src/common/database/query_handler.hh
src/common/parcel/query_parcelable.cc
src/common/parcel/query_parcelable.hh
src/common/request_handler/query_request_handler.cc
src/manager/pkginfo_manager.cc
src/manager/pkginfo_manager.h
src/pkginfo_internal.c
src/pkgmgrinfo_db.c
src/pkgmgrinfo_internal.h
test/unit_tests/test_parcel.cc

index 70d7bd2..872c53e 100644 (file)
@@ -286,5 +286,7 @@ void AbstractDBHandler::SetLocale(const std::string& locale) {
 
 void AbstractDBHandler::SetDBType(DBType type) { db_type_ = type; }
 
+AbstractDBHandler::OperationType AbstractDBHandler::GetOpType() { return op_type_; }
+
 }  // namespace database
 }  // namespace pkgmgr_common
index 0c7099a..16a4e50 100644 (file)
@@ -49,6 +49,7 @@ class EXPORT_API AbstractDBHandler {
   void SetLocale(const std::string& locale);
   void SetDBType(DBType type);
   void SetOpType(OperationType type);
+  OperationType GetOpType();
 
  protected:
   bool Connect();
index e260c70..7764412 100644 (file)
@@ -25,7 +25,7 @@ QueryHandler::QueryHandler(uid_t uid) : AbstractDBHandler(uid), uid_(uid) {}
 
 QueryHandler::~QueryHandler() {}
 
-void QueryHandler::SetQuery(std::string query) {
+void QueryHandler::SetQuery(std::vector<std::string> query) {
   query_ = query;
 }
 
@@ -44,24 +44,44 @@ bool QueryHandler::Execute() {
   GList* list =nullptr;
   int row = 0;
   int col = 0;
-  int ret = get_query_result(GetConnection(), query_.c_str(), &list, &row, &col);
-  if (ret != PMINFO_R_OK) {
-    // TODO: error log
+  if (query_.size() == 0)
     return false;
-  }
 
-  result_.clear();
-  result_.resize(row);
-  GList* tmp = list;
-  for (int i = 0; i < row; ++i) {
-    for (int j = 0; j < col; ++j) {
-      result_[i].emplace_back(reinterpret_cast<char *>(tmp->data));
-      tmp = tmp->next;
+  if (GetOpType() == OPERATION_TYPE_READ) {
+    int ret = get_query_result(GetConnection(), query_[0].c_str(), &list, &row, &col);
+    if (ret != PMINFO_R_OK) {
+      // TODO: error log
+      return false;
     }
-  }
 
-  g_list_free(list);
-  return true;
+    result_.clear();
+    result_.resize(row);
+    GList* tmp = list;
+    for (int i = 0; i < row; ++i) {
+      for (int j = 0; j < col; ++j) {
+        result_[i].emplace_back(reinterpret_cast<char *>(tmp->data));
+        tmp = tmp->next;
+      }
+    }
+
+    g_list_free(list);
+    return true;
+  } else {
+    result_.clear();
+    result_.resize(1);
+    const char **queries = (const char **)calloc(query_.size(), sizeof(char *));
+    int i = 0;
+    for (const auto& query : query_)
+      queries[i++] = query.c_str();
+
+    int ret = execute_write_queries(GetConnection(), queries, query_.size());
+    if (ret != 0)
+      result_[0].emplace_back("FAIL");
+    else
+      result_[0].emplace_back("SUCCESS");
+    free(queries);
+    return true;
+  }
 }
 
 }  // namespace database
index a1df5b4..93eba5c 100644 (file)
@@ -37,7 +37,7 @@ class EXPORT_API QueryHandler : public AbstractDBHandler{
  public:
   QueryHandler(uid_t uid);
   ~QueryHandler();
-  void SetQuery(std::string query);
+  void SetQuery(std::vector<std::string> query);
   bool BindString(std::string value);
   bool BindInt(int value);
   std::string GetString();
@@ -48,7 +48,7 @@ class EXPORT_API QueryHandler : public AbstractDBHandler{
 
  private:
   uid_t uid_;
-  std::string query_;
+  std::vector<std::string> query_;
   std::vector<std::vector<std::string>> result_;
 };
 
index 0d66367..1d6d12f 100644 (file)
@@ -25,32 +25,43 @@ namespace pkgmgr_common {
 namespace parcel {
 
 QueryParcelable::QueryParcelable()
-    : AbstractParcelable(0, ParcelableType::Query), query_(""), db_type_(AbstractDBHandler::DBType::DB_TYPE_NONE), op_type_(AbstractDBHandler::OperationType::OPERATION_TYPE_NONE) {}
+    : AbstractParcelable(0, ParcelableType::Query), db_type_(AbstractDBHandler::DBType::DB_TYPE_NONE), op_type_(AbstractDBHandler::OperationType::OPERATION_TYPE_NONE) {}
 
-QueryParcelable::QueryParcelable(uid_t uid, std::string query, AbstractDBHandler::DBType db_type, AbstractDBHandler::OperationType op_type)
-    : AbstractParcelable(uid, ParcelableType::Query), query_(query), db_type_(db_type), op_type_(op_type) {}
+
+QueryParcelable::QueryParcelable(uid_t uid, std::string query,
+    AbstractDBHandler::DBType db_type, AbstractDBHandler::OperationType op_type)
+    : AbstractParcelable(0, ParcelableType::Query), queries_(std::vector<std::string>{query}), db_type_(db_type), op_type_(op_type) {}
+
+QueryParcelable::QueryParcelable(uid_t uid, std::vector<std::string> queries, AbstractDBHandler::DBType db_type, AbstractDBHandler::OperationType op_type)
+    : AbstractParcelable(uid, ParcelableType::Query), queries_(queries), db_type_(db_type), op_type_(op_type) {}
 
 void QueryParcelable::WriteToParcel(tizen_base::Parcel* parcel) const {
   AbstractParcelable::WriteToParcel(parcel);
-  parcel->WriteString(query_);
+  WriteInt(parcel, queries_.size());
+  for (const auto& query : queries_)
+    parcel->WriteString(query);
   WriteInt(parcel, db_type_);
   WriteInt(parcel, op_type_);
 }
 
 void QueryParcelable::ReadFromParcel(tizen_base::Parcel* parcel) {
+  int query_size = 0;
   int op_type = 0;
   int db_type = 0;
 
   AbstractParcelable::ReadFromParcel(parcel);
-  query_ = parcel->ReadString();
+  ReadInt(parcel, &query_size);
+  for (int i = 0; i < query_size; ++i) {
+    queries_.emplace_back(parcel->ReadString());
+  }
   ReadInt(parcel, &db_type);
   db_type_ = static_cast<AbstractDBHandler::DBType>(db_type);
   ReadInt(parcel, &op_type);
   op_type_ = static_cast<AbstractDBHandler::OperationType>(op_type);
 }
 
-const std::string& QueryParcelable::GetQuery() {
-  return query_;
+const std::vector<std::string>& QueryParcelable::GetQueries() {
+  return queries_;
 }
 
 AbstractDBHandler::DBType QueryParcelable::GetDBType() {
index 7b2e260..63b52c0 100644 (file)
@@ -26,7 +26,8 @@ class EXPORT_API QueryParcelable : public AbstractParcelable {
 
   QueryParcelable();
   QueryParcelable(uid_t uid, std::string query, AbstractDBHandler::DBType db_type, AbstractDBHandler::OperationType op_type);
-  const std::string& GetQuery();
+  QueryParcelable(uid_t uid, std::vector<std::string> query, AbstractDBHandler::DBType db_type, AbstractDBHandler::OperationType op_type);
+  const std::vector<std::string>& GetQueries();
   AbstractDBHandler::DBType GetDBType();
   AbstractDBHandler::OperationType GetOpType();
 
@@ -34,7 +35,7 @@ class EXPORT_API QueryParcelable : public AbstractParcelable {
   void ReadFromParcel(tizen_base::Parcel* parcel) override;
 
  private:
-  std::string query_;
+  std::vector<std::string> queries_;
   AbstractDBHandler::DBType db_type_;
   AbstractDBHandler::OperationType op_type_;
 };
index d1fca70..a1a90b0 100644 (file)
@@ -28,7 +28,7 @@ bool QueryRequestHandler::HandleRequest(unsigned char* data, int size,
 
   QueryHandler db(parcel->GetUid());
   db.SetLocale(locale);
-  db.SetQuery(parcel->GetQuery());
+  db.SetQuery(parcel->GetQueries());
   db.SetDBType(parcel->GetDBType());
   db.SetOpType(parcel->GetOpType());
   if (db.Execute() == false) return false;
index af51152..630a2b4 100644 (file)
@@ -567,3 +567,64 @@ extern "C" EXPORT_API int _get_pkg_updateinfo(const char *pkgid,
 
        return PMINFO_R_OK;
 }
+
+extern "C" EXPORT_API int _pkginfo_set_usr_installed_storage(const char *pkgid,
+               INSTALL_LOCATION location, const char *external_pkg_path,
+               uid_t uid)
+{
+       char *query = NULL;
+       const char *location_str;
+       std::vector<std::string> queries;
+
+       if (location == INSTALL_INTERNAL)
+               location_str = "installed_internal";
+       else if (location == INSTALL_EXTERNAL)
+               location_str = "installed_external";
+       else
+               location_str = "installed_extended";
+       /* pkgcakge_info table */
+       query = sqlite3_mprintf(
+                       "update package_info set installed_storage=%Q, external_path=%Q where package=%Q",
+                       location_str, external_pkg_path, pkgid);
+       queries.emplace_back(query);
+       sqlite3_free(query);
+
+       /* package_app_info table */
+       query = sqlite3_mprintf(
+                       "update package_app_info set app_installed_storage=%Q, app_external_path=%Q where package=%Q",
+                       location_str, external_pkg_path, pkgid);
+       queries.emplace_back(query);
+       sqlite3_free(query);
+
+       std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
+                       new pkgmgr_common::parcel::QueryParcelable(uid, queries,
+                                       pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
+                                       pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
+
+       pkgmgr_client::PkgInfoClient client(parcelable, uid,
+                       pkgmgr_common::ReqType::QUERY);
+       if (!client.SendRequest()) {
+               return PMINFO_R_ERROR;
+       }
+
+       std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
+                       std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
+                                       client.GetResultParcel()));
+
+       auto result_list = return_parcel->GetResult();
+       if (result_list.size() != 1) {
+               LOG(ERROR) << "Invalid result";
+               return PMINFO_R_ERROR;
+       }
+
+       if (result_list[0].size() != 1) {
+               LOG(ERROR) << "Invalid result";
+               return PMINFO_R_ERROR;
+       }
+
+       LOG(ERROR) << "result : " << result_list[0][0];
+       if (result_list[0][0] != "SUCCESS")
+               return PMINFO_R_ERROR;
+
+       return PMINFO_R_OK;
+}
index a2cabc1..1e63a5e 100644 (file)
@@ -59,6 +59,10 @@ int _plugininfo_get_appids(
 int _get_pkg_updateinfo(const char *pkgid,
                GSList **update_info_list, uid_t uid);
 
+int _pkginfo_set_usr_installed_storage(const char *pkgid,
+               INSTALL_LOCATION location, const char *external_pkg_path,
+               uid_t uid);
+
 #ifdef __cplusplus
 }
 #endif
index de84f5f..0e1e085 100644 (file)
 #include "pkgmgrinfo_debug.h"
 #include "pkgmgr-info.h"
 
+#define __BEGIN_TRANSACTION(db)                                                \
+do {                                                                           \
+       if (sqlite3_exec(db, "BEGIN DEFERRED", NULL, NULL, NULL) !=            \
+                       SQLITE_OK) {                                           \
+               _LOGE("begin transaction failed: %s", sqlite3_errmsg(db));     \
+               return -1;                                                     \
+       }                                                                      \
+} while (0)                                                                    \
+
+#define __DO_TRANSACTION(db, func)                                             \
+do {                                                                           \
+       if (func) {                                                            \
+               _LOGE("transaction failed: %s, rollback", sqlite3_errmsg(db)); \
+               if (sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL) !=          \
+                               SQLITE_OK)                                     \
+                       _LOGE("roll back transaction failed: %s",              \
+                                       sqlite3_errmsg(db));                   \
+               return -1;                                                     \
+       }                                                                      \
+} while (0)                                                                    \
+
+#define __END_TRANSACTION(db)                                                  \
+do {                                                                           \
+       if (sqlite3_exec(db, "COMMIT", NULL, NULL, NULL) !=                    \
+                       SQLITE_OK) {                                           \
+               _LOGE("commit failed: %s, rollback", sqlite3_errmsg(db));      \
+               if (sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL) !=          \
+                               SQLITE_OK)                                     \
+                       _LOGE("roll back transaction failed: %s",              \
+                                       sqlite3_errmsg(db));                   \
+               return -1;                                                     \
+       }                                                                      \
+} while (0)                                                                    \
+
 static int __free_packages(gpointer key, gpointer value,
                gpointer user_data)
 {
@@ -621,3 +655,45 @@ API int get_query_result(sqlite3 *db, const char *query,
 
        return PMINFO_R_OK;
 }
+
+static int __execute_query(sqlite3 *db, const char *query) {
+       int ret = 0;
+       sqlite3_stmt *stmt = NULL;
+
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+
+       ret = sqlite3_step(stmt);
+       if (ret != SQLITE_DONE) {
+               LOGE("step failed: %s", sqlite3_errmsg(db));
+               sqlite3_finalize(stmt);
+               return -1;
+       }
+
+       sqlite3_finalize(stmt);
+
+       return 0;
+}
+
+API int execute_write_queries(sqlite3 *db, const char **queries, int len) {
+       int ret = 0;
+       int col_cnt = 0;
+       int row_cnt = 0;
+       int i = 0;
+       sqlite3_stmt *stmt = NULL;
+       char *result = NULL;
+
+       __BEGIN_TRANSACTION(db);
+       for (i = 0; i < len; ++i) {
+               __DO_TRANSACTION(db, __execute_query(db, queries[i]));
+       }
+       __END_TRANSACTION(db);
+
+       // Is db handel freed by AbstractDBHandler?
+       // sqlite3_close_v2(db);
+
+       return 0;
+}
index e313037..c9ee010 100644 (file)
@@ -20,6 +20,7 @@
 #include "pkgmgrinfo_private.h"
 #include "pkgmgr_parser.h"
 #include "pkgmgr_parser_db.h"
+#include "manager/pkginfo_manager.h"
 
 typedef int (*sqlite_query_callback)(void *data, int ncols, char **coltxt, char **colname);
 
@@ -242,70 +243,7 @@ inline void _save_column_str(sqlite3_stmt *stmt, int idx, char **str)
 API int pkgmgrinfo_pkginfo_set_usr_installed_storage(const char *pkgid, INSTALL_LOCATION location, const char *external_pkg_path, uid_t uid)
 {
        retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "pkgid is NULL\n");
-       int ret = -1;
-       sqlite3 *pkgmgr_parser_db = NULL;
-       char *query = NULL;
-       char *db_path;
-       const char *location_str;
-
-       db_path = getUserPkgParserDBPathUID(uid);
-       if (db_path == NULL) {
-               _LOGE("Failed to get pkg parser db path - %d", uid);
-               return PMINFO_R_ERROR;
-       }
-
-       //ret = __open_db(db_path, &pkgmgr_parser_db, SQLITE_OPEN_READWRITE);
-       ret = 0;
-       if (ret != SQLITE_OK) {
-               _LOGE("connect db failed!");
-               free(db_path);
-               return PMINFO_R_ERROR;
-       }
-       free(db_path);
-
-       /*Begin transaction*/
-       /* Setting Manifest DB */
-       ret = sqlite3_exec(pkgmgr_parser_db, "BEGIN DEFERRED", NULL, NULL, NULL);
-       tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Failed to begin transaction\n");
-       _LOGD("Transaction Begin\n");
-
-       if (location == INSTALL_INTERNAL)
-               location_str = "installed_internal";
-       else if (location == INSTALL_EXTERNAL)
-               location_str = "installed_external";
-       else
-               location_str = "installed_extended";
-       /* pkgcakge_info table */
-       query = sqlite3_mprintf(
-                       "update package_info set installed_storage=%Q, external_path=%Q where package=%Q",
-                       location_str, external_pkg_path, pkgid);
-
-       ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, NULL);
-       tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
-       sqlite3_free(query);
-
-       /* package_app_info table */
-       query = sqlite3_mprintf(
-                       "update package_app_info set app_installed_storage=%Q, app_external_path=%Q where package=%Q",
-                       location_str, external_pkg_path, pkgid);
-
-       ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, NULL);
-       tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
-
-       /*Commit transaction*/
-       ret = sqlite3_exec(pkgmgr_parser_db, "COMMIT", NULL, NULL, NULL);
-       if (ret != SQLITE_OK) {
-               _LOGE("Failed to commit transaction. Rollback now\n");
-               ret = sqlite3_exec(pkgmgr_parser_db, "ROLLBACK", NULL, NULL, NULL);
-               tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
-       }
-       _LOGD("Transaction Commit and End\n");
-
-       ret = PMINFO_R_OK;
-catch:
-       sqlite3_close_v2(pkgmgr_parser_db);
-       sqlite3_free(query);
-       return ret;
+       return _pkginfo_set_usr_installed_storage(pkgid, location, external_pkg_path, uid);
 }
 
 API int pkgmgrinfo_pkginfo_set_installed_storage(const char *pkgid, INSTALL_LOCATION location, const char *external_pkg_path)
index 8697af7..52d8178 100644 (file)
@@ -21,6 +21,7 @@ int certinfo_internal_get(sqlite3 *db, const char *pkgid, uid_t uid, pkgmgrinfo_
 int certinfo_internal_set(sqlite3 *db, const char *pkgid, pkgmgrinfo_instcertinfo_h handle, uid_t uid);
 int certinfo_internal_delete(sqlite3 *db, const char *pkgid);
 int get_query_result(sqlite3 *db, const char *query, GList **list, int *row, int *col);
+int execute_write_queries(sqlite3 *db, const char **queries, int len);
 /** @} */
 #ifdef __cplusplus
 }
index f5bbe5e..fd76bc7 100644 (file)
@@ -175,7 +175,8 @@ TEST_F(ParcelTest, ResultParcelable) {
 
 TEST_F(ParcelTest, QueryParcelable) {
   tizen_base::Parcel parcel;
-  std::string query = "select * from package_info";
+  std::vector<std::string> query;
+  query.emplace_back("select * from package_info");
 
   pp::QueryParcelable origin_parcelable(0, query,
       pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
@@ -184,7 +185,7 @@ TEST_F(ParcelTest, QueryParcelable) {
   parcel.WriteParcelable(origin_parcelable);
   parcel.ReadParcelable(&new_parcelable);
 
-  EXPECT_EQ(origin_parcelable.GetQuery(), new_parcelable.GetQuery());
+  EXPECT_EQ(origin_parcelable.GetQueries(), new_parcelable.GetQueries());
   EXPECT_EQ(origin_parcelable.GetDBType(), new_parcelable.GetDBType());
   EXPECT_EQ(origin_parcelable.GetOpType(), new_parcelable.GetOpType());
 }