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
DataValue()85 DataValue::DataValue() : type_(StorageType::STORAGE_TYPE_NULL)
86 {
87 value_.zeroMem = nullptr;
88 }
89
~DataValue()90 DataValue::~DataValue()
91 {
92 ResetValue();
93 }
94
DataValue(const DataValue & dataValue)95 DataValue::DataValue(const DataValue &dataValue)
96 {
97 *this = dataValue;
98 }
99
DataValue(DataValue && dataValue)100 DataValue::DataValue(DataValue &&dataValue) noexcept
101 {
102 *this = std::move(dataValue);
103 }
104
operator =(const DataValue & dataValue)105 DataValue &DataValue::operator=(const DataValue &dataValue)
106 {
107 if (&dataValue == this) {
108 return *this;
109 }
110 ResetValue();
111 switch (dataValue.type_) {
112 case StorageType::STORAGE_TYPE_INTEGER:
113 (void)dataValue.GetInt64(this->value_.iValue);
114 break;
115 case StorageType::STORAGE_TYPE_REAL:
116 (void)dataValue.GetDouble(this->value_.dValue);
117 break;
118 case StorageType::STORAGE_TYPE_BLOB:
119 case StorageType::STORAGE_TYPE_TEXT:
120 (void)dataValue.GetBlob(this->value_.blobPtr);
121 break;
122 default:
123 break;
124 }
125 type_ = dataValue.type_;
126 return *this;
127 }
128
operator =(DataValue && dataValue)129 DataValue &DataValue::operator=(DataValue &&dataValue) noexcept
130 {
131 if (&dataValue == this) {
132 return *this;
133 }
134 ResetValue();
135 this->type_ = dataValue.type_;
136 this->value_ = dataValue.value_;
137 switch (type_) {
138 case StorageType::STORAGE_TYPE_BLOB:
139 case StorageType::STORAGE_TYPE_TEXT:
140 dataValue.value_.blobPtr = nullptr;
141 break;
142 default:
143 break;
144 }
145 return *this;
146 }
147
operator =(int64_t intVal)148 DataValue &DataValue::operator=(int64_t intVal)
149 {
150 ResetValue();
151 type_ = StorageType::STORAGE_TYPE_INTEGER;
152 value_.iValue = intVal;
153 return *this;
154 }
155
operator =(double doubleVal)156 DataValue &DataValue::operator=(double doubleVal)
157 {
158 ResetValue();
159 type_ = StorageType::STORAGE_TYPE_REAL;
160 value_.dValue = doubleVal;
161 return *this;
162 }
163
operator =(const Blob & blob)164 DataValue &DataValue::operator=(const Blob &blob)
165 {
166 (void)SetBlob(blob);
167 return *this;
168 }
169
Set(Blob * & blob)170 int DataValue::Set(Blob *&blob)
171 {
172 ResetValue();
173 if (blob == nullptr || blob->GetSize() <= 0) {
174 LOGE("Transfer Blob to DataValue failed.");
175 return -E_INVALID_ARGS;
176 }
177 type_ = StorageType::STORAGE_TYPE_BLOB;
178 value_.blobPtr = blob;
179 blob = nullptr;
180 return E_OK;
181 }
182
operator =(const std::string & string)183 DataValue &DataValue::operator=(const std::string &string)
184 {
185 (void)SetText(string);
186 return *this;
187 }
188
operator ==(const DataValue & dataValue) const189 bool DataValue::operator==(const DataValue &dataValue) const
190 {
191 if (dataValue.type_ != type_) {
192 return false;
193 }
194 switch (type_) {
195 case StorageType::STORAGE_TYPE_INTEGER:
196 return dataValue.value_.iValue == value_.iValue;
197 case StorageType::STORAGE_TYPE_REAL:
198 return dataValue.value_.dValue == value_.dValue;
199 case StorageType::STORAGE_TYPE_BLOB:
200 case StorageType::STORAGE_TYPE_TEXT:
201 if (dataValue.value_.blobPtr->GetSize() != value_.blobPtr->GetSize()) {
202 return false;
203 }
204 for (uint32_t i = 0; i < dataValue.value_.blobPtr->GetSize(); ++i) {
205 if (dataValue.value_.blobPtr->GetData()[i] != value_.blobPtr->GetData()[i]) {
206 return false;
207 }
208 }
209 return true;
210 default:
211 return true;
212 }
213 }
214
operator !=(const DataValue & dataValue) const215 bool DataValue::operator!=(const DataValue &dataValue) const
216 {
217 return !(*this == dataValue);
218 }
219
GetDouble(double & outVal) const220 int DataValue::GetDouble(double &outVal) const
221 {
222 if (type_ != StorageType::STORAGE_TYPE_REAL) {
223 return -E_NOT_SUPPORT;
224 }
225 outVal = value_.dValue;
226 return E_OK;
227 }
228
GetInt64(int64_t & outVal) const229 int DataValue::GetInt64(int64_t &outVal) const
230 {
231 if (type_ != StorageType::STORAGE_TYPE_INTEGER) {
232 return -E_NOT_SUPPORT;
233 }
234 outVal = value_.iValue;
235 return E_OK;
236 }
237
GetBlob(Blob * & outVal) const238 int DataValue::GetBlob(Blob *&outVal) const
239 {
240 if (type_ != StorageType::STORAGE_TYPE_BLOB && type_ != StorageType::STORAGE_TYPE_TEXT) {
241 return -E_NOT_SUPPORT;
242 }
243 delete outVal;
244 outVal = nullptr;
245 outVal = new (std::nothrow) Blob();
246 if (outVal == nullptr) {
247 return -E_OUT_OF_MEMORY;
248 }
249 return outVal->WriteBlob(value_.blobPtr->GetData(), value_.blobPtr->GetSize());
250 }
251
SetBlob(const Blob & val)252 int DataValue::SetBlob(const Blob &val)
253 {
254 ResetValue();
255 if (val.GetSize() <= 0) {
256 return E_OK;
257 }
258 value_.blobPtr = new(std::nothrow) Blob();
259 if (value_.blobPtr == nullptr) {
260 return -E_OUT_OF_MEMORY;
261 }
262 type_ = StorageType::STORAGE_TYPE_BLOB;
263 int errCode = E_OK;
264 if (val.GetSize() > 0) {
265 errCode = value_.blobPtr->WriteBlob(val.GetData(), val.GetSize());
266 }
267 return errCode;
268 }
269
GetBlob(Blob & outVal) const270 int DataValue::GetBlob(Blob &outVal) const
271 {
272 if (type_ != StorageType::STORAGE_TYPE_BLOB && type_ != StorageType::STORAGE_TYPE_TEXT) {
273 return -E_NOT_SUPPORT;
274 }
275 return outVal.WriteBlob(value_.blobPtr->GetData(), value_.blobPtr->GetSize());
276 }
277
SetText(const std::string & val)278 int DataValue::SetText(const std::string &val)
279 {
280 return SetText(reinterpret_cast<const uint8_t *>(val.c_str()), val.length());
281 }
282
SetText(const uint8_t * val,uint32_t length)283 int DataValue::SetText(const uint8_t *val, uint32_t length)
284 {
285 ResetValue();
286 value_.blobPtr = new(std::nothrow) Blob();
287 if (value_.blobPtr == nullptr) {
288 return -E_OUT_OF_MEMORY;
289 }
290 type_ = StorageType::STORAGE_TYPE_TEXT;
291 return value_.blobPtr->WriteBlob(val, length);
292 }
293
GetText(std::string & outValue) const294 int DataValue::GetText(std::string &outValue) const
295 {
296 if (type_ != StorageType::STORAGE_TYPE_TEXT) {
297 return -E_NOT_SUPPORT;
298 }
299 const uint8_t *data = value_.blobPtr->GetData();
300 uint32_t len = value_.blobPtr->GetSize();
301 if (len == 0) {
302 outValue = "";
303 return E_OK;
304 }
305 outValue.resize(len);
306 outValue.assign(data, data + len);
307 return E_OK;
308 }
309
GetType() const310 StorageType DataValue::GetType() const
311 {
312 return type_;
313 }
314
GetBlobLength(uint32_t & length) const315 int DataValue::GetBlobLength(uint32_t &length) const
316 {
317 if (type_ != StorageType::STORAGE_TYPE_BLOB && type_ != StorageType::STORAGE_TYPE_TEXT) {
318 return -E_NOT_SUPPORT;
319 }
320 length = value_.blobPtr->GetSize();
321 return E_OK;
322 }
323
ResetValue()324 void DataValue::ResetValue()
325 {
326 switch (type_) {
327 case StorageType::STORAGE_TYPE_TEXT:
328 case StorageType::STORAGE_TYPE_BLOB:
329 delete value_.blobPtr;
330 value_.blobPtr = nullptr;
331 break;
332 case StorageType::STORAGE_TYPE_NULL:
333 case StorageType::STORAGE_TYPE_INTEGER:
334 case StorageType::STORAGE_TYPE_REAL:
335 default:
336 break;
337 }
338 type_ = StorageType::STORAGE_TYPE_NULL;
339 value_.zeroMem = nullptr;
340 }
341
ToString() const342 std::string DataValue::ToString() const
343 {
344 std::string res;
345 switch (type_) {
346 case StorageType::STORAGE_TYPE_TEXT:
347 (void)GetText(res);
348 break;
349 case StorageType::STORAGE_TYPE_BLOB:
350 res = "NOT SUPPORT";
351 break;
352 case StorageType::STORAGE_TYPE_NULL:
353 res = "null";
354 break;
355 case StorageType::STORAGE_TYPE_INTEGER:
356 res = std::to_string(value_.iValue);
357 break;
358 case StorageType::STORAGE_TYPE_REAL:
359 res = std::to_string(value_.dValue);
360 break;
361 default:
362 res = "default";
363 break;
364 }
365 return "[" + res + "]";
366 }
367 } // namespace DistributedDB
368 #endif