Archiv-System: Clear archiviert, Button lädt ältere Archive chronologisch, kein Limit
This commit is contained in:
1 parent
fb2c3a0720
commit
843c210209
9 files changed
+363
-129
No files matched your search
+78
-15
@@ -28,13 +28,23 @@ public class DatabaseService
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
|
||||
// Dapper: snake_case → PascalCase Mapping
|
||||
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
|
||||
|
||||
conn.Execute(@"
|
||||
CREATE TABLE IF NOT EXISTS archives (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
archive_id TEXT NOT NULL UNIQUE,
|
||||
name TEXT,
|
||||
chain_count INTEGER NOT NULL DEFAULT 0,
|
||||
message_count INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS chains (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
chain_id TEXT NOT NULL UNIQUE,
|
||||
session_id TEXT,
|
||||
archive_id TEXT,
|
||||
model TEXT NOT NULL,
|
||||
system_prompt TEXT,
|
||||
input_tokens INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -60,10 +70,63 @@ public class DatabaseService
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_chains_session ON chains(session_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_chains_archive ON chains(archive_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_chain ON messages(chain_id);
|
||||
");
|
||||
}
|
||||
|
||||
// ── Archives ──
|
||||
|
||||
public async Task<ArchiveRecord> CreateArchive(string name = null)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
|
||||
// Zähle aktive Chains und Messages
|
||||
var chainCount = await conn.ExecuteScalarAsync<int>(
|
||||
"SELECT COUNT(*) FROM chains WHERE archive_id IS NULL");
|
||||
if (chainCount == 0) return null;
|
||||
|
||||
var messageCount = await conn.ExecuteScalarAsync<int>(@"
|
||||
SELECT COUNT(*) FROM messages
|
||||
WHERE chain_id IN (SELECT chain_id FROM chains WHERE archive_id IS NULL)");
|
||||
|
||||
var archive = new ArchiveRecord
|
||||
{
|
||||
ArchiveId = Guid.NewGuid().ToString("N"),
|
||||
Name = name,
|
||||
ChainCount = chainCount,
|
||||
MessageCount = messageCount,
|
||||
CreatedAt = DateTime.UtcNow.ToString("o")
|
||||
};
|
||||
|
||||
await conn.ExecuteAsync(@"
|
||||
INSERT INTO archives (archive_id, name, chain_count, message_count, created_at)
|
||||
VALUES (@ArchiveId, @Name, @ChainCount, @MessageCount, @CreatedAt)
|
||||
", archive);
|
||||
|
||||
// Alle aktiven Chains diesem Archiv zuweisen
|
||||
await conn.ExecuteAsync(
|
||||
"UPDATE chains SET archive_id = @archiveId WHERE archive_id IS NULL",
|
||||
new { archiveId = archive.ArchiveId });
|
||||
|
||||
return archive;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ArchiveRecord>> GetArchives(int limit = 20)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QueryAsync<ArchiveRecord>(
|
||||
"SELECT * FROM archives ORDER BY id DESC LIMIT @limit", new { limit });
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ChainRecord>> GetArchiveChains(string archiveId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QueryAsync<ChainRecord>(
|
||||
"SELECT * FROM chains WHERE archive_id = @archiveId ORDER BY id",
|
||||
new { archiveId });
|
||||
}
|
||||
|
||||
// ── Chains ──
|
||||
|
||||
public async Task CreateChain(ChainRecord chain)
|
||||
@@ -71,8 +134,8 @@ public class DatabaseService
|
||||
using var conn = CreateConnection();
|
||||
chain.CreatedAt = DateTime.UtcNow.ToString("o");
|
||||
await conn.ExecuteAsync(@"
|
||||
INSERT INTO chains (chain_id, session_id, model, system_prompt, input_tokens, output_tokens, iterations, stop_reason, duration_ms, created_at)
|
||||
VALUES (@ChainId, @SessionId, @Model, @SystemPrompt, @InputTokens, @OutputTokens, @Iterations, @StopReason, @DurationMs, @CreatedAt)
|
||||
INSERT INTO chains (chain_id, session_id, archive_id, model, system_prompt, input_tokens, output_tokens, iterations, stop_reason, duration_ms, created_at)
|
||||
VALUES (@ChainId, @SessionId, @ArchiveId, @Model, @SystemPrompt, @InputTokens, @OutputTokens, @Iterations, @StopReason, @DurationMs, @CreatedAt)
|
||||
", chain);
|
||||
}
|
||||
|
||||
@@ -98,21 +161,19 @@ public class DatabaseService
|
||||
);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ChainRecord>> GetRecentChains(int limit = 50)
|
||||
public async Task<IEnumerable<ChainRecord>> GetActiveChains()
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QueryAsync<ChainRecord>(
|
||||
"SELECT * FROM chains ORDER BY id DESC LIMIT @limit", new { limit }
|
||||
);
|
||||
"SELECT * FROM chains WHERE archive_id IS NULL ORDER BY id DESC");
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ChainRecord>> GetSessionChains(string sessionId, int limit = 100)
|
||||
public async Task<IEnumerable<ChainRecord>> GetSessionChains(string sessionId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QueryAsync<ChainRecord>(
|
||||
"SELECT * FROM chains WHERE session_id = @sessionId ORDER BY id DESC LIMIT @limit",
|
||||
new { sessionId, limit }
|
||||
);
|
||||
"SELECT * FROM chains WHERE session_id = @sessionId AND archive_id IS NULL ORDER BY id DESC",
|
||||
new { sessionId });
|
||||
}
|
||||
|
||||
// ── Messages ──
|
||||
@@ -136,12 +197,14 @@ public class DatabaseService
|
||||
);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<MessageRecord>> GetMessagesAfterId(long afterId, int limit = 200)
|
||||
public async Task<IEnumerable<MessageRecord>> GetActiveMessagesAfterId(long afterId, int limit = 200)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QueryAsync<MessageRecord>(
|
||||
"SELECT * FROM messages WHERE id > @afterId ORDER BY id LIMIT @limit",
|
||||
new { afterId, limit }
|
||||
);
|
||||
return await conn.QueryAsync<MessageRecord>(@"
|
||||
SELECT m.* FROM messages m
|
||||
JOIN chains c ON m.chain_id = c.chain_id
|
||||
WHERE m.id > @afterId AND c.archive_id IS NULL
|
||||
ORDER BY m.id LIMIT @limit",
|
||||
new { afterId, limit });
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user