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
49
OnCreate(RdbStore & store)50 int TransactionTest::TransactionTestOpenCallback::OnCreate(RdbStore &store)
51 {
52 auto [ret, value] = store.Execute(CREATE_TABLE_SQL);
53 return ret;
54 }
55
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)56 int TransactionTest::TransactionTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
57 {
58 return E_OK;
59 }
60
SetUpTestCase()61 void TransactionTest::SetUpTestCase()
62 {
63 int errCode = E_OK;
64 RdbHelper::DeleteRdbStore(DATABASE_NAME);
65 RdbStoreConfig config(DATABASE_NAME);
66 TransactionTestOpenCallback helper;
67 TransactionTest::store_ = RdbHelper::GetRdbStore(config, 1, helper, errCode);
68 EXPECT_NE(TransactionTest::store_, nullptr);
69 EXPECT_EQ(errCode, E_OK);
70 }
71
TearDownTestCase()72 void TransactionTest::TearDownTestCase()
73 {
74 store_ = nullptr;
75 RdbHelper::DeleteRdbStore(DATABASE_NAME);
76 }
77
SetUp()78 void TransactionTest::SetUp()
79 {
80 store_->Execute("DELETE FROM test");
81 }
82
TearDown()83 void TransactionTest::TearDown()
84 {
85 }
86
87 /**
88 * @tc.name: RdbStore_Transaction_001
89 * @tc.desc: createTransaction and commit
90 * @tc.type: FUNC
91 */
92 HWTEST_F(TransactionTest, RdbStore_Transaction_001, TestSize.Level1)
93 {
94 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
95
96 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
97 ASSERT_EQ(ret, E_OK);
98 ASSERT_NE(transaction, nullptr);
99
100 auto result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
101 ASSERT_EQ(result.first, E_OK);
102 ASSERT_EQ(1, result.second);
103
104 result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
105 ASSERT_EQ(result.first, E_OK);
106 ASSERT_EQ(2, result.second);
107
108 result = store->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[2]), RdbStore::NO_ACTION);
109 ASSERT_EQ(result.first, E_SQLITE_BUSY);
110
111 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
112 ASSERT_NE(resultSet, nullptr);
113 int32_t rowCount{};
114 ret = resultSet->GetRowCount(rowCount);
115 ASSERT_EQ(ret, E_OK);
116 ASSERT_EQ(rowCount, 2);
117
118 ret = transaction->Commit();
119 ASSERT_EQ(ret, E_OK);
120
121 ValueObject value;
122 ret = resultSet->Get(0, value);
123 ASSERT_EQ(ret, E_ALREADY_CLOSED);
124
125 result = store->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[2]), RdbStore::NO_ACTION);
126 ASSERT_EQ(result.first, E_OK);
127 ASSERT_EQ(3, result.second);
128
129 result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
130 ASSERT_EQ(result.first, E_ALREADY_CLOSED);
131
132 resultSet = store->QueryByStep("SELECT * FROM test");
133 ASSERT_NE(resultSet, nullptr);
134 resultSet->GetRowCount(rowCount);
135 EXPECT_EQ(rowCount, 3);
136 }
137
138 /**
139 * @tc.name: RdbStore_Transaction_002
140 * @tc.desc: createTransaction and rollback
141 * @tc.type: FUNC
142 */
143 HWTEST_F(TransactionTest, RdbStore_Transaction_002, TestSize.Level1)
144 {
145 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
146
147 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
148 ASSERT_EQ(ret, E_OK);
149 ASSERT_NE(transaction, nullptr);
150
151 auto result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
152 ASSERT_EQ(result.first, E_OK);
153 ASSERT_EQ(1, result.second);
154
155 result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
156 ASSERT_EQ(result.first, E_OK);
157 ASSERT_EQ(2, result.second);
158
159 ret = transaction->Rollback();
160 ASSERT_EQ(ret, E_OK);
161
162 auto resultSet = store->QueryByStep("SELECT * FROM test");
163 ASSERT_NE(resultSet, nullptr);
164 int32_t rowCount{};
165 ret = resultSet->GetRowCount(rowCount);
166 ASSERT_EQ(ret, E_OK);
167 ASSERT_EQ(rowCount, 0);
168
169 result = store->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[2]), RdbStore::NO_ACTION);
170 ASSERT_EQ(result.first, E_OK);
171 ASSERT_EQ(3, result.second);
172
173 result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
174 ASSERT_EQ(result.first, E_ALREADY_CLOSED);
175
176 resultSet = store->QueryByStep("SELECT * FROM test");
177 ASSERT_NE(resultSet, nullptr);
178 ret = resultSet->GetRowCount(rowCount);
179 EXPECT_EQ(ret, E_OK);
180 EXPECT_EQ(rowCount, 1);
181 }
182
183 /**
184 * @tc.name: RdbStore_Transaction_003
185 * @tc.desc: batchInsert
186 * @tc.type: FUNC
187 */
188 HWTEST_F(TransactionTest, RdbStore_Transaction_003, TestSize.Level1)
189 {
190 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
191
192 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
193 ASSERT_EQ(ret, E_OK);
194 ASSERT_NE(transaction, nullptr);
195
196 Transaction::Rows rows {
197 UTUtils::SetRowData(UTUtils::g_rowData[0]),
198 UTUtils::SetRowData(UTUtils::g_rowData[1]),
199 UTUtils::SetRowData(UTUtils::g_rowData[2]),
200 };
201 auto result = transaction->BatchInsert("test", rows);
202 ASSERT_EQ(result.first, E_OK);
203 ASSERT_EQ(result.second, 3);
204
205 ret = transaction->Commit();
206 ASSERT_EQ(ret, E_OK);
207
208 auto resultSet = store->QueryByStep("SELECT * FROM test");
209 ASSERT_NE(resultSet, nullptr);
210 int32_t rowCount{};
211 ret = resultSet->GetRowCount(rowCount);
212 EXPECT_EQ(ret, E_OK);
213 EXPECT_EQ(rowCount, 3);
214 }
215
216 /**
217 * @tc.name: RdbStore_Transaction_004
218 * @tc.desc: batchInsert
219 * @tc.type: FUNC
220 */
221 HWTEST_F(TransactionTest, RdbStore_Transaction_004, TestSize.Level1)
222 {
223 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
224
225 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
226 ASSERT_EQ(ret, E_OK);
227 ASSERT_NE(transaction, nullptr);
228
229 Transaction::RefRows rows;
230 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[0]));
231 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[1]));
232 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[2]));
233
234 auto result = transaction->BatchInsert("test", rows);
235 ASSERT_EQ(result.first, E_OK);
236 ASSERT_EQ(result.second, 3);
237
238 ret = transaction->Commit();
239 ASSERT_EQ(ret, E_OK);
240
241 auto resultSet = store->QueryByStep("SELECT * FROM test");
242 ASSERT_NE(resultSet, nullptr);
243 int32_t rowCount{};
244 ret = resultSet->GetRowCount(rowCount);
245 EXPECT_EQ(ret, E_OK);
246 EXPECT_EQ(rowCount, 3);
247 }
248
249 /**
250 * @tc.name: RdbStore_Transaction_005
251 * @tc.desc: Update
252 * @tc.type: FUNC
253 */
254 HWTEST_F(TransactionTest, RdbStore_Transaction_005, TestSize.Level1)
255 {
256 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
257
258 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
259 ASSERT_EQ(ret, E_OK);
260 ASSERT_NE(transaction, nullptr);
261
262 auto result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
263 ASSERT_EQ(result.first, E_OK);
264 ASSERT_EQ(result.second, 1);
265
266 result = transaction->Update("test", UTUtils::SetRowData(UTUtils::g_rowData[1]), "id=1");
267 ASSERT_EQ(result.first, E_OK);
268 ASSERT_EQ(result.second, 1);
269
270 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
271 ASSERT_NE(resultSet, nullptr);
272 int32_t rowCount{};
273 ret = resultSet->GetRowCount(rowCount);
274 ASSERT_EQ(ret, E_OK);
275 ASSERT_EQ(rowCount, 1);
276 ret = resultSet->GoToFirstRow();
277 ASSERT_EQ(ret, E_OK);
278 int32_t columnIndex{};
279 ret = resultSet->GetColumnIndex("id", columnIndex);
280 ASSERT_EQ(ret, E_OK);
281 int32_t id{};
282 ret = resultSet->GetInt(columnIndex, id);
283 ASSERT_EQ(ret, E_OK);
284 ASSERT_EQ(id, 2);
285
286 AbsRdbPredicates predicates("test");
287 predicates.EqualTo("id", ValueObject(2));
288 result = transaction->Update(UTUtils::SetRowData(UTUtils::g_rowData[2]), predicates);
289 ASSERT_EQ(result.first, E_OK);
290 ASSERT_EQ(result.second, 1);
291
292 ret = transaction->Commit();
293 ASSERT_EQ(ret, E_OK);
294
295 resultSet = store->QueryByStep("SELECT * FROM test");
296 ASSERT_NE(resultSet, nullptr);
297 ret = resultSet->GetRowCount(rowCount);
298 ASSERT_EQ(ret, E_OK);
299 ASSERT_EQ(rowCount, 1);
300 ret = resultSet->GoToFirstRow();
301 ASSERT_EQ(ret, E_OK);
302 resultSet->GetColumnIndex("id", columnIndex);
303 ret = resultSet->GetInt(columnIndex, id);
304 EXPECT_EQ(ret, E_OK);
305 EXPECT_EQ(id, 3);
306 }
307
308 /**
309 * @tc.name: RdbStore_Transaction_006
310 * @tc.desc: Delete
311 * @tc.type: FUNC
312 */
313 HWTEST_F(TransactionTest, RdbStore_Transaction_006, TestSize.Level1)
314 {
315 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
316
317 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
318 ASSERT_EQ(ret, E_OK);
319 ASSERT_NE(transaction, nullptr);
320
321 Transaction::RefRows rows;
322 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[0]));
323 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[1]));
324 rows.Put(UTUtils::SetRowData(UTUtils::g_rowData[2]));
325
326 auto result = transaction->BatchInsert("test", rows);
327 ASSERT_EQ(result.first, E_OK);
328 ASSERT_EQ(result.second, 3);
329
330 result = transaction->Delete("test", "id=1");
331 ASSERT_EQ(result.first, E_OK);
332 ASSERT_EQ(result.second, 1);
333
334 AbsRdbPredicates predicates("test");
335 predicates.EqualTo("id", ValueObject(2));
336 result = transaction->Delete(predicates);
337 ASSERT_EQ(result.first, E_OK);
338 ASSERT_EQ(result.second, 1);
339
340 ret = transaction->Commit();
341 ASSERT_EQ(ret, E_OK);
342
343 auto resultSet = store->QueryByStep("SELECT * FROM test");
344 ASSERT_NE(resultSet, nullptr);
345 int32_t rowCount{};
346 ret = resultSet->GetRowCount(rowCount);
347 ASSERT_EQ(ret, E_OK);
348 ASSERT_EQ(rowCount, 1);
349 ret = resultSet->GoToFirstRow();
350 ASSERT_EQ(ret, E_OK);
351 int32_t columnIndex{};
352 resultSet->GetColumnIndex("id", columnIndex);
353 int32_t id{};
354 ret = resultSet->GetInt(columnIndex, id);
355 EXPECT_EQ(ret, E_OK);
356 EXPECT_EQ(id, 3);
357 }
358
359 /**
360 * @tc.name: RdbStore_Transaction_007
361 * @tc.desc: Execute
362 * @tc.type: FUNC
363 */
364 HWTEST_F(TransactionTest, RdbStore_Transaction_007, TestSize.Level1)
365 {
366 std::shared_ptr<RdbStore> &store = TransactionTest::store_;
367
368 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
369 ASSERT_EQ(ret, E_OK);
370 ASSERT_NE(transaction, nullptr);
371
372 auto res = transaction->Execute(
373 "CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
374 ASSERT_EQ(res.first, E_OK);
375 Transaction::Row row;
376 row.Put("id", 1);
377 row.Put("name", "Jim");
378 auto result = transaction->Insert("test1", row);
379 ASSERT_EQ(result.first, E_OK);
380 ASSERT_EQ(result.second, 1);
381
382 ret = transaction->Commit();
383 ASSERT_EQ(ret, E_OK);
384
385 auto resultSet = store->QueryByStep("SELECT * FROM test1");
386 ASSERT_NE(resultSet, nullptr);
387 int32_t rowCount{};
388 ret = resultSet->GetRowCount(rowCount);
389 EXPECT_EQ(ret, E_OK);
390 EXPECT_EQ(rowCount, 1);
391 }
392