mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-07 08:06:37 +08:00
refactor(repository): 收敛 model/repository 分层为唯一持久化入口
将 OpenFlare 与平台业务的数据访问从 model 与 apps 直连迁入 repository, model 仅保留实体与无 IO 规则;补充 code-check 架构守卫与开发规范。
This commit is contained in:
@@ -5,6 +5,10 @@ package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
|
||||
db "github.com/Rain-kl/Wavelet/internal/infra/persistence"
|
||||
"github.com/Rain-kl/Wavelet/internal/model"
|
||||
@@ -18,3 +22,76 @@ func ListUploadStats(ctx context.Context) ([]model.UploadStat, error) {
|
||||
}
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
// GetTotalUploadStat returns the aggregate total-dimension stats row.
|
||||
func GetTotalUploadStat(ctx context.Context) (model.UploadStat, error) {
|
||||
var total model.UploadStat
|
||||
if err := db.DB(ctx).
|
||||
Where("dimension = ? AND stat_key = ?", model.UploadStatDimensionTotal, "").
|
||||
First(&total).Error; err != nil {
|
||||
return model.UploadStat{}, err
|
||||
}
|
||||
return total, nil
|
||||
}
|
||||
|
||||
// ListUploadStatsByDimension returns stats rows for a single dimension.
|
||||
func ListUploadStatsByDimension(ctx context.Context, dimension string) ([]model.UploadStat, error) {
|
||||
var rows []model.UploadStat
|
||||
if err := db.DB(ctx).Where("dimension = ?", dimension).Find(&rows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
// DeleteAllUploadStatsTx removes every row from w_upload_stats within a transaction.
|
||||
func DeleteAllUploadStatsTx(tx *gorm.DB) error {
|
||||
return tx.Where("1 = 1").Delete(&model.UploadStat{}).Error
|
||||
}
|
||||
|
||||
// UpsertUploadStatDeltaTx applies an incremental count/size delta for one dimension key.
|
||||
func UpsertUploadStatDeltaTx(tx *gorm.DB, dimension, key string, countDelta, sizeDelta int64) error {
|
||||
return tx.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{
|
||||
{Name: "dimension"},
|
||||
{Name: "stat_key"},
|
||||
},
|
||||
DoUpdates: clause.Assignments(map[string]any{
|
||||
"file_count": gorm.Expr(
|
||||
"CASE WHEN w_upload_stats.file_count + ? < 0 THEN 0 ELSE w_upload_stats.file_count + ? END",
|
||||
countDelta,
|
||||
countDelta,
|
||||
),
|
||||
"file_size": gorm.Expr(
|
||||
"CASE WHEN w_upload_stats.file_size + ? < 0 THEN 0 ELSE w_upload_stats.file_size + ? END",
|
||||
sizeDelta,
|
||||
sizeDelta,
|
||||
),
|
||||
"updated_at": time.Now(),
|
||||
}),
|
||||
}).Create(&model.UploadStat{
|
||||
Dimension: dimension,
|
||||
StatKey: key,
|
||||
FileCount: countDelta,
|
||||
FileSize: sizeDelta,
|
||||
}).Error
|
||||
}
|
||||
|
||||
// RebuildUploadStats clears w_upload_stats and re-applies deltas for every active upload
|
||||
// inside a single transaction. applyDelta should apply +1 stats for one upload row.
|
||||
func RebuildUploadStats(ctx context.Context, applyDelta func(tx *gorm.DB, upload *model.Upload) error) error {
|
||||
return db.DB(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
if err := DeleteAllUploadStatsTx(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
uploads, err := ListActiveUploadsTx(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range uploads {
|
||||
if err := applyDelta(tx, &uploads[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user