veza/veza-backend-api/internal/repositories/reaction_repository.go
2026-03-06 10:29:30 +01:00

84 lines
2.6 KiB
Go

package repositories
import (
"context"
"veza-backend-api/internal/models"
"github.com/google/uuid"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
type ReactionRepository struct {
db *gorm.DB
}
func NewReactionRepository(db *gorm.DB) *ReactionRepository {
return &ReactionRepository{db: db}
}
func (r *ReactionRepository) Add(ctx context.Context, reaction *models.MessageReaction) error {
return r.db.WithContext(ctx).
Clauses(clause.OnConflict{DoNothing: true}).
Create(reaction).Error
}
func (r *ReactionRepository) Remove(ctx context.Context, userID, messageID uuid.UUID) error {
return r.db.WithContext(ctx).
Where("user_id = ? AND message_id = ?", userID, messageID).
Delete(&models.MessageReaction{}).Error
}
func (r *ReactionRepository) RemoveByEmoji(ctx context.Context, userID, messageID uuid.UUID, emoji string) error {
return r.db.WithContext(ctx).
Where("user_id = ? AND message_id = ? AND emoji = ?", userID, messageID, emoji).
Delete(&models.MessageReaction{}).Error
}
func (r *ReactionRepository) GetByMessageID(ctx context.Context, messageID uuid.UUID) ([]models.MessageReaction, error) {
var reactions []models.MessageReaction
err := r.db.WithContext(ctx).Where("message_id = ?", messageID).Find(&reactions).Error
return reactions, err
}
func (r *ReactionRepository) GetByMessageIDGrouped(ctx context.Context, messageID uuid.UUID) (map[string][]string, error) {
var reactions []models.MessageReaction
err := r.db.WithContext(ctx).Where("message_id = ?", messageID).Find(&reactions).Error
if err != nil {
return nil, err
}
grouped := make(map[string][]string)
for _, reaction := range reactions {
grouped[reaction.Emoji] = append(grouped[reaction.Emoji], reaction.UserID.String())
}
return grouped, nil
}
// GetReactionsForMessageIDs returns reactions grouped by message ID (map[messageID]map[emoji][]userID).
// Avoids N+1 queries when enriching multiple messages.
func (r *ReactionRepository) GetReactionsForMessageIDs(ctx context.Context, messageIDs []uuid.UUID) (map[uuid.UUID]map[string][]string, error) {
if len(messageIDs) == 0 {
return nil, nil
}
var reactions []models.MessageReaction
err := r.db.WithContext(ctx).
Where("message_id IN ?", messageIDs).
Find(&reactions).Error
if err != nil {
return nil, err
}
result := make(map[uuid.UUID]map[string][]string)
for _, reaction := range reactions {
if result[reaction.MessageID] == nil {
result[reaction.MessageID] = make(map[string][]string)
}
result[reaction.MessageID][reaction.Emoji] = append(
result[reaction.MessageID][reaction.Emoji],
reaction.UserID.String(),
)
}
return result, nil
}