• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #define LOG_TAG "CloudDbProxy"
17 
18 #include "cloud_db_proxy.h"
19 
20 #include <cerrno>
21 #include <cstring>
22 #include <securec.h>
23 
24 #include "db_error.h"
25 #include "log_print.h"
26 
27 namespace OHOS::CollaborationEdit {
28 // batchInsert log field index
29 constexpr int32_t LOG_EQUIP_ID_FIELD_IDX = 0;
30 constexpr int32_t LOG_TIMESTAMP_FIELD_IDX = 1;
31 constexpr int32_t LOG_SYNC_LOG_FIELD_IDX = 2;
32 constexpr int32_t LOG_MAX_FIELD_SIZE = 3;
33 
34 // query result field index
35 constexpr uint8_t QRY_RSP_EQUIP_ID_IDX = 0u;
36 constexpr uint8_t QRY_RSP_TIMESTAMP_IDX = 1u;
37 constexpr uint8_t QRY_RSP_SYNC_LOG_IDX = 2u;
38 constexpr uint8_t QRY_RSP_CURSOR_IDX = 3u;
39 constexpr uint8_t QRY_MAX_FIELD_SIZE = 4u;
40 
41 const std::string EQUIP_ID = "equipId";
42 const std::string CURSOR = "cursor";
43 const std::string SYNC_LOG_EVENT = "syncLogEvent";
44 const std::string TIMESTAMP = "timestamp";
45 
46 constexpr int CURSOR_BASE = 10;
47 
48 static const std::map<GRD_QueryConditionTypeE, Predicate> PREDICATE_MAP = {
49     {GRD_QUERY_CONDITION_TYPE_EQUAL_TO, EQUAL_TO},
50     {GRD_QUERY_CONDITION_TYPE_NOT_EQUAL_TO, NOT_EQUAL_TO},
51     {GRD_QUERY_CONDITION_TYPE_GREATER_THAN, GREATER_THAN},
52     {GRD_QUERY_CONDITION_TYPE_LESS_THAN, LESS_THAN},
53     {GRD_QUERY_CONDITION_TYPE_GREATER_THAN_OR_EQUAL_TO, GREATER_THAN_OR_EQUAL_TO},
54     {GRD_QUERY_CONDITION_TYPE_LESS_THAN_OR_EQUAL_TO, LESS_THAN_OR_EQUAL_TO}
55 };
56 
57 static const std::map<uint8_t, ExtendFieldParser> QRY_RSP_PARSER_MAP = {
58     {QRY_RSP_EQUIP_ID_IDX, CloudDbProxy::EquipIdParseFunc},
59     {QRY_RSP_TIMESTAMP_IDX, CloudDbProxy::TimestampParseFunc},
60     {QRY_RSP_SYNC_LOG_IDX, CloudDbProxy::SyncLogParseFunc},
61     {QRY_RSP_CURSOR_IDX, CloudDbProxy::CursorParseFunc}
62 };
63 
~CloudDbProxy()64 CloudDbProxy::~CloudDbProxy()
65 {
66     if (napiCloudDb_ != nullptr) {
67         delete napiCloudDb_;
68         napiCloudDb_ = nullptr;
69     }
70 }
71 
SetNapiCloudDb(NapiCloudDb * napiCloudDb)72 void CloudDbProxy::SetNapiCloudDb(NapiCloudDb *napiCloudDb)
73 {
74     napiCloudDb_ = napiCloudDb;
75 }
76 
GetCloudRecord(GRD_CloudRecordT & record,CloudParamsAdapterT & paramsAdapter)77 int32_t CloudDbProxy::GetCloudRecord(GRD_CloudRecordT &record, CloudParamsAdapterT &paramsAdapter)
78 {
79     if (record.fieldSize != LOG_MAX_FIELD_SIZE) {
80         LOG_ERROR("[GetCloudRecord] field size go wrong, size = %{public}d", record.fieldSize);
81         return E_INVALID_ARGS;
82     }
83     GRD_CloudFieldT equipId = record.fields[LOG_EQUIP_ID_FIELD_IDX];
84     paramsAdapter.id.assign(static_cast<char *>(equipId.value));
85 
86     GRD_CloudFieldT syncLog = record.fields[LOG_SYNC_LOG_FIELD_IDX];
87     paramsAdapter.record.assign(static_cast<uint8_t *>(syncLog.value),
88         static_cast<uint8_t *>(syncLog.value) + syncLog.valueLen);
89 
90     GRD_CloudFieldT timestamp = record.fields[LOG_TIMESTAMP_FIELD_IDX];
91     uint64_t *timestampPtr = static_cast<uint64_t *>(timestamp.value);
92     paramsAdapter.timestamp = *timestampPtr;
93     return E_OK;
94 }
95 
FreeExtendFields(GRD_CloudFieldT * fields,uint8_t fieldSize)96 void CloudDbProxy::FreeExtendFields(GRD_CloudFieldT *fields, uint8_t fieldSize)
97 {
98     for (uint8_t i = 0; i < fieldSize; i++) {
99         if (fields[i].key != nullptr) {
100             free(fields[i].key);
101             fields[i].key = nullptr;
102         }
103 
104         if (fields[i].value != nullptr) {
105             free(fields[i].value);
106             fields[i].value = nullptr;
107         }
108     }
109 }
110 
CreateSingleField(GRD_CloudFieldT & field,ExtendRecordFieldT & srcField)111 int32_t CloudDbProxy::CreateSingleField(GRD_CloudFieldT &field, ExtendRecordFieldT &srcField)
112 {
113     void *fieldVal = malloc(srcField.valueLen);
114     if (fieldVal == nullptr) {
115         LOG_ERROR("alloc field value go wrong");
116         return E_OUT_OF_MEMORY;
117     }
118     (void)memset_s(fieldVal, srcField.valueLen, 0, srcField.valueLen);
119     errno_t err = memcpy_s(fieldVal, srcField.valueLen, srcField.valuePtr, srcField.valueLen);
120     if (err != EOK) {
121         LOG_ERROR("copy field value go wrong, err: %{public}d", err);
122         free(fieldVal);
123         return E_MEMORY_OPERATION_ERROR;
124     }
125 
126     char *fieldKey = static_cast<char *>(malloc(srcField.fieldName.length() + 1));
127     if (fieldKey == nullptr) {
128         LOG_ERROR("alloc field key go wrong");
129         free(fieldVal);
130         return E_OUT_OF_MEMORY;
131     }
132     err = strcpy_s(fieldKey, srcField.fieldName.length() + 1, srcField.fieldName.c_str());
133     if (err != EOK) {
134         LOG_ERROR("copy field key go wrong, err: %{public}d", err);
135         free(fieldVal);
136         free(fieldKey);
137         return E_MEMORY_OPERATION_ERROR;
138     }
139     field.key = fieldKey;
140     field.value = fieldVal;
141     field.type = srcField.type;
142     field.valueLen = srcField.valueLen;
143     return E_OK;
144 }
145 
ParseExtendField(CloudParamsAdapterT & extend,uint32_t index,GRD_CloudRecordT * records,uint32_t maxRecordSize)146 int32_t CloudDbProxy::ParseExtendField(CloudParamsAdapterT &extend, uint32_t index, GRD_CloudRecordT *records,
147     uint32_t maxRecordSize)
148 {
149     if (index >= maxRecordSize) {
150         LOG_ERROR("index is wrong, index:%{public}u, max:%{public}u", index, maxRecordSize);
151         return E_INVALID_ARGS;
152     }
153     size_t fieldSize = sizeof(GRD_CloudFieldT) * QRY_MAX_FIELD_SIZE;
154     records[index].fields = static_cast<GRD_CloudFieldT *>(malloc(fieldSize));
155     if (records[index].fields == nullptr) {
156         LOG_ERROR("alloc for extend field go wrong");
157         return E_OUT_OF_MEMORY;
158     }
159     (void)memset_s(records[index].fields, fieldSize, 0, fieldSize);
160 
161     int32_t ret = E_OK;
162     for (uint8_t i = 0; i < QRY_MAX_FIELD_SIZE; i++) {
163         ExtendRecordFieldT field = {};
164         auto it = QRY_RSP_PARSER_MAP.find(i);
165         if (it == QRY_RSP_PARSER_MAP.end()) {
166             LOG_ERROR("field content index is wrong, index=%{public}u", i);
167             FreeExtendFields(records[index].fields, records[index].fieldSize);
168             free(records[index].fields);
169             records[index].fields = nullptr;
170             return E_INVALID_ARGS;
171         }
172         it->second(extend, field);
173 
174         ret = CreateSingleField(records[index].fields[i], field);
175         if (ret != E_OK) {
176             LOG_ERROR("create single field go wrong, index=%{public}u, ret=%{public}d", i, ret);
177             FreeExtendFields(records[index].fields, records[index].fieldSize);
178             free(records[index].fields);
179             records[index].fields = nullptr;
180             return ret;
181         }
182         records[index].fieldSize++;
183     }
184     return E_OK;
185 }
186 
ParseExtendVector(GRD_CloudParamsT * cloudParams,std::vector<CloudParamsAdapterT> & extends)187 int32_t CloudDbProxy::ParseExtendVector(GRD_CloudParamsT *cloudParams, std::vector<CloudParamsAdapterT> &extends)
188 {
189     if (cloudParams == nullptr) {
190         LOG_ERROR("cloud params is nullptr");
191         return E_INVALID_ARGS;
192     }
193     if (cloudParams->extends == nullptr || *cloudParams->extends != nullptr || cloudParams->extendSize == nullptr) {
194         LOG_ERROR("extend field is nullptr");
195         return E_INVALID_ARGS;
196     }
197     size_t totalSize = sizeof(GRD_CloudRecordT) * extends.size();
198     *cloudParams->extends = (GRD_CloudRecordT *)malloc(totalSize);
199     if (*cloudParams->extends == nullptr) {
200         LOG_ERROR("alloc extends go wrong");
201         return E_INVALID_ARGS;
202     }
203     (void)memset_s(*cloudParams->extends, totalSize, 0, totalSize);
204 
205     int32_t ret = E_OK;
206     for (CloudParamsAdapterT extend : extends) {
207         ret = ParseExtendField(extend, *cloudParams->extendSize, *cloudParams->extends, extends.size());
208         if (ret != E_OK) {
209             LOG_ERROR("parse extend field go wrong, ret=%{public}d", ret);
210             free(*cloudParams->extends);
211             *(cloudParams->extendSize) = 0;
212             return ret;
213         }
214         (*cloudParams->extendSize)++;
215     }
216     return E_OK;
217 }
218 
GetCloudParamsVector(GRD_CloudParamsT * cloudParams,std::vector<CloudParamsAdapterT> & cloudParamsVector)219 int32_t CloudDbProxy::GetCloudParamsVector(GRD_CloudParamsT *cloudParams,
220     std::vector<CloudParamsAdapterT> &cloudParamsVector)
221 {
222     if (cloudParams == nullptr) {
223         LOG_ERROR("[GetCloudParamsVector] cloud params is nullptr");
224         return E_INVALID_ARGS;
225     }
226     for (uint32_t i = 0; i < cloudParams->recordSize; i++) {
227         CloudParamsAdapterT paramsAdapter;
228         int32_t ret = GetCloudRecord(cloudParams->records[i], paramsAdapter);
229         if (ret != 0) {
230             LOG_ERROR("[GetCloudParamsVector] get cloud record go wrong, ret = %{public}d", ret);
231             return ret;
232         }
233         cloudParamsVector.push_back(paramsAdapter);
234     }
235     return E_OK;
236 }
237 
GetQueryParams(GRD_CloudParamsT * cloudParams,std::vector<QueryConditionT> & queryConditions)238 int32_t CloudDbProxy::GetQueryParams(GRD_CloudParamsT *cloudParams, std::vector<QueryConditionT> &queryConditions)
239 {
240     if (cloudParams == nullptr) {
241         LOG_ERROR("cloud params is nullptr");
242         return E_INVALID_ARGS;
243     }
244     if (cloudParams->records == nullptr || cloudParams->recordSize == 0) {
245         LOG_ERROR("record field is wrong");
246         return E_INVALID_ARGS;
247     }
248 
249     GRD_CloudRecordT record = cloudParams->records[0];
250     for (uint8_t i = 0; i < record.fieldSize; i++) {
251         GRD_CloudFieldT field = record.fields[i];
252         QueryConditionT condition;
253         condition.fieldName = std::string(field.key);
254         auto it = PREDICATE_MAP.find(field.condition);
255         if (it == PREDICATE_MAP.end()) {
256             LOG_ERROR("predicate is wrong, field name: %{public}s, predicate = %{public}d", field.key, field.condition);
257             queryConditions.clear();
258             return E_INVALID_ARGS;
259         }
260         condition.predicate = it->second;
261         if (condition.fieldName == CURSOR) {
262             if (field.valueLen <= 1) {
263                 condition.fieldValue_num = 0;
264                 queryConditions.push_back(condition);
265                 continue;
266             }
267             condition.fieldValue_num = GetCursorValue(field);
268             if (condition.fieldValue_num < 0) {
269                 queryConditions.clear();
270                 return E_INVALID_ARGS;
271             }
272         } else if (condition.fieldName == EQUIP_ID) {
273             condition.fieldValue_str = std::string(static_cast<char *>(field.value));
274         } else {
275             LOG_ERROR("condition field name is wrong, field name: %{public}s", field.key);
276             queryConditions.clear();
277             return E_INVALID_ARGS;
278         }
279         queryConditions.push_back(condition);
280     }
281     return E_OK;
282 }
283 
GetCursorValue(GRD_CloudFieldT & field)284 int64_t CloudDbProxy::GetCursorValue(GRD_CloudFieldT &field)
285 {
286     int64_t cursor = -1;
287     if (field.value == nullptr) {
288         LOG_ERROR("field value is null");
289         return cursor;
290     }
291     std::string tmpString;
292     tmpString.resize(field.valueLen);
293     errno_t errNo = memcpy_s(&tmpString[0], field.valueLen, field.value, field.valueLen);
294     if (errNo != EOK) {
295         LOG_ERROR("copy cursor value wrong");
296         return cursor;
297     }
298     errno = 0;
299     cursor = std::strtol(tmpString.c_str(), nullptr, CURSOR_BASE);
300     if (errno == EINVAL) {
301         LOG_ERROR("cursor field is not integer");
302         cursor = -1;
303     }
304     if (errno == ERANGE) {
305         LOG_ERROR("cursor is too long");
306         cursor = -1;
307     }
308     return cursor;
309 }
310 
CursorParseFunc(CloudParamsAdapterT & extend,ExtendRecordFieldT & destField)311 void CloudDbProxy::CursorParseFunc(CloudParamsAdapterT &extend, ExtendRecordFieldT &destField)
312 {
313     destField.type = GRD_CLOUD_FIELD_TYPE_STRING;
314     destField.fieldName = CURSOR;
315     destField.valueLen = std::to_string(extend.cursor).length() + 1;
316     destField.fieldValue_str = std::to_string(extend.cursor);
317     destField.valuePtr = reinterpret_cast<const void *>(destField.fieldValue_str.c_str());
318 }
319 
EquipIdParseFunc(CloudParamsAdapterT & extend,ExtendRecordFieldT & destField)320 void CloudDbProxy::EquipIdParseFunc(CloudParamsAdapterT &extend, ExtendRecordFieldT &destField)
321 {
322     destField.type = GRD_CLOUD_FIELD_TYPE_STRING;
323     destField.fieldName = EQUIP_ID;
324     destField.valueLen = extend.id.length() + 1;
325     destField.valuePtr = reinterpret_cast<const void *>(extend.id.c_str());
326 }
327 
TimestampParseFunc(CloudParamsAdapterT & extend,ExtendRecordFieldT & destField)328 void CloudDbProxy::TimestampParseFunc(CloudParamsAdapterT &extend, ExtendRecordFieldT &destField)
329 {
330     destField.type = GRD_CLOUD_FIELD_TYPE_INT;
331     destField.fieldName = TIMESTAMP;
332     destField.valueLen = sizeof(uint64_t);
333     destField.valuePtr = &extend.timestamp;
334 }
335 
SyncLogParseFunc(CloudParamsAdapterT & extend,ExtendRecordFieldT & destField)336 void CloudDbProxy::SyncLogParseFunc(CloudParamsAdapterT &extend, ExtendRecordFieldT &destField)
337 {
338     destField.type = GRD_CLOUD_FIELD_TYPE_BYTES;
339     destField.fieldName = SYNC_LOG_EVENT;
340     destField.valueLen = extend.record.size() * sizeof(uint8_t);
341     destField.valuePtr = reinterpret_cast<const void *>(extend.record.data());
342 }
343 
BatchInsert(void * cloudDB,GRD_CloudParamsT * cloudParams)344 int32_t CloudDbProxy::BatchInsert(void *cloudDB, GRD_CloudParamsT *cloudParams)
345 {
346     std::vector<CloudParamsAdapterT> cloudParamsVector;
347     int32_t ret = GetCloudParamsVector(cloudParams, cloudParamsVector);
348     if (ret != E_OK) {
349         LOG_ERROR("[BatchInsert] get cloud params go wrong, ret = %{public}d", ret);
350         return ret;
351     }
352     CloudDbProxy *cloudDbProxy = static_cast<CloudDbProxy *>(cloudDB);
353     return cloudDbProxy->napiCloudDb_->BatchInsert(cloudParamsVector);
354 }
355 
Query(void * cloudDB,GRD_CloudParamsT * cloudParams)356 int32_t CloudDbProxy::Query(void *cloudDB, GRD_CloudParamsT *cloudParams)
357 {
358     std::vector<QueryConditionT> queryConditions;
359     int32_t ret = GetQueryParams(cloudParams, queryConditions);
360     if (ret != E_OK) {
361         LOG_ERROR("get cloud params go wrong, ret = %{public}d", ret);
362         return CloudErrorCodeE::E_CLOUD_ERROR;
363     }
364     std::vector<CloudParamsAdapterT> extends;
365     CloudDbProxy *cloudDbProxy = static_cast<CloudDbProxy *>(cloudDB);
366     ret = cloudDbProxy->napiCloudDb_->Query(queryConditions, extends);
367     if (ret == CloudErrorCodeE::E_CLOUD_ERROR) {
368         LOG_ERROR("cloudDb query go wrong, ret = %{public}d", ret);
369         return ret;
370     }
371     if (ret == CloudErrorCodeE::E_QUERY_END) {
372         return ret;
373     }
374     // set query result to cloudParams
375     ret = ParseExtendVector(cloudParams, extends);
376     if (ret != E_OK) {
377         LOG_ERROR("cloudDb query parse result go wrong, ret = %{public}d", ret);
378         return CloudErrorCodeE::E_CLOUD_ERROR;
379     }
380     return CloudErrorCodeE::E_CLOUD_OK;
381 }
382 
DownloadAsset(void * cloudDB,const char * equipId,char * path)383 int32_t CloudDbProxy::DownloadAsset(void *cloudDB, const char *equipId, char *path)
384 {
385     CloudDbProxy *cloudDbProxy = static_cast<CloudDbProxy *>(cloudDB);
386     std::string equipIdStr(equipId);
387     std::string pathStr(path);
388     return cloudDbProxy->napiCloudDb_->DownloadAsset(equipIdStr, pathStr);
389 }
390 
UploadAsset(void * cloudDB,char * path)391 int32_t CloudDbProxy::UploadAsset(void *cloudDB, char *path)
392 {
393     CloudDbProxy *cloudDbProxy = static_cast<CloudDbProxy *>(cloudDB);
394     std::string pathStr(path);
395     return cloudDbProxy->napiCloudDb_->UploadAsset(pathStr);
396 }
397 
DeleteAsset(void * cloudDB,char * path)398 int32_t CloudDbProxy::DeleteAsset(void *cloudDB, char *path)
399 {
400     CloudDbProxy *cloudDbProxy = static_cast<CloudDbProxy *>(cloudDB);
401     std::string pathStr(path);
402     return cloudDbProxy->napiCloudDb_->DeleteAsset(pathStr);
403 }
404 
DeleteLocalAsset(void * cloudDB,char * path)405 int32_t CloudDbProxy::DeleteLocalAsset(void *cloudDB, char *path)
406 {
407     CloudDbProxy *cloudDbProxy = static_cast<CloudDbProxy *>(cloudDB);
408     std::string pathStr(path);
409     return cloudDbProxy->napiCloudDb_->DeleteLocalAsset(pathStr);
410 }
411 
SendAwarenessData(void * cloudDB,const uint8_t * data,uint32_t dataSize)412 int32_t CloudDbProxy::SendAwarenessData(void *cloudDB, const uint8_t *data, uint32_t dataSize)
413 {
414     return E_OK;
415 }
416 
Lock(void * cloudDB,uint32_t * lockTimeMs)417 int32_t CloudDbProxy::Lock(void *cloudDB, uint32_t *lockTimeMs)
418 {
419     return E_OK;
420 }
421 
UnLock(void * cloudDB)422 int32_t CloudDbProxy::UnLock(void *cloudDB)
423 {
424     return E_OK;
425 }
426 
HeartBeat(void * cloudDB)427 int32_t CloudDbProxy::HeartBeat(void *cloudDB)
428 {
429     return E_OK;
430 }
431 
Close(void * cloudDB)432 int32_t CloudDbProxy::Close(void *cloudDB)
433 {
434     return E_OK;
435 }
436 } // namespace OHOS::CollaborationEdit
437