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