• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
20 #include "common.h"
21 #include "rdb_errno.h"
22 #include "rdb_helper.h"
23 #include "rdb_open_callback.h"
24 
25 using namespace testing::ext;
26 using namespace OHOS::NativeRdb;
27 
28 static const std::string DATABASE_NAME = RDB_TEST_PATH + "transaction_test.db";
29 static const char CREATE_TABLE_SQL[] =
30     "CREATE TABLE IF NOT EXISTS test "
31     "(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)";
32 
33 class TransactionTest : public testing::Test {
34 public:
35     static void SetUpTestCase();
36     static void TearDownTestCase();
37     void SetUp() override;
38     void TearDown() override;
39 
40     static inline std::shared_ptr<RdbStore> store_;
41 
42     class TransactionTestOpenCallback : public RdbOpenCallback {
43     public:
44         int OnCreate(RdbStore &store) override;
45         int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
46     };
47 };
48 
OnCreate(RdbStore & store)49 int TransactionTest::TransactionTestOpenCallback::OnCreate(RdbStore &store)
50 {
51     auto [ret, value] = store.Execute(CREATE_TABLE_SQL);
52     return ret;
53 }
54 
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)55 int TransactionTest::TransactionTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
56 {
57     return E_OK;
58 }
59 
SetUpTestCase()60 void TransactionTest::SetUpTestCase()
61 {
62     int errCode = E_OK;
63     RdbHelper::DeleteRdbStore(DATABASE_NAME);
64     RdbStoreConfig config(DATABASE_NAME);
65     TransactionTestOpenCallback helper;
66     TransactionTest::store_ = RdbHelper::GetRdbStore(config, 1, helper, errCode);
67     EXPECT_NE(TransactionTest::store_, nullptr);
68     EXPECT_EQ(errCode, E_OK);
69 }
70 
TearDownTestCase()71 void TransactionTest::TearDownTestCase()
72 {
73     store_ = nullptr;
74     RdbHelper::DeleteRdbStore(DATABASE_NAME);
75 }
76 
SetUp()77 void TransactionTest::SetUp()
78 {
79     store_->Execute("DELETE FROM test");
80 }
81 
TearDown()82 void TransactionTest::TearDown()
83 {
84 }
85 
86 /**
87  * @tc.name: RdbStore_Transaction_001
88  * @tc.desc: createTransaction and commit
89  * @tc.type: FUNC
90  */
91 HWTEST_F(TransactionTest, RdbStore_Transaction_001, TestSize.Level1)
92 {
93     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
94 
95     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
96     ASSERT_EQ(ret, E_OK);
97     ASSERT_NE(transaction, nullptr);
98 
99     auto result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
100     ASSERT_EQ(result.first, E_OK);
101     ASSERT_EQ(1, result.second);
102 
103     result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
104     ASSERT_EQ(result.first, E_OK);
105     ASSERT_EQ(2, result.second);
106 
107     result = store->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[2]), RdbStore::NO_ACTION);
108     ASSERT_EQ(result.first, E_SQLITE_BUSY);
109 
110     auto resultSet = transaction->QueryByStep("SELECT * FROM test");
111     ASSERT_NE(resultSet, nullptr);
112     int32_t rowCount{};
113     ret = resultSet->GetRowCount(rowCount);
114     ASSERT_EQ(ret, E_OK);
115     ASSERT_EQ(rowCount, 2);
116 
117     ret = transaction->Commit();
118     ASSERT_EQ(ret, E_OK);
119 
120     ValueObject value;
121     ret = resultSet->Get(0, value);
122     ASSERT_EQ(ret, E_ALREADY_CLOSED);
123 
124     result = store->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[2]), RdbStore::NO_ACTION);
125     ASSERT_EQ(result.first, E_OK);
126     ASSERT_EQ(3, result.second);
127 
128     result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
129     ASSERT_EQ(result.first, E_ALREADY_CLOSED);
130 
131     resultSet = store->QueryByStep("SELECT * FROM test");
132     ASSERT_NE(resultSet, nullptr);
133     resultSet->GetRowCount(rowCount);
134     EXPECT_EQ(rowCount, 3);
135 }
136 
137 /**
138  * @tc.name: RdbStore_Transaction_002
139  * @tc.desc: createTransaction and rollback
140  * @tc.type: FUNC
141  */
142 HWTEST_F(TransactionTest, RdbStore_Transaction_002, TestSize.Level1)
143 {
144     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
145 
146     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
147     ASSERT_EQ(ret, E_OK);
148     ASSERT_NE(transaction, nullptr);
149 
150     auto result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
151     ASSERT_EQ(result.first, E_OK);
152     ASSERT_EQ(1, result.second);
153 
154     result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
155     ASSERT_EQ(result.first, E_OK);
156     ASSERT_EQ(2, result.second);
157 
158     ret = transaction->Rollback();
159     ASSERT_EQ(ret, E_OK);
160 
161     auto resultSet = store->QueryByStep("SELECT * FROM test");
162     ASSERT_NE(resultSet, nullptr);
163     int32_t rowCount{};
164     ret = resultSet->GetRowCount(rowCount);
165     ASSERT_EQ(ret, E_OK);
166     ASSERT_EQ(rowCount, 0);
167 
168     result = store->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[2]), RdbStore::NO_ACTION);
169     ASSERT_EQ(result.first, E_OK);
170     ASSERT_EQ(3, result.second);
171 
172     result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
173     ASSERT_EQ(result.first, E_ALREADY_CLOSED);
174 
175     resultSet = store->QueryByStep("SELECT * FROM test");
176     ASSERT_NE(resultSet, nullptr);
177     ret = resultSet->GetRowCount(rowCount);
178     EXPECT_EQ(ret, E_OK);
179     EXPECT_EQ(rowCount, 1);
180 }
181 
182 /**
183  * @tc.name: RdbStore_Transaction_003
184  * @tc.desc: batchInsert
185  * @tc.type: FUNC
186  */
187 HWTEST_F(TransactionTest, RdbStore_Transaction_003, TestSize.Level1)
188 {
189     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
190 
191     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
192     ASSERT_EQ(ret, E_OK);
193     ASSERT_NE(transaction, nullptr);
194 
195     Transaction::Rows rows{
196         UTUtils::SetRowData(UTUtils::g_rowData[0]),
197         UTUtils::SetRowData(UTUtils::g_rowData[1]),
198         UTUtils::SetRowData(UTUtils::g_rowData[2]),
199     };
200     auto result = transaction->BatchInsert("test", rows);
201     ASSERT_EQ(result.first, E_OK);
202     ASSERT_EQ(result.second, 3);
203 
204     ret = transaction->Commit();
205     ASSERT_EQ(ret, E_OK);
206 
207     auto resultSet = store->QueryByStep("SELECT * FROM test");
208     ASSERT_NE(resultSet, nullptr);
209     int32_t rowCount{};
210     ret = resultSet->GetRowCount(rowCount);
211     EXPECT_EQ(ret, E_OK);
212     EXPECT_EQ(rowCount, 3);
213 }
214 
215 /**
216  * @tc.name: RdbStore_Transaction_004
217  * @tc.desc: batchInsert
218  * @tc.type: FUNC
219  */
220 HWTEST_F(TransactionTest, RdbStore_Transaction_004, TestSize.Level1)
221 {
222     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
223 
224     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
225     ASSERT_EQ(ret, E_OK);
226     ASSERT_NE(transaction, nullptr);
227 
228     Transaction::RefRows rows;
229     rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[0]));
230     rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[1]));
231     rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[2]));
232 
233     auto result = transaction->BatchInsert("test", rows);
234     ASSERT_EQ(result.first, E_OK);
235     ASSERT_EQ(result.second, 3);
236 
237     ret = transaction->Commit();
238     ASSERT_EQ(ret, E_OK);
239 
240     auto resultSet = store->QueryByStep("SELECT * FROM test");
241     ASSERT_NE(resultSet, nullptr);
242     int32_t rowCount{};
243     ret = resultSet->GetRowCount(rowCount);
244     EXPECT_EQ(ret, E_OK);
245     EXPECT_EQ(rowCount, 3);
246 }
247 
248 /**
249  * @tc.name: RdbStore_Transaction_005
250  * @tc.desc: Update
251  * @tc.type: FUNC
252  */
253 HWTEST_F(TransactionTest, RdbStore_Transaction_005, TestSize.Level1)
254 {
255     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
256 
257     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
258     ASSERT_EQ(ret, E_OK);
259     ASSERT_NE(transaction, nullptr);
260 
261     auto result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
262     ASSERT_EQ(result.first, E_OK);
263     ASSERT_EQ(result.second, 1);
264 
265     result = transaction->Update("test", UTUtils::SetRowData(UTUtils::g_rowData[1]), "id=1");
266     ASSERT_EQ(result.first, E_OK);
267     ASSERT_EQ(result.second, 1);
268 
269     auto resultSet = transaction->QueryByStep("SELECT * FROM test");
270     ASSERT_NE(resultSet, nullptr);
271     int32_t rowCount{};
272     ret = resultSet->GetRowCount(rowCount);
273     ASSERT_EQ(ret, E_OK);
274     ASSERT_EQ(rowCount, 1);
275     ret = resultSet->GoToFirstRow();
276     ASSERT_EQ(ret, E_OK);
277     int32_t columnIndex{};
278     ret = resultSet->GetColumnIndex("id", columnIndex);
279     ASSERT_EQ(ret, E_OK);
280     int32_t id{};
281     ret = resultSet->GetInt(columnIndex, id);
282     ASSERT_EQ(ret, E_OK);
283     ASSERT_EQ(id, 2);
284 
285     AbsRdbPredicates predicates("test");
286     predicates.EqualTo("id", ValueObject(2));
287     result = transaction->Update(UTUtils::SetRowData(UTUtils::g_rowData[2]), predicates);
288     ASSERT_EQ(result.first, E_OK);
289     ASSERT_EQ(result.second, 1);
290 
291     ret = transaction->Commit();
292     ASSERT_EQ(ret, E_OK);
293 
294     resultSet = store->QueryByStep("SELECT * FROM test");
295     ASSERT_NE(resultSet, nullptr);
296     ret = resultSet->GetRowCount(rowCount);
297     ASSERT_EQ(ret, E_OK);
298     ASSERT_EQ(rowCount, 1);
299     ret = resultSet->GoToFirstRow();
300     ASSERT_EQ(ret, E_OK);
301     resultSet->GetColumnIndex("id", columnIndex);
302     ret = resultSet->GetInt(columnIndex, id);
303     EXPECT_EQ(ret, E_OK);
304     EXPECT_EQ(id, 3);
305 }
306 
307 /**
308  * @tc.name: RdbStore_Transaction_006
309  * @tc.desc: Delete
310  * @tc.type: FUNC
311  */
312 HWTEST_F(TransactionTest, RdbStore_Transaction_006, TestSize.Level1)
313 {
314     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
315 
316     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
317     ASSERT_EQ(ret, E_OK);
318     ASSERT_NE(transaction, nullptr);
319 
320     Transaction::RefRows rows;
321     rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[0]));
322     rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[1]));
323     rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[2]));
324 
325     auto result = transaction->BatchInsert("test", rows);
326     ASSERT_EQ(result.first, E_OK);
327     ASSERT_EQ(result.second, 3);
328 
329     result = transaction->Delete("test", "id=1");
330     ASSERT_EQ(result.first, E_OK);
331     ASSERT_EQ(result.second, 1);
332 
333     AbsRdbPredicates predicates("test");
334     predicates.EqualTo("id", ValueObject(2));
335     result = transaction->Delete(predicates);
336     ASSERT_EQ(result.first, E_OK);
337     ASSERT_EQ(result.second, 1);
338 
339     ret = transaction->Commit();
340     ASSERT_EQ(ret, E_OK);
341 
342     auto resultSet = store->QueryByStep("SELECT * FROM test");
343     ASSERT_NE(resultSet, nullptr);
344     int32_t rowCount{};
345     ret = resultSet->GetRowCount(rowCount);
346     ASSERT_EQ(ret, E_OK);
347     ASSERT_EQ(rowCount, 1);
348     ret = resultSet->GoToFirstRow();
349     ASSERT_EQ(ret, E_OK);
350     int32_t columnIndex{};
351     resultSet->GetColumnIndex("id", columnIndex);
352     int32_t id{};
353     ret = resultSet->GetInt(columnIndex, id);
354     EXPECT_EQ(ret, E_OK);
355     EXPECT_EQ(id, 3);
356 }
357 
358 /**
359  * @tc.name: RdbStore_Transaction_007
360  * @tc.desc: Execute
361  * @tc.type: FUNC
362  */
363 HWTEST_F(TransactionTest, RdbStore_Transaction_007, TestSize.Level1)
364 {
365     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
366 
367     store->Execute("DROP TABLE IF EXISTS test1");
368     auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
369     ASSERT_EQ(res.first, E_OK);
370     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
371     ASSERT_EQ(ret, E_OK);
372     ASSERT_NE(transaction, nullptr);
373 
374     Transaction::Row row;
375     row.Put("id", 1);
376     row.Put("name", "Jim");
377     auto result = transaction->Insert("test1", row);
378     ASSERT_EQ(result.first, E_OK);
379     ASSERT_EQ(result.second, 1);
380 
381     ret = transaction->Commit();
382     ASSERT_EQ(ret, E_OK);
383 
384     auto resultSet = store->QueryByStep("SELECT * FROM test1");
385     ASSERT_NE(resultSet, nullptr);
386     int32_t rowCount{};
387     ret = resultSet->GetRowCount(rowCount);
388     EXPECT_EQ(ret, E_OK);
389     EXPECT_EQ(rowCount, 1);
390 }
391 
392 /**
393  * @tc.name: RdbStore_Transaction_008
394  * @tc.desc: Insert with ConflictResolution::ON_CONFLICT_ROLLBACK
395  * @tc.type: FUNC
396  */
397 HWTEST_F(TransactionTest, RdbStore_Transaction_008, TestSize.Level1)
398 {
399     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
400     store->Execute("DROP TABLE IF EXISTS test1");
401     auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
402     ASSERT_EQ(res.first, E_OK);
403     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
404     ASSERT_EQ(ret, E_OK);
405     ASSERT_NE(transaction, nullptr);
406 
407     Transaction::Row row;
408     row.Put("id", 1);
409     row.Put("name", "Jim");
410     auto result = transaction->Insert("test1", row);
411     ASSERT_EQ(result.first, E_OK);
412     ASSERT_EQ(result.second, 1);
413 
414     result = transaction->Insert("test1", row, ConflictResolution::ON_CONFLICT_ROLLBACK);
415     ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
416     ASSERT_EQ(result.second, -1);
417     ASSERT_EQ(transaction->Commit(), E_SQLITE_ERROR);
418 
419     auto resultSet = store->QueryByStep("SELECT * FROM test1");
420     ASSERT_NE(resultSet, nullptr);
421     int32_t rowCount{};
422     ret = resultSet->GetRowCount(rowCount);
423     EXPECT_EQ(ret, E_OK);
424     EXPECT_EQ(rowCount, 0);
425 }
426 
427 /**
428  * @tc.name: RdbStore_Transaction_009
429  * @tc.desc: Update with ConflictResolution::ON_CONFLICT_ROLLBACK
430  * @tc.type: FUNC
431  */
432 HWTEST_F(TransactionTest, RdbStore_Transaction_009, TestSize.Level1)
433 {
434     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
435     store->Execute("DROP TABLE IF EXISTS test1");
436     auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
437     ASSERT_EQ(res.first, E_OK);
438     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
439     ASSERT_EQ(ret, E_OK);
440     ASSERT_NE(transaction, nullptr);
441 
442     Transaction::Row row;
443     row.Put("id", 1);
444     row.Put("name", "Jim");
445     auto result = transaction->Insert("test1", row);
446     ASSERT_EQ(result.first, E_OK);
447     ASSERT_EQ(result.second, 1);
448 
449     row.Put("name", ValueObject());
450     result = transaction->Update(
451         "test1", row, "id = ?", std::vector<ValueObject>{ "1" }, ConflictResolution::ON_CONFLICT_ROLLBACK);
452     ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
453     ASSERT_EQ(result.second, 0);
454     ASSERT_EQ(transaction->Commit(), E_SQLITE_ERROR);
455 
456     auto resultSet = store->QueryByStep("SELECT * FROM test1");
457     ASSERT_NE(resultSet, nullptr);
458     int32_t rowCount{};
459     ret = resultSet->GetRowCount(rowCount);
460     EXPECT_EQ(ret, E_OK);
461     EXPECT_EQ(rowCount, 0);
462 }
463 
464 /**
465  * @tc.name: RdbStore_Transaction_010
466  * @tc.desc: Update with ConflictResolution::ON_CONFLICT_ROLLBACK
467  * @tc.type: FUNC
468  */
469 HWTEST_F(TransactionTest, RdbStore_Transaction_010, TestSize.Level1)
470 {
471     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
472     store->Execute("DROP TABLE IF EXISTS test1");
473     auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
474     ASSERT_EQ(res.first, E_OK);
475     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
476     ASSERT_EQ(ret, E_OK);
477     ASSERT_NE(transaction, nullptr);
478 
479     Transaction::Row row;
480     row.Put("id", 1);
481     row.Put("name", "Jim");
482     auto result = transaction->Insert("test1", row);
483     ASSERT_EQ(result.first, E_OK);
484     ASSERT_EQ(result.second, 1);
485 
486     row.Put("name", ValueObject());
487     AbsRdbPredicates predicates("test1");
488     predicates.EqualTo("id", 1);
489     result = transaction->Update(row, predicates, ConflictResolution::ON_CONFLICT_ROLLBACK);
490     ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
491     ASSERT_EQ(result.second, 0);
492     ASSERT_EQ(transaction->Commit(), E_SQLITE_ERROR);
493 
494     auto resultSet = store->QueryByStep("SELECT * FROM test1");
495     ASSERT_NE(resultSet, nullptr);
496     int32_t rowCount{};
497     ret = resultSet->GetRowCount(rowCount);
498     EXPECT_EQ(ret, E_OK);
499     EXPECT_EQ(rowCount, 0);
500 }
501 
502 /**
503  * @tc.name: RdbStore_Transaction_011
504  * @tc.desc: BatchInsert with ConflictResolution::ON_CONFLICT_ROLLBACK
505  * @tc.type: FUNC
506  */
507 HWTEST_F(TransactionTest, RdbStore_Transaction_011, TestSize.Level1)
508 {
509     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
510     store->Execute("DROP TABLE IF EXISTS test1");
511     auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
512     ASSERT_EQ(res.first, E_OK);
513     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
514     ASSERT_EQ(ret, E_OK);
515     ASSERT_NE(transaction, nullptr);
516 
517     ValuesBuckets rows;
518     for (int i = 0; i < 5; i++) {
519         Transaction::Row row;
520         row.Put("id", i);
521         row.Put("name", "Jim");
522         rows.Put(row);
523     }
524     Transaction::Row row;
525     row.Put("id", 2);
526     row.Put("name", "Jim");
527     auto result = transaction->Insert("test1", row);
528     ASSERT_EQ(result.first, E_OK);
529     ASSERT_EQ(result.second, 2);
530     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_ROLLBACK);
531     ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
532     ASSERT_EQ(result.second, 0);
533     ASSERT_EQ(transaction->Commit(), E_SQLITE_ERROR);
534 
535     auto resultSet = store->QueryByStep("SELECT * FROM test1");
536     ASSERT_NE(resultSet, nullptr);
537     int32_t rowCount{};
538     ret = resultSet->GetRowCount(rowCount);
539     EXPECT_EQ(ret, E_OK);
540     EXPECT_EQ(rowCount, 0);
541 }
542 
543 /**
544  * @tc.name: RdbStore_Transaction_012
545  * @tc.desc: BatchInsert with ConflictResolution::ON_CONFLICT_ABORT
546  * @tc.type: FUNC
547  */
548 HWTEST_F(TransactionTest, RdbStore_Transaction_012, TestSize.Level1)
549 {
550     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
551     store->Execute("DROP TABLE IF EXISTS test1");
552     auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
553     ASSERT_EQ(res.first, E_OK);
554     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
555     ASSERT_EQ(ret, E_OK);
556     ASSERT_NE(transaction, nullptr);
557 
558     ValuesBuckets rows;
559     for (int i = 0; i < 5; i++) {
560         Transaction::Row row;
561         row.Put("id", i);
562         row.Put("name", "Jim");
563         rows.Put(row);
564     }
565     Transaction::Row row;
566     row.Put("id", 2);
567     row.Put("name", "Jim");
568     auto result = transaction->Insert("test1", row);
569     ASSERT_EQ(result.first, E_OK);
570     ASSERT_EQ(result.second, 2);
571     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_ABORT);
572     ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
573     ASSERT_EQ(result.second, 0);
574     ASSERT_EQ(transaction->Commit(), E_OK);
575 
576     auto resultSet = store->QueryByStep("SELECT * FROM test1");
577     ASSERT_NE(resultSet, nullptr);
578     int32_t rowCount{};
579     ret = resultSet->GetRowCount(rowCount);
580     EXPECT_EQ(ret, E_OK);
581     EXPECT_EQ(rowCount, 1);
582 }
583 
584 /**
585  * @tc.name: RdbStore_Transaction_013
586  * @tc.desc: BatchInsert with ConflictResolution::ON_CONFLICT_FAIL
587  * @tc.type: FUNC
588  */
589 HWTEST_F(TransactionTest, RdbStore_Transaction_013, TestSize.Level1)
590 {
591     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
592     store->Execute("DROP TABLE IF EXISTS test1");
593     auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
594     ASSERT_EQ(res.first, E_OK);
595     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
596     ASSERT_EQ(ret, E_OK);
597     ASSERT_NE(transaction, nullptr);
598 
599     ValuesBuckets rows;
600     for (int i = 0; i < 5; i++) {
601         Transaction::Row row;
602         row.Put("id", i);
603         row.Put("name", "Jim");
604         rows.Put(row);
605     }
606     Transaction::Row row;
607     row.Put("id", 2);
608     row.Put("name", "Jim");
609     auto result = transaction->Insert("test1", row);
610     ASSERT_EQ(result.first, E_OK);
611     ASSERT_EQ(result.second, 2);
612     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_FAIL);
613     ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
614     ASSERT_EQ(result.second, 2);
615     ASSERT_EQ(transaction->Commit(), E_OK);
616 
617     auto resultSet = store->QueryByStep("SELECT * FROM test1");
618     ASSERT_NE(resultSet, nullptr);
619     int32_t rowCount{};
620     ret = resultSet->GetRowCount(rowCount);
621     EXPECT_EQ(ret, E_OK);
622     EXPECT_EQ(rowCount, 3);
623 }
624 
625 /**
626  * @tc.name: RdbStore_Transaction_014
627  * @tc.desc: BatchInsert with ConflictResolution::ON_CONFLICT_IGNORE
628  * @tc.type: FUNC
629  */
630 HWTEST_F(TransactionTest, RdbStore_Transaction_014, TestSize.Level1)
631 {
632     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
633     store->Execute("DROP TABLE IF EXISTS test1");
634     auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
635     ASSERT_EQ(res.first, E_OK);
636     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
637     ASSERT_EQ(ret, E_OK);
638     ASSERT_NE(transaction, nullptr);
639 
640     ValuesBuckets rows;
641     for (int i = 0; i < 5; i++) {
642         Transaction::Row row;
643         row.Put("id", i);
644         row.Put("name", "Jim_batchInsert");
645         rows.Put(row);
646     }
647     Transaction::Row row;
648     row.Put("id", 2);
649     row.Put("name", "Jim_insert");
650     auto result = transaction->Insert("test1", row);
651     ASSERT_EQ(result.first, E_OK);
652     ASSERT_EQ(result.second, 2);
653     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_IGNORE);
654     ASSERT_EQ(result.first, E_OK);
655     ASSERT_EQ(result.second, 4);
656     ASSERT_EQ(transaction->Commit(), E_OK);
657 
658     auto resultSet = store->QueryByStep("SELECT * FROM test1");
659     ASSERT_NE(resultSet, nullptr);
660     int32_t rowCount{};
661     ret = resultSet->GetRowCount(rowCount);
662     EXPECT_EQ(ret, E_OK);
663     EXPECT_EQ(rowCount, 5);
664     resultSet = store->QueryByStep("SELECT * FROM test1 where id = 2");
665     ASSERT_NE(resultSet, nullptr);
666     ASSERT_EQ(resultSet->GoToFirstRow(), E_OK);
667     int columnIndex = -1;
668     ASSERT_EQ(resultSet->GetColumnIndex("name", columnIndex), E_OK);
669     std::string name;
670     EXPECT_EQ(resultSet->GetString(columnIndex, name), E_OK);
671     EXPECT_EQ(name, "Jim_insert");
672 }
673 
674 /**
675  * @tc.name: RdbStore_Transaction_015
676  * @tc.desc: BatchInsert with ConflictResolution::ON_CONFLICT_REPLACE
677  * @tc.type: FUNC
678  */
679 HWTEST_F(TransactionTest, RdbStore_Transaction_015, TestSize.Level1)
680 {
681     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
682     store->Execute("DROP TABLE IF EXISTS test1");
683     auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
684     ASSERT_EQ(res.first, E_OK);
685     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
686     ASSERT_EQ(ret, E_OK);
687     ASSERT_NE(transaction, nullptr);
688 
689     ValuesBuckets rows;
690     for (int i = 0; i < 5; i++) {
691         Transaction::Row row;
692         row.Put("id", i);
693         row.Put("name", "Jim_batchInsert");
694         rows.Put(row);
695     }
696     Transaction::Row row;
697     row.Put("id", 2);
698     row.Put("name", "Jim_insert");
699     auto result = transaction->Insert("test1", row);
700     ASSERT_EQ(result.first, E_OK);
701     ASSERT_EQ(result.second, 2);
702     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_REPLACE);
703     ASSERT_EQ(result.first, E_OK);
704     ASSERT_EQ(result.second, 5);
705     ASSERT_EQ(transaction->Commit(), E_OK);
706 
707     auto resultSet = store->QueryByStep("SELECT * FROM test1");
708     ASSERT_NE(resultSet, nullptr);
709     int32_t rowCount{};
710     ret = resultSet->GetRowCount(rowCount);
711     EXPECT_EQ(ret, E_OK);
712     EXPECT_EQ(rowCount, 5);
713     resultSet = store->QueryByStep("SELECT * FROM test1 where id = 2");
714     ASSERT_NE(resultSet, nullptr);
715     ASSERT_EQ(resultSet->GoToFirstRow(), E_OK);
716     int columnIndex = -1;
717     ASSERT_EQ(resultSet->GetColumnIndex("name", columnIndex), E_OK);
718     std::string name;
719     EXPECT_EQ(resultSet->GetString(columnIndex, name), E_OK);
720     EXPECT_EQ(name, "Jim_batchInsert");
721 }
722 
723 /**
724  * @tc.name: RdbStore_Transaction_016
725  * @tc.desc: BatchInsert with ConflictResolution::ON_CONFLICT_REPLACE and failed
726  * @tc.type: FUNC
727  */
728 HWTEST_F(TransactionTest, RdbStore_Transaction_016, TestSize.Level1)
729 {
730     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
731     store->Execute("DROP TABLE IF EXISTS test1");
732     auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
733     ASSERT_EQ(res.first, E_OK);
734     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
735     ASSERT_EQ(ret, E_OK);
736     ASSERT_NE(transaction, nullptr);
737 
738     ValuesBuckets rows;
739     for (int i = 0; i < 5; i++) {
740         Transaction::Row row;
741         row.Put("id", i);
742         row.Put("name", i == 2 ? ValueObject() : "Jim_batchInsert");
743         rows.Put(row);
744     }
745     Transaction::Row row;
746     row.Put("id", 2);
747     row.Put("name", "Jim_insert");
748     auto result = transaction->Insert("test1", row);
749     ASSERT_EQ(result.first, E_OK);
750     ASSERT_EQ(result.second, 2);
751     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_REPLACE);
752     // ON_CONFLICT_REPLACE is equivalent to ON_CONFLICT_ABORT after failure
753     ASSERT_EQ(result.first, E_SQLITE_CONSTRAINT);
754     ASSERT_EQ(result.second, 0);
755     ASSERT_EQ(transaction->Commit(), E_OK);
756 
757     auto resultSet = store->QueryByStep("SELECT * FROM test1");
758     ASSERT_NE(resultSet, nullptr);
759     ASSERT_EQ(resultSet->GoToFirstRow(), E_OK);
760     int columnIndex = -1;
761     ASSERT_EQ(resultSet->GetColumnIndex("name", columnIndex), E_OK);
762     std::string name;
763     EXPECT_EQ(resultSet->GetString(columnIndex, name), E_OK);
764     EXPECT_EQ(name, "Jim_insert");
765 }
766 
767 /**
768  * @tc.name: RdbStore_Transaction_017
769  * @tc.desc: BatchInsert when busy
770  * @tc.type: FUNC
771  */
772 HWTEST_F(TransactionTest, RdbStore_Transaction_017, TestSize.Level1)
773 {
774     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
775     store->Execute("DROP TABLE IF EXISTS test1");
776     auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
777     ASSERT_EQ(res.first, E_OK);
778     auto [ret1, transaction1] = store->CreateTransaction(Transaction::EXCLUSIVE);
779     ASSERT_EQ(ret1, E_OK);
780     ASSERT_NE(transaction1, nullptr);
781 
782     auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
783     ASSERT_EQ(ret, E_OK);
784     ASSERT_NE(transaction, nullptr);
785 
786     ValuesBuckets rows;
787     for (int i = 0; i < 5; i++) {
788         Transaction::Row row;
789         row.Put("id", i);
790         row.Put("name", "Jim_batchInsert");
791         rows.Put(row);
792     }
793     auto result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_NONE);
794     ASSERT_EQ(result.first, E_SQLITE_BUSY);
795     ASSERT_EQ(result.second, -1);
796 
797     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_ROLLBACK);
798     ASSERT_EQ(result.first, E_SQLITE_BUSY);
799     ASSERT_EQ(result.second, -1);
800 
801     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_ABORT);
802     ASSERT_EQ(result.first, E_SQLITE_BUSY);
803     ASSERT_EQ(result.second, -1);
804 
805     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_FAIL);
806     ASSERT_EQ(result.first, E_SQLITE_BUSY);
807     ASSERT_EQ(result.second, -1);
808 
809     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_IGNORE);
810     ASSERT_EQ(result.first, E_SQLITE_BUSY);
811     ASSERT_EQ(result.second, -1);
812 
813     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_REPLACE);
814     ASSERT_EQ(result.first, E_SQLITE_BUSY);
815     ASSERT_EQ(result.second, -1);
816 }
817 
818 /**
819  * @tc.name: RdbStore_Transaction_018
820  * @tc.desc: BatchInsert when over limit rows
821  * @tc.type: FUNC
822  */
823 HWTEST_F(TransactionTest, RdbStore_Transaction_018, TestSize.Level1)
824 {
825     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
826     store->Execute("DROP TABLE IF EXISTS test1");
827     auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
828     ASSERT_EQ(res.first, E_OK);
829 
830     auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
831     ASSERT_EQ(ret, E_OK);
832     ASSERT_NE(transaction, nullptr);
833 
834     //sqlite default max param number
835     int32_t maxNumber = 32766;
836     int32_t maxRows = maxNumber / 2 + 1;
837     ValuesBuckets rows;
838     for (int32_t i = 0; i < maxRows; i++) {
839         Transaction::Row row;
840         row.Put("id", i);
841         row.Put("name", "Jim_batchInsert");
842         rows.Put(row);
843     }
844     auto result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_NONE);
845     ASSERT_EQ(result.first, E_INVALID_ARGS);
846     ASSERT_EQ(result.second, -1);
847 
848     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_ROLLBACK);
849     ASSERT_EQ(result.first, E_INVALID_ARGS);
850     ASSERT_EQ(result.second, -1);
851 
852     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_ABORT);
853     ASSERT_EQ(result.first, E_INVALID_ARGS);
854     ASSERT_EQ(result.second, -1);
855 
856     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_FAIL);
857     ASSERT_EQ(result.first, E_INVALID_ARGS);
858     ASSERT_EQ(result.second, -1);
859 
860     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_IGNORE);
861     ASSERT_EQ(result.first, E_INVALID_ARGS);
862     ASSERT_EQ(result.second, -1);
863 
864     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_REPLACE);
865     ASSERT_EQ(result.first, E_INVALID_ARGS);
866     ASSERT_EQ(result.second, -1);
867 }
868 
869 /**
870  * @tc.name: RdbStore_Transaction_019
871  * @tc.desc: Normal BatchInsertWithConflictResolution
872  * @tc.type: FUNC
873  */
874 HWTEST_F(TransactionTest, RdbStore_Transaction_019, TestSize.Level1)
875 {
876     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
877     store->Execute("DROP TABLE IF EXISTS test1");
878     auto res = store->Execute("CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
879     ASSERT_EQ(res.first, E_OK);
880     auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
881     ASSERT_EQ(ret, E_OK);
882     ASSERT_NE(transaction, nullptr);
883 
884     ValuesBuckets rows;
885     auto result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_NONE);
886     ASSERT_EQ(result.first, E_OK);
887     ASSERT_EQ(result.second, 0);
888     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_ROLLBACK);
889     ASSERT_EQ(result.first, E_OK);
890     ASSERT_EQ(result.second, 0);
891     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_ABORT);
892     ASSERT_EQ(result.first, E_OK);
893     ASSERT_EQ(result.second, 0);
894     for (int i = 0; i < 2; i++) {
895         Transaction::Row row;
896         row.Put("name", "Jim_batchInsert");
897         rows.Put(row);
898     }
899     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_FAIL);
900     ASSERT_EQ(result.first, E_OK);
901     ASSERT_EQ(result.second, 2);
902     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_IGNORE);
903     ASSERT_EQ(result.first, E_OK);
904     ASSERT_EQ(result.second, 2);
905     result = transaction->BatchInsertWithConflictResolution("test1", rows, ConflictResolution::ON_CONFLICT_REPLACE);
906     ASSERT_EQ(result.first, E_OK);
907     ASSERT_EQ(result.second, 2);
908 
909     ASSERT_EQ(transaction->Commit(), E_OK);
910     auto resultSet = store->QueryByStep("SELECT * FROM test1");
911     ASSERT_NE(resultSet, nullptr);
912     int32_t rowCount{};
913     ret = resultSet->GetRowCount(rowCount);
914     EXPECT_EQ(ret, E_OK);
915     EXPECT_EQ(rowCount, 6);
916 }
917 
918 /**
919  * @tc.name: RdbStore_Transaction_020
920  * @tc.desc: After executing the ddl statement, the transaction links cached in the history need to be cleared.
921  * Continuing to use the old connections will result in errors due to changes in the table structure.
922  * @tc.type: FUNC
923  */
924 HWTEST_F(TransactionTest, RdbStore_Transaction_020, TestSize.Level1)
925 {
926     std::shared_ptr<RdbStore> &store = TransactionTest::store_;
927 
928     auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
929     ASSERT_EQ(ret, E_OK);
930     ASSERT_NE(transaction, nullptr);
931 
932     Transaction::Row row;
933     row.Put("id", 1);
934     row.Put("name", "Jim");
935     auto result = transaction->Insert("test", row);
936     ASSERT_EQ(result.first, E_OK);
937     ASSERT_EQ(result.second, 1);
938 
939     ret = transaction->Commit();
940     ASSERT_EQ(ret, E_OK);
941     transaction = nullptr;
942 
943     store->Execute("DROP TABLE IF EXISTS test1");
944     auto res = store->Execute(
945         "CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
946     ASSERT_EQ(res.first, E_OK);
947     // After creating the table, the links will be cleared, and creating a new transaction will create a new connection,
948     // ensuring that the transaction operation does not report errors.
949     std::tie(ret, transaction) = store->CreateTransaction(Transaction::DEFERRED);
950     ASSERT_EQ(ret, E_OK);
951     ASSERT_NE(transaction, nullptr);
952 
953     auto resultSet = transaction->QueryByStep("SELECT * FROM test");
954     ASSERT_NE(resultSet, nullptr);
955     int32_t rowCount{};
956     ret = resultSet->GetRowCount(rowCount);
957     EXPECT_EQ(ret, E_OK);
958     EXPECT_EQ(rowCount, 1);
959 }
960