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 }