void AbstractDBHandler::SetDBType(DBType type) { db_type_ = type; }
+AbstractDBHandler::OperationType AbstractDBHandler::GetOpType() { return op_type_; }
+
} // namespace database
} // namespace pkgmgr_common
void SetLocale(const std::string& locale);
void SetDBType(DBType type);
void SetOpType(OperationType type);
+ OperationType GetOpType();
protected:
bool Connect();
QueryHandler::~QueryHandler() {}
-void QueryHandler::SetQuery(std::string query) {
+void QueryHandler::SetQuery(std::vector<std::string> query) {
query_ = query;
}
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
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();
private:
uid_t uid_;
- std::string query_;
+ std::vector<std::string> query_;
std::vector<std::vector<std::string>> result_;
};
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() {
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();
void ReadFromParcel(tizen_base::Parcel* parcel) override;
private:
- std::string query_;
+ std::vector<std::string> queries_;
AbstractDBHandler::DBType db_type_;
AbstractDBHandler::OperationType op_type_;
};
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;
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;
+}
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
#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)
{
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;
+}
#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);
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)
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
}
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,
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());
}