this repo has no description
1package db 2 3import ( 4 "fmt" 5 "log" 6 "strings" 7 "time" 8) 9 10type Follow struct { 11 UserDid string 12 SubjectDid string 13 FollowedAt time.Time 14 Rkey string 15} 16 17func AddFollow(e Execer, follow *Follow) error { 18 query := `insert or ignore into follows (user_did, subject_did, rkey) values (?, ?, ?)` 19 _, err := e.Exec(query, follow.UserDid, follow.SubjectDid, follow.Rkey) 20 return err 21} 22 23// Get a follow record 24func GetFollow(e Execer, userDid, subjectDid string) (*Follow, error) { 25 query := `select user_did, subject_did, followed_at, rkey from follows where user_did = ? and subject_did = ?` 26 row := e.QueryRow(query, userDid, subjectDid) 27 28 var follow Follow 29 var followedAt string 30 err := row.Scan(&follow.UserDid, &follow.SubjectDid, &followedAt, &follow.Rkey) 31 if err != nil { 32 return nil, err 33 } 34 35 followedAtTime, err := time.Parse(time.RFC3339, followedAt) 36 if err != nil { 37 log.Println("unable to determine followed at time") 38 follow.FollowedAt = time.Now() 39 } else { 40 follow.FollowedAt = followedAtTime 41 } 42 43 return &follow, nil 44} 45 46// Remove a follow 47func DeleteFollow(e Execer, userDid, subjectDid string) error { 48 _, err := e.Exec(`delete from follows where user_did = ? and subject_did = ?`, userDid, subjectDid) 49 return err 50} 51 52// Remove a follow 53func DeleteFollowByRkey(e Execer, userDid, rkey string) error { 54 _, err := e.Exec(`delete from follows where user_did = ? and rkey = ?`, userDid, rkey) 55 return err 56} 57 58func 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) 65 if err != nil { 66 return 0, 0, err 67 } 68 return followers, following, nil 69} 70 71func 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 = " limit ?" 88 args = append(args, limit) 89 } 90 91 query := fmt.Sprintf( 92 `select user_did, subject_did, followed_at, rkey 93 from follows 94 %s 95 order by followed_at desc 96 %s 97 `, whereClause, limitClause) 98 99 rows, err := e.Query(query, args...) 100 if err != nil { 101 return nil, err 102 } 103 for rows.Next() { 104 var follow Follow 105 var followedAt string 106 err := rows.Scan( 107 &follow.UserDid, 108 &follow.SubjectDid, 109 &followedAt, 110 &follow.Rkey, 111 ) 112 if err != nil { 113 return nil, err 114 } 115 followedAtTime, err := time.Parse(time.RFC3339, followedAt) 116 if err != nil { 117 log.Println("unable to determine followed at time") 118 follow.FollowedAt = time.Now() 119 } else { 120 follow.FollowedAt = followedAtTime 121 } 122 follows = append(follows, follow) 123 } 124 return follows, nil 125} 126 127func GetFollowers(e Execer, did string) ([]Follow, error) { 128 return GetFollows(e, 0, FilterEq("subject_did", did)) 129} 130 131func GetFollowing(e Execer, did string) ([]Follow, error) { 132 return GetFollows(e, 0, FilterEq("user_did", did)) 133} 134 135type FollowStatus int 136 137const ( 138 IsNotFollowing FollowStatus = iota 139 IsFollowing 140 IsSelf 141) 142 143func (s FollowStatus) String() string { 144 switch s { 145 case IsNotFollowing: 146 return "IsNotFollowing" 147 case IsFollowing: 148 return "IsFollowing" 149 case IsSelf: 150 return "IsSelf" 151 default: 152 return "IsNotFollowing" 153 } 154} 155 156func GetFollowStatus(e Execer, userDid, subjectDid string) FollowStatus { 157 if userDid == subjectDid { 158 return IsSelf 159 } else if _, err := GetFollow(e, userDid, subjectDid); err != nil { 160 return IsNotFollowing 161 } else { 162 return IsFollowing 163 } 164}