• 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 
~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