1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #define LOG_TAG "Config"
16 #include "sqlite_global_config.h"
17
18 #include <sys/stat.h>
19 #include <sys/types.h>
20
21 #include <cerrno>
22 #include <chrono>
23 #include <cinttypes>
24 #include <cstring>
25 #include <mutex>
26 #include <regex>
27
28 #include "logger.h"
29 #include "rdb_errno.h"
30 #include "sqlite3sym.h"
31 #include "sqlite_utils.h"
32 #include "rdb_fault_hiview_reporter.h"
33
34 namespace OHOS {
35 namespace NativeRdb {
36 using namespace OHOS::Rdb;
37 using namespace std::chrono;
38
39 static std::string g_lastCorruptionMsg;
40 static std::mutex g_corruptionMutex;
41
InitSqliteGlobalConfig()42 void SqliteGlobalConfig::InitSqliteGlobalConfig()
43 {
44 static SqliteGlobalConfig globalConfig;
45 }
46
SqliteGlobalConfig()47 SqliteGlobalConfig::SqliteGlobalConfig()
48 {
49 umask(GlobalExpr::APP_DEFAULT_UMASK);
50
51 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
52
53 sqlite3_config(SQLITE_CONFIG_LOG, &Log, GlobalExpr::CALLBACK_LOG_SWITCH ? reinterpret_cast<void *>(1) : NULL);
54
55 sqlite3_config(SQLITE_CONFIG_CORRUPTION, &Corruption, nullptr);
56
57 sqlite3_soft_heap_limit(GlobalExpr::SOFT_HEAP_LIMIT);
58
59 sqlite3_initialize();
60 }
61
~SqliteGlobalConfig()62 SqliteGlobalConfig::~SqliteGlobalConfig()
63 {
64 }
65
Corruption(void * arg,const void * msg)66 void SqliteGlobalConfig::Corruption(void *arg, const void *msg)
67 {
68 std::lock_guard<std::mutex> lockGuard(g_corruptionMutex);
69 g_lastCorruptionMsg = (const char *)msg;
70 }
71
Log(const void * data,int err,const char * msg)72 void SqliteGlobalConfig::Log(const void *data, int err, const char *msg)
73 {
74 bool verboseLog = (data != nullptr);
75 auto errType = static_cast<unsigned int>(err);
76 errType &= 0xFF;
77 if (errType == SQLITE_ERROR && strstr(msg, "\"?\": syntax error in \"PRAGMA user_ve") != nullptr) {
78 return;
79 }
80 if (errType == 0 || errType == SQLITE_CONSTRAINT || errType == SQLITE_SCHEMA || errType == SQLITE_NOTICE ||
81 err == SQLITE_WARNING_AUTOINDEX) {
82 if (verboseLog) {
83 LOG_INFO("Error(%{public}d) %{public}s ", err, SqliteUtils::Anonymous(msg).c_str());
84 }
85 } else if (errType == SQLITE_WARNING) {
86 LOG_WARN("WARNING(%{public}d) %{public}s ", err, SqliteUtils::Anonymous(msg).c_str());
87 } else {
88 LOG_ERROR("Error(%{public}d) errno is:%{public}d %{public}s.", err, errno, SqliteUtils::Anonymous(msg).c_str());
89 SqliteErrReport(err, msg);
90 }
91 }
92
SqliteErrReport(int err,const char * msg)93 void SqliteGlobalConfig::SqliteErrReport(int err, const char *msg)
94 {
95 auto lowErr = static_cast<uint32_t>(err) & 0xFF;
96 if (lowErr == SQLITE_NOMEM || lowErr == SQLITE_INTERRUPT || lowErr == SQLITE_FULL || lowErr == SQLITE_SCHEMA ||
97 lowErr == SQLITE_NOLFS || lowErr == SQLITE_AUTH || lowErr == SQLITE_BUSY || lowErr == SQLITE_LOCKED ||
98 lowErr == SQLITE_IOERR || lowErr == SQLITE_CANTOPEN) {
99 std::string log(msg == nullptr ? "" : SqliteUtils::Anonymous(msg).c_str());
100 log.append(",errcode=").append(std::to_string(err)).append(",errno=").append(std::to_string(errno));
101 RdbFaultHiViewReporter::ReportFault(RdbFaultEvent(FT_SQLITE, E_DFX_SQLITE_LOG, BUNDLE_NAME_COMMON, log));
102 }
103 }
104
GetMemoryDbPath()105 std::string SqliteGlobalConfig::GetMemoryDbPath()
106 {
107 return GlobalExpr::MEMORY_DB_PATH;
108 }
109
GetSharedMemoryDbPath(const std::string & name)110 std::string SqliteGlobalConfig::GetSharedMemoryDbPath(const std::string &name)
111 {
112 static const std::regex pattern(R"(^[\w\-\.]+$)");
113 if (!name.empty() && !std::regex_match(name, pattern)) {
114 return "";
115 }
116 return GlobalExpr::SHARED_MEMORY_DB_PATH_PREFIX + name + GlobalExpr::SHARED_MEMORY_DB_PATH_SUFFIX;
117 }
118
GetPageSize()119 int SqliteGlobalConfig::GetPageSize()
120 {
121 return GlobalExpr::DB_PAGE_SIZE;
122 }
123
GetSyncMode()124 std::string SqliteGlobalConfig::GetSyncMode()
125 {
126 return GlobalExpr::DEFAULE_SYNC_MODE;
127 }
128
GetJournalFileSize()129 int SqliteGlobalConfig::GetJournalFileSize()
130 {
131 return GlobalExpr::DB_JOURNAL_SIZE;
132 }
133
GetWalAutoCheckpoint()134 int SqliteGlobalConfig::GetWalAutoCheckpoint()
135 {
136 return GlobalExpr::WAL_AUTO_CHECKPOINT;
137 }
138
GetDefaultJournalMode()139 std::string SqliteGlobalConfig::GetDefaultJournalMode()
140 {
141 return GlobalExpr::JOURNAL_MODE_WAL;
142 }
143
GetDbPath(const RdbStoreConfig & config,std::string & dbPath)144 int SqliteGlobalConfig::GetDbPath(const RdbStoreConfig &config, std::string &dbPath)
145 {
146 if (config.GetStorageMode() == StorageMode::MODE_MEMORY) {
147 if (config.GetRoleType() != OWNER) {
148 LOG_ERROR("not support MODE_MEMORY, storeName:%{public}s, role:%{public}d",
149 SqliteUtils::Anonymous(config.GetName()).c_str(), config.GetRoleType());
150 return E_NOT_SUPPORT;
151 }
152 dbPath = SqliteGlobalConfig::GetSharedMemoryDbPath(config.GetName());
153 return dbPath.empty() ? E_INVALID_FILE_PATH : E_OK;
154 }
155 std::string path;
156 if (config.GetRoleType() == OWNER) {
157 path = config.GetPath();
158 } else if (config.GetRoleType() == VISITOR || config.GetRoleType() == VISITOR_WRITE) {
159 path = config.GetVisitorDir();
160 } else {
161 LOG_ERROR("not support Role, storeName:%{public}s, role:%{public}d",
162 SqliteUtils::Anonymous(config.GetName()).c_str(), config.GetRoleType());
163 return E_NOT_SUPPORT;
164 }
165 if (path.empty() || path.front() != '/') {
166 LOG_ERROR("invalid path, bundleName:%{public}s, role:%{public}d, %{public}s",
167 config.GetBundleName().c_str(), config.GetRoleType(), SqliteUtils::Anonymous(path).c_str());
168 return E_INVALID_FILE_PATH;
169 }
170 dbPath = std::move(path);
171 return E_OK;
172 }
173
GetLastCorruptionMsg()174 std::string SqliteGlobalConfig::GetLastCorruptionMsg()
175 {
176 std::lock_guard<std::mutex> lockGuard(g_corruptionMutex);
177 std::string msg = g_lastCorruptionMsg;
178 g_lastCorruptionMsg = "";
179 return msg;
180 }
181 } // namespace NativeRdb
182 } // namespace OHOS
183