Files
RenewCMS/internal/infrastructure/persistence/repositories/imageVariantUsageRepository.go
T

65 lines
2.1 KiB
Go

package persistence
import (
domain "RenewCMS/internal/domain/image"
entity "RenewCMS/internal/infrastructure/persistence/models"
"time"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
type VariantUsageRepository struct {
db *gorm.DB
}
var _ domain.VariantUsageRepository = &VariantUsageRepository{}
func NewVariantUsageRepository(db *gorm.DB) *VariantUsageRepository {
return &VariantUsageRepository{db}
}
func (v *VariantUsageRepository) Record(batch domain.VariantUsageBatch) error {
return v.db.Transaction(func(tx *gorm.DB) error {
for _, hit := range batch.Hits {
if err := recordHit(tx, hit); err != nil {
return err
}
}
for _, rejection := range batch.Rejections {
if err := recordRejections(tx, rejection); err != nil {
return err
}
}
if batch.PruneBefore.IsZero() {
return nil
}
return tx.Where("day < ?", batch.PruneBefore.UTC().Format(domain.RejectionDayLayout)).Delete(&entity.ImageVariantRejectionDay{}).Error
})
}
func recordHit(tx *gorm.DB, hit domain.VariantHit) error {
at := hit.At.UTC()
query := tx.Model(&entity.ImageVariantFile{})
query = query.Where("variant_name = ? AND source_name = ?", hit.VariantName, hit.SourceName)
query = query.Where("last_requested_at IS NULL OR last_requested_at < ?", at)
return query.Update("last_requested_at", at).Error
}
func recordRejections(tx *gorm.DB, rejection domain.RejectionCount) error {
row := entity.ImageVariantRejectionDay{Day: rejection.Day.UTC().Format(domain.RejectionDayLayout), Count: rejection.Count}
return tx.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "day"}},
DoUpdates: clause.Assignments(map[string]any{"count": gorm.Expr("? + ?", clause.Column{Table: clause.CurrentTable, Name: "count"}, rejection.Count)}),
}).Create(&row).Error
}
func (v *VariantUsageRepository) RejectedSince(day time.Time) (int, error) {
var total int
query := v.db.Model(&entity.ImageVariantRejectionDay{})
query = query.Select("COALESCE(SUM(count), 0)")
query = query.Where("day >= ?", day.UTC().Format(domain.RejectionDayLayout))
err := query.Scan(&total).Error
return total, err
}