* 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_errno.h"
#include "rdb_helper.h"
#include "rdb_open_callback.h"
#include "value_object.h"
using namespace testing::ext;
using namespace OHOS::NativeRdb;
namespace OHOS::RdbExecuteTest {
struct RdbTestParam {
std::shared_ptr<RdbStore> store;
std::string mode;
operator std::shared_ptr<RdbStore>()
{
return store;
}
};
static RdbTestParam g_store;
static RdbTestParam g_memDb;
class RdbExecuteTest : public testing::TestWithParam<RdbTestParam *> {
public:
static void SetUpTestCase(void);
static void TearDownTestCase(void);
void SetUp();
void TearDown();
std::shared_ptr<RdbStore> store_;
static const std::string DATABASE_NAME;
};
constexpr const char *CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test "
"(id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER, salary REAL, "
"blobType BLOB)";
const std::string RdbExecuteTest::DATABASE_NAME = RDB_TEST_PATH + "execute_test.db";
class ExecuteTestOpenCallback : public RdbOpenCallback {
public:
int OnCreate(RdbStore &store) override;
int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
};
int ExecuteTestOpenCallback::OnCreate(RdbStore &store)
{
return E_OK;
}
int ExecuteTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
{
return E_OK;
}
void RdbExecuteTest::SetUpTestCase(void)
{
int errCode = E_OK;
RdbHelper::DeleteRdbStore(DATABASE_NAME);
RdbStoreConfig config(RdbExecuteTest::DATABASE_NAME);
ExecuteTestOpenCallback helper;
g_store.store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(g_store.store, nullptr);
g_store.mode = "wal";
config.SetStorageMode(StorageMode::MODE_MEMORY);
g_memDb.store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(g_memDb.store, nullptr);
g_memDb.mode = "memory";
}
void RdbExecuteTest::TearDownTestCase(void)
{
RdbStoreConfig config(RdbExecuteTest::DATABASE_NAME);
RdbHelper::DeleteRdbStore(config);
config.SetStorageMode(StorageMode::MODE_MEMORY);
RdbHelper::DeleteRdbStore(config);
}
void RdbExecuteTest::SetUp(void)
{
store_ = *GetParam();
ASSERT_NE(store_, nullptr);
store_->ExecuteSql(CREATE_TABLE_TEST);
}
void RdbExecuteTest::TearDown(void)
{
store_ = *GetParam();
ASSERT_NE(store_, nullptr);
store_->ExecuteSql("DROP TABLE test");
}
* @tc.name: RdbStore_Execute_001
* @tc.desc: test RdbStore Execute
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_001, TestSize.Level1)
{
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", 19);
values.PutDouble("salary", 200.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6 });
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("wangyjing"));
values.PutInt("age", 20);
values.PutDouble("salary", 300.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 7, 8, 9 });
ret = store_->Insert(id, "test", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(3, id);
int64_t count;
ret = store_->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(count, 3);
ret = store_->ExecuteSql("DELETE FROM test WHERE age = ? OR age = ?",
std::vector<ValueObject>{ ValueObject(std::string("18")), ValueObject(std ::string("20")) });
EXPECT_EQ(ret, E_OK);
ret = store_->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test where age = 19");
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(count, 1);
ret = store_->ExecuteSql("DELETE FROM test WHERE age = 19");
EXPECT_EQ(ret, E_OK);
ret = store_->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(count, 0);
}
* @tc.name: RdbStore_Execute_002
* @tc.desc: test RdbStore Execute
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_002, TestSize.Level1)
{
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);
ret = store_->Insert(id, "test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[1]));
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
ret = store_->Insert(id, "test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[2]));
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(3, id);
int64_t count;
ret = store_->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test", std::vector<ValueObject>());
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(count, 3);
ret = store_->ExecuteSql("DELETE FROM test WHERE age = ? OR age = ?",
std::vector<ValueObject>{ ValueObject(std::string("18")), ValueObject(std ::string("20")) });
EXPECT_EQ(ret, E_OK);
ret = store_->ExecuteAndGetLong(
count, "SELECT COUNT(*) FROM test where age = ?", std::vector<ValueObject>{ ValueObject(std::string("19")) });
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(count, 1);
ret = store_->ExecuteSql("DELETE FROM test WHERE age = 19");
EXPECT_EQ(ret, E_OK);
ret = store_->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test", std::vector<ValueObject>());
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(count, 0);
ret = store_->ExecuteSql("DROP TABLE IF EXISTS test");
EXPECT_EQ(ret, E_OK);
ret = store_->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
EXPECT_EQ(ret, E_SQLITE_ERROR);
}
* @tc.name: RdbStore_Execute_003
* @tc.desc: test RdbStore Execute
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_003, TestSize.Level1)
{
int64_t pageSize;
int ret = store_->ExecuteAndGetLong(pageSize, "PRAGMA page_size");
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(pageSize, 4096);
int64_t journalSize;
ret = store_->ExecuteAndGetLong(journalSize, "PRAGMA journal_size_limit");
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(journalSize, 1048576);
std::string journalMode;
ret = store_->ExecuteAndGetString(journalMode, "PRAGMA journal_mode");
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(journalMode, GetParam()->mode);
}
* @tc.name: RdbStore_Execute_004
* @tc.desc: Abnormal testCase for ExecuteAndGetString, if sqlstatementtype is special
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_004, TestSize.Level4)
{
std::shared_ptr<RdbStore> store = *GetParam();
std::string outValue;
int ret = store_->ExecuteAndGetString(outValue, "BEGIN;");
EXPECT_NE(E_OK, ret);
}
* @tc.name: RdbStore_Execute_005
* @tc.desc: Abnormal testCase for ExecuteForLastInsertedRowId, if sql is invalid
* @tc.type: FUNC
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_005, TestSize.Level4)
{
int64_t outValue;
int ret = store_->ExecuteForLastInsertedRowId(outValue, "", {});
EXPECT_NE(E_OK, ret);
}
* @tc.name: RdbStore_Execute_006
* @tc.desc: Abnormal testCase for ExecuteForChangedRowCount, if sql is invalid
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_006, TestSize.Level4)
{
int64_t outValue;
int ret = store_->ExecuteForChangedRowCount(outValue, "", {});
EXPECT_NE(E_OK, ret);
}
* @tc.name: RdbStore_Execute_007
* @tc.desc: Normal testCase for ExecuteAndGetString, check integrity for store
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_007, TestSize.Level1)
{
auto [ret, outValue] = store_->Execute("PRAGMA integrity_check");
EXPECT_EQ(E_OK, ret);
EXPECT_EQ(ValueObjectType::TYPE_STRING, outValue.GetType());
std::string outputResult;
outValue.GetString(outputResult);
EXPECT_EQ("ok", outputResult);
}
* @tc.name: RdbStore_Execute_008
* @tc.desc: Normal testCase for Execute, check integrity for store
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_008, TestSize.Level1)
{
auto [ret, outValue] = store_->Execute("PRAGMA quick_check");
EXPECT_EQ(E_OK, ret);
EXPECT_EQ(ValueObjectType::TYPE_STRING, outValue.GetType());
std::string outputResult;
outValue.GetString(outputResult);
EXPECT_EQ("ok", outputResult);
}
* @tc.name: RdbStore_Execute_009
* @tc.desc: Normal testCase for Execute, get user_version of store
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_009, TestSize.Level1)
{
store_->SetVersion(5);
auto [ret, outValue] = store_->Execute("PRAGMA user_version");
EXPECT_EQ(E_OK, ret);
EXPECT_EQ(ValueObjectType::TYPE_INT, outValue.GetType());
int64_t outputResult{ 0 };
outValue.GetLong(outputResult);
EXPECT_EQ(5, outputResult);
store_->SetVersion(0);
}
* @tc.name: RdbStore_Execute_0010
* @tc.desc: AbNormal testCase for Execute, execute select sql
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0010, TestSize.Level1)
{
auto [ret, outValue] = store_->Execute("SELECT * FROM test");
EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret);
auto [code, result] = store_->ExecuteExt("SELECT * FROM test");
EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, code);
}
* @tc.name: RdbStore_Execute_0011
* @tc.desc: Normal testCase for Execute, execute sql for inserting data
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0011, TestSize.Level1)
{
std::vector<ValueObject> args = { ValueObject(std::string("tt")), ValueObject(int(28)),
ValueObject(double(50000.0)) };
auto [ret, outValue] = store_->Execute("INSERT INTO test(name, age, salary) VALUES (?, ?, ?);", args);
EXPECT_EQ(E_OK, ret);
EXPECT_EQ(ValueObjectType::TYPE_INT, outValue.GetType());
int64_t outputResult;
outValue.GetLong(outputResult);
EXPECT_EQ(1, outputResult);
}
* @tc.name: RdbStore_Execute_0012
* @tc.desc: Normal testCase for Execute, execute sql for batch insert data
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0012, TestSize.Level1)
{
std::vector<ValueObject> args = { ValueObject(std::string("tt")), ValueObject(int(28)),
ValueObject(double(50000.0)), ValueObject(std::string("ttt")), ValueObject(int(58)),
ValueObject(double(500080.0)) };
auto [ret, outValue] = store_->Execute("INSERT INTO test(name, age, salary) VALUES (?, ?, ?), (?, ?, ?)", args);
EXPECT_EQ(E_OK, ret);
EXPECT_EQ(ValueObjectType::TYPE_INT, outValue.GetType());
int64_t outputResult;
outValue.GetLong(outputResult);
EXPECT_EQ(2, outputResult);
}
* @tc.name: RdbStore_Execute_0013
* @tc.desc: Normal testCase for Execute, execute sql for updating data
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0013, TestSize.Level1)
{
std::vector<ValueObject> args = { ValueObject(std::string("tt")), ValueObject(int(28)),
ValueObject(double(50000.0)), ValueObject(std::string("ttt")), ValueObject(int(58)),
ValueObject(double(500080.0)) };
auto [ret1, outValue1] = store_->Execute("INSERT INTO test(name, age, salary) VALUES (?, ?, ?), (?, ?, ?)", args);
EXPECT_EQ(E_OK, ret1);
EXPECT_EQ(ValueObjectType::TYPE_INT, outValue1.GetType());
int64_t outputResult;
outValue1.GetLong(outputResult);
EXPECT_EQ(2, outputResult);
auto [ret2, outValue2] = store_->Execute("UPDATE test SET name='dd' WHERE id = 2");
EXPECT_EQ(E_OK, ret2);
EXPECT_EQ(ValueObjectType::TYPE_INT, outValue2.GetType());
outValue2.GetLong(outputResult);
EXPECT_EQ(1, outputResult);
}
* @tc.name: RdbStore_Execute_0014
* @tc.desc: Normal testCase for Execute, execute sql for deleting data
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0014, TestSize.Level1)
{
std::vector<ValueObject> args = { ValueObject(std::string("tt")), ValueObject(int(28)),
ValueObject(double(50000.0)), ValueObject(std::string("ttt")), ValueObject(int(82)),
ValueObject(double(500080.0)) };
auto [ret1, outValue1] = store_->Execute("INSERT INTO test(name, age, salary) VALUES (?, ?, ?), (?, ?, ?)", args);
EXPECT_EQ(E_OK, ret1);
EXPECT_EQ(ValueObjectType::TYPE_INT, outValue1.GetType());
int64_t outputResult;
outValue1.GetLong(outputResult);
EXPECT_EQ(2, outputResult);
auto [ret2, outValue2] = store_->Execute("DELETE FROM test");
EXPECT_EQ(E_OK, ret2);
EXPECT_EQ(ValueObjectType::TYPE_INT, outValue2.GetType());
outValue2.GetLong(outputResult);
EXPECT_EQ(2, outputResult);
}
* @tc.name: RdbStore_Execute_0015
* @tc.desc: AbNormal testCase for Execute, execute sql for attaching database and transaction
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0015, TestSize.Level1)
{
auto [ret1, outValue1] = store_->Execute("ATTACH DATABASE 'execute_attach_test.db' AS 'attach.db'");
EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret1);
auto [ret2, outValue2] = store_->Execute("DETACH DATABASE 'attach.db'");
EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret2);
auto [ret3, outValue3] = store_->Execute("BEGIN TRANSACTION");
EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret3);
auto [ret4, outValue4] = store_->Execute("COMMIT");
EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret4);
auto [ret5, outValue5] = store_->Execute("ROLLBACK");
EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret5);
auto [ret6, outValue6] = store_->ExecuteExt("ROLLBACK");
EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret6);
}
* @tc.name: RdbStore_Execute_0016
* @tc.desc: Normal testCase for Execute, execute DDL sql for creating and dropping table
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0016, TestSize.Level1)
{
int64_t intOutValue;
constexpr const char *CREATE_TABLE_TEST2 = "CREATE TABLE IF NOT EXISTS test2 "
"(id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER, salary REAL, "
"blobType BLOB)";
constexpr const char *DROP_TABLE_TEST2 = "DROP TABLE test2";
constexpr const char *TEST_TABLE_IS_EXIST =
"SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='test2'";
auto [ret1, outValue1] = store_->Execute(CREATE_TABLE_TEST2);
EXPECT_EQ(E_OK, ret1);
EXPECT_EQ(ValueObjectType::TYPE_NULL, outValue1.GetType());
std::shared_ptr<ResultSet> resultSet = store_->QuerySql(TEST_TABLE_IS_EXIST);
EXPECT_NE(nullptr, resultSet);
resultSet->GoToFirstRow();
resultSet->GetLong(0, intOutValue);
EXPECT_EQ(1, intOutValue);
resultSet->Close();
auto [ret2, outValue2] = store_->ExecuteExt(DROP_TABLE_TEST2);
EXPECT_EQ(E_OK, ret2);
EXPECT_EQ(0, outValue2.changed);
int rowCount = -1;
outValue2.results->GetRowCount(rowCount);
EXPECT_EQ(0, rowCount);
resultSet = store_->QuerySql(TEST_TABLE_IS_EXIST);
EXPECT_NE(nullptr, resultSet);
resultSet->GoToFirstRow();
resultSet->GetLong(0, intOutValue);
EXPECT_EQ(0, intOutValue);
resultSet->Close();
}
* @tc.name: RdbStore_Execute_0017
* @tc.desc: Normal testCase for Execute, execute sql for creating table and insert, query data
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0017, TestSize.Level1)
{
int64_t intOutValue;
int intOutResultSet;
constexpr const char *CREATE_TABLE_TEST2 = "CREATE TABLE IF NOT EXISTS test2 "
"(id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER, salary REAL, "
"blobType BLOB)";
constexpr const char *DROP_TABLE_TEST2 = "DROP TABLE test2";
auto [ret1, outValue1] = store_->Execute(CREATE_TABLE_TEST2);
EXPECT_EQ(E_OK, ret1);
std::vector<ValueObject> args = { ValueObject("tt"), ValueObject(28), ValueObject(50000) };
auto [ret2, outValue2] = store_->Execute("INSERT INTO test2(name, age, salary) VALUES (?, ?, ?)", args);
EXPECT_EQ(E_OK, ret2);
outValue2.GetLong(intOutValue);
EXPECT_EQ(1, intOutValue);
std::shared_ptr<ResultSet> resultSet = store_->QuerySql("SELECT * FROM test2");
EXPECT_NE(nullptr, resultSet);
EXPECT_EQ(E_OK, resultSet->GetRowCount(intOutResultSet));
EXPECT_EQ(1, intOutResultSet);
resultSet->Close();
auto [ret3, outValue3] = store_->Execute(DROP_TABLE_TEST2);
EXPECT_EQ(E_OK, ret3);
}
* @tc.name: RdbStore_Execute_0018
* @tc.desc: AbNormal testCase for Execute, execute sql for inserting data but args is []
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0018, TestSize.Level1)
{
ValueObject outValue;
auto [ret1, outValue1] = store_->Execute("INSERT INTO test(name, age, salary) VALUES (?, ?, ?), (?, ?, ?)");
EXPECT_NE(E_OK, ret1);
}
* @tc.name: RdbStore_Execute_0019
* @tc.desc: Normal testCase for Execute, set user_version of store
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0019, TestSize.Level1)
{
auto [ret, outValue] = store_->Execute("PRAGMA user_version=5");
EXPECT_EQ(E_OK, ret);
EXPECT_EQ(ValueObjectType::TYPE_NULL, outValue.GetType());
std::tie(ret, outValue) = store_->Execute("PRAGMA user_version=0");
EXPECT_EQ(E_OK, ret);
EXPECT_EQ(ValueObjectType::TYPE_NULL, outValue.GetType());
}
* @tc.name: RdbStore_Execute_0020
* @tc.desc: AbNormal testCase for Execute, get table_info
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0020, TestSize.Level1)
{
auto [ret, outValue] = store_->Execute("PRAGMA table_info(test)");
EXPECT_EQ(E_NOT_SUPPORT_THE_SQL, ret);
}
* @tc.name: RdbStore_Execute_0021
* @tc.desc: Normal testCase for Execute insert, update and delete 2 rows with returning
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0021, TestSize.Level1)
{
std::vector<ValueObject> args = { "tt", 28, 50000.0, "ttt", 58, 500080.0 };
auto [status, result] =
store_->ExecuteExt("INSERT INTO test(name, age, salary) VALUES (?, ?, ?), (?, ?, ?) returning name", args);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 2);
int rowCount = -1;
ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
ASSERT_EQ(rowCount, 2);
int columnIndex = -1;
ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
std::string value;
ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
EXPECT_EQ(value, "tt");
ASSERT_EQ(result.results->GoToNextRow(), E_OK);
ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
EXPECT_EQ(value, "ttt");
std::tie(status, result) =
store_->ExecuteExt("update test set name = ? where name = ? returning name", {"update", "tt"});
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1);
rowCount = -1;
ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
ASSERT_EQ(rowCount, 1);
ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
EXPECT_EQ(value, "update");
std::tie(status, result) = store_->ExecuteExt("delete from test returning name");
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 2);
rowCount = -1;
ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
ASSERT_EQ(rowCount, 2);
ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
EXPECT_EQ(value, "update");
ASSERT_EQ(result.results->GoToNextRow(), E_OK);
ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
EXPECT_EQ(value, "ttt");
}
* @tc.name: RdbStore_Execute_0022
* @tc.desc: Normal testCase for Execute insert, update and delete over limit with returning
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0022, TestSize.Level1)
{
std::vector<ValueObject> args = { "0", 0 };
std::string sql = "INSERT INTO test(name, age) VALUES (?, ?)";
for (int32_t i = 1; i < 1025; i++) {
sql.append(", (?, ?)");
args.push_back(std::to_string(i));
args.push_back(i);
}
auto [status, result] = store_->ExecuteExt(sql + " returning name", args);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1025);
int rowCount = -1;
ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
ASSERT_EQ(rowCount, 1024);
int columnIndex = -1;
ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
std::string value;
ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
EXPECT_EQ(value, "0");
ASSERT_EQ(result.results->GoToRow(1000), E_OK);
ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
EXPECT_EQ(value, "1000");
std::tie(status, result) = store_->ExecuteExt("update test set name = ? returning name", { "update" });
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1025);
rowCount = -1;
ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
ASSERT_EQ(rowCount, 1024);
ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
EXPECT_EQ(value, "update");
std::tie(status, result) = store_->ExecuteExt("delete from test returning name");
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1025);
rowCount = -1;
ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
ASSERT_EQ(rowCount, 1024);
ASSERT_EQ(result.results->GetColumnIndex("name", columnIndex), E_OK);
ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
EXPECT_EQ(value, "update");
}
* @tc.name: RdbStore_Execute_0023
* @tc.desc: normal testCase for Execute insert, update and delete 0 rows with returning
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0023, TestSize.Level1)
{
std::vector<ValueObject> args = { 1, "tt", 28, 50000.0 };
auto [status, result] =
store_->ExecuteExt("INSERT INTO test(id, name, age, salary) VALUES (?, ?, ?, ?) returning id", args);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1);
int rowCount = -1;
ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
ASSERT_EQ(rowCount, 1);
int columnIndex = -1;
ASSERT_EQ(result.results->GetColumnIndex("id", columnIndex), E_OK);
int64_t value;
ASSERT_EQ(result.results->GetLong(columnIndex, value), E_OK);
EXPECT_EQ(value, 1);
std::tie(status, result) =
store_->ExecuteExt("INSERT INTO test(id, name, age, salary) VALUES (?, ?, ?, ?) returning id", args);
EXPECT_EQ(status, E_SQLITE_CONSTRAINT);
EXPECT_EQ(result.changed, 0);
rowCount = -1;
ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
ASSERT_EQ(rowCount, 0);
std::tie(status, result) =
store_->ExecuteExt("update test set name = ? where name = ? returning name", { "update", "noExist" });
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 0);
rowCount = -1;
ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
ASSERT_EQ(rowCount, 0);
std::tie(status, result) = store_->ExecuteExt("delete from test where name = ? returning name", { "noExist" });
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 0);
rowCount = -1;
ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
ASSERT_EQ(rowCount, 0);
}
* @tc.name: RdbStore_Execute_0024
* @tc.desc: abnormal testCase for Execute insert, update and delete with returning field not exist
* @tc.type: FUNC
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0024, TestSize.Level1)
{
std::vector<ValueObject> args = { 1, "tt", 28, 50000.0 };
auto [status, result] =
store_->ExecuteExt("INSERT INTO test(id, name, age, salary) VALUES (?, ?, ?, ?) returning noExist", args);
EXPECT_EQ(status, E_SQLITE_ERROR);
EXPECT_EQ(result.changed, -1);
ASSERT_EQ(result.results, nullptr);
std::tie(status, result) =
store_->ExecuteExt("update test set name = ? where name = ? returning noExist", { "update", "noExist" });
EXPECT_EQ(status, E_SQLITE_ERROR);
EXPECT_EQ(result.changed, -1);
ASSERT_EQ(result.results, nullptr);
std::tie(status, result) = store_->ExecuteExt("delete from test where name = ? returning noExist", { "noExist" });
EXPECT_EQ(status, E_SQLITE_ERROR);
EXPECT_EQ(result.changed, -1);
ASSERT_EQ(result.results, nullptr);
}
* @tc.name: RdbStore_Execute_0025
* @tc.desc: normal test. batch insert into virtual table with returning
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0025, TestSize.Level1)
{
store_->Execute("CREATE VIRTUAL TABLE IF NOT EXISTS articles USING fts5(title, content);");
std::vector<ValueObject> args = { "title", "content" };
auto [status, result] =
store_->ExecuteExt("INSERT INTO articles(title, content) VALUES (?, ?) returning title", args);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(result.changed, 1);
int rowCount = -1;
ASSERT_EQ(result.results->GetRowCount(rowCount), E_OK);
ASSERT_EQ(rowCount, 1);
int columnIndex = -1;
ASSERT_EQ(result.results->GetColumnIndex("title", columnIndex), E_OK);
std::string value;
ASSERT_EQ(result.results->GetString(columnIndex, value), E_OK);
EXPECT_EQ(value, "title");
std::vector<ValueObject> args2 = { "title2", "title" };
std::tie(status, result) =
store_->ExecuteExt("UPDATE articles set title = ? where title = ? returning title", args2);
EXPECT_EQ(status, E_SQLITE_ERROR);
EXPECT_EQ(result.changed, -1);
ASSERT_EQ(result.results, nullptr);
std::tie(status, result) = store_->ExecuteExt("DELETE FROM articles where title = ? returning title", { "title" });
EXPECT_EQ(status, E_SQLITE_ERROR);
EXPECT_EQ(result.changed, -1);
ASSERT_EQ(result.results, nullptr);
store_->Execute("Drop TABLE articles");
}
* @tc.name: RdbStore_Execute_0026
* @tc.desc: normal test. create trigger before update, delete data in trigger, then update data
* @tc.type: FUNC
* @tc.require:
* @tc.author:
*/
HWTEST_P(RdbExecuteTest, RdbStore_Execute_0026, TestSize.Level1)
{
auto [code, result1] = store_->Execute(
"CREATE TRIGGER before_update BEFORE UPDATE ON test"
" BEGIN DELETE FROM test WHERE name = 'wang'; END");
EXPECT_EQ(code, E_OK);
ValuesBuckets rows;
ValuesBucket row;
row.Put("id", 200);
row.Put("name", "wang");
rows.Put(std::move(row));
row.Put("id", 201);
row.Put("name", "zhang");
rows.Put(std::move(row));
auto [insertStatus, insertResult] =
store_->BatchInsert("test", rows, { "name" }, NativeRdb::ConflictResolution::ON_CONFLICT_IGNORE);
EXPECT_EQ(insertStatus, E_OK);
EXPECT_EQ(insertResult.changed, 2);
std::vector<ValueObject> args2 = { "liu", "zhang" };
auto [status, res] =
store_->ExecuteExt("UPDATE test set name = ? where name = ? returning name", args2);
EXPECT_EQ(status, E_OK);
EXPECT_EQ(res.changed, 1);
int rowCount = -1;
ASSERT_EQ(res.results->GetRowCount(rowCount), E_OK);
ASSERT_EQ(rowCount, 1);
int columnIndex = -1;
ASSERT_EQ(res.results->GetColumnIndex("name", columnIndex), E_OK);
std::string value;
ASSERT_EQ(res.results->GetString(columnIndex, value), E_OK);
EXPECT_EQ(value, "liu");
auto resultSet = store_->QuerySql("select name from test where id = 200");
rowCount = -1;
resultSet->GetRowCount(rowCount);
ASSERT_EQ(rowCount, 0);
store_->Execute("DROP TRIGGER IF EXISTS before_update");
}
INSTANTIATE_TEST_SUITE_P(ExecuteTest, RdbExecuteTest, testing::Values(&g_store, &g_memDb));
}