mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 03:26:37 +08:00
b0fe40142a
* Rebrand MMTL to MeBox across codebase and assets Rename the project display name, Go module path, environment variable prefix (MEBOX_*), Docker image references, and UI branding from MMTL/mmtl to MeBox/mebox. Replace logo assets with the new MeBox icon and keep legacy SQLite migration support for existing mmtl.db deployments. Co-authored-by: truewhile <truewhile@users.noreply.github.com> * Fix logo icons: use cube-only crop without truncated text Previous icon generation cropped too much of the source image, including partial MeBox wordmark text that was cut off in square icon containers. Regenerate logo-64/192/512, favicon, and SVG from cube-only region. Co-authored-by: truewhile <truewhile@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: truewhile <truewhile@users.noreply.github.com>
91 lines
2.9 KiB
Go
91 lines
2.9 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"go.uber.org/zap"
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/truewhile/MeBox/internal/config"
|
|
"github.com/truewhile/MeBox/internal/database"
|
|
"github.com/truewhile/MeBox/internal/repository"
|
|
)
|
|
|
|
// DatabaseAdminService manages database configuration, connectivity testing, and migration.
|
|
type DatabaseAdminService struct {
|
|
cfg *config.Config
|
|
log *zap.Logger
|
|
repos *repository.Container
|
|
db *gorm.DB
|
|
}
|
|
|
|
// NewDatabaseAdminService creates a new DatabaseAdminService.
|
|
func NewDatabaseAdminService(cfg *config.Config, log *zap.Logger, repos *repository.Container, db *gorm.DB) *DatabaseAdminService {
|
|
if log == nil {
|
|
log = zap.NewNop()
|
|
}
|
|
return &DatabaseAdminService{
|
|
cfg: cfg,
|
|
log: log,
|
|
repos: repos,
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
// GetStatus returns the status of the currently active database.
|
|
func (s *DatabaseAdminService) GetStatus(ctx context.Context) *database.DatabaseStatus {
|
|
return database.InspectDatabaseStatus(s.db, s.cfg)
|
|
}
|
|
|
|
// TestPostgres verifies connectivity and permissions to the specified PostgreSQL DSN.
|
|
func (s *DatabaseAdminService) TestPostgres(ctx context.Context, dsn string) (*database.PostgresTestResult, error) {
|
|
return database.TestPostgres(dsn)
|
|
}
|
|
|
|
// MigrateToPostgres copies all records from the current active database to the target PostgreSQL database.
|
|
func (s *DatabaseAdminService) MigrateToPostgres(ctx context.Context, targetDSN string) (*database.DatabaseMigrationResult, error) {
|
|
s.log.Info("starting user-initiated database migration to PostgreSQL", zap.String("target", database.MaskDSN(targetDSN)))
|
|
res, err := database.MigrateCurrentToPostgres(s.db, targetDSN, 500, s.log)
|
|
if err != nil {
|
|
s.log.Error("database migration to PostgreSQL failed", zap.Error(err))
|
|
return nil, err
|
|
}
|
|
s.log.Info("database migration to PostgreSQL completed successfully",
|
|
zap.Int64("total_rows", res.TotalRows),
|
|
zap.Int64("duration_ms", res.DurationMS),
|
|
)
|
|
return res, nil
|
|
}
|
|
|
|
// SaveConfig persists the database configuration to config.yaml and the database settings table.
|
|
func (s *DatabaseAdminService) SaveConfig(ctx context.Context, dbType, dsn string) error {
|
|
dbType = strings.TrimSpace(dbType)
|
|
dsn = strings.TrimSpace(dsn)
|
|
if dbType == "" {
|
|
dbType = "postgres"
|
|
}
|
|
if dbType == "postgres" && dsn == "" {
|
|
return fmt.Errorf("PostgreSQL DSN 不能为空")
|
|
}
|
|
|
|
// 1. 保存到本地 config.yaml
|
|
if err := config.SaveDatabaseConfig(dbType, dsn); err != nil {
|
|
return fmt.Errorf("保存配置文件失败: %w", err)
|
|
}
|
|
|
|
// 2. 更新内存配置
|
|
s.cfg.Database.Type = dbType
|
|
s.cfg.Database.DSN = dsn
|
|
|
|
// 3. 同时更新 settings 存储库作为副本
|
|
if s.repos != nil && s.repos.Setting != nil {
|
|
_ = s.repos.Setting.Set(ctx, "database.type", dbType)
|
|
_ = s.repos.Setting.Set(ctx, "database.dsn", dsn)
|
|
}
|
|
|
|
s.log.Info("database configuration saved", zap.String("type", dbType), zap.String("dsn", database.MaskDSN(dsn)))
|
|
return nil
|
|
}
|