158 lines
6.7 KiB
C#
158 lines
6.7 KiB
C#
using ClaudeDo.Data.Models;
|
|
using Microsoft.Data.Sqlite;
|
|
|
|
namespace ClaudeDo.Data.Repositories;
|
|
|
|
public sealed class ListRepository
|
|
{
|
|
private readonly SqliteConnectionFactory _factory;
|
|
|
|
public ListRepository(SqliteConnectionFactory factory) => _factory = factory;
|
|
|
|
public async Task AddAsync(ListEntity entity, CancellationToken ct = default)
|
|
{
|
|
await using var conn = _factory.Open();
|
|
await using var cmd = conn.CreateCommand();
|
|
cmd.CommandText = """
|
|
INSERT INTO lists (id, name, created_at, working_dir, default_commit_type)
|
|
VALUES (@id, @name, @created_at, @working_dir, @default_commit_type)
|
|
""";
|
|
cmd.Parameters.AddWithValue("@id", entity.Id);
|
|
cmd.Parameters.AddWithValue("@name", entity.Name);
|
|
cmd.Parameters.AddWithValue("@created_at", entity.CreatedAt.ToString("o"));
|
|
cmd.Parameters.AddWithValue("@working_dir", (object?)entity.WorkingDir ?? DBNull.Value);
|
|
cmd.Parameters.AddWithValue("@default_commit_type", entity.DefaultCommitType);
|
|
await cmd.ExecuteNonQueryAsync(ct);
|
|
}
|
|
|
|
public async Task UpdateAsync(ListEntity entity, CancellationToken ct = default)
|
|
{
|
|
await using var conn = _factory.Open();
|
|
await using var cmd = conn.CreateCommand();
|
|
cmd.CommandText = """
|
|
UPDATE lists SET name = @name, working_dir = @working_dir,
|
|
default_commit_type = @default_commit_type
|
|
WHERE id = @id
|
|
""";
|
|
cmd.Parameters.AddWithValue("@id", entity.Id);
|
|
cmd.Parameters.AddWithValue("@name", entity.Name);
|
|
cmd.Parameters.AddWithValue("@working_dir", (object?)entity.WorkingDir ?? DBNull.Value);
|
|
cmd.Parameters.AddWithValue("@default_commit_type", entity.DefaultCommitType);
|
|
await cmd.ExecuteNonQueryAsync(ct);
|
|
}
|
|
|
|
public async Task DeleteAsync(string listId, CancellationToken ct = default)
|
|
{
|
|
await using var conn = _factory.Open();
|
|
await using var cmd = conn.CreateCommand();
|
|
cmd.CommandText = "DELETE FROM lists WHERE id = @id";
|
|
cmd.Parameters.AddWithValue("@id", listId);
|
|
await cmd.ExecuteNonQueryAsync(ct);
|
|
}
|
|
|
|
public async Task<ListEntity?> GetByIdAsync(string listId, CancellationToken ct = default)
|
|
{
|
|
await using var conn = _factory.Open();
|
|
await using var cmd = conn.CreateCommand();
|
|
cmd.CommandText = "SELECT id, name, created_at, working_dir, default_commit_type FROM lists WHERE id = @id";
|
|
cmd.Parameters.AddWithValue("@id", listId);
|
|
|
|
await using var reader = await cmd.ExecuteReaderAsync(ct);
|
|
if (!await reader.ReadAsync(ct)) return null;
|
|
return ReadList(reader);
|
|
}
|
|
|
|
public async Task<List<ListEntity>> GetAllAsync(CancellationToken ct = default)
|
|
{
|
|
await using var conn = _factory.Open();
|
|
await using var cmd = conn.CreateCommand();
|
|
cmd.CommandText = "SELECT id, name, created_at, working_dir, default_commit_type FROM lists ORDER BY created_at";
|
|
|
|
await using var reader = await cmd.ExecuteReaderAsync(ct);
|
|
var result = new List<ListEntity>();
|
|
while (await reader.ReadAsync(ct))
|
|
result.Add(ReadList(reader));
|
|
return result;
|
|
}
|
|
|
|
public async Task<List<TagEntity>> GetTagsAsync(string listId, CancellationToken ct = default)
|
|
{
|
|
await using var conn = _factory.Open();
|
|
await using var cmd = conn.CreateCommand();
|
|
cmd.CommandText = """
|
|
SELECT t.id, t.name FROM tags t
|
|
JOIN list_tags lt ON lt.tag_id = t.id
|
|
WHERE lt.list_id = @list_id
|
|
""";
|
|
cmd.Parameters.AddWithValue("@list_id", listId);
|
|
|
|
await using var reader = await cmd.ExecuteReaderAsync(ct);
|
|
var result = new List<TagEntity>();
|
|
while (await reader.ReadAsync(ct))
|
|
result.Add(new TagEntity { Id = reader.GetInt64(0), Name = reader.GetString(1) });
|
|
return result;
|
|
}
|
|
|
|
public async Task AddTagAsync(string listId, long tagId, CancellationToken ct = default)
|
|
{
|
|
await using var conn = _factory.Open();
|
|
await using var cmd = conn.CreateCommand();
|
|
cmd.CommandText = "INSERT OR IGNORE INTO list_tags (list_id, tag_id) VALUES (@list_id, @tag_id)";
|
|
cmd.Parameters.AddWithValue("@list_id", listId);
|
|
cmd.Parameters.AddWithValue("@tag_id", tagId);
|
|
await cmd.ExecuteNonQueryAsync(ct);
|
|
}
|
|
|
|
public async Task RemoveTagAsync(string listId, long tagId, CancellationToken ct = default)
|
|
{
|
|
await using var conn = _factory.Open();
|
|
await using var cmd = conn.CreateCommand();
|
|
cmd.CommandText = "DELETE FROM list_tags WHERE list_id = @list_id AND tag_id = @tag_id";
|
|
cmd.Parameters.AddWithValue("@list_id", listId);
|
|
cmd.Parameters.AddWithValue("@tag_id", tagId);
|
|
await cmd.ExecuteNonQueryAsync(ct);
|
|
}
|
|
|
|
public async Task<ListConfigEntity?> GetConfigAsync(string listId, CancellationToken ct = default)
|
|
{
|
|
await using var conn = _factory.Open();
|
|
await using var cmd = conn.CreateCommand();
|
|
cmd.CommandText = "SELECT list_id, model, system_prompt, agent_path FROM list_config WHERE list_id = @list_id";
|
|
cmd.Parameters.AddWithValue("@list_id", listId);
|
|
|
|
await using var reader = await cmd.ExecuteReaderAsync(ct);
|
|
if (!await reader.ReadAsync(ct)) return null;
|
|
return new ListConfigEntity
|
|
{
|
|
ListId = reader.GetString(0),
|
|
Model = reader.IsDBNull(1) ? null : reader.GetString(1),
|
|
SystemPrompt = reader.IsDBNull(2) ? null : reader.GetString(2),
|
|
AgentPath = reader.IsDBNull(3) ? null : reader.GetString(3),
|
|
};
|
|
}
|
|
|
|
public async Task SetConfigAsync(ListConfigEntity entity, CancellationToken ct = default)
|
|
{
|
|
await using var conn = _factory.Open();
|
|
await using var cmd = conn.CreateCommand();
|
|
cmd.CommandText = """
|
|
INSERT OR REPLACE INTO list_config (list_id, model, system_prompt, agent_path)
|
|
VALUES (@list_id, @model, @system_prompt, @agent_path)
|
|
""";
|
|
cmd.Parameters.AddWithValue("@list_id", entity.ListId);
|
|
cmd.Parameters.AddWithValue("@model", (object?)entity.Model ?? DBNull.Value);
|
|
cmd.Parameters.AddWithValue("@system_prompt", (object?)entity.SystemPrompt ?? DBNull.Value);
|
|
cmd.Parameters.AddWithValue("@agent_path", (object?)entity.AgentPath ?? DBNull.Value);
|
|
await cmd.ExecuteNonQueryAsync(ct);
|
|
}
|
|
|
|
private static ListEntity ReadList(SqliteDataReader reader) => new()
|
|
{
|
|
Id = reader.GetString(0),
|
|
Name = reader.GetString(1),
|
|
CreatedAt = DateTime.Parse(reader.GetString(2)),
|
|
WorkingDir = reader.IsDBNull(3) ? null : reader.GetString(3),
|
|
DefaultCommitType = reader.GetString(4),
|
|
};
|
|
}
|