65 lines
2.1 KiB
Go
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
|
|
}
|