1 /*
2 * Copyright (c) 2023 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 #include "rd_single_ver_storage_engine.h"
16
17 #include "db_constant.h"
18 #include "grd_error.h"
19 #include "grd_type_export.h"
20 #include "rd_single_ver_storage_executor.h"
21 #include "rd_utils.h"
22 #include "single_ver_utils.h"
23 #include "sqlite_single_ver_storage_executor_sql.h"
24
25 namespace DistributedDB {
RdSingleVerStorageEngine()26 RdSingleVerStorageEngine::RdSingleVerStorageEngine()
27 {
28 LOGD("[RdSingleVerStorageEngine] RdSingleVerStorageEngine Created");
29 }
30
~RdSingleVerStorageEngine()31 RdSingleVerStorageEngine::~RdSingleVerStorageEngine()
32 {
33 }
34
GetTableMode(bool isHash)35 inline std::string GetTableMode(bool isHash)
36 {
37 return isHash ? DBConstant::RD_KV_HASH_COLLECTION_MODE : DBConstant::RD_KV_COLLECTION_MODE;
38 }
39
CreateNewExecutor(bool isWrite,StorageExecutor * & handle)40 int RdSingleVerStorageEngine::CreateNewExecutor(bool isWrite, StorageExecutor *&handle)
41 {
42 int ret = PreCreateExecutor(isWrite);
43 if (ret != E_OK) {
44 LOGE("[RdSingleVerStorageEngine][CreateNewExecutor] PreCreateExecutor unscuccess");
45 return ret;
46 }
47 GRD_DB *db = nullptr;
48 ret = TryToOpenMainDatabase(isWrite, db);
49 if (ret != E_OK) {
50 LOGE("[RdSingleVerStorageEngine] GRD_DBOPEN FAILED:%d", ret);
51 return ret;
52 }
53 if (!option_.readOnly) {
54 std::string tableMode = GetTableMode(option_.isHashTable);
55 ret = RdCreateCollection(db, SYNC_COLLECTION_NAME, tableMode.c_str(), 0);
56 if (ret != E_OK) {
57 LOGE("[RdSingleVerStorageEngine] GRD_CreateCollection SYNC_COLLECTION_NAME FAILED %d", ret);
58 (void)RdDBClose(db, GRD_DB_CLOSE_IGNORE_ERROR);
59 return ret;
60 }
61 }
62 ret = IndexPreLoad(db, SYNC_COLLECTION_NAME);
63 if (ret != E_OK) {
64 LOGE("[RdSingleVerStorageEngine] GRD_IndexPreload FAILED %d", ret);
65 (void)RdDBClose(db, GRD_DB_CLOSE_IGNORE_ERROR);
66 return ret;
67 }
68 handle = new (std::nothrow) RdSingleVerStorageExecutor(db, isWrite);
69 if (handle == nullptr) {
70 (void)RdDBClose(db, GRD_DB_CLOSE_IGNORE_ERROR);
71 return -E_OUT_OF_MEMORY;
72 }
73 if (OS::CheckPathExistence(option_.subdir + DBConstant::PATH_POSTFIX_DB_INCOMPLETE) &&
74 OS::RemoveFile(option_.subdir + DBConstant::PATH_POSTFIX_DB_INCOMPLETE) != E_OK) {
75 LOGE("Finish to create the complete database, but delete token fail! errCode = [E_SYSTEM_API_FAIL]");
76 delete handle;
77 handle = nullptr;
78 return -E_SYSTEM_API_FAIL;
79 }
80 return E_OK;
81 }
82
InitRdStorageEngine(const StorageEngineAttr & poolSize,const OpenDbProperties & option,const std::string & identifier)83 int RdSingleVerStorageEngine::InitRdStorageEngine(const StorageEngineAttr &poolSize, const OpenDbProperties &option,
84 const std::string &identifier)
85 {
86 if (StorageEngine::CheckEngineAttr(poolSize)) {
87 LOGE("Invalid storage engine attributes!");
88 return -E_INVALID_ARGS;
89 }
90 engineAttr_ = poolSize;
91 option_ = option;
92 identifier_ = identifier;
93 hashIdentifier_ = DBCommon::TransferStringToHex(identifier_);
94 int errCode = Init();
95 if (errCode != E_OK) {
96 LOGI("Storage engine init fail! errCode = [%d]", errCode);
97 }
98 return errCode;
99 }
100
GetExistedSecOption(SecurityOption & secOption) const101 int RdSingleVerStorageEngine::GetExistedSecOption(SecurityOption &secOption) const
102 {
103 LOGD("[RdSingleVerStorageEngine] Try to get existed sec option");
104 return GetExistedSecOpt(option_, secOption);
105 }
106
CheckDatabaseSecOpt(const SecurityOption & secOption) const107 int RdSingleVerStorageEngine::CheckDatabaseSecOpt(const SecurityOption &secOption) const
108 {
109 if (!(secOption == option_.securityOpt) && (secOption.securityLabel > option_.securityOpt.securityLabel) &&
110 secOption.securityLabel != SecurityLabel::NOT_SET &&
111 option_.securityOpt.securityLabel != SecurityLabel::NOT_SET) {
112 LOGE("[RdSingleVerStorageEngine] SecurityOption mismatch, existed:[%d-%d] vs input:[%d-%d]",
113 secOption.securityLabel, secOption.securityFlag, option_.securityOpt.securityLabel,
114 option_.securityOpt.securityFlag);
115 return -E_SECURITY_OPTION_CHECK_ERROR;
116 }
117 return E_OK;
118 }
119
CreateNewDirsAndSetSecOpt() const120 int RdSingleVerStorageEngine::CreateNewDirsAndSetSecOpt() const
121 {
122 LOGD("[RdSingleVerStorageEngine] Begin to create new dirs and set security option");
123 return CreateNewDirsAndSetSecOption(option_);
124 }
125
TryToOpenMainDatabase(bool isWrite,GRD_DB * & db)126 int RdSingleVerStorageEngine::TryToOpenMainDatabase(bool isWrite, GRD_DB *&db)
127 {
128 // Only could get the main database handle in the uninitialized and the main status.
129 if (GetEngineState() != EngineState::INVALID && GetEngineState() != EngineState::MAINDB) {
130 LOGE("[RdSinStoreEng][GetMainHandle] Can only create new handle for state[%d]", GetEngineState());
131 return -E_EKEYREVOKED;
132 }
133
134 option_.uri = GetDbDir(option_.subdir, DbType::MAIN) + "/" + DBConstant::SINGLE_VER_DATA_STORE +
135 DBConstant::DB_EXTENSION;
136
137 OpenDbProperties optionTemp = option_;
138 if (!isWrite) {
139 optionTemp.createIfNecessary = false;
140 }
141 int errCode = OpenGrdDb(optionTemp, db);
142 if (errCode != E_OK) {
143 LOGE("Failed to open the main database [%d], uri: %s", errCode, (option_.uri).c_str());
144 return errCode;
145 }
146
147 // Set the engine state to main status for that the main database is valid.
148 SetEngineState(EngineState::MAINDB);
149 return errCode;
150 }
151
GetDbHandle(bool isWrite,const SecurityOption & secOpt,GRD_DB * & dbHandle)152 int RdSingleVerStorageEngine::GetDbHandle(bool isWrite, const SecurityOption &secOpt, GRD_DB *&dbHandle)
153 {
154 int errCode = TryToOpenMainDatabase(isWrite, dbHandle);
155 LOGD("Finish to open the main database, write[%d], label[%d], flag[%d], id[%.6s], errCode[%d]", isWrite,
156 secOpt.securityLabel, secOpt.securityFlag, hashIdentifier_.c_str(), errCode);
157 if (!(ParamCheckUtils::IsS3SECEOpt(secOpt) && errCode == -E_EKEYREVOKED)) {
158 return errCode;
159 }
160 return -E_NOT_SUPPORT;
161 }
162
PreCreateExecutor(bool isWrite)163 int RdSingleVerStorageEngine::PreCreateExecutor(bool isWrite)
164 {
165 if (!isWrite) {
166 return E_OK;
167 }
168 // Get the existed database secure option.
169 SecurityOption existedSecOpt;
170 int ret = GetExistedSecOption(existedSecOpt);
171 if (ret != E_OK) {
172 LOGD("[RdSingleVerStorageEngine][PreCreateExecutor]Something unexpected happened");
173 return ret;
174 }
175 ret = CheckDatabaseSecOpt(existedSecOpt);
176 if (ret != E_OK) {
177 LOGD("[RdSingleVerStorageEngine][CheckDatabaseSecOpt]Something unexpected happened");
178 return ret;
179 }
180 ret = CreateNewDirsAndSetSecOpt();
181 if (ret != E_OK) {
182 LOGD("[RdSingleVerStorageEngine][CreateNewDirsAndSetSecOpt]Something unexpected happened");
183 }
184 return ret;
185 }
186
OpenGrdDb(const OpenDbProperties & option,GRD_DB * & db)187 int RdSingleVerStorageEngine::OpenGrdDb(const OpenDbProperties &option, GRD_DB *&db)
188 {
189 uint32_t flag = GRD_DB_OPEN_ONLY;
190 if (option.createIfNecessary && !option.readOnly) {
191 flag |= GRD_DB_OPEN_CREATE;
192 }
193 if (option.readOnly) {
194 flag |= GRD_DB_OPEN_SHARED_READ_ONLY;
195 }
196 int errCode = RdDbOpen(option.uri.c_str(), option.rdConfig.c_str(), flag, db);
197 if (errCode == -E_REBUILD_DATABASE) {
198 if (option.isNeedRmCorruptedDb) {
199 LOGD("[RdSingleVerStorageEngine] rebuild database successfully");
200 return E_OK;
201 } else {
202 LOGE("[RdSingleVerStorageEngine] database is corrupted");
203 return -E_INVALID_PASSWD_OR_CORRUPTED_DB;
204 }
205 }
206 return errCode;
207 }
208
IndexPreLoad(GRD_DB * & db,const char * collectionName)209 int RdSingleVerStorageEngine::IndexPreLoad(GRD_DB *&db, const char *collectionName)
210 {
211 int ret = E_OK;
212 if (isFirstTimeOpenDb_) {
213 ret = RdIndexPreload(db, collectionName);
214 if (ret != E_OK) {
215 LOGE("Unable to RdIndexPreload %d", ret);
216 return ret;
217 }
218 isFirstTimeOpenDb_ = false;
219 }
220 return E_OK;
221 }
222 } // namespace DistributedDB