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_common.h"
22 #include "rdb_errno.h"
23 #include "rdb_helper.h"
24 #include "rdb_open_callback.h"
25 #include "result_set.h"
26 #include "values_buckets.h"
27
28 using namespace testing::ext;
29 using namespace OHOS::NativeRdb;
30 namespace OHOS::RdbStoreInsertTest {
31 struct RdbTestParam {
32 std::shared_ptr<RdbStore> store;
operator std::shared_ptr<RdbStore>OHOS::RdbStoreInsertTest::RdbTestParam33 operator std::shared_ptr<RdbStore>()
34 {
35 return store;
36 }
37 };
38 static RdbTestParam g_store;
39 static RdbTestParam g_memDb;
40
41 class RdbStoreInsertTest : public testing::TestWithParam<RdbTestParam *> {
42 public:
43 static void SetUpTestCase(void);
44 static void TearDownTestCase(void);
45 void SetUp();
46 void TearDown();
47 static void CheckResultSet(std::shared_ptr<RdbStore> &store);
48 static void CheckAge(std::shared_ptr<ResultSet> &resultSet);
49 static void CheckSalary(std::shared_ptr<ResultSet> &resultSet);
50 static void CheckBlob(std::shared_ptr<ResultSet> &resultSet);
51 std::shared_ptr<RdbStore> store_;
52
53 static const std::string DATABASE_NAME;
54 };
55
56 const std::string RdbStoreInsertTest::DATABASE_NAME = RDB_TEST_PATH + "insert_test.db";
57
58 class InsertTestOpenCallback : public RdbOpenCallback {
59 public:
60 int OnCreate(RdbStore &store) override;
61 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
62 static const std::string CREATE_TABLE_TEST;
63 };
64
65 const std::string InsertTestOpenCallback::CREATE_TABLE_TEST =
66 std::string("CREATE TABLE IF NOT EXISTS test ") + std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT, "
67 "name TEXT NOT NULL, age INTEGER, salary "
68 "REAL, blobType BLOB)");
69
OnCreate(RdbStore & store)70 int InsertTestOpenCallback::OnCreate(RdbStore &store)
71 {
72 return store.ExecuteSql(CREATE_TABLE_TEST);
73 }
74
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)75 int InsertTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
76 {
77 return E_OK;
78 }
79
GetColumnValues(std::shared_ptr<ResultSet> resultSet,const std::string & filed)80 std::vector<ValueObject> GetColumnValues(std::shared_ptr<ResultSet> resultSet, const std::string &filed)
81 {
82 std::vector<ValueObject> res;
83 if (resultSet->GoToFirstRow() != E_OK) {
84 return res;
85 }
86 int32_t colIndex = -1;
87 if (resultSet->GetColumnIndex(filed, colIndex) != E_OK) {
88 return res;
89 }
90 do {
91 ValueObject value;
92 EXPECT_EQ(resultSet->Get(colIndex, value), E_OK);
93 res.push_back(value);
94 } while (resultSet->GoToNextRow() == E_OK);
95 return res;
96 }
97
SetUpTestCase(void)98 void RdbStoreInsertTest::SetUpTestCase(void)
99 {
100 int errCode = E_OK;
101 RdbHelper::DeleteRdbStore(DATABASE_NAME);
102 RdbStoreConfig config(RdbStoreInsertTest::DATABASE_NAME);
103 InsertTestOpenCallback helper;
104 g_store.store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
105 ASSERT_NE(g_store.store, nullptr);
106
107 config.SetStorageMode(StorageMode::MODE_MEMORY);
108 g_memDb.store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
109 ASSERT_NE(g_memDb.store, nullptr);
110 }
111
TearDownTestCase(void)112 void RdbStoreInsertTest::TearDownTestCase(void)
113 {
114 RdbHelper::DeleteRdbStore(RdbStoreInsertTest::DATABASE_NAME);
115 RdbStoreConfig config(RdbStoreInsertTest::DATABASE_NAME);
116 config.SetStorageMode(StorageMode::MODE_MEMORY);
117 RdbHelper::DeleteRdbStore(config);
118 }
119
SetUp(void)120 void RdbStoreInsertTest::SetUp(void)
121 {
122 store_ = *GetParam();
123 ASSERT_NE(store_, nullptr);
124 store_->ExecuteSql("DELETE FROM test");
125 }
126
TearDown(void)127 void RdbStoreInsertTest::TearDown(void)
128 {
129 }
130
131 /**
132 * @tc.name: RdbStore_Insert_001
133 * @tc.desc: test RdbStore insert
134 * @tc.type: FUNC
135 */
136 HWTEST_P(RdbStoreInsertTest, RdbStore_Insert_001, TestSize.Level0)
137 {
138 int64_t id;
139 ValuesBucket values;
140
141 values.PutInt("id", 1);
142 values.PutString("name", std::string("zhangsan"));
143 values.PutInt("age", 18);
144 values.PutDouble("salary", 100.5);
145 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
146 int ret = store_->Insert(id, "test", values);
147 EXPECT_EQ(ret, E_OK);
148 EXPECT_EQ(1, id);
149
150 values.Clear();
151 values.PutInt("id", 2);
152 values.PutString("name", std::string("lisi"));
153 values.PutInt("age", 18);
154 values.PutDouble("salary", 100.5);
155 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
156 ret = store_->Insert(id, "test", values);
157 EXPECT_EQ(ret, E_OK);
158 EXPECT_EQ(2, id);
159
160 values.Clear();
161 values.PutInt("id", 3);
162 values.PutString("name", std::string("lisi"));
163 values.PutInt("age", 20L);
164 values.PutDouble("salary", 100.5f);
165 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
166 ret = store_->Insert(id, "test", values);
167 EXPECT_EQ(ret, E_OK);
168 EXPECT_EQ(3, id);
169
170 RdbStoreInsertTest::CheckResultSet(store_);
171 }
172
CheckResultSet(std::shared_ptr<RdbStore> & store)173 void RdbStoreInsertTest::CheckResultSet(std::shared_ptr<RdbStore> &store)
174 {
175 std::shared_ptr<ResultSet> resultSet =
176 store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector<std::string>{ "zhangsan" });
177 ASSERT_NE(resultSet, nullptr);
178
179 int columnIndex;
180 int intVal;
181 std::string strVal;
182 ColumnType columnType;
183 int position;
184 int ret = resultSet->GetRowIndex(position);
185 EXPECT_EQ(ret, E_OK);
186 EXPECT_EQ(position, -1);
187
188 ret = resultSet->GetColumnType(0, columnType);
189 EXPECT_EQ(ret, E_ROW_OUT_RANGE);
190
191 ret = resultSet->GoToFirstRow();
192 EXPECT_EQ(ret, E_OK);
193
194 ret = resultSet->GetColumnIndex("id", columnIndex);
195 EXPECT_EQ(ret, E_OK);
196 EXPECT_EQ(columnIndex, 0);
197 ret = resultSet->GetColumnType(columnIndex, columnType);
198 EXPECT_EQ(ret, E_OK);
199 EXPECT_EQ(columnType, ColumnType::TYPE_INTEGER);
200 ret = resultSet->GetInt(columnIndex, intVal);
201 EXPECT_EQ(ret, E_OK);
202 EXPECT_EQ(1, intVal);
203
204 ret = resultSet->GetColumnIndex("name", columnIndex);
205 EXPECT_EQ(ret, E_OK);
206 ret = resultSet->GetColumnType(columnIndex, columnType);
207 EXPECT_EQ(ret, E_OK);
208 EXPECT_EQ(columnType, ColumnType::TYPE_STRING);
209 ret = resultSet->GetString(columnIndex, strVal);
210 EXPECT_EQ(ret, E_OK);
211 EXPECT_EQ("zhangsan", strVal);
212
213 RdbStoreInsertTest::CheckAge(resultSet);
214 RdbStoreInsertTest::CheckSalary(resultSet);
215 RdbStoreInsertTest::CheckBlob(resultSet);
216
217 ret = resultSet->GoToNextRow();
218 EXPECT_EQ(ret, E_ROW_OUT_RANGE);
219
220 ret = resultSet->GetColumnType(columnIndex, columnType);
221 EXPECT_EQ(ret, E_ROW_OUT_RANGE);
222
223 ret = resultSet->Close();
224 EXPECT_EQ(ret, E_OK);
225 }
226
CheckAge(std::shared_ptr<ResultSet> & resultSet)227 void RdbStoreInsertTest::CheckAge(std::shared_ptr<ResultSet> &resultSet)
228 {
229 int columnIndex;
230 int intVal;
231 ColumnType columnType;
232 int ret = resultSet->GetColumnIndex("age", columnIndex);
233 EXPECT_EQ(ret, E_OK);
234 ret = resultSet->GetColumnType(columnIndex, columnType);
235 EXPECT_EQ(ret, E_OK);
236 EXPECT_EQ(columnType, ColumnType::TYPE_INTEGER);
237 ret = resultSet->GetInt(columnIndex, intVal);
238 EXPECT_EQ(ret, E_OK);
239 EXPECT_EQ(18, intVal);
240 }
241
CheckSalary(std::shared_ptr<ResultSet> & resultSet)242 void RdbStoreInsertTest::CheckSalary(std::shared_ptr<ResultSet> &resultSet)
243 {
244 int columnIndex;
245 double dVal;
246 ColumnType columnType;
247 int ret = resultSet->GetColumnIndex("salary", columnIndex);
248 EXPECT_EQ(ret, E_OK);
249 ret = resultSet->GetColumnType(columnIndex, columnType);
250 EXPECT_EQ(ret, E_OK);
251 EXPECT_EQ(columnType, ColumnType::TYPE_FLOAT);
252 ret = resultSet->GetDouble(columnIndex, dVal);
253 EXPECT_EQ(ret, E_OK);
254 EXPECT_EQ(100.5, dVal);
255 }
256
CheckBlob(std::shared_ptr<ResultSet> & resultSet)257 void RdbStoreInsertTest::CheckBlob(std::shared_ptr<ResultSet> &resultSet)
258 {
259 int columnIndex;
260 std::vector<uint8_t> blob;
261 ColumnType columnType;
262 int ret = resultSet->GetColumnIndex("blobType", columnIndex);
263 EXPECT_EQ(ret, E_OK);
264 ret = resultSet->GetColumnType(columnIndex, columnType);
265 EXPECT_EQ(ret, E_OK);
266 EXPECT_EQ(columnType, ColumnType::TYPE_BLOB);
267 ret = resultSet->GetBlob(columnIndex, blob);
268 EXPECT_EQ(ret, E_OK);
269 EXPECT_EQ(3, static_cast<int>(blob.size()));
270 EXPECT_EQ(1, blob[0]);
271 EXPECT_EQ(2, blob[1]);
272 EXPECT_EQ(3, blob[2]);
273 }
274
275 /**
276 * @tc.name: RdbStore_Insert_002
277 * @tc.desc: test RdbStore insert
278 * @tc.type: FUNC
279 */
280 HWTEST_P(RdbStoreInsertTest, RdbStore_Insert_002, TestSize.Level0)
281 {
282 int64_t id;
283 ValuesBucket values;
284 values.PutInt("id", 1);
285 values.PutString("name", std::string("zhangsan"));
286 values.PutInt("age", 18);
287 values.PutDouble("salary", 100.5);
288 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
289 int ret = store_->Insert(id, "", values); // empty table name
290 EXPECT_EQ(ret, E_EMPTY_TABLE_NAME);
291
292 ret = store_->Insert(id, "wrongTable", values); // no such table
293 EXPECT_EQ(ret, E_SQLITE_ERROR);
294 }
295
296 /**
297 * @tc.name: RdbStore_Insert_003
298 * @tc.desc: test RdbStore insert
299 * @tc.type: FUNC
300 */
301 HWTEST_P(RdbStoreInsertTest, RdbStore_Insert_003, TestSize.Level0)
302 {
303 int64_t id;
304 ValuesBucket emptyBucket;
305 int ret = store_->Insert(id, "test", emptyBucket);
306 EXPECT_EQ(ret, E_EMPTY_VALUES_BUCKET);
307
308 ValuesBucket values;
309 values.PutInt("id", 1);
310 values.PutString("name", std::string("zhangsan"));
311 values.PutInt("age", 18);
312 values.PutDouble("wrongColumn", 100.5); // no such column
313 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
314 ret = store_->Insert(id, "test", values);
315 EXPECT_EQ(ret, E_SQLITE_ERROR);
316 }
317
318 /**
319 * @tc.name: RdbStore_Replace_001
320 * @tc.desc: test RdbStore replace
321 * @tc.type: FUNC
322 */
323 HWTEST_P(RdbStoreInsertTest, RdbStore_Replace_001, TestSize.Level0)
324 {
325 int64_t id;
326 ValuesBucket values;
327
328 int ret = store_->Replace(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
329 EXPECT_EQ(ret, E_OK);
330 EXPECT_EQ(1, id);
331
332 std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test");
333 EXPECT_NE(resultSet, nullptr);
334
335 ret = resultSet->GoToNextRow();
336 EXPECT_EQ(ret, E_OK);
337
338 int columnIndex;
339 int intVal;
340 std::string strVal;
341
342 ret = resultSet->GetColumnIndex("id", columnIndex);
343 EXPECT_EQ(ret, E_OK);
344 ret = resultSet->GetInt(columnIndex, intVal);
345 EXPECT_EQ(ret, E_OK);
346 EXPECT_EQ(1, intVal);
347
348 ret = resultSet->GetColumnIndex("name", columnIndex);
349 EXPECT_EQ(ret, E_OK);
350 ret = resultSet->GetString(columnIndex, strVal);
351 EXPECT_EQ(ret, E_OK);
352 EXPECT_EQ("zhangsan", strVal);
353
354 ret = resultSet->GetColumnIndex("age", columnIndex);
355 EXPECT_EQ(ret, E_OK);
356 ret = resultSet->GetInt(columnIndex, intVal);
357 EXPECT_EQ(ret, E_OK);
358 EXPECT_EQ(18, intVal);
359
360 ret = resultSet->GoToNextRow();
361 EXPECT_EQ(ret, E_ROW_OUT_RANGE);
362
363 ret = resultSet->Close();
364 EXPECT_EQ(ret, E_OK);
365 }
366
367 /**
368 * @tc.name: RdbStore_Replace_002
369 * @tc.desc: test RdbStore replace
370 * @tc.type: FUNC
371 */
372 HWTEST_P(RdbStoreInsertTest, RdbStore_Replace_002, TestSize.Level0)
373 {
374 int64_t id;
375 ValuesBucket values;
376
377 int ret = store_->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
378 EXPECT_EQ(ret, E_OK);
379 EXPECT_EQ(1, id);
380
381 values.Clear();
382 values.PutInt("id", 1);
383 values.PutString("name", std::string("zhangsan"));
384 values.PutInt("age", 18);
385 values.PutDouble("salary", 200.5);
386 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
387 ret = store_->Replace(id, "test", values);
388 EXPECT_EQ(ret, E_OK);
389 EXPECT_EQ(1, id);
390
391 std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test");
392 EXPECT_NE(resultSet, nullptr);
393
394 ret = resultSet->GoToNextRow();
395 EXPECT_EQ(ret, E_OK);
396
397 int columnIndex;
398 int intVal;
399 std::string strVal;
400
401 ret = resultSet->GetColumnIndex("id", columnIndex);
402 EXPECT_EQ(ret, E_OK);
403 ret = resultSet->GetInt(columnIndex, intVal);
404 EXPECT_EQ(ret, E_OK);
405 EXPECT_EQ(1, intVal);
406
407 ret = resultSet->GetColumnIndex("name", columnIndex);
408 EXPECT_EQ(ret, E_OK);
409 ret = resultSet->GetString(columnIndex, strVal);
410 EXPECT_EQ(ret, E_OK);
411 EXPECT_EQ("zhangsan", strVal);
412
413 ret = resultSet->GetColumnIndex("age", columnIndex);
414 EXPECT_EQ(ret, E_OK);
415 ret = resultSet->GetInt(columnIndex, intVal);
416 EXPECT_EQ(ret, E_OK);
417 EXPECT_EQ(18, intVal);
418
419 ret = resultSet->GoToNextRow();
420 EXPECT_EQ(ret, E_ROW_OUT_RANGE);
421
422 ret = resultSet->Close();
423 EXPECT_EQ(ret, E_OK);
424 }
425
426 /**
427 * @tc.name: RdbStore_Replace_003
428 * @tc.desc: test RdbStore Replace
429 * @tc.type: FUNC
430 */
431 HWTEST_P(RdbStoreInsertTest, RdbStore_Replace_003, TestSize.Level0)
432 {
433 int64_t id;
434 ValuesBucket values;
435 values.PutInt("id", 1);
436 values.PutString("name", std::string("zhangsan"));
437 values.PutInt("age", 18);
438 values.PutDouble("salary", 100.5);
439 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
440 int ret = store_->Replace(id, "", values); // empty table name
441 EXPECT_EQ(ret, E_EMPTY_TABLE_NAME);
442
443 ret = store_->Replace(id, "wrongTable", values); // no such table
444 EXPECT_EQ(ret, E_SQLITE_ERROR);
445 }
446
447 /**
448 * @tc.name: RdbStore_Replace_004
449 * @tc.desc: test RdbStore Replace
450 * @tc.type: FUNC
451 */
452 HWTEST_P(RdbStoreInsertTest, RdbStore_Replace_004, TestSize.Level0)
453 {
454 int64_t id;
455 ValuesBucket emptyBucket;
456 int ret = store_->Replace(id, "test", emptyBucket);
457 EXPECT_EQ(ret, E_EMPTY_VALUES_BUCKET);
458
459 ValuesBucket values;
460 values.PutInt("id", 1);
461 values.PutString("name", std::string("zhangsan"));
462 values.PutInt("age", 18);
463 values.PutDouble("wrongColumn", 100.5); // no such column
464 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
465 ret = store_->Replace(id, "test", values);
466 EXPECT_EQ(ret, E_SQLITE_ERROR);
467 }
468
469 /**
470 * @tc.name: RdbStore_Replace_005
471 * @tc.desc: test RdbStore replace
472 * @tc.type: FUNC
473 */
474 HWTEST_P(RdbStoreInsertTest, RdbStore_Replace_005, TestSize.Level0)
475 {
476 int64_t id;
477
478 int ret = store_->Replace(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
479 EXPECT_EQ(ret, E_OK);
480 EXPECT_EQ(1, id);
481
482 std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test");
483 EXPECT_NE(resultSet, nullptr);
484
485 ret = resultSet->GoToNextRow();
486 EXPECT_EQ(ret, E_OK);
487
488 int columnIndex;
489 double dVal;
490 std::vector<uint8_t> blob;
491
492 ret = resultSet->GetColumnIndex("salary", columnIndex);
493 EXPECT_EQ(ret, E_OK);
494 ret = resultSet->GetDouble(columnIndex, dVal);
495 EXPECT_EQ(ret, E_OK);
496 EXPECT_EQ(100.5, dVal);
497
498 ret = resultSet->GetColumnIndex("blobType", columnIndex);
499 EXPECT_EQ(ret, E_OK);
500 ret = resultSet->GetBlob(columnIndex, blob);
501 EXPECT_EQ(ret, E_OK);
502 EXPECT_EQ(3, static_cast<int>(blob.size()));
503 EXPECT_EQ(1, blob[0]);
504 EXPECT_EQ(2, blob[1]);
505 EXPECT_EQ(3, blob[2]);
506
507 ret = resultSet->GoToNextRow();
508 EXPECT_EQ(ret, E_ROW_OUT_RANGE);
509
510 ret = resultSet->Close();
511 EXPECT_EQ(ret, E_OK);
512 }
513
514 /**
515 * @tc.name: RdbStore_Replace_006
516 * @tc.desc: test RdbStore replace
517 * @tc.type: FUNC
518 */
519 HWTEST_P(RdbStoreInsertTest, RdbStore_Replace_006, TestSize.Level0)
520 {
521 int64_t id;
522 ValuesBucket values;
523
524 int ret = store_->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
525 EXPECT_EQ(ret, E_OK);
526 EXPECT_EQ(1, id);
527
528 values.Clear();
529 values.PutInt("id", 1);
530 values.PutString("name", std::string("zhangsan"));
531 values.PutInt("age", 18);
532 values.PutDouble("salary", 200.5);
533 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
534 ret = store_->Replace(id, "test", values);
535 EXPECT_EQ(ret, E_OK);
536 EXPECT_EQ(1, id);
537
538 std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test");
539 EXPECT_NE(resultSet, nullptr);
540
541 ret = resultSet->GoToNextRow();
542 EXPECT_EQ(ret, E_OK);
543
544 int columnIndex;
545 double dVal;
546 std::vector<uint8_t> blob;
547
548 ret = resultSet->GetColumnIndex("salary", columnIndex);
549 EXPECT_EQ(ret, E_OK);
550 ret = resultSet->GetDouble(columnIndex, dVal);
551 EXPECT_EQ(ret, E_OK);
552 EXPECT_EQ(200.5, dVal);
553
554 ret = resultSet->GetColumnIndex("blobType", columnIndex);
555 EXPECT_EQ(ret, E_OK);
556 ret = resultSet->GetBlob(columnIndex, blob);
557 EXPECT_EQ(ret, E_OK);
558 EXPECT_EQ(3, static_cast<int>(blob.size()));
559 EXPECT_EQ(1, blob[0]);
560 EXPECT_EQ(2, blob[1]);
561 EXPECT_EQ(3, blob[2]);
562
563 ret = resultSet->GoToNextRow();
564 EXPECT_EQ(ret, E_ROW_OUT_RANGE);
565
566 ret = resultSet->Close();
567 EXPECT_EQ(ret, E_OK);
568 }
569
570 /**
571 * @tc.name: RdbStore_InsertWithConflictResolution_001_002
572 * @tc.desc: test RdbStore InsertWithConflictResolution
573 * @tc.type: FUNC
574 */
575 HWTEST_P(RdbStoreInsertTest, RdbStore_InsertWithConflictResolution_001_002, TestSize.Level0)
576 {
577 int64_t id;
578 ValuesBucket values;
579
580 values.PutInt("id", 1);
581 values.PutString("name", std::string("zhangsan"));
582 values.PutInt("age", 18);
583 values.PutDouble("salary", 100.5);
584 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
585
586 // default is ConflictResolution::ON_CONFLICT_NONE
587 int ret = store_->InsertWithConflictResolution(id, "test", values);
588 EXPECT_EQ(ret, E_OK);
589 EXPECT_EQ(1, id);
590
591 values.Clear();
592 values.PutInt("id", 1);
593 values.PutString("name", std::string("zhangsan"));
594 values.PutInt("age", 18);
595 values.PutDouble("salary", 200.5);
596 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
597 ret = store_->InsertWithConflictResolution(id, "test", values);
598 EXPECT_EQ(ret, E_SQLITE_CONSTRAINT);
599 }
600
601 /**
602 * @tc.name: RdbStore_InsertWithConflictResolution_003_004
603 * @tc.desc: test RdbStore InsertWithConflictResolution
604 * @tc.type: FUNC
605 */
606 HWTEST_P(RdbStoreInsertTest, RdbStore_InsertWithConflictResolution_003_004, TestSize.Level0)
607 {
608 int64_t id;
609 ValuesBucket values;
610
611 values.PutInt("id", 1);
612 values.PutString("name", std::string("zhangsan"));
613 values.PutInt("age", 18);
614 values.PutDouble("salary", 100.5);
615 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
616 int ret = store_->InsertWithConflictResolution(id, "test", values, ConflictResolution::ON_CONFLICT_ROLLBACK);
617 EXPECT_EQ(ret, E_OK);
618 EXPECT_EQ(1, id);
619
620 values.Clear();
621 values.PutInt("id", 1);
622 values.PutString("name", std::string("zhangsan"));
623 values.PutInt("age", 18);
624 values.PutDouble("salary", 200.5);
625 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
626 ret = store_->InsertWithConflictResolution(id, "test", values, ConflictResolution::ON_CONFLICT_ROLLBACK);
627 EXPECT_EQ(ret, E_SQLITE_CONSTRAINT);
628 }
629
630 /**
631 * @tc.name: RdbStore_InsertWithConflictResolution_005
632 * @tc.desc: test RdbStore InsertWithConflictResolution
633 * @tc.type: FUNC
634 */
635 HWTEST_P(RdbStoreInsertTest, RdbStore_InsertWithConflictResolution_005, TestSize.Level0)
636 {
637 int64_t id;
638 ValuesBucket values;
639
640 values.PutInt("id", 1);
641 values.PutString("name", std::string("zhangsan"));
642 values.PutInt("age", 18);
643 values.PutDouble("salary", 100.5);
644 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
645 int ret = store_->InsertWithConflictResolution(id, "test", values, ConflictResolution::ON_CONFLICT_IGNORE);
646 EXPECT_EQ(ret, E_OK);
647 EXPECT_EQ(1, id);
648
649 values.Clear();
650 values.PutInt("id", 1);
651 values.PutString("name", std::string("zhangsan"));
652 values.PutInt("age", 18);
653 values.PutDouble("salary", 200.5);
654 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
655 ret = store_->InsertWithConflictResolution(id, "test", values, ConflictResolution::ON_CONFLICT_IGNORE);
656 EXPECT_EQ(ret, E_OK);
657 EXPECT_EQ(id, -1);
658 }
659
660 /**
661 * @tc.name: RdbStore_InsertWithConflictResolution_006
662 * @tc.desc: test RdbStore InsertWithConflictResolution
663 * @tc.type: FUNC
664 */
665 HWTEST_P(RdbStoreInsertTest, RdbStore_InsertWithConflictResolution_006, TestSize.Level0)
666 {
667 int64_t id;
668 ValuesBucket values;
669
670 int ret = store_->InsertWithConflictResolution(
671 id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]), ConflictResolution::ON_CONFLICT_REPLACE);
672 EXPECT_EQ(ret, E_OK);
673 EXPECT_EQ(1, id);
674
675 values.Clear();
676 values.PutInt("id", 1);
677 values.PutString("name", std::string("zhangsan"));
678 values.PutInt("age", 18);
679 values.PutDouble("salary", 200.5);
680 values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6 });
681 ret = store_->InsertWithConflictResolution(id, "test", values, ConflictResolution::ON_CONFLICT_REPLACE);
682 EXPECT_EQ(ret, E_OK);
683 EXPECT_EQ(id, 1);
684
685 std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test");
686 EXPECT_NE(resultSet, nullptr);
687
688 ret = resultSet->GoToNextRow();
689 EXPECT_EQ(ret, E_OK);
690
691 int columnIndex;
692 int intVal;
693 std::string strVal;
694
695 ret = resultSet->GetColumnIndex("id", columnIndex);
696 EXPECT_EQ(ret, E_OK);
697 ret = resultSet->GetInt(columnIndex, intVal);
698 EXPECT_EQ(ret, E_OK);
699 EXPECT_EQ(1, intVal);
700
701 ret = resultSet->GetColumnIndex("name", columnIndex);
702 EXPECT_EQ(ret, E_OK);
703 ret = resultSet->GetString(columnIndex, strVal);
704 EXPECT_EQ(ret, E_OK);
705 EXPECT_EQ("zhangsan", strVal);
706
707 ret = resultSet->GetColumnIndex("age", columnIndex);
708 EXPECT_EQ(ret, E_OK);
709 ret = resultSet->GetInt(columnIndex, intVal);
710 EXPECT_EQ(ret, E_OK);
711 EXPECT_EQ(18, intVal);
712
713 ret = resultSet->GoToNextRow();
714 EXPECT_EQ(ret, E_ROW_OUT_RANGE);
715
716 ret = resultSet->Close();
717 EXPECT_EQ(ret, E_OK);
718 }
719
720 /**
721 * @tc.name: RdbStore_InsertWithConflictResolution_007
722 * @tc.desc: test RdbStore InsertWithConflictResolution
723 * @tc.type: FUNC
724 */
725 HWTEST_P(RdbStoreInsertTest, RdbStore_InsertWithConflictResolution_007, TestSize.Level0)
726 {
727 int64_t id;
728 ValuesBucket values;
729
730 int ret = store_->InsertWithConflictResolution(
731 id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]), ConflictResolution::ON_CONFLICT_REPLACE);
732 EXPECT_EQ(ret, E_OK);
733 EXPECT_EQ(1, id);
734
735 values.Clear();
736 values.PutInt("id", 1);
737 values.PutString("name", std::string("zhangsan"));
738 values.PutInt("age", 18);
739 values.PutDouble("salary", 200.5);
740 values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6 });
741 ret = store_->InsertWithConflictResolution(id, "test", values, ConflictResolution::ON_CONFLICT_REPLACE);
742 EXPECT_EQ(ret, E_OK);
743 EXPECT_EQ(id, 1);
744
745 std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test");
746 EXPECT_NE(resultSet, nullptr);
747
748 ret = resultSet->GoToNextRow();
749 EXPECT_EQ(ret, E_OK);
750
751 int columnIndex;
752 double dVal;
753 std::vector<uint8_t> blob;
754
755 ret = resultSet->GetColumnIndex("salary", columnIndex);
756 EXPECT_EQ(ret, E_OK);
757 ret = resultSet->GetDouble(columnIndex, dVal);
758 EXPECT_EQ(ret, E_OK);
759 EXPECT_EQ(200.5, dVal);
760
761 ret = resultSet->GetColumnIndex("blobType", columnIndex);
762 EXPECT_EQ(ret, E_OK);
763 ret = resultSet->GetBlob(columnIndex, blob);
764 EXPECT_EQ(ret, E_OK);
765 EXPECT_EQ(3, static_cast<int>(blob.size()));
766 EXPECT_EQ(4, blob[0]);
767 EXPECT_EQ(5, blob[1]);
768 EXPECT_EQ(6, blob[2]);
769
770 ret = resultSet->GoToNextRow();
771 EXPECT_EQ(ret, E_ROW_OUT_RANGE);
772
773 ret = resultSet->Close();
774 EXPECT_EQ(ret, E_OK);
775 }
776
777 /**
778 * @tc.name: RdbStore_InsertWithConflictResolution_008
779 * @tc.desc: Abnormal testCase of InsertWithConflictResolution, if conflictResolution is invalid
780 * @tc.type: FUNC
781 */
782 HWTEST_P(RdbStoreInsertTest, RdbStore_InsertWithConflictResolution_008, TestSize.Level0)
783 {
784 int64_t id = 0;
785 ValuesBucket values;
786
787 values.PutInt("id", 1);
788 values.PutInt("age", 18);
789 int ret = store_->InsertWithConflictResolution(id, "test", values, static_cast<ConflictResolution>(6));
790 EXPECT_EQ(E_INVALID_CONFLICT_FLAG, ret);
791 EXPECT_EQ(0, id);
792
793 values.Clear();
794 values.PutInt("id", 1);
795 values.PutInt("age", 18);
796 ret = store_->InsertWithConflictResolution(id, "test", values, static_cast<ConflictResolution>(-1));
797 EXPECT_EQ(E_INVALID_CONFLICT_FLAG, ret);
798 EXPECT_EQ(0, id);
799 }
800
801 /**
802 * @tc.name: OverLimitWithInsert_001
803 * @tc.desc: over limit
804 * @tc.type: FUNC
805 * @tc.require:
806 * @tc.author:
807 */
808 HWTEST_P(RdbStoreInsertTest, OverLimitWithInsert_001, TestSize.Level0)
809 {
810 std::shared_ptr<RdbStore> store = *GetParam();
811 auto [code, maxPageCount] = store->Execute("PRAGMA max_page_count;");
__anon40a22aa00102(const char *) 812 auto recover = std::shared_ptr<const char>("recover", [defPageCount = maxPageCount, store](const char *) {
813 store->Execute("PRAGMA max_page_count = " + static_cast<std::string>(defPageCount) + ";");
814 });
815 std::tie(code, maxPageCount) = store->Execute("PRAGMA max_page_count = 256;");
816
817 ValuesBucket row;
818 row.Put("name", std::string(1024 * 1024, 'e'));
819 auto result = store->Insert("test", row, ConflictResolution::ON_CONFLICT_NONE);
820 ASSERT_EQ(result.first, E_SQLITE_FULL);
821 }
822
823 /**
824 * @tc.name: BatchInsert_001
825 * @tc.desc: normal test
826 * @tc.type: FUNC
827 * @tc.require:
828 * @tc.author:
829 */
830 HWTEST_P(RdbStoreInsertTest, BatchInsert_001, TestSize.Level0)
831 {
832 ValuesBuckets rows;
833 for (int i = 0; i < 5; i++) {
834 ValuesBucket row;
835 row.Put("id", i);
836 row.Put("name", "Jim");
837 rows.Put(row);
838 }
839 auto [status, result] = store_->BatchInsert("test", rows, { "id" });
840 EXPECT_EQ(status, E_OK);
841 EXPECT_EQ(result.changed, 5);
842 ASSERT_NE(result.results, nullptr);
843 int32_t count = 0;
844 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
845 ASSERT_EQ(count, 5);
846 auto values = GetColumnValues(result.results, "id");
847 ASSERT_EQ(values.size(), 5);
848 for (int i = 0; i < 5; i++) {
849 int val = -1;
850 EXPECT_EQ(values[i].GetInt(val), E_OK);
851 EXPECT_EQ(val, i);
852 }
853 }
854
855 /**
856 * @tc.name: BatchInsert_002
857 * @tc.desc: abnormal test. batch insert with returning and conflict IGNORE
858 * @tc.type: FUNC
859 * @tc.require:
860 * @tc.author:
861 */
862 HWTEST_P(RdbStoreInsertTest, BatchInsert_002, TestSize.Level0)
863 {
864 ValuesBuckets rows;
865 for (int i = 0; i < 5; i++) {
866 ValuesBucket row;
867 row.Put("id", i);
868 row.Put("name", "Jim");
869 rows.Put(row);
870 }
871 ValuesBucket row;
872 row.Put("id", 2);
873 row.Put("name", "Jim");
874 auto res = store_->Insert("test", row);
875 ASSERT_EQ(res.first, E_OK);
876 ASSERT_EQ(res.second, 2);
877 std::string returningField = "id";
878 auto [status, result] =
879 store_->BatchInsert("test", rows, { returningField }, ConflictResolution::ON_CONFLICT_IGNORE);
880 EXPECT_EQ(status, E_OK);
881 EXPECT_EQ(result.changed, 4);
882 ASSERT_NE(result.results, nullptr);
883 int32_t count = 0;
884 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
885 ASSERT_EQ(count, 4);
886 auto values = GetColumnValues(result.results, returningField);
887 ASSERT_EQ(values.size(), 4);
888 for (size_t i = 0; i < values.size(); i++) {
889 int val = -1;
890 EXPECT_EQ(values[i].GetInt(val), E_OK);
891 EXPECT_EQ(val, i + (i >= 2));
892 }
893 }
894
895 /**
896 * @tc.name: BatchInsert_003
897 * @tc.desc: abnormal test. batch insert with returning and conflict fail.
898 * When using the fail strategy, if the constraint is violated, the correct result cannot be obtained
899 * @tc.type: FUNC
900 * @tc.require:
901 * @tc.author:
902 */
903 HWTEST_P(RdbStoreInsertTest, BatchInsert_003, TestSize.Level0)
904 {
905 std::vector<ValuesBucket> rows;
906 for (int i = 0; i < 5; i++) {
907 ValuesBucket row;
908 row.Put("id", i);
909 row.Put("name", "Jim");
910 rows.push_back(std::move(row));
911 }
912 ValuesBucket row;
913 row.Put("id", 2);
914 row.Put("name", "Jim");
915 auto res = store_->Insert("test", row);
916 ASSERT_EQ(res.first, E_OK);
917 ASSERT_EQ(res.second, 2);
918 auto [status, result] = store_->BatchInsert("test", rows, { "id" }, ConflictResolution::ON_CONFLICT_FAIL);
919 EXPECT_EQ(status, E_SQLITE_CONSTRAINT);
920 EXPECT_EQ(result.changed, 2);
921 EXPECT_EQ(result.results, nullptr);
922 }
923
924 /**
925 * @tc.name: BatchInsert_004
926 * @tc.desc: abnormal test. batch insert with returning and conflict replace
927 * @tc.type: FUNC
928 * @tc.require:
929 * @tc.author:
930 */
931 HWTEST_P(RdbStoreInsertTest, BatchInsert_004, TestSize.Level0)
932 {
933 std::vector<ValuesBucket> rows;
934 for (int i = 0; i < 5; i++) {
935 ValuesBucket row;
936 row.Put("id", i);
937 row.Put("name", "Jim");
938 rows.push_back(std::move(row));
939 }
940 ValuesBucket row;
941 row.Put("id", 2);
942 row.Put("name", "Jim");
943 auto res = store_->Insert("test", row);
944 ASSERT_EQ(res.first, E_OK);
945 ASSERT_EQ(res.second, 2);
946 std::string returningField = "id";
947 auto [status, result] = store_->BatchInsert(
948 "test", ValuesBuckets(std::move(rows)), { returningField }, ConflictResolution::ON_CONFLICT_REPLACE);
949 EXPECT_EQ(status, E_OK);
950 EXPECT_EQ(result.changed, 5);
951 ASSERT_NE(result.results, nullptr);
952 int32_t count = 0;
953 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
954 ASSERT_EQ(count, 5);
955 auto values = GetColumnValues(result.results, returningField);
956 ASSERT_EQ(values.size(), 5);
957 for (size_t i = 0; i < 5; i++) {
958 int val = -1;
959 EXPECT_EQ(values[i].GetInt(val), E_OK);
960 EXPECT_EQ(val, i);
961 }
962 }
963
964 /**
965 * @tc.name: BatchInsert_005
966 * @tc.desc: abnormal test. batch insert with over returning limit
967 * @tc.type: FUNC
968 * @tc.require:
969 * @tc.author:
970 */
971 HWTEST_P(RdbStoreInsertTest, BatchInsert_005, TestSize.Level0)
972 {
973 ValuesBuckets rows;
974 rows.Reserve(1025);
975 for (int i = 0; i < 1025; i++) {
976 ValuesBucket row;
977 row.Put("id", i);
978 row.Put("name", "Jim");
979 rows.Put(std::move(row));
980 }
981 auto [status, result] = store_->BatchInsert("test", rows, { "id" }, ConflictResolution::ON_CONFLICT_REPLACE);
982 EXPECT_EQ(status, E_OK);
983 EXPECT_EQ(result.changed, 1025);
984 ASSERT_NE(result.results, nullptr);
985 int32_t count = 0;
986 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
987 ASSERT_EQ(count, 1024);
988 auto values = GetColumnValues(result.results, "id");
989 ASSERT_EQ(values.size(), 1024);
990 for (size_t i = 0; i < 1024; i++) {
991 EXPECT_EQ(int(values[i]), i);
992 }
993 }
994
995 /**
996 * @tc.name: BatchInsert_006
997 * @tc.desc: abnormal test. batch insert with returning non-existent fields
998 * @tc.type: FUNC
999 * @tc.require:
1000 * @tc.author:
1001 */
1002 HWTEST_P(RdbStoreInsertTest, BatchInsert_006, TestSize.Level0)
1003 {
1004 ValuesBuckets rows;
1005 for (int i = 0; i < 5; i++) {
1006 ValuesBucket row;
1007 row.Put("id", i);
1008 row.Put("name", "Jim");
1009 rows.Put(std::move(row));
1010 }
1011 std::string returningField = "notExist";
1012 auto [status, result] =
1013 store_->BatchInsert("test", rows, { returningField }, ConflictResolution::ON_CONFLICT_REPLACE);
1014 EXPECT_EQ(status, E_SQLITE_ERROR);
1015 EXPECT_EQ(result.changed, -1);
1016 ASSERT_EQ(result.results, nullptr);
1017 }
1018
1019 /**
1020 * @tc.name: BatchInsert_007
1021 * @tc.desc: abnormal test. batch insert with returning and no changed rows
1022 * @tc.type: FUNC
1023 * @tc.require:
1024 * @tc.author:
1025 */
1026 HWTEST_P(RdbStoreInsertTest, BatchInsert_007, TestSize.Level0)
1027 {
1028 ValuesBuckets rows;
1029 ValuesBucket row;
1030 row.Put("id", 2);
1031 row.Put("name", "Jim");
1032 auto res = store_->Insert("test", row);
1033 ASSERT_EQ(res.first, E_OK);
1034 ASSERT_EQ(res.second, 2);
1035 rows.Put(std::move(row));
1036 auto [status, result] = store_->BatchInsert("test", rows, { "id" }, ConflictResolution::ON_CONFLICT_IGNORE);
1037 EXPECT_EQ(status, E_OK);
1038 EXPECT_EQ(result.changed, 0);
1039 ASSERT_NE(result.results, nullptr);
1040 int32_t count = 0;
1041 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
1042 ASSERT_EQ(count, 0);
1043 }
1044
1045 /**
1046 * @tc.name: BatchInsert_008
1047 * @tc.desc: normal test. batch insert with returning rowId
1048 * @tc.type: FUNC
1049 * @tc.require:
1050 * @tc.author:
1051 */
1052 HWTEST_P(RdbStoreInsertTest, BatchInsert_008, TestSize.Level0)
1053 {
1054 ValuesBuckets rows;
1055 ValuesBucket row;
1056 row.Put("id", 2);
1057 row.Put("name", "Jim");
1058 rows.Put(std::move(row));
1059 // rowId can use in retuning, but get column not include rowId
1060 auto [status, result] = store_->BatchInsert("test", rows, { "rowId", "rowid", "RowId", "id" });
1061 EXPECT_EQ(status, E_OK);
1062 EXPECT_EQ(result.changed, 1);
1063 ASSERT_NE(result.results, nullptr);
1064 int32_t count = 0;
1065 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
1066 ASSERT_EQ(count, 1);
1067 RowEntity rowEntity;
1068 EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
1069 EXPECT_EQ(int(rowEntity.Get("id")), 2);
1070 }
1071
1072 /**
1073 * @tc.name: BatchInsert_009
1074 * @tc.desc: normal test. batch insert with returning *
1075 * @tc.type: FUNC
1076 * @tc.require:
1077 * @tc.author:
1078 */
1079 HWTEST_P(RdbStoreInsertTest, BatchInsert_009, TestSize.Level0)
1080 {
1081 ValuesBuckets rows;
1082 ValuesBucket row;
1083 row.Put("id", 2);
1084 row.Put("name", "Jim");
1085 row.Put("age", 18);
1086 row.PutDouble("salary", 100.5);
1087 std::vector<uint8_t> blob{ 1, 2, 3 };
1088 row.PutBlob("blobType", blob);
1089 rows.Put(std::move(row));
1090 auto [status, result] =
1091 store_->BatchInsert("test", rows, { "*" }, NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
1092 EXPECT_EQ(status, E_OK);
1093 EXPECT_EQ(result.changed, 1);
1094 ASSERT_NE(result.results, nullptr);
1095 int32_t count = 0;
1096 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
1097 ASSERT_EQ(count, 1);
1098 RowEntity rowEntity;
1099 EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
1100 EXPECT_EQ(int(rowEntity.Get("id")), 2);
1101 EXPECT_EQ(std::string(rowEntity.Get("name")), "Jim");
1102 EXPECT_EQ(int(rowEntity.Get("age")), 18);
1103 EXPECT_NEAR(double(rowEntity.Get("salary")), 100.5, std::numeric_limits<double>::epsilon());
1104 EXPECT_EQ(std::vector<uint8_t>(rowEntity.Get("blobType")), blob);
1105 }
1106
1107 /**
1108 * @tc.name: BatchInsert_010
1109 * @tc.desc: normal test. batch insert with returning complex field
1110 * @tc.type: FUNC
1111 * @tc.require:
1112 * @tc.author:
1113 */
1114 HWTEST_P(RdbStoreInsertTest, BatchInsert_010, TestSize.Level0)
1115 {
1116 ValuesBuckets rows;
1117 ValuesBucket row;
1118 row.Put("id", 2);
1119 row.Put("name", "Jim");
1120 row.PutDouble("salary", 100.5);
1121 rows.Put(std::move(row));
1122 auto [status, result] = store_->BatchInsert("test", rows, { "id", "name", "salary * 1.1 AS bonusSalary" },
1123 NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
1124 EXPECT_EQ(status, E_OK);
1125 EXPECT_EQ(result.changed, 1);
1126 ASSERT_NE(result.results, nullptr);
1127 int32_t count = 0;
1128 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
1129 ASSERT_EQ(count, 1);
1130 RowEntity rowEntity;
1131 EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
1132 EXPECT_EQ(int(rowEntity.Get("id")), 2);
1133 EXPECT_EQ(std::string(rowEntity.Get("name")), "Jim");
1134 EXPECT_NEAR(double(rowEntity.Get("bonusSalary")), 100.5 * 1.1, std::numeric_limits<double>::epsilon());
1135 }
1136
1137 /**
1138 * @tc.name: BatchInsert_011
1139 * @tc.desc: normal test. batch insert with returning complex field
1140 * @tc.type: FUNC
1141 * @tc.require:
1142 * @tc.author:
1143 */
1144 HWTEST_P(RdbStoreInsertTest, BatchInsert_011, TestSize.Level1)
1145 {
1146 ValuesBuckets rows;
1147 ValuesBucket row;
1148 row.Put("id", 1);
1149 row.Put("name", "Jim");
1150 row.Put("age", 18);
1151 row.PutDouble("salary", 110.5);
1152 rows.Put(std::move(row));
1153 row.Clear();
1154 row.Put("id", 2);
1155 row.Put("name", "Bob");
1156 row.Put("age", 22);
1157 row.PutDouble("salary", 90);
1158 rows.Put(std::move(row));
1159 auto [status, result] = store_->BatchInsert("test", rows,
1160 { "id", "name", "(salary < 100) AS lowSalary", "age > 18 as adult" },
1161 NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
1162 EXPECT_EQ(status, E_OK);
1163 EXPECT_EQ(result.changed, 2);
1164 ASSERT_NE(result.results, nullptr);
1165 int32_t count = 0;
1166 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
1167 ASSERT_EQ(count, 2);
1168 RowEntity rowEntity;
1169 EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
1170 EXPECT_EQ(int(rowEntity.Get("id")), 1);
1171 EXPECT_EQ(std::string(rowEntity.Get("name")), "Jim");
1172 EXPECT_EQ(bool(rowEntity.Get("lowSalary")), false);
1173 EXPECT_EQ(bool(rowEntity.Get("adult")), false);
1174
1175 EXPECT_EQ(result.results->GoToNextRow(), E_OK);
1176 EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
1177 EXPECT_EQ(int(rowEntity.Get("id")), 2);
1178 EXPECT_EQ(std::string(rowEntity.Get("name")), "Bob");
1179 EXPECT_EQ(bool(rowEntity.Get("lowSalary")), true);
1180 EXPECT_EQ(bool(rowEntity.Get("adult")), true);
1181 }
1182
1183 /**
1184 * @tc.name: BatchInsert_012
1185 * @tc.desc: normal test. batch insert with returning function
1186 * @tc.type: FUNC
1187 * @tc.require:
1188 * @tc.author:
1189 */
1190 HWTEST_P(RdbStoreInsertTest, BatchInsert_012, TestSize.Level1)
1191 {
1192 ValuesBuckets rows;
1193 ValuesBucket row;
1194 row.Put("id", 20);
1195 row.Put("name", "Jim");
1196 row.PutDouble("salary", 100.5);
1197 rows.Put(std::move(row));
1198 auto [status, result] = store_->BatchInsert("test", rows, { "id", "name", "datetime('now') AS createdTime" },
1199 NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
1200 EXPECT_EQ(status, E_OK);
1201 EXPECT_EQ(result.changed, 1);
1202 ASSERT_NE(result.results, nullptr);
1203 int32_t count = 0;
1204 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
1205 ASSERT_EQ(count, 1);
1206 RowEntity rowEntity;
1207 EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
1208 EXPECT_EQ(int(rowEntity.Get("id")), 20);
1209 EXPECT_EQ(std::string(rowEntity.Get("name")), "Jim");
1210 EXPECT_EQ(rowEntity.Get("createdTime").GetType(), ValueObject::TYPE_STRING);
1211 EXPECT_FALSE(std::string(rowEntity.Get("createdTime")).empty());
1212 }
1213
1214 /**
1215 * @tc.name: BatchInsert_013
1216 * @tc.desc: normal test. batch insert into virtual table with returning
1217 * @tc.type: FUNC
1218 * @tc.require:
1219 * @tc.author:
1220 */
1221 HWTEST_P(RdbStoreInsertTest, BatchInsert_013, TestSize.Level1)
1222 {
1223 store_->Execute("CREATE VIRTUAL TABLE IF NOT EXISTS articles USING fts5(title, content);");
1224 ValuesBuckets rows;
1225 ValuesBucket row;
1226 row.Put("title", "fts5");
1227 row.Put("content", "test virtual tables");
1228 rows.Put(std::move(row));
1229 auto [status, result] =
1230 store_->BatchInsert("articles", rows, { "title" }, NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
1231 EXPECT_EQ(status, E_OK);
1232 EXPECT_EQ(result.changed, 1);
1233 ASSERT_NE(result.results, nullptr);
1234 int32_t count = 0;
1235 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
1236 ASSERT_EQ(count, 1);
1237 RowEntity rowEntity;
1238 EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
1239 EXPECT_EQ(std::string(rowEntity.Get("title")), "fts5");
1240 store_->Execute("Drop TABLE articles");
1241 }
1242
1243 /**
1244 * @tc.name: BatchInsert_014
1245 * @tc.desc: normal test. batch insert with returning and trigger
1246 * @tc.type: FUNC
1247 * @tc.require:
1248 * @tc.author:
1249 */
1250 HWTEST_P(RdbStoreInsertTest, BatchInsert_014, TestSize.Level1)
1251 {
1252 auto [code, result1] = store_->Execute("CREATE TRIGGER after_name_insert AFTER INSERT ON test"
1253 " BEGIN UPDATE test SET name = 'after trigger' WHERE name = 'BatchInsert_014'; END");
1254
1255 EXPECT_EQ(code, E_OK);
1256
1257 ValuesBuckets rows;
1258 ValuesBucket row;
1259 row.Put("id", 200);
1260 row.Put("name", "BatchInsert_014");
1261 rows.Put(std::move(row));
1262 auto [status, result] =
1263 store_->BatchInsert("test", rows, { "name" }, NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
1264 EXPECT_EQ(status, E_OK);
1265 EXPECT_EQ(result.changed, 1);
1266 ASSERT_NE(result.results, nullptr);
1267 int32_t count = 0;
1268 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
1269 ASSERT_EQ(count, 1);
1270 RowEntity rowEntity;
1271 EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
1272 EXPECT_EQ(std::string(rowEntity.Get("name")), "BatchInsert_014");
1273
1274 auto resultSet = store_->QuerySql("select name from test where id = 200");
1275 int rowCount = -1;
1276 resultSet->GetRowCount(rowCount);
1277 resultSet->GoToFirstRow();
1278 EXPECT_EQ(resultSet->GetRow(rowEntity), E_OK);
1279 EXPECT_EQ(std::string(rowEntity.Get("name")), "after trigger");
1280 store_->Execute("DROP TRIGGER IF EXISTS after_name_insert");
1281 }
1282
1283 /**
1284 * @tc.name: BatchInsert_015
1285 * @tc.desc: normal test. batch insert with returning and sub query
1286 * @tc.type: FUNC
1287 * @tc.require:
1288 * @tc.author:
1289 */
1290 HWTEST_P(RdbStoreInsertTest, BatchInsert_015, TestSize.Level1)
1291 {
1292 store_->Execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT);");
1293 store_->Execute("CREATE TABLE IF NOT EXISTS logs (id INTEGER PRIMARY KEY, action TEXT);");
1294 ValuesBuckets rows;
1295 ValuesBucket row;
1296 row.Put("id", 200);
1297 row.Put("action", "BatchInsert_015");
1298 rows.Put(std::move(row));
1299 auto [status, changed] = store_->BatchInsert("logs", rows);
1300 EXPECT_EQ(status, E_OK);
1301 EXPECT_EQ(changed, 1);
1302 Results result{ -1 };
1303 row.Clear();
1304 rows.Clear();
1305 row.Put("id", 1);
1306 row.Put("name", "BatchInsert_015");
1307 rows.Put(std::move(row));
1308 std::tie(status, result) = store_->BatchInsert("users", rows,
1309 { "(SELECT COUNT(*) FROM logs WHERE action = name) AS count" },
1310 NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
1311 EXPECT_EQ(status, E_OK);
1312 EXPECT_EQ(result.changed, 1);
1313 ASSERT_NE(result.results, nullptr);
1314 int32_t count = 0;
1315 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
1316 ASSERT_EQ(count, 1);
1317 RowEntity rowEntity;
1318 EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
1319 EXPECT_EQ(int(rowEntity.Get("count")), 1);
1320 store_->Execute("DROP TABLE users");
1321 store_->Execute("DROP TABLE logs");
1322 }
1323
1324 /**
1325 * @tc.name: BatchInsert_016
1326 * @tc.desc: abnormal test. batch insert with max returning limit
1327 * @tc.type: FUNC
1328 * @tc.require:
1329 * @tc.author:
1330 */
1331 HWTEST_P(RdbStoreInsertTest, BatchInsert_016, TestSize.Level0)
1332 {
1333 int maxRowCount = 1024;
1334 ValuesBuckets rows;
1335 rows.Reserve(maxRowCount);
1336 for (int i = 0; i < maxRowCount; i++) {
1337 ValuesBucket row;
1338 row.Put("id", i);
1339 row.Put("name", "Jim");
1340 rows.Put(std::move(row));
1341 }
1342 auto [status, result] =
1343 store_->BatchInsert("test", ValuesBuckets(rows), {"id", "name"}, ConflictResolution::ON_CONFLICT_REPLACE);
1344 EXPECT_EQ(status, E_OK);
1345 EXPECT_EQ(result.changed, maxRowCount);
1346 ASSERT_NE(result.results, nullptr);
1347 int32_t count = 0;
1348 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
1349 ASSERT_EQ(count, maxRowCount);
1350 for (size_t i = 0; i < maxRowCount; i++) {
1351 RowEntity rowEntity;
1352 EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
1353 EXPECT_EQ(int(rowEntity.Get("id")), i);
1354 EXPECT_EQ(std::string(rowEntity.Get("name")), "Jim");
1355 if (i != maxRowCount - 1) {
1356 ASSERT_EQ(result.results->GoToNextRow(), E_OK);
1357 }
1358 }
1359 }
1360
1361 /**
1362 * @tc.name: BatchInsert_017
1363 * @tc.desc: abnormal test. batch insert with max returning limit
1364 * @tc.type: FUNC
1365 * @tc.require:
1366 * @tc.author:
1367 */
1368 HWTEST_P(RdbStoreInsertTest, BatchInsert_017, TestSize.Level0)
1369 {
1370 int maxRowCount = 1024;
1371 ValuesBuckets rows;
1372 rows.Reserve(maxRowCount);
1373 for (int i = 0; i < maxRowCount; i++) {
1374 ValuesBucket row;
1375 row.Put("id", i);
1376 row.Put("name", "Jim");
1377 rows.Put(std::move(row));
1378 }
1379 auto [status, result] =
1380 store_->BatchInsert("test", ValuesBuckets(rows), {"id", "name"}, ConflictResolution::ON_CONFLICT_REPLACE);
1381 EXPECT_EQ(status, E_OK);
1382 EXPECT_EQ(result.changed, maxRowCount);
1383 int32_t count = 0;
1384 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
1385 ASSERT_EQ(count, maxRowCount);
1386
1387 std::tie(status, result) =
1388 store_->ExecuteExt("UPDATE test SET name = 'Tim' WHERE name = 'Jim' RETURNING id, name");
1389
1390 EXPECT_EQ(result.changed, maxRowCount);
1391 count = 0;
1392 EXPECT_EQ(result.results->GetRowCount(count), E_OK);
1393 EXPECT_EQ(count, maxRowCount);
1394 for (size_t i = 0; i < maxRowCount; i++) {
1395 RowEntity rowEntity;
1396 EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
1397 EXPECT_EQ(int(rowEntity.Get("id")), i);
1398 EXPECT_EQ(std::string(rowEntity.Get("name")), "Tim");
1399 if (i != maxRowCount - 1) {
1400 ASSERT_EQ(result.results->GoToNextRow(), E_OK);
1401 }
1402 }
1403 }
1404
1405 /**
1406 * @tc.name: BatchInsert_018
1407 * @tc.desc: abnormal test. batch insert with max returning limit
1408 * @tc.type: FUNC
1409 * @tc.require:
1410 * @tc.author:
1411 */
1412 HWTEST_P(RdbStoreInsertTest, BatchInsert_018, TestSize.Level0)
1413 {
1414 int maxRowCount = 1024;
1415 ValuesBuckets rows;
1416 rows.Reserve(maxRowCount);
1417 for (int i = 0; i < maxRowCount; i++) {
1418 ValuesBucket row;
1419 row.Put("id", i);
1420 row.Put("name", "Jim");
1421 rows.Put(std::move(row));
1422 }
1423 auto [status, result] =
1424 store_->BatchInsert("test", ValuesBuckets(rows), {"id", "name"}, ConflictResolution::ON_CONFLICT_REPLACE);
1425 EXPECT_EQ(status, E_OK);
1426 EXPECT_EQ(result.changed, maxRowCount);
1427
1428 std::tie(status, result) =
1429 store_->ExecuteExt("update test set name = ? where name = ?", { "Tim", "Jim" });
1430
1431 EXPECT_NE(result.results, nullptr);
1432 EXPECT_EQ(result.changed, maxRowCount);
1433 int32_t count = 0;
1434 EXPECT_EQ(result.results->GetRowCount(count), E_OK);
1435 EXPECT_EQ(count, 0);
1436 }
1437 /**
1438 * @tc.name: BatchInsert_019
1439 * @tc.desc: normal test. batch insert with returning and trigger
1440 * @tc.type: FUNC
1441 * @tc.require:
1442 * @tc.author:
1443 */
1444 HWTEST_P(RdbStoreInsertTest, BatchInsert_019, TestSize.Level1)
1445 {
1446 auto [code, result1] = store_->Execute("CREATE TRIGGER after_name_insert AFTER INSERT ON test"
1447 " BEGIN UPDATE test SET name = 'after trigger' WHERE name = 'BatchInsert_014'; END");
1448
1449 EXPECT_EQ(code, E_OK);
1450
1451 auto [status, result] =
1452 store_->ExecuteExt("INSERT INTO test (id, name) VALUES (200, 'BatchInsert_014') RETURNING name;");
1453
1454 EXPECT_EQ(status, E_OK);
1455 EXPECT_EQ(result.changed, 1);
1456 ASSERT_NE(result.results, nullptr);
1457 int32_t count = 0;
1458 ASSERT_EQ(result.results->GetRowCount(count), E_OK);
1459 ASSERT_EQ(count, 1);
1460 RowEntity rowEntity;
1461 EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
1462 EXPECT_EQ(std::string(rowEntity.Get("name")), "BatchInsert_014");
1463
1464 auto resultSet = store_->QuerySql("select name from test where id = 200");
1465 int rowCount = -1;
1466 resultSet->GetRowCount(rowCount);
1467 resultSet->GoToFirstRow();
1468 EXPECT_EQ(resultSet->GetRow(rowEntity), E_OK);
1469 EXPECT_EQ(std::string(rowEntity.Get("name")), "after trigger");
1470 store_->Execute("DROP TRIGGER IF EXISTS after_name_insert");
1471 }
1472 INSTANTIATE_TEST_SUITE_P(InsertTest, RdbStoreInsertTest, testing::Values(&g_store, &g_memDb));
1473 } // namespace OHOS::RdbStoreInsertTest