1 /*
2 * Copyright (c) 2022 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
16 #include "rdb_helper.h"
17
18 #include "logger.h"
19 #include "rdb_errno.h"
20 #include "rdb_store_impl.h"
21 #include "rdb_trace.h"
22 #include "sqlite_global_config.h"
23 #include "unistd.h"
24
25 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM)
26 #include "rdb_security_manager.h"
27 #include "security_policy.h"
28 #endif
29
30 namespace OHOS {
31 namespace NativeRdb {
32 std::mutex RdbHelper::mutex_;
33 std::map<std::string, std::shared_ptr<RdbStore>> RdbHelper::storeCache_;
InitSecurityManager(const RdbStoreConfig & config)34 void RdbHelper::InitSecurityManager(const RdbStoreConfig &config)
35 {
36 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM)
37 if (config.IsEncrypt()) {
38 RdbSecurityManager::GetInstance().Init(config.GetBundleName(), config.GetPath());
39 }
40 #endif
41 }
42
GetRdbStore(const RdbStoreConfig & config,int version,RdbOpenCallback & openCallback,int & errCode)43 std::shared_ptr<RdbStore> RdbHelper::GetRdbStore(
44 const RdbStoreConfig &config, int version, RdbOpenCallback &openCallback, int &errCode)
45 {
46 SqliteGlobalConfig::InitSqliteGlobalConfig();
47 std::string path = config.GetPath();
48 std::shared_ptr<RdbStore> rdbStore;
49 {
50 std::lock_guard<std::mutex> lock(mutex_);
51 std::string path = config.GetPath();
52 if (storeCache_.find(path) == storeCache_.end()) {
53 InitSecurityManager(config);
54 rdbStore = RdbStoreImpl::Open(config, errCode);
55 if (rdbStore == nullptr) {
56 LOG_ERROR("RdbHelper GetRdbStore fail to open RdbStore, err is %{public}d", errCode);
57 return nullptr;
58 }
59 storeCache_.insert(std::pair {path, rdbStore});
60 } else {
61 return storeCache_[path];
62 }
63 }
64
65 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM)
66 errCode = SecurityPolicy::SetSecurityLabel(config);
67 if (errCode != E_OK) {
68 LOG_ERROR("RdbHelper set security label fail.");
69 storeCache_.erase(path);
70 return nullptr;
71 }
72 #endif
73
74 errCode = ProcessOpenCallback(*rdbStore, config, version, openCallback);
75 if (errCode != E_OK) {
76 LOG_ERROR("RdbHelper GetRdbStore ProcessOpenCallback fail");
77 storeCache_.erase(path);
78 return nullptr;
79 }
80
81 return rdbStore;
82 }
83
ProcessOpenCallback(RdbStore & rdbStore,const RdbStoreConfig & config,int version,RdbOpenCallback & openCallback)84 int RdbHelper::ProcessOpenCallback(
85 RdbStore &rdbStore, const RdbStoreConfig &config, int version, RdbOpenCallback &openCallback)
86 {
87 int currentVersion;
88 int errCode = rdbStore.GetVersion(currentVersion);
89 if (errCode != E_OK) {
90 return errCode;
91 }
92 if (version == currentVersion) {
93 return openCallback.OnOpen(rdbStore);
94 }
95
96 if (config.IsReadOnly()) {
97 LOG_ERROR("RdbHelper ProcessOpenCallback Can't upgrade read-only store");
98 return E_CANNOT_UPDATE_READONLY;
99 }
100
101 if (currentVersion == 0) {
102 errCode = openCallback.OnCreate(rdbStore);
103 } else if (version > currentVersion) {
104 errCode = openCallback.OnUpgrade(rdbStore, currentVersion, version);
105 } else {
106 errCode = openCallback.OnDowngrade(rdbStore, currentVersion, version);
107 }
108
109 if (errCode == E_OK) {
110 errCode = rdbStore.SetVersion(version);
111 }
112
113 if (errCode != E_OK) {
114 LOG_ERROR("RdbHelper ProcessOpenCallback set new version failed.");
115 return errCode;
116 }
117
118 return openCallback.OnOpen(rdbStore);
119 }
120
ClearCache()121 void RdbHelper::ClearCache()
122 {
123 std::lock_guard<std::mutex> lock(mutex_);
124 storeCache_.clear();
125 }
126
127
DeleteRdbKeyFiles(const std::string & dbFileName)128 static void DeleteRdbKeyFiles(const std::string &dbFileName)
129 {
130 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM)
131 RdbSecurityManager::GetInstance().DelRdbSecretDataFile(dbFileName);
132 #endif
133 }
134
135
DeleteRdbStore(const std::string & dbFileName)136 int RdbHelper::DeleteRdbStore(const std::string &dbFileName)
137 {
138 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
139 if (dbFileName.empty()) {
140 return E_EMPTY_FILE_NAME;
141 }
142
143 {
144 std::lock_guard<std::mutex> lock(mutex_);
145 if (storeCache_.find(dbFileName) != storeCache_.end()) {
146 #ifdef WINDOWS_PLATFORM
147 storeCache_[dbFileName]->Clear();
148 #endif
149 storeCache_.erase(dbFileName);
150 }
151 }
152 if (access(dbFileName.c_str(), F_OK) != 0) {
153 return E_OK; // not not exist
154 }
155 int result = remove(dbFileName.c_str());
156 if (result != 0) {
157 LOG_ERROR("RdbHelper DeleteRdbStore failed to delete the db file err = %{public}d", errno);
158 return E_REMOVE_FILE;
159 }
160
161 int errCode = E_OK;
162 std::string shmFileName = dbFileName + "-shm";
163 if (access(shmFileName.c_str(), F_OK) == 0) {
164 result = remove(shmFileName.c_str());
165 if (result < 0) {
166 LOG_ERROR("RdbHelper DeleteRdbStore failed to delete the shm file err = %{public}d", errno);
167 errCode = E_REMOVE_FILE;
168 }
169 }
170
171 std::string walFileName = dbFileName + "-wal";
172 if (access(walFileName.c_str(), F_OK) == 0) {
173 result = remove(walFileName.c_str());
174 if (result < 0) {
175 LOG_ERROR("RdbHelper DeleteRdbStore failed to delete the wal file err = %{public}d", errno);
176 errCode = E_REMOVE_FILE;
177 }
178 }
179
180 std::string journalFileName = dbFileName + "-journal";
181 if (access(journalFileName.c_str(), F_OK) == 0) {
182 result = remove(journalFileName.c_str());
183 if (result < 0) {
184 LOG_ERROR("RdbHelper DeleteRdbStore failed to delete the journal file err = %{public}d", errno);
185 errCode = E_REMOVE_FILE;
186 }
187 }
188 DeleteRdbKeyFiles(dbFileName);
189
190 return errCode;
191 }
192 } // namespace NativeRdb
193 } // namespace OHOS
194