1 /*
2 * Copyright (c) 2021 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 #include "value_object.h"
25
26 using namespace testing::ext;
27 using namespace OHOS::NativeRdb;
28 namespace OHOS::RdbExecuteTest {
29 struct RdbTestParam {
30 std::shared_ptr<RdbStore> store;
31 std::string mode;
operator std::shared_ptr<RdbStore>OHOS::RdbExecuteTest::RdbTestParam32 operator std::shared_ptr<RdbStore>()
33 {
34 return store;
35 }
36 };
37 static RdbTestParam g_store;
38 static RdbTestParam g_memDb;
39
40 class RdbExecuteTest : public testing::TestWithParam<RdbTestParam *> {
41 public:
42 static void SetUpTestCase(void);
43 static void TearDownTestCase(void);
44 void SetUp();
45 void TearDown();
46
47 std::shared_ptr<RdbStore> store_;
48 static const std::string DATABASE_NAME;
49 };
50 constexpr const char *CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test "
51 "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
52 "name TEXT NOT NULL, age INTEGER, salary REAL, "
53 "blobType BLOB)";
54 const std::string RdbExecuteTest::DATABASE_NAME = RDB_TEST_PATH + "execute_test.db";
55
56 class ExecuteTestOpenCallback : public RdbOpenCallback {
57 public:
58 int OnCreate(RdbStore &store) override;
59 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
60 };
61
OnCreate(RdbStore & store)62 int ExecuteTestOpenCallback::OnCreate(RdbStore &store)
63 {
64 return E_OK;
65 }
66
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)67 int ExecuteTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
68 {
69 return E_OK;
70 }
71
SetUpTestCase(void)72 void RdbExecuteTest::SetUpTestCase(void)
73 {
74 int errCode = E_OK;
75 RdbHelper::DeleteRdbStore(DATABASE_NAME);
76 RdbStoreConfig config(RdbExecuteTest::DATABASE_NAME);
77 ExecuteTestOpenCallback helper;
78 g_store.store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
79 ASSERT_NE(g_store.store, nullptr);
80 g_store.mode = "wal";
81
82 config.SetStorageMode(StorageMode::MODE_MEMORY);
83 g_memDb.store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
84 ASSERT_NE(g_memDb.store, nullptr);
85 g_memDb.mode = "memory";
86 }
87
TearDownTestCase(void)88 void RdbExecuteTest::TearDownTestCase(void)
89 {
90 RdbStoreConfig config(RdbExecuteTest::DATABASE_NAME);
91 RdbHelper::DeleteRdbStore(config);
92 config.SetStorageMode(StorageMode::MODE_MEMORY);
93 RdbHelper::DeleteRdbStore(config);
94 }
95
SetUp(void)96 void RdbExecuteTest::SetUp(void)
97 {
98 store_ = *GetParam();
99 ASSERT_NE(store_, nullptr);
100 store_->ExecuteSql(CREATE_TABLE_TEST);
101 }
102
TearDown(void)103 void RdbExecuteTest::TearDown(void)
104 {
105 store_ = *GetParam();
106 ASSERT_NE(store_, nullptr);
107 store_->ExecuteSql("DROP TABLE test");
108 }
109
110 /**
111 * @tc.name: RdbStore_Execute_001
112 * @tc.desc: test RdbStore Execute
113 * @tc.type: FUNC
114 */
115 HWTEST_P(RdbExecuteTest, RdbStore_Execute_001, TestSize.Level1)
116 {
117 int64_t id;
118 ValuesBucket values;
119
120 values.PutInt("id", 1);
121 values.PutString("name", std::string("zhangsan"));
122 values.PutInt("age", 18);
123 values.PutDouble("salary", 100.5);
124 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
125 int ret = store_->Insert(id, "test", values);
126 EXPECT_EQ(ret, E_OK);
127 EXPECT_EQ(1, id);
128
129 values.Clear();
130 values.PutInt("id", 2);
131 values.PutString("name", std::string("lisi"));
132 values.PutInt("age", 19);
133 values.PutDouble("salary", 200.5);
134 values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6 });
135 ret = store_->Insert(id, "test", values);
136 EXPECT_EQ(ret, E_OK);
137 EXPECT_EQ(2, id);
138
139 values.Clear();
140 values.PutInt("id", 3);
141 values.PutString("name", std::string("wangyjing"));
142 values.PutInt("age", 20);
143 values.PutDouble("salary", 300.5);
144 values.PutBlob("blobType", std::vector<uint8_t>{ 7, 8, 9 });
145 ret = store_->Insert(id, "test", values);
146 EXPECT_EQ(ret, E_OK);
147 EXPECT_EQ(3, id);
148
149 int64_t count;
150 ret = store_->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
151 EXPECT_EQ(ret, E_OK);
152 EXPECT_EQ(count, 3);
153
154 ret = store_->ExecuteSql("DELETE FROM test WHERE age = ? OR age = ?",
155 std::vector<ValueObject>{ ValueObject(std::string("18")), ValueObject(std ::string("20")) });
156 EXPECT_EQ(ret, E_OK);
157
158 ret = store_->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test where age = 19");
159 EXPECT_EQ(ret, E_OK);
160 EXPECT_EQ(count, 1);
161
162 ret = store_->ExecuteSql("DELETE FROM test WHERE age = 19");
163 EXPECT_EQ(ret, E_OK);
164
165 ret = store_->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
166 EXPECT_EQ(ret, E_OK);
167 EXPECT_EQ(count, 0);
168 }
169
170 /**
171 * @tc.name: RdbStore_Execute_002
172 * @tc.desc: test RdbStore Execute
173 * @tc.type: FUNC
174 */
175 HWTEST_P(RdbExecuteTest, RdbStore_Execute_002, TestSize.Level1)
176 {
177 int64_t id;
178 ValuesBucket values;
179
180 int ret = store_->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
181 EXPECT_EQ(ret, E_OK);
182 EXPECT_EQ(1, id);
183
184 ret = store_->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
185 EXPECT_EQ(ret, E_OK);
186 EXPECT_EQ(2, id);
187
188 ret = store_->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[2]));
189 EXPECT_EQ(ret, E_OK);
190 EXPECT_EQ(3, id);
191
192 int64_t count;
193 ret = store_->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test", std::vector<ValueObject>());
194 EXPECT_EQ(ret, E_OK);
195 EXPECT_EQ(count, 3);
196
197 ret = store_->ExecuteSql("DELETE FROM test WHERE age = ? OR age = ?",
198 std::vector<ValueObject>{ ValueObject(std::string("18")), ValueObject(std ::string("20")) });
199 EXPECT_EQ(ret, E_OK);
200
201 ret = store_->ExecuteAndGetLong(
202 count, "SELECT COUNT(*) FROM test where age = ?", std::vector<ValueObject>{ ValueObject(std::string("19")) });
203 EXPECT_EQ(ret, E_OK);
204 EXPECT_EQ(count, 1);
205
206 ret = store_->ExecuteSql("DELETE FROM test WHERE age = 19");
207 EXPECT_EQ(ret, E_OK);
208
209 ret = store_->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test", std::vector<ValueObject>());
210 EXPECT_EQ(ret, E_OK);
211 EXPECT_EQ(count, 0);
212
213 ret = store_->ExecuteSql("DROP TABLE IF EXISTS test");
214 EXPECT_EQ(ret, E_OK);
215
216 ret = store_->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
217 EXPECT_EQ(ret, E_SQLITE_ERROR);
218 }
219
220 /**
221 * @tc.name: RdbStore_Execute_003
222 * @tc.desc: test RdbStore Execute
223 * @tc.type: FUNC
224 */
225 HWTEST_P(RdbExecuteTest, RdbStore_Execute_003, TestSize.Level1)
226 {
227 int64_t pageSize;
228 int ret = store_->ExecuteAndGetLong(pageSize, "PRAGMA page_size");
229 EXPECT_EQ(ret, E_OK);
230 EXPECT_EQ(pageSize, 4096);
231
232 int64_t journalSize;
233 ret = store_->ExecuteAndGetLong(journalSize, "PRAGMA journal_size_limit");
234 EXPECT_EQ(ret, E_OK);
235 EXPECT_EQ(journalSize, 1048576);
236
237 std::string journalMode;
238 ret = store_->ExecuteAndGetString(journalMode, "PRAGMA journal_mode");
239 EXPECT_EQ(ret, E_OK);
240 EXPECT_EQ(journalMode, GetParam()->mode);
241 }
242
243 /**
244 * @tc.name: RdbStore_Execute_004
245 * @tc.desc: Abnormal testCase for ExecuteAndGetString, if sqlstatementtype is special
246 * @tc.type: FUNC
247 */
248 HWTEST_P(RdbExecuteTest, RdbStore_Execute_004, TestSize.Level4)
249 {
250 std::shared_ptr<RdbStore> store = *GetParam();
251
252 std::string outValue;
253 int ret = store_->ExecuteAndGetString(outValue, "BEGIN;");
254 EXPECT_NE(E_OK, ret);
255 }
256
257 /**
258 * @tc.name: RdbStore_Execute_005
259 * @tc.desc: Abnormal testCase for ExecuteForLastInsertedRowId, if sql is invalid
260 * @tc.type: FUNC
261 * @tc.type: FUNC
262 */
263 HWTEST_P(RdbExecuteTest, RdbStore_Execute_005, TestSize.Level4)
264 {
265 int64_t outValue;
266 int ret = store_->ExecuteForLastInsertedRowId(outValue, "", {});
267 EXPECT_NE(E_OK, ret);
268 }
269
270 /**
271 * @tc.name: RdbStore_Execute_006
272 * @tc.desc: Abnormal testCase for ExecuteForChangedRowCount, if sql is invalid
273 * @tc.type: FUNC
274 */
275 HWTEST_P(RdbExecuteTest, RdbStore_Execute_006, TestSize.Level4)
276 {
277 int64_t outValue;
278 int ret = store_->ExecuteForChangedRowCount(outValue, "", {});
279 EXPECT_NE(E_OK, ret);
280 }
281
282 /**
283 * @tc.name: RdbStore_Execute_007
284 * @tc.desc: Normal testCase for ExecuteAndGetString, check integrity for store
285 * @tc.type: FUNC
286 */
287 HWTEST_P(RdbExecuteTest, RdbStore_Execute_007, TestSize.Level1)
288 {
289 auto [ret, outValue] = store_->Execute("PRAGMA integrity_check");
290 EXPECT_EQ(E_OK, ret);
291 EXPECT_EQ(ValueObjectType::TYPE_STRING, outValue.GetType());
292
293 std::string outputResult;
294 outValue.GetString(outputResult);
295 EXPECT_EQ("ok", outputResult);
296 }
297
298 /**
299 * @tc.name: RdbStore_Execute_008
300 * @tc.desc: Normal testCase for Execute, check integrity for store
301 * @tc.type: FUNC
302 */
303 HWTEST_P(RdbExecuteTest, RdbStore_Execute_008, TestSize.Level1)
304 {
305 auto [ret, outValue] = store_->Execute("PRAGMA quick_check");
306 EXPECT_EQ(E_OK, ret);
307 EXPECT_EQ(ValueObjectType::TYPE_STRING, outValue.GetType());
308
309 std::string outputResult;
310 outValue.GetString(outputResult);
311 EXPECT_EQ("ok", outputResult);
312 }
313
314 /**
315 * @tc.name: RdbStore_Execute_009
316 * @tc.desc: Normal testCase for Execute, get user_version of store
317 * @tc.type: FUNC
318 */
319 HWTEST_P(RdbExecuteTest, RdbStore_Execute_009, TestSize.Level1)
320 {
321 // set user_version as 5
322 store_->SetVersion(5);
323 auto [ret, outValue] = store_->Execute("PRAGMA user_version");
324 EXPECT_EQ(E_OK, ret);
325 EXPECT_EQ(ValueObjectType::TYPE_INT, outValue.GetType());
326
327 int64_t outputResult{ 0 };
328 outValue.GetLong(outputResult);
329 EXPECT_EQ(5, outputResult);
330
331 // set user_version as 0
332 store_->SetVersion(0);
333 }
334
335 /**
336 * @tc.name: RdbStore_Execute_0010
337 * @tc.desc: AbNormal testCase for Execute, execute select sql
338 * @tc.type: FUNC
339 */
340 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0010, TestSize.Level1)
341 {
342 auto [ret, outValue] = store_->Execute("SELECT * FROM test");
343 EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret);
344
345 auto [code, result] = store_->ExecuteExt("SELECT * FROM test");
346 EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, code);
347 }
348
349 /**
350 * @tc.name: RdbStore_Execute_0011
351 * @tc.desc: Normal testCase for Execute, execute sql for inserting data
352 * @tc.type: FUNC
353 */
354 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0011, TestSize.Level1)
355 {
356 std::vector<ValueObject> args = { ValueObject(std::string("tt")), ValueObject(int(28)),
357 ValueObject(double(50000.0)) };
358 auto [ret, outValue] = store_->Execute("INSERT INTO test(name, age, salary) VALUES (?, ?, ?);", args);
359 EXPECT_EQ(E_OK, ret);
360 EXPECT_EQ(ValueObjectType::TYPE_INT, outValue.GetType());
361
362 int64_t outputResult;
363 outValue.GetLong(outputResult);
364 // 1 represent that the last data is inserted in the first row
365 EXPECT_EQ(1, outputResult);
366 }
367
368 /**
369 * @tc.name: RdbStore_Execute_0012
370 * @tc.desc: Normal testCase for Execute, execute sql for batch insert data
371 * @tc.type: FUNC
372 */
373 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0012, TestSize.Level1)
374 {
375 std::vector<ValueObject> args = { ValueObject(std::string("tt")), ValueObject(int(28)),
376 ValueObject(double(50000.0)), ValueObject(std::string("ttt")), ValueObject(int(58)),
377 ValueObject(double(500080.0)) };
378 auto [ret, outValue] = store_->Execute("INSERT INTO test(name, age, salary) VALUES (?, ?, ?), (?, ?, ?)", args);
379 EXPECT_EQ(E_OK, ret);
380
381 EXPECT_EQ(ValueObjectType::TYPE_INT, outValue.GetType());
382
383 int64_t outputResult;
384 outValue.GetLong(outputResult);
385 // 2 represent that the last data is inserted in the second row
386 EXPECT_EQ(2, outputResult);
387 }
388
389 /**
390 * @tc.name: RdbStore_Execute_0013
391 * @tc.desc: Normal testCase for Execute, execute sql for updating data
392 * @tc.type: FUNC
393 */
394 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0013, TestSize.Level1)
395 {
396 std::vector<ValueObject> args = { ValueObject(std::string("tt")), ValueObject(int(28)),
397 ValueObject(double(50000.0)), ValueObject(std::string("ttt")), ValueObject(int(58)),
398 ValueObject(double(500080.0)) };
399 auto [ret1, outValue1] = store_->Execute("INSERT INTO test(name, age, salary) VALUES (?, ?, ?), (?, ?, ?)", args);
400 EXPECT_EQ(E_OK, ret1);
401 EXPECT_EQ(ValueObjectType::TYPE_INT, outValue1.GetType());
402
403 int64_t outputResult;
404 outValue1.GetLong(outputResult);
405 // 2 represent that the last data is inserted in the second row
406 EXPECT_EQ(2, outputResult);
407
408 auto [ret2, outValue2] = store_->Execute("UPDATE test SET name='dd' WHERE id = 2");
409 EXPECT_EQ(E_OK, ret2);
410 EXPECT_EQ(ValueObjectType::TYPE_INT, outValue2.GetType());
411
412 outValue2.GetLong(outputResult);
413 // 1 represent that effected row id
414 EXPECT_EQ(1, outputResult);
415 }
416
417 /**
418 * @tc.name: RdbStore_Execute_0014
419 * @tc.desc: Normal testCase for Execute, execute sql for deleting data
420 * @tc.type: FUNC
421 */
422 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0014, TestSize.Level1)
423 {
424 std::vector<ValueObject> args = { ValueObject(std::string("tt")), ValueObject(int(28)),
425 ValueObject(double(50000.0)), ValueObject(std::string("ttt")), ValueObject(int(82)),
426 ValueObject(double(500080.0)) };
427 auto [ret1, outValue1] = store_->Execute("INSERT INTO test(name, age, salary) VALUES (?, ?, ?), (?, ?, ?)", args);
428 EXPECT_EQ(E_OK, ret1);
429 EXPECT_EQ(ValueObjectType::TYPE_INT, outValue1.GetType());
430
431 int64_t outputResult;
432 outValue1.GetLong(outputResult);
433 // 2 represent that the last data is inserted in the second row
434 EXPECT_EQ(2, outputResult);
435
436 auto [ret2, outValue2] = store_->Execute("DELETE FROM test");
437 EXPECT_EQ(E_OK, ret2);
438 EXPECT_EQ(ValueObjectType::TYPE_INT, outValue2.GetType());
439
440 outValue2.GetLong(outputResult);
441 // 2 represent that effected row id
442 EXPECT_EQ(2, outputResult);
443 }
444
445 /**
446 * @tc.name: RdbStore_Execute_0015
447 * @tc.desc: AbNormal testCase for Execute, execute sql for attaching database and transaction
448 * @tc.type: FUNC
449 */
450 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0015, TestSize.Level1)
451 {
452 auto [ret1, outValue1] = store_->Execute("ATTACH DATABASE 'execute_attach_test.db' AS 'attach.db'");
453 EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret1);
454
455 auto [ret2, outValue2] = store_->Execute("DETACH DATABASE 'attach.db'");
456 EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret2);
457
458 auto [ret3, outValue3] = store_->Execute("BEGIN TRANSACTION");
459 EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret3);
460
461 auto [ret4, outValue4] = store_->Execute("COMMIT");
462 EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret4);
463
464 auto [ret5, outValue5] = store_->Execute("ROLLBACK");
465 EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret5);
466
467 auto [ret6, outValue6] = store_->ExecuteExt("ROLLBACK");
468 EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret6);
469 }
470
471 /**
472 * @tc.name: RdbStore_Execute_0016
473 * @tc.desc: Normal testCase for Execute, execute DDL sql for creating and dropping table
474 * @tc.type: FUNC
475 */
476 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0016, TestSize.Level1)
477 {
478 int64_t intOutValue;
479
480 constexpr const char *CREATE_TABLE_TEST2 = "CREATE TABLE IF NOT EXISTS test2 "
481 "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
482 "name TEXT NOT NULL, age INTEGER, salary REAL, "
483 "blobType BLOB)";
484 constexpr const char *DROP_TABLE_TEST2 = "DROP TABLE test2";
485 constexpr const char *TEST_TABLE_IS_EXIST =
486 "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='test2'";
487
488 auto [ret1, outValue1] = store_->Execute(CREATE_TABLE_TEST2);
489 EXPECT_EQ(E_OK, ret1);
490 EXPECT_EQ(ValueObjectType::TYPE_NULL, outValue1.GetType());
491
492 std::shared_ptr<ResultSet> resultSet = store_->QuerySql(TEST_TABLE_IS_EXIST);
493 EXPECT_NE(nullptr, resultSet);
494 resultSet->GoToFirstRow();
495 // 0 represent that get count of table test in the first row
496 resultSet->GetLong(0, intOutValue);
497 // 1 represent that the table exists
498 EXPECT_EQ(1, intOutValue);
499 resultSet->Close();
500
501 auto [ret2, outValue2] = store_->ExecuteExt(DROP_TABLE_TEST2);
502 EXPECT_EQ(E_OK, ret2);
503 EXPECT_EQ(0, outValue2.changed);
504 int rowCount = -1;
505 outValue2.results->GetRowCount(rowCount);
506 EXPECT_EQ(0, rowCount);
507
508 resultSet = store_->QuerySql(TEST_TABLE_IS_EXIST);
509 EXPECT_NE(nullptr, resultSet);
510 resultSet->GoToFirstRow();
511 // 0 represent that get count of table test in the first column
512 resultSet->GetLong(0, intOutValue);
513 // 0 represent the table does not exist
514 EXPECT_EQ(0, intOutValue);
515 resultSet->Close();
516 }
517
518 /**
519 * @tc.name: RdbStore_Execute_0017
520 * @tc.desc: Normal testCase for Execute, execute sql for creating table and insert, query data
521 * @tc.type: FUNC
522 */
523 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0017, TestSize.Level1)
524 {
525 int64_t intOutValue;
526 int intOutResultSet;
527
528 constexpr const char *CREATE_TABLE_TEST2 = "CREATE TABLE IF NOT EXISTS test2 "
529 "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
530 "name TEXT NOT NULL, age INTEGER, salary REAL, "
531 "blobType BLOB)";
532 constexpr const char *DROP_TABLE_TEST2 = "DROP TABLE test2";
533
534 auto [ret1, outValue1] = store_->Execute(CREATE_TABLE_TEST2);
535 EXPECT_EQ(E_OK, ret1);
536
537 std::vector<ValueObject> args = { ValueObject("tt"), ValueObject(28), ValueObject(50000) };
538 auto [ret2, outValue2] = store_->Execute("INSERT INTO test2(name, age, salary) VALUES (?, ?, ?)", args);
539 EXPECT_EQ(E_OK, ret2);
540 outValue2.GetLong(intOutValue);
541 // 1 represent that the last data is inserted in the first row
542 EXPECT_EQ(1, intOutValue);
543
544 std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test2");
545 EXPECT_NE(nullptr, resultSet);
546 EXPECT_EQ(E_OK, resultSet->GetRowCount(intOutResultSet));
547 // 1 represent that the row number of resultSet
548 EXPECT_EQ(1, intOutResultSet);
549 resultSet->Close();
550
551 auto [ret3, outValue3] = store_->Execute(DROP_TABLE_TEST2);
552 EXPECT_EQ(E_OK, ret3);
553 }
554
555 /**
556 * @tc.name: RdbStore_Execute_0018
557 * @tc.desc: AbNormal testCase for Execute, execute sql for inserting data but args is []
558 * @tc.type: FUNC
559 */
560 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0018, TestSize.Level1)
561 {
562 ValueObject outValue;
563
564 auto [ret1, outValue1] = store_->Execute("INSERT INTO test(name, age, salary) VALUES (?, ?, ?), (?, ?, ?)");
565 EXPECT_NE(E_OK, ret1);
566 }
567
568 /**
569 * @tc.name: RdbStore_Execute_0019
570 * @tc.desc: Normal testCase for Execute, set user_version of store
571 * @tc.type: FUNC
572 */
573 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0019, TestSize.Level1)
574 {
575 // set user_version as 5
576 auto [ret, outValue] = store_->Execute("PRAGMA user_version=5");
577 EXPECT_EQ(E_OK, ret);
578 EXPECT_EQ(ValueObjectType::TYPE_NULL, outValue.GetType());
579
580 // set user_version as 0
581 std::tie(ret, outValue) = store_->Execute("PRAGMA user_version=0");
582 EXPECT_EQ(E_OK, ret);
583 EXPECT_EQ(ValueObjectType::TYPE_NULL, outValue.GetType());
584 }
585
586 /**
587 * @tc.name: RdbStore_Execute_0020
588 * @tc.desc: AbNormal testCase for Execute, get table_info
589 * @tc.type: FUNC
590 */
591 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0020, TestSize.Level1)
592 {
593 auto [ret, outValue] = store_->Execute("PRAGMA table_info(test)");
594 EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret);
595 }
596
597 /**
598 * @tc.name: RdbStore_Execute_0021
599 * @tc.desc: Normal testCase for Execute insert, update and delete 2 rows with returning
600 * @tc.type: FUNC
601 */
602 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0021, TestSize.Level1)
603 {
604 std::vector<ValueObject> args = { "tt", 28, 50000.0, "ttt", 58, 500080.0 };
605 auto [status, result] =
606 store_->ExecuteExt("INSERT INTO test(name, age, salary) VALUES (?, ?, ?), (?, ?, ?) returning name", args);
607 EXPECT_EQ(status, E_OK);
608 EXPECT_EQ(result.changed, 2);
609 int rowCount = -1;
610 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
611 ASSERT_EQ(rowCount, 2);
612 int columnIndex = -1;
613 ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
614 std::string value;
615 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
616 EXPECT_EQ(value, "tt");
617 ASSERT_EQ(result.results->GoToNextRow(), E_OK);
618 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
619 EXPECT_EQ(value, "ttt");
620
621 std::tie(status, result) =
622 store_->ExecuteExt("update test set name = ? where name = ? returning name", {"update", "tt"});
623 EXPECT_EQ(status, E_OK);
624 EXPECT_EQ(result.changed, 1);
625 rowCount = -1;
626 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
627 ASSERT_EQ(rowCount, 1);
628 ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
629 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
630 EXPECT_EQ(value, "update");
631
632 std::tie(status, result) = store_->ExecuteExt("delete from test returning name");
633 EXPECT_EQ(status, E_OK);
634 EXPECT_EQ(result.changed, 2);
635 rowCount = -1;
636 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
637 ASSERT_EQ(rowCount, 2);
638 ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
639 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
640 EXPECT_EQ(value, "update");
641 ASSERT_EQ(result.results->GoToNextRow(), E_OK);
642 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
643 EXPECT_EQ(value, "ttt");
644 }
645
646 /**
647 * @tc.name: RdbStore_Execute_0022
648 * @tc.desc: Normal testCase for Execute insert, update and delete over limit with returning
649 * @tc.type: FUNC
650 */
651 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0022, TestSize.Level1)
652 {
653 std::vector<ValueObject> args = { "0", 0 };
654 std::string sql = "INSERT INTO test(name, age) VALUES (?, ?)";
655 for (int32_t i = 1; i < 1025; i++) {
656 sql.append(", (?, ?)");
657 args.push_back(std::to_string(i));
658 args.push_back(i);
659 }
660 auto [status, result] = store_->ExecuteExt(sql + " returning name", args);
661 EXPECT_EQ(status, E_OK);
662 EXPECT_EQ(result.changed, 1025);
663 int rowCount = -1;
664 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
665 ASSERT_EQ(rowCount, 1024);
666 int columnIndex = -1;
667 ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
668 std::string value;
669 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
670 EXPECT_EQ(value, "0");
671 ASSERT_EQ(result.results->GoToRow(1000), E_OK);
672 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
673 EXPECT_EQ(value, "1000");
674
675 std::tie(status, result) = store_->ExecuteExt("update test set name = ? returning name", { "update" });
676 EXPECT_EQ(status, E_OK);
677 EXPECT_EQ(result.changed, 1025);
678 rowCount = -1;
679 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
680 ASSERT_EQ(rowCount, 1024);
681 ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
682 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
683 EXPECT_EQ(value, "update");
684
685
686 std::tie(status, result) = store_->ExecuteExt("delete from test returning name");
687 EXPECT_EQ(status, E_OK);
688 EXPECT_EQ(result.changed, 1025);
689 rowCount = -1;
690 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
691 ASSERT_EQ(rowCount, 1024);
692 ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
693 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
694 EXPECT_EQ(value, "update");
695 }
696
697 /**
698 * @tc.name: RdbStore_Execute_0023
699 * @tc.desc: normal testCase for Execute insert, update and delete 0 rows with returning
700 * @tc.type: FUNC
701 */
702 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0023, TestSize.Level1)
703 {
704 std::vector<ValueObject> args = { 1, "tt", 28, 50000.0 };
705 auto [status, result] =
706 store_->ExecuteExt("INSERT INTO test(id, name, age, salary) VALUES (?, ?, ?, ?) returning id", args);
707 EXPECT_EQ(status, E_OK);
708 EXPECT_EQ(result.changed, 1);
709
710 int rowCount = -1;
711 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
712 ASSERT_EQ(rowCount, 1);
713 int columnIndex = -1;
714 ASSERT_EQ(result.results->GetColumnIndex("id", columnIndex), E_OK);
715 int64_t value;
716 ASSERT_EQ(result.results->GetLong(columnIndex, value), E_OK);
717 EXPECT_EQ(value, 1);
718
719 std::tie(status, result) =
720 store_->ExecuteExt("INSERT INTO test(id, name, age, salary) VALUES (?, ?, ?, ?) returning id", args);
721 EXPECT_EQ(status, E_SQLITE_CONSTRAINT);
722 EXPECT_EQ(result.changed, 0);
723 rowCount = -1;
724 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
725 ASSERT_EQ(rowCount, 0);
726
727 std::tie(status, result) =
728 store_->ExecuteExt("update test set name = ? where name = ? returning name", { "update", "noExist" });
729 EXPECT_EQ(status, E_OK);
730 EXPECT_EQ(result.changed, 0);
731 rowCount = -1;
732 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
733 ASSERT_EQ(rowCount, 0);
734
735 std::tie(status, result) = store_->ExecuteExt("delete from test where name = ? returning name", { "noExist" });
736 EXPECT_EQ(status, E_OK);
737 EXPECT_EQ(result.changed, 0);
738 rowCount = -1;
739 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
740 ASSERT_EQ(rowCount, 0);
741 }
742
743 /**
744 * @tc.name: RdbStore_Execute_0024
745 * @tc.desc: abnormal testCase for Execute insert, update and delete with returning field not exist
746 * @tc.type: FUNC
747 */
748 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0024, TestSize.Level1)
749 {
750 std::vector<ValueObject> args = { 1, "tt", 28, 50000.0 };
751 auto [status, result] =
752 store_->ExecuteExt("INSERT INTO test(id, name, age, salary) VALUES (?, ?, ?, ?) returning noExist", args);
753 EXPECT_EQ(status, E_SQLITE_ERROR);
754 EXPECT_EQ(result.changed, -1);
755 ASSERT_EQ(result.results, nullptr);
756
757 std::tie(status, result) =
758 store_->ExecuteExt("update test set name = ? where name = ? returning noExist", { "update", "noExist" });
759 EXPECT_EQ(status, E_SQLITE_ERROR);
760 EXPECT_EQ(result.changed, -1);
761 ASSERT_EQ(result.results, nullptr);
762
763 std::tie(status, result) = store_->ExecuteExt("delete from test where name = ? returning noExist", { "noExist" });
764 EXPECT_EQ(status, E_SQLITE_ERROR);
765 EXPECT_EQ(result.changed, -1);
766 ASSERT_EQ(result.results, nullptr);
767 }
768
769 /**
770 * @tc.name: RdbStore_Execute_0025
771 * @tc.desc: normal test. batch insert into virtual table with returning
772 * @tc.type: FUNC
773 * @tc.require:
774 * @tc.author:
775 */
776 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0025, TestSize.Level1)
777 {
778 store_->Execute("CREATE VIRTUAL TABLE IF NOT EXISTS articles USING fts5(title, content);");
779
780 std::vector<ValueObject> args = { "title", "content" };
781 auto [status, result] =
782 store_->ExecuteExt("INSERT INTO articles(title, content) VALUES (?, ?) returning title", args);
783 EXPECT_EQ(status, E_OK);
784 EXPECT_EQ(result.changed, 1);
785 int rowCount = -1;
786 ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
787 ASSERT_EQ(rowCount, 1);
788 int columnIndex = -1;
789 ASSERT_EQ(result.results->GetColumnIndex("title", columnIndex), E_OK);
790 std::string value;
791 ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
792 EXPECT_EQ(value, "title");
793
794 std::vector<ValueObject> args2 = { "title2", "title" };
795 std::tie(status, result) =
796 store_->ExecuteExt("UPDATE articles set title = ? where title = ? returning title", args2);
797 EXPECT_EQ(status, E_SQLITE_ERROR);
798 EXPECT_EQ(result.changed, -1);
799 ASSERT_EQ(result.results, nullptr);
800
801 // DELETE RETURNING is not available on virtual tables
802 std::tie(status, result) = store_->ExecuteExt("DELETE FROM articles where title = ? returning title", { "title" });
803 EXPECT_EQ(status, E_SQLITE_ERROR);
804 EXPECT_EQ(result.changed, -1);
805 ASSERT_EQ(result.results, nullptr);
806 store_->Execute("Drop TABLE articles");
807 }
808
809 /**
810 * @tc.name: RdbStore_Execute_0026
811 * @tc.desc: normal test. create trigger before update, delete data in trigger, then update data
812 * @tc.type: FUNC
813 * @tc.require:
814 * @tc.author:
815 */
816 HWTEST_P(RdbExecuteTest, RdbStore_Execute_0026, TestSize.Level1)
817 {
818 auto [code, result1] = store_->Execute(
819 "CREATE TRIGGER before_update BEFORE UPDATE ON test"
820 " BEGIN DELETE FROM test WHERE name = 'wang'; END");
821
822 EXPECT_EQ(code, E_OK);
823
824 ValuesBuckets rows;
825 ValuesBucket row;
826 row.Put("id", 200);
827 row.Put("name", "wang");
828 rows.Put(std::move(row));
829 row.Put("id", 201);
830 row.Put("name", "zhang");
831 rows.Put(std::move(row));
832
833 auto [insertStatus, insertResult] =
834 store_->BatchInsert("test", rows, { "name" }, NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
835 EXPECT_EQ(insertStatus, E_OK);
836 EXPECT_EQ(insertResult.changed, 2);
837
838 std::vector<ValueObject> args2 = { "liu", "zhang" };
839 auto [status, res] =
840 store_->ExecuteExt("UPDATE test set name = ? where name = ? returning name", args2);
841
842 EXPECT_EQ(status, E_OK);
843 EXPECT_EQ(res.changed, 1);
844 int rowCount = -1;
845 ASSERT_EQ(res.results->GetRowCount(rowCount), E_OK);
846 ASSERT_EQ(rowCount, 1);
847 int columnIndex = -1;
848 ASSERT_EQ(res.results->GetColumnIndex("name", columnIndex), E_OK);
849 std::string value;
850 ASSERT_EQ(res.results->GetString(columnIndex, value), E_OK);
851 EXPECT_EQ(value, "liu");
852
853 // Check the trigger effect
854 auto resultSet = store_->QuerySql("select name from test where id = 200");
855
856 rowCount = -1;
857 resultSet->GetRowCount(rowCount);
858 ASSERT_EQ(rowCount, 0);
859 store_->Execute("DROP TRIGGER IF EXISTS before_update");
860 }
861
862 INSTANTIATE_TEST_SUITE_P(ExecuteTest, RdbExecuteTest, testing::Values(&g_store, &g_memDb));
863
864 } // namespace OHOS::RdbExecuteTest