appview: db: follow: add GetFollowers and GetFollowing functions to fetch Follows #483

merged
opened by ptr.pet targeting master from [deleted fork]: followers-following-list
Changed files
+65 -41
appview
+64 -40
appview/db/follow.go
··· 1 package db 2 3 import ( 4 "log" 5 "time" 6 ) 7 ··· 56 func GetFollowerFollowingCount(e Execer, did string) (int, int, error) { 57 followers, following := 0, 0 58 err := e.QueryRow( 59 - `SELECT 60 COUNT(CASE WHEN subject_did = ? THEN 1 END) AS followers, 61 COUNT(CASE WHEN user_did = ? THEN 1 END) AS following 62 FROM follows;`, did, did).Scan(&followers, &following) ··· 66 return followers, following, nil 67 } 68 69 - type FollowStatus int 70 - 71 - const ( 72 - IsNotFollowing FollowStatus = iota 73 - IsFollowing 74 - IsSelf 75 - ) 76 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" 87 } 88 - } 89 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 97 } 98 - } 99 - 100 - func GetAllFollows(e Execer, limit int) ([]Follow, error) { 101 - var follows []Follow 102 103 rows, err := e.Query(` 104 select user_did, subject_did, followed_at, rkey 105 from follows 106 order by followed_at desc 107 - limit ?`, limit, 108 - ) 109 if err != nil { 110 return nil, err 111 } 112 - defer rows.Close() 113 - 114 for rows.Next() { 115 var follow Follow 116 var followedAt string 117 - if err := rows.Scan(&follow.UserDid, &follow.SubjectDid, &followedAt, &follow.Rkey); err != nil { 118 return nil, err 119 } 120 - 121 followedAtTime, err := time.Parse(time.RFC3339, followedAt) 122 if err != nil { 123 log.Println("unable to determine followed at time") ··· 125 } else { 126 follow.FollowedAt = followedAtTime 127 } 128 - 129 follows = append(follows, follow) 130 } 131 132 - if err := rows.Err(); err != nil { 133 - return nil, err 134 } 135 136 - return follows, nil 137 }
··· 1 package db 2 3 import ( 4 + "fmt" 5 "log" 6 + "strings" 7 "time" 8 ) 9 ··· 58 func GetFollowerFollowingCount(e Execer, did string) (int, int, error) { 59 followers, following := 0, 0 60 err := e.QueryRow( 61 + `SELECT 62 COUNT(CASE WHEN subject_did = ? THEN 1 END) AS followers, 63 COUNT(CASE WHEN user_did = ? THEN 1 END) AS following 64 FROM follows;`, did, did).Scan(&followers, &following) ··· 68 return followers, following, nil 69 } 70 71 + func GetFollows(e Execer, limit int, filters ...filter) ([]Follow, error) { 72 + var follows []Follow 73 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()...) 79 } 80 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) 88 } 89 90 rows, err := e.Query(` 91 select user_did, subject_did, followed_at, rkey 92 from follows 93 + %s 94 order by followed_at desc 95 + %s 96 + `, whereClause, limitClause) 97 if err != nil { 98 return nil, err 99 } 100 for rows.Next() { 101 var follow Follow 102 var followedAt string 103 + err := rows.Scan( 104 + &follow.UserDid, 105 + &follow.SubjectDid, 106 + &followedAt, 107 + &follow.Rkey, 108 + ) 109 + if err != nil { 110 return nil, err 111 } 112 followedAtTime, err := time.Parse(time.RFC3339, followedAt) 113 if err != nil { 114 log.Println("unable to determine followed at time") ··· 116 } else { 117 follow.FollowedAt = followedAtTime 118 } 119 follows = append(follows, follow) 120 } 121 + return follows, nil 122 + } 123 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" 150 } 151 + } 152 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 + } 161 }
+1 -1
appview/db/timeline.go
··· 137 } 138 139 func getTimelineFollows(e Execer) ([]TimelineEvent, error) { 140 - follows, err := GetAllFollows(e, Limit) 141 if err != nil { 142 return nil, err 143 }
··· 137 } 138 139 func getTimelineFollows(e Execer) ([]TimelineEvent, error) { 140 + follows, err := GetFollows(e, Limit) 141 if err != nil { 142 return nil, err 143 }