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 ¶m, 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 ¶m, 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 ¶m) 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 }