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