成员:陈予曈,朱陈媛
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

292 lines
8.8 KiB

  1. #include "gtest/gtest.h"
  2. #include "db/NewDB.h" // NewDB 的头文件
  3. #include "leveldb/env.h"
  4. #include "leveldb/db.h"
  5. #include <iostream>
  6. using namespace leveldb;
  7. // 打开数据库的辅助函数
  8. Status OpenDB(std::string dbName, NewDB** db) {
  9. Options options = Options();
  10. options.create_if_missing = true;
  11. return NewDB::Open(options, dbName, db);
  12. }
  13. std::string testdbname = "testdb11";
  14. // 测试 NewDB::Put_fields 方法和二级索引的创建
  15. TEST(TestNewDB, PutFieldsWithIndexTest) {
  16. // 创建 NewDB 实例
  17. NewDB* db;
  18. if (OpenDB(testdbname, &db).ok() == false) {
  19. std::cerr << "open db failed" << std::endl;
  20. abort();
  21. }
  22. // 创建索引字段
  23. db->CreateIndexOnField("address");
  24. // 定义插入的字段数据
  25. std::string key1 = "k_1";
  26. FieldArray fields1 = {
  27. {"name", "Customer#000000001"},
  28. {"address", "IVhzIApeRb"},
  29. {"phone", "25-989-741-2988"}
  30. };
  31. // 定义字段数组,用于获取数据
  32. FieldArray retrieved_fields;
  33. // 使用 NewDB::Put_fields 插入数据
  34. db->Put_fields(WriteOptions(), key1, fields1);
  35. // // 检查索引是否成功创建
  36. // EXPECT_TRUE(db->IsFieldIndexed("address")); // 检查字段是否已索引
  37. // 获取并验证字段数据
  38. db->Get_fields(ReadOptions(), key1, &retrieved_fields);
  39. EXPECT_EQ(retrieved_fields.size(), fields1.size());
  40. // 验证插入的每个字段
  41. for (size_t i = 0; i < fields1.size(); ++i) {
  42. EXPECT_EQ(fields1[i].first, retrieved_fields[i].first); // 字段名
  43. EXPECT_EQ(fields1[i].second, retrieved_fields[i].second); // 字段值
  44. }
  45. // 插入第二条数据
  46. std::string key2 = "k_2";
  47. FieldArray fields2 = {
  48. {"name", "Customer#000000002"},
  49. {"address", "TXkjZEdIrZ"},
  50. {"phone", "25-123-456-7890"}
  51. };
  52. db->Put_fields(WriteOptions(), key2, fields2);
  53. // 获取并验证第二条数据
  54. FieldArray retrieved_fields2;
  55. db->Get_fields(ReadOptions(), key2, &retrieved_fields2);
  56. EXPECT_EQ(retrieved_fields2.size(), fields2.size());
  57. for (size_t i = 0; i < fields2.size(); ++i) {
  58. EXPECT_EQ(fields2[i].first, retrieved_fields2[i].first); // 字段名
  59. EXPECT_EQ(fields2[i].second, retrieved_fields2[i].second); // 字段值
  60. }
  61. // 清理数据库
  62. delete db;
  63. }
  64. TEST(TestNewDB, DeleteDataTest) {
  65. // 创建 NewDB 实例
  66. NewDB* db;
  67. ASSERT_TRUE(OpenDB(testdbname, &db).ok());
  68. // 插入测试数据
  69. std::string key = "k_3";
  70. FieldArray fields = {
  71. {"name", "Customer#000000003"},
  72. {"address", "AddressToDelete"},
  73. {"phone", "25-789-123-4567"}
  74. };
  75. ASSERT_TRUE(db->Put_fields(WriteOptions(), key, fields).ok());
  76. // 删除数据
  77. ASSERT_TRUE(db->Delete(WriteOptions(), key));
  78. // 验证数据已被删除
  79. FieldArray retrieved_fields;
  80. Status s = db->Get_fields(ReadOptions(), key, &retrieved_fields);
  81. ASSERT_FALSE(s.ok()); // 数据应该不存在
  82. // 清理数据库
  83. delete db;
  84. }
  85. TEST(TestNewDB, QueryByIndexTest) {
  86. // 创建 NewDB 实例
  87. NewDB* db;
  88. ASSERT_TRUE(OpenDB(testdbname, &db).ok());
  89. // 创建索引字段
  90. db->CreateIndexOnField("address");
  91. // 插入测试数据
  92. std::string key1 = "k_4";
  93. FieldArray fields1 = {
  94. {"name", "Customer#000000004"},
  95. {"address", "AddressToFind"},
  96. {"phone", "25-987-654-3210"}
  97. };
  98. ASSERT_TRUE(db->Put_fields(WriteOptions(), key1, fields1).ok());
  99. // 查询索引
  100. Field field_to_query{"address", "AddressToFind"};
  101. std::vector<std::string> matching_keys = db->QueryByIndex(field_to_query);
  102. // 验证查询结果
  103. ASSERT_EQ(matching_keys.size(), 1);
  104. EXPECT_EQ(matching_keys[0], key1);
  105. // 清理数据库
  106. delete db;
  107. }
  108. TEST(TestNewDB, DeleteIndexTest) {
  109. // 创建 NewDB 实例
  110. NewDB* db;
  111. ASSERT_TRUE(OpenDB(testdbname, &db).ok());
  112. // 创建索引字段
  113. db->CreateIndexOnField("address");
  114. // 插入测试数据
  115. std::string key1 = "k_5";
  116. FieldArray fields1 = {
  117. {"name", "Customer#000000005"},
  118. {"address", "AddressToDeleteIndex"},
  119. {"phone", "25-123-456-7890"}
  120. };
  121. ASSERT_TRUE(db->Put_fields(WriteOptions(), key1, fields1).ok());
  122. // 删除索引
  123. ASSERT_TRUE(db->DeleteIndex("address:AddressToDeleteIndex_k_5"));
  124. // 尝试查询已删除的索引
  125. Field field_to_query{"address", "AddressToDeleteIndex"};
  126. std::vector<std::string> matching_keys = db->QueryByIndex(field_to_query);
  127. // 验证查询结果为空
  128. EXPECT_TRUE(matching_keys.empty());
  129. // 清理数据库
  130. delete db;
  131. }
  132. TEST(TestNewDB, UpdateFieldsAndQueryIndexTest) {
  133. // 创建 NewDB 实例
  134. NewDB* db;
  135. ASSERT_TRUE(OpenDB(testdbname, &db).ok());
  136. // 创建索引字段
  137. db->CreateIndexOnField("address");
  138. // 插入初始数据
  139. std::string key = "k_6";
  140. FieldArray initial_fields = {
  141. {"name", "Customer#000000006"},
  142. {"address", "InitialAddress"},
  143. {"phone", "25-987-654-3210"}
  144. };
  145. ASSERT_TRUE(db->Put_fields(WriteOptions(), key, initial_fields).ok());
  146. // 验证初始数据的索引查询
  147. Field query_field1{"address", "InitialAddress"};
  148. std::vector<std::string> matching_keys = db->QueryByIndex(query_field1);
  149. ASSERT_EQ(matching_keys.size(), 1);
  150. EXPECT_EQ(matching_keys[0], key);
  151. // 更新数据
  152. FieldArray updated_fields = {
  153. {"name", "Customer#000000006"},
  154. {"address", "UpdatedAddress"},
  155. {"phone", "25-987-654-3210"}
  156. };
  157. ASSERT_TRUE(db->Put_fields(WriteOptions(), key, updated_fields).ok());
  158. // 获取并验证字段数据
  159. FieldArray retrieved_fields;
  160. db->Get_fields(ReadOptions(), key, &retrieved_fields);
  161. EXPECT_EQ(retrieved_fields.size(), updated_fields.size());
  162. // 验证插入的每个字段
  163. for (size_t i = 0; i < updated_fields.size(); ++i) {
  164. EXPECT_EQ(updated_fields[i].first, retrieved_fields[i].first); // 字段名
  165. EXPECT_EQ(updated_fields[i].second, retrieved_fields[i].second); // 字段值
  166. }
  167. // 验证新的 address 字段值存在于索引中
  168. Field query_field2{"address", "UpdatedAddress"};
  169. matching_keys = db->QueryByIndex(query_field2);
  170. ASSERT_EQ(matching_keys.size(), 1);
  171. EXPECT_EQ(matching_keys[0], key);
  172. // 验证旧的 address 字段值不再存在于索引中
  173. matching_keys = db->QueryByIndex(query_field1);
  174. ASSERT_EQ(matching_keys.size(), 0);
  175. EXPECT_TRUE(matching_keys.empty());
  176. // 清理数据库
  177. db->Delete(WriteOptions(), "k_1");
  178. db->Delete(WriteOptions(), "k_2");
  179. db->Delete(WriteOptions(), "k_3");
  180. db->Delete(WriteOptions(), "k_4");
  181. db->Delete(WriteOptions(), "k_5");
  182. db->Delete(WriteOptions(), "k_6");
  183. delete db;
  184. }
  185. TEST(TestNewDB, CreateIndexOnExistingDataTest) {
  186. // 创建 NewDB 实例
  187. NewDB* db;
  188. ASSERT_TRUE(OpenDB(testdbname, &db).ok());
  189. // 插入一些测试数据(没有索引的情况下)
  190. std::string key1 = "k_1";
  191. FieldArray fields1 = {
  192. {"name", "Customer#000000001"},
  193. {"address", "IVhzIApeRb"},
  194. {"phone", "25-989-741-2988"}
  195. };
  196. ASSERT_TRUE(db->Put_fields(WriteOptions(), key1, fields1).ok());
  197. std::string key2 = "k_2";
  198. FieldArray fields2 = {
  199. {"name", "Customer#000000002"},
  200. {"address", "TXkjZEdIrZ"},
  201. {"phone", "25-123-456-7890"}
  202. };
  203. ASSERT_TRUE(db->Put_fields(WriteOptions(), key2, fields2).ok());
  204. std::string key3 = "k_3";
  205. FieldArray fields3 = {
  206. {"name", "Customer#000000003"},
  207. {"address", "IVhzIApeRb"}, // 相同地址字段值
  208. {"phone", "25-789-123-4567"}
  209. };
  210. ASSERT_TRUE(db->Put_fields(WriteOptions(), key3, fields3).ok());
  211. // 创建索引字段 'address'
  212. ASSERT_TRUE(db->CreateIndexOnField("address"));
  213. // 查询索引字段 'address' 的数据,验证它能正确索引已有的数据
  214. Field field_to_query{"address", "IVhzIApeRb"};
  215. std::vector<std::string> matching_keys = db->QueryByIndex(field_to_query);
  216. // 验证索引查询结果
  217. ASSERT_EQ(matching_keys.size(), 2); // 预期查询到两个相同地址的记录
  218. EXPECT_TRUE(std::find(matching_keys.begin(), matching_keys.end(), key1) != matching_keys.end());
  219. EXPECT_TRUE(std::find(matching_keys.begin(), matching_keys.end(), key3) != matching_keys.end());
  220. field_to_query.second = "TXkjZEdIrZ"; // 另一个地址值
  221. matching_keys = db->QueryByIndex(field_to_query);
  222. // 验证查询结果
  223. ASSERT_EQ(matching_keys.size(), 1); // 预期只有一个结果
  224. EXPECT_EQ(matching_keys[0], key2);
  225. // 清理数据库
  226. db->Delete(WriteOptions(), key1);
  227. db->Delete(WriteOptions(), key2);
  228. db->Delete(WriteOptions(), key3);
  229. delete db;
  230. }
  231. // 主函数运行所有测试
  232. int main(int argc, char** argv) {
  233. testing::InitGoogleTest(&argc, argv);
  234. return RUN_ALL_TESTS();
  235. }