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_transformer.h"
17 
18 #include "db_errno.h"
19 #include "log_print.h"
20 #include "parcel.h"
21 #include "relational_schema_object.h"
22 
23 namespace DistributedDB {
TransformTableData(const TableDataWithLog & tableDataWithLog,const std::vector<FieldInfo> & fieldInfoList,std::vector<DataItem> & dataItems)24 int DataTransformer::TransformTableData(const TableDataWithLog &tableDataWithLog,
25     const std::vector<FieldInfo> &fieldInfoList, std::vector<DataItem> &dataItems)
26 {
27     if (tableDataWithLog.dataList.empty()) {
28         return E_OK;
29     }
30     for (const RowDataWithLog& data : tableDataWithLog.dataList) {
31         DataItem dataItem;
32         int errCode = SerializeDataItem(data, fieldInfoList, dataItem);
33         if (errCode != E_OK) {
34             return errCode;
35         }
36         dataItems.push_back(std::move(dataItem));
37     }
38     return E_OK;
39 }
40 
TransformDataItem(const std::vector<DataItem> & dataItems,const std::vector<FieldInfo> & remoteFieldInfo,OptTableDataWithLog & tableDataWithLog)41 int DataTransformer::TransformDataItem(const std::vector<DataItem> &dataItems,
42     const std::vector<FieldInfo> &remoteFieldInfo, OptTableDataWithLog &tableDataWithLog)
43 {
44     if (dataItems.empty()) {
45         return E_OK;
46     }
47     for (const DataItem &dataItem : dataItems) {
48         OptRowDataWithLog dataWithLog;
49         int errCode = DeSerializeDataItem(dataItem, dataWithLog, remoteFieldInfo);
50         if (errCode != E_OK) {
51             return errCode;
52         }
53         tableDataWithLog.dataList.push_back(std::move(dataWithLog));
54     }
55     return E_OK;
56 }
57 
SerializeDataItem(const RowDataWithLog & data,const std::vector<FieldInfo> & fieldInfo,DataItem & dataItem)58 int DataTransformer::SerializeDataItem(const RowDataWithLog &data,
59     const std::vector<FieldInfo> &fieldInfo, DataItem &dataItem)
60 {
61     int errCode = SerializeValue(dataItem.value, data.rowData, fieldInfo);
62     if (errCode != E_OK) {
63         return errCode;
64     }
65     const LogInfo &logInfo = data.logInfo;
66     dataItem.timestamp = logInfo.timestamp;
67     dataItem.dev = logInfo.device;
68     dataItem.origDev = logInfo.originDev;
69     dataItem.writeTimestamp = logInfo.wTimestamp;
70     dataItem.flag = logInfo.flag;
71     dataItem.hashKey = logInfo.hashKey;
72     return E_OK;
73 }
74 
DeSerializeDataItem(const DataItem & dataItem,OptRowDataWithLog & data,const std::vector<FieldInfo> & remoteFieldInfo)75 int DataTransformer::DeSerializeDataItem(const DataItem &dataItem, OptRowDataWithLog &data,
76     const std::vector<FieldInfo> &remoteFieldInfo)
77 {
78     if ((dataItem.flag & DataItem::DELETE_FLAG) == 0 &&
79         (dataItem.flag & DataItem::REMOTE_DEVICE_DATA_MISS_QUERY) == 0) {
80         int errCode = DeSerializeValue(dataItem.value, data.optionalData, remoteFieldInfo);
81         if (errCode != E_OK) {
82             return errCode;
83         }
84     }
85 
86     LogInfo &logInfo = data.logInfo;
87     logInfo.timestamp = dataItem.timestamp;
88     logInfo.device = dataItem.dev;
89     logInfo.originDev = dataItem.origDev;
90     logInfo.wTimestamp = dataItem.writeTimestamp;
91     logInfo.flag = dataItem.flag;
92     logInfo.hashKey = dataItem.hashKey;
93     return E_OK;
94 }
95 
CalDataValueLength(const DataValue & dataValue)96 uint32_t DataTransformer::CalDataValueLength(const DataValue &dataValue)
97 {
98     switch (dataValue.GetType()) {
99         case StorageType::STORAGE_TYPE_NULL:
100             return Parcel::GetUInt32Len();
101         case StorageType::STORAGE_TYPE_INTEGER:
102             return Parcel::GetInt64Len();
103         case StorageType::STORAGE_TYPE_REAL:
104             return Parcel::GetDoubleLen();
105         default:
106             break;
107     }
108     if (dataValue.GetType() != StorageType::STORAGE_TYPE_BLOB &&
109         dataValue.GetType() != StorageType::STORAGE_TYPE_TEXT) {
110         return 0u;
111     }
112     uint32_t length = 0;
113     switch (dataValue.GetType()) {
114         case StorageType::STORAGE_TYPE_BLOB:
115         case StorageType::STORAGE_TYPE_TEXT: {
116             Blob blob;
117             (void)dataValue.GetBlob(blob);
118             length = blob.GetSize();
119             length = Parcel::GetEightByteAlign(length);
120             length += Parcel::GetUInt32Len(); // record data length
121             break;
122         }
123         default:
124             break;
125     }
126     return length;
127 }
128 
129 namespace {
SerializeNullValue(const DataValue & dataValue,Parcel & parcel)130 int SerializeNullValue(const DataValue &dataValue, Parcel &parcel)
131 {
132     return parcel.WriteUInt32(0u);
133 }
134 
DeSerializeNullValue(DataValue & dataValue,Parcel & parcel)135 int DeSerializeNullValue(DataValue &dataValue, Parcel &parcel)
136 {
137     uint32_t dataLength = -1;
138     (void)parcel.ReadUInt32(dataLength);
139     if (parcel.IsError() || dataLength != 0) {
140         return -E_PARSE_FAIL;
141     }
142     dataValue.ResetValue();
143     return E_OK;
144 }
145 
SerializeIntValue(const DataValue & dataValue,Parcel & parcel)146 int SerializeIntValue(const DataValue &dataValue, Parcel &parcel)
147 {
148     int64_t val = 0;
149     (void)dataValue.GetInt64(val);
150     return parcel.WriteInt64(val);
151 }
152 
DeSerializeIntValue(DataValue & dataValue,Parcel & parcel)153 int DeSerializeIntValue(DataValue &dataValue, Parcel &parcel)
154 {
155     int64_t val = 0;
156     (void)parcel.ReadInt64(val);
157     if (parcel.IsError()) {
158         return -E_PARSE_FAIL;
159     }
160     dataValue = val;
161     return E_OK;
162 }
163 
SerializeDoubleValue(const DataValue & dataValue,Parcel & parcel)164 int SerializeDoubleValue(const DataValue &dataValue, Parcel &parcel)
165 {
166     double val = 0;
167     (void)dataValue.GetDouble(val);
168     return parcel.WriteDouble(val);
169 }
170 
DeSerializeDoubleValue(DataValue & dataValue,Parcel & parcel)171 int DeSerializeDoubleValue(DataValue &dataValue, Parcel &parcel)
172 {
173     double val = 0;
174     (void)parcel.ReadDouble(val);
175     if (parcel.IsError()) {
176         return -E_PARSE_FAIL;
177     }
178     dataValue = val;
179     return E_OK;
180 }
181 
SerializeBlobValue(const DataValue & dataValue,Parcel & parcel)182 int SerializeBlobValue(const DataValue &dataValue, Parcel &parcel)
183 {
184     Blob val;
185     (void)dataValue.GetBlob(val);
186     uint32_t size = val.GetSize();
187     int errCode = parcel.WriteUInt32(size);
188     if (errCode != E_OK) {
189         return errCode;
190     }
191     if (size != 0u) {
192         errCode = parcel.WriteBlob(reinterpret_cast<const char *>(val.GetData()), size);
193     }
194     return errCode;
195 }
196 
DeSerializeBlobByType(DataValue & dataValue,Parcel & parcel,StorageType type)197 int DeSerializeBlobByType(DataValue &dataValue, Parcel &parcel, StorageType type)
198 {
199     uint32_t blobLength = 0;
200     (void)parcel.ReadUInt32(blobLength);
201     if (blobLength >= DBConstant::MAX_VALUE_SIZE || parcel.IsError()) { // One blob cannot be over one value size.
202         return -E_PARSE_FAIL;
203     }
204     char *array = nullptr;
205     if (blobLength != 0u) {
206         array = new (std::nothrow) char[blobLength]();
207         if (array == nullptr) {
208             return -E_OUT_OF_MEMORY;
209         }
210         (void)parcel.ReadBlob(array, blobLength);
211         if (parcel.IsError()) {
212             delete []array;
213             return -E_PARSE_FAIL;
214         }
215     }
216 
217     int errCode = -E_NOT_SUPPORT;
218     if (type == StorageType::STORAGE_TYPE_TEXT) {
219         errCode = dataValue.SetText(reinterpret_cast<const uint8_t *>(array), blobLength);
220     } else if (type == StorageType::STORAGE_TYPE_BLOB) {
221         Blob val;
222         errCode = val.WriteBlob(reinterpret_cast<const uint8_t *>(array), blobLength);
223         if (errCode == E_OK) {
224             errCode = dataValue.SetBlob(val);
225         }
226     }
227     delete []array;
228     return errCode;
229 }
230 
DeSerializeBlobValue(DataValue & dataValue,Parcel & parcel)231 int DeSerializeBlobValue(DataValue &dataValue, Parcel &parcel)
232 {
233     return DeSerializeBlobByType(dataValue, parcel, StorageType::STORAGE_TYPE_BLOB);
234 }
235 
SerializeTextValue(const DataValue & dataValue,Parcel & parcel)236 int SerializeTextValue(const DataValue &dataValue, Parcel &parcel)
237 {
238     return SerializeBlobValue(dataValue, parcel);
239 }
240 
DeSerializeTextValue(DataValue & dataValue,Parcel & parcel)241 int DeSerializeTextValue(DataValue &dataValue, Parcel &parcel)
242 {
243     return DeSerializeBlobByType(dataValue, parcel, StorageType::STORAGE_TYPE_TEXT);
244 }
245 }
246 
SerializeDataValue(const DataValue & dataValue,Parcel & parcel)247 int DataTransformer::SerializeDataValue(const DataValue &dataValue, Parcel &parcel)
248 {
249     static const std::function<int(const DataValue&, Parcel&)> funcs[] = {
250         SerializeNullValue, SerializeIntValue,
251         SerializeDoubleValue, SerializeTextValue, SerializeBlobValue,
252     };
253     StorageType type = dataValue.GetType();
254     parcel.WriteUInt32(static_cast<uint32_t>(type));
255     if (type < StorageType::STORAGE_TYPE_NULL || type > StorageType::STORAGE_TYPE_BLOB) {
256         LOGE("Cannot serialize %u", static_cast<unsigned>(type));
257         return -E_NOT_SUPPORT;
258     }
259     return funcs[static_cast<uint32_t>(type) - 1](dataValue, parcel);
260 }
261 
DeserializeDataValue(DataValue & dataValue,Parcel & parcel)262 int DataTransformer::DeserializeDataValue(DataValue &dataValue, Parcel &parcel)
263 {
264     static const std::function<int(DataValue&, Parcel&)> funcs[] = {
265         DeSerializeNullValue, DeSerializeIntValue,
266         DeSerializeDoubleValue, DeSerializeTextValue, DeSerializeBlobValue,
267     };
268     uint32_t type = 0;
269     parcel.ReadUInt32(type);
270     if (type < static_cast<uint32_t>(StorageType::STORAGE_TYPE_NULL) ||
271         type > static_cast<uint32_t>(StorageType::STORAGE_TYPE_BLOB)) {
272         LOGE("Cannot deserialize %u", type);
273         return -E_PARSE_FAIL;
274     }
275     return funcs[type - 1](dataValue, parcel);
276 }
277 
SerializeValue(Value & value,const RowData & rowData,const std::vector<FieldInfo> & fieldInfoList)278 int DataTransformer::SerializeValue(Value &value, const RowData &rowData, const std::vector<FieldInfo> &fieldInfoList)
279 {
280     if (rowData.size() != fieldInfoList.size()) {
281         LOGE("[DataTransformer][SerializeValue] unequal field counts!");
282         return -E_INVALID_ARGS;
283     }
284 
285     uint64_t totalLength = Parcel::GetUInt64Len(); // first record field count
286     for (uint32_t i = 0; i < rowData.size(); ++i) {
287         const auto &dataValue = rowData[i];
288         totalLength += Parcel::GetUInt32Len(); // For save the dataValue's type.
289         uint32_t dataLength = CalDataValueLength(dataValue);
290         totalLength += dataLength;
291         if (totalLength > static_cast<uint64_t>(INT32_MAX)) {
292             LOGE("[DataTransformer][SerializeValue] DataValue is too large!");
293             return -E_INVALID_ARGS;
294         }
295     }
296     value.resize(static_cast<uint32_t>(totalLength));
297     if (value.size() != static_cast<uint32_t>(totalLength)) {
298         return -E_OUT_OF_MEMORY;
299     }
300     Parcel parcel(value.data(), value.size());
301     (void)parcel.WriteUInt64(rowData.size());
302     for (const auto &dataValue : rowData) {
303         int errCode = SerializeDataValue(dataValue, parcel);
304         if (errCode != E_OK) {
305             value.clear();
306             return errCode;
307         }
308     }
309     return E_OK;
310 }
311 
DeSerializeValue(const Value & value,OptRowData & optionalData,const std::vector<FieldInfo> & remoteFieldInfo)312 int DataTransformer::DeSerializeValue(const Value &value, OptRowData &optionalData,
313     const std::vector<FieldInfo> &remoteFieldInfo)
314 {
315     Parcel parcel(const_cast<uint8_t *>(value.data()), value.size());
316     uint64_t fieldCount = 0;
317     (void)parcel.ReadUInt64(fieldCount);
318     if (fieldCount > DBConstant::MAX_COLUMN || parcel.IsError()) {
319         return -E_PARSE_FAIL;
320     }
321     for (size_t i = 0; i < fieldCount; ++i) {
322         DataValue dataValue;
323         int errCode = DeserializeDataValue(dataValue, parcel);
324         if (errCode != E_OK) {
325             LOGD("[DataTransformer][DeSerializeValue] deSerialize failed");
326             return errCode;
327         }
328         optionalData.push_back(std::move(dataValue));
329     }
330     return E_OK;
331 }
332 } // namespace DistributedDB
333 #endif