• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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