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