Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
2.6 kB · 88 lines
Go
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889package model
import ( "context" "fmt" "time"
"stream.place/streamplace/pkg/appbsky" "stream.place/streamplace/pkg/aqtime")
type Follow struct { UserDID string `gorm:"primaryKey;index:user_idx;column:user_did"` SubjectDID string `gorm:"primaryKey;index:subject_idx;column:subject_did"` RKey string `gorm:"index;column:rkey"` CreatedAt time.Time}
// CreateFollow records a follow edge. Keyed by (user, subject) with no CID// column, so Save (upsert) is already redelivery-safe: the same follow arriving// twice rewrites the same row.func (m *DBModel) CreateFollow(ctx context.Context, userDID, rkey string, follow appbsky.GraphFollow) error { at, err := aqtime.FromString(follow.CreatedAt) if err != nil { return fmt.Errorf("failed to parse follow createdAt: %w", err) } return m.DB.Save(&Follow{ UserDID: userDID, SubjectDID: follow.Subject, RKey: rkey, CreatedAt: at.Time(), }).Error}
func (m *DBModel) DeleteFollow(ctx context.Context, userDID, rkey string) error { res := m.DB.Where("user_did = ? AND rkey = ?", userDID, rkey).Delete(&Follow{}) if res.Error != nil { return fmt.Errorf("failed to delete follow: %w", res.Error) } if res.RowsAffected == 0 { return fmt.Errorf("no follow found for userDID %s and rkey %s", userDID, rkey) } return nil}
func (m *DBModel) GetUserFollowing(ctx context.Context, userDID string) ([]Follow, error) { var follows []Follow return follows, m.DB.Where("user_did = ?", userDID).Find(&follows).Error}
func (m *DBModel) GetUserFollowers(ctx context.Context, userDID string) ([]Follow, error) { var follows []Follow return follows, m.DB.Where("subject_did = ?", userDID).Find(&follows).Error}
func (m *DBModel) GetUserFollowingUser(ctx context.Context, userDID, subjectDID string) (*Follow, error) { var follow Follow result := m.DB.Where("user_did = ? AND subject_did = ?", userDID, subjectDID).First(&follow) if result.RowsAffected == 0 { return nil, nil } return &follow, result.Error}
type followerCountRow struct { SubjectDID string Count int}
func (m *DBModel) CountFollowersBatch(ctx context.Context, dids []string) (map[string]int, error) { if len(dids) == 0 { return map[string]int{}, nil } var rows []followerCountRow err := m.DB.Table("follows"). Select("subject_did, COUNT(*) as count"). Where("subject_did IN ?", dids). Group("subject_did"). Find(&rows).Error if err != nil { return nil, err } counts := make(map[string]int, len(rows)) for _, r := range rows { counts[r.SubjectDID] = r.Count } return counts, nil}