• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 
16 #include "relational_store_utils.h"
17 #include "native_log.h"
18 #include "rdb_store.h"
19 
20 namespace OHOS {
21 namespace Relational {
MallocCString(const std::string & origin)22     char* MallocCString(const std::string& origin)
23     {
24         if (origin.empty()) {
25             return nullptr;
26         }
27         auto len = origin.length() + 1;
28         char* res = static_cast<char*>(malloc(sizeof(char) * len));
29         if (res == nullptr) {
30             return nullptr;
31         }
32         return std::char_traits<char>::copy(res, origin.c_str(), len);
33     }
34 
ValueTypeToValueObjectBlob(const ValueType & value)35     NativeRdb::ValueObject ValueTypeToValueObjectBlob(const ValueType& value)
36     {
37         std::vector<uint8_t> blob = std::vector<uint8_t>();
38         for (int64_t j = 0; j < value.Uint8Array.size; j++) {
39             blob.push_back(value.Uint8Array.head[j]);
40         }
41         return NativeRdb::ValueObject(blob);
42     }
43 
ValueTypeToValueObjectAsset(const ValueType & value)44     NativeRdb::ValueObject ValueTypeToValueObjectAsset(const ValueType& value)
45     {
46         std::string modifyTime = value.asset.modifyTime;
47         std::string size = value.asset.size;
48         NativeRdb::ValueObject::Asset asset = {
49             .status = value.asset.status,
50             .name = value.asset.name,
51             .uri = value.asset.uri,
52             .createTime = value.asset.createTime,
53             .modifyTime = modifyTime,
54             .size = size,
55             .hash = modifyTime + "_" + size,
56             .path = value.asset.path
57         };
58         return NativeRdb::ValueObject(asset);
59     }
60 
ValueTypeToValueObjectAssets(const ValueType & value)61     NativeRdb::ValueObject ValueTypeToValueObjectAssets(const ValueType& value)
62     {
63         std::vector<NativeRdb::ValueObject::Asset> assets = std::vector<NativeRdb::ValueObject::Asset>();
64         for (int64_t j = 0; j < value.assets.size; j++) {
65             Asset asset = value.assets.head[j];
66             std::string modifyTime = asset.modifyTime;
67             std::string size = asset.size;
68             NativeRdb::ValueObject::Asset nativeAsset = {
69                 .status = asset.status,
70                 .name = asset.name,
71                 .uri = asset.uri,
72                 .createTime = asset.createTime,
73                 .modifyTime = modifyTime,
74                 .size = size,
75                 .hash = modifyTime + "_" + size,
76                 .path = asset.path
77             };
78             assets.push_back(nativeAsset);
79         }
80         return NativeRdb::ValueObject(assets);
81     }
82 
ValueTypeToValueObject(const ValueType & value)83     NativeRdb::ValueObject ValueTypeToValueObject(const ValueType& value)
84     {
85         NativeRdb::ValueObject valueObject;
86         switch (value.tag) {
87             case TYPE_NULL: {
88                 valueObject = NativeRdb::ValueObject();
89                 break;
90             }
91             case TYPE_INT: {
92                 valueObject = NativeRdb::ValueObject(value.integer);
93                 break;
94             }
95             case TYPE_DOU: {
96                 valueObject = NativeRdb::ValueObject(value.dou);
97                 break;
98             }
99             case TYPE_STR: {
100                 valueObject = NativeRdb::ValueObject(value.string);
101                 break;
102             }
103             case TYPE_BOOL: {
104                 valueObject = NativeRdb::ValueObject(value.boolean);
105                 break;
106             }
107             case TYPE_BLOB: {
108                 valueObject = ValueTypeToValueObjectBlob(value);
109                 break;
110             }
111             case TYPE_ASSET: {
112                 valueObject = ValueTypeToValueObjectAsset(value);
113                 break;
114             }
115             case TYPE_ASSETS: {
116                 valueObject = ValueTypeToValueObjectAssets(value);
117                 break;
118             }
119             default:
120                 valueObject = NativeRdb::ValueObject();
121                 break;
122         }
123         return valueObject;
124     }
125 
ValueObjectToValueTypeAsset(const NativeRdb::ValueObject & object)126     ValueType ValueObjectToValueTypeAsset(const NativeRdb::ValueObject& object)
127     {
128         NativeRdb::ValueObject::Asset val;
129         object.GetAsset(val);
130         Asset asset = Asset {
131             .name = MallocCString(val.name),
132             .uri = MallocCString(val.uri),
133             .path = MallocCString(val.path),
134             .createTime = MallocCString(val.createTime),
135             .modifyTime = MallocCString(val.modifyTime),
136             .size = MallocCString(val.size),
137             .status = val.status
138         };
139         return ValueType {.asset = asset, .tag = TYPE_ASSET};
140     }
141 
ValueObjectToValueTypeAssets(const NativeRdb::ValueObject & object)142     ValueType ValueObjectToValueTypeAssets(const NativeRdb::ValueObject& object)
143     {
144         NativeRdb::ValueObject::Assets val;
145         object.GetAssets(val);
146         Assets assets = Assets {.head = static_cast<Asset*>(malloc(val.size() * sizeof(Asset))), .size = val.size()};
147         if (assets.head == nullptr) {
148             return ValueType {.assets = Assets{nullptr, -1}, .tag = TYPE_ASSETS};
149         }
150         for (std::size_t i = 0; i < val.size(); i++) {
151             assets.head[i] = Asset {
152                 .name = MallocCString(val[i].name),
153                 .uri = MallocCString(val[i].uri),
154                 .path = MallocCString(val[i].path),
155                 .createTime = MallocCString(val[i].createTime),
156                 .modifyTime = MallocCString(val[i].modifyTime),
157                 .size = MallocCString(val[i].size),
158                 .status = static_cast<int32_t>(val[i].status)
159             };
160         }
161         return ValueType {.assets = assets, .tag = TYPE_ASSETS};
162     }
163 
ValueObjectToValueType(const NativeRdb::ValueObject & object)164     ValueType ValueObjectToValueType(const NativeRdb::ValueObject& object)
165     {
166         switch (object.GetType()) {
167             case NativeRdb::ValueObject::TYPE_NULL:
168                 return ValueType {.tag = TYPE_NULL};
169             case NativeRdb::ValueObject::TYPE_INT: {
170                 int64_t val;
171                 object.GetLong(val);
172                 return ValueType {.integer = val, .tag = TYPE_INT};
173             }
174             case NativeRdb::ValueObject::TYPE_DOUBLE: {
175                 double val;
176                 object.GetDouble(val);
177                 return ValueType {.dou = val, .tag = TYPE_DOU};
178             }
179             case NativeRdb::ValueObject::TYPE_STRING: {
180                 std::string val;
181                 object.GetString(val);
182                 return ValueType {.string = MallocCString(val), .tag = TYPE_STR};
183             }
184             case NativeRdb::ValueObject::TYPE_BOOL: {
185                 bool val;
186                 object.GetBool(val);
187                 return ValueType {.boolean = val, .tag = TYPE_BOOL};
188             }
189             case NativeRdb::ValueObject::TYPE_BLOB: {
190                 std::vector<uint8_t> val;
191                 object.GetBlob(val);
192                 CArrUI8 arr = CArrUI8 {.head = static_cast<uint8_t*>(malloc(val.size() * sizeof(uint8_t))),
193                     .size = val.size()};
194                 if (arr.head == nullptr) {
195                     return ValueType {.Uint8Array = CArrUI8 {nullptr, -1}, .tag = TYPE_BLOB};
196                 }
197                 return ValueType {.Uint8Array = arr, .tag = TYPE_BLOB};
198             }
199             case NativeRdb::ValueObject::TYPE_ASSET: {
200                 return ValueObjectToValueTypeAsset(object);
201             }
202             case NativeRdb::ValueObject::TYPE_ASSETS: {
203                 return ValueObjectToValueTypeAssets(object);
204             }
205             case NativeRdb::ValueObject::TYPE_BUTT:
206                 return ValueType {.tag = 128};
207             default:
208                 return ValueType {.tag = TYPE_NULL};
209         }
210     }
211 
VectorToCArrStr(const std::vector<std::string> & devices)212     CArrStr VectorToCArrStr(const std::vector<std::string> &devices)
213     {
214         CArrStr cArrStr{0};
215         if (devices.size() == 0) {
216             return cArrStr;
217         }
218         cArrStr.head = static_cast<char**>(malloc(sizeof(char*) * devices.size()));
219         if (cArrStr.head == nullptr) {
220             return cArrStr;
221         }
222         for (size_t i = 0; i < devices.size(); i++) {
223             cArrStr.head[i] = MallocCString(devices[i]);
224         }
225         cArrStr.size = static_cast<int64_t>(devices.size());
226         return cArrStr;
227     }
228 
CArrStrToVector(CArrStr carr)229     std::vector<std::string> CArrStrToVector(CArrStr carr)
230     {
231         std::vector<std::string> arr;
232         for (int i = 0; i < carr.size; i++) {
233             if (carr.head[i] != nullptr) {
234                 arr.push_back(carr.head[i]);
235             } else {
236                 arr.push_back(std::string());
237             }
238         }
239         return arr;
240     }
241 
RetPRIKeyTypeToVariant(RetPRIKeyType & value)242     std::variant<std::monostate, std::string, int64_t, double> RetPRIKeyTypeToVariant(RetPRIKeyType &value)
243     {
244         switch (value.tag) {
245             case NativeRdb::ValueObject::TYPE_INT:
246                 return std::variant<std::monostate, std::string, int64_t, double>(value.integer);
247             case NativeRdb::ValueObject::TYPE_DOUBLE:
248                 return std::variant<std::monostate, std::string, int64_t, double>(value.dou);
249             case NativeRdb::ValueObject::TYPE_STRING:
250                 return std::variant<std::monostate, std::string, int64_t, double>(value.string);
251             default:
252                 return std::variant<std::monostate, std::string, int64_t, double>(0);
253         }
254     }
255 
VariantToRetPRIKeyType(const std::variant<std::monostate,std::string,int64_t,double> & value)256     RetPRIKeyType VariantToRetPRIKeyType(const std::variant<std::monostate, std::string, int64_t, double> &value)
257     {
258         if (std::holds_alternative<int64_t>(value)) {
259             return RetPRIKeyType{ .integer = std::get<int64_t>(value), .dou = 0.0,
260                 .string = nullptr, .tag = NativeRdb::ValueObject::TYPE_INT };
261         } else if (std::holds_alternative<double>(value)) {
262             return RetPRIKeyType{ .integer = 0, .dou = std::get<double>(value),
263                 .string = nullptr, .tag = NativeRdb::ValueObject::TYPE_DOUBLE };
264         } else if (std::holds_alternative<std::string>(value)) {
265             return RetPRIKeyType{ .integer = 0, .dou = 0.0,
266                 .string = MallocCString(std::get<std::string>(value)), .tag = NativeRdb::ValueObject::TYPE_STRING };
267         } else {
268             return RetPRIKeyType{0};
269         }
270     }
271 
CArrPRIKeyTypeToPRIKeyArray(CArrPRIKeyType & cPrimaryKeys)272     std::vector<NativeRdb::RdbStore::PRIKey> CArrPRIKeyTypeToPRIKeyArray(CArrPRIKeyType &cPrimaryKeys)
273     {
274         std::vector<NativeRdb::RdbStore::PRIKey> res = std::vector<NativeRdb::RdbStore::PRIKey>();
275         for (int64_t i = 0; i < cPrimaryKeys.size; i++) {
276             res.push_back(RetPRIKeyTypeToVariant(cPrimaryKeys.head[i]));
277         }
278         return res;
279     }
280 
MapToModifyTime(std::map<NativeRdb::RdbStore::PRIKey,NativeRdb::RdbStore::Date> & map,int32_t & errCode)281     ModifyTime MapToModifyTime(std::map<NativeRdb::RdbStore::PRIKey, NativeRdb::RdbStore::Date> &map, int32_t &errCode)
282     {
283         ModifyTime modifyTime{0};
284         modifyTime.size = static_cast<int64_t>(map.size());
285         modifyTime.key = static_cast<RetPRIKeyType*>(malloc(sizeof(RetPRIKeyType) * modifyTime.size));
286         modifyTime.value = static_cast<uint64_t*>(malloc(sizeof(uint64_t) * modifyTime.size));
287         if (modifyTime.key == nullptr || modifyTime.value == nullptr) {
288             free(modifyTime.key);
289             free(modifyTime.value);
290             errCode = -1;
291             return ModifyTime{0};
292         }
293         int64_t index = 0;
294         for (auto it = map.begin(); it != map.end(); ++it) {
295             modifyTime.key[index] = VariantToRetPRIKeyType(it->first);
296             modifyTime.value[index] = static_cast<uint64_t>((it->second).date);
297             index++;
298         }
299         return modifyTime;
300     }
301 
VectorToCArrPRIKeyType(std::vector<DistributedRdb::RdbStoreObserver::PrimaryKey> arr)302     CArrPRIKeyType VectorToCArrPRIKeyType(std::vector<DistributedRdb::RdbStoreObserver::PrimaryKey> arr)
303     {
304         CArrPRIKeyType types{0};
305         if (arr.size() == 0) {
306             return types;
307         }
308         types.head = static_cast<RetPRIKeyType*>(malloc(sizeof(RetPRIKeyType) * arr.size()));
309         if (types.head == nullptr) {
310             return types;
311         }
312         for (size_t i = 0; i < arr.size(); i++) {
313             types.head[i] = VariantToRetPRIKeyType(arr[i]);
314         }
315         types.size = static_cast<int64_t>(arr.size());
316         return types;
317     }
318 
ToRetChangeInfo(const DistributedRdb::Origin & origin,DistributedRdb::RdbStoreObserver::ChangeInfo::iterator info)319     RetChangeInfo ToRetChangeInfo(const DistributedRdb::Origin &origin,
320         DistributedRdb::RdbStoreObserver::ChangeInfo::iterator info)
321     {
322         RetChangeInfo retInfo{0};
323         retInfo.table = MallocCString(info->first);
324         retInfo.type = origin.dataType;
325         retInfo.inserted = VectorToCArrPRIKeyType(info->
326             second[DistributedRdb::RdbStoreObserver::ChangeType::CHG_TYPE_INSERT]);
327         retInfo.updated = VectorToCArrPRIKeyType(info->
328             second[DistributedRdb::RdbStoreObserver::ChangeType::CHG_TYPE_UPDATE]);
329         retInfo.deleted = VectorToCArrPRIKeyType(info->
330             second[DistributedRdb::RdbStoreObserver::ChangeType::CHG_TYPE_DELETE]);
331         return retInfo;
332     }
333 
ToCArrRetChangeInfo(const DistributedRdb::Origin & origin,const DistributedRdb::RdbStoreObserver::PrimaryFields & fields,DistributedRdb::RdbStoreObserver::ChangeInfo && changeInfo)334     CArrRetChangeInfo ToCArrRetChangeInfo(const DistributedRdb::Origin &origin,
335         const DistributedRdb::RdbStoreObserver::PrimaryFields &fields,
336         DistributedRdb::RdbStoreObserver::ChangeInfo &&changeInfo)
337     {
338         CArrRetChangeInfo infos{0};
339         if (changeInfo.size() == 0) {
340             return infos;
341         }
342         infos.head = static_cast<RetChangeInfo*>(malloc(sizeof(RetChangeInfo) * changeInfo.size()));
343         if (infos.head == nullptr) {
344             return CArrRetChangeInfo{0};
345         }
346         int64_t index = 0;
347         for (auto it = changeInfo.begin(); it != changeInfo.end(); ++it) {
348             infos.head[index] = ToRetChangeInfo(origin, it);
349             index++;
350         }
351         infos.size = static_cast<int64_t>(changeInfo.size());
352         return infos;
353     }
354 
ToStatistic(DistributedRdb::Statistic statistic)355     CStatistic ToStatistic(DistributedRdb::Statistic statistic)
356     {
357         return CStatistic{ .total = statistic.total, .successful = statistic.success,
358             .failed = statistic.failed, .remained = statistic.untreated };
359     }
360 
ToCTableDetails(DistributedRdb::TableDetail detail)361     CTableDetails ToCTableDetails(DistributedRdb::TableDetail detail)
362     {
363         return CTableDetails{ .upload = ToStatistic(detail.upload), .download = ToStatistic(detail.download) };
364     }
365 
ToCDetails(DistributedRdb::TableDetails details)366     CDetails ToCDetails(DistributedRdb::TableDetails details)
367     {
368         if (details.size() == 0) {
369             return CDetails{0};
370         }
371         char** key = static_cast<char**>(malloc(sizeof(char*) * details.size()));
372         CTableDetails* value = static_cast<CTableDetails*>(malloc(sizeof(CTableDetails) * details.size()));
373         if (key == nullptr || value == nullptr) {
374             free(key);
375             free(value);
376             return CDetails{0};
377         }
378         int64_t index = 0;
379         for (auto it = details.begin(); it != details.end(); ++it) {
380             key[index] = MallocCString(it->first);
381             value[index] = ToCTableDetails(it->second);
382             index++;
383         }
384         return CDetails{ .key = key, .value = value, .size = details.size() };
385     }
386 
ToCProgressDetails(const DistributedRdb::Details & details)387     CProgressDetails ToCProgressDetails(const  DistributedRdb::Details &details)
388     {
389         if (details.empty()) {
390             return CProgressDetails{0};
391         }
392         DistributedRdb::ProgressDetail detail = details.begin() ->second;
393         return CProgressDetails{ .schedule = detail.progress, .code = detail.code,
394             .details = ToCDetails(detail.details) };
395     }
396 }
397 }