DB: Message + Attachments in einer Transaktion speichern (1x fsync statt N+1)
This commit is contained in:
1 parent
1271c9c651
commit
0b2c9a08c6
2 files changed
+43
-25
No files matched your search
+11
-17
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in new issue
Block a user