#include "gtest/gtest.h" #include "db/NewDB.h" // NewDB 的头文件 #include "leveldb/env.h" #include "leveldb/db.h" #include using namespace leveldb; // 打开数据库的辅助函数 Status OpenDB(std::string dbName, NewDB** db) { Options options = Options(); options.create_if_missing = true; return NewDB::Open(options, dbName, db); } std::string testdbname = "testdb11"; // 测试 NewDB::Put_fields 方法和二级索引的创建 TEST(TestNewDB, PutFieldsWithIndexTest) { // 创建 NewDB 实例 NewDB* db; if (OpenDB(testdbname, &db).ok() == false) { std::cerr << "open db failed" << std::endl; abort(); } // 创建索引字段 db->CreateIndexOnField("address"); // 定义插入的字段数据 std::string key1 = "k_1"; FieldArray fields1 = { {"name", "Customer#000000001"}, {"address", "IVhzIApeRb"}, {"phone", "25-989-741-2988"} }; // 定义字段数组,用于获取数据 FieldArray retrieved_fields; // 使用 NewDB::Put_fields 插入数据 db->Put_fields(WriteOptions(), key1, fields1); // // 检查索引是否成功创建 // EXPECT_TRUE(db->IsFieldIndexed("address")); // 检查字段是否已索引 // 获取并验证字段数据 db->Get_fields(ReadOptions(), key1, &retrieved_fields); EXPECT_EQ(retrieved_fields.size(), fields1.size()); // 验证插入的每个字段 for (size_t i = 0; i < fields1.size(); ++i) { EXPECT_EQ(fields1[i].first, retrieved_fields[i].first); // 字段名 EXPECT_EQ(fields1[i].second, retrieved_fields[i].second); // 字段值 } // 插入第二条数据 std::string key2 = "k_2"; FieldArray fields2 = { {"name", "Customer#000000002"}, {"address", "TXkjZEdIrZ"}, {"phone", "25-123-456-7890"} }; db->Put_fields(WriteOptions(), key2, fields2); // 获取并验证第二条数据 FieldArray retrieved_fields2; db->Get_fields(ReadOptions(), key2, &retrieved_fields2); EXPECT_EQ(retrieved_fields2.size(), fields2.size()); for (size_t i = 0; i < fields2.size(); ++i) { EXPECT_EQ(fields2[i].first, retrieved_fields2[i].first); // 字段名 EXPECT_EQ(fields2[i].second, retrieved_fields2[i].second); // 字段值 } // 清理数据库 delete db; } TEST(TestNewDB, DeleteDataTest) { // 创建 NewDB 实例 NewDB* db; ASSERT_TRUE(OpenDB(testdbname, &db).ok()); // 插入测试数据 std::string key = "k_3"; FieldArray fields = { {"name", "Customer#000000003"}, {"address", "AddressToDelete"}, {"phone", "25-789-123-4567"} }; ASSERT_TRUE(db->Put_fields(WriteOptions(), key, fields).ok()); // 删除数据 ASSERT_TRUE(db->Delete(WriteOptions(), key)); // 验证数据已被删除 FieldArray retrieved_fields; Status s = db->Get_fields(ReadOptions(), key, &retrieved_fields); ASSERT_FALSE(s.ok()); // 数据应该不存在 // 清理数据库 delete db; } TEST(TestNewDB, QueryByIndexTest) { // 创建 NewDB 实例 NewDB* db; ASSERT_TRUE(OpenDB(testdbname, &db).ok()); // 创建索引字段 db->CreateIndexOnField("address"); // 插入测试数据 std::string key1 = "k_4"; FieldArray fields1 = { {"name", "Customer#000000004"}, {"address", "AddressToFind"}, {"phone", "25-987-654-3210"} }; ASSERT_TRUE(db->Put_fields(WriteOptions(), key1, fields1).ok()); // 查询索引 Field field_to_query{"address", "AddressToFind"}; std::vector matching_keys = db->QueryByIndex(field_to_query); // 验证查询结果 ASSERT_EQ(matching_keys.size(), 1); EXPECT_EQ(matching_keys[0], key1); // 清理数据库 delete db; } TEST(TestNewDB, DeleteIndexTest) { // 创建 NewDB 实例 NewDB* db; ASSERT_TRUE(OpenDB(testdbname, &db).ok()); // 创建索引字段 db->CreateIndexOnField("address"); // 插入测试数据 std::string key1 = "k_5"; FieldArray fields1 = { {"name", "Customer#000000005"}, {"address", "AddressToDeleteIndex"}, {"phone", "25-123-456-7890"} }; ASSERT_TRUE(db->Put_fields(WriteOptions(), key1, fields1).ok()); // 删除索引 ASSERT_TRUE(db->DeleteIndex("address:AddressToDeleteIndex_k_5")); // 尝试查询已删除的索引 Field field_to_query{"address", "AddressToDeleteIndex"}; std::vector matching_keys = db->QueryByIndex(field_to_query); // 验证查询结果为空 EXPECT_TRUE(matching_keys.empty()); // 清理数据库 delete db; } TEST(TestNewDB, UpdateFieldsAndQueryIndexTest) { // 创建 NewDB 实例 NewDB* db; ASSERT_TRUE(OpenDB(testdbname, &db).ok()); // 创建索引字段 db->CreateIndexOnField("address"); // 插入初始数据 std::string key = "k_6"; FieldArray initial_fields = { {"name", "Customer#000000006"}, {"address", "InitialAddress"}, {"phone", "25-987-654-3210"} }; ASSERT_TRUE(db->Put_fields(WriteOptions(), key, initial_fields).ok()); // 验证初始数据的索引查询 Field query_field1{"address", "InitialAddress"}; std::vector matching_keys = db->QueryByIndex(query_field1); ASSERT_EQ(matching_keys.size(), 1); EXPECT_EQ(matching_keys[0], key); // 更新数据 FieldArray updated_fields = { {"name", "Customer#000000006"}, {"address", "UpdatedAddress"}, {"phone", "25-987-654-3210"} }; ASSERT_TRUE(db->Put_fields(WriteOptions(), key, updated_fields).ok()); // 获取并验证字段数据 FieldArray retrieved_fields; db->Get_fields(ReadOptions(), key, &retrieved_fields); EXPECT_EQ(retrieved_fields.size(), updated_fields.size()); // 验证插入的每个字段 for (size_t i = 0; i < updated_fields.size(); ++i) { EXPECT_EQ(updated_fields[i].first, retrieved_fields[i].first); // 字段名 EXPECT_EQ(updated_fields[i].second, retrieved_fields[i].second); // 字段值 } // 验证新的 address 字段值存在于索引中 Field query_field2{"address", "UpdatedAddress"}; matching_keys = db->QueryByIndex(query_field2); ASSERT_EQ(matching_keys.size(), 1); EXPECT_EQ(matching_keys[0], key); // 验证旧的 address 字段值不再存在于索引中 matching_keys = db->QueryByIndex(query_field1); ASSERT_EQ(matching_keys.size(), 0); EXPECT_TRUE(matching_keys.empty()); // 清理数据库 db->Delete(WriteOptions(), "k_1"); db->Delete(WriteOptions(), "k_2"); db->Delete(WriteOptions(), "k_3"); db->Delete(WriteOptions(), "k_4"); db->Delete(WriteOptions(), "k_5"); db->Delete(WriteOptions(), "k_6"); delete db; } TEST(TestNewDB, CreateIndexOnExistingDataTest) { // 创建 NewDB 实例 NewDB* db; ASSERT_TRUE(OpenDB(testdbname, &db).ok()); // 插入一些测试数据(没有索引的情况下) std::string key1 = "k_1"; FieldArray fields1 = { {"name", "Customer#000000001"}, {"address", "IVhzIApeRb"}, {"phone", "25-989-741-2988"} }; ASSERT_TRUE(db->Put_fields(WriteOptions(), key1, fields1).ok()); std::string key2 = "k_2"; FieldArray fields2 = { {"name", "Customer#000000002"}, {"address", "TXkjZEdIrZ"}, {"phone", "25-123-456-7890"} }; ASSERT_TRUE(db->Put_fields(WriteOptions(), key2, fields2).ok()); std::string key3 = "k_3"; FieldArray fields3 = { {"name", "Customer#000000003"}, {"address", "IVhzIApeRb"}, // 相同地址字段值 {"phone", "25-789-123-4567"} }; ASSERT_TRUE(db->Put_fields(WriteOptions(), key3, fields3).ok()); // 创建索引字段 'address' ASSERT_TRUE(db->CreateIndexOnField("address")); // 查询索引字段 'address' 的数据,验证它能正确索引已有的数据 Field field_to_query{"address", "IVhzIApeRb"}; std::vector matching_keys = db->QueryByIndex(field_to_query); // 验证索引查询结果 ASSERT_EQ(matching_keys.size(), 2); // 预期查询到两个相同地址的记录 EXPECT_TRUE(std::find(matching_keys.begin(), matching_keys.end(), key1) != matching_keys.end()); EXPECT_TRUE(std::find(matching_keys.begin(), matching_keys.end(), key3) != matching_keys.end()); field_to_query.second = "TXkjZEdIrZ"; // 另一个地址值 matching_keys = db->QueryByIndex(field_to_query); // 验证查询结果 ASSERT_EQ(matching_keys.size(), 1); // 预期只有一个结果 EXPECT_EQ(matching_keys[0], key2); // 清理数据库 db->Delete(WriteOptions(), key1); db->Delete(WriteOptions(), key2); db->Delete(WriteOptions(), key3); delete db; } // 主函数运行所有测试 int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }