mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 11:36:36 +08:00
Allow virtual media reference ids
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user