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