Fix db.go and setting.go

This commit is contained in:
Dikiy13371 2025-10-08 01:29:05 +03:00
parent 82f0a5680b
commit b5861d31ae
2 changed files with 51 additions and 43 deletions

View file

@ -2,9 +2,7 @@ package database
import ( import (
"errors" "errors"
"io/fs" "fmt"
"os"
"path"
"github.com/mhsanaei/3x-ui/v2/database/model" "github.com/mhsanaei/3x-ui/v2/database/model"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
@ -14,30 +12,20 @@ import (
var db *gorm.DB var db *gorm.DB
// GetDB returns the global GORM database instance. // InitDB открывает sqlite и выполняет миграции / начальное заполнение.
func GetDB() *gorm.DB { return db }
// InitDB sets up the database connection, migrates models, and runs seeders.
func InitDB(dbPath string) error { func InitDB(dbPath string) error {
// ensure dir exists
dir := path.Dir(dbPath)
if err := os.MkdirAll(dir, fs.ModePerm); err != nil {
return err
}
// open SQLite (dev)
database, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{}) database, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{})
if err != nil { if err != nil {
return err return err
} }
db = database db = database
// migrations // миграции
if err := AutoMigrate(); err != nil { if err := AutoMigrate(); err != nil {
return err return err
} }
// seed admin // seed admin (один раз создаём дефолтного админа при отсутствии)
if err := SeedAdmin(); err != nil { if err := SeedAdmin(); err != nil {
return err return err
} }
@ -45,14 +33,38 @@ func InitDB(dbPath string) error {
return nil return nil
} }
// AutoMigrate applies schema migrations. // GetDB возвращает активное соединение GORM.
func GetDB() *gorm.DB {
return db
}
// IsNotFound — хелпер для проверки "запись не найдена".
func IsNotFound(err error) bool {
return errors.Is(err, gorm.ErrRecordNotFound)
}
// Checkpoint — безопасный чекпоинт WAL для sqlite.
// Для других СУБД — no-op.
func Checkpoint() error {
if db == nil {
return fmt.Errorf("database is not initialized")
}
if db.Dialector.Name() != "sqlite" {
return nil
}
// TRUNCATE обычно полезнее, чтобы подрезать WAL-файл.
return db.Exec("PRAGMA wal_checkpoint(TRUNCATE);").Error
}
// AutoMigrate применяет миграции схемы.
func AutoMigrate() error { func AutoMigrate() error {
return db.AutoMigrate( return db.AutoMigrate(
&model.User{}, // User{ Id, Username, PasswordHash, Role } &model.User{},
&model.Setting{}, // таблица настроек
) )
} }
// SeedAdmin creates a default admin if it doesn't exist. // SeedAdmin создаёт дефолтного админа, если его нет.
func SeedAdmin() error { func SeedAdmin() error {
var count int64 var count int64
if err := db.Model(&model.User{}). if err := db.Model(&model.User{}).
@ -72,27 +84,3 @@ func SeedAdmin() error {
} }
return db.Create(&admin).Error return db.Create(&admin).Error
} }
// IsNotFound reports whether err is gorm's record-not-found.
func IsNotFound(err error) bool {
return errors.Is(err, gorm.ErrRecordNotFound)
}
// IsSQLiteDB reports whether current DB dialector is sqlite.
func IsSQLiteDB() bool {
if db == nil {
return false
}
return db.Dialector.Name() == "sqlite"
}
// Checkpoint runs WAL checkpoint for SQLite to compact the WAL file.
// No-op for non-SQLite databases.
func Checkpoint() error {
if !IsSQLiteDB() {
return nil
}
// FULL/TRUNCATE — в зависимости от нужной семантики.
// TRUNCATE чаще используется, чтобы обрезать WAL-файл.
return db.Exec("PRAGMA wal_checkpoint(TRUNCATE);").Error
}

View file

@ -110,6 +110,26 @@ var defaultValueMap = map[string]string{
// It handles configuration storage, retrieval, and validation for all system settings. // It handles configuration storage, retrieval, and validation for all system settings.
type SettingService struct{} type SettingService struct{}
// getValue читает ключ из БД (таблица settings). Если записи нет — вернёт дефолт.
func (s *SettingService) getValue(key string) (string, error) {
db := database.GetDB()
if db != nil {
var rec model.Setting
err := db.First(&rec, "key = ?", key).Error
if err == nil {
return rec.Value, nil
}
// если записи нет — идём в дефолты; если другая ошибка — пробрасываем
if !database.IsNotFound(err) {
return "", err
}
}
if v, ok := defaultValueMap[key]; ok {
return v, nil
}
return "", fmt.Errorf("setting %q not found", key)
}
// OIDCConfig defines OpenID Connect settings for external authentication. // OIDCConfig defines OpenID Connect settings for external authentication.
type OIDCConfig struct { type OIDCConfig struct {
Enabled bool Enabled bool