mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-22 07:32:32 +01:00
Move all direct DB access from handlers_rengoku.go (11 calls) and handlers_mail.go (10 calls) into dedicated repository types, continuing the established extraction pattern. RengokuRepository provides UpsertScore and GetRanking, replacing a 3-call check/insert/update sequence and an 8-case switch of nearly identical queries respectively. MailRepository provides SendMail, SendMailTx, GetListForCharacter, GetByID, MarkRead, MarkDeleted, SetLocked, and MarkItemReceived. The old Mail.Send(), Mail.MarkRead(), GetMailListForCharacter, and GetMailByID free functions are removed. Guild handlers that sent mail via Mail.Send(s, ...) now call mailRepo directly.
77 lines
2.5 KiB
Go
77 lines
2.5 KiB
Go
package channelserver
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
)
|
|
|
|
// RengokuRepository centralizes all database access for the rengoku_score table.
|
|
type RengokuRepository struct {
|
|
db *sqlx.DB
|
|
}
|
|
|
|
// NewRengokuRepository creates a new RengokuRepository.
|
|
func NewRengokuRepository(db *sqlx.DB) *RengokuRepository {
|
|
return &RengokuRepository{db: db}
|
|
}
|
|
|
|
// UpsertScore ensures a rengoku_score row exists for the character and updates it.
|
|
func (r *RengokuRepository) UpsertScore(charID uint32, maxStagesMp, maxPointsMp, maxStagesSp, maxPointsSp uint32) error {
|
|
var t int
|
|
err := r.db.QueryRow("SELECT character_id FROM rengoku_score WHERE character_id=$1", charID).Scan(&t)
|
|
if err != nil {
|
|
if _, err := r.db.Exec("INSERT INTO rengoku_score (character_id) VALUES ($1)", charID); err != nil {
|
|
return fmt.Errorf("insert rengoku_score: %w", err)
|
|
}
|
|
}
|
|
if _, err := r.db.Exec(
|
|
"UPDATE rengoku_score SET max_stages_mp=$1, max_points_mp=$2, max_stages_sp=$3, max_points_sp=$4 WHERE character_id=$5",
|
|
maxStagesMp, maxPointsMp, maxStagesSp, maxPointsSp, charID,
|
|
); err != nil {
|
|
return fmt.Errorf("update rengoku_score: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// rengokuScoreQuery is the shared FROM/JOIN clause for ranking queries.
|
|
const rengokuScoreQueryRepo = `, c.name FROM rengoku_score rs
|
|
LEFT JOIN characters c ON c.id = rs.character_id
|
|
LEFT JOIN guild_characters gc ON gc.character_id = rs.character_id `
|
|
|
|
// rengokuColumnForLeaderboard maps a leaderboard index to the score column name.
|
|
func rengokuColumnForLeaderboard(leaderboard uint32) string {
|
|
switch leaderboard {
|
|
case 0, 2:
|
|
return "max_stages_mp"
|
|
case 1, 3:
|
|
return "max_points_mp"
|
|
case 4, 6:
|
|
return "max_stages_sp"
|
|
case 5, 7:
|
|
return "max_points_sp"
|
|
default:
|
|
return "max_stages_mp"
|
|
}
|
|
}
|
|
|
|
// rengokuIsGuildFiltered returns true if the leaderboard index is guild-scoped.
|
|
func rengokuIsGuildFiltered(leaderboard uint32) bool {
|
|
return leaderboard == 2 || leaderboard == 3 || leaderboard == 6 || leaderboard == 7
|
|
}
|
|
|
|
// GetRanking returns rengoku scores for the given leaderboard.
|
|
// For guild-scoped leaderboards (2,3,6,7), guildID filters the results.
|
|
func (r *RengokuRepository) GetRanking(leaderboard uint32, guildID uint32) (*sqlx.Rows, error) {
|
|
col := rengokuColumnForLeaderboard(leaderboard)
|
|
if rengokuIsGuildFiltered(leaderboard) {
|
|
return r.db.Queryx(
|
|
fmt.Sprintf("SELECT %s AS score %s WHERE guild_id=$1 ORDER BY %s DESC", col, rengokuScoreQueryRepo, col),
|
|
guildID,
|
|
)
|
|
}
|
|
return r.db.Queryx(
|
|
fmt.Sprintf("SELECT %s AS score %s ORDER BY %s DESC", col, rengokuScoreQueryRepo, col),
|
|
)
|
|
}
|