* Copyright (c) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <string>
#include "rdb_test_common.h"
#include "rdb_common.h"
#include "rdb_errno.h"
#include "rdb_helper.h"
#include "rdb_open_callback.h"
#include "result_set.h"
#include "values_buckets.h"
using namespace testing::ext;
using namespace OHOS::NativeRdb;
namespace OHOS::RdbStoreInsertTest {
struct RdbTestParam {
std::shared_ptr<RdbStore> store;
operator std::shared_ptr<RdbStore>()
{
return store;
}
};
static RdbTestParam g_store;
static RdbTestParam g_memDb;
class RdbStoreInsertTest : public testing::TestWithParam<RdbTestParam *> {
public:
static void SetUpTestCase(void);
static void TearDownTestCase(void);
void SetUp();
void TearDown();
static void CheckResultSet(std::shared_ptr<RdbStore> &store);
static void CheckAge(std::shared_ptr<ResultSet> &resultSet);
static void CheckSalary(std::shared_ptr<ResultSet> &resultSet);
static void CheckBlob(std::shared_ptr<ResultSet> &resultSet);
std::shared_ptr<RdbStore> store_;
static const std::string DATABASE_NAME;
};
const std::string RdbStoreInsertTest::DATABASE_NAME = RDB_TEST_PATH + "insert_test.db";
class InsertTestOpenCallback : public RdbOpenCallback {
public:
int OnCreate(RdbStore &store) override;
int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
static const std::string CREATE_TABLE_TEST;
};
const std::string InsertTestOpenCallback::CREATE_TABLE_TEST =
std::string("CREATE TABLE IF NOT EXISTS test ") + std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER, salary "
"REAL, blobType BLOB)");
int InsertTestOpenCallback::OnCreate(RdbStore &store)
{
return store.ExecuteSql(CREATE_TABLE_TEST);
}
int InsertTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
{
return E_OK;
}
std::vector<ValueObject> GetColumnValues(std::shared_ptr<ResultSet> resultSet, const std::string &filed)
{
std::vector<ValueObject> res;
if (resultSet->GoToFirstRow() != E_OK) {
return res;
}
int32_t colIndex = -1;
if (resultSet->GetColumnIndex(filed, colIndex) != E_OK) {
return res;
}
do {
ValueObject value;
EXPECT_EQ(resultSet->Get(colIndex, value), E_OK);
res.push_back(value);
} while (resultSet->GoToNextRow() == E_OK);
return res;
}
void RdbStoreInsertTest::SetUpTestCase(void)
{
int errCode = E_OK;
RdbHelper::DeleteRdbStore(DATABASE_NAME);
RdbStoreConfig config(RdbStoreInsertTest::DATABASE_NAME);
InsertTestOpenCallback helper;
g_store.store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(g_store.store, nullptr);
config.SetStorageMode(StorageMode::MODE_MEMORY);
g_memDb.store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(g_memDb.store, nullptr);
}
void RdbStoreInsertTest::TearDownTestCase(void)
{
RdbHelper::DeleteRdbStore(RdbStoreInsertTest::DATABASE_NAME);
RdbStoreConfig config(RdbStoreInsertTest::DATABASE_NAME);
config.SetStorageMode(StorageMode::MODE_MEMORY);
RdbHelper::DeleteRdbStore(config);
}
void RdbStoreInsertTest::SetUp(void)
{
store_ = *GetParam();
ASSERT_NE(store_, nullptr);
store_->ExecuteSql("DELETE FROM test");
}
void RdbStoreInsertTest::TearDown(void)
{
}
* @tc.name: RdbStore_Insert_001
* @tc.desc: test RdbStore insert
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_Insert_001, TestSize.Level0)
{
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 100.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
int ret = store_->Insert(id, "test", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 18);
values.PutDouble("salary", 100.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
ret = store_->Insert(id, "test", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
values.Clear();
values.PutInt("id", 3);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 20L);
values.PutDouble("salary", 100.5f);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
ret = store_->Insert(id, "test", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(3, id);
RdbStoreInsertTest::CheckResultSet(store_);
}
void RdbStoreInsertTest::CheckResultSet(std::shared_ptr<RdbStore> &store)
{
std::shared_ptr<ResultSet> resultSet =
store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector<std::string>{ "zhangsan" });
ASSERT_NE(resultSet, nullptr);
int columnIndex;
int intVal;
std::string strVal;
ColumnType columnType;
int position;
int ret = resultSet->GetRowIndex(position);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(position, -1);
ret = resultSet->GetColumnType(0, columnType);
EXPECT_EQ(ret, E_ROW_OUT_RANGE);
ret = resultSet->GoToFirstRow();
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetColumnIndex("id", columnIndex);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(columnIndex, 0);
ret = resultSet->GetColumnType(columnIndex, columnType);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(columnType, ColumnType::TYPE_INTEGER);
ret = resultSet->GetInt(columnIndex, intVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, intVal);
ret = resultSet->GetColumnIndex("name", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetColumnType(columnIndex, columnType);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(columnType, ColumnType::TYPE_STRING);
ret = resultSet->GetString(columnIndex, strVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ("zhangsan", strVal);
RdbStoreInsertTest::CheckAge(resultSet);
RdbStoreInsertTest::CheckSalary(resultSet);
RdbStoreInsertTest::CheckBlob(resultSet);
ret = resultSet->GoToNextRow();
EXPECT_EQ(ret, E_ROW_OUT_RANGE);
ret = resultSet->GetColumnType(columnIndex, columnType);
EXPECT_EQ(ret, E_ROW_OUT_RANGE);
ret = resultSet->Close();
EXPECT_EQ(ret, E_OK);
}
void RdbStoreInsertTest::CheckAge(std::shared_ptr<ResultSet> &resultSet)
{
int columnIndex;
int intVal;
ColumnType columnType;
int ret = resultSet->GetColumnIndex("age", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetColumnType(columnIndex, columnType);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(columnType, ColumnType::TYPE_INTEGER);
ret = resultSet->GetInt(columnIndex, intVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(18, intVal);
}
void RdbStoreInsertTest::CheckSalary(std::shared_ptr<ResultSet> &resultSet)
{
int columnIndex;
double dVal;
ColumnType columnType;
int ret = resultSet->GetColumnIndex("salary", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetColumnType(columnIndex, columnType);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(columnType, ColumnType::TYPE_FLOAT);
ret = resultSet->GetDouble(columnIndex, dVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(100.5, dVal);
}
void RdbStoreInsertTest::CheckBlob(std::shared_ptr<ResultSet> &resultSet)
{
int columnIndex;
std::vector<uint8_t> blob;
ColumnType columnType;
int ret = resultSet->GetColumnIndex("blobType", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetColumnType(columnIndex, columnType);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(columnType, ColumnType::TYPE_BLOB);
ret = resultSet->GetBlob(columnIndex, blob);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(3, static_cast<int>(blob.size()));
EXPECT_EQ(1, blob[0]);
EXPECT_EQ(2, blob[1]);
EXPECT_EQ(3, blob[2]);
}
* @tc.name: RdbStore_Insert_002
* @tc.desc: test RdbStore insert
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_Insert_002, TestSize.Level0)
{
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 100.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
int ret = store_->Insert(id, "", values);
EXPECT_EQ(ret, E_EMPTY_TABLE_NAME);
ret = store_->Insert(id, "wrongTable", values);
EXPECT_EQ(ret, E_SQLITE_ERROR);
}
* @tc.name: RdbStore_Insert_003
* @tc.desc: test RdbStore insert
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_Insert_003, TestSize.Level0)
{
int64_t id;
ValuesBucket emptyBucket;
int ret = store_->Insert(id, "test", emptyBucket);
EXPECT_EQ(ret, E_EMPTY_VALUES_BUCKET);
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("wrongColumn", 100.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
ret = store_->Insert(id, "test", values);
EXPECT_EQ(ret, E_SQLITE_ERROR);
}
* @tc.name: RdbStore_Replace_001
* @tc.desc: test RdbStore replace
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_Replace_001, TestSize.Level0)
{
int64_t id;
ValuesBucket values;
int ret = store_->Replace(id, "test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[0]));
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test");
EXPECT_NE(resultSet, nullptr);
ret = resultSet->GoToNextRow();
EXPECT_EQ(ret, E_OK);
int columnIndex;
int intVal;
std::string strVal;
ret = resultSet->GetColumnIndex("id", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetInt(columnIndex, intVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, intVal);
ret = resultSet->GetColumnIndex("name", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetString(columnIndex, strVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ("zhangsan", strVal);
ret = resultSet->GetColumnIndex("age", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetInt(columnIndex, intVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(18, intVal);
ret = resultSet->GoToNextRow();
EXPECT_EQ(ret, E_ROW_OUT_RANGE);
ret = resultSet->Close();
EXPECT_EQ(ret, E_OK);
}
* @tc.name: RdbStore_Replace_002
* @tc.desc: test RdbStore replace
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_Replace_002, TestSize.Level0)
{
int64_t id;
ValuesBucket values;
int ret = store_->Insert(id, "test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[0]));
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
values.Clear();
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 200.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
ret = store_->Replace(id, "test", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test");
EXPECT_NE(resultSet, nullptr);
ret = resultSet->GoToNextRow();
EXPECT_EQ(ret, E_OK);
int columnIndex;
int intVal;
std::string strVal;
ret = resultSet->GetColumnIndex("id", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetInt(columnIndex, intVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, intVal);
ret = resultSet->GetColumnIndex("name", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetString(columnIndex, strVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ("zhangsan", strVal);
ret = resultSet->GetColumnIndex("age", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetInt(columnIndex, intVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(18, intVal);
ret = resultSet->GoToNextRow();
EXPECT_EQ(ret, E_ROW_OUT_RANGE);
ret = resultSet->Close();
EXPECT_EQ(ret, E_OK);
}
* @tc.name: RdbStore_Replace_003
* @tc.desc: test RdbStore Replace
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_Replace_003, TestSize.Level0)
{
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 100.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
int ret = store_->Replace(id, "", values);
EXPECT_EQ(ret, E_EMPTY_TABLE_NAME);
ret = store_->Replace(id, "wrongTable", values);
EXPECT_EQ(ret, E_SQLITE_ERROR);
}
* @tc.name: RdbStore_Replace_004
* @tc.desc: test RdbStore Replace
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_Replace_004, TestSize.Level0)
{
int64_t id;
ValuesBucket emptyBucket;
int ret = store_->Replace(id, "test", emptyBucket);
EXPECT_EQ(ret, E_EMPTY_VALUES_BUCKET);
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("wrongColumn", 100.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
ret = store_->Replace(id, "test", values);
EXPECT_EQ(ret, E_SQLITE_ERROR);
}
* @tc.name: RdbStore_Replace_005
* @tc.desc: test RdbStore replace
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_Replace_005, TestSize.Level0)
{
int64_t id;
int ret = store_->Replace(id, "test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[0]));
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test");
EXPECT_NE(resultSet, nullptr);
ret = resultSet->GoToNextRow();
EXPECT_EQ(ret, E_OK);
int columnIndex;
double dVal;
std::vector<uint8_t> blob;
ret = resultSet->GetColumnIndex("salary", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetDouble(columnIndex, dVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(100.5, dVal);
ret = resultSet->GetColumnIndex("blobType", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetBlob(columnIndex, blob);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(3, static_cast<int>(blob.size()));
EXPECT_EQ(1, blob[0]);
EXPECT_EQ(2, blob[1]);
EXPECT_EQ(3, blob[2]);
ret = resultSet->GoToNextRow();
EXPECT_EQ(ret, E_ROW_OUT_RANGE);
ret = resultSet->Close();
EXPECT_EQ(ret, E_OK);
}
* @tc.name: RdbStore_Replace_006
* @tc.desc: test RdbStore replace
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_Replace_006, TestSize.Level0)
{
int64_t id;
ValuesBucket values;
int ret = store_->Insert(id, "test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[0]));
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
values.Clear();
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 200.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
ret = store_->Replace(id, "test", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test");
EXPECT_NE(resultSet, nullptr);
ret = resultSet->GoToNextRow();
EXPECT_EQ(ret, E_OK);
int columnIndex;
double dVal;
std::vector<uint8_t> blob;
ret = resultSet->GetColumnIndex("salary", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetDouble(columnIndex, dVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(200.5, dVal);
ret = resultSet->GetColumnIndex("blobType", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetBlob(columnIndex, blob);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(3, static_cast<int>(blob.size()));
EXPECT_EQ(1, blob[0]);
EXPECT_EQ(2, blob[1]);
EXPECT_EQ(3, blob[2]);
ret = resultSet->GoToNextRow();
EXPECT_EQ(ret, E_ROW_OUT_RANGE);
ret = resultSet->Close();
EXPECT_EQ(ret, E_OK);
}
* @tc.name: RdbStore_InsertWithConflictResolution_001_002
* @tc.desc: test RdbStore InsertWithConflictResolution
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_InsertWithConflictResolution_001_002, TestSize.Level0)
{
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 100.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
int ret = store_->InsertWithConflictResolution(id, "test", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
values.Clear();
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 200.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
ret = store_->InsertWithConflictResolution(id, "test", values);
EXPECT_EQ(ret, E_SQLITE_CONSTRAINT);
}
* @tc.name: RdbStore_InsertWithConflictResolution_003_004
* @tc.desc: test RdbStore InsertWithConflictResolution
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_InsertWithConflictResolution_003_004, TestSize.Level0)
{
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 100.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
int ret = store_->InsertWithConflictResolution(id, "test", values, ConflictResolution::ON_CONFLICT_ROLLBACK);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
values.Clear();
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 200.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
ret = store_->InsertWithConflictResolution(id, "test", values, ConflictResolution::ON_CONFLICT_ROLLBACK);
EXPECT_EQ(ret, E_SQLITE_CONSTRAINT);
}
* @tc.name: RdbStore_InsertWithConflictResolution_005
* @tc.desc: test RdbStore InsertWithConflictResolution
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_InsertWithConflictResolution_005, TestSize.Level0)
{
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 100.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
int ret = store_->InsertWithConflictResolution(id, "test", values, ConflictResolution::ON_CONFLICT_IGNORE);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
values.Clear();
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 200.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
ret = store_->InsertWithConflictResolution(id, "test", values, ConflictResolution::ON_CONFLICT_IGNORE);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(id, -1);
}
* @tc.name: RdbStore_InsertWithConflictResolution_006
* @tc.desc: test RdbStore InsertWithConflictResolution
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_InsertWithConflictResolution_006, TestSize.Level0)
{
int64_t id;
ValuesBucket values;
int ret = store_->InsertWithConflictResolution(
id, "test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[0]), ConflictResolution::ON_CONFLICT_REPLACE);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
values.Clear();
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 200.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6 });
ret = store_->InsertWithConflictResolution(id, "test", values, ConflictResolution::ON_CONFLICT_REPLACE);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(id, 1);
std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test");
EXPECT_NE(resultSet, nullptr);
ret = resultSet->GoToNextRow();
EXPECT_EQ(ret, E_OK);
int columnIndex;
int intVal;
std::string strVal;
ret = resultSet->GetColumnIndex("id", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetInt(columnIndex, intVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, intVal);
ret = resultSet->GetColumnIndex("name", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetString(columnIndex, strVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ("zhangsan", strVal);
ret = resultSet->GetColumnIndex("age", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetInt(columnIndex, intVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(18, intVal);
ret = resultSet->GoToNextRow();
EXPECT_EQ(ret, E_ROW_OUT_RANGE);
ret = resultSet->Close();
EXPECT_EQ(ret, E_OK);
}
* @tc.name: RdbStore_InsertWithConflictResolution_007
* @tc.desc: test RdbStore InsertWithConflictResolution
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_InsertWithConflictResolution_007, TestSize.Level0)
{
int64_t id;
ValuesBucket values;
int ret = store_->InsertWithConflictResolution(
id, "test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[0]), ConflictResolution::ON_CONFLICT_REPLACE);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
values.Clear();
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
values.PutDouble("salary", 200.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6 });
ret = store_->InsertWithConflictResolution(id, "test", values, ConflictResolution::ON_CONFLICT_REPLACE);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(id, 1);
std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test");
EXPECT_NE(resultSet, nullptr);
ret = resultSet->GoToNextRow();
EXPECT_EQ(ret, E_OK);
int columnIndex;
double dVal;
std::vector<uint8_t> blob;
ret = resultSet->GetColumnIndex("salary", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetDouble(columnIndex, dVal);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(200.5, dVal);
ret = resultSet->GetColumnIndex("blobType", columnIndex);
EXPECT_EQ(ret, E_OK);
ret = resultSet->GetBlob(columnIndex, blob);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(3, static_cast<int>(blob.size()));
EXPECT_EQ(4, blob[0]);
EXPECT_EQ(5, blob[1]);
EXPECT_EQ(6, blob[2]);
ret = resultSet->GoToNextRow();
EXPECT_EQ(ret, E_ROW_OUT_RANGE);
ret = resultSet->Close();
EXPECT_EQ(ret, E_OK);
}
* @tc.name: RdbStore_InsertWithConflictResolution_008
* @tc.desc: Abnormal testCase of InsertWithConflictResolution, if conflictResolution is invalid
* @tc.type: FUNC
*/
HWTEST_P(RdbStoreInsertTest, RdbStore_InsertWithConflictResolution_008, TestSize.Level0)
{
int64_t id = 0;
ValuesBucket values;
values.PutInt("id", 1);
values.PutInt("age", 18);
int ret = store_->InsertWithConflictResolution(id, "test", values, static_cast<ConflictResolution>(6));
EXPECT_EQ(E_INVALID_CONFLICT_FLAG, ret);
EXPECT_EQ(0, id);
values.Clear();
values.PutInt("id", 1);
values.PutInt("age", 18);
ret = store_->InsertWithConflictResolution(id, "test", values, static_cast<ConflictResolution>(-1));
EXPECT_EQ(E_INVALID_CONFLICT_FLAG, ret);
EXPECT_EQ(0, id);
}
* @tc.name: OverLimitWithInsert_001
* @tc.desc: over limit
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, OverLimitWithInsert_001, TestSize.Level0)
{
std::shared_ptr<RdbStore> store = *GetParam();
auto [code, maxPageCount] = store->Execute("PRAGMA max_page_count;");
auto recover = std::shared_ptr<const char>("recover", [defPageCount = maxPageCount, store](const char *) {
store->Execute("PRAGMA max_page_count = " + static_cast<std::string>(defPageCount) + ";");
});
std::tie(code, maxPageCount) = store->Execute("PRAGMA max_page_count = 256;");
ValuesBucket row;
row.Put("name", std::string(1024 * 1024, 'e'));
auto result = store->Insert("test", row, ConflictResolution::ON_CONFLICT_NONE);
ASSERT_EQ(result.first, E_SQLITE_FULL);
}
* @tc.name: BatchInsert_001
* @tc.desc: normal test
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_001, TestSize.Level0)
{
ValuesBuckets rows;
for (int i = 0; i < 5; i++) {
ValuesBucket row;
row.Put("id", i);
row.Put("name", "Jim");
rows.Put(row);
}
auto [status, result] = store_->BatchInsert("test", rows, { "id" });
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 5);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 5);
auto values = GetColumnValues(result.results, "id");
ASSERT_EQ(values.size(), 5);
for (int i = 0; i < 5; i++) {
int val = -1;
EXPECT_EQ(values[i].GetInt(val), E_OK);
EXPECT_EQ(val, i);
}
}
* @tc.name: BatchInsert_002
* @tc.desc: abnormal test. batch insert with returning and conflict IGNORE
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_002, TestSize.Level0)
{
ValuesBuckets rows;
for (int i = 0; i < 5; i++) {
ValuesBucket row;
row.Put("id", i);
row.Put("name", "Jim");
rows.Put(row);
}
ValuesBucket row;
row.Put("id", 2);
row.Put("name", "Jim");
auto res = store_->Insert("test", row);
ASSERT_EQ(res.first, E_OK);
ASSERT_EQ(res.second, 2);
std::string returningField = "id";
auto [status, result] =
store_->BatchInsert("test", rows, { returningField }, ConflictResolution::ON_CONFLICT_IGNORE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 4);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 4);
auto values = GetColumnValues(result.results, returningField);
ASSERT_EQ(values.size(), 4);
for (size_t i = 0; i < values.size(); i++) {
int val = -1;
EXPECT_EQ(values[i].GetInt(val), E_OK);
EXPECT_EQ(val, i + (i >= 2));
}
}
* @tc.name: BatchInsert_003
* @tc.desc: abnormal test. batch insert with returning and conflict fail.
* When using the fail strategy, if the constraint is violated, the correct result cannot be obtained
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_003, TestSize.Level0)
{
std::vector<ValuesBucket> rows;
for (int i = 0; i < 5; i++) {
ValuesBucket row;
row.Put("id", i);
row.Put("name", "Jim");
rows.push_back(std::move(row));
}
ValuesBucket row;
row.Put("id", 2);
row.Put("name", "Jim");
auto res = store_->Insert("test", row);
ASSERT_EQ(res.first, E_OK);
ASSERT_EQ(res.second, 2);
auto [status, result] = store_->BatchInsert("test", rows, { "id" }, ConflictResolution::ON_CONFLICT_FAIL);
EXPECT_EQ(status, E_SQLITE_CONSTRAINT);
EXPECT_EQ(result.changed, 2);
EXPECT_EQ(result.results, nullptr);
}
* @tc.name: BatchInsert_004
* @tc.desc: abnormal test. batch insert with returning and conflict replace
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_004, TestSize.Level0)
{
std::vector<ValuesBucket> rows;
for (int i = 0; i < 5; i++) {
ValuesBucket row;
row.Put("id", i);
row.Put("name", "Jim");
rows.push_back(std::move(row));
}
ValuesBucket row;
row.Put("id", 2);
row.Put("name", "Jim");
auto res = store_->Insert("test", row);
ASSERT_EQ(res.first, E_OK);
ASSERT_EQ(res.second, 2);
std::string returningField = "id";
auto [status, result] = store_->BatchInsert(
"test", ValuesBuckets(std::move(rows)), { returningField }, ConflictResolution::ON_CONFLICT_REPLACE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 5);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 5);
auto values = GetColumnValues(result.results, returningField);
ASSERT_EQ(values.size(), 5);
for (size_t i = 0; i < 5; i++) {
int val = -1;
EXPECT_EQ(values[i].GetInt(val), E_OK);
EXPECT_EQ(val, i);
}
}
* @tc.name: BatchInsert_005
* @tc.desc: abnormal test. batch insert with over returning limit
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_005, TestSize.Level0)
{
ValuesBuckets rows;
rows.Reserve(1025);
for (int i = 0; i < 1025; i++) {
ValuesBucket row;
row.Put("id", i);
row.Put("name", "Jim");
rows.Put(std::move(row));
}
auto [status, result] = store_->BatchInsert("test", rows, { "id" }, ConflictResolution::ON_CONFLICT_REPLACE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1025);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 1024);
auto values = GetColumnValues(result.results, "id");
ASSERT_EQ(values.size(), 1024);
for (size_t i = 0; i < 1024; i++) {
EXPECT_EQ(int(values[i]), i);
}
}
* @tc.name: BatchInsert_006
* @tc.desc: abnormal test. batch insert with returning non-existent fields
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_006, TestSize.Level0)
{
ValuesBuckets rows;
for (int i = 0; i < 5; i++) {
ValuesBucket row;
row.Put("id", i);
row.Put("name", "Jim");
rows.Put(std::move(row));
}
std::string returningField = "notExist";
auto [status, result] =
store_->BatchInsert("test", rows, { returningField }, ConflictResolution::ON_CONFLICT_REPLACE);
EXPECT_EQ(status, E_SQLITE_ERROR);
EXPECT_EQ(result.changed, -1);
ASSERT_EQ(result.results, nullptr);
}
* @tc.name: BatchInsert_007
* @tc.desc: abnormal test. batch insert with returning and no changed rows
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_007, TestSize.Level0)
{
ValuesBuckets rows;
ValuesBucket row;
row.Put("id", 2);
row.Put("name", "Jim");
auto res = store_->Insert("test", row);
ASSERT_EQ(res.first, E_OK);
ASSERT_EQ(res.second, 2);
rows.Put(std::move(row));
auto [status, result] = store_->BatchInsert("test", rows, { "id" }, ConflictResolution::ON_CONFLICT_IGNORE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 0);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 0);
}
* @tc.name: BatchInsert_008
* @tc.desc: normal test. batch insert with returning rowId
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_008, TestSize.Level0)
{
ValuesBuckets rows;
ValuesBucket row;
row.Put("id", 2);
row.Put("name", "Jim");
rows.Put(std::move(row));
auto [status, result] = store_->BatchInsert("test", rows, { "rowId", "rowid", "RowId", "id" });
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 1);
RowEntity rowEntity;
EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
EXPECT_EQ(int(rowEntity.Get("id")), 2);
}
* @tc.name: BatchInsert_009
* @tc.desc: normal test. batch insert with returning *
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_009, TestSize.Level0)
{
ValuesBuckets rows;
ValuesBucket row;
row.Put("id", 2);
row.Put("name", "Jim");
row.Put("age", 18);
row.PutDouble("salary", 100.5);
std::vector<uint8_t> blob{ 1, 2, 3 };
row.PutBlob("blobType", blob);
rows.Put(std::move(row));
auto [status, result] =
store_->BatchInsert("test", rows, { "*" }, NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 1);
RowEntity rowEntity;
EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
EXPECT_EQ(int(rowEntity.Get("id")), 2);
EXPECT_EQ(std::string(rowEntity.Get("name")), "Jim");
EXPECT_EQ(int(rowEntity.Get("age")), 18);
EXPECT_NEAR(double(rowEntity.Get("salary")), 100.5, std::numeric_limits<double>::epsilon());
EXPECT_EQ(std::vector<uint8_t>(rowEntity.Get("blobType")), blob);
}
* @tc.name: BatchInsert_010
* @tc.desc: normal test. batch insert with returning complex field
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_010, TestSize.Level0)
{
ValuesBuckets rows;
ValuesBucket row;
row.Put("id", 2);
row.Put("name", "Jim");
row.PutDouble("salary", 100.5);
rows.Put(std::move(row));
auto [status, result] = store_->BatchInsert("test", rows, { "id", "name", "salary * 1.1 AS bonusSalary" },
NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 1);
RowEntity rowEntity;
EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
EXPECT_EQ(int(rowEntity.Get("id")), 2);
EXPECT_EQ(std::string(rowEntity.Get("name")), "Jim");
EXPECT_NEAR(double(rowEntity.Get("bonusSalary")), 100.5 * 1.1, std::numeric_limits<double>::epsilon());
}
* @tc.name: BatchInsert_011
* @tc.desc: normal test. batch insert with returning complex field
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_011, TestSize.Level1)
{
ValuesBuckets rows;
ValuesBucket row;
row.Put("id", 1);
row.Put("name", "Jim");
row.Put("age", 18);
row.PutDouble("salary", 110.5);
rows.Put(std::move(row));
row.Clear();
row.Put("id", 2);
row.Put("name", "Bob");
row.Put("age", 22);
row.PutDouble("salary", 90);
rows.Put(std::move(row));
auto [status, result] = store_->BatchInsert("test", rows,
{ "id", "name", "(salary < 100) AS lowSalary", "age > 18 as adult" },
NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 2);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 2);
RowEntity rowEntity;
EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
EXPECT_EQ(int(rowEntity.Get("id")), 1);
EXPECT_EQ(std::string(rowEntity.Get("name")), "Jim");
EXPECT_EQ(bool(rowEntity.Get("lowSalary")), false);
EXPECT_EQ(bool(rowEntity.Get("adult")), false);
EXPECT_EQ(result.results->GoToNextRow(), E_OK);
EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
EXPECT_EQ(int(rowEntity.Get("id")), 2);
EXPECT_EQ(std::string(rowEntity.Get("name")), "Bob");
EXPECT_EQ(bool(rowEntity.Get("lowSalary")), true);
EXPECT_EQ(bool(rowEntity.Get("adult")), true);
}
* @tc.name: BatchInsert_012
* @tc.desc: normal test. batch insert with returning function
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_012, TestSize.Level1)
{
ValuesBuckets rows;
ValuesBucket row;
row.Put("id", 20);
row.Put("name", "Jim");
row.PutDouble("salary", 100.5);
rows.Put(std::move(row));
auto [status, result] = store_->BatchInsert("test", rows, { "id", "name", "datetime('now') AS createdTime" },
NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 1);
RowEntity rowEntity;
EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
EXPECT_EQ(int(rowEntity.Get("id")), 20);
EXPECT_EQ(std::string(rowEntity.Get("name")), "Jim");
EXPECT_EQ(rowEntity.Get("createdTime").GetType(), ValueObject::TYPE_STRING);
EXPECT_FALSE(std::string(rowEntity.Get("createdTime")).empty());
}
* @tc.name: BatchInsert_013
* @tc.desc: normal test. batch insert into virtual table with returning
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_013, TestSize.Level1)
{
store_->Execute("CREATE VIRTUAL TABLE IF NOT EXISTS articles USING fts5(title, content);");
ValuesBuckets rows;
ValuesBucket row;
row.Put("title", "fts5");
row.Put("content", "test virtual tables");
rows.Put(std::move(row));
auto [status, result] =
store_->BatchInsert("articles", rows, { "title" }, NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 1);
RowEntity rowEntity;
EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
EXPECT_EQ(std::string(rowEntity.Get("title")), "fts5");
store_->Execute("Drop TABLE articles");
}
* @tc.name: BatchInsert_014
* @tc.desc: normal test. batch insert with returning and trigger
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_014, TestSize.Level1)
{
auto [code, result1] = store_->Execute("CREATE TRIGGER after_name_insert AFTER INSERT ON test"
" BEGIN UPDATE test SET name = 'after trigger' WHERE name = 'BatchInsert_014'; END");
EXPECT_EQ(code, E_OK);
ValuesBuckets rows;
ValuesBucket row;
row.Put("id", 200);
row.Put("name", "BatchInsert_014");
rows.Put(std::move(row));
auto [status, result] =
store_->BatchInsert("test", rows, { "name" }, NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 1);
RowEntity rowEntity;
EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
EXPECT_EQ(std::string(rowEntity.Get("name")), "BatchInsert_014");
auto resultSet = store_->QuerySql("select name from test where id = 200");
int rowCount = -1;
resultSet->GetRowCount(rowCount);
resultSet->GoToFirstRow();
EXPECT_EQ(resultSet->GetRow(rowEntity), E_OK);
EXPECT_EQ(std::string(rowEntity.Get("name")), "after trigger");
store_->Execute("DROP TRIGGER IF EXISTS after_name_insert");
}
* @tc.name: BatchInsert_015
* @tc.desc: normal test. batch insert with returning and sub query
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_015, TestSize.Level1)
{
store_->Execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT);");
store_->Execute("CREATE TABLE IF NOT EXISTS logs (id INTEGER PRIMARY KEY, action TEXT);");
ValuesBuckets rows;
ValuesBucket row;
row.Put("id", 200);
row.Put("action", "BatchInsert_015");
rows.Put(std::move(row));
auto [status, changed] = store_->BatchInsert("logs", rows);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(changed, 1);
Results result{ -1 };
row.Clear();
rows.Clear();
row.Put("id", 1);
row.Put("name", "BatchInsert_015");
rows.Put(std::move(row));
std::tie(status, result) = store_->BatchInsert("users", rows,
{ "(SELECT COUNT(*) FROM logs WHERE action = name) AS count" },
NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 1);
RowEntity rowEntity;
EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
EXPECT_EQ(int(rowEntity.Get("count")), 1);
store_->Execute("DROP TABLE users");
store_->Execute("DROP TABLE logs");
}
* @tc.name: BatchInsert_016
* @tc.desc: abnormal test. batch insert with max returning limit
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_016, TestSize.Level0)
{
int maxRowCount = 1024;
ValuesBuckets rows;
rows.Reserve(maxRowCount);
for (int i = 0; i < maxRowCount; i++) {
ValuesBucket row;
row.Put("id", i);
row.Put("name", "Jim");
rows.Put(std::move(row));
}
auto [status, result] =
store_->BatchInsert("test", ValuesBuckets(rows), {"id", "name"}, ConflictResolution::ON_CONFLICT_REPLACE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, maxRowCount);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, maxRowCount);
for (size_t i = 0; i < maxRowCount; i++) {
RowEntity rowEntity;
EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
EXPECT_EQ(int(rowEntity.Get("id")), i);
EXPECT_EQ(std::string(rowEntity.Get("name")), "Jim");
if (i != maxRowCount - 1) {
ASSERT_EQ(result.results->GoToNextRow(), E_OK);
}
}
}
* @tc.name: BatchInsert_017
* @tc.desc: abnormal test. batch insert with max returning limit
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_017, TestSize.Level0)
{
int maxRowCount = 1024;
ValuesBuckets rows;
rows.Reserve(maxRowCount);
for (int i = 0; i < maxRowCount; i++) {
ValuesBucket row;
row.Put("id", i);
row.Put("name", "Jim");
rows.Put(std::move(row));
}
auto [status, result] =
store_->BatchInsert("test", ValuesBuckets(rows), {"id", "name"}, ConflictResolution::ON_CONFLICT_REPLACE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, maxRowCount);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, maxRowCount);
std::tie(status, result) =
store_->ExecuteExt("UPDATE test SET name = 'Tim' WHERE name = 'Jim' RETURNING id, name");
EXPECT_EQ(result.changed, maxRowCount);
count = 0;
EXPECT_EQ(result.results->GetRowCount(count), E_OK);
EXPECT_EQ(count, maxRowCount);
for (size_t i = 0; i < maxRowCount; i++) {
RowEntity rowEntity;
EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
EXPECT_EQ(int(rowEntity.Get("id")), i);
EXPECT_EQ(std::string(rowEntity.Get("name")), "Tim");
if (i != maxRowCount - 1) {
ASSERT_EQ(result.results->GoToNextRow(), E_OK);
}
}
}
* @tc.name: BatchInsert_018
* @tc.desc: abnormal test. batch insert with max returning limit
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_018, TestSize.Level0)
{
int maxRowCount = 1024;
ValuesBuckets rows;
rows.Reserve(maxRowCount);
for (int i = 0; i < maxRowCount; i++) {
ValuesBucket row;
row.Put("id", i);
row.Put("name", "Jim");
rows.Put(std::move(row));
}
auto [status, result] =
store_->BatchInsert("test", ValuesBuckets(rows), {"id", "name"}, ConflictResolution::ON_CONFLICT_REPLACE);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, maxRowCount);
std::tie(status, result) =
store_->ExecuteExt("update test set name = ? where name = ?", { "Tim", "Jim" });
EXPECT_NE(result.results, nullptr);
EXPECT_EQ(result.changed, maxRowCount);
int32_t count = 0;
EXPECT_EQ(result.results->GetRowCount(count), E_OK);
EXPECT_EQ(count, 0);
}
* @tc.name: BatchInsert_019
* @tc.desc: normal test. batch insert with returning and trigger
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbStoreInsertTest, BatchInsert_019, TestSize.Level1)
{
auto [code, result1] = store_->Execute("CREATE TRIGGER after_name_insert AFTER INSERT ON test"
" BEGIN UPDATE test SET name = 'after trigger' WHERE name = 'BatchInsert_014'; END");
EXPECT_EQ(code, E_OK);
auto [status, result] =
store_->ExecuteExt("INSERT INTO test (id, name) VALUES (200, 'BatchInsert_014') RETURNING name;");
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1);
ASSERT_NE(result.results, nullptr);
int32_t count = 0;
ASSERT_EQ(result.results->GetRowCount(count), E_OK);
ASSERT_EQ(count, 1);
RowEntity rowEntity;
EXPECT_EQ(result.results->GetRow(rowEntity), E_OK);
EXPECT_EQ(std::string(rowEntity.Get("name")), "BatchInsert_014");
auto resultSet = store_->QuerySql("select name from test where id = 200");
int rowCount = -1;
resultSet->GetRowCount(rowCount);
resultSet->GoToFirstRow();
EXPECT_EQ(resultSet->GetRow(rowEntity), E_OK);
EXPECT_EQ(std::string(rowEntity.Get("name")), "after trigger");
store_->Execute("DROP TRIGGER IF EXISTS after_name_insert");
}
INSTANTIATE_TEST_SUITE_P(InsertTest, RdbStoreInsertTest, testing::Values(&g_store, &g_memDb));
}