netplay-lobby-server-go/model/repository/sessionrepository.go
2024-12-24 22:09:17 +08:00

97 lines
2.8 KiB
Go

package repository
import (
"fmt"
"time"
"github.com/jinzhu/gorm"
"github.com/libretro/netplay-lobby-server-go/model/entity"
)
// SessionRepository 抽象了会话的数据库操作。
type SessionRepository struct {
db *gorm.DB
}
// NewSessionRepository 返回一个新的 SessionRepository。
func NewSessionRepository(db *gorm.DB) *SessionRepository {
return &SessionRepository{db}
}
// GetAll 返回当前所有正在托管的会话。Deadline 用于过滤旧会话。零值的 Deadline 会停用此过滤器。
func (r *SessionRepository) GetAll(deadline time.Time) ([]entity.Session, error) {
var s []entity.Session
if deadline.IsZero() {
if err := r.db.Order("username").Find(&s).Error; err != nil {
return nil, fmt.Errorf("无法查询所有会话: %w", err)
}
} else if err := r.db.Where("updated_at > ?", deadline).Order("username").Find(&s).Error; err != nil {
return nil, fmt.Errorf("无法查询带有截止日期 %s 的所有会话: %w", deadline, err)
}
return s, nil
}
// GetByID 返回具有给定 ID 的会话。如果找不到会话,则返回 nil。
func (r *SessionRepository) GetByID(id string) (*entity.Session, error) {
var s entity.Session
if err := r.db.Where("id = ?", id).First(&s).Error; err != nil {
if gorm.IsRecordNotFoundError(err) {
return nil, nil
}
return nil, fmt.Errorf("无法查询 ID 为 %s 的会话: %w", id, err)
}
return &s, nil
}
// GetByRoomID 返回具有给定 RoomID 的会话。如果找不到会话,则返回 nil。
func (r *SessionRepository) GetByRoomID(id int32) (*entity.Session, error) {
var s entity.Session
if err := r.db.Where("room_id = ?", id).First(&s).Error; err != nil {
if gorm.IsRecordNotFoundError(err) {
return nil, nil
}
return nil, fmt.Errorf("无法查询 RoomID 为 %d 的会话: %w", id, err)
}
return &s, nil
}
// Create 创建一个新的会话。
func (r *SessionRepository) Create(s *entity.Session) error {
if err := r.db.Create(s).Error; err != nil {
return fmt.Errorf("无法创建会话 %v: %w", s, err)
}
return nil
}
// Update 更新一个会话。
func (r *SessionRepository) Update(s *entity.Session) error {
if err := r.db.Model(&s).Save(&s).Error; err != nil {
return fmt.Errorf("无法更新会话 %v: %w", s, err)
}
return nil
}
// Touch 更新 UpdatedAt 时间戳。
func (r *SessionRepository) Touch(id string) error {
if err := r.db.Model(&entity.Session{}).Where("id = ?", id).Update("updated_at", time.Now()).Error; err != nil {
return fmt.Errorf("无法触碰 ID 为 %s 的会话: %w", id, err)
}
return nil
}
// PurgeOld 清除所有早于给定时间戳的会话。
func (r *SessionRepository) PurgeOld(deadline time.Time) error {
if err := r.db.Where("updated_at < ?", deadline).Delete(entity.Session{}).Error; err != nil {
return fmt.Errorf("无法删除旧会话: %w", err)
}
return nil
}