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