1 /*
2 * Copyright (c) 2025 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 #include <gtest/gtest.h>
16 #include <unistd.h>
17
18 #include <memory>
19 #include <string>
20 #include <thread>
21
22 #include "common.h"
23 #include "block_data.h"
24 #include "rdb_errno.h"
25 #include "rdb_helper.h"
26 #include "rdb_open_callback.h"
27 #include "rdb_sql_log.h"
28 #include "rdb_store.h"
29 #include "rdb_store_manager.h"
30 #include "rdb_types.h"
31 #include "executor_pool.h"
32 #include "shared_block.h"
33 #include "sqlite_utils.h"
34 #include "values_bucket.h"
35
36 using namespace testing::ext;
37 using namespace OHOS::NativeRdb;
38 using namespace OHOS::DistributedRdb;
39
40 static constexpr int32_t MAX_THREAD = 8;
41 static constexpr int32_t MID_THREAD = 4;
42 static constexpr int32_t SLEEP_TIME = 500;
43 static constexpr int32_t MAX_SLEEP_TIME = 2000;
44 static constexpr int32_t JOURNAL_MAX_SIZE = 4096;
45 static constexpr int32_t JOURNAL_MIN_SIZE = 1024;
46 static constexpr double DEFAULT_SALARY = 100.5;
47 static constexpr int32_t AGE_NUM = 18;
48
49 class RdbStoreStoreMultiTest : public testing::Test {
50 public:
51 static void SetUpTestCase(void);
52 static void TearDownTestCase(void);
53 void SetUp();
54 void TearDown();
55
56 static std::shared_ptr<RdbStore> CreateRDB(const std::string &path,
57 bool encrypt = false, const std::string &bundleName = "");
58 static std::shared_ptr<RdbStore> CreateRDBSleep(const std::string &path,
59 bool encrypt = false, const std::string &bundleName = "");
60 static void InsertData(std::shared_ptr<RdbStore> rdbStore);
61 static void QueryData(std::shared_ptr<RdbStore> rdbStore);
62 };
63
64
SetUpTestCase(void)65 void RdbStoreStoreMultiTest::SetUpTestCase(void)
66 {
67 }
68
TearDownTestCase(void)69 void RdbStoreStoreMultiTest::TearDownTestCase(void)
70 {
71 }
72
SetUp()73 void RdbStoreStoreMultiTest::SetUp()
74 {
75 }
76
TearDown()77 void RdbStoreStoreMultiTest::TearDown()
78 {
79 }
80
81 class RDBCallback : public RdbOpenCallback {
82 public:
83 int OnCreate(RdbStore &store) override;
84 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
85 };
86
OnCreate(RdbStore & store)87 int RDBCallback::OnCreate(RdbStore &store)
88 {
89 return E_OK;
90 }
91
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)92 int RDBCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
93 {
94 return E_OK;
95 }
96
97 class CallbackSleep : public RdbOpenCallback {
98 public:
99 int OnCreate(RdbStore &store) override;
100 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
101 };
102
OnCreate(RdbStore & store)103 int CallbackSleep::OnCreate(RdbStore &store)
104 {
105 std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
106 return E_OK;
107 }
108
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)109 int CallbackSleep::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
110 {
111 std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
112 return E_OK;
113 }
114
CreateRDB(const std::string & path,bool encrypt,const std::string & bundleName)115 std::shared_ptr<RdbStore> RdbStoreStoreMultiTest::CreateRDB(const std::string &path,
116 bool encrypt, const std::string &bundleName)
117 {
118 int version = 1;
119 RdbStoreConfig config(path);
120 config.SetEncryptStatus(encrypt);
121 config.SetBundleName(bundleName);
122 RDBCallback helper;
123 int errCode = E_OK;
124 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, version, helper, errCode);
125 EXPECT_NE(store, nullptr);
126 return store;
127 }
128
CreateRDBSleep(const std::string & path,bool encrypt,const std::string & bundleName)129 std::shared_ptr<RdbStore> RdbStoreStoreMultiTest::CreateRDBSleep(const std::string &path,
130 bool encrypt, const std::string &bundleName)
131 {
132 int version = 1;
133 RdbStoreConfig config(path);
134 config.SetEncryptStatus(encrypt);
135 config.SetBundleName(bundleName);
136 CallbackSleep helper;
137 int errCode = E_OK;
138 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, version, helper, errCode);
139 EXPECT_NE(store, nullptr);
140 return store;
141 }
142
InsertData(std::shared_ptr<RdbStore> rdbStore)143 void RdbStoreStoreMultiTest::InsertData(std::shared_ptr<RdbStore> rdbStore)
144 {
145 const std::string createTable =
146 std::string("CREATE TABLE IF NOT EXISTS test ") + std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT, "
147 "name TEXT NOT NULL, age INTEGER, salary "
148 "REAL, blobType BLOB)");
149 rdbStore->Execute(createTable);
150 int64_t id;
151 ValuesBucket values;
152
153 values.PutInt("id", 1);
154 values.PutString("name", std::string("zhangsan"));
155 values.PutInt("age", AGE_NUM);
156 values.PutDouble("salary", DEFAULT_SALARY);
157 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
158 int ret = rdbStore->Insert(id, "test", values);
159 EXPECT_EQ(ret, E_OK);
160 EXPECT_EQ(1, id);
161 }
162
QueryData(std::shared_ptr<RdbStore> rdbStore)163 void RdbStoreStoreMultiTest::QueryData(std::shared_ptr<RdbStore> rdbStore)
164 {
165 std::shared_ptr<ResultSet> resultSet = rdbStore->QuerySql("select * from test");
166 int ret = resultSet->GoToNextRow();
167 EXPECT_EQ(ret, E_OK);
168 int columnIndex;
169 std::string strVal;
170
171 ret = resultSet->GetColumnIndex("name", columnIndex);
172 EXPECT_EQ(ret, E_OK);
173 ret = resultSet->GetString(columnIndex, strVal);
174 EXPECT_EQ(ret, E_OK);
175 EXPECT_EQ("zhangsan", strVal);
176 }
177
178 std::string g_dbPaths[MAX_THREAD] = { "/data/test/store1.db", "/data/test/store2.db",
179 "/data/test/store3.db", "/data/test/store4.db", "/data/test/store5.db",
180 "/data/test/store6.db", "/data/test/store7.db", "/data/test/store8.db" };
181
182 std::string g_dbBundlenames[MAX_THREAD] = { "com.ohos.test1", "com.ohos.test2",
183 "com.ohos.test3", "com.ohos.test4", "com.ohos.test5",
184 "com.ohos.test6", "com.ohos.test7", "com.ohos.test8" };
185
186 /**
187 * @tc.name: GetRdbStoreTest_001
188 * @tc.desc: test Multithreading calls GetRdbStore with same store
189 * @tc.type: FUNC
190 * @tc.require:
191 * @tc.author:
192 */
193 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_001, TestSize.Level1)
194 {
195 std::string path = "/data/test/store.db";
196 std::shared_ptr<RdbStore> stores[MAX_THREAD];
197 std::thread threads[MAX_THREAD];
198 for (int i = 0; i < MAX_THREAD; ++i) {
__anon2ff4e1870102() 199 threads[i] = std::thread([i, &stores, &path]() {
200 stores[i] = RdbStoreStoreMultiTest::CreateRDB(path);
201 });
202 }
203 for (auto& t : threads) {
204 if (t.joinable()) {
205 t.join();
206 }
207 }
208 EXPECT_EQ(stores[0], stores[1]);
209 EXPECT_EQ(stores[1], stores[2]);
210 EXPECT_EQ(stores[2], stores[3]);
211 EXPECT_EQ(stores[3], stores[4]);
212 EXPECT_EQ(stores[4], stores[5]);
213 EXPECT_EQ(stores[5], stores[6]);
214 EXPECT_EQ(stores[6], stores[7]);
215 RdbHelper::DeleteRdbStore(path);
216 }
217
218 /**
219 * @tc.name: GetRdbStoreTest_002
220 * @tc.desc: test Multithreading calls GetRdbStore with same encrypt store
221 * @tc.type: FUNC
222 * @tc.require:
223 * @tc.author:
224 */
225 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_002, TestSize.Level1)
226 {
227 std::string path = "/data/test/encryptStore.db";
228 std::string bundleName = "com.ohos.test";
229 std::shared_ptr<RdbStore> stores[MAX_THREAD];
230 std::thread threads[MAX_THREAD];
231 for (int i = 0; i < MAX_THREAD; ++i) {
__anon2ff4e1870202() 232 threads[i] = std::thread([i, &stores, &path, &bundleName]() {
233 stores[i] = RdbStoreStoreMultiTest::CreateRDB(path, true, bundleName);
234 });
235 }
236 for (auto& t : threads) {
237 if (t.joinable()) {
238 t.join();
239 }
240 }
241
242 EXPECT_EQ(stores[0], stores[1]);
243 EXPECT_EQ(stores[1], stores[2]);
244 EXPECT_EQ(stores[2], stores[3]);
245 EXPECT_EQ(stores[3], stores[4]);
246 EXPECT_EQ(stores[4], stores[5]);
247 EXPECT_EQ(stores[5], stores[6]);
248 EXPECT_EQ(stores[6], stores[7]);
249 RdbHelper::DeleteRdbStore(path);
250 }
251
252 /**
253 * @tc.name: GetRdbStoreTest_003
254 * @tc.desc: test Multithreading calls GetRdbStore with diff store
255 * @tc.type: FUNC
256 * @tc.require:
257 * @tc.author:
258 */
259 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_003, TestSize.Level1)
260 {
261 std::shared_ptr<RdbStore> stores[MAX_THREAD];
262 std::thread threads[MAX_THREAD];
263 for (int i = 0; i < MID_THREAD; ++i) {
__anon2ff4e1870302() 264 threads[i] = std::thread([i, &stores]() {
265 stores[i] = RdbStoreStoreMultiTest::CreateRDB(g_dbPaths[i]);
266 });
267 }
268 for (int i = MID_THREAD; i < MAX_THREAD; ++i) {
__anon2ff4e1870402() 269 threads[i] = std::thread([i, &stores]() {
270 stores[i] = RdbStoreStoreMultiTest::CreateRDBSleep(g_dbPaths[i]);
271 });
272 }
273 for (int i = 0; i < MAX_THREAD; ++i) {
274 if (threads[i].joinable()) {
275 threads[i].join();
276 }
277 EXPECT_NE(stores[i], nullptr);
278 }
279 std::this_thread::sleep_for(std::chrono::milliseconds(MAX_SLEEP_TIME));
280 for (int i = 0; i < MAX_THREAD; ++i) {
281 RdbHelper::DeleteRdbStore(g_dbPaths[i]);
282 }
283 }
284
285 /**
286 * @tc.name: GetRdbStoreTest_004
287 * @tc.desc: test Multithreading calls GetRdbStore with diff encrypt store
288 * @tc.type: FUNC
289 * @tc.require:
290 * @tc.author:
291 */
292 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_004, TestSize.Level1)
293 {
294 std::string bundleName = "com.ohos.test";
295 std::shared_ptr<RdbStore> stores[MAX_THREAD];
296 std::thread threads[MAX_THREAD];
297 for (int i = 0; i < MID_THREAD; ++i) {
__anon2ff4e1870502() 298 threads[i] = std::thread([i, &stores, &bundleName]() {
299 stores[i] = RdbStoreStoreMultiTest::CreateRDB(g_dbPaths[i], true, bundleName);
300 });
301 }
302 for (int i = MID_THREAD; i < MAX_THREAD; ++i) {
__anon2ff4e1870602() 303 threads[i] = std::thread([i, &stores, &bundleName]() {
304 stores[i] = RdbStoreStoreMultiTest::CreateRDBSleep(g_dbPaths[i], true, bundleName);
305 });
306 }
307 for (int i = 0; i < MAX_THREAD; ++i) {
308 if (threads[i].joinable()) {
309 threads[i].join();
310 }
311 EXPECT_NE(stores[i], nullptr);
312 }
313 std::this_thread::sleep_for(std::chrono::milliseconds(MAX_SLEEP_TIME));
314 for (int i = 0; i < MAX_THREAD; ++i) {
315 RdbHelper::DeleteRdbStore(g_dbPaths[i]);
316 }
317 }
318
319 /**
320 * @tc.name: GetRdbStoreTest_005
321 * @tc.desc: test Multithreading calls GetRdbStore with diff encrypt store and store
322 * @tc.type: FUNC
323 * @tc.require:
324 * @tc.author:
325 */
326 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_005, TestSize.Level1)
327 {
328 std::string bundleName = "com.ohos.test";
329 std::shared_ptr<RdbStore> stores[MAX_THREAD];
330 std::thread threads[MAX_THREAD];
331 for (int i = 0; i < MID_THREAD; ++i) {
__anon2ff4e1870702() 332 threads[i] = std::thread([i, &stores, &bundleName]() {
333 stores[i] = RdbStoreStoreMultiTest::CreateRDB(g_dbPaths[i]);
334 });
335 }
336 for (int i = MID_THREAD; i < MAX_THREAD; ++i) {
__anon2ff4e1870802() 337 threads[i] = std::thread([i, &stores, &bundleName]() {
338 stores[i] = RdbStoreStoreMultiTest::CreateRDBSleep(g_dbPaths[i], true, bundleName);
339 });
340 }
341 for (int i = 0; i < MAX_THREAD; ++i) {
342 if (threads[i].joinable()) {
343 threads[i].join();
344 }
345 EXPECT_NE(stores[i], nullptr);
346 }
347 std::this_thread::sleep_for(std::chrono::milliseconds(MAX_SLEEP_TIME));
348 for (int i = 0; i < MAX_THREAD; ++i) {
349 RdbHelper::DeleteRdbStore(g_dbPaths[i]);
350 }
351 }
352
353 /**
354 * @tc.name: GetRdbStoreTest_006
355 * @tc.desc: test Multithreading calls GetRdbStore with diff encrypt store with diff bundlename
356 * @tc.type: FUNC
357 * @tc.require:
358 * @tc.author:
359 */
360 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_006, TestSize.Level1)
361 {
362 std::shared_ptr<RdbStore> stores[MAX_THREAD];
363 std::thread threads[MAX_THREAD];
364 for (int i = 0; i < MAX_THREAD; ++i) {
__anon2ff4e1870902() 365 threads[i] = std::thread([i, &stores]() {
366 stores[i] = RdbStoreStoreMultiTest::CreateRDB(g_dbPaths[i], true, g_dbBundlenames[i]);
367 });
368 }
369 for (int i = 0; i < MAX_THREAD; ++i) {
370 if (threads[i].joinable()) {
371 threads[i].join();
372 }
373 EXPECT_NE(stores[i], nullptr);
374 }
375 std::this_thread::sleep_for(std::chrono::milliseconds(MAX_SLEEP_TIME));
376 for (int i = 0; i < MAX_THREAD; ++i) {
377 RdbHelper::DeleteRdbStore(g_dbPaths[i]);
378 }
379 }
380
381 /**
382 * @tc.name: GetRdbStoreTest_007
383 * @tc.desc: test Multithreading calls GetRdbStore with diff config
384 * @tc.type: FUNC
385 * @tc.require:
386 * @tc.author:
387 */
388 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_007, TestSize.Level1)
389 {
390 std::string path = "/data/test/encrypt07store.db";
391 int version = 1;
392 RdbStoreConfig configA(path);
393 configA.SetEncryptStatus(true);
394 configA.SetBundleName("com.ohos.test");
395 RDBCallback helper;
396 int errCode = E_OK;
397 std::shared_ptr<RdbStore> storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
398 EXPECT_NE(storeA, nullptr);
399 RdbStoreStoreMultiTest::InsertData(storeA);
400 storeA = nullptr;
401
402 RdbStoreConfig configB(path);
403 configB.SetEncryptStatus(false);
404 configB.SetBundleName("com.ohos.test");
405 std::shared_ptr<RdbStore> storeB = RdbHelper::GetRdbStore(configB, version, helper, errCode);
406 EXPECT_NE(storeB, nullptr);
407 RdbStoreStoreMultiTest::QueryData(storeB);
408
409 RdbHelper::DeleteRdbStore(path);
410 }
411
412 /**
413 * @tc.name: GetRdbStoreTest_008
414 * @tc.desc: test Multithreading calls GetRdbStore with diff config
415 * @tc.type: FUNC
416 * @tc.require:
417 * @tc.author:
418 */
419 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_008, TestSize.Level1)
420 {
421 std::string path = "/data/test/store.db";
422 int version = 1;
423 RdbStoreConfig configA(path);
424 configA.SetJournalSize(JOURNAL_MAX_SIZE);
425 configA.SetBundleName("com.ohos.test");
426 RDBCallback helper;
427 int errCode = E_OK;
428 std::shared_ptr<RdbStore> storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
429 EXPECT_NE(storeA, nullptr);
430
431 RdbStoreConfig configB(path);
432 configB.SetBundleName("com.ohos.test");
433 configB.SetJournalSize(JOURNAL_MIN_SIZE);
434 std::shared_ptr<RdbStore> storeB = RdbHelper::GetRdbStore(configB, version, helper, errCode);
435 EXPECT_NE(storeB, nullptr);
436 EXPECT_NE(storeA, storeB);
437
438 std::shared_ptr<RdbStore> storeC = RdbHelper::GetRdbStore(configB, version, helper, errCode);
439 EXPECT_EQ(storeB, storeC);
440 RdbHelper::DeleteRdbStore(path);
441 }
442
443 /**
444 * @tc.name: GetRdbStoreTest_009
445 * @tc.desc: test Multithreading calls GetRdbStore with diff config and allowRebuild
446 * @tc.type: FUNC
447 * @tc.require:
448 * @tc.author:
449 */
450 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_009, TestSize.Level1)
451 {
452 std::string path = "/data/test/encrypt09store.db";
453 int version = 1;
454 RdbStoreConfig configA(path);
455 configA.SetEncryptStatus(false);
456 configA.SetAllowRebuild(true);
457 configA.SetBundleName("com.ohos.test");
458 RDBCallback helper;
459 int errCode = E_OK;
460 std::shared_ptr<RdbStore> storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
461 ASSERT_NE(storeA, nullptr);
462 RdbStoreStoreMultiTest::InsertData(storeA);
463 storeA = nullptr;
464
465 RdbStoreConfig configB(path);
466 configB.SetEncryptStatus(true);
467 configB.SetAllowRebuild(true);
468 configB.SetBundleName("com.ohos.test");
469 std::shared_ptr<RdbStore> storeB = RdbHelper::GetRdbStore(configB, version, helper, errCode);
470 ASSERT_NE(storeB, nullptr);
471 auto rebuilt = RebuiltType::NONE;
472 storeB->GetRebuilt(rebuilt);
473 EXPECT_EQ(rebuilt, RebuiltType::NONE);
474 RdbStoreStoreMultiTest::QueryData(storeB);
475
476 RdbHelper::DeleteRdbStore(path);
477 }
478
479 /**
480 * @tc.name: GetRdbStoreTest_010
481 * @tc.desc: 1. Create encrypted and non-encrypted databases
482 * 2. Insert a piece of data into a non-encrypted database
483 * 3. Delete encrypted database
484 * 4. Rename the non-encrypted database as an encrypted database
485 * 5. Open with non-encrypted parameters to query data
486 * @tc.type: FUNC
487 * @tc.require:
488 * @tc.author:
489 */
490 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_010, TestSize.Level1)
491 {
492 std::string path1 = "/data/test/encrypt10store.db";
493 std::string path1Wal = "/data/test/encrypt10store.db-wal";
494 std::string path1Shm = "/data/test/encrypt10store.db-shm";
495 std::string path2 = "/data/test/10store.db";
496 std::string path2Wal = "/data/test/10store.db-wal";
497 std::string path2Shm = "/data/test/10store.db-shm";
498 int version = 1;
499 RdbStoreConfig configA(path1);
500 configA.SetEncryptStatus(true);
501 configA.SetAllowRebuild(true);
502 configA.SetBundleName("com.ohos.test");
503 RDBCallback helper;
504 int errCode = E_OK;
505 std::shared_ptr<RdbStore> storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
506 ASSERT_NE(storeA, nullptr);
507 storeA = nullptr;
508
509 RdbStoreConfig configB(path2);
510 configB.SetEncryptStatus(false);
511 configB.SetAllowRebuild(true);
512 configB.SetBundleName("com.ohos.test");
513 std::shared_ptr<RdbStore> storeB = RdbHelper::GetRdbStore(configB, version, helper, errCode);
514 ASSERT_NE(storeB, nullptr);
515 RdbStoreStoreMultiTest::InsertData(storeB);
516 storeB = nullptr;
517 // Delete the encrypted database path1, rename the database path2 to path1.
518 SqliteUtils::DeleteFile(path1);
519 SqliteUtils::DeleteFile(path1Wal);
520 SqliteUtils::DeleteFile(path1Shm);
521 SqliteUtils::RenameFile(path2, path1);
522 SqliteUtils::RenameFile(path2Wal, path1Wal);
523 SqliteUtils::RenameFile(path2Shm, path1Shm);
524 // The current database of path1 is actually a non-encrypted database,
525 // and the data content is the original data content of path2.
526 configA.SetEncryptStatus(false);
527 storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
528 ASSERT_NE(storeA, nullptr);
529 RdbStoreStoreMultiTest::QueryData(storeA);
530 storeA = nullptr;
531
532 RdbHelper::DeleteRdbStore(path1);
533 }
534
535 /**
536 * @tc.name: GetRdbStoreTest_011
537 * @tc.desc: 1. Create encrypted and non-encrypted databases
538 * 2. Insert a piece of data into a non-encrypted database
539 * 3. Delete encrypted database
540 * 4. Rename the non-encrypted database as an encrypted database
541 * 5. Open with encrypted parameters to query data
542 * @tc.type: FUNC
543 * @tc.require:
544 * @tc.author:
545 */
546 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_011, TestSize.Level1)
547 {
548 std::string path1 = "/data/test/encrypt11store.db";
549 std::string path1Wal = "/data/test/encrypt11store.db-wal";
550 std::string path1Shm = "/data/test/encrypt11store.db-shm";
551 std::string path2 = "/data/test/11store.db";
552 std::string path2Wal = "/data/test/11store.db-wal";
553 std::string path2Shm = "/data/test/11store.db-shm";
554 int version = 1;
555 RdbStoreConfig configA(path1);
556 configA.SetEncryptStatus(true);
557 configA.SetAllowRebuild(true);
558 configA.SetBundleName("com.ohos.test");
559 RDBCallback helper;
560 int errCode = E_OK;
561 std::shared_ptr<RdbStore> storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
562 ASSERT_NE(storeA, nullptr);
563 storeA = nullptr;
564
565 RdbStoreConfig configB(path2);
566 configB.SetEncryptStatus(false);
567 configB.SetAllowRebuild(true);
568 configB.SetBundleName("com.ohos.test");
569 std::shared_ptr<RdbStore> storeB = RdbHelper::GetRdbStore(configB, version, helper, errCode);
570 ASSERT_NE(storeB, nullptr);
571 RdbStoreStoreMultiTest::InsertData(storeB);
572 storeB = nullptr;
573 // Delete the encrypted database path1, rename the database path2 to path1, and open path1.
574 SqliteUtils::DeleteFile(path1);
575 SqliteUtils::DeleteFile(path1Wal);
576 SqliteUtils::DeleteFile(path1Shm);
577 SqliteUtils::RenameFile(path2, path1);
578 SqliteUtils::RenameFile(path2Wal, path1Wal);
579 SqliteUtils::RenameFile(path2Shm, path1Shm);
580 // The current database of path1 is actually a non-encrypted database, and it cannot be opened
581 // using encryption parameters. The reconstruction was successful, but there is no data in the table.
582 storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
583 ASSERT_NE(storeA, nullptr);
584 RebuiltType rebuiltType;
585 storeA->GetRebuilt(rebuiltType);
586 EXPECT_EQ(rebuiltType, RebuiltType::REBUILT);
587 std::shared_ptr<ResultSet> resultSet = storeA->QuerySql("select * from test");
588 int ret = resultSet->GoToNextRow();
589 EXPECT_EQ(ret, E_SQLITE_ERROR);
590 storeA = nullptr;
591
592 RdbHelper::DeleteRdbStore(path1);
593 }