package store import ( "log" "os" "path/filepath" "strings" "github.com/glebarez/sqlite" "gorm.io/gorm" gormlogger "gorm.io/gorm/logger" ) // Open 打开数据库连接并自动迁移。 // 开发默认 SQLite(dsn 支持 file:...?_journal_mode=WAL),生产可切 postgres。 func Open(driver, dsn string) (*gorm.DB, error) { var dialector gorm.Dialector switch driver { case "postgres": dialector = postgresDialector(dsn) default: // 确保 SQLite 文件所在目录存在 if dir := sqliteDir(dsn); dir != "" { _ = os.MkdirAll(dir, 0o755) } dialector = sqlite.Open(dsn) } db, err := gorm.Open(dialector, &gorm.Config{ Logger: gormlogger.Default.LogMode(gormlogger.Warn), }) if err != nil { return nil, err } if err := db.AutoMigrate(AllModels()...); err != nil { return nil, err } log.Printf("store: connected driver=%s (migrated)", driver) return db, nil } // sqliteDir 提取 SQLite DSN 中的目录部分(忽略 file: 前缀与查询参数)。 func sqliteDir(dsn string) string { d := dsn if i := strings.IndexByte(d, '?'); i >= 0 { d = d[:i] } if strings.HasPrefix(d, "file:") { d = d[len("file:"):] } if d == "" || d == ":memory:" || strings.Contains(d, "::") { return "" } return filepath.Dir(d) }