1 /*
2 * Copyright (c) 2022 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 <climits>
19 #include <string>
20
21 #include "common.h"
22 #include "rdb_errno.h"
23 #include "rdb_helper.h"
24 #include "rdb_open_callback.h"
25
26 using namespace testing::ext;
27 using namespace OHOS::NativeRdb;
28
29 class RdbTransactionTest : public testing::Test {
30 public:
31 static void SetUpTestCase(void);
32 static void TearDownTestCase(void);
33 void SetUp();
34 void TearDown();
35
36 static const std::string DATABASE_NAME;
37 static std::shared_ptr<RdbStore> store;
38 };
39
40 const std::string RdbTransactionTest::DATABASE_NAME = RDB_TEST_PATH + "transaction_test.db";
41 std::shared_ptr<RdbStore> RdbTransactionTest::store = nullptr;
42
43 class TransactionTestOpenCallback : public RdbOpenCallback {
44 public:
45 int OnCreate(RdbStore &store) override;
46 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
47 static const std::string CREATE_TABLE_TEST;
48 };
49
50 const std::string TransactionTestOpenCallback::CREATE_TABLE_TEST = std::string("CREATE TABLE IF NOT EXISTS test ")
51 + std::string("(id INTEGER PRIMARY KEY "
52 "AUTOINCREMENT, name TEXT NOT NULL, "
53 "age INTEGER, salary REAL, blobType "
54 "BLOB)");
55
OnCreate(RdbStore & store)56 int TransactionTestOpenCallback::OnCreate(RdbStore &store)
57 {
58 return store.ExecuteSql(CREATE_TABLE_TEST);
59 }
60
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)61 int TransactionTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
62 {
63 return E_OK;
64 }
65
SetUpTestCase(void)66 void RdbTransactionTest::SetUpTestCase(void)
67 {
68 int errCode = E_OK;
69 RdbHelper::DeleteRdbStore(DATABASE_NAME);
70 RdbStoreConfig config(RdbTransactionTest::DATABASE_NAME);
71 TransactionTestOpenCallback helper;
72 RdbTransactionTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
73 EXPECT_NE(RdbTransactionTest::store, nullptr);
74 EXPECT_EQ(errCode, E_OK);
75 }
76
TearDownTestCase(void)77 void RdbTransactionTest::TearDownTestCase(void)
78 {
79 store = nullptr;
80 RdbHelper::DeleteRdbStore(RdbTransactionTest::DATABASE_NAME);
81 }
82
SetUp(void)83 void RdbTransactionTest::SetUp(void)
84 {
85 store->ExecuteSql("DELETE FROM test");
86 }
87
TearDown(void)88 void RdbTransactionTest::TearDown(void)
89 {
90 }
91
92
93 /**
94 * @tc.name: RdbStore_Transaction_001
95 * @tc.desc: test RdbStore BaseTransaction
96 * @tc.type: FUNC
97 */
98 HWTEST_F(RdbTransactionTest, RdbStore_Transaction_001, TestSize.Level1)
99 {
100 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
101
102 int64_t id;
103 int ret = store->BeginTransaction();
104 EXPECT_EQ(ret, E_OK);
105
106 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
107 EXPECT_EQ(ret, E_OK);
108 EXPECT_EQ(1, id);
109
110 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
111 EXPECT_EQ(ret, E_OK);
112 EXPECT_EQ(2, id);
113
114 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[2]));
115 EXPECT_EQ(ret, E_OK);
116 EXPECT_EQ(3, id);
117
118 ret = store->Commit();
119 EXPECT_EQ(ret, E_OK);
120
121 int64_t count;
122 ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
123 EXPECT_EQ(ret, E_OK);
124 EXPECT_EQ(count, 3);
125
126 int deletedRows;
127 ret = store->Delete(deletedRows, "test");
128 EXPECT_EQ(ret, E_OK);
129 EXPECT_EQ(deletedRows, 3);
130 }
131
132 /**
133 * @tc.name: RdbStore_Transaction_002
134 * @tc.desc: test RdbStore BaseTransaction
135 * @tc.type: FUNC
136 */
137 HWTEST_F(RdbTransactionTest, RdbStore_Transaction_002, TestSize.Level1)
138 {
139 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
140
141 int64_t id;
142 int ret = store->BeginTransaction();
143 EXPECT_EQ(ret, E_OK);
144
145 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
146 EXPECT_EQ(ret, E_OK);
147 EXPECT_EQ(1, id);
148
149 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
150 EXPECT_EQ(ret, E_OK);
151 EXPECT_EQ(2, id);
152
153 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[2]));
154 EXPECT_EQ(ret, E_OK);
155 EXPECT_EQ(3, id);
156
157 ret = store->Commit();
158 EXPECT_EQ(ret, E_OK);
159
160 int64_t count;
161 ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
162 EXPECT_EQ(ret, E_OK);
163 EXPECT_EQ(count, 3);
164
165 std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
166 EXPECT_NE(resultSet, nullptr);
167 ret = resultSet->GoToNextRow();
168 EXPECT_EQ(ret, E_OK);
169 ret = resultSet->Close();
170 EXPECT_EQ(ret, E_OK);
171
172 int deletedRows;
173 ret = store->Delete(deletedRows, "test");
174 EXPECT_EQ(ret, E_OK);
175 EXPECT_EQ(deletedRows, 3);
176 }
177
178 /**
179 * @tc.name: RdbStore_Transaction_003
180 * @tc.desc: test RdbStore BaseTransaction
181 * @tc.type: FUNC
182 */
183 HWTEST_F(RdbTransactionTest, RdbStore_Transaction_003, TestSize.Level1)
184 {
185 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
186
187 int64_t id;
188 int ret = store->BeginTransaction();
189 EXPECT_EQ(ret, E_OK);
190
191 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
192 EXPECT_EQ(ret, E_OK);
193 EXPECT_EQ(1, id);
194
195 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
196 EXPECT_EQ(ret, E_OK);
197 EXPECT_EQ(2, id);
198
199 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[2]));
200 EXPECT_EQ(ret, E_OK);
201 EXPECT_EQ(3, id);
202
203 ret = store->RollBack();
204 EXPECT_EQ(ret, E_OK);
205
206 int64_t count;
207 ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
208 EXPECT_EQ(ret, E_OK);
209 EXPECT_EQ(count, 0);
210
211 std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
212 EXPECT_NE(resultSet, nullptr);
213 ret = resultSet->Close();
214 EXPECT_EQ(ret, E_OK);
215
216 int deletedRows;
217 ret = store->Delete(deletedRows, "test");
218 EXPECT_EQ(ret, E_OK);
219 EXPECT_EQ(deletedRows, 0);
220 }
221
222
223 /**
224 * @tc.name: RdbStore_NestedTransaction_001
225 * @tc.desc: test RdbStore BaseTransaction
226 * @tc.type: FUNC
227 */
228 HWTEST_F(RdbTransactionTest, RdbStore_NestedTransaction_001, TestSize.Level1)
229 {
230 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
231
232 int64_t id;
233 int ret = store->BeginTransaction();
234 EXPECT_EQ(ret, E_OK);
235
236 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
237 EXPECT_EQ(ret, E_OK);
238 EXPECT_EQ(1, id);
239
240 ret = store->BeginTransaction();
241 EXPECT_EQ(ret, E_OK);
242 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
243 EXPECT_EQ(ret, E_OK);
244 EXPECT_EQ(2, id);
245 ret = store->Commit(); // not commit
246 EXPECT_EQ(ret, E_OK);
247
248 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[2]));
249 EXPECT_EQ(ret, E_OK);
250 EXPECT_EQ(3, id);
251
252 ret = store->Commit();
253 EXPECT_EQ(ret, E_OK);
254
255 int64_t count;
256 ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
257 EXPECT_EQ(ret, E_OK);
258 EXPECT_EQ(count, 3);
259
260 std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
261 EXPECT_NE(resultSet, nullptr);
262 ret = resultSet->GoToNextRow();
263 EXPECT_EQ(ret, E_OK);
264 ret = resultSet->Close();
265 EXPECT_EQ(ret, E_OK);
266
267 int deletedRows;
268 ret = store->Delete(deletedRows, "test");
269 EXPECT_EQ(ret, E_OK);
270 EXPECT_EQ(deletedRows, 3);
271 }
272
273 /**
274 * @tc.name: RdbStore_NestedTransaction_002
275 * @tc.desc: test RdbStore BaseTransaction
276 * @tc.type: FUNC
277 */
278 HWTEST_F(RdbTransactionTest, RdbStore_NestedTransaction_002, TestSize.Level1)
279 {
280 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
281
282 int64_t id;
283 int ret = store->BeginTransaction();
284 EXPECT_EQ(ret, E_OK);
285
286 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
287 EXPECT_EQ(ret, E_OK);
288 EXPECT_EQ(1, id);
289
290 ret = store->BeginTransaction();
291 EXPECT_EQ(ret, E_OK);
292 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
293 EXPECT_EQ(ret, E_OK);
294 EXPECT_EQ(2, id);
295 ret = store->Commit();
296 EXPECT_EQ(ret, E_OK);
297 ret = store->Commit(); // commit
298 EXPECT_EQ(ret, E_OK);
299
300 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[2]));
301 EXPECT_EQ(ret, E_OK);
302 EXPECT_EQ(3, id);
303
304 int64_t count;
305 ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
306 EXPECT_EQ(ret, E_OK);
307 EXPECT_EQ(count, 3);
308
309 std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
310 EXPECT_NE(resultSet, nullptr);
311 ret = resultSet->GoToNextRow();
312 EXPECT_EQ(ret, E_OK);
313 ret = resultSet->Close();
314 EXPECT_EQ(ret, E_OK);
315
316 int deletedRows;
317 ret = store->Delete(deletedRows, "test");
318 EXPECT_EQ(ret, E_OK);
319 EXPECT_EQ(deletedRows, 3);
320 }
321
322 /**
323 * @tc.name: RdbStore_NestedTransaction_003
324 * @tc.desc: test RdbStore BaseTransaction
325 * @tc.type: FUNC
326 */
327 HWTEST_F(RdbTransactionTest, RdbStore_NestedTransaction_003, TestSize.Level1)
328 {
329 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
330
331 int64_t id;
332 int ret = store->BeginTransaction();
333 EXPECT_EQ(ret, E_OK);
334
335 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
336 EXPECT_EQ(ret, E_OK);
337 EXPECT_EQ(1, id);
338
339 ret = store->BeginTransaction();
340 EXPECT_EQ(ret, E_OK);
341 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
342 EXPECT_EQ(ret, E_OK);
343 EXPECT_EQ(2, id);
344 ret = store->Commit(); // not commit
345 EXPECT_EQ(ret, E_OK);
346
347 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[2]));
348 EXPECT_EQ(ret, E_OK);
349 EXPECT_EQ(3, id);
350
351 ret = store->Commit(); // not commit
352 EXPECT_EQ(ret, E_OK);
353
354 int64_t count;
355 ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
356 EXPECT_EQ(ret, E_OK);
357 EXPECT_EQ(count, 3);
358
359 std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
360 EXPECT_NE(resultSet, nullptr);
361 ret = resultSet->GoToNextRow();
362 EXPECT_EQ(ret, E_OK);
363 ret = resultSet->Close();
364 EXPECT_EQ(ret, E_OK);
365
366 int deletedRows;
367 ret = store->Delete(deletedRows, "test");
368 EXPECT_EQ(ret, E_OK);
369 EXPECT_EQ(deletedRows, 3);
370 }
371
372 /**
373 * @tc.name: RdbStore_NestedTransaction_004
374 * @tc.desc: test RdbStore BaseTransaction
375 * @tc.type: FUNC
376 */
377 HWTEST_F(RdbTransactionTest, RdbStore_NestedTransaction_004, TestSize.Level1)
378 {
379 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
380
381 int64_t id;
382 int ret = store->BeginTransaction();
383 EXPECT_EQ(ret, E_OK);
384
385 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
386 EXPECT_EQ(ret, E_OK);
387 EXPECT_EQ(1, id);
388
389 ret = store->BeginTransaction();
390 EXPECT_EQ(ret, E_OK);
391 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
392 EXPECT_EQ(ret, E_OK);
393 EXPECT_EQ(2, id);
394 ret = store->Commit(); // commit
395 EXPECT_EQ(ret, E_OK);
396
397 ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[2]));
398 EXPECT_EQ(ret, E_OK);
399 EXPECT_EQ(3, id);
400
401 ret = store->Commit(); // commit
402 EXPECT_EQ(ret, E_OK);
403
404 int64_t count;
405 ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
406 EXPECT_EQ(ret, E_OK);
407 EXPECT_EQ(count, 3);
408
409 std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
410 EXPECT_NE(resultSet, nullptr);
411 ret = resultSet->GoToNextRow();
412 EXPECT_EQ(ret, E_OK);
413 ret = resultSet->GoToNextRow();
414 EXPECT_EQ(ret, E_OK);
415 ret = resultSet->GoToNextRow();
416 EXPECT_EQ(ret, E_OK);
417 ret = resultSet->GoToNextRow();
418 EXPECT_EQ(ret, E_ERROR);
419 ret = resultSet->Close();
420 EXPECT_EQ(ret, E_OK);
421
422 int deletedRows;
423 ret = store->Delete(deletedRows, "test");
424 EXPECT_EQ(ret, E_OK);
425 EXPECT_EQ(deletedRows, 3);
426 }
427
428 /**
429 * @tc.name: RdbStore_BatchInsert_001
430 * @tc.desc: test RdbStore BatchInsert
431 * @tc.type: FUNC
432 * @tc.require: issueI5GZGX
433 */
434 HWTEST_F(RdbTransactionTest, RdbStore_BatchInsert_001, TestSize.Level1)
435 {
436 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
437
438 ValuesBucket values;
439
440 values.PutString("name", "zhangsan");
441 values.PutInt("age", 18);
442 values.PutDouble("salary", 100.5);
443 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
444
445 std::vector<ValuesBucket> valuesBuckets;
446 for (int i = 0; i < 100; i++) {
447 valuesBuckets.push_back(values);
448 }
449 int64_t insertNum = 0;
450 int ret = store->BatchInsert(insertNum, "test", valuesBuckets);
451 EXPECT_EQ(E_OK, ret);
452 EXPECT_EQ(100, insertNum);
453 std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
454 int rowCount = 0;
455 resultSet->GetRowCount(rowCount);
456 EXPECT_EQ(100, rowCount);
457 }
458
459
460 /**
461 * @tc.name: RdbStore_BatchInsert_002
462 * @tc.desc: test RdbStore BatchInsert
463 * @tc.type: FUNC
464 * @tc.require: issue-I6BAX0
465 */
466 HWTEST_F(RdbTransactionTest, RdbStore_BatchInsert_002, TestSize.Level1)
467 {
468 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
469 store->ExecuteSql("delete from test");
470 std::string name = "zhangsan";
471 int age = 18;
472 double salary = 100.5;
473 std::vector<uint8_t> blob = { 1, 2, 3 };
474 std::vector<ValuesBucket> valuesBuckets;
475 for (int i = 0; i < 100; i++) {
476 ValuesBucket values;
477 values.PutString("name", name);
478 values.PutInt("age", age + i);
479 values.PutDouble("salary", salary + i);
480 values.PutBlob("blobType", blob);
481 valuesBuckets.push_back(std::move(values));
482 }
483
484 int64_t number = 0;
485 int error = store->BatchInsert(number, "test", valuesBuckets);
486 EXPECT_EQ(E_OK, error);
487 EXPECT_EQ(100, number);
488 int rowCount = 0;
489 std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
490 resultSet->GetRowCount(rowCount);
491 EXPECT_EQ(100, rowCount);
492 }
493
494
495 /**
496 * @tc.name: RdbStore_BatchInsert_003
497 * @tc.desc: test RdbStore BatchInsert
498 * @tc.type: FUNC
499 * @tc.require: issue-I6BAX0
500 */
501 HWTEST_F(RdbTransactionTest, RdbStore_BatchInsert_003, TestSize.Level1)
502 {
503 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
504 store->ExecuteSql("delete from test");
505
506 int id = 0;
507 std::string name = "zhangsan";
508 int age = 18;
509 double salary = 100.5;
510 std::vector<uint8_t> blob = { 1, 2, 3 };
511 std::vector<ValuesBucket> valuesBuckets;
512 for (int i = 0; i < 100; i++) {
513 RowData rowData1 = {id + i, name, age + i, salary + i, blob};
514 ValuesBucket values = UTUtils::SetRowData(rowData1);
515 valuesBuckets.push_back(std::move(values));
516 }
517
518 int64_t number = 0;
519 int error = store->BatchInsert(number, "test", valuesBuckets);
520 EXPECT_EQ(E_OK, error);
521 EXPECT_EQ(100, number);
522
523 int rowCount = 0;
524 std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
525 resultSet->GetRowCount(rowCount);
526 EXPECT_EQ(100, rowCount);
527
528 valuesBuckets.clear();
529 for (int i = 50; i < 100; i++) {
530 RowData rowData2 = {id + i, name, age + i, salary + i, blob};
531 ValuesBucket values = UTUtils::SetRowData(rowData2);
532 valuesBuckets.push_back(std::move(values));
533 }
534
535 number = INT_MIN;
536 error = store->BatchInsert(number, "test", valuesBuckets);
537 EXPECT_EQ(E_OK, error);
538 EXPECT_EQ(50, number);
539
540 resultSet = store->QuerySql("SELECT * FROM test");
541 resultSet->GetRowCount(rowCount);
542 EXPECT_EQ(100, rowCount);
543 number = 0l;
544 while (true) {
545 error = resultSet->GoToNextRow();
546 if (error != E_OK) {
547 break;
548 }
549 number++;
550 }
551 resultSet->Close();
552 EXPECT_EQ(100, number);
553 }