1 /*
2 * Copyright (c) 2025 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 "db_common.h"
17 #include "value_hash_calc.h"
18
19 namespace DistributedDB {
20 namespace {
21 constexpr const int32_t HEAD_SIZE = 3;
22 constexpr const int32_t END_SIZE = 3;
23 constexpr const int32_t MIN_SIZE = HEAD_SIZE + END_SIZE + 3;
24 constexpr const char *REPLACE_CHAIN = "***";
25 constexpr const char *DEFAULT_ANONYMOUS = "******";
26
27 const std::string HEX_CHAR_MAP = "0123456789abcdef";
28 }
29
StringToVector(const std::string & src,std::vector<uint8_t> & dst)30 void DBCommon::StringToVector(const std::string &src, std::vector<uint8_t> &dst)
31 {
32 dst.resize(src.size());
33 dst.assign(src.begin(), src.end());
34 }
35
StringMiddleMasking(const std::string & name)36 std::string DBCommon::StringMiddleMasking(const std::string &name)
37 {
38 if (name.length() <= HEAD_SIZE) {
39 return DEFAULT_ANONYMOUS;
40 }
41
42 if (name.length() < MIN_SIZE) {
43 return (name.substr(0, HEAD_SIZE) + REPLACE_CHAIN);
44 }
45
46 return (name.substr(0, HEAD_SIZE) + REPLACE_CHAIN + name.substr(name.length() - END_SIZE, END_SIZE));
47 }
48
RTrim(std::string & oriString)49 void DBCommon::RTrim(std::string &oriString)
50 {
51 if (oriString.empty()) {
52 return;
53 }
54 oriString.erase(oriString.find_last_not_of(" ") + 1);
55 }
56
CheckIsAlnumOrUnderscore(const std::string & text)57 bool DBCommon::CheckIsAlnumOrUnderscore(const std::string &text)
58 {
59 auto iter = std::find_if_not(text.begin(), text.end(), [](char c) {
60 return (std::isalnum(c) || c == '_');
61 });
62 return iter == text.end();
63 }
64
ToLowerCase(const std::string & str)65 std::string DBCommon::ToLowerCase(const std::string &str)
66 {
67 std::string res(str.length(), ' ');
68 std::transform(str.begin(), str.end(), res.begin(), ::tolower);
69 return res;
70 }
71
ToUpperCase(const std::string & str)72 std::string DBCommon::ToUpperCase(const std::string &str)
73 {
74 std::string res(str.length(), ' ');
75 std::transform(str.begin(), str.end(), res.begin(), ::toupper);
76 return res;
77 }
78
CalcValueHash(const std::vector<uint8_t> & value,std::vector<uint8_t> & hashValue)79 int DBCommon::CalcValueHash(const std::vector<uint8_t> &value, std::vector<uint8_t> &hashValue)
80 {
81 ValueHashCalc hashCalc;
82 int errCode = hashCalc.Initialize();
83 if (errCode != E_OK) {
84 return -E_INTERNAL_ERROR;
85 }
86
87 errCode = hashCalc.Update(value);
88 if (errCode != E_OK) {
89 return -E_INTERNAL_ERROR;
90 }
91
92 errCode = hashCalc.GetResult(hashValue);
93 if (errCode != E_OK) {
94 return -E_INTERNAL_ERROR;
95 }
96
97 return E_OK;
98 }
99
100
101 namespace {
CharIn(char c,const std::string & pattern)102 bool CharIn(char c, const std::string &pattern)
103 {
104 return std::any_of(pattern.begin(), pattern.end(), [c] (char p) {
105 return c == p;
106 });
107 }
108 }
HasConstraint(const std::string & sql,const std::string & keyWord,const std::string & prePattern,const std::string & nextPattern)109 bool DBCommon::HasConstraint(const std::string &sql, const std::string &keyWord, const std::string &prePattern,
110 const std::string &nextPattern)
111 {
112 size_t pos = 0;
113 while ((pos = sql.find(keyWord, pos)) != std::string::npos) {
114 if (pos >= 1 && CharIn(sql[pos - 1], prePattern) && ((pos + keyWord.length() == sql.length()) ||
115 ((pos + keyWord.length() < sql.length()) && CharIn(sql[pos + keyWord.length()], nextPattern)))) {
116 return true;
117 }
118 pos++;
119 }
120 return false;
121 }
122
TransferStringToHex(const std::string & origStr)123 std::string DBCommon::TransferStringToHex(const std::string &origStr)
124 {
125 if (origStr.empty()) {
126 return "";
127 }
128
129 std::string tmp;
130 for (auto item : origStr) {
131 unsigned char currentByte = static_cast<unsigned char>(item);
132 tmp.push_back(HEX_CHAR_MAP[currentByte >> 4]); // high 4 bits to one hex.
133 tmp.push_back(HEX_CHAR_MAP[currentByte & 0x0F]); // low 4 bits to one hex.
134 }
135 return tmp;
136 }
137
GetCursorKey(const std::string & tableName)138 std::string DBCommon::GetCursorKey(const std::string &tableName)
139 {
140 return std::string(DBConstant::RELATIONAL_PREFIX) + "cursor_" + ToLowerCase(tableName);
141 }
142
TrimSpace(const std::string & input)143 std::string DBCommon::TrimSpace(const std::string &input)
144 {
145 std::string res;
146 res.reserve(input.length());
147 bool isPreSpace = true;
148 for (char c : input) {
149 if (std::isspace(c)) {
150 isPreSpace = true;
151 } else {
152 if (!res.empty() && isPreSpace) {
153 res += ' ';
154 }
155 res += c;
156 isPreSpace = false;
157 }
158 }
159 res.shrink_to_fit();
160 return res;
161 }
162
TransferHashString(const std::string & devName)163 std::string DBCommon::TransferHashString(const std::string &devName)
164 {
165 if (devName.empty()) {
166 return "";
167 }
168 std::vector<uint8_t> devVect(devName.begin(), devName.end());
169 std::vector<uint8_t> hashVect;
170 int errCode = CalcValueHash(devVect, hashVect);
171 if (errCode != E_OK) {
172 return "";
173 }
174
175 return std::string(hashVect.begin(), hashVect.end());
176 }
177
CaseInsensitiveCompare(const std::string & first,const std::string & second)178 bool DBCommon::CaseInsensitiveCompare(const std::string &first, const std::string &second)
179 {
180 return (strcasecmp(first.c_str(), second.c_str()) == 0);
181 }
182 } // namespace DistributedDB
183