2 * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "abstract_db_handler.hh"
22 #include <sys/sysmacros.h>
23 #include <sys/types.h>
24 #include <tzplatform_config.h>
29 #include "db_handle_provider.hh"
30 #include "utils/logging.hh"
32 #include "pkgmgr-info.h"
33 #include "pkgmgrinfo_debug.h"
34 #include "pkgmgrinfo_private.h"
38 constexpr useconds_t BUSY_WAITING_USEC = (1000000 / 10 / 2); /* 0.05 sec */
39 constexpr int BUSY_WAITING_MAX = 100; /* wait for max 5 sec */
41 int __readdb_busy_handler(void *data, int count) {
42 if (count < BUSY_WAITING_MAX) {
43 usleep(BUSY_WAITING_USEC);
46 /* sqlite3_prepare_v2 will return SQLITE_BUSY */
51 int __open_read_db(const char *path, sqlite3 **db) {
54 ret = sqlite3_open_v2(path, db,
55 SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, NULL);
56 if (ret != SQLITE_OK) {
57 sqlite3_close_v2(*db);
61 ret = sqlite3_busy_handler(*db, __readdb_busy_handler, NULL);
62 if (ret != SQLITE_OK) {
63 LOG(ERROR) << "failed to register busy handler:" << sqlite3_errmsg(*db);
64 sqlite3_close_v2(*db);
71 constexpr const char RESOURCED_BUS_NAME[] = "org.tizen.resourced";
72 constexpr const char RESOURCED_PROC_PATH[] = "/Org/Tizen/ResourceD/Process";
73 constexpr const char RESOURCED_PROC_INTERFACE[] = "org.tizen.resourced.process";
74 constexpr const char RESOURCED_PROC_METHOD[] = "ProcExclude";
76 int __writedb_busy_handler(void *data, int count) {
77 if (count < (BUSY_WAITING_MAX / 2)) {
78 usleep(BUSY_WAITING_USEC);
80 } else if (count < BUSY_WAITING_MAX) {
81 usleep(BUSY_WAITING_USEC);
84 /* sqlite3_prepare_v2 will return SQLITE_BUSY */
89 int __open_write_db(uid_t uid, const char* path,
93 ret = sqlite3_open_v2(path, db, SQLITE_OPEN_READWRITE, NULL);
94 if (ret != SQLITE_OK) {
95 sqlite3_close_v2(*db);
99 ret = sqlite3_busy_handler(*db, __writedb_busy_handler,
100 reinterpret_cast<void*>(const_cast<char*>(path)));
101 if (ret != SQLITE_OK) {
102 LOG(ERROR) << "failed to register busy handler:" << sqlite3_errmsg(*db);
103 sqlite3_close_v2(*db);
107 ret = sqlite3_exec(*db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL);
108 if (ret != SQLITE_OK) {
109 LOG(ERROR) << "failed to enable foreign key support:"
110 << sqlite3_errmsg(*db);
111 sqlite3_close_v2(*db);
118 int __open_create_db(uid_t uid, const char* path,
122 ret = sqlite3_open_v2(path, db,
123 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
124 if (ret != SQLITE_OK) {
125 sqlite3_close_v2(*db);
129 ret = sqlite3_busy_handler(*db, __writedb_busy_handler,
130 reinterpret_cast<void*>(const_cast<char*>(path)));
131 if (ret != SQLITE_OK) {
132 LOG(ERROR) << "failed to register busy handler:" << sqlite3_errmsg(*db);
133 sqlite3_close_v2(*db);
140 static uid_t globaluser_uid = -1;
142 uid_t ConvertUID(uid_t uid) {
143 if (uid < REGULAR_USER) {
144 if (globaluser_uid == (uid_t)-1)
145 globaluser_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
147 return globaluser_uid;
155 namespace pkgmgr_server {
158 std::shared_mutex AbstractDBHandler::lock_;
160 AbstractDBHandler::~AbstractDBHandler() {
161 for (auto& db_handle : db_handle_list_)
162 sqlite3_close_v2(db_handle.first);
165 std::vector<std::pair<std::string, uid_t>> AbstractDBHandler::GetDBPath() {
166 std::vector<std::pair<std::string, uid_t>> db_path;
167 if (db_type_ == pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB)
168 db_path = DBHandleProvider::GetInst(uid_).GetParserDBPath(pid_,
169 op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE);
170 else if (db_type_ == pkgmgr_common::DBType::DB_TYPE_FILE_CERTDB)
171 db_path.emplace_back(
172 std::make_pair(DBHandleProvider::GetInst(uid_).GetCertDBPath(pid_,
173 op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE),
179 bool AbstractDBHandler::Connect() {
180 if (db_type_ == pkgmgr_common::DBType::DB_TYPE_NONE ||
181 op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_NONE) {
182 LOG(ERROR) << "Invalid parameter";
186 auto dbpath_list = GetDBPath();
188 for (auto& dbpath : dbpath_list) {
190 if (op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_READ) {
191 ret = __open_read_db(dbpath.first.c_str(), &db);
193 op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE) {
194 if (ConvertUID(dbpath.second) != ConvertUID(uid_))
196 ret = __open_write_db(uid_, dbpath.first.c_str(), &db);
198 if (ConvertUID(dbpath.second) != ConvertUID(uid_))
201 if (access(dbpath.first.c_str(), F_OK) != -1) {
202 LOG(ERROR) << "Database for user " << uid_ << " is already exists";
205 ret = __open_create_db(uid_, dbpath.first.c_str(), &db);
208 if (ret != SQLITE_OK)
211 db_handle_list_.emplace_back(std::make_pair(db, dbpath.second));
217 void AbstractDBHandler::ClearDBHandle() {
218 for (const auto& db_handle : db_handle_list_)
219 sqlite3_close_v2(db_handle.first);
221 db_handle_list_.clear();
224 std::vector<std::pair<sqlite3*, uid_t>> AbstractDBHandler::GetConnection() {
225 return db_handle_list_;
228 void AbstractDBHandler::SetOpType(pkgmgr_common::DBOperationType type) {
232 const std::string& AbstractDBHandler::GetLocale() {
236 int AbstractDBHandler::GetPID() {
240 uid_t AbstractDBHandler::GetUID() {
244 void AbstractDBHandler::SetLocale(std::string locale) {
245 locale_ = std::move(locale);
248 void AbstractDBHandler::SetDBType(pkgmgr_common::DBType type) {
252 pkgmgr_common::DBOperationType AbstractDBHandler::GetOpType() {
256 uid_t AbstractDBHandler::GetDefaultUser() {
257 static uid_t default_user = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
262 } // namespace database
263 } // namespace pkgmgr_server