DB: Message + Attachments in einer Transaktion speichern (1x fsync statt N+1)

This commit is contained in:
Meleki committed 2026-02-27 08:13:44 +01:00
1 parent 1271c9c651
commit 0b2c9a08c6
2 files changed
+43 -25

No files matched your search

+11 -17
View File
@@ -133,28 +133,22 @@ public static class ChatEndpoint
var attachmentInfos = lastUserMsg.GetAttachments(); var attachmentInfos = lastUserMsg.GetAttachments();
var attachmentBlocks = lastUserMsg.GetAttachmentBlocks(); var attachmentBlocks = lastUserMsg.GetAttachmentBlocks();
var messageId = await db.SaveMessage(new MessageRecord var attachmentRecords = attachmentBlocks.Select(b => new AttachmentRecord
{
Type = b.Type,
MediaType = b.MediaType,
FileName = b.FileName,
Data = b.Data
}).ToList();
await db.SaveMessageWithAttachments(new MessageRecord
{ {
ChainId = chainId, ChainId = chainId,
Iteration = 0, Iteration = 0,
Role = "user", Role = "user",
Type = "text", Type = "text",
Content = textContent, Content = textContent
AttachmentCount = attachmentBlocks.Count }, attachmentRecords);
});
// Attachments separat speichern
foreach (var block in attachmentBlocks)
{
await db.SaveAttachment(new AttachmentRecord
{
MessageId = messageId,
Type = block.Type,
MediaType = block.MediaType,
FileName = block.FileName,
Data = block.Data
});
}
} }
var systemPrompt = new List<object> var systemPrompt = new List<object>
+32 -8
View File
@@ -360,18 +360,42 @@ public class DatabaseService
", record); ", record);
} }
// ── Attachments ── /// <summary>
/// Speichert Message + Attachments in einer Transaktion (1x fsync statt N+1).
public async Task SaveAttachment(AttachmentRecord attachment) /// </summary>
public async Task<long> SaveMessageWithAttachments(MessageRecord record, List<AttachmentRecord> attachments)
{ {
using var conn = CreateConnection(); using var conn = CreateConnection();
attachment.CreatedAt = DateTime.UtcNow.ToString("o"); using var tx = conn.BeginTransaction();
await conn.ExecuteAsync(@"
INSERT INTO attachments (message_id, type, media_type, file_name, data, created_at) record.CreatedAt = DateTime.UtcNow.ToString("o");
VALUES (@MessageId, @Type, @MediaType, @FileName, @Data, @CreatedAt) record.AttachmentCount = attachments?.Count ?? 0;
", attachment); var messageId = await conn.ExecuteScalarAsync<long>(@"
INSERT INTO messages (chain_id, role, type, content, tool_name, tool_call_id, is_error, iteration, attachment_count, created_at)
VALUES (@ChainId, @Role, @Type, @Content, @ToolName, @ToolCallId, @IsError, @Iteration, @AttachmentCount, @CreatedAt);
SELECT last_insert_rowid();
", record, tx);
if (attachments != null)
{
var now = DateTime.UtcNow.ToString("o");
foreach (var att in attachments)
{
att.MessageId = messageId;
att.CreatedAt = now;
await conn.ExecuteAsync(@"
INSERT INTO attachments (message_id, type, media_type, file_name, data, created_at)
VALUES (@MessageId, @Type, @MediaType, @FileName, @Data, @CreatedAt)
", att, tx);
}
}
tx.Commit();
return messageId;
} }
// ── Attachments ──
public async Task<IEnumerable<AttachmentRecord>> GetAttachments(long messageId) public async Task<IEnumerable<AttachmentRecord>> GetAttachments(long messageId)
{ {
using var conn = CreateConnection(); using var conn = CreateConnection();