134 lines
3.4 KiB
Go
134 lines
3.4 KiB
Go
|
|
package main
|
||
|
|
|
||
|
|
import (
|
||
|
|
"flag"
|
||
|
|
"fmt"
|
||
|
|
"log"
|
||
|
|
|
||
|
|
"gorm.io/driver/postgres"
|
||
|
|
"gorm.io/gorm"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Config 数据库配置
|
||
|
|
type Config struct {
|
||
|
|
Host string
|
||
|
|
Port int
|
||
|
|
User string
|
||
|
|
Password string
|
||
|
|
DBName string
|
||
|
|
SSLMode string
|
||
|
|
}
|
||
|
|
|
||
|
|
type PostImage struct {
|
||
|
|
ID string `gorm:"type:varchar(36);primaryKey"`
|
||
|
|
PostID string `gorm:"type:varchar(36);index"`
|
||
|
|
URL string `gorm:"type:text"`
|
||
|
|
ThumbnailURL string `gorm:"type:text"`
|
||
|
|
PreviewURL string `gorm:"type:text"`
|
||
|
|
PreviewURLLarge string `gorm:"type:text"`
|
||
|
|
Width int `gorm:"default:0"`
|
||
|
|
Height int `gorm:"default:0"`
|
||
|
|
Size int64 `gorm:"default:0"`
|
||
|
|
MimeType string `gorm:"type:varchar(50)"`
|
||
|
|
SortOrder int `gorm:"default:0"`
|
||
|
|
}
|
||
|
|
|
||
|
|
func (PostImage) TableName() string {
|
||
|
|
return "post_images"
|
||
|
|
}
|
||
|
|
|
||
|
|
func main() {
|
||
|
|
// 解析命令行参数
|
||
|
|
host := flag.String("host", "localhost", "数据库主机")
|
||
|
|
port := flag.Int("port", 5432, "数据库端口")
|
||
|
|
user := flag.String("user", "postgres", "数据库用户")
|
||
|
|
password := flag.String("password", "", "数据库密码")
|
||
|
|
dbname := flag.String("dbname", "carrot_bbs", "数据库名称")
|
||
|
|
sslmode := flag.String("sslmode", "disable", "SSL 模式")
|
||
|
|
flag.Parse()
|
||
|
|
|
||
|
|
cfg := &Config{
|
||
|
|
Host: *host,
|
||
|
|
Port: *port,
|
||
|
|
User: *user,
|
||
|
|
Password: *password,
|
||
|
|
DBName: *dbname,
|
||
|
|
SSLMode: *sslmode,
|
||
|
|
}
|
||
|
|
|
||
|
|
// 连接数据库
|
||
|
|
dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s",
|
||
|
|
cfg.Host, cfg.Port, cfg.User, cfg.Password, cfg.DBName, cfg.SSLMode)
|
||
|
|
|
||
|
|
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
|
||
|
|
if err != nil {
|
||
|
|
log.Fatalf("Failed to connect to database: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 测试连接
|
||
|
|
sqlDB, err := db.DB()
|
||
|
|
if err != nil {
|
||
|
|
log.Fatalf("Failed to get database instance: %v", err)
|
||
|
|
}
|
||
|
|
defer sqlDB.Close()
|
||
|
|
|
||
|
|
if err := sqlDB.Ping(); err != nil {
|
||
|
|
log.Fatalf("Failed to ping database: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
log.Println("Connected to database")
|
||
|
|
|
||
|
|
// 运行迁移
|
||
|
|
if err := runMigration(db); err != nil {
|
||
|
|
log.Fatalf("Migration failed: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
log.Println("Migration completed successfully")
|
||
|
|
}
|
||
|
|
|
||
|
|
func runMigration(db *gorm.DB) error {
|
||
|
|
// 检查字段是否已存在
|
||
|
|
columns, err := db.Migrator().ColumnTypes(&PostImage{})
|
||
|
|
if err != nil {
|
||
|
|
return fmt.Errorf("failed to check column existence: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
hasPreviewURL := false
|
||
|
|
hasPreviewURLLarge := false
|
||
|
|
for _, col := range columns {
|
||
|
|
if col.Name() == "preview_url" {
|
||
|
|
hasPreviewURL = true
|
||
|
|
}
|
||
|
|
if col.Name() == "preview_url_large" {
|
||
|
|
hasPreviewURLLarge = true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if hasPreviewURL && hasPreviewURLLarge {
|
||
|
|
log.Println("Columns already exist, skipping migration")
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// 添加字段
|
||
|
|
if !hasPreviewURL {
|
||
|
|
log.Println("Adding preview_url column...")
|
||
|
|
if err := db.Exec("ALTER TABLE post_images ADD COLUMN preview_url TEXT").Error; err != nil {
|
||
|
|
return fmt.Errorf("failed to add preview_url column: %w", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if !hasPreviewURLLarge {
|
||
|
|
log.Println("Adding preview_url_large column...")
|
||
|
|
if err := db.Exec("ALTER TABLE post_images ADD COLUMN preview_url_large TEXT").Error; err != nil {
|
||
|
|
return fmt.Errorf("failed to add preview_url_large column: %w", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
log.Println("Migration completed successfully")
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// 注意:此脚本仅用于添加数据库字段
|
||
|
|
// 预览图的生成由后端的 upload_service 自动处理
|
||
|
|
// 现有图片需要重新上传才能生成预览图,或者编写额外的后台任务来生成
|