Refactor pkgmgr-info
[platform/core/appfw/pkgmgr-info.git] / src / server / database / query_handler.cc
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "query_handler.hh"
18
19 #include <shared_mutex>
20 #include <vector>
21
22 #include "utils/logging.hh"
23 #include "db_handle_provider.hh"
24 #include "cache_provider.hh"
25
26 #include "pkgmgrinfo_debug.h"
27 #include "pkgmgrinfo_internal.h"
28 #include "pkgmgr_query_index.h"
29
30 namespace {
31
32 constexpr const char query_appinfo_get_localed_label[] =
33     "SELECT COALESCE((SELECT app_label FROM package_app_localized_info "
34     "WHERE app_id=? AND app_locale=?),"
35     "(SELECT app_label FROM package_app_localized_info WHERE "
36     "app_id=? AND app_locale='No Locale'))";
37
38 constexpr const char query_appinfo_get_datacontrol_info[] =
39     "SELECT app_id, access FROM "
40     "package_app_data_control WHERE "
41     "providerid=? AND type=?";
42
43 constexpr const char query_appinfo_get_datacontrol_appid[] =
44     "SELECT app_id FROM package_app_data_control "
45     "WHERE providerid=?";
46
47 constexpr const char query_appinfo_get_datacontrol_trusted_info[] =
48     "SELECT app_id, trusted FROM package_app_data_control "
49     "WHERE providerid=? AND type=?";
50
51 constexpr const char query_appinfo_get_datacontrol_privileges[] =
52     "SELECT privilege FROM package_app_data_control_privilege "
53     "WHERE providerid=? AND type=?";
54
55 constexpr const char query_appinfo_get_appcontrol_privileges[] =
56     "SELECT app_control, privilege FROM package_app_app_control_privilege "
57     "WHERE app_id=?";
58
59 constexpr const char query_plugininfo_get_appids[] =
60     "SELECT appid FROM "
61     "package_plugin_info WHERE pkgid=? AND "
62     "plugin_type=? AND plugin_name=?";
63
64 constexpr const char query_get_pkg_updateinfo_1[] =
65     "SELECT package, update_version, update_type "
66     "FROM package_update_info";
67 constexpr const char query_get_pkg_updateinfo_2[] =
68     "SELECT package, update_version, update_type "
69     "FROM package_update_info WHERE package=?";
70
71 constexpr const char query_pkginfo_set_usr_installed_storage_1[] =
72     "UPDATE package_info SET installed_storage=?, external_path=? "
73     "WHERE package=?";
74 constexpr const char query_pkginfo_set_usr_installed_storage_2[] =
75     "UPDATE package_app_info SET app_installed_storage=?, "
76     "app_external_path=? WHERE package=?";
77
78 constexpr const char query_certinfo_compare_pkg_certinfo[] =
79     "SELECT package, "
80     "COALESCE(author_signer_cert, -1) FROM package_cert_info WHERE "
81     "package IN (?, ?)";
82
83 constexpr const char query_certinfo_compare_app_certinfo[] =
84     "SELECT app_id, package FROM "
85     "package_app_info WHERE app_id IN (?, ?)";
86
87 constexpr const char query_pkginfo_delete_certinfo[] =
88     "UPDATE package_cert_info SET "
89     "package_count = package_count - 1 WHERE package=?";
90
91 // For pkgmgr_parser
92 constexpr const char query_insert_package_plugin_execution_info[] =
93     "INSERT INTO package_plugin_info "
94     "(pkgid, appid, plugin_type, plugin_name) "
95     "VALUES (?, ?, ?, ?)";
96
97 constexpr const char query_delete_package_plugin_execution_info[] =
98     "DELETE FROM package_plugin_info WHERE pkgid=?";
99
100 constexpr const char query_update_global_app_disable[] =
101     "INSERT OR REPLACE INTO package_app_info_for_uid ("
102     "  app_id, uid, is_disabled, is_splash_screen_enabled) "
103     "VALUES (?, ?, ?,"
104     "  (SELECT app_splash_screen_display FROM package_app_info"
105     "   WHERE app_id=?))";
106
107 constexpr const char query_update_app_disable_info[] =
108     "UPDATE package_app_info SET app_disable=? "
109     "WHERE app_id=?";
110
111 constexpr const char query_update_pkg_disable_info[] =
112     "UPDATE package_info SET package_disable=? "
113     "WHERE package=?";
114
115 constexpr const char query_update_global_app_splash_screen_display_info[] =
116     "INSERT OR REPLACE INTO package_app_info_for_uid("
117     "  app_id, uid, is_splash_screen_enabled) "
118     "VALUES (?, ?, ?)";
119
120 constexpr const char query_update_app_splash_screen_display_info[] =
121     "UPDATE package_app_info SET app_splash_screen_display=? "
122     "WHERE app_id=?";
123
124 constexpr const char query_update_app_label_info[] =
125     "UPDATE package_app_localized_info SET app_label=? "
126     "WHERE app_id=? AND app_label IS NOT NULL";
127
128 constexpr const char query_update_app_icon_info[] =
129     "UPDATE package_app_localized_info SET app_icon=? "
130     "WHERE app_id=? AND app_icon IS NOT NULL";
131
132 constexpr const char query_update_tep_info[] =
133     "UPDATE package_info SET package_tep_name=? "
134     "WHERE package=?";
135
136 constexpr const char query_register_pkg_update_info[] =
137     "UPDATE package_update_info "
138     "SET update_version=?, update_type=? "
139     "WHERE package=?";
140
141 constexpr const char query_unregister_pkg_update_info[] =
142     "UPDATE package_update_info "
143     "SET update_type='none' WHERE package=?";
144
145 constexpr const char query_unregister_all_pkg_update_info[] =
146     "UPDATE package_update_info "
147     "SET update_type='none'";
148
149 class QueryMaker {
150  public:
151   std::vector<const char*> query_raw_ = {
152     query_appinfo_get_localed_label,
153     query_appinfo_get_datacontrol_info,
154     query_appinfo_get_datacontrol_appid,
155     query_appinfo_get_datacontrol_trusted_info,
156     query_appinfo_get_datacontrol_privileges,
157     query_appinfo_get_appcontrol_privileges,
158     query_plugininfo_get_appids,
159     query_get_pkg_updateinfo_1,
160     query_get_pkg_updateinfo_2,
161     query_pkginfo_set_usr_installed_storage_1,
162     query_pkginfo_set_usr_installed_storage_2,
163     query_certinfo_compare_pkg_certinfo,
164     query_certinfo_compare_app_certinfo,
165     query_pkginfo_delete_certinfo,
166
167     query_insert_package_plugin_execution_info,
168     query_delete_package_plugin_execution_info,
169     query_update_global_app_disable,
170     query_update_app_disable_info,
171     query_update_pkg_disable_info,
172     query_update_global_app_splash_screen_display_info,
173     query_update_app_splash_screen_display_info,
174     query_update_app_label_info,
175     query_update_app_icon_info,
176     query_update_tep_info,
177     query_register_pkg_update_info,
178     query_unregister_pkg_update_info,
179     query_unregister_all_pkg_update_info,
180   };
181
182   const char* GetQuery(int index) {
183     return query_raw_[index];
184   }
185 };
186
187 QueryMaker __query_maker;
188
189 void __free_argument(gpointer data) {
190   query_args* args = reinterpret_cast<query_args*>(data);
191   g_list_free(args->argument);
192   free(args);
193 }
194
195 void __free_query_list(GList* queries, GList* args_list) {
196   g_list_free(queries);
197   g_list_free_full(args_list, __free_argument);
198 }
199
200 }  // namespace
201
202 namespace pkgmgr_server {
203 namespace database {
204
205 QueryHandler::QueryHandler(uid_t uid, int pid)
206     : AbstractDBHandler(uid, pid), uid_(uid) {}
207
208 QueryHandler::~QueryHandler() {}
209
210 void QueryHandler::SetQueryArgs(
211     std::vector<pkgmgr_common::parcel::QueryArgs> query_args) {
212   query_args_ = std::move(query_args);
213 }
214
215 std::string QueryHandler::GetString() { return std::string(); }
216 int QueryHandler::GetInt() { return 0; }
217 int QueryHandler::GetRecordCount() { return 0; }
218
219 std::vector<pkgmgr_common::parcel::StrArgs> QueryHandler::GetResult() {
220   return std::move(result_);
221 }
222
223 int QueryHandler::Execute() {
224   std::shared_lock<std::shared_timed_mutex> s(lock_);
225   if (!Connect()) {
226     LOG(ERROR) << "Failed to connect database";
227     return PMINFO_R_ERROR;
228   }
229
230   GList* queries = nullptr;
231   GList* args_list = nullptr;
232   for (auto& i : query_args_) {
233     const char* query = __query_maker.GetQuery(i.first);
234     if (query == nullptr) {
235       LOG(ERROR) << "Failed to get query";
236       __free_query_list(queries, args_list);
237       return PMINFO_R_ERROR;
238     }
239
240     queries = g_list_append(queries, (gpointer)query);
241     query_args* arg = reinterpret_cast<query_args*>(
242         calloc(1, sizeof(query_args)));
243     if (arg == nullptr) {
244       LOG(ERROR) << "Out of memory";
245       __free_query_list(queries, args_list);
246       return PMINFO_R_ERROR;
247     }
248     arg->len = i.second.size();
249     for (auto& argument : i.second) {
250       arg->argument = g_list_append(arg->argument,
251           gpointer(argument ? (*argument).c_str() : nullptr));
252     }
253
254     args_list = g_list_append(args_list, arg);
255   }
256
257   std::vector<std::pair<sqlite3*, uid_t>> conn_list = GetConnection();
258   int ret = PMINFO_R_ERROR;
259   if (GetOpType() == pkgmgr_common::DBOperationType::OPERATION_TYPE_READ) {
260     for (auto& conn : conn_list) {
261       for (GList* it = args_list; it; it = it->next) {
262         GList* list = nullptr;
263         int row = 0;
264         int col = 0;
265
266         query_args* params = reinterpret_cast<query_args*>(it->data);
267         ret = get_query_result(conn.first, (const char *)queries->data,
268             params->argument, &list, &row, &col);
269         if (ret == PMINFO_R_ERROR) {
270           LOG(ERROR) << "Failed to execute query";
271           __free_query_list(queries, args_list);
272           return ret;
273         }
274
275         GList* tmp = list;
276         for (int i = 0; i < row; ++i) {
277           pkgmgr_common::parcel::StrArgs vt;
278           for (int j = 0; j < col; ++j) {
279             if (!tmp->data)
280               vt.emplace_back(std::nullopt);
281             else
282               vt.emplace_back(reinterpret_cast<char *>(tmp->data));
283             tmp = tmp->next;
284           }
285           result_.emplace_back(std::move(vt));
286         }
287
288         g_list_free_full(list, free);
289       }
290     }
291     __free_query_list(queries, args_list);
292
293     return ret;
294   } else {
295     for (auto& conn : conn_list) {
296       ret = execute_write_queries(conn.first, queries, args_list);
297       if (ret != PMINFO_R_OK) {
298         LOG(ERROR) << "Failed to execute";
299         break;
300       }
301     }
302     __free_query_list(queries, args_list);
303     CacheProvider(GetUID()).ReleaseCache();
304
305     return ret;
306   }
307   return ret;
308 }
309
310 }  // namespace database
311 }  // namespace pkgmgr_server