feat(wizard): add WizardDraftRepository (Dapper.AOT)
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
using Npgsql;
|
||||
|
||||
namespace GmRelay.Shared.Features.Sessions.CreateSession.Wizard;
|
||||
|
||||
public sealed class WizardDraftRepository(NpgsqlDataSource dataSource)
|
||||
{
|
||||
public async Task<WizardDraft?> GetActiveAsync(
|
||||
long chatId, int? messageThreadId, long ownerTelegramId, CancellationToken ct)
|
||||
{
|
||||
const string sql = """
|
||||
SELECT id AS Id,
|
||||
chat_id AS ChatId,
|
||||
message_thread_id AS MessageThreadId,
|
||||
owner_telegram_id AS OwnerTelegramId,
|
||||
step AS Step,
|
||||
payload::text AS PayloadJson,
|
||||
draft_message_id AS DraftMessageId,
|
||||
created_at AS CreatedAt,
|
||||
updated_at AS UpdatedAt,
|
||||
expires_at AS ExpiresAt
|
||||
FROM wizard_drafts
|
||||
WHERE chat_id = @ChatId
|
||||
AND (message_thread_id = @ThreadId OR (@ThreadId IS NULL AND message_thread_id IS NULL))
|
||||
AND owner_telegram_id = @OwnerId
|
||||
AND expires_at > NOW()
|
||||
LIMIT 1
|
||||
""";
|
||||
|
||||
await using var connection = await dataSource.OpenConnectionAsync(ct);
|
||||
return await connection.QuerySingleOrDefaultAsync<WizardDraft>(
|
||||
new CommandDefinition(sql,
|
||||
new { ChatId = chatId, ThreadId = messageThreadId, OwnerId = ownerTelegramId },
|
||||
cancellationToken: ct));
|
||||
}
|
||||
|
||||
public async Task UpsertAsync(WizardDraft draft, CancellationToken ct)
|
||||
{
|
||||
const string sql = """
|
||||
INSERT INTO wizard_drafts
|
||||
(id, chat_id, message_thread_id, owner_telegram_id, step, payload, draft_message_id, created_at, updated_at, expires_at)
|
||||
VALUES
|
||||
(@Id, @ChatId, @MessageThreadId, @OwnerTelegramId, @Step, @Payload::jsonb, @DraftMessageId, @CreatedAt, @UpdatedAt, @ExpiresAt)
|
||||
ON CONFLICT (id) DO UPDATE
|
||||
SET step = EXCLUDED.step,
|
||||
payload = EXCLUDED.payload,
|
||||
draft_message_id = EXCLUDED.draft_message_id,
|
||||
updated_at = EXCLUDED.updated_at,
|
||||
expires_at = EXCLUDED.expires_at;
|
||||
""";
|
||||
|
||||
await using var connection = await dataSource.OpenConnectionAsync(ct);
|
||||
await connection.ExecuteAsync(new CommandDefinition(sql, draft, cancellationToken: ct));
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(Guid id, CancellationToken ct)
|
||||
{
|
||||
const string sql = "DELETE FROM wizard_drafts WHERE id = @Id";
|
||||
await using var connection = await dataSource.OpenConnectionAsync(ct);
|
||||
await connection.ExecuteAsync(new CommandDefinition(sql, new { Id = id }, cancellationToken: ct));
|
||||
}
|
||||
|
||||
public async Task<int> DeleteExpiredAsync(CancellationToken ct)
|
||||
{
|
||||
const string sql = "DELETE FROM wizard_drafts WHERE expires_at <= NOW()";
|
||||
await using var connection = await dataSource.OpenConnectionAsync(ct);
|
||||
return await connection.ExecuteAsync(new CommandDefinition(sql, cancellationToken: ct));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user