package store import ( "fmt" "log" "os" "path/filepath" "opencatd-open/pkg/config" _ "github.com/lib/pq" "github.com/ncruces/go-sqlite3/gormlite" "gorm.io/driver/mysql" "gorm.io/driver/postgres" "gorm.io/gorm" ) var DB *gorm.DB func InitDB(cfg *config.Config) (*gorm.DB, error) { var ( dialector gorm.Dialector err error ) switch cfg.DB_Type { case "sqlite": dialector, err = sqliteDialector(cfg.DSN) if err != nil { return nil, err } case "postgres": dialector = postgresDialector(cfg.DSN) case "mysql": dialector = mysqlDialector(cfg.DSN) default: return nil, fmt.Errorf("unsupported database type: %s", cfg.DB_Type) } db, err := gorm.Open(dialector, &gorm.Config{}) if err != nil { return nil, fmt.Errorf("failed to connect database: %w", err) } sqlDB, err := db.DB() if err != nil { return nil, fmt.Errorf("failed to get underlying *sql.DB: %w", err) } sqlDB.SetMaxOpenConns(cfg.DBMaxOpenConns) sqlDB.SetMaxIdleConns(cfg.DBMaxIdleConns) if err := db.AutoMigrate(AllModels()...); err != nil { log.Printf("AutoMigrate warning: %v", err) } DB = db return db, nil } func sqliteDialector(dsn string) (gorm.Dialector, error) { if dsn == "" { dsn = "db/openteam.db" } // sqlite 不会自动创建上级目录,先确保它存在(与 docker-compose 挂载的 /app/db 对应) if dir := filepath.Dir(dsn); dir != "." && dir != string(filepath.Separator) { if err := os.MkdirAll(dir, 0o755); err != nil { return nil, fmt.Errorf("failed to create database directory %s: %w", dir, err) } } return gormlite.Open(dsn), nil } func postgresDialector(dsn string) gorm.Dialector { if dsn == "" { dsn = "host=localhost user=postgres password=postgres dbname=opencatd port=5432 sslmode=disable" } return postgres.Open(dsn) } func mysqlDialector(dsn string) gorm.Dialector { if dsn == "" { dsn = "root:password@tcp(127.0.0.1:3306)/opencatd?charset=utf8mb4&parseTime=True&loc=Local" } return mysql.Open(dsn) }