|
|
- #include "gtest/gtest.h"
- #include "db/NewDB.h" // NewDB 的头文件
- #include "leveldb/env.h"
- #include "leveldb/db.h"
- #include <iostream>
-
- 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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();
- }
|