• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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