package models import ( "context" "github.com/stashapp/stash/pkg/file" ) type SceneIDLoader interface { GetSceneIDs(ctx context.Context, relatedID int) ([]int, error) } type GalleryIDLoader interface { GetGalleryIDs(ctx context.Context, relatedID int) ([]int, error) } type PerformerIDLoader interface { GetPerformerIDs(ctx context.Context, relatedID int) ([]int, error) } type TagIDLoader interface { GetTagIDs(ctx context.Context, relatedID int) ([]int, error) } type SceneMovieLoader interface { GetMovies(ctx context.Context, id int) ([]MoviesScenes, error) } type StashIDLoader interface { GetStashIDs(ctx context.Context, relatedID int) ([]StashID, error) } type VideoFileLoader interface { GetFiles(ctx context.Context, relatedID int) ([]*file.VideoFile, error) } type ImageFileLoader interface { GetFiles(ctx context.Context, relatedID int) ([]*file.ImageFile, error) } type FileLoader interface { GetFiles(ctx context.Context, relatedID int) ([]file.File, error) } type AliasLoader interface { GetAliases(ctx context.Context, relatedID int) ([]string, error) } // RelatedIDs represents a list of related IDs. // TODO - this can be made generic type RelatedIDs struct { list []int } // NewRelatedIDs returns a loaded RelatedIDs object with the provided IDs. // Loaded will return true when called on the returned object if the provided slice is not nil. func NewRelatedIDs(ids []int) RelatedIDs { return RelatedIDs{ list: ids, } } // Loaded returns true if the related IDs have been loaded. func (r RelatedIDs) Loaded() bool { return r.list != nil } func (r RelatedIDs) mustLoaded() { if !r.Loaded() { panic("list has not been loaded") } } // List returns the related IDs. Panics if the relationship has not been loaded. func (r RelatedIDs) List() []int { r.mustLoaded() return r.list } // Add adds the provided ids to the list. Panics if the relationship has not been loaded. func (r *RelatedIDs) Add(ids ...int) { r.mustLoaded() r.list = append(r.list, ids...) } func (r *RelatedIDs) load(fn func() ([]int, error)) error { if r.Loaded() { return nil } ids, err := fn() if err != nil { return err } if ids == nil { ids = []int{} } r.list = ids return nil } // RelatedMovies represents a list of related Movies. type RelatedMovies struct { list []MoviesScenes } // NewRelatedMovies returns a loaded RelatedMovies object with the provided movies. // Loaded will return true when called on the returned object if the provided slice is not nil. func NewRelatedMovies(list []MoviesScenes) RelatedMovies { return RelatedMovies{ list: list, } } // Loaded returns true if the relationship has been loaded. func (r RelatedMovies) Loaded() bool { return r.list != nil } func (r RelatedMovies) mustLoaded() { if !r.Loaded() { panic("list has not been loaded") } } // List returns the related Movies. Panics if the relationship has not been loaded. func (r RelatedMovies) List() []MoviesScenes { r.mustLoaded() return r.list } // Add adds the provided ids to the list. Panics if the relationship has not been loaded. func (r *RelatedMovies) Add(movies ...MoviesScenes) { r.mustLoaded() r.list = append(r.list, movies...) } // ForID returns the MoviesScenes object for the given movie ID. Returns nil if not found. func (r *RelatedMovies) ForID(id int) *MoviesScenes { r.mustLoaded() for _, v := range r.list { if v.MovieID == id { return &v } } return nil } func (r *RelatedMovies) load(fn func() ([]MoviesScenes, error)) error { if r.Loaded() { return nil } ids, err := fn() if err != nil { return err } if ids == nil { ids = []MoviesScenes{} } r.list = ids return nil } type RelatedStashIDs struct { list []StashID } // NewRelatedStashIDs returns a RelatedStashIDs object with the provided ids. // Loaded will return true when called on the returned object if the provided slice is not nil. func NewRelatedStashIDs(list []StashID) RelatedStashIDs { return RelatedStashIDs{ list: list, } } func (r RelatedStashIDs) mustLoaded() { if !r.Loaded() { panic("list has not been loaded") } } // Loaded returns true if the relationship has been loaded. func (r RelatedStashIDs) Loaded() bool { return r.list != nil } // List returns the related Stash IDs. Panics if the relationship has not been loaded. func (r RelatedStashIDs) List() []StashID { r.mustLoaded() return r.list } func (r *RelatedStashIDs) load(fn func() ([]StashID, error)) error { if r.Loaded() { return nil } ids, err := fn() if err != nil { return err } if ids == nil { ids = []StashID{} } r.list = ids return nil } type RelatedVideoFiles struct { primaryFile *file.VideoFile files []*file.VideoFile primaryLoaded bool } func NewRelatedVideoFiles(files []*file.VideoFile) RelatedVideoFiles { ret := RelatedVideoFiles{ files: files, primaryLoaded: true, } if len(files) > 0 { ret.primaryFile = files[0] } return ret } func (r *RelatedVideoFiles) SetPrimary(f *file.VideoFile) { r.primaryFile = f r.primaryLoaded = true } func (r *RelatedVideoFiles) Set(f []*file.VideoFile) { r.files = f if len(r.files) > 0 { r.primaryFile = r.files[0] } r.primaryLoaded = true } // Loaded returns true if the relationship has been loaded. func (r RelatedVideoFiles) Loaded() bool { return r.files != nil } // Loaded returns true if the primary file relationship has been loaded. func (r RelatedVideoFiles) PrimaryLoaded() bool { return r.primaryLoaded } // List returns the related files. Panics if the relationship has not been loaded. func (r RelatedVideoFiles) List() []*file.VideoFile { if !r.Loaded() { panic("relationship has not been loaded") } return r.files } // Primary returns the primary file. Panics if the relationship has not been loaded. func (r RelatedVideoFiles) Primary() *file.VideoFile { if !r.PrimaryLoaded() { panic("relationship has not been loaded") } return r.primaryFile } func (r *RelatedVideoFiles) load(fn func() ([]*file.VideoFile, error)) error { if r.Loaded() { return nil } var err error r.files, err = fn() if err != nil { return err } if len(r.files) > 0 { r.primaryFile = r.files[0] } r.primaryLoaded = true return nil } func (r *RelatedVideoFiles) loadPrimary(fn func() (*file.VideoFile, error)) error { if r.PrimaryLoaded() { return nil } var err error r.primaryFile, err = fn() if err != nil { return err } r.primaryLoaded = true return nil } type RelatedImageFiles struct { primaryFile *file.ImageFile files []*file.ImageFile primaryLoaded bool } func NewRelatedImageFiles(files []*file.ImageFile) RelatedImageFiles { ret := RelatedImageFiles{ files: files, primaryLoaded: true, } if len(files) > 0 { ret.primaryFile = files[0] } return ret } // Loaded returns true if the relationship has been loaded. func (r RelatedImageFiles) Loaded() bool { return r.files != nil } // Loaded returns true if the primary file relationship has been loaded. func (r RelatedImageFiles) PrimaryLoaded() bool { return r.primaryLoaded } // List returns the related files. Panics if the relationship has not been loaded. func (r RelatedImageFiles) List() []*file.ImageFile { if !r.Loaded() { panic("relationship has not been loaded") } return r.files } // Primary returns the primary file. Panics if the relationship has not been loaded. func (r RelatedImageFiles) Primary() *file.ImageFile { if !r.PrimaryLoaded() { panic("relationship has not been loaded") } return r.primaryFile } func (r *RelatedImageFiles) load(fn func() ([]*file.ImageFile, error)) error { if r.Loaded() { return nil } var err error r.files, err = fn() if err != nil { return err } if len(r.files) > 0 { r.primaryFile = r.files[0] } r.primaryLoaded = true return nil } func (r *RelatedImageFiles) loadPrimary(fn func() (*file.ImageFile, error)) error { if r.PrimaryLoaded() { return nil } var err error r.primaryFile, err = fn() if err != nil { return err } r.primaryLoaded = true return nil } type RelatedFiles struct { primaryFile file.File files []file.File primaryLoaded bool } func NewRelatedFiles(files []file.File) RelatedFiles { ret := RelatedFiles{ files: files, primaryLoaded: true, } if len(files) > 0 { ret.primaryFile = files[0] } return ret } // Loaded returns true if the relationship has been loaded. func (r RelatedFiles) Loaded() bool { return r.files != nil } // Loaded returns true if the primary file relationship has been loaded. func (r RelatedFiles) PrimaryLoaded() bool { return r.primaryLoaded } // List returns the related files. Panics if the relationship has not been loaded. func (r RelatedFiles) List() []file.File { if !r.Loaded() { panic("relationship has not been loaded") } return r.files } // Primary returns the primary file. Panics if the relationship has not been loaded. func (r RelatedFiles) Primary() file.File { if !r.PrimaryLoaded() { panic("relationship has not been loaded") } return r.primaryFile } func (r *RelatedFiles) load(fn func() ([]file.File, error)) error { if r.Loaded() { return nil } var err error r.files, err = fn() if err != nil { return err } if len(r.files) > 0 { r.primaryFile = r.files[0] } r.primaryLoaded = true return nil } func (r *RelatedFiles) loadPrimary(fn func() (file.File, error)) error { if r.PrimaryLoaded() { return nil } var err error r.primaryFile, err = fn() if err != nil { return err } r.primaryLoaded = true return nil } // RelatedStrings represents a list of related strings. // TODO - this can be made generic type RelatedStrings struct { list []string } // NewRelatedStrings returns a loaded RelatedStrings object with the provided values. // Loaded will return true when called on the returned object if the provided slice is not nil. func NewRelatedStrings(values []string) RelatedStrings { return RelatedStrings{ list: values, } } // Loaded returns true if the related IDs have been loaded. func (r RelatedStrings) Loaded() bool { return r.list != nil } func (r RelatedStrings) mustLoaded() { if !r.Loaded() { panic("list has not been loaded") } } // List returns the related values. Panics if the relationship has not been loaded. func (r RelatedStrings) List() []string { r.mustLoaded() return r.list } // Add adds the provided values to the list. Panics if the relationship has not been loaded. func (r *RelatedStrings) Add(values ...string) { r.mustLoaded() r.list = append(r.list, values...) } func (r *RelatedStrings) load(fn func() ([]string, error)) error { if r.Loaded() { return nil } values, err := fn() if err != nil { return err } if values == nil { values = []string{} } r.list = values return nil }