Remove the memory database for the cache
[platform/core/appfw/pkgmgr-info.git] / src / server / database / abstract_db_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 "abstract_db_handler.hh"
18
19 #include <gio/gio.h>
20 #include <stdlib.h>
21 #include <sys/stat.h>
22 #include <sys/sysmacros.h>
23 #include <sys/types.h>
24 #include <tzplatform_config.h>
25
26 #include <string>
27 #include <vector>
28
29 #include <database.hpp>
30 #include "db_handle_provider.hh"
31 #include "utils/logging.hh"
32
33 #include "pkgmgr-info.h"
34 #include "pkgmgrinfo_debug.h"
35 #include "pkgmgrinfo_private.h"
36
37 namespace {
38
39 constexpr useconds_t BUSY_WAITING_USEC = (1000000 / 10 / 2); /* 0.05 sec */
40 constexpr int BUSY_WAITING_MAX = 100; /* wait for max 5 sec */
41
42 bool ReadDbBusyHandler(int count) {
43   if (count < BUSY_WAITING_MAX) {
44     usleep(BUSY_WAITING_USEC);
45     return true;
46   } else {
47     return false;
48   }
49 }
50
51 tizen_base::Database OpenReadDb(const std::string& path) {
52   tizen_base::Database db(path.c_str(), SQLITE_OPEN_READONLY | SQLITE_OPEN_URI,
53       ReadDbBusyHandler);
54
55   return db;
56 }
57
58 constexpr const char RESOURCED_BUS_NAME[] = "org.tizen.resourced";
59 constexpr const char RESOURCED_PROC_PATH[] = "/Org/Tizen/ResourceD/Process";
60 constexpr const char RESOURCED_PROC_INTERFACE[] = "org.tizen.resourced.process";
61 constexpr const char RESOURCED_PROC_METHOD[] = "ProcExclude";
62
63 bool WriteDbBusyHandler(int count) {
64   if (count < (BUSY_WAITING_MAX / 2)) {
65     usleep(BUSY_WAITING_USEC);
66     return true;
67   } else if (count < BUSY_WAITING_MAX) {
68     usleep(BUSY_WAITING_USEC);
69     return true;
70   } else {
71     return false;
72   }
73 }
74
75 tizen_base::Database OpenWriteDb(uid_t uid, const std::string& path) {
76   tizen_base::Database db(path.c_str(), SQLITE_OPEN_READWRITE,
77       WriteDbBusyHandler);
78   db.OneStepExec({ "PRAGMA foreign_keys=ON" });
79
80   return db;
81 }
82
83 tizen_base::Database OpenCreateDb(uid_t uid, const std::string& path) {
84   tizen_base::Database db(path.c_str(), SQLITE_OPEN_READWRITE |
85       SQLITE_OPEN_CREATE, WriteDbBusyHandler);
86
87   return db;
88 }
89
90 uid_t ConvertUID(uid_t uid) {
91   static uid_t globaluser_uid = -1;
92
93   if (uid < REGULAR_USER) {
94     if (globaluser_uid == (uid_t)-1)
95       globaluser_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
96
97     return globaluser_uid;
98   } else {
99     return uid;
100   }
101 }
102
103 }  // namespace
104
105 namespace pkgmgr_server {
106 namespace database {
107
108 std::shared_mutex AbstractDBHandler::lock_;
109
110 AbstractDBHandler::~AbstractDBHandler() = default;
111
112 std::vector<std::pair<std::string, uid_t>> AbstractDBHandler::GetDBPath() {
113   std::vector<std::pair<std::string, uid_t>> db_path;
114   if (db_type_ == pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB)
115     db_path = DBHandleProvider::GetInst(uid_).GetParserDBPath();
116   else if (db_type_ == pkgmgr_common::DBType::DB_TYPE_FILE_CERTDB)
117     db_path.emplace_back(
118         std::make_pair(DBHandleProvider::GetInst(uid_).GetCertDBPath(), uid_));
119
120   return db_path;
121 }
122
123 bool AbstractDBHandler::Connect() {
124   if (db_type_ == pkgmgr_common::DBType::DB_TYPE_NONE ||
125       op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_NONE) {
126     LOG(ERROR) << "Invalid parameter";
127     return false;
128   }
129
130   auto dbpath_list = GetDBPath();
131
132   try {
133     for (const auto& [path, uid] : dbpath_list) {
134       if (op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_READ) {
135         db_handle_list_.emplace_back(OpenReadDb(path), uid);
136       } else if (
137           op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE) {
138         if (ConvertUID(uid) != ConvertUID(uid_))
139           continue;
140         db_handle_list_.emplace_back(OpenWriteDb(uid_, path), uid);
141       } else {
142         if (ConvertUID(uid) != ConvertUID(uid_))
143           continue;
144
145         if (access(path.c_str(), F_OK) != -1) {
146           LOG(ERROR) << "Database for user " << uid_ << " is already exists";
147           return false;
148         }
149
150         db_handle_list_.emplace_back(OpenCreateDb(uid_, path), uid);
151       }
152     }
153   } catch (const tizen_base::DbException& e) {
154     LOG(ERROR) << e.msg();
155     return false;
156   }
157
158   return true;
159 }
160
161 void AbstractDBHandler::ClearDBHandle() {
162   db_handle_list_.clear();
163 }
164
165 const std::vector<std::pair<tizen_base::Database, uid_t>>&
166     AbstractDBHandler::GetConnection() {
167   return db_handle_list_;
168 }
169
170 void AbstractDBHandler::SetOpType(pkgmgr_common::DBOperationType type) {
171   op_type_ = type;
172 }
173
174 const std::string& AbstractDBHandler::GetLocale() {
175   return locale_;
176 }
177
178 int AbstractDBHandler::GetPID() {
179   return pid_;
180 }
181
182 uid_t AbstractDBHandler::GetUID() {
183   return uid_;
184 }
185
186 void AbstractDBHandler::SetLocale(std::string locale) {
187   locale_ = std::move(locale);
188 }
189
190 void AbstractDBHandler::SetDBType(pkgmgr_common::DBType type) {
191   db_type_ = type;
192 }
193
194 pkgmgr_common::DBOperationType AbstractDBHandler::GetOpType() {
195   return op_type_;
196 }
197
198 uid_t AbstractDBHandler::GetDefaultUser() {
199   static uid_t default_user = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
200
201   return default_user;
202 }
203
204 }  // namespace database
205 }  // namespace pkgmgr_server