|
|
@ -1,292 +0,0 @@ |
|
|
|
#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(); |
|
|
|
} |