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