Signed-off-by: dusk y.bera003.06@protonmail.com
+64
-40
appview/db/follow.go
+64
-40
appview/db/follow.go
···
1
1
package db
2
2
3
3
import (
4
+
"fmt"
4
5
"log"
6
+
"strings"
5
7
"time"
6
8
)
7
9
···
56
58
func GetFollowerFollowingCount(e Execer, did string) (int, int, error) {
57
59
followers, following := 0, 0
58
60
err := e.QueryRow(
59
-
`SELECT
61
+
`SELECT
60
62
COUNT(CASE WHEN subject_did = ? THEN 1 END) AS followers,
61
63
COUNT(CASE WHEN user_did = ? THEN 1 END) AS following
62
64
FROM follows;`, did, did).Scan(&followers, &following)
···
66
68
return followers, following, nil
67
69
}
68
70
69
-
type FollowStatus int
70
-
71
-
const (
72
-
IsNotFollowing FollowStatus = iota
73
-
IsFollowing
74
-
IsSelf
75
-
)
71
+
func GetFollows(e Execer, limit int, filters ...filter) ([]Follow, error) {
72
+
var follows []Follow
76
73
77
-
func (s FollowStatus) String() string {
78
-
switch s {
79
-
case IsNotFollowing:
80
-
return "IsNotFollowing"
81
-
case IsFollowing:
82
-
return "IsFollowing"
83
-
case IsSelf:
84
-
return "IsSelf"
85
-
default:
86
-
return "IsNotFollowing"
74
+
var conditions []string
75
+
var args []any
76
+
for _, filter := range filters {
77
+
conditions = append(conditions, filter.Condition())
78
+
args = append(args, filter.Arg()...)
87
79
}
88
-
}
89
80
90
-
func GetFollowStatus(e Execer, userDid, subjectDid string) FollowStatus {
91
-
if userDid == subjectDid {
92
-
return IsSelf
93
-
} else if _, err := GetFollow(e, userDid, subjectDid); err != nil {
94
-
return IsNotFollowing
95
-
} else {
96
-
return IsFollowing
81
+
whereClause := ""
82
+
if conditions != nil {
83
+
whereClause = " where " + strings.Join(conditions, " and ")
84
+
}
85
+
limitClause := ""
86
+
if limit > 0 {
87
+
limitClause = fmt.Sprintf(" limit %d", limit)
97
88
}
98
-
}
99
-
100
-
func GetAllFollows(e Execer, limit int) ([]Follow, error) {
101
-
var follows []Follow
102
89
103
90
rows, err := e.Query(`
104
91
select user_did, subject_did, followed_at, rkey
105
92
from follows
93
+
%s
106
94
order by followed_at desc
107
-
limit ?`, limit,
108
-
)
95
+
%s
96
+
`, whereClause, limitClause)
109
97
if err != nil {
110
98
return nil, err
111
99
}
112
-
defer rows.Close()
113
-
114
100
for rows.Next() {
115
101
var follow Follow
116
102
var followedAt string
117
-
if err := rows.Scan(&follow.UserDid, &follow.SubjectDid, &followedAt, &follow.Rkey); err != nil {
103
+
err := rows.Scan(
104
+
&follow.UserDid,
105
+
&follow.SubjectDid,
106
+
&followedAt,
107
+
&follow.Rkey,
108
+
)
109
+
if err != nil {
118
110
return nil, err
119
111
}
120
-
121
112
followedAtTime, err := time.Parse(time.RFC3339, followedAt)
122
113
if err != nil {
123
114
log.Println("unable to determine followed at time")
···
125
116
} else {
126
117
follow.FollowedAt = followedAtTime
127
118
}
128
-
129
119
follows = append(follows, follow)
130
120
}
121
+
return follows, nil
122
+
}
131
123
132
-
if err := rows.Err(); err != nil {
133
-
return nil, err
124
+
func GetFollowers(e Execer, did string) ([]Follow, error) {
125
+
return GetFollows(e, 0, FilterEq("subject_did", did))
126
+
}
127
+
128
+
func GetFollowing(e Execer, did string) ([]Follow, error) {
129
+
return GetFollows(e, 0, FilterEq("user_did", did))
130
+
}
131
+
132
+
type FollowStatus int
133
+
134
+
const (
135
+
IsNotFollowing FollowStatus = iota
136
+
IsFollowing
137
+
IsSelf
138
+
)
139
+
140
+
func (s FollowStatus) String() string {
141
+
switch s {
142
+
case IsNotFollowing:
143
+
return "IsNotFollowing"
144
+
case IsFollowing:
145
+
return "IsFollowing"
146
+
case IsSelf:
147
+
return "IsSelf"
148
+
default:
149
+
return "IsNotFollowing"
134
150
}
151
+
}
135
152
136
-
return follows, nil
153
+
func GetFollowStatus(e Execer, userDid, subjectDid string) FollowStatus {
154
+
if userDid == subjectDid {
155
+
return IsSelf
156
+
} else if _, err := GetFollow(e, userDid, subjectDid); err != nil {
157
+
return IsNotFollowing
158
+
} else {
159
+
return IsFollowing
160
+
}
137
161
}
History
3 rounds
3 comments
expand 1 comment
pull request successfully merged
expand 1 comment
made a GetFollows, and made the GetFollowers and GetFollowing use that (and also removed GetAllFollows since its not necessary with GetFollows)
expand 1 comment
this is pretty cool! couple of points:
- the
GetFollow*methods are a bit repetitive (in part due to thedatabase/sqlAPIs), can we dedup them like we do in the rest of the codebase? the approach we use here is to writeGetItem(e Execer, filters ...filter) ([]Item, error)and then use filters to create more specific getters. you can look atdb/spindlesfor an example - we could do something similar for
GetFollowStatusi think
oops T.T actually fixed it