mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-12 16:26:36 +08:00
55 lines
2.0 KiB
Go
55 lines
2.0 KiB
Go
package database
|
||
|
||
import (
|
||
"path/filepath"
|
||
"strings"
|
||
"testing"
|
||
|
||
"github.com/glebarez/sqlite"
|
||
"gorm.io/gorm"
|
||
"gorm.io/gorm/logger"
|
||
|
||
"github.com/truewhile/MeBox/internal/model"
|
||
)
|
||
|
||
// TestAutoMigrateCreatesMediaPathUniqueIndex 守住 media.path 的唯一约束。
|
||
//
|
||
// 模型上不再声明 gorm:"uniqueIndex"(PostgreSQL 的 btree 单条索引项上限是
|
||
// 2704 字节,而 varchar(1024) 在中文路径下可达 3072 字节,对整列建唯一索引会让
|
||
// 这类行插入直接失败),改由 AutoMigrate 里的 ensureMediaPathIndex 按方言显式
|
||
// 建立。一旦这个调用被漏掉,扫描会静默产生重复的媒体行(同一文件被入库多次)。
|
||
func TestAutoMigrateCreatesMediaPathUniqueIndex(t *testing.T) {
|
||
db, err := gorm.Open(sqlite.Open(filepath.Join(t.TempDir(), "mebox.db")), &gorm.Config{
|
||
Logger: logger.Default.LogMode(logger.Silent),
|
||
})
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
// 必须在 TempDir 清理之前关掉连接,否则 Windows 上删除库文件会失败。
|
||
// t.Cleanup 是后进先出:这里注册的关闭早于 t.TempDir 注册的删除。
|
||
if sqlDB, err := db.DB(); err == nil {
|
||
t.Cleanup(func() { _ = sqlDB.Close() })
|
||
}
|
||
if err := AutoMigrate(db); err != nil {
|
||
t.Fatalf("AutoMigrate: %v", err)
|
||
}
|
||
|
||
var definition string
|
||
if err := db.Raw(`SELECT COALESCE(sql, '') FROM sqlite_master WHERE type = 'index' AND name = 'idx_media_path'`).Scan(&definition).Error; err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
if definition == "" {
|
||
t.Fatal("AutoMigrate did not create idx_media_path")
|
||
}
|
||
if !strings.Contains(strings.ToUpper(definition), "UNIQUE") {
|
||
t.Fatalf("idx_media_path is not unique: %q", definition)
|
||
}
|
||
|
||
if err := db.Create(&model.Media{Base: model.Base{ID: "m-1"}, Path: "/media/a.mkv"}).Error; err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
if err := db.Create(&model.Media{Base: model.Base{ID: "m-2"}, Path: "/media/a.mkv"}).Error; err == nil {
|
||
t.Fatal("a duplicate media path was accepted; the unique constraint is not enforced")
|
||
}
|
||
}
|