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 "pkgmgr-info.h"
31 #include "pkgmgrinfo_debug.h"
32 #include "pkgmgrinfo_private.h"
36 constexpr useconds_t BUSY_WAITING_USEC = (1000000 / 10 / 2); /* 0.05 sec */
37 constexpr int BUSY_WAITING_MAX = 100; /* wait for max 5 sec */
39 int __readdb_busy_handler(void *data, int count) {
40 if (count < BUSY_WAITING_MAX) {
41 usleep(BUSY_WAITING_USEC);
44 /* sqlite3_prepare_v2 will return SQLITE_BUSY */
49 int __open_read_db(const char *path, sqlite3 **db) {
52 ret = sqlite3_open_v2(path, db,
53 SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, NULL);
54 if (ret != SQLITE_OK) {
55 sqlite3_close_v2(*db);
59 ret = sqlite3_busy_handler(*db, __readdb_busy_handler, NULL);
60 if (ret != SQLITE_OK) {
61 _LOGE("failed to register busy handler: %s",
63 sqlite3_close_v2(*db);
70 constexpr const char RESOURCED_BUS_NAME[] = "org.tizen.resourced";
71 constexpr const char RESOURCED_PROC_PATH[] = "/Org/Tizen/ResourceD/Process";
72 constexpr const char RESOURCED_PROC_INTERFACE[] = "org.tizen.resourced.process";
73 constexpr const char RESOURCED_PROC_METHOD[] = "ProcExclude";
75 int __writedb_busy_handler(void *data, int count) {
76 if (count < (BUSY_WAITING_MAX / 2)) {
77 usleep(BUSY_WAITING_USEC);
79 } else if (count < BUSY_WAITING_MAX) {
80 usleep(BUSY_WAITING_USEC);
83 /* sqlite3_prepare_v2 will return SQLITE_BUSY */
88 int __open_write_db(uid_t uid, const char* path,
92 ret = sqlite3_open_v2(path, db, SQLITE_OPEN_READWRITE, NULL);
93 if (ret != SQLITE_OK) {
94 sqlite3_close_v2(*db);
98 ret = sqlite3_busy_handler(*db, __writedb_busy_handler,
99 reinterpret_cast<void*>(const_cast<char*>(path)));
100 if (ret != SQLITE_OK) {
101 _LOGE("failed to register busy handler: %s",
102 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 _LOGE("failed to enable foreign key support: %s",
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 _LOGE("failed to register busy handler: %s",
133 sqlite3_errmsg(*db));
134 sqlite3_close_v2(*db);
141 uid_t ConvertUID(uid_t uid) {
142 if (uid < REGULAR_USER)
143 return tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
150 namespace pkgmgr_server {
153 std::shared_timed_mutex AbstractDBHandler::lock_;
155 AbstractDBHandler::~AbstractDBHandler() {
156 for (auto& db_handle : db_handle_list_)
157 sqlite3_close_v2(db_handle.first);
160 std::vector<std::pair<std::string, uid_t>> AbstractDBHandler::GetDBPath() {
161 std::vector<std::pair<std::string, uid_t>> db_path;
162 if (db_type_ == pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB)
163 db_path = DBHandleProvider::GetInst(uid_).GetParserDBPath(pid_,
164 op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE);
165 else if (db_type_ == pkgmgr_common::DBType::DB_TYPE_FILE_CERTDB)
166 db_path.emplace_back(
167 std::make_pair(DBHandleProvider::GetInst(uid_).GetCertDBPath(pid_,
168 op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE), uid_));
173 bool AbstractDBHandler::Connect() {
174 if (db_type_ == pkgmgr_common::DBType::DB_TYPE_NONE ||
175 op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_NONE) {
176 _LOGE("Invalid parameter");
179 auto dbpath_list = GetDBPath();
181 for (auto& dbpath : dbpath_list) {
183 if (op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_READ) {
184 ret = __open_read_db(dbpath.first.c_str(), &db);
185 } else if (op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE) {
186 if (ConvertUID(dbpath.second) != ConvertUID(uid_))
188 ret = __open_write_db(uid_, dbpath.first.c_str(), &db);
190 if (ConvertUID(dbpath.second) != ConvertUID(uid_))
193 if (access(dbpath.first.c_str(), F_OK) != -1) {
194 _LOGE("Database for user %d is already exists", uid_);
197 ret = __open_create_db(uid_, dbpath.first.c_str(), &db);
200 if (ret != SQLITE_OK)
203 db_handle_list_.emplace_back(std::make_pair(db, dbpath.second));
209 void AbstractDBHandler::ClearDBHandle() {
210 for (auto db_handle : db_handle_list_)
211 sqlite3_close_v2(db_handle.first);
213 db_handle_list_.clear();
216 std::vector<std::pair<sqlite3*, uid_t>> AbstractDBHandler::GetConnection() {
217 return db_handle_list_;
220 void AbstractDBHandler::SetOpType(pkgmgr_common::DBOperationType type) {
224 const std::string& AbstractDBHandler::GetLocale() {
228 int AbstractDBHandler::GetPID() {
232 uid_t AbstractDBHandler::GetUID() {
236 void AbstractDBHandler::SetLocale(std::string locale) {
237 locale_ = std::move(locale);
240 void AbstractDBHandler::SetDBType(pkgmgr_common::DBType type) {
244 pkgmgr_common::DBOperationType AbstractDBHandler::GetOpType() {
248 } // namespace database
249 } // namespace pkgmgr_server