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