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