╭ changed ─────────────╮ │src/ui/Repo/Events.zig│ ╰──────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │238 fn formatId(aa: std.mem.Allocator, id: *const [evt.event_id_size]u8) ![]const u8 { │ │239 const hex = std.fmt.bytesToHex(id.*, .lower); │ │240 return try aa.dupe(u8, &hex); │ │241 -} │ │242 - │ │243 -fn readRecord( │ │244 - comptime T: type, │ │245 - comptime hash_kind: hash.HashKind, │ │246 - arena: *std.heap.ArenaAllocator, │ │247 - haxy_moment: evt.EventDB(hash_kind).HashMap(.read_only), │ │248 - id: *const [evt.event_id_size]u8, │ │249 -) !?T.Record { │ │250 - const DB = evt.EventDB(hash_kind); │ │251 - const records_cursor = try haxy_moment.getCursor(hash.hashInt(hash_kind, T.record_map_key)) orelse return null;│ │252 - const records = try DB.HashMap(.read_only).init(records_cursor); │ │253 - const record_cursor = try records.getCursor(hash.hashInt(hash_kind, id)) orelse return null; │ │254 - const record = try DB.HashMap(.read_only).init(record_cursor); │ │255 - return try evt.read(T.Record, DB, hash_kind, arena, record); │ │241 } │ │242 │ │243 const EventMeta = struct { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │265 .patchrev => evt.PatchRev, │ │266 .patch => evt.Patch, │ │267 }; │ │283 - const record = (try readRecord(T, hash_kind, arena, haxy_moment, id)) orelse return error.NotFound; │ │284 - break :blk .{ .updated_order = record.updated_order, .removed = record.removed }; │ │268 + break :blk (try evt.readRecordSubset(T, EventMeta, evt.EventDB(hash_kind), hash_kind, haxy_moment, arena, id)) orelse return error.NotFound;│ │269 }, │ │270 }; │ │271 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────╮ │281 kind: evt.EventKind, │ │282 id: *const [evt.event_id_size]u8, │ │283 ) !?Item { │ │284 + const DB = evt.EventDB(hash_kind); │ │285 + // the parts of a record a row shows │ │286 + const Authored = struct { author_email: ?[]const u8 }; │ │287 + const Owned = struct { event: struct { user_id: []const u8 } };│ │288 var item: Item = .{ │ │289 .id = try formatId(arena.allocator(), id), │ │290 .kind = kind, │ ╰────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │292 }; │ │293 switch (kind) { │ │294 .user => { │ │307 - const record = (try readRecord(evt.User, hash_kind, arena, haxy_moment, id)) orelse return null; │ │295 + const record = (try evt.readRecordSubset(evt.User, struct { event: struct { email: []const u8 } }, DB, hash_kind, haxy_moment, arena, id)) orelse return null;│ │296 item.author = try ui.Author.initFromEmail(admin_moment, arena, record.event.email); │ │297 }, │ │298 .repo => { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │311 - const record = (try readRecord(evt.Repo, hash_kind, arena, haxy_moment, id)) orelse return null; │ │299 + const record = (try evt.readRecordSubset(evt.Repo, Owned, DB, hash_kind, haxy_moment, arena, id)) orelse return null;│ │300 if (admin_moment) |moment| { │ │301 if (try evt.User.readById(evt.AdminDB, evt.admin_repo_opts.hash, moment, arena, record.event.user_id)) |user| │ │302 item.author = .{ .user_name = user.event.name }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │303 } │ │304 }, │ │305 .fork => { │ │318 - const record = (try readRecord(evt.Fork, hash_kind, arena, haxy_moment, id)) orelse return null; │ │306 + const record = (try evt.readRecordSubset(evt.Fork, Owned, DB, hash_kind, haxy_moment, arena, id)) orelse return null;│ │307 if (admin_moment) |moment| { │ │308 if (try evt.User.readById(evt.AdminDB, evt.admin_repo_opts.hash, moment, arena, record.event.user_id)) |user| │ │309 item.author = .{ .user_name = user.event.name }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │310 } │ │311 }, │ │312 .issue => { │ │325 - const record = (try readRecord(evt.Issue, hash_kind, arena, haxy_moment, id)) orelse return null; │ │313 + const record = (try evt.readRecordSubset(evt.Issue, Authored, DB, hash_kind, haxy_moment, arena, id)) orelse return null;│ │314 item.author = try ui.Author.initFromEmail(admin_moment, arena, record.author_email); │ │315 if (!include_view_url) return item; │ │316 const route = ui.RoutablePage.repoThreadCommentsRoute(.issue, identity, item.id, 0) orelse return error.RouteTooLong; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │317 item.view_url = try route.toUrl(arena); │ │318 }, │ │319 .discuss => { │ │332 - const record = (try readRecord(evt.Discussion, hash_kind, arena, haxy_moment, id)) orelse return null; │ │320 + const record = (try evt.readRecordSubset(evt.Discussion, Authored, DB, hash_kind, haxy_moment, arena, id)) orelse return null;│ │321 item.author = try ui.Author.initFromEmail(admin_moment, arena, record.author_email); │ │322 if (!include_view_url) return item; │ │323 const route = ui.RoutablePage.repoThreadCommentsRoute(.discuss, identity, item.id, 0) orelse return error.RouteTooLong; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │324 item.view_url = try route.toUrl(arena); │ │325 }, │ │326 .comment => { │ │339 - const record = (try readRecord(evt.Comment, hash_kind, arena, haxy_moment, id)) orelse return null; │ │327 + const record = (try evt.readRecordSubset(evt.Comment, struct { author_email: ?[]const u8, event: struct { thread_id: [evt.event_id_size * 2]u8 } }, DB, hash_kind, haxy_moment, arena, id)) orelse return null;│ │328 item.author = try ui.Author.initFromEmail(admin_moment, arena, record.author_email); │ │329 if (!include_view_url) return item; │ │330 var thread_id: [evt.event_id_size]u8 = undefined; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │334 item.view_url = try route.toUrl(arena); │ │335 }, │ │336 .attach => { │ │349 - const record = (try readRecord(evt.Attachment, hash_kind, arena, haxy_moment, id)) orelse return null; │ │337 + const record = (try evt.readRecordSubset(evt.Attachment, struct { author_email: ?[]const u8, event: struct { parent_id: [evt.event_id_size * 2]u8 } }, DB, hash_kind, haxy_moment, arena, id)) orelse return null;│ │338 item.author = try ui.Author.initFromEmail(admin_moment, arena, record.author_email); │ │339 if (!include_view_url) return item; │ │340 var parent_id: [evt.event_id_size]u8 = undefined; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯