using ZB.MOM.WW.CBDD.Bson; using ZB.MOM.WW.CBDD.Core.Collections; using ZB.MOM.WW.CBDD.Core.Storage; using ZB.MOM.WW.CBDD.Core.Transactions; using ZB.MOM.WW.CBDD.Shared; using ZB.MOM.WW.CBDD.Shared.TestDbContext_TestDbContext_Mappers; using Xunit; using static ZB.MOM.WW.CBDD.Tests.SchemaTests; namespace ZB.MOM.WW.CBDD.Tests; public class BulkOperationsTests : IDisposable { private readonly string _dbPath; private readonly string _walPath; private readonly Shared.TestDbContext _dbContext; /// /// Initializes a new instance of the class. /// public BulkOperationsTests() { _dbPath = Path.Combine(Path.GetTempPath(), $"test_bulk_{Guid.NewGuid()}.db"); _walPath = Path.Combine(Path.GetTempPath(), $"test_bulk_{Guid.NewGuid()}.wal"); _dbContext = new Shared.TestDbContext(_dbPath); } /// /// Executes Dispose. /// public void Dispose() { _dbContext.Dispose(); } /// /// Executes UpdateBulk_UpdatesMultipleDocuments. /// [Fact] public void UpdateBulk_UpdatesMultipleDocuments() { // Arrange: Insert 100 users var users = new List(); for (int i = 0; i < 100; i++) { users.Add(new User { Id = ObjectId.NewObjectId(), Name = $"User {i}", Age = 20 }); } _dbContext.Users.InsertBulk(users); _dbContext.SaveChanges(); // Modify users foreach (var u in users) { u.Age = 30; // In-place update (int is same size) if (u.Name.EndsWith("0")) u.Name += "_Modified_Longer"; // Force move update } // Act var updatedCount = _dbContext.Users.UpdateBulk(users); _dbContext.SaveChanges(); // Assert updatedCount.ShouldBe(100); // Verify changes foreach (var u in users) { var stored = _dbContext.Users.FindById(u.Id); stored.ShouldNotBeNull(); stored.Age.ShouldBe(30); stored.Name.ShouldBe(u.Name); } } /// /// Executes DeleteBulk_RemovesMultipleDocuments. /// [Fact] public void DeleteBulk_RemovesMultipleDocuments() { // Arrange: Insert 100 users var users = new List(); for (int i = 0; i < 100; i++) { users.Add(new User { Id = ObjectId.NewObjectId(), Name = $"User {i}", Age = 20 }); } _dbContext.Users.InsertBulk(users); _dbContext.SaveChanges(); var idsToDelete = users.Take(50).Select(u => u.Id).ToList(); // Act var deletedCount = _dbContext.Users.DeleteBulk(idsToDelete); _dbContext.SaveChanges(); // Assert deletedCount.ShouldBe(50); // Verify deleted foreach (var id in idsToDelete) { _dbContext.Users.FindById(id).ShouldBeNull(); } // Verify remaining var remaining = users.Skip(50).ToList(); foreach (var u in remaining) { _dbContext.Users.FindById(u.Id).ShouldNotBeNull(); } // Verify count // Note: Count() is not fully implemented efficiently yet (iterates everything), but FindAll().Count() works _dbContext.Users.FindAll().Count().ShouldBe(50); } /// /// Executes DeleteBulk_WithTransaction_Rollworks. /// [Fact] public void DeleteBulk_WithTransaction_Rollworks() { // Arrange var user = new User { Id = ObjectId.NewObjectId(), Name = "Txn User", Age = 20 }; _dbContext.Users.Insert(user); _dbContext.SaveChanges(); _dbContext.Users.FindById(user.Id).ShouldNotBeNull(); using (var txn = _dbContext.BeginTransaction()) { _dbContext.Users.DeleteBulk(new[] { user.Id }); txn.Rollback(); } // Assert: Should still exist _dbContext.Users.FindById(user.Id).ShouldNotBeNull(); } }