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
16 #include "single_ver_utils.h"
17
18 #include "db_common.h"
19 #include "platform_specific.h"
20 #include "runtime_context.h"
21
22 namespace DistributedDB {
23
GetPathSecurityOption(const std::string & filePath,SecurityOption & secOpt)24 int GetPathSecurityOption(const std::string &filePath, SecurityOption &secOpt)
25 {
26 return RuntimeContext::GetInstance()->GetSecurityOption(filePath, secOpt);
27 }
28
GetDbDir(const std::string & subDir,DbType type)29 std::string GetDbDir(const std::string &subDir, DbType type)
30 {
31 switch (type) {
32 case DbType::MAIN:
33 return subDir + "/" + DBConstant::MAINDB_DIR;
34 case DbType::META:
35 return subDir + "/" + DBConstant::METADB_DIR;
36 case DbType::CACHE:
37 return subDir + "/" + DBConstant::CACHEDB_DIR;
38 default:
39 break;
40 }
41 return "";
42 }
43
GetDatabasePath(const KvDBProperties & kvDBProp)44 std::string GetDatabasePath(const KvDBProperties &kvDBProp)
45 {
46 return GetSubDirPath(kvDBProp) + "/" + DBConstant::MAINDB_DIR + "/" + DBConstant::SINGLE_VER_DATA_STORE +
47 DBConstant::DB_EXTENSION;
48 }
49
GetSubDirPath(const KvDBProperties & kvDBProp)50 std::string GetSubDirPath(const KvDBProperties &kvDBProp)
51 {
52 std::string dataDir = kvDBProp.GetStringProp(KvDBProperties::DATA_DIR, "");
53 std::string identifierDir = kvDBProp.GetStringProp(KvDBProperties::IDENTIFIER_DIR, "");
54 return dataDir + "/" + identifierDir + "/" + DBConstant::SINGLE_SUB_DIR;
55 }
56
ClearIncompleteDatabase(const KvDBProperties & kvDBPro)57 int ClearIncompleteDatabase(const KvDBProperties &kvDBPro)
58 {
59 std::string dbSubDir = GetSubDirPath(kvDBPro);
60 if (OS::CheckPathExistence(dbSubDir + DBConstant::PATH_POSTFIX_DB_INCOMPLETE)) {
61 int errCode = DBCommon::RemoveAllFilesOfDirectory(dbSubDir);
62 if (errCode != E_OK) {
63 LOGE("Remove the incomplete database dir failed!");
64 return -E_REMOVE_FILE;
65 }
66 }
67 return E_OK;
68 }
69
CreateNewDirsAndSetSecOption(const OpenDbProperties & option)70 int CreateNewDirsAndSetSecOption(const OpenDbProperties &option)
71 {
72 std::vector<std::string> dbDir { DBConstant::MAINDB_DIR, DBConstant::METADB_DIR, DBConstant::CACHEDB_DIR };
73 for (const auto &item : dbDir) {
74 if (OS::CheckPathExistence(option.subdir + "/" + item)) {
75 continue;
76 }
77
78 // Dir and old db file not existed, it means that the database is newly created
79 // need create flag of database not incomplete
80 if (!OS::CheckPathExistence(option.subdir + DBConstant::PATH_POSTFIX_DB_INCOMPLETE) &&
81 !OS::CheckPathExistence(option.subdir + "/" + DBConstant::SINGLE_VER_DATA_STORE +
82 DBConstant::DB_EXTENSION) &&
83 OS::CreateFileByFileName(option.subdir + DBConstant::PATH_POSTFIX_DB_INCOMPLETE) != E_OK) {
84 LOGE("Fail to create the token of database incompleted! errCode = [E_SYSTEM_API_FAIL]");
85 return -E_SYSTEM_API_FAIL;
86 }
87
88 if (DBCommon::CreateDirectory(option.subdir + "/" + item) != E_OK) {
89 LOGE("Create sub-directory for single ver failed, errno:%d", errno);
90 return -E_SYSTEM_API_FAIL;
91 }
92
93 if (option.securityOpt.securityLabel == NOT_SET) {
94 continue;
95 }
96
97 SecurityOption secOption = option.securityOpt;
98 if (item == DBConstant::METADB_DIR) {
99 secOption.securityLabel = ((option.securityOpt.securityLabel >= SecurityLabel::S2) ?
100 SecurityLabel::S2 : option.securityOpt.securityLabel);
101 secOption.securityFlag = SecurityFlag::ECE;
102 }
103
104 int errCode = RuntimeContext::GetInstance()->SetSecurityOption(option.subdir + "/" + item, secOption);
105 if (errCode != E_OK && errCode != -E_NOT_SUPPORT) {
106 LOGE("Set the security option of sub-directory failed[%d]", errCode);
107 return errCode;
108 }
109 }
110 return E_OK;
111 }
112
GetExistedSecOpt(const OpenDbProperties & opt,SecurityOption & secOption)113 int GetExistedSecOpt(const OpenDbProperties &opt, SecurityOption &secOption)
114 {
115 // Check the existence of the database, include the origin database and the database in the 'main' directory.
116 auto mainDbDir = GetDbDir(opt.subdir, DbType::MAIN);
117 auto mainDbFilePath = mainDbDir + "/" + DBConstant::SINGLE_VER_DATA_STORE + DBConstant::DB_EXTENSION;
118 auto origDbFilePath = opt.subdir + "/" + DBConstant::SINGLE_VER_DATA_STORE + DBConstant::DB_EXTENSION;
119 if (!OS::CheckPathExistence(origDbFilePath) && !OS::CheckPathExistence(mainDbFilePath)) {
120 secOption = opt.securityOpt;
121 return E_OK;
122 }
123
124 // the main database file has high priority of the security option.
125 int errCode;
126 if (OS::CheckPathExistence(mainDbFilePath)) {
127 errCode = GetPathSecurityOption(mainDbFilePath, secOption);
128 } else {
129 errCode = GetPathSecurityOption(origDbFilePath, secOption);
130 }
131 if (errCode == E_OK) {
132 return E_OK;
133 }
134 secOption = SecurityOption();
135 if (errCode == -E_NOT_SUPPORT) {
136 return E_OK;
137 }
138 LOGE("Get the security option of the existed database failed.");
139 return errCode;
140 }
141
InitCommitNotifyDataKeyStatus(SingleVerNaturalStoreCommitNotifyData * committedData,const Key & hashKey,const DataOperStatus & dataStatus)142 void InitCommitNotifyDataKeyStatus(SingleVerNaturalStoreCommitNotifyData *committedData, const Key &hashKey,
143 const DataOperStatus &dataStatus)
144 {
145 if (committedData == nullptr) {
146 return;
147 }
148
149 ExistStatus existedStatus = ExistStatus::NONE;
150 if (dataStatus.preStatus == DataStatus::DELETED) {
151 existedStatus = ExistStatus::DELETED;
152 } else if (dataStatus.preStatus == DataStatus::EXISTED) {
153 existedStatus = ExistStatus::EXIST;
154 }
155
156 committedData->InitKeyPropRecord(hashKey, existedStatus);
157 }
158 } // namespace DistributedDB