Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview: implement GetFollowersFollowingCounts to query follow stats for multiple dids in one go

- moves FollowStats type from timeline.go into follow.go
- makes existing GetFollowersFollowingCount also use FollowStats

Signed-off-by: dusk <y.bera003.06@protonmail.com>

authored by

dusk and committed by
Tangled
e7b51821 4e5b1f20

+98 -29
+79 -3
appview/db/follow.go
··· 55 55 return err 56 56 } 57 57 58 - func GetFollowerFollowingCount(e Execer, did string) (int, int, error) { 58 + type FollowStats struct { 59 + Followers int 60 + Following int 61 + } 62 + 63 + func GetFollowerFollowingCount(e Execer, did string) (FollowStats, error) { 59 64 followers, following := 0, 0 60 65 err := e.QueryRow( 61 66 `SELECT ··· 68 63 COUNT(CASE WHEN user_did = ? THEN 1 END) AS following 69 64 FROM follows;`, did, did).Scan(&followers, &following) 70 65 if err != nil { 71 - return 0, 0, err 66 + return FollowStats{}, err 72 67 } 73 - return followers, following, nil 68 + return FollowStats{ 69 + Followers: followers, 70 + Following: following, 71 + }, nil 72 + } 73 + 74 + func GetFollowerFollowingCounts(e Execer, dids []string) (map[string]FollowStats, error) { 75 + if len(dids) == 0 { 76 + return nil, nil 77 + } 78 + 79 + placeholders := make([]string, len(dids)) 80 + for i := range placeholders { 81 + placeholders[i] = "?" 82 + } 83 + placeholderStr := strings.Join(placeholders, ",") 84 + 85 + args := make([]any, len(dids)*2) 86 + for i, did := range dids { 87 + args[i] = did 88 + args[i+len(dids)] = did 89 + } 90 + 91 + query := fmt.Sprintf(` 92 + select 93 + coalesce(f.did, g.did) as did, 94 + coalesce(f.followers, 0) as followers, 95 + coalesce(g.following, 0) as following 96 + from ( 97 + select subject_did as did, count(*) as followers 98 + from follows 99 + where subject_did in (%s) 100 + group by subject_did 101 + ) f 102 + full outer join ( 103 + select user_did as did, count(*) as following 104 + from follows 105 + where user_did in (%s) 106 + group by user_did 107 + ) g on f.did = g.did`, 108 + placeholderStr, placeholderStr) 109 + 110 + result := make(map[string]FollowStats) 111 + 112 + rows, err := e.Query(query, args...) 113 + if err != nil { 114 + return nil, err 115 + } 116 + defer rows.Close() 117 + 118 + for rows.Next() { 119 + var did string 120 + var followers, following int 121 + if err := rows.Scan(&did, &followers, &following); err != nil { 122 + return nil, err 123 + } 124 + result[did] = FollowStats{ 125 + Followers: followers, 126 + Following: following, 127 + } 128 + } 129 + 130 + for _, did := range dids { 131 + if _, exists := result[did]; !exists { 132 + result[did] = FollowStats{ 133 + Followers: 0, 134 + Following: 0, 135 + } 136 + } 137 + } 138 + 139 + return result, nil 74 140 } 75 141 76 142 func GetFollows(e Execer, limit int, filters ...filter) ([]Follow, error) {
+3 -15
appview/db/timeline.go
··· 20 20 *FollowStats 21 21 } 22 22 23 - type FollowStats struct { 24 - Followers int 25 - Following int 26 - } 27 - 28 23 const Limit = 50 29 24 30 25 // TODO: this gathers heterogenous events from different sources and aggregates ··· 151 156 return nil, err 152 157 } 153 158 154 - followStatMap := make(map[string]FollowStats) 155 - for _, s := range subjects { 156 - followers, following, err := GetFollowerFollowingCount(e, s) 157 - if err != nil { 158 - return nil, err 159 - } 160 - followStatMap[s] = FollowStats{ 161 - Followers: followers, 162 - Following: following, 163 - } 159 + followStatMap, err := GetFollowerFollowingCounts(e, subjects) 160 + if err != nil { 161 + return nil, err 164 162 } 165 163 166 164 var events []TimelineEvent
+13 -8
appview/state/profile.go
··· 63 63 return nil 64 64 } 65 65 66 - followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did) 66 + followStats, err := db.GetFollowerFollowingCount(s.db, did) 67 67 if err != nil { 68 68 log.Printf("getting follow stats for %s: %s", did, err) 69 69 } ··· 82 82 UserHandle: ident.Handle.String(), 83 83 Profile: profile, 84 84 FollowStatus: followStatus, 85 - FollowersCount: followersCount, 86 - FollowingCount: followingCount, 85 + FollowersCount: followStats.Followers, 86 + FollowingCount: followStats.Following, 87 87 }, 88 88 } 89 89 } ··· 241 241 return FollowsPageParams{}, err 242 242 } 243 243 244 + followStatsMap, err := db.GetFollowerFollowingCounts(s.db, followDids) 245 + if err != nil { 246 + log.Printf("getting follow counts for %s: %s", followDids, err) 247 + } 248 + 244 249 var loggedInUserFollowing map[string]struct{} 245 250 if loggedInUser != nil { 246 251 following, err := db.GetFollowing(s.db, loggedInUser.Did) ··· 262 257 263 258 followCards := make([]pages.FollowCard, 0, len(follows)) 264 259 for _, did := range followDids { 265 - followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did) 266 - if err != nil { 267 - log.Printf("getting follow stats for %s: %s", did, err) 260 + followStats, exists := followStatsMap[did] 261 + if !exists { 262 + followStats = db.FollowStats{} 268 263 } 269 264 followStatus := db.IsNotFollowing 270 265 if loggedInUserFollowing != nil { ··· 284 279 followCards = append(followCards, pages.FollowCard{ 285 280 UserDid: did, 286 281 FollowStatus: followStatus, 287 - FollowersCount: followersCount, 288 - FollowingCount: followingCount, 282 + FollowersCount: followStats.Followers, 283 + FollowingCount: followStats.Following, 289 284 Profile: profile, 290 285 }) 291 286 }
+3 -3
appview/strings/strings.go
··· 202 202 followStatus = db.GetFollowStatus(s.Db, loggedInUser.Did, id.DID.String()) 203 203 } 204 204 205 - followersCount, followingCount, err := db.GetFollowerFollowingCount(s.Db, id.DID.String()) 205 + followStats, err := db.GetFollowerFollowingCount(s.Db, id.DID.String()) 206 206 if err != nil { 207 207 l.Error("failed to get follow stats", "err", err) 208 208 } ··· 214 214 UserHandle: id.Handle.String(), 215 215 Profile: profile, 216 216 FollowStatus: followStatus, 217 - FollowersCount: followersCount, 218 - FollowingCount: followingCount, 217 + FollowersCount: followStats.Followers, 218 + FollowingCount: followStats.Following, 219 219 }, 220 220 Strings: all, 221 221 })