package store import ( "context" "github.com/pkg/errors" "gorm.io/gorm" ) func (s *Store) UpsertPlayer(ctx context.Context, name string, userEmail string, userProvider string) (*Player, error) { var player *Player err := s.Do(ctx, func(db *gorm.DB) error { var existing *Player err := db.First(&existing, "user_email = ? and user_provider = ?", userEmail, userProvider).Error if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { return errors.WithStack(err) } if existing != nil && existing.ID != 0 { err := db.Model(&existing).UpdateColumn("name", name).Error if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { return errors.WithStack(err) } player = existing return nil } player = &Player{ Name: name, UserEmail: userEmail, UserProvider: userProvider, } if err := db.Save(player).Error; err != nil { return errors.WithStack(err) } return nil }) if err != nil { return nil, errors.WithStack(err) } return player, nil } func (s *Store) GetPlayerRank(ctx context.Context, playerID uint) (int, error) { var rank int err := s.Tx(ctx, func(db *gorm.DB) error { err := db.Model(&Player{}).Select("player_ranks.rank").Table("( ? ) as player_ranks", db.Model(&Player{}).Select("id", "rank() over (order by score desc) rank", "deleted_at")).Where("player_ranks.id = ?", playerID).First(&rank).Error if err != nil { return errors.WithStack(err) } return nil }) if err != nil { return 0, errors.WithStack(err) } return rank, nil }