Allow virtual media reference ids

This commit is contained in:
ShukeBta
2026-06-16 02:20:27 +08:00
parent 284ec873bc
commit a9b85c0f3f
4 changed files with 53 additions and 7 deletions
+6
View File
@@ -662,6 +662,12 @@ func ensurePostgresColumnCompatibility(db *gorm.DB) error {
statements := []string{
`ALTER TABLE media ALTER COLUMN container TYPE varchar(128)`,
`ALTER TABLE media ALTER COLUMN genres TYPE text`,
`ALTER TABLE media ALTER COLUMN series_id TYPE varchar(128)`,
`ALTER TABLE media ALTER COLUMN duplicate_of TYPE varchar(128)`,
`ALTER TABLE playback_histories ALTER COLUMN media_id TYPE varchar(128)`,
`ALTER TABLE favorites ALTER COLUMN media_id TYPE varchar(128)`,
`ALTER TABLE playlist_items ALTER COLUMN media_id TYPE varchar(128)`,
`ALTER TABLE strm_records ALTER COLUMN media_id TYPE varchar(128)`,
}
for _, stmt := range statements {
if err := db.Exec(stmt).Error; err != nil {
+5 -5
View File
@@ -70,7 +70,7 @@ type Library struct {
type Media struct {
Base
LibraryID string `gorm:"index;size:36" json:"library_id"`
SeriesID string `gorm:"index;size:36" json:"series_id,omitempty"`
SeriesID string `gorm:"index;size:128" json:"series_id,omitempty"`
Title string `gorm:"size:255;not null" json:"title"`
OriginalName string `gorm:"size:255" json:"original_name,omitempty"`
Path string `gorm:"uniqueIndex;size:1024;not null" json:"path"`
@@ -115,7 +115,7 @@ type Media struct {
// IsDuplicate flags this media as a duplicate of another media row.
IsDuplicate bool `gorm:"default:false" json:"is_duplicate"`
DuplicateOf string `gorm:"size:36" json:"duplicate_of,omitempty"`
DuplicateOf string `gorm:"size:128" json:"duplicate_of,omitempty"`
}
// APIConfig stores third-party data-source configuration. The api_key
@@ -160,7 +160,7 @@ type Series struct {
type PlaybackHistory struct {
Base
UserID string `gorm:"index;size:36;not null" json:"user_id"`
MediaID string `gorm:"index;size:36;not null" json:"media_id"`
MediaID string `gorm:"index;size:128;not null" json:"media_id"`
PositionMs int64 `json:"position_ms"`
DurationMs int64 `json:"duration_ms"`
WatchedAt time.Time `json:"watched_at"`
@@ -171,7 +171,7 @@ type PlaybackHistory struct {
type Favorite struct {
Base
UserID string `gorm:"index;size:36;not null;uniqueIndex:uniq_user_media" json:"user_id"`
MediaID string `gorm:"index;size:36;not null;uniqueIndex:uniq_user_media" json:"media_id"`
MediaID string `gorm:"index;size:128;not null;uniqueIndex:uniq_user_media" json:"media_id"`
}
// Playlist 是用户策划的、有序的媒体列表。
@@ -186,7 +186,7 @@ type Playlist struct {
type PlaylistItem struct {
Base
PlaylistID string `gorm:"index;size:36;not null" json:"playlist_id"`
MediaID string `gorm:"index;size:36;not null" json:"media_id"`
MediaID string `gorm:"index;size:128;not null" json:"media_id"`
Position int `json:"position"`
}
+40
View File
@@ -0,0 +1,40 @@
package model
import (
"sync"
"testing"
"gorm.io/gorm/schema"
)
func TestMediaReferenceFieldsAllowVirtualEmbyIDs(t *testing.T) {
virtualIDLen := len("msgo-series-c003a8f345ea99aca9bb857591afd915")
cases := []struct {
name string
model any
fieldName string
}{
{name: "media_series_id", model: &Media{}, fieldName: "SeriesID"},
{name: "media_duplicate_of", model: &Media{}, fieldName: "DuplicateOf"},
{name: "playback_history_media_id", model: &PlaybackHistory{}, fieldName: "MediaID"},
{name: "favorite_media_id", model: &Favorite{}, fieldName: "MediaID"},
{name: "playlist_item_media_id", model: &PlaylistItem{}, fieldName: "MediaID"},
{name: "strm_record_media_id", model: &STRMRecord{}, fieldName: "MediaID"},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
parsed, err := schema.Parse(tc.model, &sync.Map{}, schema.NamingStrategy{})
if err != nil {
t.Fatal(err)
}
field := parsed.LookUpField(tc.fieldName)
if field == nil {
t.Fatalf("field %s not found", tc.fieldName)
}
if field.Size < virtualIDLen {
t.Fatalf("%s size = %d, want at least %d", tc.fieldName, field.Size, virtualIDLen)
}
})
}
}
+2 -2
View File
@@ -10,8 +10,8 @@ type STRMRecord struct {
FilePath string `gorm:"size:1024;not null" json:"file_path"` // 本地 STRM 文件路径
Protocol string `gorm:"size:32;not null" json:"protocol"` // webdav / alist / s3 / http / https
FileSize int64 `json:"file_size"`
MediaID string `gorm:"size:36;index" json:"media_id"` // 关联媒体 ID
MediaType string `gorm:"size:16" json:"media_type"` // movie / series
MediaID string `gorm:"size:128;index" json:"media_id"` // 关联媒体 ID
MediaType string `gorm:"size:16" json:"media_type"` // movie / series
SeasonNum int `json:"season_num"`
EpisodeNum int `json:"episode_num"`
}