1 /*
2 * Copyright (c) 2021 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 #ifdef RELATIONAL_STORE
16 #include "data_value.h"
17
18 #include "db_errno.h"
19 #include "relational_schema_object.h"
20 #include "securec.h"
21
22 namespace DistributedDB {
Blob()23 Blob::Blob() : ptr_(nullptr), size_(0)
24 {
25 }
26
~Blob()27 Blob::~Blob()
28 {
29 if (ptr_ != nullptr) {
30 delete[] ptr_;
31 ptr_ = nullptr;
32 }
33 size_ = 0;
34 }
35
Blob(Blob && blob)36 Blob::Blob(Blob &&blob) : ptr_(blob.ptr_), size_(blob.size_)
37 {
38 blob.ptr_ = nullptr;
39 blob.size_ = 0;
40 }
41
operator =(Blob && blob)42 Blob &Blob::operator=(Blob &&blob) noexcept
43 {
44 if (&blob != this) {
45 delete[] ptr_;
46 ptr_ = blob.ptr_;
47 size_ = blob.size_;
48 blob.ptr_ = nullptr;
49 blob.size_ = 0;
50 }
51 return *this;
52 }
53
GetData() const54 const uint8_t *Blob::GetData() const
55 {
56 return ptr_;
57 }
58
GetSize() const59 uint32_t Blob::GetSize() const
60 {
61 return size_;
62 }
63
WriteBlob(const uint8_t * ptrArray,const uint32_t & size)64 int Blob::WriteBlob(const uint8_t *ptrArray, const uint32_t &size)
65 {
66 if (ptrArray == nullptr || size == 0) {
67 return E_OK;
68 }
69
70 delete[] ptr_;
71 ptr_ = nullptr;
72
73 ptr_ = new (std::nothrow) uint8_t[size];
74 if (ptr_ == nullptr) {
75 return -E_OUT_OF_MEMORY;
76 }
77 errno_t errCode = memcpy_s(ptr_, size, ptrArray, size);
78 if (errCode != EOK) {
79 return -E_SECUREC_ERROR;
80 }
81 size_ = size;
82 return E_OK;
83 }
84
ToVector() const85 std::vector<uint8_t> Blob::ToVector() const
86 {
87 return std::vector<uint8_t>(ptr_, ptr_ + size_);
88 }
89
DataValue()90 DataValue::DataValue() : type_(StorageType::STORAGE_TYPE_NULL)
91 {
92 value_.zeroMem = nullptr;
93 }
94
~DataValue()95 DataValue::~DataValue()
96 {
97 ResetValue();
98 }
99
DataValue(const DataValue & dataValue)100 DataValue::DataValue(const DataValue &dataValue)
101 {
102 *this = dataValue;
103 }
104
DataValue(DataValue && dataValue)105 DataValue::DataValue(DataValue &&dataValue) noexcept
106 {
107 *this = std::move(dataValue);
108 }
109
operator =(const DataValue & dataValue)110 DataValue &DataValue::operator=(const DataValue &dataValue)
111 {
112 if (&dataValue == this) {
113 return *this;
114 }
115 ResetValue();
116 switch (dataValue.type_) {
117 case StorageType::STORAGE_TYPE_INTEGER:
118 (void)dataValue.GetInt64(this->value_.iValue);
119 break;
120 case StorageType::STORAGE_TYPE_REAL:
121 (void)dataValue.GetDouble(this->value_.dValue);
122 break;
123 case StorageType::STORAGE_TYPE_BLOB:
124 case StorageType::STORAGE_TYPE_TEXT:
125 (void)dataValue.GetBlob(this->value_.blobPtr);
126 break;
127 default:
128 break;
129 }
130 type_ = dataValue.type_;
131 return *this;
132 }
133
operator =(DataValue && dataValue)134 DataValue &DataValue::operator=(DataValue &&dataValue) noexcept
135 {
136 if (&dataValue == this) {
137 return *this;
138 }
139 ResetValue();
140 this->type_ = dataValue.type_;
141 this->value_ = dataValue.value_;
142 switch (type_) {
143 case StorageType::STORAGE_TYPE_BLOB:
144 case StorageType::STORAGE_TYPE_TEXT:
145 dataValue.value_.blobPtr = nullptr;
146 break;
147 default:
148 break;
149 }
150 return *this;
151 }
152
operator =(int64_t intVal)153 DataValue &DataValue::operator=(int64_t intVal)
154 {
155 ResetValue();
156 type_ = StorageType::STORAGE_TYPE_INTEGER;
157 value_.iValue = intVal;
158 return *this;
159 }
160
operator =(double doubleVal)161 DataValue &DataValue::operator=(double doubleVal)
162 {
163 ResetValue();
164 type_ = StorageType::STORAGE_TYPE_REAL;
165 value_.dValue = doubleVal;
166 return *this;
167 }
168
operator =(const Blob & blob)169 DataValue &DataValue::operator=(const Blob &blob)
170 {
171 (void)SetBlob(blob);
172 return *this;
173 }
174
Set(Blob * & blob)175 int DataValue::Set(Blob *&blob)
176 {
177 ResetValue();
178 if (blob == nullptr || blob->GetSize() < 0) {
179 LOGE("Transfer Blob to DataValue failed.");
180 return -E_INVALID_ARGS;
181 }
182 type_ = StorageType::STORAGE_TYPE_BLOB;
183 value_.blobPtr = blob;
184 blob = nullptr;
185 return E_OK;
186 }
187
operator =(const std::string & string)188 DataValue &DataValue::operator=(const std::string &string)
189 {
190 (void)SetText(string);
191 return *this;
192 }
193
operator ==(const DataValue & dataValue) const194 bool DataValue::operator==(const DataValue &dataValue) const
195 {
196 if (dataValue.type_ != type_) {
197 return false;
198 }
199 switch (type_) {
200 case StorageType::STORAGE_TYPE_INTEGER:
201 return dataValue.value_.iValue == value_.iValue;
202 case StorageType::STORAGE_TYPE_REAL:
203 return dataValue.value_.dValue == value_.dValue;
204 case StorageType::STORAGE_TYPE_BLOB:
205 case StorageType::STORAGE_TYPE_TEXT:
206 if (dataValue.value_.blobPtr->GetSize() != value_.blobPtr->GetSize()) {
207 return false;
208 }
209 for (uint32_t i = 0; i < dataValue.value_.blobPtr->GetSize(); ++i) {
210 if (dataValue.value_.blobPtr->GetData()[i] != value_.blobPtr->GetData()[i]) {
211 return false;
212 }
213 }
214 return true;
215 default:
216 return true;
217 }
218 }
219
operator !=(const DataValue & dataValue) const220 bool DataValue::operator!=(const DataValue &dataValue) const
221 {
222 return !(*this == dataValue);
223 }
224
GetDouble(double & outVal) const225 int DataValue::GetDouble(double &outVal) const
226 {
227 if (type_ != StorageType::STORAGE_TYPE_REAL) {
228 return -E_NOT_SUPPORT;
229 }
230 outVal = value_.dValue;
231 return E_OK;
232 }
233
GetInt64(int64_t & outVal) const234 int DataValue::GetInt64(int64_t &outVal) const
235 {
236 if (type_ != StorageType::STORAGE_TYPE_INTEGER) {
237 return -E_NOT_SUPPORT;
238 }
239 outVal = value_.iValue;
240 return E_OK;
241 }
242
GetBlob(Blob * & outVal) const243 int DataValue::GetBlob(Blob *&outVal) const
244 {
245 if (type_ != StorageType::STORAGE_TYPE_BLOB && type_ != StorageType::STORAGE_TYPE_TEXT) {
246 return -E_NOT_SUPPORT;
247 }
248 delete outVal;
249 outVal = nullptr;
250 outVal = new (std::nothrow) Blob();
251 if (outVal == nullptr) {
252 return -E_OUT_OF_MEMORY;
253 }
254 return outVal->WriteBlob(value_.blobPtr->GetData(), value_.blobPtr->GetSize());
255 }
256
SetBlob(const Blob & val)257 int DataValue::SetBlob(const Blob &val)
258 {
259 ResetValue();
260 if (val.GetSize() < 0) {
261 return E_OK;
262 }
263 value_.blobPtr = new(std::nothrow) Blob();
264 if (value_.blobPtr == nullptr) {
265 return -E_OUT_OF_MEMORY;
266 }
267 type_ = StorageType::STORAGE_TYPE_BLOB;
268 int errCode = E_OK;
269 if (val.GetSize() > 0) {
270 errCode = value_.blobPtr->WriteBlob(val.GetData(), val.GetSize());
271 }
272 return errCode;
273 }
274
GetBlob(Blob & outVal) const275 int DataValue::GetBlob(Blob &outVal) const
276 {
277 if (type_ != StorageType::STORAGE_TYPE_BLOB && type_ != StorageType::STORAGE_TYPE_TEXT) {
278 return -E_NOT_SUPPORT;
279 }
280 return outVal.WriteBlob(value_.blobPtr->GetData(), value_.blobPtr->GetSize());
281 }
282
SetText(const std::string & val)283 int DataValue::SetText(const std::string &val)
284 {
285 return SetText(reinterpret_cast<const uint8_t *>(val.c_str()), val.length());
286 }
287
SetText(const uint8_t * val,uint32_t length)288 int DataValue::SetText(const uint8_t *val, uint32_t length)
289 {
290 ResetValue();
291 value_.blobPtr = new(std::nothrow) Blob();
292 if (value_.blobPtr == nullptr) {
293 return -E_OUT_OF_MEMORY;
294 }
295 type_ = StorageType::STORAGE_TYPE_TEXT;
296 return value_.blobPtr->WriteBlob(val, length);
297 }
298
GetText(std::string & outValue) const299 int DataValue::GetText(std::string &outValue) const
300 {
301 if (type_ != StorageType::STORAGE_TYPE_TEXT) {
302 return -E_NOT_SUPPORT;
303 }
304 const uint8_t *data = value_.blobPtr->GetData();
305 uint32_t len = value_.blobPtr->GetSize();
306 if (len == 0) {
307 outValue = "";
308 return E_OK;
309 }
310 outValue.resize(len);
311 outValue.assign(data, data + len);
312 return E_OK;
313 }
314
GetType() const315 StorageType DataValue::GetType() const
316 {
317 return type_;
318 }
319
ResetValue()320 void DataValue::ResetValue()
321 {
322 switch (type_) {
323 case StorageType::STORAGE_TYPE_TEXT:
324 case StorageType::STORAGE_TYPE_BLOB:
325 delete value_.blobPtr;
326 value_.blobPtr = nullptr;
327 break;
328 case StorageType::STORAGE_TYPE_NULL:
329 case StorageType::STORAGE_TYPE_INTEGER:
330 case StorageType::STORAGE_TYPE_REAL:
331 default:
332 break;
333 }
334 type_ = StorageType::STORAGE_TYPE_NULL;
335 value_.zeroMem = nullptr;
336 }
337
ToString() const338 std::string DataValue::ToString() const
339 {
340 std::string res;
341 switch (type_) {
342 case StorageType::STORAGE_TYPE_TEXT:
343 (void)GetText(res);
344 break;
345 case StorageType::STORAGE_TYPE_BLOB:
346 res = "NOT SUPPORT";
347 break;
348 case StorageType::STORAGE_TYPE_NULL:
349 res = "null";
350 break;
351 case StorageType::STORAGE_TYPE_INTEGER:
352 res = std::to_string(value_.iValue);
353 break;
354 case StorageType::STORAGE_TYPE_REAL:
355 res = std::to_string(value_.dValue);
356 break;
357 default:
358 res = "default";
359 break;
360 }
361 return "[" + res + "]";
362 }
363 } // namespace DistributedDB
364 #endif