forked from
tangled.org/core
fork
Configure Feed
Select the types of activity you want to include in your feed.
this repo has no description
fork
Configure Feed
Select the types of activity you want to include in your feed.
1package db
2
3import (
4 "log"
5 "time"
6)
7
8type Follow struct {
9 UserDid string
10 SubjectDid string
11 FollowedAt time.Time
12 RKey string
13}
14
15func AddFollow(e Execer, userDid, subjectDid, rkey string) error {
16 query := `insert or ignore into follows (user_did, subject_did, rkey) values (?, ?, ?)`
17 _, err := e.Exec(query, userDid, subjectDid, rkey)
18 return err
19}
20
21// Get a follow record
22func GetFollow(e Execer, userDid, subjectDid string) (*Follow, error) {
23 query := `select user_did, subject_did, followed_at, rkey from follows where user_did = ? and subject_did = ?`
24 row := e.QueryRow(query, userDid, subjectDid)
25
26 var follow Follow
27 var followedAt string
28 err := row.Scan(&follow.UserDid, &follow.SubjectDid, &followedAt, &follow.RKey)
29 if err != nil {
30 return nil, err
31 }
32
33 followedAtTime, err := time.Parse(time.RFC3339, followedAt)
34 if err != nil {
35 log.Println("unable to determine followed at time")
36 follow.FollowedAt = time.Now()
37 } else {
38 follow.FollowedAt = followedAtTime
39 }
40
41 return &follow, nil
42}
43
44// Get a follow record
45func DeleteFollow(e Execer, userDid, subjectDid string) error {
46 _, err := e.Exec(`delete from follows where user_did = ? and subject_did = ?`, userDid, subjectDid)
47 return err
48}
49
50func GetFollowerFollowing(e Execer, did string) (int, int, error) {
51 followers, following := 0, 0
52 err := e.QueryRow(
53 `SELECT
54 COUNT(CASE WHEN subject_did = ? THEN 1 END) AS followers,
55 COUNT(CASE WHEN user_did = ? THEN 1 END) AS following
56 FROM follows;`, did, did).Scan(&followers, &following)
57 if err != nil {
58 return 0, 0, err
59 }
60 return followers, following, nil
61}
62
63type FollowStatus int
64
65const (
66 IsNotFollowing FollowStatus = iota
67 IsFollowing
68 IsSelf
69)
70
71func (s FollowStatus) String() string {
72 switch s {
73 case IsNotFollowing:
74 return "IsNotFollowing"
75 case IsFollowing:
76 return "IsFollowing"
77 case IsSelf:
78 return "IsSelf"
79 default:
80 return "IsNotFollowing"
81 }
82}
83
84func GetFollowStatus(e Execer, userDid, subjectDid string) FollowStatus {
85 if userDid == subjectDid {
86 return IsSelf
87 } else if _, err := GetFollow(e, userDid, subjectDid); err != nil {
88 return IsNotFollowing
89 } else {
90 return IsFollowing
91 }
92}
93
94func GetAllFollows(e Execer) ([]Follow, error) {
95 var follows []Follow
96
97 rows, err := e.Query(`select user_did, subject_did, followed_at, rkey from follows`)
98 if err != nil {
99 return nil, err
100 }
101 defer rows.Close()
102
103 for rows.Next() {
104 var follow Follow
105 var followedAt string
106 if err := rows.Scan(&follow.UserDid, &follow.SubjectDid, &followedAt, &follow.RKey); err != nil {
107 return nil, err
108 }
109
110 followedAtTime, err := time.Parse(time.RFC3339, followedAt)
111 if err != nil {
112 log.Println("unable to determine followed at time")
113 follow.FollowedAt = time.Now()
114 } else {
115 follow.FollowedAt = followedAtTime
116 }
117
118 follows = append(follows, follow)
119 }
120
121 if err := rows.Err(); err != nil {
122 return nil, err
123 }
124
125 return follows, nil
126}