126 lines
2.9 kB
1
package db
2
3
import (
4
"log"
5
"time"
6
)
7
8
type Follow struct {
9
UserDid string
10
SubjectDid string
11
FollowedAt time.Time
12
RKey string
13
}
14
15
func (d *DB) AddFollow(userDid, subjectDid, rkey string) error {
16
query := `insert or ignore into follows (user_did, subject_did, rkey) values (?, ?, ?)`
17
_, err := d.db.Exec(query, userDid, subjectDid, rkey)
18
return err
19
}
20
21
// Get a follow record
22
func (d *DB) GetFollow(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 := d.db.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
45
func (d *DB) DeleteFollow(userDid, subjectDid string) error {
46
_, err := d.db.Exec(`delete from follows where user_did = ? and subject_did = ?`, userDid, subjectDid)
47
return err
48
}
49
50
func (d *DB) GetFollowerFollowing(did string) (int, int, error) {
51
followers, following := 0, 0
52
err := d.db.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
63
type FollowStatus int
64
65
const (
66
IsNotFollowing FollowStatus = iota
67
IsFollowing
68
IsSelf
69
)
70
71
func (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
84
func (d *DB) GetFollowStatus(userDid, subjectDid string) FollowStatus {
85
if userDid == subjectDid {
86
return IsSelf
87
} else if _, err := d.GetFollow(userDid, subjectDid); err != nil {
88
return IsNotFollowing
89
} else {
90
return IsFollowing
91
}
92
}
93
94
func (d *DB) GetAllFollows() ([]Follow, error) {
95
var follows []Follow
96
97
rows, err := d.db.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
}
127