diff --git a/src/Database.zig b/src/Database.zig index f86f218..7b5ea12 100644 --- a/src/Database.zig +++ b/src/Database.zig @@ -744,10 +744,13 @@ pub fn removeMessage(self: *const Database, filename: [:0]const u8) RemoveMessag pub const FindMessageError = error{ /// Out of memory creating message object. OutOfMemory, - /// The caller must upgrade the database to use this function - /// (`findMessageByFilename` only). + /// The database is in an older on-disk format that cannot look messages + /// up by filename; call `Database.upgrade` first. Returned by + /// `findMessageByFilename` only. UpgradeRequired, - /// A Xapian exception occurred. + /// The underlying Xapian database reported an error — for example, the + /// database has been closed, or an I/O failure occurred while reading + /// it. XapianException, /// libnotmuch returned an undocumented status code. Unexpected, diff --git a/src/tests.zig b/src/tests.zig index d3390f9..f83023f 100644 --- a/src/tests.zig +++ b/src/tests.zig @@ -255,6 +255,34 @@ test "Database.removeMessage with a message stored under multiple filenames" { try std.testing.expect(try ghost.getFlag(.ghost)); } +test "Database.findMessageByFilename" { + const alloc = std.testing.allocator; + var test_db = try fixture.corpusDatabase(); + defer test_db.deinit(); + const db = test_db.database; + + const root = db.getPath() orelse return error.TestUnexpectedResult; + + // Lookup by absolute filename. + const abs = try std.fs.path.joinZ(alloc, &.{ root, "cur", "two.eml" }); + defer alloc.free(abs); + const by_abs = try db.findMessageByFilename(abs) orelse return error.TestUnexpectedResult; + defer by_abs.deinit(); + try std.testing.expectEqualStrings("two@example.org", by_abs.getMessageID() orelse ""); + + // Lookup by filename relative to the database path. + const by_rel = try db.findMessageByFilename("cur/two.eml") orelse return error.TestUnexpectedResult; + defer by_rel.deinit(); + try std.testing.expectEqualStrings("two@example.org", by_rel.getMessageID() orelse ""); + + // Unknown filenames return null. + try std.testing.expectEqual(@as(?notmuch.Message, null), try db.findMessageByFilename("cur/missing.eml")); + + // A closed database reports a Xapian exception. + try db.close(); + try std.testing.expectError(error.XapianException, db.findMessageByFilename(abs)); +} + test "Database configuration access" { var test_db = try fixture.corpusDatabase(); defer test_db.deinit();