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 "logger.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 static const int E_SQLITE_ERROR; // errno SQLITE_ERROR
39 };
40
41 const std::string RdbTransactionTest::DATABASE_NAME = RDB_TEST_PATH + "transaction_test.db";
42 std::shared_ptr<RdbStore> RdbTransactionTest::store = nullptr;
43 const int RdbTransactionTest::E_SQLITE_ERROR = -1; // errno SQLITE_ERROR
44
45 class TransactionTestOpenCallback : public RdbOpenCallback {
46 public:
47 int OnCreate(RdbStore &rdbStore) override;
48 int OnUpgrade(RdbStore &rdbStore, int oldVersion, int newVersion) override;
49 static const std::string CREATE_TABLE_TEST;
50 };
51
52 const std::string TransactionTestOpenCallback::CREATE_TABLE_TEST = std::string("CREATE TABLE IF NOT EXISTS test ")
53 + std::string("(id INTEGER PRIMARY KEY "
54 "AUTOINCREMENT, name TEXT NOT NULL, "
55 "age INTEGER, salary REAL, blobType "
56 "BLOB)");
57
OnCreate(RdbStore & store)58 int TransactionTestOpenCallback::OnCreate(RdbStore &store)
59 {
60 return store.ExecuteSql(CREATE_TABLE_TEST);
61 }
62
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)63 int TransactionTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
64 {
65 return E_OK;
66 }
67
SetUpTestCase(void)68 void RdbTransactionTest::SetUpTestCase(void)
69 {
70 int errCode = E_OK;
71 RdbStoreConfig config(RdbTransactionTest::DATABASE_NAME);
72 TransactionTestOpenCallback helper;
73 RdbTransactionTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
74 EXPECT_NE(RdbTransactionTest::store, nullptr);
75 EXPECT_EQ(errCode, E_OK);
76 }
77
TearDownTestCase(void)78 void RdbTransactionTest::TearDownTestCase(void)
79 {
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 * @tc.require: AR000CU2BO
97 * @tc.author: chenxi
98 */
99 HWTEST_F(RdbTransactionTest, RdbStore_Transaction_001, TestSize.Level1)
100 {
101 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
102
103 int64_t id;
104 ValuesBucket values;
105
106 int ret = store->BeginTransaction();
107 EXPECT_EQ(ret, E_OK);
108
109 values.PutInt("id", 1);
110 values.PutString("name", std::string("zhangsan"));
111 values.PutInt("age", 18);
112 values.PutDouble("salary", 100.5);
113 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
114 ret = store->Insert(id, "test", values);
115 EXPECT_EQ(ret, E_OK);
116 EXPECT_EQ(1, id);
117
118 values.Clear();
119 values.PutInt("id", 2);
120 values.PutString("name", std::string("lisi"));
121 values.PutInt("age", 19);
122 values.PutDouble("salary", 200.5);
123 values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6 });
124 ret = store->Insert(id, "test", values);
125 EXPECT_EQ(ret, E_OK);
126 EXPECT_EQ(2, id);
127
128 values.Clear();
129 values.PutInt("id", 3);
130 values.PutString("name", std::string("wangyjing"));
131 values.PutInt("age", 20);
132 values.PutDouble("salary", 300.5);
133 values.PutBlob("blobType", std::vector<uint8_t>{ 7, 8, 9 });
134 ret = store->Insert(id, "test", values);
135 EXPECT_EQ(ret, E_OK);
136 EXPECT_EQ(3, id);
137
138 ret = store->Commit();
139 EXPECT_EQ(ret, E_OK);
140
141 int64_t count;
142 ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
143 EXPECT_EQ(ret, E_OK);
144 EXPECT_EQ(count, 3);
145
146 int deletedRows;
147 ret = store->Delete(deletedRows, "test");
148 EXPECT_EQ(ret, E_OK);
149 EXPECT_EQ(deletedRows, 3);
150 }
151
152 /**
153 * @tc.name: RdbStore_Transaction_002
154 * @tc.desc: test RdbStore BaseTransaction
155 * @tc.type: FUNC
156 * @tc.require: AR000CU2BO
157 * @tc.author: chenxi
158 */
159 HWTEST_F(RdbTransactionTest, RdbStore_Transaction_002, TestSize.Level1)
160 {
161 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
162
163 int64_t id;
164 ValuesBucket values;
165
166 int ret = store->BeginTransaction();
167 EXPECT_EQ(ret, E_OK);
168
169 values.PutInt("id", 1);
170 values.PutString("name", std::string("zhangsan"));
171 values.PutInt("age", 18);
172 values.PutDouble("salary", 100.5);
173 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
174 ret = store->Insert(id, "test", values);
175 EXPECT_EQ(ret, E_OK);
176 EXPECT_EQ(1, id);
177
178 values.Clear();
179 values.PutInt("id", 2);
180 values.PutString("name", std::string("lisi"));
181 values.PutInt("age", 19);
182 values.PutDouble("salary", 200.5);
183 values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6 });
184 ret = store->Insert(id, "test", values);
185 EXPECT_EQ(ret, E_OK);
186 EXPECT_EQ(2, id);
187
188 values.Clear();
189 values.PutInt("id", 3);
190 values.PutString("name", std::string("wangyjing"));
191 values.PutInt("age", 20);
192 values.PutDouble("salary", 300.5);
193 values.PutBlob("blobType", std::vector<uint8_t>{ 7, 8, 9 });
194 ret = store->Insert(id, "test", values);
195 EXPECT_EQ(ret, E_OK);
196 EXPECT_EQ(3, id);
197
198 ret = store->Commit();
199 EXPECT_EQ(ret, E_OK);
200
201 int64_t count;
202 ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
203 EXPECT_EQ(ret, E_OK);
204 EXPECT_EQ(count, 3);
205
206 std::unique_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
207 EXPECT_NE(resultSet, nullptr);
208 ret = resultSet->GoToNextRow();
209 EXPECT_EQ(ret, E_OK);
210 ret = resultSet->Close();
211 EXPECT_EQ(ret, E_OK);
212
213 int deletedRows;
214 ret = store->Delete(deletedRows, "test");
215 EXPECT_EQ(ret, E_OK);
216 EXPECT_EQ(deletedRows, 3);
217 }
218
219 /**
220 * @tc.name: RdbStore_NestedTransaction_001
221 * @tc.desc: test RdbStore BaseTransaction
222 * @tc.type: FUNC
223 * @tc.require: AR000CU2BO
224 * @tc.author: chenxi
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 ValuesBucket values;
232
233 int ret = store->BeginTransaction();
234 EXPECT_EQ(ret, E_OK);
235
236 values.PutInt("id", 1);
237 values.PutString("name", std::string("zhangsan"));
238 values.PutInt("age", 18);
239 values.PutDouble("salary", 100.5);
240 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
241 ret = store->Insert(id, "test", values);
242 EXPECT_EQ(ret, E_OK);
243 EXPECT_EQ(1, id);
244
245 ret = store->BeginTransaction();
246 EXPECT_EQ(ret, E_OK);
247 values.Clear();
248 values.PutInt("id", 2);
249 values.PutString("name", std::string("lisi"));
250 values.PutInt("age", 19);
251 values.PutDouble("salary", 200.5);
252 values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6 });
253 ret = store->Insert(id, "test", values);
254 EXPECT_EQ(ret, E_OK);
255 EXPECT_EQ(2, id);
256 ret = store->Commit(); // not commit
257 EXPECT_EQ(ret, E_OK);
258
259 values.Clear();
260 values.PutInt("id", 3);
261 values.PutString("name", std::string("wangyjing"));
262 values.PutInt("age", 20);
263 values.PutDouble("salary", 300.5);
264 values.PutBlob("blobType", std::vector<uint8_t>{ 7, 8, 9 });
265 ret = store->Insert(id, "test", values);
266 EXPECT_EQ(ret, E_OK);
267 EXPECT_EQ(3, id);
268
269 ret = store->Commit();
270 EXPECT_EQ(ret, E_OK);
271
272 int64_t count;
273 ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
274 EXPECT_EQ(ret, E_OK);
275 EXPECT_EQ(count, 3);
276
277 std::unique_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
278 EXPECT_NE(resultSet, nullptr);
279 ret = resultSet->GoToNextRow();
280 EXPECT_EQ(ret, E_OK);
281 ret = resultSet->Close();
282 EXPECT_EQ(ret, E_OK);
283
284 int deletedRows;
285 ret = store->Delete(deletedRows, "test");
286 EXPECT_EQ(ret, E_OK);
287 EXPECT_EQ(deletedRows, 3);
288 }
289
290 /**
291 * @tc.name: RdbStore_NestedTransaction_002
292 * @tc.desc: test RdbStore BaseTransaction
293 * @tc.type: FUNC
294 * @tc.require: AR000CU2BO
295 * @tc.author: chenxi
296 */
297 HWTEST_F(RdbTransactionTest, RdbStore_NestedTransaction_002, TestSize.Level1)
298 {
299 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
300
301 int64_t id;
302 ValuesBucket values;
303
304 int ret = store->BeginTransaction();
305 EXPECT_EQ(ret, E_OK);
306
307 values.PutInt("id", 1);
308 values.PutString("name", std::string("zhangsan"));
309 values.PutInt("age", 18);
310 values.PutDouble("salary", 100.5);
311 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
312 ret = store->Insert(id, "test", values);
313 EXPECT_EQ(ret, E_OK);
314 EXPECT_EQ(1, id);
315
316 ret = store->BeginTransaction();
317 EXPECT_EQ(ret, E_OK);
318 values.Clear();
319 values.PutInt("id", 2);
320 values.PutString("name", std::string("lisi"));
321 values.PutInt("age", 19);
322 values.PutDouble("salary", 200.5);
323 values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6 });
324 ret = store->Insert(id, "test", values);
325 EXPECT_EQ(ret, E_OK);
326 EXPECT_EQ(2, id);
327 ret = store->Commit();
328 EXPECT_EQ(ret, E_OK);
329 ret = store->Commit(); // commit
330 EXPECT_EQ(ret, E_OK);
331
332 values.Clear();
333 values.PutInt("id", 3);
334 values.PutString("name", std::string("wangyjing"));
335 values.PutInt("age", 20);
336 values.PutDouble("salary", 300.5);
337 values.PutBlob("blobType", std::vector<uint8_t>{ 7, 8, 9 });
338 ret = store->Insert(id, "test", values);
339 EXPECT_EQ(ret, E_OK);
340 EXPECT_EQ(3, id);
341
342 int64_t count;
343 ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
344 EXPECT_EQ(ret, E_OK);
345 EXPECT_EQ(count, 3);
346
347 std::unique_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
348 EXPECT_NE(resultSet, nullptr);
349 ret = resultSet->GoToNextRow();
350 EXPECT_EQ(ret, E_OK);
351 ret = resultSet->Close();
352 EXPECT_EQ(ret, E_OK);
353
354 int deletedRows;
355 ret = store->Delete(deletedRows, "test");
356 EXPECT_EQ(ret, E_OK);
357 EXPECT_EQ(deletedRows, 3);
358 }
359
360 /**
361 * @tc.name: RdbStore_NestedTransaction_003
362 * @tc.desc: test RdbStore BaseTransaction
363 * @tc.type: FUNC
364 * @tc.require: AR000CU2BO
365 * @tc.author: chenxi
366 */
367 HWTEST_F(RdbTransactionTest, RdbStore_NestedTransaction_003, TestSize.Level1)
368 {
369 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
370
371 int64_t id;
372 ValuesBucket values;
373
374 int ret = store->BeginTransaction();
375 EXPECT_EQ(ret, E_OK);
376
377 values.PutInt("id", 1);
378 values.PutString("name", std::string("zhangsan"));
379 values.PutInt("age", 18);
380 values.PutDouble("salary", 100.5);
381 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
382 ret = store->Insert(id, "test", values);
383 EXPECT_EQ(ret, E_OK);
384 EXPECT_EQ(1, id);
385
386 ret = store->BeginTransaction();
387 EXPECT_EQ(ret, E_OK);
388 values.Clear();
389 values.PutInt("id", 2);
390 values.PutString("name", std::string("lisi"));
391 values.PutInt("age", 19);
392 values.PutDouble("salary", 200.5);
393 values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6 });
394 ret = store->Insert(id, "test", values);
395 EXPECT_EQ(ret, E_OK);
396 EXPECT_EQ(2, id);
397 ret = store->Commit(); // not commit
398 EXPECT_EQ(ret, E_OK);
399
400 values.Clear();
401 values.PutInt("id", 3);
402 values.PutString("name", std::string("wangyjing"));
403 values.PutInt("age", 20);
404 values.PutDouble("salary", 300.5);
405 values.PutBlob("blobType", std::vector<uint8_t>{ 7, 8, 9 });
406 ret = store->Insert(id, "test", values);
407 EXPECT_EQ(ret, E_OK);
408 EXPECT_EQ(3, id);
409
410 ret = store->Commit(); // not commit
411 EXPECT_EQ(ret, E_OK);
412
413 int64_t count;
414 ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
415 EXPECT_EQ(ret, E_OK);
416 EXPECT_EQ(count, 3);
417
418 std::unique_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
419 EXPECT_NE(resultSet, nullptr);
420 ret = resultSet->GoToNextRow();
421 EXPECT_EQ(ret, E_OK);
422 ret = resultSet->Close();
423 EXPECT_EQ(ret, E_OK);
424
425 int deletedRows;
426 ret = store->Delete(deletedRows, "test");
427 EXPECT_EQ(ret, E_OK);
428 EXPECT_EQ(deletedRows, 3);
429 }
430
431 /**
432 * @tc.name: RdbStore_NestedTransaction_004
433 * @tc.desc: test RdbStore BaseTransaction
434 * @tc.type: FUNC
435 * @tc.require: AR000CU2BO
436 * @tc.author: chenxi
437 */
438 HWTEST_F(RdbTransactionTest, RdbStore_NestedTransaction_004, TestSize.Level1)
439 {
440 std::shared_ptr<RdbStore> &store = RdbTransactionTest::store;
441
442 int64_t id;
443 ValuesBucket values;
444
445 int ret = store->BeginTransaction();
446 EXPECT_EQ(ret, E_OK);
447
448 values.PutInt("id", 1);
449 values.PutString("name", std::string("zhangsan"));
450 values.PutInt("age", 18);
451 values.PutDouble("salary", 100.5);
452 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
453 ret = store->Insert(id, "test", values);
454 EXPECT_EQ(ret, E_OK);
455 EXPECT_EQ(1, id);
456
457 ret = store->BeginTransaction();
458 EXPECT_EQ(ret, E_OK);
459 values.Clear();
460 values.PutInt("id", 2);
461 values.PutString("name", std::string("lisi"));
462 values.PutInt("age", 19);
463 values.PutDouble("salary", 200.5);
464 values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6 });
465 ret = store->Insert(id, "test", values);
466 EXPECT_EQ(ret, E_OK);
467 EXPECT_EQ(2, id);
468 ret = store->Commit(); // commit
469 EXPECT_EQ(ret, E_OK);
470
471 values.Clear();
472 values.PutInt("id", 3);
473 values.PutString("name", std::string("wangyjing"));
474 values.PutInt("age", 20);
475 values.PutDouble("salary", 300.5);
476 values.PutBlob("blobType", std::vector<uint8_t>{ 7, 8, 9 });
477 ret = store->Insert(id, "test", values);
478 EXPECT_EQ(ret, E_OK);
479 EXPECT_EQ(3, id);
480
481 ret = store->Commit(); // commit
482 EXPECT_EQ(ret, E_OK);
483
484 int64_t count;
485 ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
486 EXPECT_EQ(ret, E_OK);
487 EXPECT_EQ(count, 3);
488
489 std::unique_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
490 EXPECT_NE(resultSet, nullptr);
491 ret = resultSet->GoToNextRow();
492 EXPECT_EQ(ret, E_OK);
493 ret = resultSet->GoToNextRow();
494 EXPECT_EQ(ret, E_OK);
495 ret = resultSet->GoToNextRow();
496 EXPECT_EQ(ret, E_OK);
497 ret = resultSet->GoToNextRow();
498 EXPECT_EQ(ret, E_ERROR);
499 ret = resultSet->Close();
500 EXPECT_EQ(ret, E_OK);
501
502 int deletedRows;
503 ret = store->Delete(deletedRows, "test");
504 EXPECT_EQ(ret, E_OK);
505 EXPECT_EQ(deletedRows, 3);
506 }