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