tinyrelayfile
tinyrelay/internal/community/records_reader.go/

internal/community/records_reader.go raw
1package community
2
3import (
4 "context"
5 "errors"
6 "strings"
7
8 "github.com/FelineStateMachine/tinyrelay/internal/communityread"
9)
10
11// Members exposes the community-owned membership projection to records. The
12// records package consumes this narrow read model and never relies on table
13// names or columns.
14func (s *Service) Members(ctx context.Context) ([]communityread.Member, error) {
15 rows, err := s.store.DB().QueryContext(ctx, `SELECT pubkey,name,role FROM community_members ORDER BY pubkey`)
16 if err != nil {
17 if strings.Contains(err.Error(), "no such table") {
18 return nil, nil
19 }
20 return nil, err
21 }
22 defer rows.Close()
23 var out []communityread.Member
24 for rows.Next() {
25 var member communityread.Member
26 if err := rows.Scan(&member.PubKey, &member.Name, &member.Role); err != nil {
27 return nil, err
28 }
29 out = append(out, member)
30 }
31 return out, rows.Err()
32}
33
34// MemberStatus reports the key's membership and the current member count in one
35// call so succession checks use a consistent community snapshot.
36func (s *Service) MemberStatus(ctx context.Context, pubkey string) (bool, int, error) {
37 var count int
38 var member int
39 if err := s.store.DB().QueryRowContext(ctx, `SELECT count(*), coalesce(max(pubkey=?),0) FROM community_members`, pubkey).Scan(&count, &member); err != nil {
40 if strings.Contains(err.Error(), "no such table") {
41 return false, 0, nil
42 }
43 return false, 0, err
44 }
45 return member != 0, count, nil
46}
47
48// ModerationCounts returns the counters needed by the moderation view.
49func (s *Service) ModerationCounts(ctx context.Context, start int64) (communityread.ModerationCounts, error) {
50 var out communityread.ModerationCounts
51 queries := []struct {
52 table string
53 to *int
54 where string
55 }{
56 {"community_bans", &out.Bans, "at>=?"},
57 {"community_reports", &out.Reports, "at>=?"},
58 {"community_reports", &out.Resolved, "resolved_at>=?"},
59 {"community_event_bans", &out.Hidden, "at>=?"},
60 {"community_ip_blocks", &out.BlockedAddresses, "at>=?"},
61 }
62 var failures error
63 for _, query := range queries {
64 if err := s.store.DB().QueryRowContext(ctx, "SELECT count(*) FROM "+query.table+" WHERE "+query.where, start).Scan(query.to); err != nil {
65 if strings.Contains(err.Error(), "no such table") {
66 continue
67 }
68 failures = errors.Join(failures, err)
69 }
70 }
71 return out, failures
72}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs