Initialize CBDD solution and add a .NET-focused gitignore for generated artifacts.
This commit is contained in:
150
tests/CBDD.Tests/CollectionIndexManagerAndDefinitionTests.cs
Normal file
150
tests/CBDD.Tests/CollectionIndexManagerAndDefinitionTests.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
using ZB.MOM.WW.CBDD.Core.Indexing;
|
||||
using ZB.MOM.WW.CBDD.Core.Storage;
|
||||
using ZB.MOM.WW.CBDD.Shared;
|
||||
using ZB.MOM.WW.CBDD.Shared.TestDbContext_TestDbContext_Mappers;
|
||||
|
||||
namespace ZB.MOM.WW.CBDD.Tests;
|
||||
|
||||
public class CollectionIndexManagerAndDefinitionTests
|
||||
{
|
||||
[Fact]
|
||||
public void FindBestIndex_Should_Prefer_Unique_Index()
|
||||
{
|
||||
var dbPath = NewDbPath();
|
||||
try
|
||||
{
|
||||
using var storage = new StorageEngine(dbPath, PageFileConfig.Default);
|
||||
var mapper = new ZB_MOM_WW_CBDD_Shared_PersonMapper();
|
||||
using var manager = new CollectionIndexManager<int, Person>(storage, mapper, "people_idx_pref_unique");
|
||||
|
||||
manager.CreateIndex(p => p.Age, name: "idx_age", unique: false);
|
||||
manager.CreateIndex(p => p.Age, name: "idx_age_unique", unique: true);
|
||||
|
||||
var best = manager.FindBestIndex("Age");
|
||||
|
||||
best.ShouldNotBeNull();
|
||||
best.Definition.Name.ShouldBe("idx_age_unique");
|
||||
best.Definition.IsUnique.ShouldBeTrue();
|
||||
}
|
||||
finally
|
||||
{
|
||||
CleanupFiles(dbPath);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FindBestCompoundIndex_Should_Choose_Longest_Prefix()
|
||||
{
|
||||
var dbPath = NewDbPath();
|
||||
try
|
||||
{
|
||||
using var storage = new StorageEngine(dbPath, PageFileConfig.Default);
|
||||
var mapper = new ZB_MOM_WW_CBDD_Shared_PersonMapper();
|
||||
using var manager = new CollectionIndexManager<int, Person>(storage, mapper, "people_idx_compound");
|
||||
|
||||
manager.CreateIndex(new CollectionIndexDefinition<Person>(
|
||||
"idx_name",
|
||||
["Name"],
|
||||
p => p.Name));
|
||||
|
||||
manager.CreateIndex(new CollectionIndexDefinition<Person>(
|
||||
"idx_name_age",
|
||||
["Name", "Age"],
|
||||
p => new { p.Name, p.Age }));
|
||||
|
||||
manager.CreateIndex(new CollectionIndexDefinition<Person>(
|
||||
"idx_name_age_id",
|
||||
["Name", "Age", "Id"],
|
||||
p => new { p.Name, p.Age, p.Id }));
|
||||
|
||||
var best = manager.FindBestCompoundIndex(["Name", "Age"]);
|
||||
|
||||
best.ShouldNotBeNull();
|
||||
best.Definition.Name.ShouldBe("idx_name_age_id");
|
||||
best.Definition.PropertyPaths.Length.ShouldBe(3);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CleanupFiles(dbPath);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DropIndex_Should_Remove_Metadata_And_Be_Idempotent()
|
||||
{
|
||||
var dbPath = NewDbPath();
|
||||
const string collectionName = "people_idx_drop";
|
||||
|
||||
try
|
||||
{
|
||||
using var storage = new StorageEngine(dbPath, PageFileConfig.Default);
|
||||
var mapper = new ZB_MOM_WW_CBDD_Shared_PersonMapper();
|
||||
|
||||
using (var manager = new CollectionIndexManager<int, Person>(storage, mapper, collectionName))
|
||||
{
|
||||
manager.CreateIndex(p => p.Age, name: "idx_age", unique: false);
|
||||
manager.DropIndex("idx_age").ShouldBeTrue();
|
||||
manager.DropIndex("idx_age").ShouldBeFalse();
|
||||
manager.GetIndexInfo().ShouldBeEmpty();
|
||||
}
|
||||
|
||||
using var reloaded = new CollectionIndexManager<int, Person>(storage, mapper, collectionName);
|
||||
reloaded.GetIndexInfo().ShouldBeEmpty();
|
||||
}
|
||||
finally
|
||||
{
|
||||
CleanupFiles(dbPath);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CollectionIndexDefinition_Should_Respect_Query_Support_Rules()
|
||||
{
|
||||
var definition = new CollectionIndexDefinition<Person>(
|
||||
"idx_name_age",
|
||||
["Name", "Age"],
|
||||
p => new { p.Name, p.Age });
|
||||
|
||||
definition.CanSupportQuery("Name").ShouldBeTrue();
|
||||
definition.CanSupportQuery("Age").ShouldBeFalse();
|
||||
|
||||
definition.CanSupportCompoundQuery(["Name"]).ShouldBeTrue();
|
||||
definition.CanSupportCompoundQuery(["Name", "Age"]).ShouldBeTrue();
|
||||
definition.CanSupportCompoundQuery(["Name", "Age", "Id"]).ShouldBeFalse();
|
||||
|
||||
definition.ToString().ShouldContain("idx_name_age");
|
||||
definition.ToString().ShouldContain("Name");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CollectionIndexInfo_ToString_Should_Include_Diagnostics()
|
||||
{
|
||||
var info = new CollectionIndexInfo
|
||||
{
|
||||
Name = "idx_age",
|
||||
PropertyPaths = ["Age"],
|
||||
EstimatedDocumentCount = 12,
|
||||
EstimatedSizeBytes = 4096
|
||||
};
|
||||
|
||||
var text = info.ToString();
|
||||
|
||||
text.ShouldContain("idx_age");
|
||||
text.ShouldContain("Age");
|
||||
text.ShouldContain("12 docs");
|
||||
}
|
||||
|
||||
private static string NewDbPath()
|
||||
=> Path.Combine(Path.GetTempPath(), $"idx_mgr_{Guid.NewGuid():N}.db");
|
||||
|
||||
private static void CleanupFiles(string dbPath)
|
||||
{
|
||||
if (File.Exists(dbPath)) File.Delete(dbPath);
|
||||
|
||||
var walPath = Path.ChangeExtension(dbPath, ".wal");
|
||||
if (File.Exists(walPath)) File.Delete(walPath);
|
||||
|
||||
var altWalPath = dbPath + "-wal";
|
||||
if (File.Exists(altWalPath)) File.Delete(altWalPath);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user