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 "sqlite_global_config.h"
22 #include "unistd.h"
23
24 namespace OHOS {
25 namespace NativeRdb {
26 std::mutex RdbHelper::mutex_;
27 std::map<std::string, std::shared_ptr<RdbStore>> RdbHelper::storeCache_;
GetRdbStore(const RdbStoreConfig & config,int version,RdbOpenCallback & openCallback,int & errCode)28 std::shared_ptr<RdbStore> RdbHelper::GetRdbStore(
29 const RdbStoreConfig &config, int version, RdbOpenCallback &openCallback, int &errCode)
30 {
31 SqliteGlobalConfig::InitSqliteGlobalConfig();
32 std::shared_ptr<RdbStore> rdbStore;
33 {
34 std::lock_guard<std::mutex> lock(mutex_);
35 std::string path = config.GetPath();
36 if (storeCache_.find(path) == storeCache_.end()) {
37 rdbStore = RdbStoreImpl::Open(config, errCode);
38 if (rdbStore == nullptr) {
39 LOG_ERROR("RdbHelper GetRdbStore fail to open RdbStore, err is %{public}d", errCode);
40 return nullptr;
41 }
42 storeCache_.insert(std::pair {path, rdbStore});
43 } else {
44 rdbStore = storeCache_[path];
45 }
46 }
47
48 errCode = ProcessOpenCallback(*rdbStore, config, version, openCallback);
49 if (errCode != E_OK) {
50 LOG_ERROR("RdbHelper GetRdbStore ProcessOpenCallback fail");
51 return nullptr;
52 }
53
54 return rdbStore;
55 }
56
ProcessOpenCallback(RdbStore & rdbStore,const RdbStoreConfig & config,int version,RdbOpenCallback & openCallback)57 int RdbHelper::ProcessOpenCallback(
58 RdbStore &rdbStore, const RdbStoreConfig &config, int version, RdbOpenCallback &openCallback)
59 {
60 int currentVersion;
61 int errCode = rdbStore.GetVersion(currentVersion);
62 if (errCode != E_OK) {
63 return errCode;
64 }
65 if (version == currentVersion) {
66 return openCallback.OnOpen(rdbStore);
67 }
68
69 if (config.IsReadOnly()) {
70 LOG_ERROR("RdbHelper ProcessOpenCallback Can't upgrade read-only store");
71 return E_CANNOT_UPDATE_READONLY;
72 }
73
74 if (currentVersion == 0) {
75 errCode = openCallback.OnCreate(rdbStore);
76 } else if (version > currentVersion) {
77 errCode = openCallback.OnUpgrade(rdbStore, currentVersion, version);
78 } else {
79 errCode = openCallback.OnDowngrade(rdbStore, currentVersion, version);
80 }
81
82 if (errCode == E_OK) {
83 errCode = rdbStore.SetVersion(version);
84 }
85
86 if (errCode != E_OK) {
87 LOG_ERROR("RdbHelper ProcessOpenCallback set new version failed.");
88 return errCode;
89 }
90
91 return openCallback.OnOpen(rdbStore);
92 }
93
ClearCache()94 void RdbHelper::ClearCache()
95 {
96 storeCache_.clear();
97 }
98
DeleteRdbStore(const std::string & dbFileName)99 int RdbHelper::DeleteRdbStore(const std::string &dbFileName)
100 {
101 if (dbFileName.empty()) {
102 return E_EMPTY_FILE_NAME;
103 }
104
105 {
106 std::lock_guard<std::mutex> lock(mutex_);
107 if (storeCache_.find(dbFileName) != storeCache_.end()) {
108 storeCache_.erase(dbFileName);
109 }
110 }
111 if (access(dbFileName.c_str(), F_OK) != 0) {
112 return E_OK; // not not exist
113 }
114 int result = remove(dbFileName.c_str());
115 if (result != 0) {
116 LOG_ERROR("RdbHelper DeleteRdbStore failed to delete the db file err = %{public}d", errno);
117 return E_REMOVE_FILE;
118 }
119
120 int errCode = E_OK;
121 std::string shmFileName = dbFileName + "-shm";
122 if (access(shmFileName.c_str(), F_OK) == 0) {
123 result = remove(shmFileName.c_str());
124 if (result < 0) {
125 LOG_ERROR("RdbHelper DeleteRdbStore failed to delete the shm file err = %{public}d", errno);
126 errCode = E_REMOVE_FILE;
127 }
128 }
129
130 std::string walFileName = dbFileName + "-wal";
131 if (access(walFileName.c_str(), F_OK) == 0) {
132 result = remove(walFileName.c_str());
133 if (result < 0) {
134 LOG_ERROR("RdbHelper DeleteRdbStore failed to delete the wal file err = %{public}d", errno);
135 errCode = E_REMOVE_FILE;
136 }
137 }
138
139 std::string journalFileName = dbFileName + "-journal";
140 if (access(journalFileName.c_str(), F_OK) == 0) {
141 result = remove(journalFileName.c_str());
142 if (result < 0) {
143 LOG_ERROR("RdbHelper DeleteRdbStore failed to delete the journal file err = %{public}d", errno);
144 errCode = E_REMOVE_FILE;
145 }
146 }
147
148 return errCode;
149 }
150 } // namespace NativeRdb
151 } // namespace OHOS
152