• 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 "rdb_open_callback.h"
18 #include "rdb_store_config.h"
19 #include "rdb_store.h"
20 #include "rdb_helper.h"
21 #include "abs_rdb_predicates.h"
22 #include "logger.h"
23 #include "rdb_errno.h"
24 #include "rdb_open_callback.h"
25 #include "rdb_sql_utils.h"
26 #include "rdb_store_config.h"
27 #include "unistd.h"
28 #include "js_ability.h"
29 #include "native_log.h"
30 #include "value_object.h"
31 #include "rdb_common.h"
32 #include "native_log.h"
33 #include "relational_store_impl_rdbstore.h"
34 
35 #ifndef PATH_SPLIT
36 #define PATH_SPLIT '/'
37 #endif
38 
39 using ContextParam = OHOS::AppDataMgrJsKit::JSUtils::ContextParam;
40 using RdbConfig = OHOS::AppDataMgrJsKit::JSUtils::RdbConfig;
41 
42 using namespace OHOS::FFI;
43 
44 namespace OHOS {
45 namespace Relational {
RdbStoreObserverImpl(int64_t id,FuncType type,int32_t mode)46     RdbStoreObserverImpl::RdbStoreObserverImpl(int64_t id, FuncType type, int32_t mode)
47     {
48         callbackId = id;
49         funcType = type;
50         mode_ = mode;
51         switch (type) {
52             case NoParam: {
53                 auto cFunc = reinterpret_cast<void(*)()>(callbackId);
54                 func = CJLambda::Create(cFunc);
55                 break;
56             }
57             case ParamArrStr: {
58                 auto cFunc = reinterpret_cast<void(*)(CArrStr arr)>(callbackId);
59                 carrStrFunc = [ lambda = CJLambda::Create(cFunc)](const std::vector<std::string> &devices) ->
60                     void { lambda(VectorToCArrStr(devices)); };
61                 break;
62             }
63             case ParamChangeInfo: {
64                 auto cFunc = reinterpret_cast<void(*)(CArrRetChangeInfo arr)>(callbackId);
65                 changeInfoFunc = [ lambda = CJLambda::Create(cFunc)](const DistributedRdb::Origin &origin,
66                 const PrimaryFields &fields, DistributedRdb::RdbStoreObserver::ChangeInfo &&changeInfo) ->
67                     void { lambda(ToCArrRetChangeInfo(origin, fields, std::move(changeInfo))); };
68                 break;
69             }
70         }
71     }
72 
SyncObserverImpl(int64_t id)73     SyncObserverImpl::SyncObserverImpl(int64_t id)
74     {
75         callbackId = id;
76         auto cFunc = reinterpret_cast<void(*)(CProgressDetails details)>(callbackId);
77         func = [ lambda = CJLambda::Create(cFunc)](const DistributedRdb::Details &details) ->
78             void { lambda(ToCProgressDetails(details)); };
79     }
80 
81     class DefaultOpenCallback : public NativeRdb::RdbOpenCallback {
82     public:
OnCreate(NativeRdb::RdbStore & rdbStore)83         int OnCreate(NativeRdb::RdbStore &rdbStore) override
84         {
85             return RelationalStoreJsKit::OK;
86         }
87 
OnUpgrade(NativeRdb::RdbStore & rdbStore,int oldVersion,int newVersion)88         int OnUpgrade(NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion) override
89         {
90             return RelationalStoreJsKit::OK;
91         }
92     };
93 
RdbStoreImpl(std::shared_ptr<OHOS::NativeRdb::RdbStore> rdbStore)94     RdbStoreImpl::RdbStoreImpl(std::shared_ptr<OHOS::NativeRdb::RdbStore> rdbStore)
95     {
96         rdbStore_ = rdbStore;
97     }
98 
GetClassType()99     OHOS::FFI::RuntimeType* RdbStoreImpl::GetClassType()
100     {
101         static OHOS::FFI::RuntimeType runtimeType = OHOS::FFI::RuntimeType::Create<OHOS::FFI::FFIData>("RdbStoreImpl");
102         return &runtimeType;
103     }
104 
ConvertFromValueBucket(ValuesBucket valuesBucket)105     NativeRdb::ValuesBucket ConvertFromValueBucket(ValuesBucket valuesBucket)
106     {
107         int64_t mapSize = valuesBucket.size;
108         NativeRdb::ValuesBucket nativeValuesBucket = NativeRdb::ValuesBucket();
109 
110         for (int64_t i = 0; i < mapSize; i++) {
111             NativeRdb::ValueObject valueObject = ValueTypeToValueObject(valuesBucket.value[i]);
112             std::string keyStr = valuesBucket.key[i];
113             nativeValuesBucket.Put(keyStr, valueObject);
114         }
115         return nativeValuesBucket;
116     }
117 
Query(RdbPredicatesImpl & predicates,char ** column,int64_t columnSize)118     std::shared_ptr<NativeRdb::ResultSet> RdbStoreImpl::Query(RdbPredicatesImpl &predicates, char** column,
119         int64_t columnSize)
120     {
121         std::vector<std::string> columnsVector = std::vector<std::string>();
122         for (int64_t i = 0; i < columnSize; i++) {
123             columnsVector.push_back(std::string(column[i]));
124         }
125         auto resultSet = rdbStore_->Query(*(predicates.GetPredicates()), columnsVector);
126         return resultSet;
127     }
128 
RemoteQuery(char * device,RdbPredicatesImpl & predicates,char ** column,int64_t columnSize)129     std::shared_ptr<NativeRdb::ResultSet> RdbStoreImpl::RemoteQuery(char* device, RdbPredicatesImpl &predicates,
130         char** column, int64_t columnSize)
131     {
132         std::vector<std::string> columnsVector;
133         for (int64_t i = 0; i < columnSize; i++) {
134             columnsVector.push_back(std::string(column[i]));
135         }
136         int32_t errCode;
137         auto resultSet = rdbStore_->RemoteQuery(std::string(device), *(predicates.GetPredicates()), columnsVector,
138             errCode);
139         return resultSet;
140     }
141 
Update(ValuesBucket valuesBucket,RdbPredicatesImpl & predicates,NativeRdb::ConflictResolution conflictResolution,int32_t * errCode)142     int32_t RdbStoreImpl::Update(ValuesBucket valuesBucket, RdbPredicatesImpl &predicates,
143         NativeRdb::ConflictResolution conflictResolution, int32_t *errCode)
144     {
145         int32_t affectedRows;
146         NativeRdb::ValuesBucket nativeValuesBucket = ConvertFromValueBucket(valuesBucket);
147         *errCode = rdbStore_->UpdateWithConflictResolution(affectedRows, predicates.GetPredicates()->GetTableName(),
148             nativeValuesBucket, predicates.GetPredicates()->GetWhereClause(), predicates.GetPredicates()->GetBindArgs(),
149             conflictResolution);
150         return affectedRows;
151     }
152 
Delete(RdbPredicatesImpl & predicates,int32_t * errCode)153     int RdbStoreImpl::Delete(RdbPredicatesImpl &predicates, int32_t *errCode)
154     {
155         int deletedRows = 0;
156         *errCode = rdbStore_->Delete(deletedRows, *(predicates.GetPredicates()));
157         return deletedRows;
158     }
159 
SetDistributedTables(char ** tables,int64_t tablesSize)160     int32_t RdbStoreImpl::SetDistributedTables(char** tables, int64_t tablesSize)
161     {
162         std::vector<std::string> tablesVector;
163         for (int64_t i = 0; i < tablesSize; i++) {
164             tablesVector.push_back(std::string(tables[i]));
165         }
166         return rdbStore_->SetDistributedTables(tablesVector, DistributedRdb::DISTRIBUTED_DEVICE,
167             DistributedRdb::DistributedConfig{false});
168     }
169 
SetDistributedTables(char ** tables,int64_t tablesSize,int32_t type)170     int32_t RdbStoreImpl::SetDistributedTables(char** tables, int64_t tablesSize, int32_t type)
171     {
172         std::vector<std::string> tablesVector;
173         for (int64_t i = 0; i < tablesSize; i++) {
174             tablesVector.push_back(std::string(tables[i]));
175         }
176         return rdbStore_->SetDistributedTables(tablesVector, type, DistributedRdb::DistributedConfig{false});
177     }
178 
SetDistributedTables(char ** tables,int64_t tablesSize,int32_t type,DistributedRdb::DistributedConfig & distributedConfig)179     int32_t RdbStoreImpl::SetDistributedTables(char** tables, int64_t tablesSize, int32_t type,
180         DistributedRdb::DistributedConfig &distributedConfig)
181     {
182         std::vector<std::string> tablesVector;
183         for (int64_t i = 0; i < tablesSize; i++) {
184             tablesVector.push_back(std::string(tables[i]));
185         }
186         return rdbStore_->SetDistributedTables(tablesVector, type, distributedConfig);
187     }
188 
RollBack()189     int32_t RdbStoreImpl::RollBack()
190     {
191         return rdbStore_->RollBack();
192     }
193 
Commit()194     int32_t RdbStoreImpl::Commit()
195     {
196         return rdbStore_->Commit();
197     }
198 
BeginTransaction()199     int32_t RdbStoreImpl::BeginTransaction()
200     {
201         return rdbStore_->BeginTransaction();
202     }
203 
Backup(const char * destName)204     int32_t RdbStoreImpl::Backup(const char* destName)
205     {
206         return rdbStore_->Backup(destName, newKey);
207     }
208 
Restore(const char * srcName)209     int32_t RdbStoreImpl::Restore(const char* srcName)
210     {
211         return rdbStore_->Restore(srcName, newKey);
212     }
213 
ObtainDistributedTableName(const char * device,const char * table)214     char* RdbStoreImpl::ObtainDistributedTableName(const char* device, const char* table)
215     {
216         int errCode = RelationalStoreJsKit::E_INNER_ERROR;
217         std::string tableName = rdbStore_->ObtainDistributedTableName(device, table, errCode);
218         return MallocCString(tableName);
219     }
220 
Emit(const char * event)221     int32_t RdbStoreImpl::Emit(const char* event)
222     {
223         return rdbStore_->Notify(event);
224     }
225 
Insert(const char * table,ValuesBucket valuesBucket,int32_t conflict,int32_t * errCode)226     int64_t RdbStoreImpl::Insert(const char* table, ValuesBucket valuesBucket, int32_t conflict, int32_t *errCode)
227     {
228         std::string tableName = table;
229         int64_t result;
230         NativeRdb::ValuesBucket nativeValuesBucket = ConvertFromValueBucket(valuesBucket);
231         *errCode = rdbStore_->InsertWithConflictResolution(result, tableName,
232             nativeValuesBucket, NativeRdb::ConflictResolution(conflict));
233         return result;
234     }
235 
ExecuteSql(const char * sql,int32_t * errCode)236     void RdbStoreImpl::ExecuteSql(const char* sql, int32_t *errCode)
237     {
238         *errCode = rdbStore_->ExecuteSql(sql, bindArgs);
239     }
240 
241 
CleanDirtyData(const char * tableName,uint64_t cursor)242     int32_t RdbStoreImpl::CleanDirtyData(const char* tableName, uint64_t cursor)
243     {
244         int32_t rtnCode = rdbStore_->CleanDirtyData(tableName, cursor);
245         return rtnCode;
246     }
247 
BatchInsert(int64_t & insertNum,const char * tableName,ValuesBucket * valuesBuckets,int64_t valuesSize)248     int32_t RdbStoreImpl::BatchInsert(int64_t &insertNum, const char* tableName, ValuesBucket* valuesBuckets,
249         int64_t valuesSize)
250     {
251         std::vector<NativeRdb::ValuesBucket> valuesVector;
252         std::string tableNameStr = tableName;
253         if (tableNameStr.empty()) {
254             return RelationalStoreJsKit::E_PARAM_ERROR;
255         }
256         for (int64_t i = 0; i < valuesSize; i++) {
257             NativeRdb::ValuesBucket nativeValuesBucket = ConvertFromValueBucket(valuesBuckets[i]);
258             valuesVector.push_back(nativeValuesBucket);
259         }
260         int32_t rtnCode = rdbStore_->BatchInsert(insertNum, tableNameStr, valuesVector);
261         return rtnCode;
262     }
263 
Sync(int32_t mode,RdbPredicatesImpl & predicates)264     CArrSyncResult RdbStoreImpl::Sync(int32_t mode, RdbPredicatesImpl &predicates)
265     {
266         DistributedRdb::SyncOption option;
267         option.mode = static_cast<DistributedRdb::SyncMode>(mode);
268         option.isBlock = true;
269         DistributedRdb::SyncResult resMap;
270         rdbStore_->Sync(option, *(predicates.GetPredicates()),
271             [&resMap](const DistributedRdb::SyncResult &result) { resMap = result; });
272         char** resultStr = static_cast<char**>(malloc(resMap.size() * sizeof(char*)));
273         int32_t* resultNum = static_cast<int32_t*>(malloc(resMap.size() * sizeof(int32_t)));
274         if (resultStr == nullptr || resultNum == nullptr) {
275             free(resultStr);
276             free(resultNum);
277             return CArrSyncResult{nullptr, nullptr, -1};
278         }
279         size_t i = 0;
280         for (auto it = resMap.begin(); it != resMap.end(); ++it) {
281             resultStr[i] = MallocCString(it->first);
282             resultNum[i] = it->second;
283             i++;
284         }
285         return CArrSyncResult{resultStr, resultNum, int64_t(resMap.size())};
286     }
287 
QuerySql(const char * sql,ValueType * bindArgs,int64_t size)288     std::shared_ptr<NativeRdb::ResultSet> RdbStoreImpl::QuerySql(const char *sql, ValueType *bindArgs, int64_t size)
289     {
290         std::string tmpSql = sql;
291         std::vector<NativeRdb::ValueObject> tmpBindArgs = std::vector<NativeRdb::ValueObject>();
292         for (int64_t i = 0; i < size; i++) {
293             tmpBindArgs.push_back(ValueTypeToValueObject(bindArgs[i]));
294         }
295         auto result = rdbStore_->QueryByStep(tmpSql, tmpBindArgs);
296         return result;
297     }
298 
ExecuteSql(const char * sql,ValueType * bindArgs,int64_t bindArgsSize,int32_t * errCode)299     void RdbStoreImpl::ExecuteSql(const char* sql, ValueType* bindArgs, int64_t bindArgsSize, int32_t *errCode)
300     {
301         std::vector<NativeRdb::ValueObject> bindArgsObjects = std::vector<NativeRdb::ValueObject>();
302         for (int64_t i = 0; i < bindArgsSize; i++) {
303             bindArgsObjects.push_back(ValueTypeToValueObject(bindArgs[i]));
304         }
305         *errCode = rdbStore_->ExecuteSql(sql, bindArgsObjects);
306     }
307 
RegisterObserver(const char * event,bool interProcess,std::function<void ()> * callback,const std::function<void ()> & callbackRef)308     int32_t RdbStoreImpl::RegisterObserver(const char *event, bool interProcess, std::function<void()> *callback,
309         const std::function<void()>& callbackRef)
310     {
311         DistributedRdb::SubscribeOption option;
312         option.event = event;
313         interProcess ? option.mode = DistributedRdb::SubscribeMode::LOCAL_SHARED : option.mode =
314             DistributedRdb::SubscribeMode::LOCAL;
315         if (option.mode == DistributedRdb::SubscribeMode::LOCAL) {
316             return RegisteredObserver(option, localObservers_, callback, callbackRef);
317         }
318         return RegisteredObserver(option, localSharedObservers_, callback, callbackRef);
319     }
320 
isSameFunction(const std::function<void ()> * f1,const std::function<void ()> * f2)321     bool isSameFunction(const std::function<void()> *f1, const std::function<void()> *f2)
322     {
323         return f1 == f2;
324     }
325 
HasRegisteredObserver(std::function<void ()> * callback,std::list<std::shared_ptr<RdbStoreObserverImpl>> & observers)326     bool RdbStoreImpl::HasRegisteredObserver(
327         std::function<void()> *callback,
328         std::list<std::shared_ptr<RdbStoreObserverImpl>> &observers)
329     {
330         for (auto &it : observers) {
331             if (isSameFunction(callback, it->GetCallBack())) {
332                 return true;
333             }
334         }
335         return false;
336     }
337 
RdbStoreObserverImpl(std::function<void ()> * callback,const std::function<void ()> & callbackRef)338     RdbStoreObserverImpl::RdbStoreObserverImpl(std::function<void()> *callback,
339         const std::function<void()>& callbackRef)
340     {
341         m_callback = callback;
342         m_callbackRef = callbackRef;
343     }
344 
GetCallBack()345     std::function<void()> *RdbStoreObserverImpl::GetCallBack()
346     {
347         return m_callback;
348     }
349 
RegisteredObserver(DistributedRdb::SubscribeOption option,std::map<std::string,std::list<std::shared_ptr<RdbStoreObserverImpl>>> & observers,std::function<void ()> * callback,const std::function<void ()> & callbackRef)350     int32_t RdbStoreImpl::RegisteredObserver(
351         DistributedRdb::SubscribeOption option,
352         std::map<std::string, std::list<std::shared_ptr<RdbStoreObserverImpl>>> &observers,
353         std::function<void()> *callback, const std::function<void()>& callbackRef)
354     {
355         observers.try_emplace(option.event);
356         if (!HasRegisteredObserver(callback, observers[option.event])) {
357             auto localObserver = std::make_shared<RdbStoreObserverImpl>(callback, callbackRef);
358             int32_t errCode = rdbStore_->Subscribe(option, localObserver.get());
359             if (errCode != NativeRdb::E_OK) {
360                 return errCode;
361             }
362             observers[option.event].push_back(localObserver);
363             LOGI("subscribe success event: %{public}s", option.event.c_str());
364         } else {
365             LOGI("duplicate subscribe event: %{public}s", option.event.c_str());
366         }
367         return RelationalStoreJsKit::OK;
368     }
369 
RegisterObserverArrStr(int32_t subscribeType,int64_t callbackId)370     int32_t RdbStoreImpl::RegisterObserverArrStr(int32_t subscribeType, int64_t callbackId)
371     {
372         int32_t mode = subscribeType;
373         DistributedRdb::SubscribeOption option;
374         option.mode = static_cast<DistributedRdb::SubscribeMode>(mode);
375         option.event = "dataChange";
376         auto observer = std::make_shared<RdbStoreObserverImpl>(callbackId, RdbStoreObserverImpl::ParamArrStr, mode);
377         int32_t errCode = NativeRdb::E_OK;
378         if (option.mode == DistributedRdb::SubscribeMode::LOCAL_DETAIL) {
379             errCode = rdbStore_->SubscribeObserver(option, observer);
380         } else {
381             errCode = rdbStore_->Subscribe(option, observer.get());
382         }
383         if (errCode == NativeRdb::E_OK) {
384             observers_[mode].push_back(observer);
385             LOGI("subscribe success");
386         }
387         return errCode;
388     }
389 
RegisterObserverChangeInfo(int32_t subscribeType,int64_t callbackId)390     int32_t RdbStoreImpl::RegisterObserverChangeInfo(int32_t subscribeType, int64_t callbackId)
391     {
392         int32_t mode = subscribeType;
393         DistributedRdb::SubscribeOption option;
394         option.mode = static_cast<DistributedRdb::SubscribeMode>(mode);
395         option.event = "dataChange";
396         auto observer = std::make_shared<RdbStoreObserverImpl>(callbackId, RdbStoreObserverImpl::ParamChangeInfo, mode);
397         int32_t errCode = NativeRdb::E_OK;
398         if (option.mode == DistributedRdb::SubscribeMode::LOCAL_DETAIL) {
399             errCode = rdbStore_->SubscribeObserver(option, observer);
400         } else {
401             errCode = rdbStore_->Subscribe(option, observer.get());
402         }
403         if (errCode == NativeRdb::E_OK) {
404             observers_[mode].push_back(observer);
405             LOGI("subscribe success");
406         }
407         return errCode;
408     }
409 
RegisterObserverProgressDetails(int64_t callbackId)410     int32_t RdbStoreImpl::RegisterObserverProgressDetails(int64_t callbackId)
411     {
412         auto observer = std::make_shared<SyncObserverImpl>(callbackId);
413         int errCode = rdbStore_->RegisterAutoSyncCallback(observer);
414         if (errCode == NativeRdb::E_OK) {
415             syncObservers_.push_back(observer);
416             LOGI("progress subscribe success");
417         }
418         return errCode;
419     }
420 
UnRegisterObserver(const char * event,bool interProcess,std::function<void ()> * callback)421     int32_t RdbStoreImpl::UnRegisterObserver(const char *event, bool interProcess, std::function<void()> *callback)
422     {
423         DistributedRdb::SubscribeOption option;
424         option.event = event;
425         interProcess ? option.mode = DistributedRdb::SubscribeMode::LOCAL_SHARED : option.mode =
426             DistributedRdb::SubscribeMode::LOCAL;
427         if (option.mode == DistributedRdb::SubscribeMode::LOCAL) {
428             return UnRegisteredObserver(option, localObservers_, callback);
429         }
430         return UnRegisteredObserver(option, localSharedObservers_, callback);
431     }
432 
UnRegisteredObserver(DistributedRdb::SubscribeOption option,std::map<std::string,std::list<std::shared_ptr<RdbStoreObserverImpl>>> & observers,std::function<void ()> * callback)433     int32_t RdbStoreImpl::UnRegisteredObserver(DistributedRdb::SubscribeOption option,
434         std::map<std::string, std::list<std::shared_ptr<RdbStoreObserverImpl>>> &observers,
435         std::function<void()> *callback)
436     {
437         auto obs = observers.find(option.event);
438         if (obs == observers.end()) {
439             LOGI("observer not found, event: %{public}s", option.event.c_str());
440             return RelationalStoreJsKit::OK;
441         }
442 
443         auto &list = obs->second;
444         for (auto it = list.begin(); it != list.end(); it++) {
445             if (isSameFunction(callback, (*it)->GetCallBack())) {
446                 int errCode = rdbStore_->UnSubscribe(option, it->get());
447                 if (errCode != RelationalStoreJsKit::OK) {
448                     return errCode;
449                 }
450                 list.erase(it);
451                 break;
452             }
453         }
454         if (list.empty()) {
455             observers.erase(option.event);
456         }
457         LOGI("unsubscribe success, event: %{public}s", option.event.c_str());
458         return RelationalStoreJsKit::OK;
459     }
460 
UnRegisterAllObserver(const char * event,bool interProcess)461     int32_t RdbStoreImpl::UnRegisterAllObserver(const char *event, bool interProcess)
462     {
463         DistributedRdb::SubscribeOption option;
464         option.event = event;
465         interProcess ? option.mode = DistributedRdb::SubscribeMode::LOCAL_SHARED : option.mode =
466             DistributedRdb::SubscribeMode::LOCAL;
467         if (option.mode == DistributedRdb::SubscribeMode::LOCAL) {
468             return UnRegisteredAllObserver(option, localObservers_);
469         }
470         return UnRegisteredAllObserver(option, localSharedObservers_);
471     }
472 
UnRegisteredAllObserver(DistributedRdb::SubscribeOption option,std::map<std::string,std::list<std::shared_ptr<RdbStoreObserverImpl>>> & observers)473     int32_t RdbStoreImpl::UnRegisteredAllObserver(DistributedRdb::SubscribeOption option, std::map<std::string,
474         std::list<std::shared_ptr<RdbStoreObserverImpl>>> &observers)
475     {
476         auto obs = observers.find(option.event);
477         if (obs == observers.end()) {
478             LOGI("observer not found, event: %{public}s", option.event.c_str());
479             return RelationalStoreJsKit::OK;
480         }
481 
482         int errCode = rdbStore_->UnSubscribe(option, nullptr);
483         if (errCode != RelationalStoreJsKit::OK) {
484             return errCode;
485         }
486         observers.erase(option.event);
487         LOGI("unsubscribe success, event: %{public}s", option.event.c_str());
488         return RelationalStoreJsKit::OK;
489     }
490 
UnRegisterObserverArrStrChangeInfo(int32_t subscribeType,int64_t callbackId)491     int32_t RdbStoreImpl::UnRegisterObserverArrStrChangeInfo(int32_t subscribeType, int64_t callbackId)
492     {
493         int32_t mode = subscribeType;
494         DistributedRdb::SubscribeOption option;
495         option.mode = static_cast<DistributedRdb::SubscribeMode>(mode);
496         option.event = "dataChange";
497         for (auto it = observers_[mode].begin(); it != observers_[mode].end();) {
498             if (*it == nullptr) {
499                 it = observers_[mode].erase(it);
500                 continue;
501             }
502             if (((**it).GetCallBackId() != callbackId)) {
503                 ++it;
504                 continue;
505             }
506             int errCode = NativeRdb::E_OK;
507             if (option.mode == DistributedRdb::SubscribeMode::LOCAL_DETAIL) {
508                 errCode = rdbStore_->UnsubscribeObserver(option, *it);
509             } else {
510                 errCode = rdbStore_->UnSubscribe(option, it->get());
511             }
512             if (errCode != NativeRdb::E_OK) {
513                 return errCode;
514             }
515             it = observers_[mode].erase(it);
516         }
517         return NativeRdb::E_OK;
518     }
519 
UnRegisterObserverArrStrChangeInfoAll(int32_t subscribeType)520     int32_t RdbStoreImpl::UnRegisterObserverArrStrChangeInfoAll(int32_t subscribeType)
521     {
522         int32_t mode = subscribeType;
523         DistributedRdb::SubscribeOption option;
524         option.mode = static_cast<DistributedRdb::SubscribeMode>(mode);
525         option.event = "dataChange";
526         for (auto it = observers_[mode].begin(); it != observers_[mode].end();) {
527             if (*it == nullptr) {
528                 it = observers_[mode].erase(it);
529                 continue;
530             }
531             int errCode = NativeRdb::E_OK;
532             if (option.mode == DistributedRdb::SubscribeMode::LOCAL_DETAIL) {
533                 errCode = rdbStore_->UnsubscribeObserver(option, *it);
534             } else {
535                 errCode = rdbStore_->UnSubscribe(option, it->get());
536             }
537             if (errCode != NativeRdb::E_OK) {
538                 return errCode;
539             }
540             it = observers_[mode].erase(it);
541         }
542         return NativeRdb::E_OK;
543     }
544 
UnRegisterObserverProgressDetails(int64_t callbackId)545     int32_t RdbStoreImpl::UnRegisterObserverProgressDetails(int64_t callbackId)
546     {
547         for (auto it = syncObservers_.begin(); it != syncObservers_.end();) {
548             if (*it == nullptr) {
549                 it = syncObservers_.erase(it);
550                 continue;
551             }
552             if (((**it).GetCallBackId() != callbackId)) {
553                 ++it;
554                 continue;
555             }
556 
557             int32_t errCode = rdbStore_->UnregisterAutoSyncCallback(*it);
558             if (errCode != NativeRdb::E_OK) {
559                 return errCode;
560             }
561             it = syncObservers_.erase(it);
562         }
563         return NativeRdb::E_OK;
564     }
565 
UnRegisterObserverProgressDetailsAll()566     int32_t RdbStoreImpl::UnRegisterObserverProgressDetailsAll()
567     {
568         for (auto it = syncObservers_.begin(); it != syncObservers_.end();) {
569             if (*it == nullptr) {
570                 it = syncObservers_.erase(it);
571                 continue;
572             }
573             int32_t errCode = rdbStore_->UnregisterAutoSyncCallback(*it);
574             if (errCode != NativeRdb::E_OK) {
575                 return errCode;
576             }
577             it = syncObservers_.erase(it);
578         }
579         return NativeRdb::E_OK;
580     }
581 
CloudSync(int32_t mode,CArrStr tables,int64_t callbackId)582     int32_t RdbStoreImpl::CloudSync(int32_t mode, CArrStr tables, int64_t callbackId)
583     {
584         DistributedRdb::SyncOption option;
585         option.mode = static_cast<DistributedRdb::SyncMode>(mode);
586         option.isBlock = false;
587         std::vector<std::string> arr = CArrStrToVector(tables);
588         auto cFunc = reinterpret_cast<void(*)(CProgressDetails details)>(callbackId);
589         auto async = [ lambda = CJLambda::Create(cFunc)](const DistributedRdb::Details &details) ->
590             void { lambda(ToCProgressDetails(details)); };
591         int32_t errCode = rdbStore_->Sync(option, arr, async);
592         return errCode;
593     }
594 
GetVersion(int32_t & errCode)595     int32_t RdbStoreImpl::GetVersion(int32_t& errCode)
596     {
597         int32_t version = 0;
598         errCode = rdbStore_->GetVersion(version);
599         return version;
600     }
601 
SetVersion(int32_t value,int32_t & errCode)602     void RdbStoreImpl::SetVersion(int32_t value, int32_t &errCode)
603     {
604         errCode = rdbStore_->SetVersion(value);
605     }
606 
GetModifyTime(char * cTables,char * cColumnName,CArrPRIKeyType & cPrimaryKeys,int32_t & errCode)607     ModifyTime RdbStoreImpl::GetModifyTime(char *cTables, char *cColumnName, CArrPRIKeyType &cPrimaryKeys,
608         int32_t& errCode)
609     {
610         std::string tableName = cTables;
611         std::string columnName = cColumnName;
612         std::vector<NativeRdb::RdbStore::PRIKey> keys = CArrPRIKeyTypeToPRIKeyArray(cPrimaryKeys);
613         std::map<NativeRdb::RdbStore::PRIKey, NativeRdb::RdbStore::Date> map =
614             rdbStore_->GetModifyTime(tableName, columnName, keys);
615         if (map.empty()) {
616             errCode = NativeRdb::E_ERROR;
617             return ModifyTime{0};
618         }
619         return MapToModifyTime(map, errCode);
620     }
621 
GetRealPath(AppDataMgrJsKit::JSUtils::RdbConfig & rdbConfig,const AppDataMgrJsKit::JSUtils::ContextParam & param,std::shared_ptr<OHOS::AppDataMgrJsKit::Context> abilitycontext)622     int32_t GetRealPath(AppDataMgrJsKit::JSUtils::RdbConfig &rdbConfig,
623         const AppDataMgrJsKit::JSUtils::ContextParam &param,
624         std::shared_ptr<OHOS::AppDataMgrJsKit::Context> abilitycontext)
625     {
626         if (rdbConfig.name.find(PATH_SPLIT) != std::string::npos) {
627             LOGE("Parameter error. The StoreConfig.name must be a file name without path.");
628             return RelationalStoreJsKit::E_PARAM_ERROR;
629         }
630 
631         if (!rdbConfig.customDir.empty()) {
632             // determine if the first character of customDir is '/'
633             if (rdbConfig.customDir.find_first_of(PATH_SPLIT) == 0) {
634                 LOGE("Parameter error. The customDir must be a relative directory.");
635                 return RelationalStoreJsKit::E_PARAM_ERROR;
636             }
637             // customDir length is limited to 128 bytes
638             if (rdbConfig.customDir.length() > 128) {
639                 LOGE("Parameter error. The customDir length must be less than or equal to 128 bytes.");
640                 return RelationalStoreJsKit::E_PARAM_ERROR;
641             }
642         }
643 
644         std::string baseDir = param.baseDir;
645         if (!rdbConfig.dataGroupId.empty()) {
646             if (!param.isStageMode) {
647                 return RelationalStoreJsKit::E_NOT_STAGE_MODE;
648             }
649             std::string groupDir;
650             int errCode = abilitycontext->GetSystemDatabaseDir(rdbConfig.dataGroupId, groupDir);
651             if (errCode != NativeRdb::E_OK && groupDir.empty()) {
652                 return RelationalStoreJsKit::E_DATA_GROUP_ID_INVALID;
653             }
654             baseDir = groupDir;
655         }
656 
657         auto [realPath, errorCode] =
658             NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(baseDir, rdbConfig.name, rdbConfig.customDir);
659         // realPath length is limited to 1024 bytes
660         if (errorCode != NativeRdb::E_OK || realPath.length() > 1024) {
661             LOGE("Parameter error. The database path must be a valid path.");
662             return RelationalStoreJsKit::E_PARAM_ERROR;
663         }
664         rdbConfig.path = realPath;
665         return NativeRdb::E_OK;
666     }
667 
initContextParam(AppDataMgrJsKit::JSUtils::ContextParam & param,std::shared_ptr<OHOS::AppDataMgrJsKit::Context> abilitycontext)668     void initContextParam(AppDataMgrJsKit::JSUtils::ContextParam &param,
669         std::shared_ptr<OHOS::AppDataMgrJsKit::Context> abilitycontext)
670     {
671         param.bundleName = abilitycontext->GetBundleName();
672         param.moduleName = abilitycontext->GetModuleName();
673         param.baseDir = abilitycontext->GetDatabaseDir();
674         param.area = abilitycontext->GetArea();
675         param.isSystemApp = abilitycontext->IsSystemAppCalled();
676         param.isStageMode = abilitycontext->IsStageMode();
677     }
678 
initRdbConfig(AppDataMgrJsKit::JSUtils::RdbConfig & rdbConfig,StoreConfig & config)679     void initRdbConfig(AppDataMgrJsKit::JSUtils::RdbConfig &rdbConfig, StoreConfig &config)
680     {
681         rdbConfig.isEncrypt = config.encrypt;
682         rdbConfig.isSearchable = config.isSearchable;
683         rdbConfig.isAutoClean = config.autoCleanDirtyData;
684         rdbConfig.securityLevel = static_cast<NativeRdb::SecurityLevel>(config.securityLevel);
685         rdbConfig.dataGroupId = config.dataGroupId;
686         rdbConfig.name = config.name;
687         rdbConfig.customDir = config.customDir;
688     }
689 
getRdbStoreConfig(const AppDataMgrJsKit::JSUtils::RdbConfig & rdbConfig,const AppDataMgrJsKit::JSUtils::ContextParam & param)690     NativeRdb::RdbStoreConfig getRdbStoreConfig(const AppDataMgrJsKit::JSUtils::RdbConfig &rdbConfig,
691         const AppDataMgrJsKit::JSUtils::ContextParam &param)
692     {
693         NativeRdb::RdbStoreConfig rdbStoreConfig(rdbConfig.path);
694         rdbStoreConfig.SetEncryptStatus(rdbConfig.isEncrypt);
695         rdbStoreConfig.SetSearchable(rdbConfig.isSearchable);
696         rdbStoreConfig.SetIsVector(rdbConfig.vector);
697         rdbStoreConfig.SetAutoClean(rdbConfig.isAutoClean);
698         rdbStoreConfig.SetSecurityLevel(rdbConfig.securityLevel);
699         rdbStoreConfig.SetDataGroupId(rdbConfig.dataGroupId);
700         rdbStoreConfig.SetName(rdbConfig.name);
701         rdbStoreConfig.SetCustomDir(rdbConfig.customDir);
702         rdbStoreConfig.SetAllowRebuild(rdbConfig.allowRebuild);
703 
704         if (!param.bundleName.empty()) {
705             rdbStoreConfig.SetBundleName(param.bundleName);
706         }
707         rdbStoreConfig.SetModuleName(param.moduleName);
708         rdbStoreConfig.SetArea(param.area);
709         return rdbStoreConfig;
710     }
711 
GetRdbStore(OHOS::AbilityRuntime::Context * context,StoreConfig config,int32_t * errCode)712     int64_t GetRdbStore(OHOS::AbilityRuntime::Context* context, StoreConfig config,
713         int32_t *errCode)
714     {
715         if (context == nullptr) {
716             *errCode = -1;
717             return -1;
718         }
719         auto abilitycontext = std::make_shared<AppDataMgrJsKit::Context>(context->shared_from_this());
720         AppDataMgrJsKit::JSUtils::ContextParam param;
721         initContextParam(param, abilitycontext);
722         AppDataMgrJsKit::JSUtils::RdbConfig rdbConfig;
723         initRdbConfig(rdbConfig, config);
724 
725         *errCode = GetRealPath(rdbConfig, param, abilitycontext);
726         if (*errCode != NativeRdb::E_OK) {
727             return -1;
728         }
729 
730         DefaultOpenCallback callback;
731         auto rdbStore =
732             NativeRdb::RdbHelper::GetRdbStore(getRdbStoreConfig(rdbConfig, param), -1, callback, *errCode);
733         if (*errCode != 0) {
734             return -1;
735         }
736         auto nativeRdbStore = FFIData::Create<RdbStoreImpl>(rdbStore);
737         if (nativeRdbStore == nullptr) {
738             *errCode = -1;
739             return -1;
740         }
741         return nativeRdbStore->GetID();
742     }
743 
DeleteRdbStore(OHOS::AbilityRuntime::Context * context,const char * name,int32_t * errCode)744     void DeleteRdbStore(OHOS::AbilityRuntime::Context* context, const char* name,
745         int32_t *errCode)
746     {
747         if (context == nullptr) {
748             *errCode = -1;
749             return;
750         }
751         auto abilitycontext = std::make_shared<AppDataMgrJsKit::Context>(context->shared_from_this());
752         AppDataMgrJsKit::JSUtils::ContextParam param;
753         initContextParam(param, abilitycontext);
754         AppDataMgrJsKit::JSUtils::RdbConfig rdbConfig;
755         rdbConfig.name = name;
756 
757         *errCode = GetRealPath(rdbConfig, param, abilitycontext);
758         if (*errCode != NativeRdb::E_OK) {
759             return;
760         }
761         *errCode = NativeRdb::RdbHelper::DeleteRdbStore(rdbConfig.path);
762         return;
763     }
764 
DeleteRdbStoreConfig(OHOS::AbilityRuntime::Context * context,StoreConfig config,int32_t * errCode)765     void DeleteRdbStoreConfig(OHOS::AbilityRuntime::Context* context, StoreConfig config,
766         int32_t *errCode)
767     {
768         if (context == nullptr) {
769             *errCode = -1;
770             return;
771         }
772         auto abilitycontext = std::make_shared<AppDataMgrJsKit::Context>(context->shared_from_this());
773         AppDataMgrJsKit::JSUtils::ContextParam param;
774         initContextParam(param, abilitycontext);
775         AppDataMgrJsKit::JSUtils::RdbConfig rdbConfig;
776         initRdbConfig(rdbConfig, config);
777 
778         *errCode = GetRealPath(rdbConfig, param, abilitycontext);
779         if (*errCode != NativeRdb::E_OK) {
780             return;
781         }
782         *errCode = NativeRdb::RdbHelper::DeleteRdbStore(rdbConfig.path);
783         return;
784     }
785 }
786 }