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 <string>
19 #include <cstdlib>
20
21 #include "abs_rdb_predicates.h"
22 #include "common.h"
23 #include "rdb_errno.h"
24 #include "rdb_helper.h"
25 #include "rdb_open_callback.h"
26
27 using namespace testing::ext;
28 using namespace OHOS::NativeRdb;
29
30 static const std::string DATABASE_NAME = RDB_TEST_PATH + "transaction_test.db";
31 static const char CREATE_TABLE_SQL[] =
32 "CREATE TABLE IF NOT EXISTS test "
33 "(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)";
34 static const char CREATE_TABLE1_SQL[] =
35 "CREATE TABLE IF NOT EXISTS test1 "
36 "(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)";
37
38 class TransactionTest : public testing::Test {
39 public:
40 static void SetUpTestCase();
41 static void TearDownTestCase();
42 void SetUp() override;
43 void TearDown() override;
44
45 static inline std::shared_ptr<RdbStore> store_;
46
47 class TransactionTestOpenCallback : public RdbOpenCallback {
48 public:
49 int OnCreate(RdbStore &store) override;
50 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
51 };
52 };
53
OnCreate(RdbStore & store)54 int TransactionTest::TransactionTestOpenCallback::OnCreate(RdbStore &store)
55 {
56 auto [ret, value] = store.Execute(CREATE_TABLE_SQL);
57 return ret;
58 }
59
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)60 int TransactionTest::TransactionTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
61 {
62 return E_OK;
63 }
64
SetUpTestCase()65 void TransactionTest::SetUpTestCase()
66 {
67 int errCode = E_OK;
68 RdbHelper::DeleteRdbStore(DATABASE_NAME);
69 RdbStoreConfig config(DATABASE_NAME);
70 TransactionTestOpenCallback helper;
71 TransactionTest::store_ = RdbHelper::GetRdbStore(config, 1, helper, errCode);
72 ASSERT_NE(TransactionTest::store_, nullptr);
73 ASSERT_EQ(errCode, E_OK);
74 }
75
TearDownTestCase()76 void TransactionTest::TearDownTestCase()
77 {
78 store_ = nullptr;
79 RdbHelper::DeleteRdbStore(DATABASE_NAME);
80 }
81
SetUp()82 void TransactionTest::SetUp()
83 {
84 ASSERT_NE(store_, nullptr);
85 store_->Execute("DELETE FROM test");
86 }
87
TearDown()88 void TransactionTest::TearDown()
89 {
90 }
91
92 /**
93 * @tc.name: RdbStore_Transaction_001
94 * @tc.desc: createTransaction and commit
95 * @tc.type: FUNC
96 */
97 HWTEST_F(TransactionTest, RdbStore_Transaction_001, TestSize.Level1)
98 {
99 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
100
101 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
102 ASSERT_EQ(ret, E_OK);
103 ASSERT_NE(transaction, nullptr);
104
105 auto result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
106 ASSERT_EQ(result.first, E_OK);
107 ASSERT_EQ(1, result.second);
108
109 result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
110 ASSERT_EQ(result.first, E_OK);
111 ASSERT_EQ(2, result.second);
112
113 result = store->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[2]), RdbStore::NO_ACTION);
114 ASSERT_EQ(result.first, E_SQLITE_BUSY);
115
116 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
117 ASSERT_NE(resultSet, nullptr);
118 int32_t rowCount{};
119 ret = resultSet->GetRowCount(rowCount);
120 ASSERT_EQ(ret, E_OK);
121 ASSERT_EQ(rowCount, 2);
122
123 ret = transaction->Commit();
124 ASSERT_EQ(ret, E_OK);
125
126 ValueObject value;
127 ret = resultSet->Get(0, value);
128 ASSERT_EQ(ret, E_ALREADY_CLOSED);
129
130 result = store->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[2]), RdbStore::NO_ACTION);
131 ASSERT_EQ(result.first, E_OK);
132 ASSERT_EQ(3, result.second);
133
134 result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
135 ASSERT_EQ(result.first, E_ALREADY_CLOSED);
136
137 resultSet = store->QueryByStep("SELECT * FROM test");
138 ASSERT_NE(resultSet, nullptr);
139 resultSet->GetRowCount(rowCount);
140 EXPECT_EQ(rowCount, 3);
141 }
142
143 /**
144 * @tc.name: RdbStore_Transaction_002
145 * @tc.desc: createTransaction and rollback
146 * @tc.type: FUNC
147 */
148 HWTEST_F(TransactionTest, RdbStore_Transaction_002, TestSize.Level1)
149 {
150 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
151
152 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
153 ASSERT_EQ(ret, E_OK);
154 ASSERT_NE(transaction, nullptr);
155
156 auto result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
157 ASSERT_EQ(result.first, E_OK);
158 ASSERT_EQ(1, result.second);
159
160 result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
161 ASSERT_EQ(result.first, E_OK);
162 ASSERT_EQ(2, result.second);
163
164 ret = transaction->Rollback();
165 ASSERT_EQ(ret, E_OK);
166
167 auto resultSet = store->QueryByStep("SELECT * FROM test");
168 ASSERT_NE(resultSet, nullptr);
169 int32_t rowCount{};
170 ret = resultSet->GetRowCount(rowCount);
171 ASSERT_EQ(ret, E_OK);
172 ASSERT_EQ(rowCount, 0);
173
174 result = store->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[2]), RdbStore::NO_ACTION);
175 ASSERT_EQ(result.first, E_OK);
176 ASSERT_EQ(3, result.second);
177
178 result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
179 ASSERT_EQ(result.first, E_ALREADY_CLOSED);
180
181 resultSet = store->QueryByStep("SELECT * FROM test");
182 ASSERT_NE(resultSet, nullptr);
183 ret = resultSet->GetRowCount(rowCount);
184 EXPECT_EQ(ret, E_OK);
185 EXPECT_EQ(rowCount, 1);
186 }
187
188 /**
189 * @tc.name: RdbStore_Transaction_003
190 * @tc.desc: batchInsert
191 * @tc.type: FUNC
192 */
193 HWTEST_F(TransactionTest, RdbStore_Transaction_003, TestSize.Level1)
194 {
195 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
196
197 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
198 ASSERT_EQ(ret, E_OK);
199 ASSERT_NE(transaction, nullptr);
200
201 Transaction::Rows rows{
202 UTUtils::SetRowData(UTUtils::g_rowData[0]),
203 UTUtils::SetRowData(UTUtils::g_rowData[1]),
204 UTUtils::SetRowData(UTUtils::g_rowData[2]),
205 };
206 auto result = transaction->BatchInsert("test", rows);
207 ASSERT_EQ(result.first, E_OK);
208 ASSERT_EQ(result.second, 3);
209
210 ret = transaction->Commit();
211 ASSERT_EQ(ret, E_OK);
212
213 auto resultSet = store->QueryByStep("SELECT * FROM test");
214 ASSERT_NE(resultSet, nullptr);
215 int32_t rowCount{};
216 ret = resultSet->GetRowCount(rowCount);
217 EXPECT_EQ(ret, E_OK);
218 EXPECT_EQ(rowCount, 3);
219 }
220
221 /**
222 * @tc.name: RdbStore_Transaction_004
223 * @tc.desc: batchInsert
224 * @tc.type: FUNC
225 */
226 HWTEST_F(TransactionTest, RdbStore_Transaction_004, TestSize.Level1)
227 {
228 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
229
230 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
231 ASSERT_EQ(ret, E_OK);
232 ASSERT_NE(transaction, nullptr);
233
234 Transaction::RefRows rows;
235 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[0]));
236 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[1]));
237 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[2]));
238
239 auto result = transaction->BatchInsert("test", rows);
240 ASSERT_EQ(result.first, E_OK);
241 ASSERT_EQ(result.second, 3);
242
243 ret = transaction->Commit();
244 ASSERT_EQ(ret, E_OK);
245
246 auto resultSet = store->QueryByStep("SELECT * FROM test");
247 ASSERT_NE(resultSet, nullptr);
248 int32_t rowCount{};
249 ret = resultSet->GetRowCount(rowCount);
250 EXPECT_EQ(ret, E_OK);
251 EXPECT_EQ(rowCount, 3);
252 }
253
254 /**
255 * @tc.name: RdbStore_Transaction_005
256 * @tc.desc: Update
257 * @tc.type: FUNC
258 */
259 HWTEST_F(TransactionTest, RdbStore_Transaction_005, TestSize.Level1)
260 {
261 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
262
263 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
264 ASSERT_EQ(ret, E_OK);
265 ASSERT_NE(transaction, nullptr);
266
267 auto result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
268 ASSERT_EQ(result.first, E_OK);
269 ASSERT_EQ(result.second, 1);
270
271 result = transaction->Update("test", UTUtils::SetRowData(UTUtils::g_rowData[1]), "id=1");
272 ASSERT_EQ(result.first, E_OK);
273 ASSERT_EQ(result.second, 1);
274
275 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
276 ASSERT_NE(resultSet, nullptr);
277 int32_t rowCount{};
278 ret = resultSet->GetRowCount(rowCount);
279 ASSERT_EQ(ret, E_OK);
280 ASSERT_EQ(rowCount, 1);
281 ret = resultSet->GoToFirstRow();
282 ASSERT_EQ(ret, E_OK);
283 int32_t columnIndex{};
284 ret = resultSet->GetColumnIndex("id", columnIndex);
285 ASSERT_EQ(ret, E_OK);
286 int32_t id{};
287 ret = resultSet->GetInt(columnIndex, id);
288 ASSERT_EQ(ret, E_OK);
289 ASSERT_EQ(id, 2);
290
291 AbsRdbPredicates predicates("test");
292 predicates.EqualTo("id", ValueObject(2));
293 result = transaction->Update(UTUtils::SetRowData(UTUtils::g_rowData[2]), predicates);
294 ASSERT_EQ(result.first, E_OK);
295 ASSERT_EQ(result.second, 1);
296
297 ret = transaction->Commit();
298 ASSERT_EQ(ret, E_OK);
299
300 resultSet = store->QueryByStep("SELECT * FROM test");
301 ASSERT_NE(resultSet, nullptr);
302 ret = resultSet->GetRowCount(rowCount);
303 ASSERT_EQ(ret, E_OK);
304 ASSERT_EQ(rowCount, 1);
305 ret = resultSet->GoToFirstRow();
306 ASSERT_EQ(ret, E_OK);
307 resultSet->GetColumnIndex("id", columnIndex);
308 ret = resultSet->GetInt(columnIndex, id);
309 EXPECT_EQ(ret, E_OK);
310 EXPECT_EQ(id, 3);
311 }
312
313 /**
314 * @tc.name: RdbStore_Transaction_006
315 * @tc.desc: Delete
316 * @tc.type: FUNC
317 */
318 HWTEST_F(TransactionTest, RdbStore_Transaction_006, TestSize.Level1)
319 {
320 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
321
322 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
323 ASSERT_EQ(ret, E_OK);
324 ASSERT_NE(transaction, nullptr);
325
326 Transaction::RefRows rows;
327 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[0]));
328 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[1]));
329 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[2]));
330
331 auto result = transaction->BatchInsert("test", rows);
332 ASSERT_EQ(result.first, E_OK);
333 ASSERT_EQ(result.second, 3);
334
335 result = transaction->Delete("test", "id=1");
336 ASSERT_EQ(result.first, E_OK);
337 ASSERT_EQ(result.second, 1);
338
339 AbsRdbPredicates predicates("test");
340 predicates.EqualTo("id", ValueObject(2));
341 result = transaction->Delete(predicates);
342 ASSERT_EQ(result.first, E_OK);
343 ASSERT_EQ(result.second, 1);
344
345 ret = transaction->Commit();
346 ASSERT_EQ(ret, E_OK);
347
348 auto resultSet = store->QueryByStep("SELECT * FROM test");
349 ASSERT_NE(resultSet, nullptr);
350 int32_t rowCount{};
351 ret = resultSet->GetRowCount(rowCount);
352 ASSERT_EQ(ret, E_OK);
353 ASSERT_EQ(rowCount, 1);
354 ret = resultSet->GoToFirstRow();
355 ASSERT_EQ(ret, E_OK);
356 int32_t columnIndex{};
357 resultSet->GetColumnIndex("id", columnIndex);
358 int32_t id{};
359 ret = resultSet->GetInt(columnIndex, id);
360 EXPECT_EQ(ret, E_OK);
361 EXPECT_EQ(id, 3);
362 }
363
364 /**
365 * @tc.name: RdbStore_Transaction_007
366 * @tc.desc: Execute
367 * @tc.type: FUNC
368 */
369 HWTEST_F(TransactionTest, RdbStore_Transaction_007, TestSize.Level1)
370 {
371 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
372
373 store->Execute("DROP TABLE IF EXISTS test1");
374 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
375 ASSERT_EQ(res.first, E_OK);
376 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
377 ASSERT_EQ(ret, E_OK);
378 ASSERT_NE(transaction, nullptr);
379
380 Transaction::Row row;
381 row.Put("id", 1);
382 row.Put("name", "Jim");
383 auto result = transaction->Insert("test1", row);
384 ASSERT_EQ(result.first, E_OK);
385 ASSERT_EQ(result.second, 1);
386
387 ret = transaction->Commit();
388 ASSERT_EQ(ret, E_OK);
389
390 auto resultSet = store->QueryByStep("SELECT * FROM test1");
391 ASSERT_NE(resultSet, nullptr);
392 int32_t rowCount{};
393 ret = resultSet->GetRowCount(rowCount);
394 EXPECT_EQ(ret, E_OK);
395 EXPECT_EQ(rowCount, 1);
396 }
397
398 /**
399 * @tc.name: RdbStore_Transaction_008
400 * @tc.desc: Insert with ConflictResolution::ON_CONFLICT_ROLLBACK
401 * @tc.type: FUNC
402 */
403 HWTEST_F(TransactionTest, RdbStore_Transaction_008, TestSize.Level1)
404 {
405 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
406 store->Execute("DROP TABLE IF EXISTS test1");
407 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
408 ASSERT_EQ(res.first, E_OK);
409 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
410 ASSERT_EQ(ret, E_OK);
411 ASSERT_NE(transaction, nullptr);
412
413 Transaction::Row row;
414 row.Put("id", 1);
415 row.Put("name", "Jim");
416 auto result = transaction->Insert("test1", row);
417 ASSERT_EQ(result.first, E_OK);
418 ASSERT_EQ(result.second, 1);
419
420 result = transaction->Insert("test1", row, ConflictResolution::ON_CONFLICT_ROLLBACK);
421 ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
422 ASSERT_EQ(result.second, -1);
423 ASSERT_EQ(transaction->Commit(), E_SQLITE_ERROR);
424
425 auto resultSet = store->QueryByStep("SELECT * FROM test1");
426 ASSERT_NE(resultSet, nullptr);
427 int32_t rowCount{};
428 ret = resultSet->GetRowCount(rowCount);
429 EXPECT_EQ(ret, E_OK);
430 EXPECT_EQ(rowCount, 0);
431 }
432
433 /**
434 * @tc.name: RdbStore_Transaction_009
435 * @tc.desc: Update with ConflictResolution::ON_CONFLICT_ROLLBACK
436 * @tc.type: FUNC
437 */
438 HWTEST_F(TransactionTest, RdbStore_Transaction_009, TestSize.Level1)
439 {
440 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
441 store->Execute("DROP TABLE IF EXISTS test1");
442 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
443 ASSERT_EQ(res.first, E_OK);
444 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
445 ASSERT_EQ(ret, E_OK);
446 ASSERT_NE(transaction, nullptr);
447
448 Transaction::Row row;
449 row.Put("id", 1);
450 row.Put("name", "Jim");
451 auto result = transaction->Insert("test1", row);
452 ASSERT_EQ(result.first, E_OK);
453 ASSERT_EQ(result.second, 1);
454
455 row.Put("name", ValueObject());
456 result = transaction->Update(
457 "test1", row, "id = ?", std::vector<ValueObject>{ "1" }, ConflictResolution::ON_CONFLICT_ROLLBACK);
458 ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
459 ASSERT_EQ(result.second, 0);
460 ASSERT_EQ(transaction->Commit(), E_SQLITE_ERROR);
461
462 auto resultSet = store->QueryByStep("SELECT * FROM test1");
463 ASSERT_NE(resultSet, nullptr);
464 int32_t rowCount{};
465 ret = resultSet->GetRowCount(rowCount);
466 EXPECT_EQ(ret, E_OK);
467 EXPECT_EQ(rowCount, 0);
468 }
469
470 /**
471 * @tc.name: RdbStore_Transaction_010
472 * @tc.desc: Update with ConflictResolution::ON_CONFLICT_ROLLBACK
473 * @tc.type: FUNC
474 */
475 HWTEST_F(TransactionTest, RdbStore_Transaction_010, TestSize.Level1)
476 {
477 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
478 store->Execute("DROP TABLE IF EXISTS test1");
479 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
480 ASSERT_EQ(res.first, E_OK);
481 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
482 ASSERT_EQ(ret, E_OK);
483 ASSERT_NE(transaction, nullptr);
484
485 Transaction::Row row;
486 row.Put("id", 1);
487 row.Put("name", "Jim");
488 auto result = transaction->Insert("test1", row);
489 ASSERT_EQ(result.first, E_OK);
490 ASSERT_EQ(result.second, 1);
491
492 row.Put("name", ValueObject());
493 AbsRdbPredicates predicates("test1");
494 predicates.EqualTo("id", 1);
495 result = transaction->Update(row, predicates, ConflictResolution::ON_CONFLICT_ROLLBACK);
496 ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
497 ASSERT_EQ(result.second, 0);
498 ASSERT_EQ(transaction->Commit(), E_SQLITE_ERROR);
499
500 auto resultSet = store->QueryByStep("SELECT * FROM test1");
501 ASSERT_NE(resultSet, nullptr);
502 int32_t rowCount{};
503 ret = resultSet->GetRowCount(rowCount);
504 EXPECT_EQ(ret, E_OK);
505 EXPECT_EQ(rowCount, 0);
506 }
507
508 /**
509 * @tc.name: RdbStore_Transaction_011
510 * @tc.desc: BatchInsert with ConflictResolution::ON_CONFLICT_ROLLBACK
511 * @tc.type: FUNC
512 */
513 HWTEST_F(TransactionTest, RdbStore_Transaction_011, TestSize.Level1)
514 {
515 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
516 store->Execute("DROP TABLE IF EXISTS test1");
517 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
518 ASSERT_EQ(res.first, E_OK);
519 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
520 ASSERT_EQ(ret, E_OK);
521 ASSERT_NE(transaction, nullptr);
522
523 ValuesBuckets rows;
524 for (int i = 0; i < 5; i++) {
525 Transaction::Row row;
526 row.Put("id", i);
527 row.Put("name", "Jim");
528 rows.Put(row);
529 }
530 Transaction::Row row;
531 row.Put("id", 2);
532 row.Put("name", "Jim");
533 auto result = transaction->Insert("test1", row);
534 ASSERT_EQ(result.first, E_OK);
535 ASSERT_EQ(result.second, 2);
536 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_ROLLBACK);
537 ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
538 ASSERT_EQ(result.second, 0);
539 ASSERT_EQ(transaction->Commit(), E_SQLITE_ERROR);
540
541 auto resultSet = store->QueryByStep("SELECT * FROM test1");
542 ASSERT_NE(resultSet, nullptr);
543 int32_t rowCount{};
544 ret = resultSet->GetRowCount(rowCount);
545 EXPECT_EQ(ret, E_OK);
546 EXPECT_EQ(rowCount, 0);
547 }
548
549 /**
550 * @tc.name: RdbStore_Transaction_012
551 * @tc.desc: BatchInsert with ConflictResolution::ON_CONFLICT_ABORT
552 * @tc.type: FUNC
553 */
554 HWTEST_F(TransactionTest, RdbStore_Transaction_012, TestSize.Level1)
555 {
556 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
557 store->Execute("DROP TABLE IF EXISTS test1");
558 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
559 ASSERT_EQ(res.first, E_OK);
560 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
561 ASSERT_EQ(ret, E_OK);
562 ASSERT_NE(transaction, nullptr);
563
564 ValuesBuckets rows;
565 for (int i = 0; i < 5; i++) {
566 Transaction::Row row;
567 row.Put("id", i);
568 row.Put("name", "Jim");
569 rows.Put(row);
570 }
571 Transaction::Row row;
572 row.Put("id", 2);
573 row.Put("name", "Jim");
574 auto result = transaction->Insert("test1", row);
575 ASSERT_EQ(result.first, E_OK);
576 ASSERT_EQ(result.second, 2);
577 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_ABORT);
578 ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
579 ASSERT_EQ(result.second, 0);
580 ASSERT_EQ(transaction->Commit(), E_OK);
581
582 auto resultSet = store->QueryByStep("SELECT * FROM test1");
583 ASSERT_NE(resultSet, nullptr);
584 int32_t rowCount{};
585 ret = resultSet->GetRowCount(rowCount);
586 EXPECT_EQ(ret, E_OK);
587 EXPECT_EQ(rowCount, 1);
588 }
589
590 /**
591 * @tc.name: RdbStore_Transaction_013
592 * @tc.desc: BatchInsert with ConflictResolution::ON_CONFLICT_FAIL
593 * @tc.type: FUNC
594 */
595 HWTEST_F(TransactionTest, RdbStore_Transaction_013, TestSize.Level1)
596 {
597 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
598 store->Execute("DROP TABLE IF EXISTS test1");
599 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
600 ASSERT_EQ(res.first, E_OK);
601 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
602 ASSERT_EQ(ret, E_OK);
603 ASSERT_NE(transaction, nullptr);
604
605 ValuesBuckets rows;
606 for (int i = 0; i < 5; i++) {
607 Transaction::Row row;
608 row.Put("id", i);
609 row.Put("name", "Jim");
610 rows.Put(row);
611 }
612 Transaction::Row row;
613 row.Put("id", 2);
614 row.Put("name", "Jim");
615 auto result = transaction->Insert("test1", row);
616 ASSERT_EQ(result.first, E_OK);
617 ASSERT_EQ(result.second, 2);
618 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_FAIL);
619 ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
620 ASSERT_EQ(result.second, 2);
621 ASSERT_EQ(transaction->Commit(), E_OK);
622
623 auto resultSet = store->QueryByStep("SELECT * FROM test1");
624 ASSERT_NE(resultSet, nullptr);
625 int32_t rowCount{};
626 ret = resultSet->GetRowCount(rowCount);
627 EXPECT_EQ(ret, E_OK);
628 EXPECT_EQ(rowCount, 3);
629 }
630
631 /**
632 * @tc.name: RdbStore_Transaction_014
633 * @tc.desc: BatchInsert with ConflictResolution::ON_CONFLICT_IGNORE
634 * @tc.type: FUNC
635 */
636 HWTEST_F(TransactionTest, RdbStore_Transaction_014, TestSize.Level1)
637 {
638 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
639 store->Execute("DROP TABLE IF EXISTS test1");
640 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
641 ASSERT_EQ(res.first, E_OK);
642 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
643 ASSERT_EQ(ret, E_OK);
644 ASSERT_NE(transaction, nullptr);
645
646 ValuesBuckets rows;
647 for (int i = 0; i < 5; i++) {
648 Transaction::Row row;
649 row.Put("id", i);
650 row.Put("name", "Jim_batchInsert");
651 rows.Put(row);
652 }
653 Transaction::Row row;
654 row.Put("id", 2);
655 row.Put("name", "Jim_insert");
656 auto result = transaction->Insert("test1", row);
657 ASSERT_EQ(result.first, E_OK);
658 ASSERT_EQ(result.second, 2);
659 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_IGNORE);
660 ASSERT_EQ(result.first, E_OK);
661 ASSERT_EQ(result.second, 4);
662 ASSERT_EQ(transaction->Commit(), E_OK);
663
664 auto resultSet = store->QueryByStep("SELECT * FROM test1");
665 ASSERT_NE(resultSet, nullptr);
666 int32_t rowCount{};
667 ret = resultSet->GetRowCount(rowCount);
668 EXPECT_EQ(ret, E_OK);
669 EXPECT_EQ(rowCount, 5);
670 resultSet = store->QueryByStep("SELECT * FROM test1 where id = 2");
671 ASSERT_NE(resultSet, nullptr);
672 ASSERT_EQ(resultSet->GoToFirstRow(), E_OK);
673 int columnIndex = -1;
674 ASSERT_EQ(resultSet->GetColumnIndex("name", columnIndex), E_OK);
675 std::string name;
676 EXPECT_EQ(resultSet->GetString(columnIndex, name), E_OK);
677 EXPECT_EQ(name, "Jim_insert");
678 }
679
680 /**
681 * @tc.name: RdbStore_Transaction_015
682 * @tc.desc: BatchInsert with ConflictResolution::ON_CONFLICT_REPLACE
683 * @tc.type: FUNC
684 */
685 HWTEST_F(TransactionTest, RdbStore_Transaction_015, TestSize.Level1)
686 {
687 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
688 store->Execute("DROP TABLE IF EXISTS test1");
689 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
690 ASSERT_EQ(res.first, E_OK);
691 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
692 ASSERT_EQ(ret, E_OK);
693 ASSERT_NE(transaction, nullptr);
694
695 ValuesBuckets rows;
696 for (int i = 0; i < 5; i++) {
697 Transaction::Row row;
698 row.Put("id", i);
699 row.Put("name", "Jim_batchInsert");
700 rows.Put(row);
701 }
702 Transaction::Row row;
703 row.Put("id", 2);
704 row.Put("name", "Jim_insert");
705 auto result = transaction->Insert("test1", row);
706 ASSERT_EQ(result.first, E_OK);
707 ASSERT_EQ(result.second, 2);
708 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_REPLACE);
709 ASSERT_EQ(result.first, E_OK);
710 ASSERT_EQ(result.second, 5);
711 ASSERT_EQ(transaction->Commit(), E_OK);
712
713 auto resultSet = store->QueryByStep("SELECT * FROM test1");
714 ASSERT_NE(resultSet, nullptr);
715 int32_t rowCount{};
716 ret = resultSet->GetRowCount(rowCount);
717 EXPECT_EQ(ret, E_OK);
718 EXPECT_EQ(rowCount, 5);
719 resultSet = store->QueryByStep("SELECT * FROM test1 where id = 2");
720 ASSERT_NE(resultSet, nullptr);
721 ASSERT_EQ(resultSet->GoToFirstRow(), E_OK);
722 int columnIndex = -1;
723 ASSERT_EQ(resultSet->GetColumnIndex("name", columnIndex), E_OK);
724 std::string name;
725 EXPECT_EQ(resultSet->GetString(columnIndex, name), E_OK);
726 EXPECT_EQ(name, "Jim_batchInsert");
727 }
728
729 /**
730 * @tc.name: RdbStore_Transaction_016
731 * @tc.desc: BatchInsert with ConflictResolution::ON_CONFLICT_REPLACE and failed
732 * @tc.type: FUNC
733 */
734 HWTEST_F(TransactionTest, RdbStore_Transaction_016, TestSize.Level1)
735 {
736 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
737 store->Execute("DROP TABLE IF EXISTS test1");
738 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
739 ASSERT_EQ(res.first, E_OK);
740 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
741 ASSERT_EQ(ret, E_OK);
742 ASSERT_NE(transaction, nullptr);
743
744 ValuesBuckets rows;
745 for (int i = 0; i < 5; i++) {
746 Transaction::Row row;
747 row.Put("id", i);
748 row.Put("name", i == 2 ? ValueObject() : "Jim_batchInsert");
749 rows.Put(row);
750 }
751 Transaction::Row row;
752 row.Put("id", 2);
753 row.Put("name", "Jim_insert");
754 auto result = transaction->Insert("test1", row);
755 ASSERT_EQ(result.first, E_OK);
756 ASSERT_EQ(result.second, 2);
757 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_REPLACE);
758 // ON_CONFLICT_REPLACE is equivalent to ON_CONFLICT_ABORT after failure
759 ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
760 ASSERT_EQ(result.second, 0);
761 ASSERT_EQ(transaction->Commit(), E_OK);
762
763 auto resultSet = store->QueryByStep("SELECT * FROM test1");
764 ASSERT_NE(resultSet, nullptr);
765 ASSERT_EQ(resultSet->GoToFirstRow(), E_OK);
766 int columnIndex = -1;
767 ASSERT_EQ(resultSet->GetColumnIndex("name", columnIndex), E_OK);
768 std::string name;
769 EXPECT_EQ(resultSet->GetString(columnIndex, name), E_OK);
770 EXPECT_EQ(name, "Jim_insert");
771 }
772
773 /**
774 * @tc.name: RdbStore_Transaction_017
775 * @tc.desc: BatchInsert when busy
776 * @tc.type: FUNC
777 */
778 HWTEST_F(TransactionTest, RdbStore_Transaction_017, TestSize.Level1)
779 {
780 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
781 store->Execute("DROP TABLE IF EXISTS test1");
782 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
783 ASSERT_EQ(res.first, E_OK);
784 auto [ret1, transaction1] = store->CreateTransaction(Transaction::EXCLUSIVE);
785 ASSERT_EQ(ret1, E_OK);
786 ASSERT_NE(transaction1, nullptr);
787
788 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
789 ASSERT_EQ(ret, E_OK);
790 ASSERT_NE(transaction, nullptr);
791
792 ValuesBuckets rows;
793 for (int i = 0; i < 5; i++) {
794 Transaction::Row row;
795 row.Put("id", i);
796 row.Put("name", "Jim_batchInsert");
797 rows.Put(row);
798 }
799 auto result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_NONE);
800 ASSERT_EQ(result.first, E_SQLITE_BUSY);
801 ASSERT_EQ(result.second, -1);
802
803 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_ROLLBACK);
804 ASSERT_EQ(result.first, E_SQLITE_BUSY);
805 ASSERT_EQ(result.second, -1);
806
807 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_ABORT);
808 ASSERT_EQ(result.first, E_SQLITE_BUSY);
809 ASSERT_EQ(result.second, -1);
810
811 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_FAIL);
812 ASSERT_EQ(result.first, E_SQLITE_BUSY);
813 ASSERT_EQ(result.second, -1);
814
815 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_IGNORE);
816 ASSERT_EQ(result.first, E_SQLITE_BUSY);
817 ASSERT_EQ(result.second, -1);
818
819 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_REPLACE);
820 ASSERT_EQ(result.first, E_SQLITE_BUSY);
821 ASSERT_EQ(result.second, -1);
822 }
823
824 /**
825 * @tc.name: RdbStore_Transaction_018
826 * @tc.desc: BatchInsert when over limit rows
827 * @tc.type: FUNC
828 */
829 HWTEST_F(TransactionTest, RdbStore_Transaction_018, TestSize.Level1)
830 {
831 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
832 store->Execute("DROP TABLE IF EXISTS test1");
833 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
834 ASSERT_EQ(res.first, E_OK);
835
836 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
837 ASSERT_EQ(ret, E_OK);
838 ASSERT_NE(transaction, nullptr);
839
840 //sqlite default max param number
841 int32_t maxNumber = 32766;
842 int32_t maxRows = maxNumber / 2 + 1;
843 ValuesBuckets rows;
844 for (int32_t i = 0; i < maxRows; i++) {
845 Transaction::Row row;
846 row.Put("id", i);
847 row.Put("name", "Jim_batchInsert");
848 rows.Put(row);
849 }
850 auto result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_NONE);
851 ASSERT_EQ(result.first, E_INVALID_ARGS);
852 ASSERT_EQ(result.second, -1);
853
854 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_ROLLBACK);
855 ASSERT_EQ(result.first, E_INVALID_ARGS);
856 ASSERT_EQ(result.second, -1);
857
858 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_ABORT);
859 ASSERT_EQ(result.first, E_INVALID_ARGS);
860 ASSERT_EQ(result.second, -1);
861
862 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_FAIL);
863 ASSERT_EQ(result.first, E_INVALID_ARGS);
864 ASSERT_EQ(result.second, -1);
865
866 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_IGNORE);
867 ASSERT_EQ(result.first, E_INVALID_ARGS);
868 ASSERT_EQ(result.second, -1);
869
870 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_REPLACE);
871 ASSERT_EQ(result.first, E_INVALID_ARGS);
872 ASSERT_EQ(result.second, -1);
873 }
874
875 /**
876 * @tc.name: RdbStore_Transaction_019
877 * @tc.desc: Normal BatchInsert
878 * @tc.type: FUNC
879 */
880 HWTEST_F(TransactionTest, RdbStore_Transaction_019, TestSize.Level1)
881 {
882 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
883 store->Execute("DROP TABLE IF EXISTS test1");
884 auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
885 ASSERT_EQ(res.first, E_OK);
886 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
887 ASSERT_EQ(ret, E_OK);
888 ASSERT_NE(transaction, nullptr);
889
890 ValuesBuckets rows;
891 auto result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_NONE);
892 ASSERT_EQ(result.first, E_OK);
893 ASSERT_EQ(result.second, 0);
894 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_ROLLBACK);
895 ASSERT_EQ(result.first, E_OK);
896 ASSERT_EQ(result.second, 0);
897 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_ABORT);
898 ASSERT_EQ(result.first, E_OK);
899 ASSERT_EQ(result.second, 0);
900 for (int i = 0; i < 2; i++) {
901 Transaction::Row row;
902 row.Put("name", "Jim_batchInsert");
903 rows.Put(row);
904 }
905 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_FAIL);
906 ASSERT_EQ(result.first, E_OK);
907 ASSERT_EQ(result.second, 2);
908 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_IGNORE);
909 ASSERT_EQ(result.first, E_OK);
910 ASSERT_EQ(result.second, 2);
911 result = transaction->BatchInsert("test1", rows, ConflictResolution::ON_CONFLICT_REPLACE);
912 ASSERT_EQ(result.first, E_OK);
913 ASSERT_EQ(result.second, 2);
914
915 ASSERT_EQ(transaction->Commit(), E_OK);
916 auto resultSet = store->QueryByStep("SELECT * FROM test1");
917 ASSERT_NE(resultSet, nullptr);
918 int32_t rowCount{};
919 ret = resultSet->GetRowCount(rowCount);
920 EXPECT_EQ(ret, E_OK);
921 EXPECT_EQ(rowCount, 6);
922 }
923
924 /**
925 * @tc.name: RdbStore_Transaction_020
926 * @tc.desc: After executing the ddl statement, the transaction links cached in the history need to be cleared.
927 * Continuing to use the old connections will result in errors due to changes in the table structure.
928 * @tc.type: FUNC
929 */
930 HWTEST_F(TransactionTest, RdbStore_Transaction_020, TestSize.Level1)
931 {
932 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
933
934 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
935 ASSERT_EQ(ret, E_OK);
936 ASSERT_NE(transaction, nullptr);
937
938 Transaction::Row row;
939 row.Put("id", 1);
940 row.Put("name", "Jim");
941 auto result = transaction->Insert("test", row);
942 ASSERT_EQ(result.first, E_OK);
943 ASSERT_EQ(result.second, 1);
944
945 ret = transaction->Commit();
946 ASSERT_EQ(ret, E_OK);
947 transaction = nullptr;
948
949 store->Execute("DROP TABLE IF EXISTS test1");
950 auto res = store->Execute(
951 "CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
952 ASSERT_EQ(res.first, E_OK);
953 // After creating the table, the links will be cleared, and creating a new transaction will create a new connection,
954 // ensuring that the transaction operation does not report errors.
955 std::tie(ret, transaction) = store->CreateTransaction(Transaction::DEFERRED);
956 ASSERT_EQ(ret, E_OK);
957 ASSERT_NE(transaction, nullptr);
958
959 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
960 ASSERT_NE(resultSet, nullptr);
961 int32_t rowCount{};
962 ret = resultSet->GetRowCount(rowCount);
963 EXPECT_EQ(ret, E_OK);
964 EXPECT_EQ(rowCount, 1);
965 }
966
967 /**
968 * @tc.name: RdbStore_Transaction_021
969 * @tc.desc: Abnormal testcase of Insert after commit.
970 * @tc.type: FUNC
971 */
972 HWTEST_F(TransactionTest, RdbStore_Transaction_021, TestSize.Level1)
973 {
974 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
975
976 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
977 ASSERT_EQ(ret, E_OK);
978 ASSERT_NE(transaction, nullptr);
979
980 ret = transaction->Commit();
981 EXPECT_EQ(ret, E_OK);
982
983 auto [err, rows] = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]), Transaction::NO_ACTION);
984 EXPECT_EQ(err, E_ALREADY_CLOSED);
985 }
986
987 /**
988 * @tc.name: RdbStore_Transaction_022
989 * @tc.desc: Abnormal testcase of BatchInsert after commit.
990 * @tc.type: FUNC
991 */
992 HWTEST_F(TransactionTest, RdbStore_Transaction_022, TestSize.Level1)
993 {
994 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
995
996 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
997 ASSERT_EQ(ret, E_OK);
998 ASSERT_NE(transaction, nullptr);
999
1000 ret = transaction->Commit();
1001 EXPECT_EQ(ret, E_OK);
1002
1003 Transaction::Rows rows{
1004 UTUtils::SetRowData(UTUtils::g_rowData[0]),
1005 UTUtils::SetRowData(UTUtils::g_rowData[1]),
1006 UTUtils::SetRowData(UTUtils::g_rowData[2]),
1007 };
1008 auto result = transaction->BatchInsert("test", rows);
1009 ASSERT_EQ(result.first, E_ALREADY_CLOSED);
1010 ASSERT_EQ(result.second, -1);
1011 }
1012
1013 /**
1014 * @tc.name: RdbStore_Transaction_023
1015 * @tc.desc: Abnormal testcase of BatchInsert after commit.
1016 * @tc.type: FUNC
1017 */
1018 HWTEST_F(TransactionTest, RdbStore_Transaction_023, TestSize.Level1)
1019 {
1020 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1021
1022 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1023 ASSERT_EQ(ret, E_OK);
1024 ASSERT_NE(transaction, nullptr);
1025
1026 ret = transaction->Commit();
1027 EXPECT_EQ(ret, E_OK);
1028
1029 Transaction::RefRows rows;
1030 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[0]));
1031 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[1]));
1032 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[2]));
1033 auto result = transaction->BatchInsert("test", rows);
1034 ASSERT_EQ(result.first, E_ALREADY_CLOSED);
1035 ASSERT_EQ(result.second, -1);
1036 }
1037
1038 /**
1039 * @tc.name: RdbStore_Transaction_024
1040 * @tc.desc: Abnormal testcase of BatchInsert after commit.
1041 * @tc.type: FUNC
1042 */
1043 HWTEST_F(TransactionTest, RdbStore_Transaction_024, TestSize.Level1)
1044 {
1045 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1046
1047 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1048 ASSERT_EQ(ret, E_OK);
1049 ASSERT_NE(transaction, nullptr);
1050
1051 ret = transaction->Commit();
1052 EXPECT_EQ(ret, E_OK);
1053
1054 ValuesBuckets rows;
1055 for (int i = 0; i < 5; i++) {
1056 Transaction::Row row;
1057 row.Put("id", i);
1058 row.Put("name", "Jim");
1059 rows.Put(row);
1060 }
1061 auto result = transaction->BatchInsert("test", rows, ConflictResolution::ON_CONFLICT_ROLLBACK);
1062 ASSERT_EQ(result.first, E_ALREADY_CLOSED);
1063
1064 auto res = transaction->BatchInsert("test", rows, { "id" }, ConflictResolution::ON_CONFLICT_ROLLBACK);
1065 ASSERT_EQ(res.first, E_ALREADY_CLOSED);
1066 }
1067
1068 /**
1069 * @tc.name: RdbStore_Transaction_025
1070 * @tc.desc: Abnormal testcase of Update after commit.
1071 * @tc.type: FUNC
1072 */
1073 HWTEST_F(TransactionTest, RdbStore_Transaction_025, TestSize.Level1)
1074 {
1075 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1076
1077 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1078 ASSERT_EQ(ret, E_OK);
1079 ASSERT_NE(transaction, nullptr);
1080
1081 ret = transaction->Commit();
1082 EXPECT_EQ(ret, E_OK);
1083
1084 auto result = transaction->Update("test", UTUtils::SetRowData(UTUtils::g_rowData[1]), "id=1");
1085 ASSERT_EQ(result.first, E_ALREADY_CLOSED);
1086 }
1087
1088 /**
1089 * @tc.name: RdbStore_Transaction_026
1090 * @tc.desc: Abnormal testcase of Update after commit.
1091 * @tc.type: FUNC
1092 */
1093 HWTEST_F(TransactionTest, RdbStore_Transaction_026, TestSize.Level1)
1094 {
1095 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1096
1097 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1098 ASSERT_EQ(ret, E_OK);
1099 ASSERT_NE(transaction, nullptr);
1100
1101 ret = transaction->Commit();
1102 EXPECT_EQ(ret, E_OK);
1103
1104 AbsRdbPredicates predicates("test");
1105 predicates.EqualTo("id", ValueObject(2));
1106 auto result = transaction->Update(UTUtils::SetRowData(UTUtils::g_rowData[2]), predicates);
1107 ASSERT_EQ(result.first, E_ALREADY_CLOSED);
1108 }
1109
1110 /**
1111 * @tc.name: RdbStore_Transaction_027
1112 * @tc.desc: Abnormal testcase of Delete after commit.
1113 * @tc.type: FUNC
1114 */
1115 HWTEST_F(TransactionTest, RdbStore_Transaction_027, TestSize.Level1)
1116 {
1117 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1118
1119 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1120 ASSERT_EQ(ret, E_OK);
1121 ASSERT_NE(transaction, nullptr);
1122
1123 ret = transaction->Commit();
1124 EXPECT_EQ(ret, E_OK);
1125
1126 auto result = transaction->Delete("test", "id=1");
1127 ASSERT_EQ(result.first, E_ALREADY_CLOSED);
1128 ASSERT_EQ(result.second, -1);
1129
1130 AbsRdbPredicates predicates("test");
1131 predicates.EqualTo("id", ValueObject(2));
1132 result = transaction->Delete(predicates);
1133 ASSERT_EQ(result.first, E_ALREADY_CLOSED);
1134 ASSERT_EQ(result.second, -1);
1135 }
1136
1137 /**
1138 * @tc.name: RdbStore_Transaction_028
1139 * @tc.desc: Abnormal testcase of QueryByStep after commit.
1140 * @tc.type: FUNC
1141 */
1142 HWTEST_F(TransactionTest, RdbStore_Transaction_028, TestSize.Level1)
1143 {
1144 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1145
1146 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1147 ASSERT_EQ(ret, E_OK);
1148 ASSERT_NE(transaction, nullptr);
1149
1150 ret = transaction->Commit();
1151 EXPECT_EQ(ret, E_OK);
1152
1153 auto result = transaction->QueryByStep("SELECT * FROM test");
1154 ASSERT_EQ(result, nullptr);
1155
1156 AbsRdbPredicates predicates("test");
1157 predicates.EqualTo("id", ValueObject(2));
1158 result = transaction->QueryByStep(predicates);
1159 ASSERT_EQ(result, nullptr);
1160 }
1161
1162 /**
1163 * @tc.name: RdbStore_Transaction_029
1164 * @tc.desc: Abnormal testcase of QueryByStep after commit.
1165 * @tc.type: FUNC
1166 */
1167 HWTEST_F(TransactionTest, RdbStore_Transaction_029, TestSize.Level1)
1168 {
1169 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1170
1171 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1172 ASSERT_EQ(ret, E_OK);
1173 ASSERT_NE(transaction, nullptr);
1174
1175 ret = transaction->Commit();
1176 EXPECT_EQ(ret, E_OK);
1177
1178 auto result = transaction->Execute(CREATE_TABLE_SQL);
1179 ASSERT_EQ(result.first, E_ALREADY_CLOSED);
1180
1181 auto res = transaction->ExecuteExt(CREATE_TABLE_SQL);
1182 ASSERT_EQ(res.first, E_ALREADY_CLOSED);
1183 }
1184
1185 /**
1186 * @tc.name: RdbStore_Transaction_030
1187 * @tc.desc: Abnormal testcase of commit after commit and rollback.
1188 * @tc.type: FUNC
1189 */
1190 HWTEST_F(TransactionTest, RdbStore_Transaction_030, TestSize.Level1)
1191 {
1192 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1193
1194 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1195 ASSERT_EQ(ret, E_OK);
1196 ASSERT_NE(transaction, nullptr);
1197
1198 ret = transaction->Commit();
1199 EXPECT_EQ(ret, E_OK);
1200
1201 ret = transaction->Commit();
1202 EXPECT_EQ(ret, E_ALREADY_CLOSED);
1203
1204 ret = transaction->Rollback();
1205 EXPECT_EQ(ret, E_ALREADY_CLOSED);
1206 }
1207
1208 /**
1209 * @tc.name: RdbStore_Transaction_031
1210 * @tc.desc: normal testcase of batch insert with returning 1.
1211 * @tc.type: FUNC
1212 */
1213 HWTEST_F(TransactionTest, RdbStore_Transaction_031, TestSize.Level1)
1214 {
1215 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1216
1217 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1218 ASSERT_EQ(ret, E_OK);
1219 ASSERT_NE(transaction, nullptr);
1220 ValuesBuckets rows;
1221 for (int i = 0; i < 1; i++) {
1222 ValuesBucket row;
1223 row.Put("id", i);
1224 row.Put("name", "Jim");
1225 rows.Put(row);
1226 }
1227 std::string returningField = "id";
1228 auto [status, result] = transaction->BatchInsert("test", rows, { returningField });
1229 EXPECT_EQ(status, E_OK);
1230 EXPECT_EQ(result.changed, 1);
1231
1232 int rowCount = -1;
1233 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1234 EXPECT_EQ(rowCount, 1);
1235
1236 int columnIndex = -1;
1237 ASSERT_EQ(result.results->GetColumnIndex(returningField, columnIndex), E_OK);
1238 int value = -1;
1239 result.results->GetInt(columnIndex, value);
1240 EXPECT_EQ(value, 0);
1241 ret = transaction->Commit();
1242 EXPECT_EQ(ret, E_OK);
1243 }
1244
1245 /**
1246 * @tc.name: RdbStore_Transaction_032
1247 * @tc.desc: normal testcase of batch insert with returning 0.
1248 * @tc.type: FUNC
1249 */
1250 HWTEST_F(TransactionTest, RdbStore_Transaction_032, TestSize.Level1)
1251 {
1252 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1253
1254 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
1255 ASSERT_EQ(ret, E_OK);
1256 ASSERT_NE(transaction, nullptr);
1257 ValuesBuckets rows;
1258 ValuesBucket row;
1259 row.Put("id", 2);
1260 row.Put("name", "Jim");
1261 auto res = transaction->Insert("test", row);
1262 ASSERT_EQ(res.first, E_OK);
1263 ASSERT_EQ(res.second, 2);
1264 rows.Put(row);
1265 auto [status, result] = transaction->BatchInsert("test", rows, { "id" }, ConflictResolution::ON_CONFLICT_IGNORE);
1266 EXPECT_EQ(status, E_OK);
1267 EXPECT_EQ(result.changed, 0);
1268 int rowCount = -1;
1269 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1270 EXPECT_EQ(rowCount, 0);
1271 ret = transaction->Commit();
1272 EXPECT_EQ(ret, E_OK);
1273 }
1274
1275 /**
1276 * @tc.name: RdbStore_Transaction_033
1277 * @tc.desc: normal testcase of batch insert with returning overlimit.
1278 * @tc.type: FUNC
1279 */
1280 HWTEST_F(TransactionTest, RdbStore_Transaction_033, TestSize.Level1)
1281 {
1282 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1283
1284 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1285 ASSERT_EQ(ret, E_OK);
1286 ASSERT_NE(transaction, nullptr);
1287
1288 ValuesBuckets rows;
1289 for (int i = 0; i < 1025; i++) {
1290 ValuesBucket row;
1291 row.Put("id", i);
1292 row.Put("name", "Jim");
1293 rows.Put(row);
1294 }
1295 auto [status, result] = transaction->BatchInsert("test", rows, { "id" }, ConflictResolution::ON_CONFLICT_REPLACE);
1296 EXPECT_EQ(status, E_OK);
1297 EXPECT_EQ(result.changed, 1025);
1298 int rowCount = -1;
1299 int maxRowCount = 1024;
1300 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1301 EXPECT_EQ(rowCount, maxRowCount);
1302 int colIndex = -1;
1303 ASSERT_EQ(result.results->GetColumnIndex("id", colIndex), E_OK);
1304 for (size_t i = 0; i < maxRowCount; i++) {
1305 int value = -1;
1306 ASSERT_EQ(result.results->GetInt(colIndex, value), E_OK);
1307 EXPECT_EQ(value, i);
1308 if (i != maxRowCount - 1) {
1309 ASSERT_EQ(result.results->GoToNextRow(), E_OK);
1310 }
1311 }
1312
1313 ret = transaction->Commit();
1314 EXPECT_EQ(ret, E_OK);
1315 }
1316
1317 /**
1318 * @tc.name: RdbStore_Transaction_034
1319 * @tc.desc: normal testcase of batch insert with not exist returning field.
1320 * @tc.type: FUNC
1321 */
1322 HWTEST_F(TransactionTest, RdbStore_Transaction_034, TestSize.Level1)
1323 {
1324 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1325
1326 auto [ret, transaction] = store->CreateTransaction(Transaction::IMMEDIATE);
1327 ASSERT_EQ(ret, E_OK);
1328 ASSERT_NE(transaction, nullptr);
1329
1330 ValuesBuckets rows;
1331 for (int i = 0; i < 5; i++) {
1332 ValuesBucket row;
1333 row.Put("id", i);
1334 row.Put("name", "Jim");
1335 rows.Put(row);
1336 }
1337 auto [status, result] =
1338 transaction->BatchInsert("test", rows, { "notExist" }, ConflictResolution::ON_CONFLICT_REPLACE);
1339 EXPECT_EQ(status, E_SQLITE_ERROR);
1340 EXPECT_EQ(result.changed, -1);
1341 ASSERT_EQ(result.results, nullptr);
1342
1343 ret = transaction->Commit();
1344 EXPECT_EQ(ret, E_OK);
1345 }
1346
1347 /**
1348 * @tc.name: RdbStore_Transaction_035
1349 * @tc.desc: normal testcase of batch insert with Busy.
1350 * @tc.type: FUNC
1351 */
1352 HWTEST_F(TransactionTest, RdbStore_Transaction_035, TestSize.Level1)
1353 {
1354 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1355
1356 auto [res, transactionImme] = store->CreateTransaction(Transaction::IMMEDIATE);
1357 ASSERT_EQ(res, E_OK);
1358 ASSERT_NE(transactionImme, nullptr);
1359
1360 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1361 ASSERT_EQ(ret, E_OK);
1362 ASSERT_NE(transaction, nullptr);
1363
1364 ValuesBuckets rows;
1365 for (int i = 0; i < 5; i++) {
1366 ValuesBucket row;
1367 row.Put("id", i);
1368 row.Put("name", "Jim");
1369 rows.Put(row);
1370 }
1371 auto [status, result] = transaction->BatchInsert("test", rows, { "id" }, ConflictResolution::ON_CONFLICT_REPLACE);
1372 EXPECT_EQ(status, E_SQLITE_BUSY);
1373 EXPECT_EQ(result.changed, -1);
1374 int rowCount = -1;
1375 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1376 EXPECT_EQ(rowCount, 0);
1377
1378 ret = transaction->Rollback();
1379 EXPECT_EQ(ret, E_OK);
1380 }
1381
1382 /**
1383 * @tc.name: RdbStore_Transaction_036
1384 * @tc.desc: normal testcase of update with returning 1.
1385 * @tc.type: FUNC
1386 */
1387 HWTEST_F(TransactionTest, RdbStore_Transaction_036, TestSize.Level1)
1388 {
1389 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1390
1391 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1392 ASSERT_EQ(ret, E_OK);
1393 ASSERT_NE(transaction, nullptr);
1394
1395 Transaction::Row row;
1396 row.Put("id", 1);
1397 row.Put("name", "Jim");
1398 auto res = transaction->Insert("test", row);
1399 ASSERT_EQ(res.first, E_OK);
1400 ASSERT_EQ(res.second, 1);
1401
1402 row.Put("name", "Bob");
1403 AbsRdbPredicates predicates("test");
1404 predicates.EqualTo("id", 1);
1405 auto [status, result] = transaction->Update(row, predicates, { "id" }, ConflictResolution::ON_CONFLICT_REPLACE);
1406 EXPECT_EQ(status, E_OK);
1407 EXPECT_EQ(result.changed, 1);
1408 int rowCount = -1;
1409 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1410 EXPECT_EQ(rowCount, 1);
1411 int columnIndex = -1;
1412 ASSERT_EQ(result.results->GetColumnIndex("id", columnIndex), E_OK);
1413 int value = -1;
1414 ASSERT_EQ(result.results->GetInt(columnIndex, value), E_OK);
1415 EXPECT_EQ(value, 1);
1416
1417 ret = transaction->Rollback();
1418 EXPECT_EQ(ret, E_OK);
1419 }
1420
1421 /**
1422 * @tc.name: RdbStore_Transaction_037
1423 * @tc.desc: abnormal testcase of update with returning 0.
1424 * @tc.type: FUNC
1425 */
1426 HWTEST_F(TransactionTest, RdbStore_Transaction_037, TestSize.Level1)
1427 {
1428 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1429
1430 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1431 ASSERT_EQ(ret, E_OK);
1432 ASSERT_NE(transaction, nullptr);
1433
1434 Transaction::Row row;
1435 row.Put("id", 1);
1436 row.Put("name", "Jim");
1437 auto res = transaction->Insert("test", row);
1438 ASSERT_EQ(res.first, E_OK);
1439 ASSERT_EQ(res.second, 1);
1440
1441 row.Put("name", "Bob");
1442 AbsRdbPredicates predicates("test");
1443 predicates.EqualTo("id", 2);
1444 auto [status, result] = transaction->Update(row, predicates, { "id" });
1445 EXPECT_EQ(status, E_OK);
1446 EXPECT_EQ(result.changed, 0);
1447 int rowCount = -1;
1448 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1449 EXPECT_EQ(rowCount, 0);
1450
1451 ret = transaction->Rollback();
1452 EXPECT_EQ(ret, E_OK);
1453 }
1454
1455 /**
1456 * @tc.name: RdbStore_Transaction_038
1457 * @tc.desc: abnormal testcase of update with returning overlimit.
1458 * @tc.type: FUNC
1459 */
1460 HWTEST_F(TransactionTest, RdbStore_Transaction_038, TestSize.Level1)
1461 {
1462 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1463
1464 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1465 ASSERT_EQ(ret, E_OK);
1466 ASSERT_NE(transaction, nullptr);
1467
1468 ValuesBuckets rows;
1469 for (int i = 0; i < 1025; i++) {
1470 ValuesBucket row;
1471 row.Put("id", i);
1472 row.Put("name", "Jim");
1473 rows.Put(row);
1474 }
1475 auto res = transaction->BatchInsert("test", rows, ConflictResolution::ON_CONFLICT_REPLACE);
1476 EXPECT_EQ(res.first, E_OK);
1477 EXPECT_EQ(res.second, 1025);
1478
1479 ValuesBucket row;
1480 row.Put("name", "Tom");
1481
1482 AbsRdbPredicates predicates("test");
1483 auto [status, result] = transaction->Update(row, predicates, { "id" });
1484 EXPECT_EQ(status, E_OK);
1485 EXPECT_EQ(result.changed, 1025);
1486 int rowCount = -1;
1487 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1488 EXPECT_EQ(rowCount, 1024);
1489
1490 ret = transaction->Rollback();
1491 EXPECT_EQ(ret, E_OK);
1492 }
1493
1494 /**
1495 * @tc.name: RdbStore_Transaction_039
1496 * @tc.desc: abnormal testcase of update with returning not exist field.
1497 * @tc.type: FUNC
1498 */
1499 HWTEST_F(TransactionTest, RdbStore_Transaction_039, TestSize.Level1)
1500 {
1501 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1502
1503 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1504 ASSERT_EQ(ret, E_OK);
1505 ASSERT_NE(transaction, nullptr);
1506
1507 ValuesBuckets rows;
1508 for (int i = 0; i < 2; i++) {
1509 ValuesBucket row;
1510 row.Put("id", i);
1511 row.Put("name", "Jim");
1512 rows.Put(row);
1513 }
1514 auto res = transaction->BatchInsert("test", rows, ConflictResolution::ON_CONFLICT_REPLACE);
1515 EXPECT_EQ(res.first, E_OK);
1516 EXPECT_EQ(res.second, 2);
1517
1518 ValuesBucket row;
1519 row.Put("name", "Tom");
1520
1521 AbsRdbPredicates predicates("test");
1522 auto [status, result] = transaction->Update(row, predicates, { "notExist" });
1523 EXPECT_EQ(status, E_SQLITE_ERROR);
1524 EXPECT_EQ(result.changed, -1);
1525 ASSERT_EQ(result.results, nullptr);
1526
1527 ret = transaction->Rollback();
1528 EXPECT_EQ(ret, E_OK);
1529 }
1530
1531 /**
1532 * @tc.name: RdbStore_Transaction_040
1533 * @tc.desc: abnormal testcase of update with Busy.
1534 * @tc.type: FUNC
1535 */
1536 HWTEST_F(TransactionTest, RdbStore_Transaction_040, TestSize.Level1)
1537 {
1538 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1539
1540 auto [res, transactionImme] = store->CreateTransaction(Transaction::IMMEDIATE);
1541 ASSERT_EQ(res, E_OK);
1542 ASSERT_NE(transactionImme, nullptr);
1543
1544 ValuesBuckets rows;
1545 for (int i = 0; i < 5; i++) {
1546 ValuesBucket row;
1547 row.Put("id", i);
1548 row.Put("name", "Jim");
1549 rows.Put(row);
1550 }
1551 auto [status, result] =
1552 transactionImme->BatchInsert("test", rows, { "id" }, ConflictResolution::ON_CONFLICT_REPLACE);
1553 EXPECT_EQ(status, E_OK);
1554 EXPECT_EQ(result.changed, 5);
1555 int rowCount = -1;
1556 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1557 EXPECT_EQ(rowCount, 5);
1558
1559 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1560 ASSERT_EQ(ret, E_OK);
1561 ASSERT_NE(transaction, nullptr);
1562
1563 ValuesBucket row;
1564 row.Put("name", "Tom");
1565 AbsRdbPredicates predicates("test");
1566 std::tie(status, result) = transaction->Update(row, predicates, { "id" });
1567 EXPECT_EQ(status, E_SQLITE_BUSY);
1568 EXPECT_EQ(result.changed, -1);
1569
1570 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1571 EXPECT_EQ(rowCount, 0);
1572
1573 ret = transaction->Rollback();
1574 EXPECT_EQ(ret, E_OK);
1575 }
1576
1577 /**
1578 * @tc.name: RdbStore_Transaction_041
1579 * @tc.desc: normal testcase of delete with returning 1.
1580 * @tc.type: FUNC
1581 */
1582 HWTEST_F(TransactionTest, RdbStore_Transaction_041, TestSize.Level1)
1583 {
1584 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1585
1586 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1587 ASSERT_EQ(ret, E_OK);
1588 ASSERT_NE(transaction, nullptr);
1589
1590 Transaction::Row row;
1591 row.Put("id", 1);
1592 row.Put("name", "Jim");
1593 auto res = transaction->Insert("test", row);
1594 ASSERT_EQ(res.first, E_OK);
1595 ASSERT_EQ(res.second, 1);
1596
1597 AbsRdbPredicates predicates("test");
1598 predicates.EqualTo("id", 1);
1599 auto [status, result] = transaction->Delete(predicates, { "id" });
1600 EXPECT_EQ(status, E_OK);
1601 EXPECT_EQ(result.changed, 1);
1602
1603 int rowCount = -1;
1604 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1605 EXPECT_EQ(rowCount, 1);
1606 int columnIndex = -1;
1607 ASSERT_EQ(result.results->GetColumnIndex("id", columnIndex), E_OK);
1608 int value = -1;
1609 ASSERT_EQ(result.results->GetInt(columnIndex, value), E_OK);
1610 EXPECT_EQ(value, 1);
1611
1612 ret = transaction->Rollback();
1613 EXPECT_EQ(ret, E_OK);
1614 }
1615
1616 /**
1617 * @tc.name: RdbStore_Transaction_042
1618 * @tc.desc: normal testcase of delete with returning 0.
1619 * @tc.type: FUNC
1620 */
1621 HWTEST_F(TransactionTest, RdbStore_Transaction_042, TestSize.Level1)
1622 {
1623 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1624
1625 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1626 ASSERT_EQ(ret, E_OK);
1627 ASSERT_NE(transaction, nullptr);
1628
1629 Transaction::Row row;
1630 row.Put("id", 1);
1631 row.Put("name", "Jim");
1632 auto res = transaction->Insert("test", row);
1633 ASSERT_EQ(res.first, E_OK);
1634 ASSERT_EQ(res.second, 1);
1635
1636 AbsRdbPredicates predicates("test");
1637 predicates.EqualTo("id", 2);
1638 auto [status, result] = transaction->Delete(predicates, { "id" });
1639 EXPECT_EQ(status, E_OK);
1640 EXPECT_EQ(result.changed, 0);
1641 int rowCount = -1;
1642 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1643 EXPECT_EQ(rowCount, 0);
1644
1645 ret = transaction->Rollback();
1646 EXPECT_EQ(ret, E_OK);
1647 }
1648
1649 /**
1650 * @tc.name: RdbStore_Transaction_043
1651 * @tc.desc: abnormal testcase of delete with returning over limit.
1652 * @tc.type: FUNC
1653 */
1654 HWTEST_F(TransactionTest, RdbStore_Transaction_043, TestSize.Level1)
1655 {
1656 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1657
1658 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1659 ASSERT_EQ(ret, E_OK);
1660 ASSERT_NE(transaction, nullptr);
1661
1662 ValuesBuckets rows;
1663 for (int i = 0; i < 1025; i++) {
1664 ValuesBucket row;
1665 row.Put("id", i);
1666 row.Put("name", "Jim");
1667 rows.Put(row);
1668 }
1669 auto [status, result] = transaction->BatchInsert("test", rows, { "id" }, ConflictResolution::ON_CONFLICT_REPLACE);
1670 EXPECT_EQ(status, E_OK);
1671 EXPECT_EQ(result.changed, 1025);
1672 int rowCount = -1;
1673 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1674 EXPECT_EQ(rowCount, 1024);
1675
1676 AbsRdbPredicates predicates("test");
1677 std::tie(status, result) = transaction->Delete(predicates, { "id" });
1678 EXPECT_EQ(status, E_OK);
1679 EXPECT_EQ(result.changed, 1025);
1680
1681 rowCount = -1;
1682 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1683 EXPECT_EQ(rowCount, 1024);
1684
1685 ret = transaction->Rollback();
1686 EXPECT_EQ(ret, E_OK);
1687 }
1688
1689 /**
1690 * @tc.name: RdbStore_Transaction_044
1691 * @tc.desc: abnormal testcase of delete with returning no exist field.
1692 * @tc.type: FUNC
1693 */
1694 HWTEST_F(TransactionTest, RdbStore_Transaction_044, TestSize.Level1)
1695 {
1696 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1697
1698 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
1699 ASSERT_EQ(ret, E_OK);
1700 ASSERT_NE(transaction, nullptr);
1701
1702 ValuesBuckets rows;
1703 for (int i = 0; i < 2; i++) {
1704 ValuesBucket row;
1705 row.Put("id", i);
1706 row.Put("name", "Jim");
1707 rows.Put(row);
1708 }
1709 auto [status, result] = transaction->BatchInsert("test", rows, { "id" }, ConflictResolution::ON_CONFLICT_ROLLBACK);
1710 EXPECT_EQ(status, E_OK);
1711 EXPECT_EQ(result.changed, 2);
1712 int rowCount = -1;
1713 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1714 EXPECT_EQ(rowCount, 2);
1715
1716 AbsRdbPredicates predicates("test");
1717 std::tie(status, result) = transaction->Delete(predicates, { "noExist" });
1718 EXPECT_EQ(status, E_SQLITE_ERROR);
1719 EXPECT_EQ(result.changed, -1);
1720
1721 ASSERT_EQ(result.results, nullptr);
1722
1723 ret = transaction->Rollback();
1724 EXPECT_EQ(ret, E_OK);
1725 }
1726
1727 /**
1728 * @tc.name: RdbStore_Transaction_045
1729 * @tc.desc: normal testcase of execute with returning over limit.
1730 * @tc.type: FUNC
1731 */
1732 HWTEST_F(TransactionTest, RdbStore_Transaction_045, TestSize.Level1)
1733 {
1734 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1735
1736 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
1737 ASSERT_EQ(ret, E_OK);
1738 ASSERT_NE(transaction, nullptr);
1739
1740 std::vector<ValueObject> args = { "tt", 28, 50000.0, "ttt", 58, 500080.0 };
1741 auto [status, result] =
1742 transaction->ExecuteExt("INSERT INTO test(name, age, salary) VALUES (?, ?, ?), (?, ?, ?) returning name", args);
1743 EXPECT_EQ(status, E_OK);
1744 EXPECT_EQ(result.changed, 2);
1745
1746 int rowCount = -1;
1747 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1748 EXPECT_EQ(rowCount, 2);
1749
1750 int columnIndex = -1;
1751 ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
1752 std::string value;
1753 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
1754 EXPECT_EQ(value, "tt");
1755 ASSERT_EQ(result.results->GoToNextRow(), E_OK);
1756 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
1757 EXPECT_EQ(value, "ttt");
1758
1759 std::tie(status, result) =
1760 transaction->ExecuteExt("update test set name = ? where name = ? returning name", { "update", "tt" });
1761 EXPECT_EQ(status, E_OK);
1762 EXPECT_EQ(result.changed, 1);
1763
1764 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1765 EXPECT_EQ(rowCount, 1);
1766 ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
1767 result.results->GetString(columnIndex, value);
1768 EXPECT_EQ(value, "update");
1769
1770 std::tie(status, result) = transaction->ExecuteExt("delete from test returning name");
1771 EXPECT_EQ(status, E_OK);
1772 EXPECT_EQ(result.changed, 2);
1773 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1774 EXPECT_EQ(rowCount, 2);
1775 ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
1776 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
1777 EXPECT_EQ(value, "update");
1778 ASSERT_EQ(result.results->GoToNextRow(), E_OK);
1779 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
1780 EXPECT_EQ(value, "ttt");
1781
1782 ret = transaction->Rollback();
1783 EXPECT_EQ(ret, E_OK);
1784 }
1785
1786 /**
1787 * @tc.name: RdbStore_Transaction_046
1788 * @tc.desc: abnormal testcase of execute with returning.
1789 * @tc.type: FUNC
1790 */
1791 HWTEST_F(TransactionTest, RdbStore_Transaction_046, TestSize.Level1)
1792 {
1793 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1794
1795 auto [ret, transaction] = store->CreateTransaction(Transaction::IMMEDIATE);
1796 ASSERT_EQ(ret, E_OK);
1797 ASSERT_NE(transaction, nullptr);
1798
1799 std::vector<ValueObject> args = { "0", 0 };
1800 std::string sql = "INSERT INTO test(name, age) VALUES (?, ?)";
1801 for (int32_t i = 1; i < 1025; i++) {
1802 sql.append(", (?, ?)");
1803 args.push_back(std::to_string(i));
1804 args.push_back(i);
1805 }
1806 auto [status, result] = transaction->ExecuteExt(sql + " returning name", args);
1807 EXPECT_EQ(status, E_OK);
1808 EXPECT_EQ(result.changed, 1025);
1809 int rowCount = -1;
1810 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1811 ASSERT_EQ(rowCount, 1024);
1812 int columnIndex = -1;
1813 ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
1814 std::string value;
1815 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
1816 EXPECT_EQ(value, "0");
1817 ASSERT_EQ(result.results->GoToRow(1000), E_OK);
1818 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
1819 EXPECT_EQ(value, "1000");
1820
1821 std::tie(status, result) = transaction->ExecuteExt("update test set name = ? returning name", { "update" });
1822 EXPECT_EQ(status, E_OK);
1823 EXPECT_EQ(result.changed, 1025);
1824 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1825 ASSERT_EQ(rowCount, 1024);
1826 ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
1827 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
1828 EXPECT_EQ(value, "update");
1829
1830 std::tie(status, result) = transaction->ExecuteExt("delete from test returning name", {});
1831 EXPECT_EQ(status, E_OK);
1832 EXPECT_EQ(result.changed, 1025);
1833 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1834 ASSERT_EQ(rowCount, 1024);
1835 ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
1836 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
1837 EXPECT_EQ(value, "update");
1838
1839 ret = transaction->Rollback();
1840 EXPECT_EQ(ret, E_OK);
1841 }
1842
1843 /**
1844 * @tc.name: RdbStore_Transaction_047
1845 * @tc.desc: normal testcase of execute with returning 0 rows.
1846 * @tc.type: FUNC
1847 */
1848 HWTEST_F(TransactionTest, RdbStore_Transaction_047, TestSize.Level1)
1849 {
1850 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1851
1852 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
1853 ASSERT_EQ(ret, E_OK);
1854 ASSERT_NE(transaction, nullptr);
1855
1856 std::vector<ValueObject> args = { 1, "tt", 28, 50000.0 };
1857 auto [status, result] =
1858 transaction->ExecuteExt("INSERT INTO test(id, name, age, salary) VALUES (?, ?, ?, ?) returning id", args);
1859 EXPECT_EQ(status, E_OK);
1860 EXPECT_EQ(result.changed, 1);
1861 int rowCount = -1;
1862 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1863 ASSERT_EQ(rowCount, 1);
1864 int columnIndex = -1;
1865 ASSERT_EQ(result.results->GetColumnIndex("id", columnIndex), E_OK);
1866 int64_t value;
1867 ASSERT_EQ(result.results->GetLong(columnIndex, value), E_OK);
1868 EXPECT_EQ(value, 1);
1869 std::tie(status, result) =
1870 transaction->ExecuteExt("INSERT INTO test(id, name, age, salary) VALUES (?, ?, ?, ?) returning id", args);
1871 EXPECT_EQ(status, E_SQLITE_CONSTRAINT);
1872 EXPECT_EQ(result.changed, 0);
1873 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1874 ASSERT_EQ(rowCount, 0);
1875
1876 std::tie(status, result) =
1877 transaction->ExecuteExt("update test set name = ? where name = ? returning name", { "update", "noExist" });
1878 EXPECT_EQ(status, E_OK);
1879 EXPECT_EQ(result.changed, 0);
1880 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1881 ASSERT_EQ(rowCount, 0);
1882
1883 std::tie(status, result) = transaction->ExecuteExt("delete from test where name = ? returning name", { "noExist" });
1884 EXPECT_EQ(status, E_OK);
1885 EXPECT_EQ(result.changed, 0);
1886 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1887 ASSERT_EQ(rowCount, 0);
1888
1889 ret = transaction->Rollback();
1890 EXPECT_EQ(ret, E_OK);
1891 }
1892
1893 /**
1894 * @tc.name: RdbStore_Transaction_048
1895 * @tc.desc: abnormal testcase of execute busy with returning.
1896 * @tc.type: FUNC
1897 */
1898 HWTEST_F(TransactionTest, RdbStore_Transaction_048, TestSize.Level1)
1899 {
1900 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
1901
1902 auto [res, immeTrans] = store->CreateTransaction(Transaction::EXCLUSIVE);
1903 ASSERT_EQ(res, E_OK);
1904 ASSERT_NE(immeTrans, nullptr);
1905
1906 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1907 ASSERT_EQ(ret, E_OK);
1908 ASSERT_NE(transaction, nullptr);
1909
1910 std::vector<ValueObject> args = { 1, "tt", 28, 50000.0 };
1911 auto [status, result] =
1912 transaction->ExecuteExt("INSERT INTO test(id, name, age, salary) VALUES (?, ?, ?, ?) returning id", args);
1913 EXPECT_EQ(status, E_SQLITE_BUSY);
1914 EXPECT_EQ(result.changed, -1);
1915 int rowCount = -1;
1916 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1917 ASSERT_EQ(rowCount, 0);
1918
1919 std::tie(status, result) =
1920 transaction->ExecuteExt("update test set name = ? where name = ? returning name", { "update", "noExist" });
1921 EXPECT_EQ(status, E_SQLITE_BUSY);
1922 EXPECT_EQ(result.changed, -1);
1923 rowCount = -1;
1924 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1925 ASSERT_EQ(rowCount, 0);
1926
1927
1928 std::tie(status, result) = transaction->ExecuteExt("delete from test where name = ? returning name", { "noExist" });
1929 EXPECT_EQ(status, E_SQLITE_BUSY);
1930 EXPECT_EQ(result.changed, -1);
1931 rowCount = -1;
1932 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
1933 ASSERT_EQ(rowCount, 0);
1934
1935 ret = transaction->Rollback();
1936 EXPECT_EQ(ret, E_OK);
1937 }
1938
1939 /**
1940 * @tc.name: RdbStore_Transaction_049
1941 * @tc.desc: Crash Occurs When Test Commit Fails
1942 * This test case constructs a transaction commit failure scenario.
1943 * A special command is used to operate the database file.
1944 * To avoid affecting other test cases, this test case uses an independent database file.
1945 * @tc.type: FUNC
1946 */
1947 HWTEST_F(TransactionTest, RdbStore_Transaction_049, TestSize.Level1)
1948 {
1949 const std::string dbPath = RDB_TEST_PATH + "transaction049_test.db";
1950 RdbHelper::DeleteRdbStore(dbPath);
1951 RdbStoreConfig config(dbPath);
1952 config.SetHaMode(HAMode::MAIN_REPLICA); // Dual-write must be enabled.
1953 config.SetReadOnly(false);
1954 TransactionTestOpenCallback helper;
1955 int errCode = E_OK;
1956 const int version = 1;
1957 std::shared_ptr<RdbStore> storePtr = RdbHelper::GetRdbStore(config, version, helper, errCode);
1958 EXPECT_NE(storePtr, nullptr);
1959 EXPECT_EQ(errCode, E_OK);
1960
1961 storePtr->Execute("DROP TABLE IF EXISTS test1");
1962 auto res = storePtr->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
1963 ASSERT_EQ(res.first, E_OK);
1964
1965 auto [ret, transaction] = storePtr->CreateTransaction(Transaction::IMMEDIATE);
1966 ASSERT_EQ(ret, E_OK);
1967 ASSERT_NE(transaction, nullptr);
1968
1969 const int idValue = 1;
1970 Transaction::Row row;
1971 row.Put("id", idValue);
1972 row.Put("name", "Jim");
1973 auto result = transaction->Insert("test1", row);
1974 ASSERT_EQ(result.first, E_OK);
1975 const int count = 1;
1976 ASSERT_EQ(result.second, count);
1977
1978 // Constructing a Commit Failure Scenario
1979 std::string walFile = dbPath + "-wal";
1980
1981 // Disabling wal File Operations
1982 std::string chattrAddiCmd = "chattr +i " + walFile;
1983 system(chattrAddiCmd.c_str());
1984
1985 ret = transaction->Commit();
1986 EXPECT_NE(ret, E_OK);
1987
1988 // Enable the wal file operation.
1989 std::string chattrSubiCmd = "chattr -i " + walFile;
1990 system(chattrSubiCmd.c_str());
1991
1992 RdbHelper::DeleteRdbStore(dbPath);
1993 }
1994
1995 /**
1996 * @tc.name: RdbStore_Transaction_050
1997 * @tc.desc: abnormal testcase of trigger delete with returning in trans.
1998 * @tc.type: FUNC
1999 */
2000 HWTEST_F(TransactionTest, RdbStore_Transaction_050, TestSize.Level1)
2001 {
2002 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2003
2004 auto [res, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
2005 ASSERT_EQ(res, E_OK);
2006 ASSERT_NE(transaction, nullptr);
2007
2008 auto [code, result1] = transaction->Execute(
2009 "CREATE TRIGGER before_update BEFORE UPDATE ON test"
2010 " BEGIN DELETE FROM test WHERE name = 'wang'; END");
2011 EXPECT_EQ(code, E_OK);
2012
2013 ValuesBuckets rows;
2014 ValuesBucket row;
2015 row.Put("id", 200);
2016 row.Put("name", "wang");
2017 rows.Put(std::move(row));
2018 row.Put("id", 201);
2019 row.Put("name", "zhang");
2020 rows.Put(std::move(row));
2021
2022 auto [status, result] =
2023 transaction->BatchInsert("test", rows, { "name" }, ConflictResolution::ON_CONFLICT_IGNORE);
2024 EXPECT_EQ(status, E_OK);
2025 EXPECT_EQ(result.changed, 2);
2026 ASSERT_NE(result.results, nullptr);
2027
2028 auto predicates = AbsRdbPredicates("test");
2029 predicates.EqualTo("name", "zhang");
2030 ValuesBucket values;
2031 values.PutString("name", "liu");
2032
2033 std::tie(status, result) = transaction->Update(values, predicates, { "name" });
2034
2035 EXPECT_EQ(status, E_OK);
2036 EXPECT_EQ(result.changed, 1);
2037 int rowCount = -1;
2038 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
2039 ASSERT_EQ(rowCount, 1);
2040 int columnIndex = -1;
2041 ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
2042 std::string value;
2043 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
2044 EXPECT_EQ(value, "liu");
2045
2046 // Check the trigger effect
2047 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
2048
2049 rowCount = -1;
2050 resultSet->GetRowCount(rowCount);
2051 ASSERT_EQ(rowCount, 1);
2052
2053 transaction->Execute("DROP TRIGGER IF EXISTS before_update");
2054
2055 int ret = transaction->Rollback();
2056 EXPECT_EQ(ret, E_OK);
2057 }
2058
2059 /**
2060 * @tc.name: RdbStore_Transaction_051
2061 * @tc.desc: abnormal testcase of trigger update with returning in trans.
2062 * @tc.type: FUNC
2063 */
2064 HWTEST_F(TransactionTest, RdbStore_Transaction_051, TestSize.Level1)
2065 {
2066 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2067
2068 auto [res, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
2069 ASSERT_EQ(res, E_OK);
2070 ASSERT_NE(transaction, nullptr);
2071
2072 auto [code, result1] = transaction->Execute(
2073 "CREATE TRIGGER before_delete BEFORE DELETE ON test"
2074 " BEGIN UPDATE test SET name = 'li' WHERE name = 'zhao'; END");
2075 EXPECT_EQ(code, E_OK);
2076
2077 ValuesBuckets rows;
2078 ValuesBucket row;
2079 row.Put("id", 201);
2080 row.Put("name", "zhang");
2081 rows.Put(std::move(row));
2082 row.Put("id", 202);
2083 row.Put("name", "zhao");
2084 rows.Put(std::move(row));
2085
2086 auto [status, result] =
2087 transaction->BatchInsert("test", rows, { "name" }, ConflictResolution::ON_CONFLICT_IGNORE);
2088 EXPECT_EQ(status, E_OK);
2089 EXPECT_EQ(result.changed, 2);
2090 ASSERT_NE(result.results, nullptr);
2091
2092 AbsRdbPredicates predicates("test");
2093 predicates.EqualTo("name", "zhang");
2094 std::tie(status, result) = transaction->Delete(predicates, { "name" });
2095
2096 EXPECT_EQ(status, E_OK);
2097 EXPECT_EQ(result.changed, 1);
2098 int rowCount = -1;
2099 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
2100 ASSERT_EQ(rowCount, 1);
2101 std::string value;
2102 ASSERT_EQ(result.results->GetString(0, value), E_OK);
2103 EXPECT_EQ(value, "zhang");
2104
2105 // Check the trigger effect
2106 AbsRdbPredicates predicates1("test");
2107 predicates1.EqualTo("id", 202);
2108 auto [queryResult, queryStatus] = transaction->QueryByStep("select name from test where id = 202");
2109
2110 rowCount = -1;
2111 queryResult->GetRowCount(rowCount);
2112 ASSERT_EQ(rowCount, 1);
2113 ASSERT_EQ(queryResult->GoToNextRow(), E_OK);
2114
2115 value.clear();
2116 EXPECT_EQ(E_OK, queryResult->GetString(0, value));
2117 EXPECT_EQ(value, "li");
2118
2119 transaction->Execute("DROP TRIGGER IF EXISTS before_update");
2120
2121 int ret = transaction->Rollback();
2122 EXPECT_EQ(ret, E_OK);
2123 }
2124
2125 /**
2126 * @tc.name: RdbStore_Transaction_052
2127 * @tc.desc: abnormal testcase of virtual table with returning in transaction.
2128 * @tc.type: FUNC
2129 */
2130 HWTEST_F(TransactionTest, RdbStore_Transaction_052, TestSize.Level1)
2131 {
2132 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2133 auto [createTableStatus, createTableresult] =
2134 store->Execute("CREATE VIRTUAL TABLE IF NOT EXISTS articles USING fts5(title, content);");
2135
2136 auto [res, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
2137 ASSERT_EQ(res, E_OK);
2138 ASSERT_NE(transaction, nullptr);
2139
2140 ValuesBuckets rows;
2141 ValuesBucket row;
2142 row.Put("title", "fts5");
2143 row.Put("content", "test virtual tables");
2144 rows.Put(std::move(row));
2145 auto [status, result] =
2146 transaction->BatchInsert("articles", rows, {"title"}, ConflictResolution::ON_CONFLICT_IGNORE);
2147 EXPECT_EQ(status, E_OK);
2148 EXPECT_EQ(result.changed, 1);
2149 ASSERT_NE(result.results, nullptr);
2150 int rowCount = -1;
2151 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
2152 EXPECT_EQ(rowCount, 1);
2153 RowEntity rowEntity;
2154 EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
2155 EXPECT_EQ(std::string(rowEntity.Get("title")), "fts5");
2156
2157 AbsRdbPredicates predicates("test");
2158 predicates.EqualTo("title", "fts5");
2159 ValuesBucket values;
2160 values.PutString("title", "fts5 updated");
2161
2162 std::tie(status, result) = transaction->Update(values, predicates, { "title" });
2163 // UPDATE RETURNING is not available on virtual tables
2164 EXPECT_EQ(status, E_SQLITE_ERROR);
2165 EXPECT_EQ(result.changed, -1);
2166 EXPECT_EQ(result.results, nullptr);
2167
2168 std::tie(status, result) = store_->Delete(predicates, { "title" });
2169 // DELETE RETURNING is not available on virtual tables
2170 EXPECT_EQ(status, E_SQLITE_ERROR);
2171 EXPECT_EQ(result.changed, -1);
2172
2173 transaction->Execute("Drop TABLE articles");
2174 EXPECT_EQ(transaction->Rollback(), E_OK);
2175 }
2176
2177 /**
2178 * @tc.name: RdbStore_Transaction_053
2179 * @tc.desc: abnormal testcase of drop the table before closing the resultSet after querying the data.
2180 * @tc.type: FUNC
2181 */
2182 HWTEST_F(TransactionTest, RdbStore_Transaction_053, TestSize.Level1)
2183 {
2184 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2185
2186 ValuesBucket row;
2187 row.Put("name", "Jim");
2188 auto res = store->Insert("test", row);
2189 ASSERT_EQ(res.first, E_OK);
2190 res = store->Insert("test", row);
2191 ASSERT_EQ(res.first, E_OK);
2192
2193 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
2194 ASSERT_EQ(ret, E_OK);
2195 ASSERT_NE(transaction, nullptr);
2196
2197 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
2198 int rowCount = 0;
2199 ret = resultSet->GetRowCount(rowCount);
2200 ASSERT_EQ(ret, E_OK);
2201 for (int i = 0; i < rowCount; i++) {
2202 ret = resultSet->GoToNextRow();
2203 ASSERT_EQ(ret, E_OK);
2204 }
2205
2206 auto [rs, obj] = transaction->Execute("DROP TABLE test");
2207 ASSERT_EQ(rs, E_SQLITE_LOCKED);
2208
2209 rs = resultSet->Close();
2210 ASSERT_EQ(rs, E_OK);
2211 rs = transaction->Rollback();
2212 ASSERT_EQ(rs, E_OK);
2213 }
2214
2215 /**
2216 * @tc.name: RdbStore_Transaction_054
2217 * @tc.desc: abnormal testcase of drop the table before closing the resultSet after querying the data.
2218 * @tc.type: FUNC
2219 */
2220 HWTEST_F(TransactionTest, RdbStore_Transaction_054, TestSize.Level1)
2221 {
2222 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2223
2224 ValuesBucket row;
2225 row.Put("name", "Jim");
2226 auto res = store->Insert("test", row);
2227 ASSERT_EQ(res.first, E_OK);
2228 res = store->Insert("test", row);
2229 ASSERT_EQ(res.first, E_OK);
2230
2231 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
2232 ASSERT_EQ(ret, E_OK);
2233 ASSERT_NE(transaction, nullptr);
2234
2235 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
2236 int rowCount = 0;
2237 ret = resultSet->GetRowCount(rowCount);
2238 ASSERT_EQ(ret, E_OK);
2239 for (int i = 0; i < rowCount - 1; i++) {
2240 ret = resultSet->GoToNextRow();
2241 ASSERT_EQ(ret, E_OK);
2242 }
2243
2244 auto [rs, obj] = transaction->Execute("DROP TABLE test");
2245 ASSERT_EQ(rs, E_SQLITE_LOCKED);
2246
2247 rs = resultSet->Close();
2248 ASSERT_EQ(rs, E_OK);
2249 rs = transaction->Rollback();
2250 ASSERT_EQ(rs, E_OK);
2251 }
2252
2253 /**
2254 * @tc.name: RdbStore_Transaction_055
2255 * @tc.desc: normal testcase of drop the table after querying the data and closing the resultSet.
2256 * @tc.type: FUNC
2257 */
2258 HWTEST_F(TransactionTest, RdbStore_Transaction_055, TestSize.Level1)
2259 {
2260 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2261
2262 auto [rt, object] = store->Execute(CREATE_TABLE1_SQL);
2263 ASSERT_EQ(rt, E_OK);
2264
2265 ValuesBucket row;
2266 row.Put("name", "Jim");
2267 auto res = store->Insert("test1", row);
2268 ASSERT_EQ(res.first, E_OK);
2269 res = store->Insert("test1", row);
2270 ASSERT_EQ(res.first, E_OK);
2271
2272 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
2273 ASSERT_EQ(ret, E_OK);
2274 ASSERT_NE(transaction, nullptr);
2275
2276 auto resultSet = transaction->QueryByStep("SELECT * FROM test1");
2277 int rowCount = 0;
2278 ret = resultSet->GetRowCount(rowCount);
2279 ASSERT_EQ(ret, E_OK);
2280 for (int i = 0; i < rowCount; i++) {
2281 ret = resultSet->GoToNextRow();
2282 ASSERT_EQ(ret, E_OK);
2283 }
2284
2285 ret = resultSet->Close();
2286 ASSERT_EQ(ret, E_OK);
2287
2288 auto [rs, obj] = transaction->Execute("DROP TABLE test1");
2289 ASSERT_EQ(rs, E_OK);
2290
2291 rs = transaction->Commit();
2292 ASSERT_EQ(rs, E_OK);
2293 }
2294
2295 /**
2296 * @tc.name: RdbStore_Transaction_056
2297 * @tc.desc: abnormal testcase of drop the index before closing the resultSet after querying the data.
2298 * @tc.type: FUNC
2299 */
2300 HWTEST_F(TransactionTest, RdbStore_Transaction_056, TestSize.Level1)
2301 {
2302 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2303
2304 auto [rt, object] = store->Execute("CREATE INDEX test_index ON test(age)");
2305 ASSERT_EQ(rt, E_OK);
2306
2307 ValuesBucket row;
2308 row.Put("name", "Jim");
2309 auto res = store->Insert("test", row);
2310 ASSERT_EQ(res.first, E_OK);
2311 res = store->Insert("test", row);
2312 ASSERT_EQ(res.first, E_OK);
2313
2314 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
2315 ASSERT_EQ(ret, E_OK);
2316 ASSERT_NE(transaction, nullptr);
2317
2318 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
2319 int rowCount = 0;
2320 ret = resultSet->GetRowCount(rowCount);
2321 ASSERT_EQ(ret, E_OK);
2322 for (int i = 0; i < rowCount; i++) {
2323 ret = resultSet->GoToNextRow();
2324 ASSERT_EQ(ret, E_OK);
2325 }
2326
2327 auto [rs, obj] = transaction->Execute("DROP INDEX test_index");
2328 ASSERT_EQ(rs, E_SQLITE_LOCKED);
2329
2330 rs = resultSet->Close();
2331 ASSERT_EQ(rs, E_OK);
2332 rs = transaction->Rollback();
2333 ASSERT_EQ(rs, E_OK);
2334
2335 std::tie(rt, object) = store->Execute("DROP INDEX test_index");
2336 ASSERT_EQ(rt, E_OK);
2337 }
2338
2339 /**
2340 * @tc.name: RdbStore_Transaction_057
2341 * @tc.desc: abnormal testcase of drop the index before closing the resultSet after querying the data.
2342 * @tc.type: FUNC
2343 */
2344 HWTEST_F(TransactionTest, RdbStore_Transaction_057, TestSize.Level1)
2345 {
2346 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2347
2348 auto [rt, object] = store->Execute("CREATE INDEX test_index ON test(age)");
2349 ASSERT_EQ(rt, E_OK);
2350
2351 ValuesBucket row;
2352 row.Put("name", "Jim");
2353 auto res = store->Insert("test", row);
2354 ASSERT_EQ(res.first, E_OK);
2355 res = store->Insert("test", row);
2356 ASSERT_EQ(res.first, E_OK);
2357
2358 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
2359 ASSERT_EQ(ret, E_OK);
2360 ASSERT_NE(transaction, nullptr);
2361
2362 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
2363 int rowCount = 0;
2364 ret = resultSet->GetRowCount(rowCount);
2365 ASSERT_EQ(ret, E_OK);
2366 for (int i = 0; i < rowCount - 1; i++) {
2367 ret = resultSet->GoToNextRow();
2368 ASSERT_EQ(ret, E_OK);
2369 }
2370
2371 auto [rs, obj] = transaction->Execute("DROP INDEX test_index");
2372 ASSERT_EQ(rs, E_SQLITE_LOCKED);
2373
2374 rs = resultSet->Close();
2375 ASSERT_EQ(rs, E_OK);
2376 rs = transaction->Rollback();
2377 ASSERT_EQ(rs, E_OK);
2378
2379 std::tie(rt, object) = store->Execute("DROP INDEX test_index");
2380 ASSERT_EQ(rt, E_OK);
2381 }
2382
2383 /**
2384 * @tc.name: RdbStore_Transaction_058
2385 * @tc.desc: normal testcase of drop the index after querying the data and closing the resultSet.
2386 * @tc.type: FUNC
2387 */
2388 HWTEST_F(TransactionTest, RdbStore_Transaction_058, TestSize.Level1)
2389 {
2390 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2391
2392 auto [rt, object] = store->Execute("CREATE INDEX test_index ON test(age)");
2393 ASSERT_EQ(rt, E_OK);
2394
2395 ValuesBucket row;
2396 row.Put("name", "Jim");
2397 auto res = store->Insert("test", row);
2398 ASSERT_EQ(res.first, E_OK);
2399 res = store->Insert("test", row);
2400 ASSERT_EQ(res.first, E_OK);
2401
2402 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
2403 ASSERT_EQ(ret, E_OK);
2404 ASSERT_NE(transaction, nullptr);
2405
2406 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
2407 int rowCount = 0;
2408 ret = resultSet->GetRowCount(rowCount);
2409 ASSERT_EQ(ret, E_OK);
2410 for (int i = 0; i < rowCount; i++) {
2411 ret = resultSet->GoToNextRow();
2412 ASSERT_EQ(ret, E_OK);
2413 }
2414
2415 ret = resultSet->Close();
2416 ASSERT_EQ(ret, E_OK);
2417
2418 auto [rs, obj] = transaction->Execute("DROP INDEX test_index");
2419 ASSERT_EQ(rs, E_OK);
2420
2421 rs = transaction->Commit();
2422 ASSERT_EQ(rs, E_OK);
2423 }
2424
2425 /**
2426 * @tc.name: RdbStore_Transaction_059
2427 * @tc.desc: normal testcase of drop the table after querying the data and closing the resultSet.
2428 * @tc.type: FUNC
2429 */
2430 HWTEST_F(TransactionTest, RdbStore_Transaction_059, TestSize.Level1)
2431 {
2432 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2433
2434 auto [rt, object] = store->Execute(CREATE_TABLE1_SQL);
2435 ASSERT_EQ(rt, E_OK);
2436
2437 auto [res, transaction] = store->CreateTransaction(Transaction::DEFERRED);
2438 ASSERT_EQ(res, E_OK);
2439 ASSERT_NE(transaction, nullptr);
2440
2441 auto resultSet = transaction->QueryByStep("SELECT * FROM test1");
2442 int rowCount = 0;
2443 auto ret = resultSet->GetRowCount(rowCount);
2444 ASSERT_EQ(ret, E_OK);
2445 for (int i = 0; i < rowCount; i++) {
2446 ret = resultSet->GoToNextRow();
2447 ASSERT_EQ(ret, E_OK);
2448 }
2449
2450 auto [rs, obj] = transaction->Execute("DROP TABLE test1");
2451 ASSERT_EQ(rs, E_OK);
2452
2453 rs = resultSet->Close();
2454 ASSERT_EQ(rs, E_OK);
2455
2456 rs = transaction->Commit();
2457 ASSERT_EQ(rs, E_OK);
2458 }
2459
2460 /**
2461 * @tc.name: RdbStore_Transaction_060
2462 * @tc.desc: normal testcase of drop the index after querying the data and closing the resultSet.
2463 * @tc.type: FUNC
2464 */
2465 HWTEST_F(TransactionTest, RdbStore_Transaction_060, TestSize.Level1)
2466 {
2467 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2468
2469 auto [rt, object] = store->Execute("CREATE INDEX test_index ON test(age)");
2470 ASSERT_EQ(rt, E_OK);
2471
2472 auto [res, transaction] = store->CreateTransaction(Transaction::DEFERRED);
2473 ASSERT_EQ(res, E_OK);
2474 ASSERT_NE(transaction, nullptr);
2475
2476 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
2477 int rowCount = 0;
2478 auto ret = resultSet->GetRowCount(rowCount);
2479 ASSERT_EQ(ret, E_OK);
2480 for (int i = 0; i < rowCount; i++) {
2481 ret = resultSet->GoToNextRow();
2482 ASSERT_EQ(ret, E_OK);
2483 }
2484
2485 auto [rs, obj] = transaction->Execute("DROP INDEX test_index");
2486 ASSERT_EQ(rs, E_OK);
2487
2488 rs = resultSet->Close();
2489 ASSERT_EQ(rs, E_OK);
2490
2491 rs = transaction->Commit();
2492 ASSERT_EQ(rs, E_OK);
2493 }
2494
2495 /**
2496 * @tc.name: RdbStore_Transaction_061
2497 * @tc.desc: abnormal testcase of drop the table before closing the resultSet after querying the data.
2498 * @tc.type: FUNC
2499 */
2500 HWTEST_F(TransactionTest, RdbStore_Transaction_061, TestSize.Level1)
2501 {
2502 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2503
2504 auto [rt, object] = store->Execute(CREATE_TABLE1_SQL);
2505 ASSERT_EQ(rt, E_OK);
2506
2507 ValuesBucket row;
2508 row.Put("name", "Jim");
2509 auto res = store->Insert("test", row);
2510 ASSERT_EQ(res.first, E_OK);
2511 res = store->Insert("test", row);
2512 ASSERT_EQ(res.first, E_OK);
2513
2514 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
2515 ASSERT_EQ(ret, E_OK);
2516 ASSERT_NE(transaction, nullptr);
2517
2518 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
2519 int rowCount = 0;
2520 ret = resultSet->GetRowCount(rowCount);
2521 ASSERT_EQ(ret, E_OK);
2522 for (int i = 0; i < rowCount; i++) {
2523 ret = resultSet->GoToNextRow();
2524 ASSERT_EQ(ret, E_OK);
2525 }
2526
2527 auto [rs, obj] = transaction->Execute("DROP TABLE test1");
2528 ASSERT_EQ(rs, E_SQLITE_LOCKED);
2529
2530 rs = resultSet->Close();
2531 ASSERT_EQ(rs, E_OK);
2532 rs = transaction->Rollback();
2533 ASSERT_EQ(rs, E_OK);
2534 }
2535
2536 /**
2537 * @tc.name: RdbStore_Transaction_062
2538 * @tc.desc: abnormal testcase of drop the table before closing the resultSet after querying the data.
2539 * @tc.type: FUNC
2540 */
2541 HWTEST_F(TransactionTest, RdbStore_Transaction_062, TestSize.Level1)
2542 {
2543 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2544
2545 ValuesBucket row;
2546 row.Put("name", "Jim");
2547 auto res = store->Insert("test", row);
2548 ASSERT_EQ(res.first, E_OK);
2549 res = store->Insert("test", row);
2550 ASSERT_EQ(res.first, E_OK);
2551
2552 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
2553 ASSERT_EQ(ret, E_OK);
2554 ASSERT_NE(transaction, nullptr);
2555
2556 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
2557
2558 auto [rs, obj] = transaction->Execute("DROP TABLE test");
2559 ASSERT_EQ(rs, E_OK);
2560
2561 rs = resultSet->Close();
2562 ASSERT_EQ(rs, E_OK);
2563 rs = transaction->Rollback();
2564 ASSERT_EQ(rs, E_OK);
2565 }
2566
2567 /**
2568 * @tc.name: RdbStore_Transaction_063
2569 * @tc.desc: normal testcase of drop the table before closing the resultSet after querying the data.
2570 * @tc.type: FUNC
2571 */
2572 HWTEST_F(TransactionTest, RdbStore_Transaction_063, TestSize.Level1)
2573 {
2574 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
2575
2576 ValuesBucket row;
2577 row.Put("name", "Jim");
2578 auto res = store->Insert("test", row);
2579 ASSERT_EQ(res.first, E_OK);
2580 res = store->Insert("test", row);
2581 ASSERT_EQ(res.first, E_OK);
2582
2583 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
2584 ASSERT_EQ(ret, E_OK);
2585 ASSERT_NE(transaction, nullptr);
2586
2587 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
2588 int rowCount = 0;
2589 ret = resultSet->GetRowCount(rowCount);
2590 ASSERT_EQ(ret, E_OK);
2591 for (int i = 0; i < rowCount; i++) {
2592 ret = resultSet->GoToNextRow();
2593 ASSERT_EQ(ret, E_OK);
2594 }
2595
2596 ret = resultSet->GoToNextRow();
2597 ASSERT_NE(ret, E_OK);
2598
2599 auto [rs, obj] = transaction->Execute("DROP TABLE test");
2600 ASSERT_EQ(rs, E_OK);
2601
2602 rs = resultSet->Close();
2603 ASSERT_EQ(rs, E_OK);
2604 rs = transaction->Rollback();
2605 ASSERT_EQ(rs, E_OK);
2606 }
2607