feat: add expiration handling for database entries and enhance user model with rules

This commit is contained in:
krau
2025-04-12 11:14:13 +08:00
parent 50fba3f910
commit 3bdef20e85
4 changed files with 59 additions and 11 deletions

View File

@@ -1,6 +1,7 @@
package dao
import (
"errors"
"fmt"
"os"
"path/filepath"
@@ -17,8 +18,7 @@ var db *gorm.DB
func Init() {
if err := os.MkdirAll(filepath.Dir(config.Cfg.DB.Path), 0755); err != nil {
common.Log.Fatal("Failed to create data directory: ", err)
os.Exit(1)
common.Log.Panic("Failed to create data directory: ", err)
}
var err error
db, err = gorm.Open(sqlite.Open(config.Cfg.DB.Path), &gorm.Config{
@@ -32,17 +32,25 @@ func Init() {
PrepareStmt: true,
})
if err != nil {
common.Log.Fatal("Failed to open database: ", err)
os.Exit(1)
common.Log.Panic("Failed to open database: ", err)
}
common.Log.Debug("Database connected")
if err := db.AutoMigrate(&ReceivedFile{}, &User{}, &Dir{}, &CallbackData{}); err != nil {
common.Log.Fatal("迁移数据库失败, 如果您从旧版本升级, 建议手动删除数据库文件后重试: ", err)
if err := db.AutoMigrate(&ReceivedFile{}, &User{}, &Dir{}, &CallbackData{}, &Rule{}); err != nil {
common.Log.Panic("迁移数据库失败, 如果您从旧版本升级, 建议手动删除数据库文件后重试: ", err)
}
if err := syncUsers(); err != nil {
common.Log.Fatal("Failed to sync users:", err)
common.Log.Panic("Failed to sync users:", err)
}
common.Log.Debug("Database migrated")
if config.Cfg.DB.Expire == 0 {
return
}
if err := cleanExpiredData(db); err != nil {
common.Log.Error("Failed to clean expired data: ", err)
} else {
common.Log.Debug("Cleaned expired data")
}
go cleanJob(db)
}
func syncUsers() error {
@@ -81,3 +89,27 @@ func syncUsers() error {
return nil
}
func cleanExpiredData(db *gorm.DB) error {
var fileErr error
if err := db.Where("updated_at < ?", time.Now().Add(-time.Duration(config.Cfg.DB.Expire)*time.Second)).Unscoped().Delete(&ReceivedFile{}).Error; err != nil {
fileErr = fmt.Errorf("failed to delete expired files: %w", err)
}
var cbErr error
if err := db.Where("updated_at < ?", time.Now().Add(-time.Duration(config.Cfg.DB.Expire)*time.Second)).Unscoped().Delete(&CallbackData{}).Error; err != nil {
cbErr = fmt.Errorf("failed to delete expired callback data: %w", err)
}
return errors.Join(fileErr, cbErr)
}
func cleanJob(db *gorm.DB) {
tick := time.NewTicker(time.Duration(config.Cfg.DB.Expire) * time.Second)
defer tick.Stop()
for range tick.C {
if err := cleanExpiredData(db); err != nil {
common.Log.Error("Failed to clean expired data: ", err)
} else {
common.Log.Debug("Cleaned expired data")
}
}
}