• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     sqlite3_register_cksumvfs(0);
62 }
63 
~SqliteGlobalConfig()64 SqliteGlobalConfig::~SqliteGlobalConfig()
65 {
66     sqlite3_unregister_cksumvfs();
67     sqlite3_config(SQLITE_CONFIG_CORRUPTION, nullptr, nullptr);
68     sqlite3_config(SQLITE_CONFIG_LOG, nullptr, nullptr);
69     LOG_INFO("Destruct.");
70 }
71 
Corruption(void * arg,const void * msg)72 void SqliteGlobalConfig::Corruption(void *arg, const void *msg)
73 {
74     std::lock_guard<std::mutex> lockGuard(g_corruptionMutex);
75     g_lastCorruptionMsg = (const char *)msg;
76 }
77 
Log(const void * data,int err,const char * msg)78 void SqliteGlobalConfig::Log(const void *data, int err, const char *msg)
79 {
80     bool verboseLog = (data != nullptr);
81     auto errType = static_cast<unsigned int>(err);
82     errType &= 0xFF;
83     if (errType == SQLITE_ERROR && strstr(msg, "\"?\": syntax error in \"PRAGMA user_ve") != nullptr) {
84         return;
85     }
86     if (errType == 0 || errType == SQLITE_CONSTRAINT || errType == SQLITE_SCHEMA || errType == SQLITE_NOTICE ||
87         err == SQLITE_WARNING_AUTOINDEX) {
88         if (verboseLog) {
89             LOG_INFO("Error(%{public}d) %{public}s ", err, SqliteUtils::SqlAnonymous(msg).c_str());
90         }
91     } else if (errType == SQLITE_WARNING) {
92         LOG_WARN("WARNING(%{public}d) %{public}s ", err, SqliteUtils::SqlAnonymous(msg).c_str());
93     } else {
94         LOG_ERROR("Error(%{public}d) errno is:%{public}d %{public}s.", err, errno,
95             SqliteUtils::SqlAnonymous(msg).c_str());
96         SqliteErrReport(err, msg);
97     }
98 }
99 
SqliteErrReport(int err,const char * msg)100 void SqliteGlobalConfig::SqliteErrReport(int err, const char *msg)
101 {
102     auto lowErr = static_cast<uint32_t>(err) & 0xFF;
103     if (lowErr == SQLITE_NOMEM || lowErr == SQLITE_INTERRUPT || lowErr == SQLITE_FULL || lowErr == SQLITE_SCHEMA ||
104         lowErr == SQLITE_NOLFS || lowErr == SQLITE_AUTH || lowErr == SQLITE_BUSY || lowErr == SQLITE_LOCKED ||
105         lowErr == SQLITE_IOERR || lowErr == SQLITE_CANTOPEN) {
106         std::string log(msg == nullptr ? "" : SqliteUtils::Anonymous(msg).c_str());
107         log.append(",errcode=").append(std::to_string(err)).append(",errno=").append(std::to_string(errno));
108         RdbFaultHiViewReporter::ReportFault(RdbFaultEvent(FT_SQLITE, E_DFX_SQLITE_LOG, BUNDLE_NAME_COMMON, log));
109     }
110 }
111 
GetMemoryDbPath()112 std::string SqliteGlobalConfig::GetMemoryDbPath()
113 {
114     return GlobalExpr::MEMORY_DB_PATH;
115 }
116 
GetSharedMemoryDbPath(const std::string & name)117 std::string SqliteGlobalConfig::GetSharedMemoryDbPath(const std::string &name)
118 {
119     static const std::regex pattern(R"(^[\w\-\.]+$)");
120     if (!name.empty() && !std::regex_match(name, pattern)) {
121         return "";
122     }
123     return GlobalExpr::SHARED_MEMORY_DB_PATH_PREFIX + name + GlobalExpr::SHARED_MEMORY_DB_PATH_SUFFIX;
124 }
125 
GetPageSize()126 int SqliteGlobalConfig::GetPageSize()
127 {
128     return GlobalExpr::DB_PAGE_SIZE;
129 }
130 
GetSyncMode()131 std::string SqliteGlobalConfig::GetSyncMode()
132 {
133     return GlobalExpr::DEFAULE_SYNC_MODE;
134 }
135 
GetJournalFileSize()136 int SqliteGlobalConfig::GetJournalFileSize()
137 {
138     return GlobalExpr::DB_JOURNAL_SIZE;
139 }
140 
GetWalAutoCheckpoint()141 int SqliteGlobalConfig::GetWalAutoCheckpoint()
142 {
143     return GlobalExpr::WAL_AUTO_CHECKPOINT;
144 }
145 
GetDefaultJournalMode()146 std::string SqliteGlobalConfig::GetDefaultJournalMode()
147 {
148     return GlobalExpr::JOURNAL_MODE_WAL;
149 }
150 
GetDbPath(const RdbStoreConfig & config,std::string & dbPath)151 int SqliteGlobalConfig::GetDbPath(const RdbStoreConfig &config, std::string &dbPath)
152 {
153     if (config.GetStorageMode() == StorageMode::MODE_MEMORY) {
154         if (config.GetRoleType() != OWNER) {
155             LOG_ERROR("not support MODE_MEMORY, storeName:%{public}s, role:%{public}d",
156                 SqliteUtils::Anonymous(config.GetName()).c_str(), config.GetRoleType());
157             return E_NOT_SUPPORT;
158         }
159         dbPath = SqliteGlobalConfig::GetSharedMemoryDbPath(config.GetName());
160         return dbPath.empty() ? E_INVALID_FILE_PATH : E_OK;
161     }
162     std::string path;
163     if (config.GetRoleType() == OWNER) {
164         path = config.GetPath();
165     } else if (config.GetRoleType() == VISITOR || config.GetRoleType() == VISITOR_WRITE) {
166         path = config.GetVisitorDir();
167     } else {
168         LOG_ERROR("not support Role, storeName:%{public}s, role:%{public}d",
169             SqliteUtils::Anonymous(config.GetName()).c_str(), config.GetRoleType());
170         return E_NOT_SUPPORT;
171     }
172     if (path.empty() || path.front() != '/') {
173         LOG_ERROR("invalid path, bundleName:%{public}s, role:%{public}d, %{public}s",
174             config.GetBundleName().c_str(), config.GetRoleType(), SqliteUtils::Anonymous(path).c_str());
175         return E_INVALID_FILE_PATH;
176     }
177     dbPath = std::move(path);
178     return E_OK;
179 }
180 
GetLastCorruptionMsg()181 std::string SqliteGlobalConfig::GetLastCorruptionMsg()
182 {
183     std::lock_guard<std::mutex> lockGuard(g_corruptionMutex);
184     std::string msg = g_lastCorruptionMsg;
185     g_lastCorruptionMsg = "";
186     return msg;
187 }
188 } // namespace NativeRdb
189 } // namespace OHOS
190