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
16 #include <gtest/gtest.h>
17
18 #include <string>
19
20 #include "common.h"
21 #include "rdb_errno.h"
22 #include "rdb_helper.h"
23 #include "rdb_open_callback.h"
24
25 using namespace testing::ext;
26 using namespace OHOS::NativeRdb;
27
28 class OpenCallback : public RdbOpenCallback {
29 public:
OnCreate(RdbStore & store)30 int OnCreate(RdbStore &store) override
31 {
32 return E_OK;
33 }
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)34 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override
35 {
36 return E_OK;
37 }
38 };
39
40 class RdbMemoryDbTest : public testing::Test {
41 public:
42 static void SetUpTestCase(void);
43 static void TearDownTestCase(void);
44 void SetUp();
45 void TearDown();
46 void InitDb();
47
48 static const std::string rdbStorePath;
49 static std::shared_ptr<RdbStore> g_store;
50 };
51 const std::string RdbMemoryDbTest::rdbStorePath = RDB_TEST_PATH + std::string("MemoryTest");
52 std::shared_ptr<RdbStore> RdbMemoryDbTest::g_store = nullptr;
53
SetUpTestCase(void)54 void RdbMemoryDbTest::SetUpTestCase(void)
55 {
56 }
57
TearDownTestCase(void)58 void RdbMemoryDbTest::TearDownTestCase(void)
59 {
60 }
61
SetUp(void)62 void RdbMemoryDbTest::SetUp(void)
63 {
64 InitDb();
65 }
66
TearDown(void)67 void RdbMemoryDbTest::TearDown(void)
68 {
69 RdbStoreConfig config(rdbStorePath);
70 config.SetStorageMode(StorageMode::MODE_MEMORY);
71 RdbHelper::DeleteRdbStore(config);
72 }
73
74 class RdbMemoryDbTestWrongSqlOpenCallback : public RdbOpenCallback {
75 public:
76 int OnCreate(RdbStore &store) override;
77 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
78 };
79 constexpr const char *WRONG_SQL_TEST = "CREATE TABL IF NOT EXISTS test "
80 "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
81 "name TEXT NOT NULL, age INTEGER, salary REAL, "
82 "blobType BLOB)";
83 class RdbMemoryDbTestOpenCallback : public RdbOpenCallback {
84 public:
85 int OnCreate(RdbStore &store) override;
86 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
87 };
88 constexpr const char *CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test "
89 "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
90 "name TEXT NOT NULL, age INTEGER, salary REAL, "
91 "blobType BLOB)";
InitDb()92 void RdbMemoryDbTest::InitDb()
93 {
94 int errCode = E_OK;
95 RdbStoreConfig config(RdbMemoryDbTest::rdbStorePath);
96 RdbMemoryDbTestOpenCallback helper;
97 config.SetStorageMode(StorageMode::MODE_MEMORY);
98 RdbMemoryDbTest::g_store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
99 ASSERT_NE(g_store, nullptr);
100 ASSERT_EQ(errCode, E_OK);
101 }
102
OnCreate(RdbStore & store)103 int RdbMemoryDbTestWrongSqlOpenCallback::OnCreate(RdbStore &store)
104 {
105 return store.ExecuteSql(WRONG_SQL_TEST);
106 }
107
OnCreate(RdbStore & store)108 int RdbMemoryDbTestOpenCallback::OnCreate(RdbStore &store)
109 {
110 return store.ExecuteSql(CREATE_TABLE_TEST);
111 }
112
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)113 int RdbMemoryDbTestWrongSqlOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
114 {
115 return E_OK;
116 }
117
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)118 int RdbMemoryDbTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
119 {
120 return E_OK;
121 }
122 /**
123 * @tc.name: GetMemoryDb_001
124 * @tc.desc: Get MemoryDb with different config
125 * @tc.type: FUNC
126 * @tc.require:
127 * @tc.author:
128 */
129 HWTEST_F(RdbMemoryDbTest, GetMemoryDb_001, TestSize.Level1)
130 {
131 int errCode = E_ERROR;
132 std::string path = RDB_TEST_PATH + "GetMemoryDb_001";
133 RdbStoreConfig config(path.c_str());
134 config.SetStorageMode(StorageMode::MODE_MEMORY);
135 RdbMemoryDbTestOpenCallback normalCallback;
136 std::shared_ptr<RdbStore> rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
137 EXPECT_EQ(errCode, E_OK);
138 EXPECT_NE(rdbStore, nullptr);
139 ASSERT_NE(access(path.c_str(), F_OK), 0);
140 rdbStore = nullptr;
141
142 RdbMemoryDbTestWrongSqlOpenCallback abnormalHelper;
143 rdbStore = RdbHelper::GetRdbStore(config, 1, abnormalHelper, errCode);
144 EXPECT_NE(errCode, E_OK);
145 EXPECT_EQ(rdbStore, nullptr);
146 rdbStore = nullptr;
147
148 config.SetSearchable(true);
149 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
150 EXPECT_EQ(errCode, E_NOT_SUPPORT);
151 EXPECT_EQ(rdbStore, nullptr);
152 rdbStore = nullptr;
153 config.SetSearchable(false);
154
155 config.SetIsVector(true);
156 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
157 EXPECT_EQ(errCode, E_NOT_SUPPORT);
158 EXPECT_EQ(rdbStore, nullptr);
159 rdbStore = nullptr;
160 config.SetIsVector(false);
161
162 config.SetEncryptStatus(true);
163 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
164 EXPECT_EQ(errCode, E_NOT_SUPPORT);
165 EXPECT_EQ(rdbStore, nullptr);
166 rdbStore = nullptr;
167 config.SetEncryptStatus(false);
168
169 config.SetHaMode(HAMode::MAIN_REPLICA);
170 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
171 EXPECT_EQ(errCode, E_NOT_SUPPORT);
172 EXPECT_EQ(rdbStore, nullptr);
173 rdbStore = nullptr;
174 config.SetHaMode(HAMode::SINGLE);
175
176 config.SetRoleType(RoleType::VISITOR);
177 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
178 EXPECT_EQ(errCode, E_NOT_SUPPORT);
179 EXPECT_EQ(rdbStore, nullptr);
180 }
181
182 /**
183 * @tc.name: GetMemoryDb_002
184 * @tc.desc: Get MemoryDb with different config
185 * @tc.type: FUNC
186 * @tc.require:
187 * @tc.author:
188 */
189 HWTEST_F(RdbMemoryDbTest, GetMemoryDb_002, TestSize.Level1)
190 {
191 int errCode = E_ERROR;
192 std::string path = RDB_TEST_PATH + "GetMemoryDb_002";
193 RdbStoreConfig config(path);
194 config.SetStorageMode(StorageMode::MODE_MEMORY);
195 RdbMemoryDbTestOpenCallback normalCallback;
196 std::shared_ptr<RdbStore> rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
197 EXPECT_EQ(errCode, E_OK);
198 EXPECT_NE(rdbStore, nullptr);
199
200 config.SetPageSize(1024);
201 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
202 EXPECT_EQ(errCode, E_CONFIG_INVALID_CHANGE);
203 EXPECT_EQ(rdbStore, nullptr);
204 }
205
206 /**
207 * @tc.name: GetMemoryDb_003
208 * @tc.desc: Get MemoryDb after delete
209 * @tc.type: FUNC
210 * @tc.require:
211 * @tc.author:
212 */
213 HWTEST_F(RdbMemoryDbTest, GetMemoryDb_003, TestSize.Level1)
214 {
215 int errCode = E_ERROR;
216 std::string path = RDB_TEST_PATH + "GetMemoryDb_003";
217 RdbStoreConfig config(path);
218 config.SetStorageMode(StorageMode::MODE_MEMORY);
219 RdbMemoryDbTestOpenCallback normalCallback;
220 std::shared_ptr<RdbStore> rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
221 EXPECT_EQ(errCode, E_OK);
222 ASSERT_NE(rdbStore, nullptr);
223
224 ValuesBucket values;
225 values.PutInt("id", 1);
226 values.PutString("name", std::string("zhangsan"));
227 values.PutInt("age", 18);
228 auto [ret, row] = rdbStore->Insert("test", values);
229 EXPECT_EQ(ret, E_OK);
230 auto pred = AbsRdbPredicates("test");
231 auto resultSet = rdbStore->Query(pred);
232 ASSERT_NE(resultSet, nullptr);
233 int count = -1;
234 EXPECT_EQ(resultSet->GetRowCount(count), E_OK);
235 EXPECT_EQ(count, 1);
236
237 auto rdbStore2 = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
238 EXPECT_EQ(errCode, E_OK);
239 ASSERT_NE(rdbStore2, nullptr);
240 resultSet = rdbStore2->Query(pred);
241 ASSERT_NE(resultSet, nullptr);
242 count = -1;
243 EXPECT_EQ(resultSet->GetRowCount(count), E_OK);
244 EXPECT_EQ(count, 1);
245 resultSet = nullptr;
246
247 RdbHelper::DeleteRdbStore(config);
248 std::tie(ret, row) = rdbStore->Insert("test", values);
249 EXPECT_EQ(ret, E_ALREADY_CLOSED);
250
251 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
252 EXPECT_EQ(errCode, E_OK);
253 ASSERT_NE(rdbStore, nullptr);
254 resultSet = rdbStore->Query(pred);
255 ASSERT_NE(resultSet, nullptr);
256 count = -1;
257 EXPECT_EQ(resultSet->GetRowCount(count), E_OK);
258 EXPECT_EQ(count, 0);
259 }
260
261 /**
262 * @tc.name: CRUD of MemoryDb_001
263 * @tc.desc: CRUD with Transaction of MemoryDb
264 * @tc.type: FUNC
265 * @tc.require:
266 * @tc.author:
267 */
268 HWTEST_F(RdbMemoryDbTest, CRUDWithMemoryDb_001, TestSize.Level1)
269 {
270 std::shared_ptr<RdbStore> &store = g_store;
271
272 auto [ret, transaction] = store->CreateTransaction(Transaction::IMMEDIATE);
273 ASSERT_EQ(ret, E_OK);
274 ASSERT_NE(transaction, nullptr);
275
276 auto result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
277 ASSERT_EQ(result.first, E_OK);
278 ASSERT_EQ(1, result.second);
279
280 result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
281 ASSERT_EQ(result.first, E_OK);
282 ASSERT_EQ(2, result.second);
283
284 result = store->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[2]), RdbStore::NO_ACTION);
285 ASSERT_EQ(result.first, E_SQLITE_LOCKED);
286
287 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
288 ASSERT_NE(resultSet, nullptr);
289 int32_t rowCount{};
290 ret = resultSet->GetRowCount(rowCount);
291 ASSERT_EQ(ret, E_OK);
292 ASSERT_EQ(rowCount, 2);
293
294 ret = transaction->Commit();
295 ASSERT_EQ(ret, E_OK);
296
297 ValueObject value;
298 ret = resultSet->Get(0, value);
299 ASSERT_EQ(ret, E_ALREADY_CLOSED);
300
301 result = store->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[2]), RdbStore::NO_ACTION);
302 ASSERT_EQ(result.first, E_OK);
303 ASSERT_EQ(3, result.second);
304
305 result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
306 ASSERT_EQ(result.first, E_ALREADY_CLOSED);
307
308 resultSet = store->QueryByStep("SELECT * FROM test");
309 ASSERT_NE(resultSet, nullptr);
310 resultSet->GetRowCount(rowCount);
311 EXPECT_EQ(rowCount, 3);
312 }
313
314 /**
315 * @tc.name: CRUD of MemoryDb_002
316 * @tc.desc: CRUD with Transaction of MemoryDb
317 * @tc.type: FUNC
318 * @tc.require:
319 * @tc.author:
320 */
321 HWTEST_F(RdbMemoryDbTest, CRUDWithMemoryDb_002, TestSize.Level1)
322 {
323 std::shared_ptr<RdbStore> &store = g_store;
324
325 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
326 ASSERT_EQ(ret, E_OK);
327 ASSERT_NE(transaction, nullptr);
328
329 auto result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
330 ASSERT_EQ(result.first, E_OK);
331 ASSERT_EQ(result.second, 1);
332
333 result = transaction->Update("test", UTUtils::SetRowData(UTUtils::g_rowData[1]), "id=1");
334 ASSERT_EQ(result.first, E_OK);
335 ASSERT_EQ(result.second, 1);
336
337 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
338 ASSERT_NE(resultSet, nullptr);
339 int32_t rowCount{};
340 ret = resultSet->GetRowCount(rowCount);
341 ASSERT_EQ(ret, E_OK);
342 ASSERT_EQ(rowCount, 1);
343 ret = resultSet->GoToFirstRow();
344 ASSERT_EQ(ret, E_OK);
345 int32_t columnIndex{};
346 ret = resultSet->GetColumnIndex("id", columnIndex);
347 ASSERT_EQ(ret, E_OK);
348 int32_t id{};
349 ret = resultSet->GetInt(columnIndex, id);
350 ASSERT_EQ(ret, E_OK);
351 ASSERT_EQ(id, 2);
352
353 AbsRdbPredicates predicates("test");
354 predicates.EqualTo("id", ValueObject(2));
355 result = transaction->Update(UTUtils::SetRowData(UTUtils::g_rowData[2]), predicates);
356 ASSERT_EQ(result.first, E_OK);
357 ASSERT_EQ(result.second, 1);
358
359 ret = transaction->Commit();
360 ASSERT_EQ(ret, E_OK);
361
362 resultSet = store->QueryByStep("SELECT * FROM test");
363 ASSERT_NE(resultSet, nullptr);
364 ret = resultSet->GetRowCount(rowCount);
365 ASSERT_EQ(ret, E_OK);
366 ASSERT_EQ(rowCount, 1);
367 ret = resultSet->GoToFirstRow();
368 ASSERT_EQ(ret, E_OK);
369 resultSet->GetColumnIndex("id", columnIndex);
370 ret = resultSet->GetInt(columnIndex, id);
371 EXPECT_EQ(ret, E_OK);
372 EXPECT_EQ(id, 3);
373 }
374
375 /**
376 * @tc.name: CRUD of MemoryDb_003
377 * @tc.desc: CRUD with Transaction of MemoryDb
378 * @tc.type: FUNC
379 * @tc.require:
380 * @tc.author:
381 */
382 HWTEST_F(RdbMemoryDbTest, CRUDWithMemoryDb_003, TestSize.Level1)
383 {
384 std::shared_ptr<RdbStore> &store = g_store;
385 store->Execute("DROP TABLE IF EXISTS test1");
386 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
387 ASSERT_EQ(res.first, E_OK);
388 auto [ret1, transaction1] = store->CreateTransaction(Transaction::IMMEDIATE);
389 ASSERT_EQ(ret1, E_OK);
390 ASSERT_NE(transaction1, nullptr);
391
392 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
393 ASSERT_EQ(ret, E_OK);
394 ASSERT_NE(transaction, nullptr);
395
396 ValuesBuckets rows;
397 for (int i = 0; i < 5; i++) {
398 Transaction::Row row;
399 row.Put("id", i);
400 row.Put("name", "Jim_batchInsert");
401 rows.Put(row);
402 }
403 auto result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_NONE);
404 ASSERT_EQ(result.first, E_SQLITE_LOCKED);
405 ASSERT_EQ(result.second, -1);
406
407 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_ROLLBACK);
408 ASSERT_EQ(result.first, E_SQLITE_LOCKED);
409 ASSERT_EQ(result.second, -1);
410
411 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_ABORT);
412 ASSERT_EQ(result.first, E_SQLITE_LOCKED);
413 ASSERT_EQ(result.second, -1);
414
415 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_FAIL);
416 ASSERT_EQ(result.first, E_SQLITE_LOCKED);
417 ASSERT_EQ(result.second, -1);
418
419 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_IGNORE);
420 ASSERT_EQ(result.first, E_SQLITE_LOCKED);
421 ASSERT_EQ(result.second, -1);
422
423 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_REPLACE);
424 ASSERT_EQ(result.first, E_SQLITE_LOCKED);
425 ASSERT_EQ(result.second, -1);
426 }
427
428 /**
429 * @tc.name: CRUD of MemoryDb_004
430 * @tc.desc: CRUD with Transaction of MemoryDb
431 * @tc.type: FUNC
432 * @tc.require:
433 * @tc.author:
434 */
435 HWTEST_F(RdbMemoryDbTest, CRUDWithMemoryDb_004, TestSize.Level1)
436 {
437 std::shared_ptr<RdbStore> &store = g_store;
438
439 auto [ret1, transaction1] = store->CreateTransaction(Transaction::DEFERRED);
440 ASSERT_EQ(ret1, E_OK);
441 ASSERT_NE(transaction1, nullptr);
442
443 auto [ret2, transaction2] = store->CreateTransaction(Transaction::DEFERRED);
444 ASSERT_EQ(ret2, E_OK);
445 ASSERT_NE(transaction2, nullptr);
446
447 auto [ret3, transaction3] = store->CreateTransaction(Transaction::EXCLUSIVE);
448 ASSERT_EQ(ret3, E_OK);
449 ASSERT_NE(transaction3, nullptr);
450
451 auto [ret4, transaction4] = store->CreateTransaction(Transaction::IMMEDIATE);
452 ASSERT_EQ(ret4, E_SQLITE_LOCKED);
453 ASSERT_EQ(transaction4, nullptr);
454 transaction3 = nullptr;
455
456 std::tie(ret4, transaction4) = store->CreateTransaction(Transaction::IMMEDIATE);
457 ASSERT_EQ(ret4, E_OK);
458 ASSERT_NE(transaction4, nullptr);
459
460 std::tie(ret3, transaction3) = store->CreateTransaction(Transaction::EXCLUSIVE);
461 ASSERT_EQ(ret3, E_SQLITE_LOCKED);
462 ASSERT_EQ(transaction3, nullptr);
463 }
464
465 /**
466 *@tc.name: GetMemoryDb_004
467 *@tc.desc: Get MemoryDb with diff name
468 *@tc.type: FUNC
469 *@tc.require:
470 *@tc.author:
471 */
472 HWTEST_F(RdbMemoryDbTest, GetMemoryDb_004, TestSize.Level1)
473 {
474 int errCode = E_ERROR;
475 RdbStoreConfig config(RDB_TEST_PATH);
476 config.SetName("mem_test");
477 config.SetStorageMode(StorageMode::MODE_MEMORY);
478 RdbMemoryDbTestOpenCallback normalCallback;
479 std::shared_ptr<RdbStore> rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
480 EXPECT_EQ(errCode, E_OK);
481 EXPECT_NE(rdbStore, nullptr);
482
483 config.SetName("eme.db");
484 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
485 EXPECT_EQ(errCode, E_OK);
486 EXPECT_NE(rdbStore, nullptr);
487
488 config.SetName("test123-test");
489 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
490 EXPECT_EQ(errCode, E_OK);
491 EXPECT_NE(rdbStore, nullptr);
492
493 config.SetName("test%");
494 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
495 EXPECT_NE(errCode, E_OK);
496 EXPECT_EQ(rdbStore, nullptr);
497
498 config.SetName("test:");
499 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
500 EXPECT_NE(errCode, E_OK);
501 EXPECT_EQ(rdbStore, nullptr);
502
503 config.SetName("test?");
504 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
505 EXPECT_NE(errCode, E_OK);
506 EXPECT_EQ(rdbStore, nullptr);
507
508 config.SetName("test$");
509 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
510 EXPECT_NE(errCode, E_OK);
511 EXPECT_EQ(rdbStore, nullptr);
512
513 config.SetName("test(");
514 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
515 EXPECT_NE(errCode, E_OK);
516 EXPECT_EQ(rdbStore, nullptr);
517
518 config.SetName("test)");
519 rdbStore = RdbHelper::GetRdbStore(config, 1, normalCallback, errCode);
520 EXPECT_NE(errCode, E_OK);
521 EXPECT_EQ(rdbStore, nullptr);
522 }