• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "ExtensionCloudServerImpl"
17 #include "cloud_server_impl.h"
18 #include "accesstoken_kit.h"
19 #include "asset_loader_impl.h"
20 #include "cloud_extension.h"
21 #include "cloud_ext_types.h"
22 #include "cloud/subscription.h"
23 #include "error.h"
24 #include "error/general_error.h"
25 #include "extension_util.h"
26 #include "log_print.h"
27 #include "metadata/meta_data_manager.h"
28 #include "utils/anonymous.h"
29 
30 namespace OHOS::CloudData {
31 __attribute__((used)) static bool g_isInit = CloudServerImpl::Init();
32 using namespace Security::AccessToken;
33 using DBMetaMgr = DistributedData::MetaDataManager;
34 using Anonymous = DistributedData::Anonymous;
35 
Init()36 bool CloudServerImpl::Init()
37 {
38     static CloudServerImpl cloudServerInstance;
39     static std::once_flag onceFlag;
40     std::call_once(onceFlag, [&]() { DistributedData::CloudServer::RegisterCloudInstance(&cloudServerInstance); });
41     return true;
42 }
43 
GetServerInfo(int32_t userId,bool needSpaceInfo)44 std::pair<int32_t, DBCloudInfo> CloudServerImpl::GetServerInfo(int32_t userId, bool needSpaceInfo)
45 {
46     DBCloudInfo result;
47     OhCloudExtCloudSync *server = OhCloudExtCloudSyncNew(userId);
48     if (server == nullptr) {
49         return { DBErr::E_ERROR, result };
50     }
51     auto pServer = std::shared_ptr<OhCloudExtCloudSync>(server, [](auto *server) {
52         OhCloudExtCloudSyncFree(server);
53     });
54     OhCloudExtCloudInfo *info = nullptr;
55     auto status = OhCloudExtCloudSyncGetServiceInfo(pServer.get(), &info);
56     if (status != ERRNO_SUCCESS || info == nullptr) {
57         return { DBErr::E_ERROR, result };
58     }
59     auto pInfo = std::shared_ptr<OhCloudExtCloudInfo>(info, [](auto *info) { OhCloudExtCloudInfoFree(info); });
60     status = OhCloudExtCloudInfoGetUser(pInfo.get(), &result.user);
61     if (status != ERRNO_SUCCESS || result.user != userId) {
62         ZLOGE("[IN]user: %{public}d, [OUT]user: %{public}d", userId, result.user);
63         return { DBErr::E_ERROR, result };
64     }
65     unsigned char *id = nullptr;
66     size_t idLen = 0;
67     status = OhCloudExtCloudInfoGetId(pInfo.get(), &id, reinterpret_cast<unsigned int *>(&idLen));
68     if (status != ERRNO_SUCCESS || id == nullptr) {
69         return { DBErr::E_ERROR, result };
70     }
71     result.id = std::string(reinterpret_cast<char *>(id), idLen);
72     if (needSpaceInfo) {
73         unsigned long long totalSpace = 0;
74         OhCloudExtCloudInfoGetTotalSpace(pInfo.get(), &totalSpace);
75         result.totalSpace = totalSpace;
76         unsigned long long remainSpace = 0;
77         OhCloudExtCloudInfoGetRemainSpace(pInfo.get(), &remainSpace);
78         result.remainSpace = remainSpace;
79     }
80     OhCloudExtCloudInfoEnabled(pInfo.get(), &result.enableCloud);
81     OhCloudExtHashMap *briefInfo = nullptr;
82     status = OhCloudExtCloudInfoGetAppInfo(pInfo.get(), &briefInfo);
83     if (status != ERRNO_SUCCESS || briefInfo == nullptr) {
84         return { DBErr::E_ERROR, result };
85     }
86     auto pBriefInfo = std::shared_ptr<OhCloudExtHashMap>(briefInfo, [](auto *briefInfo) {
87         OhCloudExtHashMapFree(briefInfo);
88     });
89     GetAppInfo(pBriefInfo, result);
90     return { DBErr::E_ERROR, result };
91 }
92 
GetAppInfo(std::shared_ptr<OhCloudExtHashMap> briefInfo,DBCloudInfo & cloudInfo)93 void CloudServerImpl::GetAppInfo(std::shared_ptr<OhCloudExtHashMap> briefInfo, DBCloudInfo &cloudInfo)
94 {
95     OhCloudExtVector *keys = nullptr;
96     OhCloudExtVector *values = nullptr;
97     auto status = OhCloudExtHashMapIterGetKeyValuePair(briefInfo.get(), &keys, &values);
98     if (status != ERRNO_SUCCESS || keys == nullptr || values == nullptr) {
99         return;
100     }
101     auto pKeys = std::shared_ptr<OhCloudExtVector>(keys, [](auto *keys) { OhCloudExtVectorFree(keys); });
102     auto pValues = std::shared_ptr<OhCloudExtVector>(values, [](auto *values) { OhCloudExtVectorFree(values); });
103     size_t keysLen = 0;
104     OhCloudExtVectorGetLength(pKeys.get(), reinterpret_cast<unsigned int *>(&keysLen));
105     size_t valuesLen = 0;
106     OhCloudExtVectorGetLength(pValues.get(), reinterpret_cast<unsigned int *>(&valuesLen));
107     if (keysLen == 0 || keysLen != valuesLen) {
108         return;
109     }
110     for (size_t i = 0; i < keysLen; i++) {
111         void *key = nullptr;
112         size_t keyLen = 0;
113         status = OhCloudExtVectorGet(pKeys.get(), i, &key, reinterpret_cast<unsigned int *>(&keyLen));
114         if (status != ERRNO_SUCCESS || key == nullptr) {
115             return;
116         }
117         void *value = nullptr;
118         size_t valueLen = 0;
119         status = OhCloudExtVectorGet(pValues.get(), i, &value, reinterpret_cast<unsigned int *>(&valueLen));
120         if (status != ERRNO_SUCCESS || value == nullptr) {
121             return;
122         }
123         std::string bundle(reinterpret_cast<char *>(key), keyLen);
124         OhCloudExtAppInfo *appInfo = reinterpret_cast<OhCloudExtAppInfo *>(value);
125         cloudInfo.apps[bundle] = ExtensionUtil::ConvertAppInfo(appInfo);
126         OhCloudExtAppInfoFree(appInfo);
127     }
128 }
129 
GetAppSchema(int32_t userId,const std::string & bundleName)130 std::pair<int32_t, DBSchemaMeta> CloudServerImpl::GetAppSchema(int32_t userId, const std::string &bundleName)
131 {
132     DBSchemaMeta dbSchema;
133     dbSchema.bundleName = bundleName;
134     OhCloudExtCloudSync *server = OhCloudExtCloudSyncNew(userId);
135     if (server == nullptr) {
136         return { DBErr::E_ERROR, dbSchema };
137     }
138     auto pServer = std::shared_ptr<OhCloudExtCloudSync>(server, [](auto *server) {
139         OhCloudExtCloudSyncFree(server);
140     });
141     OhCloudExtSchemaMeta *schema = nullptr;
142     auto status = OhCloudExtCloudSyncGetAppSchema(pServer.get(),
143         reinterpret_cast<const unsigned char *>(bundleName.c_str()), bundleName.size(), &schema);
144     if (status == ERRNO_UNSUPPORTED) {
145         return { DBErr::E_NOT_SUPPORT, dbSchema };
146     }
147     if (status != ERRNO_SUCCESS || schema == nullptr) {
148         return { DBErr::E_ERROR, dbSchema };
149     }
150     auto pSchema = std::shared_ptr<OhCloudExtSchemaMeta>(schema, [](auto *schema) {
151         OhCloudExtSchemaMetaFree(schema);
152     });
153     OhCloudExtSchemaMetaGetVersion(pSchema.get(), &dbSchema.version);
154     OhCloudExtVector *databases = nullptr;
155     status = OhCloudExtSchemaMetaGetDatabases(pSchema.get(), &databases);
156     if (status != ERRNO_SUCCESS || databases == nullptr) {
157         return { DBErr::E_ERROR, dbSchema };
158     }
159     auto pDatabases = std::shared_ptr<OhCloudExtVector>(databases, [](auto *databases) {
160         OhCloudExtVectorFree(databases);
161     });
162     GetDatabases(pDatabases, dbSchema);
163     return { DBErr::E_OK, dbSchema };
164 }
165 
GetDatabases(std::shared_ptr<OhCloudExtVector> databases,DBSchemaMeta & dbSchema)166 void CloudServerImpl::GetDatabases(std::shared_ptr<OhCloudExtVector> databases, DBSchemaMeta &dbSchema)
167 {
168     size_t dbsLen = 0;
169     auto status = OhCloudExtVectorGetLength(databases.get(), reinterpret_cast<unsigned int *>(&dbsLen));
170     if (status != ERRNO_SUCCESS || dbsLen == 0) {
171         return;
172     }
173     dbSchema.databases.reserve(dbsLen);
174     for (size_t i = 0; i < dbsLen; i++) {
175         void *database = nullptr;
176         size_t dbLen = 0;
177         status = OhCloudExtVectorGet(databases.get(), i, &database, reinterpret_cast<unsigned int *>(&dbLen));
178         if (status != ERRNO_SUCCESS || database == nullptr) {
179             return;
180         }
181         OhCloudExtDatabase *db = reinterpret_cast<OhCloudExtDatabase *>(database);
182         auto pDb = std::shared_ptr<OhCloudExtDatabase>(db, [](auto *db) { OhCloudExtDatabaseFree(db); });
183         DBMeta dbMeta;
184         unsigned char *name = nullptr;
185         size_t nameLen = 0;
186         OhCloudExtDatabaseGetName(pDb.get(), &name, reinterpret_cast<unsigned int *>(&nameLen));
187         if (name == nullptr) {
188             return;
189         }
190         dbMeta.name = std::string(reinterpret_cast<char *>(name), nameLen);
191         unsigned char *alias = nullptr;
192         size_t aliasLen = 0;
193         OhCloudExtDatabaseGetAlias(pDb.get(), &alias, reinterpret_cast<unsigned int *>(&aliasLen));
194         if (alias == nullptr) {
195             return;
196         }
197         dbMeta.alias = std::string(reinterpret_cast<char *>(alias), aliasLen);
198         OhCloudExtHashMap *tables = nullptr;
199         OhCloudExtDatabaseGetTable(pDb.get(), &tables);
200         if (tables == nullptr) {
201             return;
202         }
203         auto pTables = std::shared_ptr<OhCloudExtHashMap>(tables, [](auto *tables) {
204             OhCloudExtHashMapFree(tables);
205         });
206         GetTables(pTables, dbMeta);
207         dbSchema.databases.emplace_back(std::move(dbMeta));
208     }
209 }
210 
GetTables(std::shared_ptr<OhCloudExtHashMap> tables,DBMeta & dbMeta)211 void CloudServerImpl::GetTables(std::shared_ptr<OhCloudExtHashMap> tables, DBMeta &dbMeta)
212 {
213     OhCloudExtVector *keys = nullptr;
214     OhCloudExtVector *values = nullptr;
215     auto status = OhCloudExtHashMapIterGetKeyValuePair(tables.get(), &keys, &values);
216     if (status != ERRNO_SUCCESS || keys == nullptr || values == nullptr) {
217         return;
218     }
219     auto pKeys = std::shared_ptr<OhCloudExtVector>(keys, [](auto *keys) { OhCloudExtVectorFree(keys); });
220     auto pValues = std::shared_ptr<OhCloudExtVector>(values, [](auto *values) { OhCloudExtVectorFree(values); });
221     size_t keysLen = 0;
222     OhCloudExtVectorGetLength(pKeys.get(), reinterpret_cast<unsigned int *>(&keysLen));
223     size_t valuesLen = 0;
224     OhCloudExtVectorGetLength(pValues.get(), reinterpret_cast<unsigned int *>(&valuesLen));
225     if (keysLen == 0 || keysLen != valuesLen) {
226         return;
227     }
228     for (size_t i = 0; i < valuesLen; i++) {
229         void *value = nullptr;
230         size_t valueLen = 0;
231         status = OhCloudExtVectorGet(pValues.get(), i, &value, reinterpret_cast<unsigned int *>(&valueLen));
232         if (status != ERRNO_SUCCESS || value == nullptr) {
233             return;
234         }
235         DBTable dbTable;
236         OhCloudExtTable *table = reinterpret_cast<OhCloudExtTable *>(value);
237         auto pTable = std::shared_ptr<OhCloudExtTable>(table, [](auto *table) { OhCloudExtTableFree(table); });
238         GetTableInfo(pTable, dbTable);
239         OhCloudExtVector *fields = nullptr;
240         status = OhCloudExtTableGetFields(pTable.get(), &fields);
241         if (status != ERRNO_SUCCESS || fields == nullptr) {
242             return;
243         }
244         auto pFields = std::shared_ptr<OhCloudExtVector>(fields, [](auto *fields) {
245             OhCloudExtVectorFree(fields);
246         });
247         GetFields(pFields, dbTable);
248         dbMeta.tables.emplace_back(std::move(dbTable));
249     }
250 }
251 
GetTableInfo(std::shared_ptr<OhCloudExtTable> pTable,DBTable & dbTable)252 void CloudServerImpl::GetTableInfo(std::shared_ptr<OhCloudExtTable> pTable, DBTable &dbTable)
253 {
254     unsigned char *tbName = nullptr;
255     size_t tbNameLen = 0;
256     OhCloudExtTableGetName(pTable.get(), &tbName, reinterpret_cast<unsigned int *>(&tbNameLen));
257     if (tbName == nullptr) {
258         return;
259     }
260     dbTable.name = std::string(reinterpret_cast<char *>(tbName), tbNameLen);
261     unsigned char *tbAlias = nullptr;
262     size_t tbAliasLen = 0;
263     OhCloudExtTableGetAlias(pTable.get(), &tbAlias, reinterpret_cast<unsigned int *>(&tbAliasLen));
264     if (tbAlias == nullptr) {
265         return;
266     }
267     dbTable.alias = std::string(reinterpret_cast<char *>(tbAlias), tbAliasLen);
268 }
269 
GetFields(std::shared_ptr<OhCloudExtVector> fields,DBTable & dbTable)270 void CloudServerImpl::GetFields(std::shared_ptr<OhCloudExtVector> fields, DBTable &dbTable)
271 {
272     size_t fieldsLen = 0;
273     auto status = OhCloudExtVectorGetLength(fields.get(), reinterpret_cast<unsigned int *>(&fieldsLen));
274     if (status != ERRNO_SUCCESS || fieldsLen == 0) {
275         return;
276     }
277     dbTable.fields.reserve(fieldsLen);
278     for (size_t i = 0; i < fieldsLen; i++) {
279         void *value = nullptr;
280         size_t valueLen = 0;
281         status = OhCloudExtVectorGet(fields.get(), i, &value, reinterpret_cast<unsigned int *>(&valueLen));
282         if (status != ERRNO_SUCCESS || value == nullptr) {
283             return;
284         }
285         OhCloudExtField *field = reinterpret_cast<OhCloudExtField *>(value);
286         auto pField = std::shared_ptr<OhCloudExtField>(field, [](auto *field) { OhCloudExtFieldFree(field); });
287         DBField dbField;
288         unsigned char *colName = nullptr;
289         size_t colLen = 0;
290         OhCloudExtFieldGetColName(pField.get(), &colName, reinterpret_cast<unsigned int *>(&colLen));
291         if (colName == nullptr) {
292             return;
293         }
294         dbField.colName = std::string(reinterpret_cast<char *>(colName), colLen);
295         unsigned char *fdAlias = nullptr;
296         size_t fdAliasLen = 0;
297         OhCloudExtFieldGetAlias(pField.get(), &fdAlias, reinterpret_cast<unsigned int *>(&fdAliasLen));
298         if (fdAlias == nullptr) {
299             return;
300         }
301         dbField.alias = std::string(reinterpret_cast<char *>(fdAlias), fdAliasLen);
302         uint32_t fdtype;
303         OhCloudExtFieldGetTyp(pField.get(), &fdtype);
304         dbField.type = static_cast<int32_t>(fdtype);
305         bool primary = false;
306         OhCloudExtFieldGetPrimary(pField.get(), &primary);
307         dbField.primary = primary;
308         bool nullable = true;
309         OhCloudExtFieldGetNullable(pField.get(), &nullable);
310         dbField.nullable = nullable;
311         dbTable.fields.emplace_back(std::move(dbField));
312     }
313 }
314 
Subscribe(int32_t userId,const std::map<std::string,std::vector<DBMeta>> & dbs)315 int32_t CloudServerImpl::Subscribe(int32_t userId, const std::map<std::string, std::vector<DBMeta>> &dbs)
316 {
317     OhCloudExtCloudSync *server = OhCloudExtCloudSyncNew(userId);
318     if (server == nullptr) {
319         return DBErr::E_ERROR;
320     }
321     auto pServer = std::shared_ptr<OhCloudExtCloudSync>(server, [](auto *server) {
322         OhCloudExtCloudSyncFree(server);
323     });
324     OhCloudExtHashMap *databases = OhCloudExtHashMapNew(OhCloudExtRustType::VALUETYPE_VEC_DATABASE);
325     if (databases == nullptr) {
326         return DBErr::E_ERROR;
327     }
328     auto pDatabases = std::shared_ptr<OhCloudExtHashMap>(databases, [](auto *databases) {
329         OhCloudExtHashMapFree(databases);
330     });
331     for (auto &[bundle, db] : dbs) {
332         OhCloudExtVector *database = OhCloudExtVectorNew(OhCloudExtRustType::VALUETYPE_DATABASE);
333         if (database == nullptr) {
334             return DBErr::E_ERROR;
335         }
336         size_t databaseLen = 0;
337         for (auto &item : db) {
338             auto data = ExtensionUtil::Convert(item);
339             if (data.first == nullptr) {
340                 return DBErr::E_ERROR;
341             }
342             auto status = OhCloudExtVectorPush(database, data.first, data.second);
343             if (status != ERRNO_SUCCESS) {
344                 return DBErr::E_ERROR;
345             }
346             databaseLen += 1;
347         }
348         auto status = OhCloudExtHashMapInsert(pDatabases.get(),
349             const_cast<void *>(reinterpret_cast<const void *>(bundle.c_str())), bundle.size(), database, databaseLen);
350         if (status != ERRNO_SUCCESS) {
351             return DBErr::E_ERROR;
352         }
353     }
354     return DoSubscribe(userId, pServer, pDatabases);
355 }
356 
DoSubscribe(int32_t userId,std::shared_ptr<OhCloudExtCloudSync> server,std::shared_ptr<OhCloudExtHashMap> databases)357 int32_t CloudServerImpl::DoSubscribe(int32_t userId, std::shared_ptr<OhCloudExtCloudSync> server,
358     std::shared_ptr<OhCloudExtHashMap> databases)
359 {
360     auto expire = std::chrono::duration_cast<std::chrono::milliseconds>
361         ((std::chrono::system_clock::now() + std::chrono::hours(INTERVAL)).time_since_epoch()).count();
362     OhCloudExtHashMap *relations = nullptr;
363     OhCloudExtVector *errs = nullptr;
364     auto status = OhCloudExtCloudSyncSubscribe(server.get(), databases.get(), expire, &relations, &errs);
365     if (status != ERRNO_SUCCESS || relations == nullptr) {
366         return DBErr::E_ERROR;
367     }
368     auto pRelations = std::shared_ptr<OhCloudExtHashMap>(relations, [](auto *relations) {
369         OhCloudExtHashMapFree(relations);
370     });
371     if (errs != nullptr) {
372         auto pErrs = std::shared_ptr<OhCloudExtVector>(errs, [](auto *errs) { OhCloudExtVectorFree(errs); });
373         size_t errsLen = 0;
374         status = OhCloudExtVectorGetLength(pErrs.get(), reinterpret_cast<unsigned int *>(&errsLen));
375         if (status != ERRNO_SUCCESS || errsLen == 0) {
376             return DBErr::E_ERROR;
377         }
378         for (size_t i = 0; i < errsLen; i++) {
379             void *value = nullptr;
380             size_t valueLen = 0;
381             status = OhCloudExtVectorGet(pErrs.get(), i, &value, reinterpret_cast<unsigned int *>(&valueLen));
382             if (status != ERRNO_SUCCESS || value == nullptr) {
383                 return DBErr::E_ERROR;
384             }
385             auto err = *reinterpret_cast<int *>(value);
386             if (err != ERRNO_SUCCESS) {
387                 ZLOGE("sub fail, user:%{public}d, err:%{public}d", userId, err);
388                 return DBErr::E_ERROR;
389             }
390         }
391     }
392     return SaveSubscription(userId, pRelations, server);
393 }
394 
SaveSubscription(int32_t userId,std::shared_ptr<OhCloudExtHashMap> relations,std::shared_ptr<OhCloudExtCloudSync> server)395 int32_t CloudServerImpl::SaveSubscription(int32_t userId, std::shared_ptr<OhCloudExtHashMap> relations,
396     std::shared_ptr<OhCloudExtCloudSync> server)
397 {
398     OhCloudExtCloudInfo *info = nullptr;
399     auto status = OhCloudExtCloudSyncGetServiceInfo(server.get(), &info);
400     if (status != ERRNO_SUCCESS || info == nullptr) {
401         return DBErr::E_ERROR;
402     }
403     auto pInfo = std::shared_ptr<OhCloudExtCloudInfo>(info, [](auto *info) { OhCloudExtCloudInfoFree(info); });
404     unsigned char *id = nullptr;
405     size_t idLen = 0;
406     status = OhCloudExtCloudInfoGetId(pInfo.get(), &id, reinterpret_cast<unsigned int *>(&idLen));
407     if (status != ERRNO_SUCCESS || id == nullptr) {
408         return DBErr::E_ERROR;
409     }
410     std::string accountId(reinterpret_cast<char *>(id), idLen);
411     DBSub sub;
412     sub.userId = userId;
413     DBMetaMgr::GetInstance().LoadMeta(sub.GetKey(), sub, true);
414     if (!sub.id.empty() && sub.id != accountId) {
415         ZLOGE("diff id, [meta]id:%{public}s, [server]id:%{public}s", Anonymous::Change(sub.id).c_str(),
416               Anonymous::Change(accountId).c_str());
417         return DBErr::E_OK;
418     }
419     sub.id = accountId;
420     OhCloudExtVector *keys = nullptr;
421     OhCloudExtVector *values = nullptr;
422     status = OhCloudExtHashMapIterGetKeyValuePair(relations.get(), &keys, &values);
423     if (status != ERRNO_SUCCESS || keys == nullptr || values == nullptr) {
424         return DBErr::E_ERROR;
425     }
426     auto pKeys = std::shared_ptr<OhCloudExtVector>(keys, [](auto *keys) { OhCloudExtVectorFree(keys); });
427     auto pValues = std::shared_ptr<OhCloudExtVector>(values, [](auto *values) { OhCloudExtVectorFree(values); });
428     if (SaveRelation(pKeys, pValues, sub) != DBErr::E_OK) {
429         return DBErr::E_ERROR;
430     }
431     DBMetaMgr::GetInstance().SaveMeta(sub.GetKey(), sub, true);
432     return DBErr::E_OK;
433 }
434 
SaveRelation(std::shared_ptr<OhCloudExtVector> keys,std::shared_ptr<OhCloudExtVector> values,DBSub & sub)435 int32_t CloudServerImpl::SaveRelation(std::shared_ptr<OhCloudExtVector> keys,
436     std::shared_ptr<OhCloudExtVector> values, DBSub &sub)
437 {
438     size_t valuesLen = 0;
439     auto status = OhCloudExtVectorGetLength(values.get(), reinterpret_cast<unsigned int *>(&valuesLen));
440     if (status != ERRNO_SUCCESS || valuesLen == 0) {
441         return DBErr::E_ERROR;
442     }
443     for (size_t i = 0; i < valuesLen; i++) {
444         void *value = nullptr;
445         size_t valueLen = 0;
446         OhCloudExtVectorGet(values.get(), i, &value, reinterpret_cast<unsigned int *>(&valueLen));
447         if (value == nullptr) {
448             return DBErr::E_ERROR;
449         }
450         OhCloudExtRelationSet *relationSet = reinterpret_cast<OhCloudExtRelationSet *>(value);
451         auto pRelationSet = std::shared_ptr<OhCloudExtRelationSet>(relationSet, [](auto *relationSet) {
452             OhCloudExtRelationSetFree(relationSet);
453         });
454         unsigned char *bundle = nullptr;
455         size_t bundleLen = 0;
456         OhCloudExtRelationSetGetBundleName(pRelationSet.get(), &bundle, reinterpret_cast<unsigned int *>(&bundleLen));
457         if (bundle == nullptr) {
458             return DBErr::E_ERROR;
459         }
460         unsigned long long expire = 0;
461         status = OhCloudExtRelationSetGetExpireTime(pRelationSet.get(), &expire);
462         if (status != ERRNO_SUCCESS || expire == 0) {
463             return DBErr::E_ERROR;
464         }
465         std::string bundleName(reinterpret_cast<char *>(bundle), bundleLen);
466         sub.expiresTime[bundleName] = static_cast<uint64_t>(expire);
467         OhCloudExtHashMap *relations = nullptr;
468         status = OhCloudExtRelationSetGetRelations(pRelationSet.get(), &relations);
469         if (status != ERRNO_SUCCESS || relations == nullptr) {
470             return DBErr::E_ERROR;
471         }
472         auto pRelations = std::shared_ptr<OhCloudExtHashMap>(relations, [](auto *relations) {
473             OhCloudExtHashMapFree(relations);
474         });
475         DBRelation dbRelation;
476         dbRelation.id = sub.id;
477         dbRelation.bundleName = bundleName;
478         if (GetRelation(pRelations, dbRelation) != DBErr::E_OK) {
479             return DBErr::E_ERROR;
480         }
481         DBMetaMgr::GetInstance().SaveMeta(sub.GetRelationKey(bundleName), dbRelation, true);
482     }
483     return DBErr::E_OK;
484 }
485 
GetRelation(std::shared_ptr<OhCloudExtHashMap> relations,DBRelation & dbRelation)486 int32_t CloudServerImpl::GetRelation(std::shared_ptr<OhCloudExtHashMap> relations, DBRelation &dbRelation)
487 {
488     OhCloudExtVector *keys = nullptr;
489     OhCloudExtVector *values = nullptr;
490     auto status = OhCloudExtHashMapIterGetKeyValuePair(relations.get(), &keys, &values);
491     if (status != ERRNO_SUCCESS || keys == nullptr || values == nullptr) {
492         return DBErr::E_ERROR;
493     }
494     auto pKeys = std::shared_ptr<OhCloudExtVector>(keys, [](auto *keys) { OhCloudExtVectorFree(keys); });
495     auto pValues = std::shared_ptr<OhCloudExtVector>(values, [](auto *values) { OhCloudExtVectorFree(values); });
496     size_t keysLen = 0;
497     OhCloudExtVectorGetLength(pKeys.get(), reinterpret_cast<unsigned int *>(&keysLen));
498     size_t valuesLen = 0;
499     OhCloudExtVectorGetLength(pValues.get(), reinterpret_cast<unsigned int *>(&valuesLen));
500     if (keysLen == 0 || keysLen != valuesLen) {
501         return DBErr::E_ERROR;
502     }
503     for (size_t i = 0; i < keysLen; i++) {
504         void *dbName = nullptr;
505         size_t dbNameLen = 0;
506         status = OhCloudExtVectorGet(pKeys.get(), i, &dbName, reinterpret_cast<unsigned int *>(&dbNameLen));
507         if (status != ERRNO_SUCCESS || dbName == nullptr) {
508             return DBErr::E_ERROR;
509         }
510         std::string databaseName(reinterpret_cast<char *>(dbName), dbNameLen);
511         void *subId = nullptr;
512         size_t subIdLen = 0;
513         status = OhCloudExtVectorGet(pValues.get(), i, &subId, reinterpret_cast<unsigned int *>(&subIdLen));
514         if (status != ERRNO_SUCCESS || subId == nullptr) {
515             return DBErr::E_ERROR;
516         }
517         uint64_t subscribeId = *reinterpret_cast<uint64_t *>(subId);
518         dbRelation.relations[std::move(databaseName)] = std::to_string(subscribeId);
519     }
520     return DBErr::E_OK;
521 }
522 
Unsubscribe(int32_t userId,const std::map<std::string,std::vector<DBMeta>> & dbs)523 int32_t CloudServerImpl::Unsubscribe(int32_t userId, const std::map<std::string, std::vector<DBMeta>> &dbs)
524 {
525     DBSub sub;
526     sub.userId = userId;
527     DBMetaMgr::GetInstance().LoadMeta(sub.GetKey(), sub, true);
528     if (sub.id.empty()) {
529         return DBErr::E_OK;
530     }
531     OhCloudExtCloudSync *server = OhCloudExtCloudSyncNew(userId);
532     if (server == nullptr) {
533         return DBErr::E_ERROR;
534     }
535     auto pServer = std::shared_ptr<OhCloudExtCloudSync>(server, [](auto *server) { OhCloudExtCloudSyncFree(server); });
536     std::vector<std::string> bundles;
537     OhCloudExtHashMap *subs = OhCloudExtHashMapNew(OhCloudExtRustType::VALUETYPE_VEC_STRING);
538     if (subs == nullptr) {
539         return DBErr::E_ERROR;
540     }
541     auto pSubs = std::shared_ptr<OhCloudExtHashMap>(subs, [](auto *subs) { OhCloudExtHashMapFree(subs); });
542     for (auto &[bundle, databases] : dbs) {
543         DBRelation dbRelation;
544         DBMetaMgr::GetInstance().LoadMeta(DBSub::GetRelationKey(userId, bundle), dbRelation, true);
545         OhCloudExtVector *relation = OhCloudExtVectorNew(OhCloudExtRustType::VALUETYPE_U32);
546         if (relation == nullptr) {
547             return DBErr::E_ERROR;
548         }
549         size_t relationLen = 0;
550         for (auto &database : databases) {
551             auto it = dbRelation.relations.find(database.name);
552             if (it == dbRelation.relations.end()) {
553                 continue;
554             }
555             uint32_t subId = static_cast<uint32_t>(std::atoi(it->second.c_str()));
556             if (OhCloudExtVectorPush(relation, &subId, sizeof(uint32_t)) != ERRNO_SUCCESS) {
557                 return DBErr::E_ERROR;
558             }
559             relationLen += 1;
560         }
561         auto status = OhCloudExtHashMapInsert(pSubs.get(),
562             const_cast<void *>(reinterpret_cast<const void *>(bundle.c_str())), bundle.size(), relation, relationLen);
563         if (status != ERRNO_SUCCESS) {
564             return DBErr::E_ERROR;
565         }
566         bundles.emplace_back(bundle);
567     }
568     if (DoUnsubscribe(pServer, pSubs, bundles, sub) != DBErr::E_OK) {
569         return DBErr::E_ERROR;
570     }
571     DBMetaMgr::GetInstance().SaveMeta(sub.GetKey(), sub, true);
572     return DBErr::E_OK;
573 }
574 
DoUnsubscribe(std::shared_ptr<OhCloudExtCloudSync> server,std::shared_ptr<OhCloudExtHashMap> relations,const std::vector<std::string> & bundles,DBSub & sub)575 int32_t CloudServerImpl::DoUnsubscribe(std::shared_ptr<OhCloudExtCloudSync> server,
576     std::shared_ptr<OhCloudExtHashMap> relations, const std::vector<std::string> &bundles, DBSub &sub)
577 {
578     OhCloudExtVector *errs = nullptr;
579     auto status =  OhCloudExtCloudSyncUnsubscribe(server.get(), relations.get(), &errs);
580     if (status != ERRNO_SUCCESS) {
581         return DBErr::E_ERROR;
582     }
583     if (errs != nullptr) {
584         auto pErrs = std::shared_ptr<OhCloudExtVector>(errs, [](auto *errs) { OhCloudExtVectorFree(errs); });
585         size_t errsLen = 0;
586         OhCloudExtVectorGetLength(pErrs.get(), reinterpret_cast<unsigned int *>(&errsLen));
587         if (errsLen != bundles.size()) {
588             return DBErr::E_ERROR;
589         }
590         for (size_t i = 0; i < errsLen; i++) {
591             void *value = nullptr;
592             size_t valueLen = 0;
593             status = OhCloudExtVectorGet(pErrs.get(), i, &value, reinterpret_cast<unsigned int *>(&valueLen));
594             if (status != ERRNO_SUCCESS || value == nullptr) {
595                 return DBErr::E_ERROR;
596             }
597             int err = *reinterpret_cast<int *>(value);
598             if (err != ERRNO_SUCCESS) {
599                 continue;
600             }
601             sub.expiresTime.erase(bundles[i]);
602             DBMetaMgr::GetInstance().DelMeta(sub.GetRelationKey(bundles[i]), true);
603         }
604     } else {
605         for (size_t i = 0; i < bundles.size(); i++) {
606             sub.expiresTime.erase(bundles[i]);
607             DBMetaMgr::GetInstance().DelMeta(sub.GetRelationKey(bundles[i]), true);
608         }
609     }
610     return DBErr::E_OK;
611 }
612 
ConnectAssetLoader(uint32_t tokenId,const DBMeta & dbMeta)613 std::shared_ptr<DBAssetLoader> CloudServerImpl::ConnectAssetLoader(uint32_t tokenId, const DBMeta &dbMeta)
614 {
615     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
616         return nullptr;
617     }
618     HapTokenInfo hapInfo;
619     if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != RET_SUCCESS) {
620         return nullptr;
621     }
622     auto data = ExtensionUtil::Convert(dbMeta);
623     if (data.first == nullptr) {
624         return nullptr;
625     }
626     OhCloudExtCloudAssetLoader *loader = OhCloudExtCloudAssetLoaderNew(hapInfo.userID,
627         reinterpret_cast<const unsigned char *>(hapInfo.bundleName.c_str()),
628         hapInfo.bundleName.size(), data.first);
629     return loader != nullptr ? std::make_shared<AssetLoaderImpl>(loader) : nullptr;
630 }
631 
ConnectAssetLoader(const std::string & bundleName,int user,const DBMeta & dbMeta)632 std::shared_ptr<DBAssetLoader> CloudServerImpl::ConnectAssetLoader(
633     const std::string &bundleName, int user, const DBMeta &dbMeta)
634 {
635     auto data = ExtensionUtil::Convert(dbMeta);
636     if (data.first == nullptr) {
637         return nullptr;
638     }
639     OhCloudExtCloudAssetLoader *loader = OhCloudExtCloudAssetLoaderNew(
640         user, reinterpret_cast<const unsigned char *>(bundleName.c_str()), bundleName.size(), data.first);
641     return loader != nullptr ? std::make_shared<AssetLoaderImpl>(loader) : nullptr;
642 }
643 
ConnectCloudDB(uint32_t tokenId,const DBMeta & dbMeta)644 std::shared_ptr<DBCloudDB> CloudServerImpl::ConnectCloudDB(uint32_t tokenId, const DBMeta &dbMeta)
645 {
646     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
647         return nullptr;
648     }
649     HapTokenInfo hapInfo;
650     if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != RET_SUCCESS) {
651         return nullptr;
652     }
653     auto data = ExtensionUtil::Convert(dbMeta);
654     if (data.first == nullptr) {
655         return nullptr;
656     }
657     OhCloudExtCloudDatabase *cloudDb = OhCloudExtCloudDbNew(hapInfo.userID,
658         reinterpret_cast<const unsigned char *>(hapInfo.bundleName.c_str()),
659         hapInfo.bundleName.size(), data.first);
660     return cloudDb != nullptr ? std::make_shared<CloudDbImpl>(cloudDb) : nullptr;
661 }
662 
ConnectCloudDB(const std::string & bundleName,int user,const DBMeta & dbMeta)663 std::shared_ptr<DBCloudDB> CloudServerImpl::ConnectCloudDB(
664     const std::string &bundleName, int user, const DBMeta &dbMeta)
665 {
666     auto data = ExtensionUtil::Convert(dbMeta);
667     if (data.first == nullptr) {
668         return nullptr;
669     }
670     OhCloudExtCloudDatabase *cloudDb = OhCloudExtCloudDbNew(
671         user, reinterpret_cast<const unsigned char *>(bundleName.c_str()), bundleName.size(), data.first);
672     return cloudDb != nullptr ? std::make_shared<CloudDbImpl>(cloudDb) : nullptr;
673 }
674 } // namespace OHOS::CloudData