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 #define LOG_TAG "RelationalStore" 16 #include "relational_store.h" 17 18 #include "convertor_error_code.h" 19 #include "grd_api_manager.h" 20 #include "logger.h" 21 #include "modify_time_cursor.h" 22 #include "raw_data_parser.h" 23 #include "rdb_errno.h" 24 #include "rdb_helper.h" 25 #include "rdb_predicates.h" 26 #include "rdb_sql_utils.h" 27 #include "rdb_store_config.h" 28 #include "relational_cursor.h" 29 #include "relational_predicates.h" 30 #include "relational_predicates_objects.h" 31 #include "relational_store_error_code.h" 32 #include "relational_store_impl.h" 33 #include "relational_types_v0.h" 34 #include "relational_values_bucket.h" 35 #include "securec.h" 36 #include "sqlite_global_config.h" 37 38 using namespace OHOS::RdbNdk; 39 using namespace OHOS::DistributedRdb; 40 constexpr int RDB_STORE_CID = 1234560; // The class id used to uniquely identify the OH_Rdb_Store class. 41 constexpr int RDB_CONFIG_SIZE_V0 = 41; 42 constexpr int RDB_CONFIG_SIZE_V1 = 45; 43 constexpr int RDB_CONFIG_V2_MAGIC_CODE = 0xDBCF2ADE; 44 45 static int g_supportDbTypes[] = {RDB_SQLITE, RDB_CAYLEY}; 46 47 struct OH_Rdb_ConfigV2 { 48 int magicNum = RDB_CONFIG_V2_MAGIC_CODE; 49 std::string dataBaseDir = ""; 50 std::string storeName = ""; 51 std::string bundleName = ""; 52 std::string moduleName = ""; 53 bool isEncrypt = false; 54 int securityLevel = 0; 55 int area = 0; 56 int dbType = RDB_SQLITE; 57 }; 58 OH_Rdb_CreateConfig()59 OH_Rdb_ConfigV2 *OH_Rdb_CreateConfig() 60 { 61 return new (std::nothrow) OH_Rdb_ConfigV2(); 62 } 63 OH_Rdb_DestroyConfig(OH_Rdb_ConfigV2 * config)64 int OH_Rdb_DestroyConfig(OH_Rdb_ConfigV2 *config) 65 { 66 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { 67 LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when destroy.", 68 (config == nullptr), (config == nullptr ? 0 : config->magicNum)); 69 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 70 } 71 delete config; 72 config = nullptr; 73 return OH_Rdb_ErrCode::RDB_OK; 74 } 75 OH_Rdb_SetDatabaseDir(OH_Rdb_ConfigV2 * config,const char * dataBaseDir)76 int OH_Rdb_SetDatabaseDir(OH_Rdb_ConfigV2 *config, const char *dataBaseDir) 77 { 78 if (config == nullptr || dataBaseDir == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { 79 LOG_ERROR("config is null %{public}d or dataBaseDir %{public}d magic num not valid %{public}x " 80 "when Set DataBaseDir.", (config == nullptr), (dataBaseDir == nullptr), 81 (config == nullptr ? 0 : config->magicNum)); 82 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 83 } 84 config->dataBaseDir = std::string(dataBaseDir); 85 return OH_Rdb_ErrCode::RDB_OK; 86 } 87 OH_Rdb_SetStoreName(OH_Rdb_ConfigV2 * config,const char * storeName)88 int OH_Rdb_SetStoreName(OH_Rdb_ConfigV2 *config, const char *storeName) 89 { 90 if (config == nullptr || storeName == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { 91 LOG_ERROR("config is null %{public}d or storeName %{public}d or magic num not ok" 92 "%{public}x When set storeName.", (config == nullptr), (storeName == nullptr), 93 (config == nullptr ? 0 : config->magicNum)); 94 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 95 } 96 config->storeName = std::string(storeName); 97 return OH_Rdb_ErrCode::RDB_OK; 98 } 99 OH_Rdb_SetBundleName(OH_Rdb_ConfigV2 * config,const char * bundleName)100 int OH_Rdb_SetBundleName(OH_Rdb_ConfigV2 *config, const char *bundleName) 101 { 102 if (config == nullptr || bundleName == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { 103 LOG_ERROR("config is null %{public}d or bundleName %{public}d magic num no ok %{public}x when set bundleName.", 104 (config == nullptr), (bundleName == nullptr), (config == nullptr ? 0 : config->magicNum)); 105 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 106 } 107 config->bundleName = std::string(bundleName); 108 return OH_Rdb_ErrCode::RDB_OK; 109 } 110 OH_Rdb_SetModuleName(OH_Rdb_ConfigV2 * config,const char * moduleName)111 int OH_Rdb_SetModuleName(OH_Rdb_ConfigV2 *config, const char *moduleName) 112 { 113 if (config == nullptr || moduleName == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { 114 LOG_ERROR("config is null %{public}d or moduleName %{public}d magic num no ok %{public}x when set moduleName.", 115 (config == nullptr), (moduleName == nullptr), (config == nullptr ? 0 : config->magicNum)); 116 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 117 } 118 config->moduleName = std::string(moduleName); 119 return OH_Rdb_ErrCode::RDB_OK; 120 } 121 OH_Rdb_SetEncrypted(OH_Rdb_ConfigV2 * config,bool isEncrypted)122 int OH_Rdb_SetEncrypted(OH_Rdb_ConfigV2 *config, bool isEncrypted) 123 { 124 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { 125 LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when set encrypt.", (config == nullptr), 126 (config == nullptr ? 0 : config->magicNum)); 127 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 128 } 129 config->isEncrypt = isEncrypted; 130 return OH_Rdb_ErrCode::RDB_OK; 131 } 132 OH_Rdb_SetSecurityLevel(OH_Rdb_ConfigV2 * config,int securityLevel)133 int OH_Rdb_SetSecurityLevel(OH_Rdb_ConfigV2 *config, int securityLevel) 134 { 135 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { 136 LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when set security level.", 137 (config == nullptr), (config == nullptr ? 0 : config->magicNum)); 138 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 139 } 140 if (securityLevel < S1 || securityLevel > S4) { 141 LOG_ERROR("securityLevel value is out of range %{public}d", securityLevel); 142 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 143 } 144 config->securityLevel = securityLevel; 145 return OH_Rdb_ErrCode::RDB_OK; 146 } 147 OH_Rdb_SetArea(OH_Rdb_ConfigV2 * config,int area)148 int OH_Rdb_SetArea(OH_Rdb_ConfigV2 *config, int area) 149 { 150 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { 151 LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when set area.", (config == nullptr), 152 (config == nullptr ? 0 : config->magicNum)); 153 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 154 } 155 if (area < RDB_SECURITY_AREA_EL1 || area > RDB_SECURITY_AREA_EL5) { 156 LOG_ERROR("area value is out of range %{public}d", area); 157 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 158 } 159 config->area = area; 160 return OH_Rdb_ErrCode::RDB_OK; 161 } 162 OH_Rdb_SetDbType(OH_Rdb_ConfigV2 * config,int dbType)163 int OH_Rdb_SetDbType(OH_Rdb_ConfigV2 *config, int dbType) 164 { 165 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE) || 166 (dbType < RDB_SQLITE || dbType > RDB_CAYLEY)) { 167 LOG_ERROR("config is null %{public}d or magicNum not valid %{public}d or dbType is out of range %{public}d", 168 (config == nullptr), (config == nullptr ? 0 : config->magicNum), dbType); 169 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 170 } 171 if (dbType == RDB_CAYLEY && !(OHOS::NativeRdb::IsUsingArkData())) { 172 return OH_Rdb_ErrCode::RDB_E_NOT_SUPPORTED; 173 } 174 config->dbType = dbType; 175 return OH_Rdb_ErrCode::RDB_OK; 176 } 177 OH_Rdb_GetSupportedDbType(int * numType)178 const int *OH_Rdb_GetSupportedDbType(int *numType) 179 { 180 if (numType == nullptr) { 181 return nullptr; 182 } 183 // if use arkData, then numType will be 2 {RDB_SQLITE and RDB_CAYLEY}, otherwise only 1 {RDB_SQLITE} 184 *numType = OHOS::NativeRdb::IsUsingArkData() ? 2 : 1; 185 return g_supportDbTypes; 186 } 187 OH_Rdb_CreateValueObject()188 OH_VObject *OH_Rdb_CreateValueObject() 189 { 190 return new (std::nothrow) RelationalPredicatesObjects(); 191 } 192 OH_Rdb_CreateValuesBucket()193 OH_VBucket *OH_Rdb_CreateValuesBucket() 194 { 195 return new (std::nothrow) RelationalValuesBucket(); 196 } 197 OH_Rdb_CreatePredicates(const char * table)198 OH_Predicates *OH_Rdb_CreatePredicates(const char *table) 199 { 200 if (table == nullptr) { 201 return nullptr; 202 } 203 return new (std::nothrow) RelationalPredicate(table); 204 } 205 RelationalStore(std::shared_ptr<OHOS::NativeRdb::RdbStore> store)206 OHOS::RdbNdk::RelationalStore::RelationalStore(std::shared_ptr<OHOS::NativeRdb::RdbStore> store) : store_(store) 207 { 208 id = RDB_STORE_CID; 209 } 210 SubscribeAutoSyncProgress(const Rdb_ProgressObserver * callback)211 int RelationalStore::SubscribeAutoSyncProgress(const Rdb_ProgressObserver *callback) 212 { 213 std::lock_guard<decltype(mutex_)> lock(mutex_); 214 bool result = std::any_of( 215 callbacks_.begin(), callbacks_.end(), [callback](const auto &observer) { return *observer == callback; }); 216 if (result) { 217 LOG_INFO("duplicate subscribe."); 218 return OH_Rdb_ErrCode::RDB_OK; 219 } 220 auto obs = std::make_shared<NDKDetailProgressObserver>(callback); 221 int errCode = store_->RegisterAutoSyncCallback(obs); 222 if (errCode == NativeRdb::E_OK) { 223 LOG_ERROR("subscribe failed."); 224 return ConvertorErrorCode::NativeToNdk(errCode); 225 } 226 callbacks_.push_back(std::move(obs)); 227 return OH_Rdb_ErrCode::RDB_OK; 228 } 229 UnsubscribeAutoSyncProgress(const Rdb_ProgressObserver * callback)230 int RelationalStore::UnsubscribeAutoSyncProgress(const Rdb_ProgressObserver *callback) 231 { 232 std::lock_guard<decltype(mutex_)> lock(mutex_); 233 for (auto it = callbacks_.begin(); it != callbacks_.end();) { 234 if (callback != nullptr && !(**it == callback)) { 235 ++it; 236 continue; 237 } 238 239 int errCode = store_->UnregisterAutoSyncCallback(*it); 240 if (errCode != NativeRdb::E_OK) { 241 LOG_ERROR("unsubscribe failed."); 242 return ConvertorErrorCode::NativeToNdk(errCode); 243 } 244 it = callbacks_.erase(it); 245 LOG_DEBUG("progress unsubscribe success."); 246 } 247 return OH_Rdb_ErrCode::RDB_OK; 248 } 249 ~RelationalStore()250 RelationalStore::~RelationalStore() 251 { 252 if (store_ == nullptr || callbacks_.empty()) { 253 return; 254 } 255 for (auto &callback : callbacks_) { 256 store_->UnregisterAutoSyncCallback(callback); 257 } 258 } 259 TransformMode(Rdb_SyncMode & mode)260 SyncMode NDKUtils::TransformMode(Rdb_SyncMode &mode) 261 { 262 switch (mode) { 263 case RDB_SYNC_MODE_TIME_FIRST: 264 return TIME_FIRST; 265 case RDB_SYNC_MODE_NATIVE_FIRST: 266 return NATIVE_FIRST; 267 case RDB_SYNC_MODE_CLOUD_FIRST: 268 return CLOUD_FIRST; 269 default: 270 return static_cast<SyncMode>(-1); 271 } 272 } 273 GetSubscribeType(Rdb_SubscribeType & type)274 OHOS::DistributedRdb::SubscribeMode NDKUtils::GetSubscribeType(Rdb_SubscribeType &type) 275 { 276 switch (type) { 277 case Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD: 278 return SubscribeMode::CLOUD; 279 case Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD_DETAILS: 280 return SubscribeMode::CLOUD_DETAIL; 281 case Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS: 282 return SubscribeMode::LOCAL_DETAIL; 283 default: 284 return SubscribeMode::SUBSCRIBE_MODE_MAX; 285 } 286 } 287 288 class MainOpenCallback : public OHOS::NativeRdb::RdbOpenCallback { 289 public: 290 int OnCreate(OHOS::NativeRdb::RdbStore &rdbStore) override; 291 int OnUpgrade(OHOS::NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion) override; 292 }; 293 OnCreate(OHOS::NativeRdb::RdbStore & rdbStore)294 int MainOpenCallback::OnCreate(OHOS::NativeRdb::RdbStore &rdbStore) 295 { 296 return OH_Rdb_ErrCode::RDB_OK; 297 } 298 OnUpgrade(OHOS::NativeRdb::RdbStore & rdbStore,int oldVersion,int newVersion)299 int MainOpenCallback::OnUpgrade(OHOS::NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion) 300 { 301 return OH_Rdb_ErrCode::RDB_OK; 302 } 303 GetRelationalStore(OH_Rdb_Store * store)304 RelationalStore *GetRelationalStore(OH_Rdb_Store *store) 305 { 306 if (store == nullptr || store->id != RDB_STORE_CID) { 307 LOG_ERROR("store is invalid. is null %{public}d", (store == nullptr)); 308 return nullptr; 309 } 310 return static_cast<RelationalStore *>(store); 311 } 312 GetRdbStoreConfig(const OH_Rdb_ConfigV2 * config,int * errCode)313 static OHOS::NativeRdb::RdbStoreConfig GetRdbStoreConfig(const OH_Rdb_ConfigV2 *config, int *errCode) 314 { 315 if (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE || 316 (OHOS::NativeRdb::SecurityLevel(config->securityLevel) < OHOS::NativeRdb::SecurityLevel::S1 || 317 OHOS::NativeRdb::SecurityLevel(config->securityLevel) >= OHOS::NativeRdb::SecurityLevel::LAST) || 318 (config->area < RDB_SECURITY_AREA_EL1 || config->area > RDB_SECURITY_AREA_EL5) || 319 (config->dbType < RDB_SQLITE || config->dbType > RDB_CAYLEY)) { 320 *errCode = OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 321 LOG_ERROR("Config magic number is not valid %{public}x or securityLevel %{public}d area %{public}d" 322 "dbType %{public}d ret %{public}d", config->magicNum, config->securityLevel, config->area, config->dbType, 323 *errCode); 324 return OHOS::NativeRdb::RdbStoreConfig(""); 325 } 326 std::string realPath = 327 OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, config->storeName, *errCode); 328 if (*errCode != 0) { 329 *errCode = ConvertorErrorCode::NativeToNdk(*errCode); 330 LOG_ERROR("Get database path failed from new config, ret %{public}d ", *errCode); 331 return OHOS::NativeRdb::RdbStoreConfig(""); 332 } 333 OHOS::NativeRdb::RdbStoreConfig rdbStoreConfig(realPath); 334 rdbStoreConfig.SetSecurityLevel(OHOS::NativeRdb::SecurityLevel(config->securityLevel)); 335 rdbStoreConfig.SetEncryptStatus(config->isEncrypt); 336 rdbStoreConfig.SetArea(config->area - 1); 337 rdbStoreConfig.SetIsVector(config->dbType == RDB_CAYLEY); 338 rdbStoreConfig.SetBundleName(config->bundleName); 339 rdbStoreConfig.SetName(config->storeName); 340 return rdbStoreConfig; 341 } 342 OH_Rdb_GetOrOpen(const OH_Rdb_Config * config,int * errCode)343 OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode) 344 { 345 if (config == nullptr || config->selfSize > RDB_CONFIG_SIZE_V1 || errCode == nullptr) { 346 LOG_ERROR("Parameters set error:config is NULL ? %{public}d and config size is %{public}zu or " 347 "errCode is NULL ? %{public}d ", 348 (config == nullptr), sizeof(OH_Rdb_Config), (errCode == nullptr)); 349 return nullptr; 350 } 351 352 std::string realPath = 353 OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, config->storeName, *errCode); 354 if (*errCode != 0) { 355 *errCode = ConvertorErrorCode::NativeToNdk(*errCode); 356 LOG_ERROR("Get database path failed, ret %{public}d ", *errCode); 357 return nullptr; 358 } 359 OHOS::NativeRdb::RdbStoreConfig rdbStoreConfig(realPath); 360 rdbStoreConfig.SetSecurityLevel(OHOS::NativeRdb::SecurityLevel(config->securityLevel)); 361 rdbStoreConfig.SetEncryptStatus(config->isEncrypt); 362 if (config->selfSize > RDB_CONFIG_SIZE_V0) { 363 rdbStoreConfig.SetArea(config->area - 1); 364 } 365 if (config->bundleName != nullptr) { 366 rdbStoreConfig.SetBundleName(config->bundleName); 367 } 368 rdbStoreConfig.SetName(config->storeName); 369 370 MainOpenCallback callback; 371 std::shared_ptr<OHOS::NativeRdb::RdbStore> store = 372 OHOS::NativeRdb::RdbHelper::GetRdbStore(rdbStoreConfig, -1, callback, *errCode); 373 *errCode = ConvertorErrorCode::NativeToNdk(*errCode); 374 if (store == nullptr) { 375 LOG_ERROR("Get RDB Store fail %{public}s", realPath.c_str()); 376 return nullptr; 377 } 378 return new (std::nothrow) RelationalStore(store); 379 } 380 OH_Rdb_CreateOrOpen(const OH_Rdb_ConfigV2 * config,int * errCode)381 OH_Rdb_Store *OH_Rdb_CreateOrOpen(const OH_Rdb_ConfigV2 *config, int *errCode) 382 { 383 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE) || errCode == nullptr) { 384 LOG_ERROR("Parameters set error:config is NULL ? %{public}d or magicNum is not valid %{public}d or" 385 " errCode is NULL ? %{public}d ", (config == nullptr), (config == nullptr ? 0 : config->magicNum), 386 (errCode == nullptr)); 387 return nullptr; 388 } 389 OHOS::NativeRdb::RdbStoreConfig rdbStoreConfig = GetRdbStoreConfig(config, errCode); 390 if (*errCode != OH_Rdb_ErrCode::RDB_OK) { 391 return nullptr; 392 } 393 MainOpenCallback callback; 394 std::shared_ptr<OHOS::NativeRdb::RdbStore> store = 395 OHOS::NativeRdb::RdbHelper::GetRdbStore(rdbStoreConfig, -1, callback, *errCode); 396 *errCode = ConvertorErrorCode::NativeToNdk(*errCode); 397 if (store == nullptr) { 398 LOG_ERROR("Get RDB Store fail %{public}s", rdbStoreConfig.GetPath().c_str()); 399 return nullptr; 400 } 401 return new (std::nothrow) RelationalStore(store); 402 } 403 OH_Rdb_CloseStore(OH_Rdb_Store * store)404 int OH_Rdb_CloseStore(OH_Rdb_Store *store) 405 { 406 auto rdbStore = GetRelationalStore(store); 407 if (rdbStore == nullptr) { 408 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 409 } 410 delete rdbStore; 411 return OH_Rdb_ErrCode::RDB_OK; 412 } 413 OH_Rdb_DeleteStore(const OH_Rdb_Config * config)414 int OH_Rdb_DeleteStore(const OH_Rdb_Config *config) 415 { 416 if (config == nullptr || config->dataBaseDir == nullptr || config->storeName == nullptr) { 417 LOG_ERROR("Parameters set error:path is NULL ? %{public}d", (config == nullptr)); 418 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 419 } 420 int errCode = OHOS::NativeRdb::E_OK; 421 std::string realPath = 422 OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, config->storeName, errCode); 423 if (errCode != OHOS::NativeRdb::E_OK) { 424 return ConvertorErrorCode::NativeToNdk(errCode); 425 } 426 return ConvertorErrorCode::NativeToNdk(OHOS::NativeRdb::RdbHelper::DeleteRdbStore(realPath)); 427 } 428 OH_Rdb_DeleteStoreV2(const OH_Rdb_ConfigV2 * config)429 int OH_Rdb_DeleteStoreV2(const OH_Rdb_ConfigV2 *config) 430 { 431 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { 432 LOG_ERROR("config is NULL ? %{public}d, config is invalid ? %{public}d", (config == nullptr), 433 (config == nullptr ? 0 : config->magicNum)); 434 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 435 } 436 int errCode = OHOS::NativeRdb::E_OK; 437 std::string realPath = 438 OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, config->storeName, errCode); 439 if (errCode != OHOS::NativeRdb::E_OK) { 440 return ConvertorErrorCode::NativeToNdk(errCode); 441 } 442 return ConvertorErrorCode::NativeToNdk(OHOS::NativeRdb::RdbHelper::DeleteRdbStore(realPath)); 443 } 444 OH_Rdb_Insert(OH_Rdb_Store * store,const char * table,OH_VBucket * valuesBucket)445 int OH_Rdb_Insert(OH_Rdb_Store *store, const char *table, OH_VBucket *valuesBucket) 446 { 447 auto rdbStore = GetRelationalStore(store); 448 auto bucket = RelationalValuesBucket::GetSelf(valuesBucket); 449 if (rdbStore == nullptr || table == nullptr || bucket == nullptr) { 450 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 451 } 452 int64_t rowId = -1; 453 rdbStore->GetStore()->Insert(rowId, table, bucket->Get()); 454 return rowId >= 0 ? rowId : OH_Rdb_ErrCode::RDB_ERR; 455 } 456 OH_Rdb_Update(OH_Rdb_Store * store,OH_VBucket * valueBucket,OH_Predicates * predicates)457 int OH_Rdb_Update(OH_Rdb_Store *store, OH_VBucket *valueBucket, OH_Predicates *predicates) 458 { 459 auto rdbStore = GetRelationalStore(store); 460 auto predicate = RelationalPredicate::GetSelf(predicates); 461 auto bucket = RelationalValuesBucket::GetSelf(valueBucket); 462 if (rdbStore == nullptr || predicate == nullptr || bucket == nullptr) { 463 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 464 } 465 int updatedRows = -1; 466 rdbStore->GetStore()->Update(updatedRows, bucket->Get(), predicate->Get()); 467 return updatedRows >= 0 ? updatedRows : OH_Rdb_ErrCode::RDB_ERR; 468 } 469 OH_Rdb_Delete(OH_Rdb_Store * store,OH_Predicates * predicates)470 int OH_Rdb_Delete(OH_Rdb_Store *store, OH_Predicates *predicates) 471 { 472 auto rdbStore = GetRelationalStore(store); 473 auto predicate = RelationalPredicate::GetSelf(predicates); 474 if (rdbStore == nullptr || predicate == nullptr) { 475 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 476 } 477 int deletedRows = -1; 478 rdbStore->GetStore()->Delete(deletedRows, predicate->Get()); 479 return deletedRows >= 0 ? deletedRows : OH_Rdb_ErrCode::RDB_ERR; 480 } 481 OH_Rdb_Query(OH_Rdb_Store * store,OH_Predicates * predicates,const char * const * columnNames,int length)482 OH_Cursor *OH_Rdb_Query(OH_Rdb_Store *store, OH_Predicates *predicates, const char *const *columnNames, int length) 483 { 484 auto rdbStore = GetRelationalStore(store); 485 auto predicate = RelationalPredicate::GetSelf(predicates); 486 if (rdbStore == nullptr || predicate == nullptr) { 487 return nullptr; 488 } 489 std::vector<std::string> columns; 490 if (columnNames != nullptr && length > 0) { 491 columns.reserve(length); 492 for (int i = 0; i < length; i++) { 493 columns.push_back(columnNames[i]); 494 } 495 } 496 497 std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet = 498 rdbStore->GetStore()->QueryByStep(predicate->Get(), columns); 499 if (resultSet == nullptr) { 500 return nullptr; 501 } 502 return new (std::nothrow) RelationalCursor(std::move(resultSet)); 503 } 504 OH_Rdb_ExecuteQuery(OH_Rdb_Store * store,const char * sql)505 OH_Cursor *OH_Rdb_ExecuteQuery(OH_Rdb_Store *store, const char *sql) 506 { 507 auto rdbStore = GetRelationalStore(store); 508 if (rdbStore == nullptr || sql == nullptr) { 509 return nullptr; 510 } 511 std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet = 512 rdbStore->GetStore()->GetDbType() == OHOS::NativeRdb::DB_VECTOR 513 ? rdbStore->GetStore()->QueryByStep(sql, std::vector<std::string>{}) 514 : rdbStore->GetStore()->QuerySql(sql, std::vector<std::string>{}); 515 if (resultSet == nullptr) { 516 return nullptr; 517 } 518 return new OHOS::RdbNdk::RelationalCursor(std::move(resultSet)); 519 } 520 OH_Rdb_Execute(OH_Rdb_Store * store,const char * sql)521 int OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql) 522 { 523 auto rdbStore = GetRelationalStore(store); 524 if (rdbStore == nullptr || sql == nullptr) { 525 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 526 } 527 return ConvertorErrorCode::NativeToNdk( 528 rdbStore->GetStore()->ExecuteSql(sql, std::vector<OHOS::NativeRdb::ValueObject>{})); 529 } 530 OH_Rdb_ExecuteByTrxId(OH_Rdb_Store * store,int64_t trxId,const char * sql)531 int OH_Rdb_ExecuteByTrxId(OH_Rdb_Store *store, int64_t trxId, const char *sql) 532 { 533 auto rdbStore = GetRelationalStore(store); 534 if (rdbStore == nullptr || sql == nullptr) { 535 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 536 } 537 return ConvertorErrorCode::NativeToNdk( 538 (rdbStore->GetStore()->Execute(sql, std::vector<OHOS::NativeRdb::ValueObject>{}, trxId)).first); 539 } 540 OH_Rdb_BeginTransaction(OH_Rdb_Store * store)541 int OH_Rdb_BeginTransaction(OH_Rdb_Store *store) 542 { 543 auto rdbStore = GetRelationalStore(store); 544 if (rdbStore == nullptr) { 545 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 546 } 547 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->BeginTransaction()); 548 } 549 OH_Rdb_RollBack(OH_Rdb_Store * store)550 int OH_Rdb_RollBack(OH_Rdb_Store *store) 551 { 552 auto rdbStore = GetRelationalStore(store); 553 if (rdbStore == nullptr) { 554 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 555 } 556 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->RollBack()); 557 } 558 OH_Rdb_Commit(OH_Rdb_Store * store)559 int OH_Rdb_Commit(OH_Rdb_Store *store) 560 { 561 auto rdbStore = GetRelationalStore(store); 562 if (rdbStore == nullptr) { 563 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 564 } 565 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Commit()); 566 } 567 OH_Rdb_BeginTransWithTrxId(OH_Rdb_Store * store,int64_t * trxId)568 int OH_Rdb_BeginTransWithTrxId(OH_Rdb_Store *store, int64_t *trxId) 569 { 570 auto rdbStore = GetRelationalStore(store); 571 if (rdbStore == nullptr || trxId == nullptr) { 572 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 573 } 574 std::pair<int, int64_t> res = rdbStore->GetStore()->BeginTrans(); 575 *trxId = res.second; 576 return ConvertorErrorCode::NativeToNdk(res.first); 577 } 578 OH_Rdb_RollBackByTrxId(OH_Rdb_Store * store,int64_t trxId)579 int OH_Rdb_RollBackByTrxId(OH_Rdb_Store *store, int64_t trxId) 580 { 581 auto rdbStore = GetRelationalStore(store); 582 if (rdbStore == nullptr) { 583 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 584 } 585 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->RollBack(trxId)); 586 } 587 OH_Rdb_CommitByTrxId(OH_Rdb_Store * store,int64_t trxId)588 int OH_Rdb_CommitByTrxId(OH_Rdb_Store *store, int64_t trxId) 589 { 590 auto rdbStore = GetRelationalStore(store); 591 if (rdbStore == nullptr) { 592 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 593 } 594 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Commit(trxId)); 595 } 596 OH_Rdb_Backup(OH_Rdb_Store * store,const char * databasePath)597 int OH_Rdb_Backup(OH_Rdb_Store *store, const char *databasePath) 598 { 599 auto rdbStore = GetRelationalStore(store); 600 if (rdbStore == nullptr || databasePath == nullptr) { 601 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 602 } 603 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Backup(databasePath)); 604 } 605 OH_Rdb_Restore(OH_Rdb_Store * store,const char * databasePath)606 int OH_Rdb_Restore(OH_Rdb_Store *store, const char *databasePath) 607 { 608 auto rdbStore = GetRelationalStore(store); 609 if (rdbStore == nullptr || databasePath == nullptr) { 610 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 611 } 612 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Restore(databasePath)); 613 } 614 OH_Rdb_GetVersion(OH_Rdb_Store * store,int * version)615 int OH_Rdb_GetVersion(OH_Rdb_Store *store, int *version) 616 { 617 auto rdbStore = GetRelationalStore(store); 618 if (rdbStore == nullptr || version == nullptr) { 619 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 620 } 621 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->GetVersion(*version)); 622 } 623 OH_Rdb_SetVersion(OH_Rdb_Store * store,int version)624 int OH_Rdb_SetVersion(OH_Rdb_Store *store, int version) 625 { 626 auto rdbStore = GetRelationalStore(store); 627 if (rdbStore == nullptr) { 628 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 629 } 630 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->SetVersion(version)); 631 } 632 Convert(const Rdb_DistributedConfig * config)633 static std::pair<int32_t, Rdb_DistributedConfig> Convert(const Rdb_DistributedConfig *config) 634 { 635 std::pair<int32_t, Rdb_DistributedConfig> result = { OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, {} }; 636 auto &[errCode, cfg] = result; 637 switch (config->version) { 638 case DISTRIBUTED_CONFIG_V0: { 639 const auto *realCfg = reinterpret_cast<const DistributedConfigV0 *>(config); 640 cfg.version = realCfg->version; 641 cfg.isAutoSync = realCfg->isAutoSync; 642 errCode = OH_Rdb_ErrCode::RDB_OK; 643 break; 644 } 645 default: 646 break; 647 } 648 return result; 649 } 650 OH_Rdb_SetDistributedTables(OH_Rdb_Store * store,const char * tables[],uint32_t count,Rdb_DistributedType type,const Rdb_DistributedConfig * config)651 int OH_Rdb_SetDistributedTables(OH_Rdb_Store *store, const char *tables[], uint32_t count, Rdb_DistributedType type, 652 const Rdb_DistributedConfig *config) 653 { 654 auto rdbStore = GetRelationalStore(store); 655 if (rdbStore == nullptr || type != Rdb_DistributedType::RDB_DISTRIBUTED_CLOUD || (count > 0 && tables == nullptr)) { 656 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 657 } 658 659 auto [errCode, cfg] = Convert(config); 660 if (errCode != OH_Rdb_ErrCode::RDB_OK) { 661 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 662 } 663 std::vector<std::string> tableNames; 664 tableNames.reserve(count); 665 for (uint32_t i = 0; i < count; i++) { 666 if (tables[i] == nullptr) { 667 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 668 } 669 tableNames.emplace_back(tables[i]); 670 } 671 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->SetDistributedTables( 672 tableNames, DistributedTableType::DISTRIBUTED_CLOUD, { cfg.isAutoSync })); 673 } 674 OH_Rdb_FindModifyTime(OH_Rdb_Store * store,const char * tableName,const char * columnName,OH_VObject * values)675 OH_Cursor *OH_Rdb_FindModifyTime(OH_Rdb_Store *store, const char *tableName, const char *columnName, OH_VObject *values) 676 { 677 auto rdbStore = GetRelationalStore(store); 678 auto selfObjects = RelationalPredicatesObjects::GetSelf(values); 679 if (rdbStore == nullptr || selfObjects == nullptr || tableName == nullptr) { 680 return nullptr; 681 } 682 std::vector<ValueObject> objects = selfObjects->Get(); 683 std::vector<OHOS::NativeRdb::RdbStore::PRIKey> keys; 684 keys.reserve(objects.size()); 685 for (auto &object : objects) { 686 OHOS::NativeRdb::RdbStore::PRIKey priKey; 687 OHOS::NativeRdb::RawDataParser::Convert(std::move(object.value), priKey); 688 keys.push_back(std::move(priKey)); 689 } 690 auto results = rdbStore->GetStore()->GetModifyTime(tableName, columnName, keys); 691 return new (std::nothrow) ModifyTimeCursor(std::move(results)); 692 } 693 OH_Rdb_Subscribe(OH_Rdb_Store * store,Rdb_SubscribeType type,const Rdb_DataObserver * observer)694 int OH_Rdb_Subscribe(OH_Rdb_Store *store, Rdb_SubscribeType type, const Rdb_DataObserver *observer) 695 { 696 auto rdbStore = GetRelationalStore(store); 697 if (rdbStore == nullptr || observer == nullptr) { 698 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 699 } 700 return rdbStore->DoSubScribe(type, observer); 701 } 702 OH_Rdb_Unsubscribe(OH_Rdb_Store * store,Rdb_SubscribeType type,const Rdb_DataObserver * observer)703 int OH_Rdb_Unsubscribe(OH_Rdb_Store *store, Rdb_SubscribeType type, const Rdb_DataObserver *observer) 704 { 705 auto rdbStore = GetRelationalStore(store); 706 if (rdbStore == nullptr) { 707 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 708 } 709 return rdbStore->DoUnsubScribe(type, observer); 710 } 711 DoSubScribe(Rdb_SubscribeType type,const Rdb_DataObserver * observer)712 int RelationalStore::DoSubScribe(Rdb_SubscribeType type, const Rdb_DataObserver *observer) 713 { 714 if (store_ == nullptr || type < RDB_SUBSCRIBE_TYPE_CLOUD || type > RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS || 715 observer == nullptr || observer->callback.briefObserver == nullptr || 716 observer->callback.detailsObserver == nullptr) { 717 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 718 } 719 720 std::lock_guard<decltype(mutex_)> lock(mutex_); 721 auto result = std::any_of(dataObservers_[type].begin(), dataObservers_[type].end(), 722 [observer](const std::shared_ptr<NDKStoreObserver> &item) { 723 return *item.get() == observer; 724 }); 725 if (result) { 726 LOG_INFO("duplicate subscribe."); 727 return OH_Rdb_ErrCode::RDB_OK; 728 } 729 auto subscribeOption = SubscribeOption{ .mode = NDKUtils::GetSubscribeType(type), .event = "data_change" }; 730 auto ndkObserver = std::make_shared<NDKStoreObserver>(observer, type); 731 int subscribeResult = (type == RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS) ? 732 store_->SubscribeObserver(subscribeOption, ndkObserver) : store_->Subscribe(subscribeOption, ndkObserver.get()); 733 if (subscribeResult != OHOS::NativeRdb::E_OK) { 734 LOG_ERROR("subscribe failed."); 735 } else { 736 dataObservers_[type].emplace_back(std::move(ndkObserver)); 737 } 738 return ConvertorErrorCode::NativeToNdk(subscribeResult); 739 } 740 DoUnsubScribe(Rdb_SubscribeType type,const Rdb_DataObserver * observer)741 int RelationalStore::DoUnsubScribe(Rdb_SubscribeType type, const Rdb_DataObserver *observer) 742 { 743 if (store_ == nullptr || type < RDB_SUBSCRIBE_TYPE_CLOUD || type > RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS) { 744 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 745 } 746 std::lock_guard<decltype(mutex_)> lock(mutex_); 747 for (auto it = dataObservers_[type].begin(); it != dataObservers_[type].end();) { 748 if (observer != nullptr && !(**it == observer)) { 749 ++it; 750 continue; 751 } 752 auto subscribeOption = SubscribeOption{ .mode = NDKUtils::GetSubscribeType(type), .event = "data_change" }; 753 int errCode = (type == RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS) ? 754 store_->UnsubscribeObserver(subscribeOption, *it) : store_->UnSubscribe(subscribeOption, it->get()); 755 if (errCode != NativeRdb::E_OK) { 756 LOG_ERROR("unsubscribe failed."); 757 return ConvertorErrorCode::NativeToNdk(errCode); 758 } 759 it = dataObservers_[type].erase(it); 760 LOG_DEBUG("data observer unsubscribe success."); 761 } 762 return OH_Rdb_ErrCode::RDB_OK; 763 } 764 765 namespace { 766 struct RelationalProgressDetails : public Rdb_ProgressDetails { 767 Rdb_TableDetails *details_ = nullptr; 768 explicit RelationalProgressDetails(const ProgressDetail &detail); 769 ~RelationalProgressDetails(); 770 771 Rdb_TableDetails *GetTableDetails(int paraVersion); 772 void DestroyTableDetails(); 773 774 private: 775 uint8_t *ResizeBuff(size_t size); 776 777 TableDetails tableDetails_; 778 size_t size_ = 0; 779 uint8_t *buffer_ = nullptr; 780 }; 781 DestroyTableDetails()782 void RelationalProgressDetails::DestroyTableDetails() 783 { 784 delete[] details_; 785 details_ = nullptr; 786 } 787 RelationalProgressDetails(const ProgressDetail & detail)788 RelationalProgressDetails::RelationalProgressDetails(const ProgressDetail &detail) 789 { 790 version = DISTRIBUTED_PROGRESS_DETAIL_VERSION; 791 schedule = detail.progress; 792 code = detail.code; 793 tableLength = (int32_t)detail.details.size(); 794 tableDetails_ = detail.details; 795 } 796 ~RelationalProgressDetails()797 RelationalProgressDetails::~RelationalProgressDetails() 798 { 799 if (buffer_ != nullptr) { 800 free(buffer_); 801 } 802 buffer_ = nullptr; 803 } 804 GetTableDetails(int paraVersion)805 Rdb_TableDetails *RelationalProgressDetails::GetTableDetails(int paraVersion) 806 { 807 switch (paraVersion) { 808 case TABLE_DETAIL_V0: { 809 auto length = sizeof(TableDetailsV0) * (tableLength + 1); 810 auto *detailsV0 = (TableDetailsV0 *)ResizeBuff(length); 811 if (detailsV0 == nullptr) { 812 return nullptr; 813 } 814 (void)memset_s(detailsV0, length, 0, length); 815 int index = 0; 816 for (const auto &pair : tableDetails_) { 817 detailsV0[index].table = pair.first.c_str(); 818 detailsV0[index].upload = StatisticV0{ 819 .total = (int)pair.second.upload.total, 820 .successful = (int)pair.second.upload.success, 821 .failed = (int)pair.second.upload.failed, 822 .remained = (int)pair.second.upload.untreated, 823 }; 824 detailsV0[index].download = StatisticV0{ 825 .total = (int)pair.second.download.total, 826 .successful = (int)pair.second.download.success, 827 .failed = (int)pair.second.download.failed, 828 .remained = (int)pair.second.download.untreated, 829 }; 830 index++; 831 } 832 return reinterpret_cast<Rdb_TableDetails *>(reinterpret_cast<uint8_t *>(detailsV0)); 833 } 834 default: 835 return nullptr; 836 } 837 } 838 ResizeBuff(size_t size)839 uint8_t *RelationalProgressDetails::ResizeBuff(size_t size) 840 { 841 if (size_ >= size) { 842 return buffer_; 843 } 844 if (buffer_ != nullptr) { 845 free(buffer_); 846 } 847 buffer_ = (uint8_t *)malloc(size); 848 return buffer_; 849 } 850 } // namespace 851 GetDetails(Rdb_ProgressDetails * progress)852 static std::pair<int, RelationalProgressDetails *> GetDetails(Rdb_ProgressDetails *progress) 853 { 854 if (progress->version != DISTRIBUTED_PROGRESS_DETAIL_VERSION) { 855 return { -1, nullptr }; 856 } 857 return { 0, (RelationalProgressDetails *)progress }; 858 } 859 OH_Rdb_GetTableDetails(Rdb_ProgressDetails * progress,int32_t version)860 Rdb_TableDetails *OH_Rdb_GetTableDetails(Rdb_ProgressDetails *progress, int32_t version) 861 { 862 auto [errCode, details] = GetDetails(progress); 863 if (errCode == -1 || details == nullptr) { 864 return nullptr; 865 } 866 return details->GetTableDetails(version); 867 } 868 OH_Rdb_CloudSync(OH_Rdb_Store * store,Rdb_SyncMode mode,const char * tables[],uint32_t count,const Rdb_ProgressObserver * observer)869 int OH_Rdb_CloudSync( 870 OH_Rdb_Store *store, Rdb_SyncMode mode, const char *tables[], uint32_t count, const Rdb_ProgressObserver *observer) 871 { 872 auto rdbStore = GetRelationalStore(store); 873 if (rdbStore == nullptr || mode < RDB_SYNC_MODE_TIME_FIRST || mode > RDB_SYNC_MODE_CLOUD_FIRST || 874 observer == nullptr || observer->callback == nullptr || (count > 0 && tables == nullptr)) { 875 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 876 } 877 SyncOption syncOption{ .mode = NDKUtils::TransformMode(mode), .isBlock = false }; 878 std::vector<std::string> tableNames; 879 for (uint32_t i = 0; i < count; ++i) { 880 if (tables[i] == nullptr) { 881 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 882 } 883 tableNames.emplace_back(tables[i]); 884 } 885 886 auto progressCallback = [cxt = (*observer).context, cb = (*observer).callback](Details &&details) { 887 if (details.size() > 1) { 888 LOG_ERROR("Not support edge to edge detail notify."); 889 return; 890 } 891 if (details.empty()) { 892 LOG_ERROR("No device or cloud synced."); 893 return; 894 } 895 for (auto &[device, detail] : details) { 896 RelationalProgressDetails cloudDetail(detail); 897 cb(cxt, &cloudDetail); 898 break; 899 } 900 }; 901 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Sync(syncOption, tableNames, progressCallback)); 902 } 903 OH_Rdb_SubscribeAutoSyncProgress(OH_Rdb_Store * store,const Rdb_ProgressObserver * callback)904 int OH_Rdb_SubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressObserver *callback) 905 { 906 auto rdbStore = GetRelationalStore(store); 907 if (rdbStore == nullptr || callback == nullptr) { 908 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 909 } 910 return ConvertorErrorCode::NativeToNdk(rdbStore->SubscribeAutoSyncProgress(callback)); 911 } 912 OH_Rdb_UnsubscribeAutoSyncProgress(OH_Rdb_Store * store,const Rdb_ProgressObserver * callback)913 int OH_Rdb_UnsubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressObserver *callback) 914 { 915 auto rdbStore = GetRelationalStore(store); 916 if (rdbStore == nullptr) { 917 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 918 } 919 return ConvertorErrorCode::NativeToNdk(rdbStore->UnsubscribeAutoSyncProgress(callback)); 920 } 921 OH_Rdb_LockRow(OH_Rdb_Store * store,OH_Predicates * predicates)922 int OH_Rdb_LockRow(OH_Rdb_Store *store, OH_Predicates *predicates) 923 { 924 auto rdbStore = GetRelationalStore(store); 925 auto predicate = RelationalPredicate::GetSelf(predicates); 926 if (rdbStore == nullptr || predicate == nullptr) { 927 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 928 } 929 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->ModifyLockStatus(predicate->Get(), true)); 930 } 931 OH_Rdb_UnlockRow(OH_Rdb_Store * store,OH_Predicates * predicates)932 int OH_Rdb_UnlockRow(OH_Rdb_Store *store, OH_Predicates *predicates) 933 { 934 auto rdbStore = GetRelationalStore(store); 935 auto predicate = RelationalPredicate::GetSelf(predicates); 936 if (rdbStore == nullptr || predicate == nullptr) { 937 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; 938 } 939 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->ModifyLockStatus(predicate->Get(), false)); 940 } 941 OH_Rdb_QueryLockedRow(OH_Rdb_Store * store,OH_Predicates * predicates,const char * const * columnNames,int length)942 OH_Cursor *OH_Rdb_QueryLockedRow( 943 OH_Rdb_Store *store, OH_Predicates *predicates, const char *const *columnNames, int length) 944 { 945 auto rdbStore = GetRelationalStore(store); 946 auto predicate = RelationalPredicate::GetSelf(predicates); 947 if (rdbStore == nullptr || predicate == nullptr) { 948 LOG_ERROR("rdbStore or predicate is nullptr."); 949 return nullptr; 950 } 951 std::vector<std::string> columns; 952 if (columnNames != nullptr && length > 0) { 953 columns.reserve(length); 954 for (int i = 0; i < length; i++) { 955 columns.push_back(columnNames[i]); 956 } 957 } 958 predicate->Get().BeginWrap(); 959 predicate->Get().EqualTo(OHOS::NativeRdb::AbsRdbPredicates::LOCK_STATUS, OHOS::NativeRdb::AbsRdbPredicates::LOCKED); 960 predicate->Get().Or(); 961 predicate->Get().EqualTo( 962 OHOS::NativeRdb::AbsRdbPredicates::LOCK_STATUS, OHOS::NativeRdb::AbsRdbPredicates::LOCK_CHANGED); 963 predicate->Get().EndWrap(); 964 std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet = 965 rdbStore->GetStore()->QueryByStep(predicate->Get(), columns); 966 if (resultSet == nullptr) { 967 return nullptr; 968 } 969 return new OHOS::RdbNdk::RelationalCursor(std::move(resultSet)); 970 } 971 NDKDetailProgressObserver(const Rdb_ProgressObserver * callback)972 NDKDetailProgressObserver::NDKDetailProgressObserver(const Rdb_ProgressObserver *callback) : callback_(callback) 973 { 974 } 975 ProgressNotification(const Details & details)976 void NDKDetailProgressObserver::ProgressNotification(const Details &details) 977 { 978 if (callback_ == nullptr || details.empty()) { 979 return; 980 } 981 RelationalProgressDetails progressDetails = RelationalProgressDetails(details.begin()->second); 982 (*(callback_->callback))(callback_->context, &progressDetails); 983 progressDetails.DestroyTableDetails(); 984 } 985 operator ==(const Rdb_ProgressObserver * callback)986 bool NDKDetailProgressObserver::operator==(const Rdb_ProgressObserver *callback) 987 { 988 return callback == callback_; 989 } 990 NDKStoreObserver(const Rdb_DataObserver * observer,int mode)991 NDKStoreObserver::NDKStoreObserver(const Rdb_DataObserver *observer, int mode) : mode_(mode), observer_(observer) 992 { 993 } 994 OnChange(const std::vector<std::string> & devices)995 void NDKStoreObserver::OnChange(const std::vector<std::string> &devices) 996 { 997 if (mode_ == Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD) { 998 auto count = devices.size(); 999 std::unique_ptr<const char *[]> deviceIds = std::make_unique<const char *[]>(count); 1000 for (uint32_t i = 0; i < count; ++i) { 1001 deviceIds[i] = devices[i].c_str(); 1002 } 1003 (*observer_->callback.briefObserver)(observer_->context, deviceIds.get(), count); 1004 } 1005 } 1006 GetKeyInfoSize(RdbStoreObserver::ChangeInfo && changeInfo)1007 size_t NDKStoreObserver::GetKeyInfoSize(RdbStoreObserver::ChangeInfo &&changeInfo) 1008 { 1009 size_t size = 0; 1010 for (auto it = changeInfo.begin(); it != changeInfo.end(); ++it) { 1011 size += it->second[RdbStoreObserver::CHG_TYPE_INSERT].size() * sizeof(Rdb_KeyInfo::Rdb_KeyData); 1012 size += it->second[RdbStoreObserver::CHG_TYPE_UPDATE].size() * sizeof(Rdb_KeyInfo::Rdb_KeyData); 1013 size += it->second[RdbStoreObserver::CHG_TYPE_DELETE].size() * sizeof(Rdb_KeyInfo::Rdb_KeyData); 1014 } 1015 return size; 1016 } 1017 GetKeyDataType(std::vector<RdbStoreObserver::PrimaryKey> & primaryKey)1018 int32_t NDKStoreObserver::GetKeyDataType(std::vector<RdbStoreObserver::PrimaryKey> &primaryKey) 1019 { 1020 if (primaryKey.size() == 0) { 1021 return OH_ColumnType::TYPE_NULL; 1022 } 1023 if (std::holds_alternative<int64_t>(primaryKey[0]) || std::holds_alternative<double>(primaryKey[0])) { 1024 return OH_ColumnType::TYPE_INT64; 1025 } 1026 if (std::holds_alternative<std::string>(primaryKey[0])) { 1027 return OH_ColumnType::TYPE_TEXT; 1028 } 1029 return OH_ColumnType::TYPE_NULL; 1030 } 1031 OnChange(const Origin & origin,const RdbStoreObserver::PrimaryFields & fields,RdbStoreObserver::ChangeInfo && changeInfo)1032 void NDKStoreObserver::OnChange( 1033 const Origin &origin, const RdbStoreObserver::PrimaryFields &fields, RdbStoreObserver::ChangeInfo &&changeInfo) 1034 { 1035 uint32_t count = changeInfo.size(); 1036 if (count == 0) { 1037 LOG_ERROR("No any infos."); 1038 return; 1039 } 1040 1041 if (mode_ == Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD_DETAILS || 1042 mode_ == Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS) { 1043 size_t size = count * (sizeof(Rdb_ChangeInfo *) + sizeof(Rdb_ChangeInfo)) + 1044 GetKeyInfoSize(std::forward<RdbStoreObserver::ChangeInfo &&>(changeInfo)); 1045 std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size); 1046 Rdb_ChangeInfo **infos = (Rdb_ChangeInfo **)(buffer.get()); 1047 if (infos == nullptr) { 1048 LOG_ERROR("Failed to allocate memory for Rdb_ChangeInfo."); 1049 return; 1050 } 1051 1052 Rdb_ChangeInfo *details = (Rdb_ChangeInfo *)(infos + count); 1053 Rdb_KeyInfo::Rdb_KeyData *data = (Rdb_KeyInfo::Rdb_KeyData *)(details + count); 1054 1055 int index = 0; 1056 for (auto it = changeInfo.begin(); it != changeInfo.end(); ++it) { 1057 infos[index] = &details[index]; 1058 infos[index]->version = DISTRIBUTED_CHANGE_INFO_VERSION; 1059 infos[index]->tableName = it->first.c_str(); 1060 infos[index]->ChangeType = origin.dataType; 1061 infos[index]->inserted.count = static_cast<int>(it->second[RdbStoreObserver::CHG_TYPE_INSERT].size()); 1062 infos[index]->inserted.type = GetKeyDataType(it->second[RdbStoreObserver::CHG_TYPE_INSERT]); 1063 infos[index]->updated.count = static_cast<int>(it->second[RdbStoreObserver::CHG_TYPE_UPDATE].size()); 1064 infos[index]->updated.type = GetKeyDataType(it->second[RdbStoreObserver::CHG_TYPE_UPDATE]); 1065 infos[index]->deleted.count = static_cast<int>(it->second[RdbStoreObserver::CHG_TYPE_DELETE].size()); 1066 infos[index]->deleted.type = GetKeyDataType(it->second[RdbStoreObserver::CHG_TYPE_DELETE]); 1067 ConvertKeyInfoData(data, it->second[RdbStoreObserver::CHG_TYPE_INSERT]); 1068 infos[index]->inserted.data = data; 1069 ConvertKeyInfoData(data + infos[index]->inserted.count, it->second[RdbStoreObserver::CHG_TYPE_UPDATE]); 1070 infos[index]->updated.data = data + infos[index]->inserted.count; 1071 ConvertKeyInfoData(data + infos[index]->inserted.count + infos[index]->updated.count, 1072 it->second[RdbStoreObserver::CHG_TYPE_DELETE]); 1073 infos[index]->deleted.data = data + infos[index]->inserted.count + infos[index]->updated.count; 1074 index++; 1075 } 1076 1077 (*observer_->callback.detailsObserver)(observer_->context, const_cast<const Rdb_ChangeInfo **>(infos), count); 1078 } 1079 } 1080 OnChange()1081 void NDKStoreObserver::OnChange() 1082 { 1083 RdbStoreObserver::OnChange(); 1084 } 1085 ConvertKeyInfoData(Rdb_KeyInfo::Rdb_KeyData * keyInfoData,std::vector<RdbStoreObserver::PrimaryKey> & primaryKey)1086 void NDKStoreObserver::ConvertKeyInfoData( 1087 Rdb_KeyInfo::Rdb_KeyData *keyInfoData, std::vector<RdbStoreObserver::PrimaryKey> &primaryKey) 1088 { 1089 if (keyInfoData == nullptr || primaryKey.empty()) { 1090 LOG_WARN("no data, keyInfoData is nullptr:%{public}d", keyInfoData == nullptr); 1091 return; 1092 } 1093 1094 for (size_t i = 0; i < primaryKey.size(); ++i) { 1095 const auto &key = primaryKey[i]; 1096 if (auto val = std::get_if<double>(&key)) { 1097 keyInfoData[i].real = *val; 1098 } else if (auto val = std::get_if<int64_t>(&key)) { 1099 keyInfoData[i].integer = *val; 1100 } else if (auto val = std::get_if<std::string>(&key)) { 1101 keyInfoData[i].text = val->c_str(); 1102 } else { 1103 LOG_ERROR("Not support the data type."); 1104 return; 1105 } 1106 } 1107 } 1108 operator ==(const Rdb_DataObserver * other)1109 bool NDKStoreObserver::operator==(const Rdb_DataObserver *other) 1110 { 1111 if (other == nullptr) { 1112 return false; 1113 } 1114 return other->context == observer_->context && &(other->callback) == &(observer_->callback); 1115 }