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