mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-12-23 06:42:41 +00:00
Fix db.go and setting.go
This commit is contained in:
parent
82f0a5680b
commit
b5861d31ae
2 changed files with 51 additions and 43 deletions
|
|
@ -2,9 +2,7 @@ package database
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"fmt"
|
||||
|
||||
"github.com/mhsanaei/3x-ui/v2/database/model"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
|
@ -14,30 +12,20 @@ import (
|
|||
|
||||
var db *gorm.DB
|
||||
|
||||
// GetDB returns the global GORM database instance.
|
||||
func GetDB() *gorm.DB { return db }
|
||||
|
||||
// InitDB sets up the database connection, migrates models, and runs seeders.
|
||||
// InitDB открывает sqlite и выполняет миграции / начальное заполнение.
|
||||
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{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
db = database
|
||||
|
||||
// migrations
|
||||
// миграции
|
||||
if err := AutoMigrate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// seed admin
|
||||
// seed admin (один раз создаём дефолтного админа при отсутствии)
|
||||
if err := SeedAdmin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -45,14 +33,38 @@ func InitDB(dbPath string) error {
|
|||
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 {
|
||||
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 {
|
||||
var count int64
|
||||
if err := db.Model(&model.User{}).
|
||||
|
|
@ -72,27 +84,3 @@ func SeedAdmin() 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,26 @@ var defaultValueMap = map[string]string{
|
|||
// It handles configuration storage, retrieval, and validation for all system settings.
|
||||
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.
|
||||
type OIDCConfig struct {
|
||||
Enabled bool
|
||||
|
|
|
|||
Loading…
Reference in a new issue