feat: add expiration handling for database entries and enhance user model with rules
This commit is contained in:
@@ -37,7 +37,8 @@ type logConfig struct {
|
||||
}
|
||||
|
||||
type dbConfig struct {
|
||||
Path string `toml:"path" mapstructure:"path"`
|
||||
Path string `toml:"path" mapstructure:"path"`
|
||||
Expire int64 `toml:"expire" mapstructure:"expire"`
|
||||
}
|
||||
|
||||
type telegramConfig struct {
|
||||
@@ -93,6 +94,7 @@ func Init() error {
|
||||
viper.SetDefault("log.backup_count", 7)
|
||||
|
||||
viper.SetDefault("db.path", "data/saveany.db")
|
||||
viper.SetDefault("db.expire", 86400*5)
|
||||
|
||||
if err := viper.SafeWriteConfigAs("config.toml"); err != nil {
|
||||
if _, ok := err.(viper.ConfigFileAlreadyExistsError); !ok {
|
||||
|
||||
48
dao/db.go
48
dao/db.go
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
dao/model.go
11
dao/model.go
@@ -24,6 +24,8 @@ type User struct {
|
||||
Silent bool
|
||||
DefaultStorage string // Default storage name
|
||||
Dirs []Dir
|
||||
ApplyRule bool
|
||||
Rules []Rule
|
||||
}
|
||||
|
||||
type Dir struct {
|
||||
@@ -37,3 +39,12 @@ type CallbackData struct {
|
||||
gorm.Model
|
||||
Data string
|
||||
}
|
||||
|
||||
type Rule struct {
|
||||
gorm.Model
|
||||
UserID uint
|
||||
Type string
|
||||
Data string
|
||||
StorageName string
|
||||
DirPath string
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ func CreateUser(chatID int64) error {
|
||||
|
||||
func GetAllUsers() ([]User, error) {
|
||||
var users []User
|
||||
err := db.Preload("Dirs").Find(&users).Error
|
||||
err := db.Preload("Dirs").
|
||||
Preload("Rules").
|
||||
Find(&users).Error
|
||||
return users, err
|
||||
}
|
||||
|
||||
@@ -17,6 +19,7 @@ func GetUserByChatID(chatID int64) (*User, error) {
|
||||
var user User
|
||||
err := db.
|
||||
Preload("Dirs").
|
||||
Preload("Rules").
|
||||
Where("chat_id = ?", chatID).First(&user).Error
|
||||
return &user, err
|
||||
}
|
||||
@@ -26,5 +29,5 @@ func UpdateUser(user *User) error {
|
||||
}
|
||||
|
||||
func DeleteUser(user *User) error {
|
||||
return db.Unscoped().Select("Dirs").Delete(user).Error
|
||||
return db.Unscoped().Select("Dirs", "Rules").Delete(user).Error
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user