Ctrl K
ComunidadGuías…

Ferrite.Data/Repositories/ForumTopicsRepository.cs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2022-2026 Aykut Alparslan KOC

using Ferrite.TL.baseLayer.dto;

namespace Ferrite.Data.Repositories;

public class ForumTopicsRepository : IForumTopicsRepository
{
    private readonly IKVStore _topics;
    private readonly IKVStore _readStates;
    private readonly IKVStore _viewStates;

    public ForumTopicsRepository(IKVStore topics, IKVStore readStates, IKVStore viewStates)
    {
        _topics = topics;
        topics.SetSchema(new TableDefinition("ferrite", "forum_topics",
            new KeyDefinition("pk",
                new DataColumn { Name = "channel_id", Type = DataType.Long },
                new DataColumn { Name = "topic_id", Type = DataType.Int })));
        _readStates = readStates;
        readStates.SetSchema(new TableDefinition("ferrite", "forum_topic_read_states",
            new KeyDefinition("pk",
                new DataColumn { Name = "channel_id", Type = DataType.Long },
                new DataColumn { Name = "topic_id", Type = DataType.Int },
                new DataColumn { Name = "user_id", Type = DataType.Long })));
        _viewStates = viewStates;
        viewStates.SetSchema(new TableDefinition("ferrite", "forum_view_states",
            new KeyDefinition("pk",
                new DataColumn { Name = "channel_id", Type = DataType.Long },
                new DataColumn { Name = "user_id", Type = DataType.Long })));
    }

    public bool PutTopic(TLForumTopicInfo topic)
    {
        var info = topic.AsForumTopicInfo();
        return _topics.Put(topic.AsSpan().ToArray(), info.ChannelId, info.TopicId);
    }

    public async ValueTask<TLForumTopicInfo?> GetTopicAsync(long channelId, int topicId)
    {
        byte[]? bytes = await _topics.GetAsync(channelId, topicId);
        return bytes is { Length: > 0 }
            ? new TLForumTopicInfo(bytes, 0, bytes.Length)
            : null;
    }

    public async ValueTask<IReadOnlyCollection<TLForumTopicInfo>> GetTopicsAsync(long channelId)
    {
        List<TLForumTopicInfo> topics = new();
        await foreach (byte[] bytes in _topics.IterateAsync(channelId))
        {
            topics.Add(new TLForumTopicInfo(bytes, 0, bytes.Length));
        }
        return topics;
    }

    public bool DeleteTopic(long channelId, int topicId)
    {
        bool deleted = _topics.Delete(channelId, topicId);
        _readStates.Delete(channelId, topicId);
        return deleted;
    }

    public bool DeleteTopics(long channelId)
    {
        bool deleted = _topics.Delete(channelId);
        _readStates.Delete(channelId);
        _viewStates.Delete(channelId);
        return deleted;
    }

    public bool PutReadState(TLForumTopicReadState readState)
    {
        var state = readState.AsForumTopicReadState();
        return _readStates.Put(readState.AsSpan().ToArray(), state.ChannelId,
            state.TopicId, state.UserId);
    }

    public async ValueTask<TLForumTopicReadState?> GetReadStateAsync(long channelId,
        int topicId, long userId)
    {
        byte[]? bytes = await _readStates.GetAsync(channelId, topicId, userId);
        return bytes is { Length: > 0 }
            ? new TLForumTopicReadState(bytes, 0, bytes.Length)
            : null;
    }

    public bool DeleteReadStates(long channelId, int topicId) =>
        _readStates.Delete(channelId, topicId);

    public bool PutUserState(TLForumUserState userState)
    {
        var state = userState.AsForumUserState();
        return _viewStates.Put(userState.AsSpan().ToArray(), state.ChannelId, state.UserId);
    }

    public async ValueTask<TLForumUserState?> GetUserStateAsync(long channelId, long userId)
    {
        byte[]? bytes = await _viewStates.GetAsync(channelId, userId);
        return bytes is { Length: > 0 }
            ? new TLForumUserState(bytes, 0, bytes.Length)
            : null;
    }
}