mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-07 22:06:38 +08:00
support multiple roots per library
This commit is contained in:
@@ -3,6 +3,7 @@ package repository
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
@@ -17,17 +18,51 @@ func (r *LibraryRepository) Create(ctx context.Context, l *model.Library) error
|
||||
return r.db.WithContext(ctx).Create(l).Error
|
||||
}
|
||||
|
||||
func (r *LibraryRepository) CreateWithRoots(ctx context.Context, l *model.Library, roots []model.LibraryRoot) error {
|
||||
if !r.hasLibraryRootsTable() {
|
||||
return r.Create(ctx, l)
|
||||
}
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Create(l).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range roots {
|
||||
roots[i].LibraryID = l.ID
|
||||
if roots[i].SortOrder == 0 {
|
||||
roots[i].SortOrder = i
|
||||
}
|
||||
if err := tx.Create(&roots[i]).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
l.Roots = roots
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// List returns all enabled+disabled libraries.
|
||||
func (r *LibraryRepository) List(ctx context.Context) ([]model.Library, error) {
|
||||
var ls []model.Library
|
||||
err := r.db.WithContext(ctx).Order("created_at asc").Find(&ls).Error
|
||||
q := r.db.WithContext(ctx).Order("created_at asc")
|
||||
if r.hasLibraryRootsTable() {
|
||||
q = q.Preload("Roots", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Order("sort_order asc, created_at asc")
|
||||
})
|
||||
}
|
||||
err := q.Find(&ls).Error
|
||||
return ls, err
|
||||
}
|
||||
|
||||
// FindByID returns the library, or (nil, nil) when missing.
|
||||
func (r *LibraryRepository) FindByID(ctx context.Context, id string) (*model.Library, error) {
|
||||
var l model.Library
|
||||
err := r.db.WithContext(ctx).Where("id = ?", id).First(&l).Error
|
||||
q := r.db.WithContext(ctx).Where("id = ?", id)
|
||||
if r.hasLibraryRootsTable() {
|
||||
q = q.Preload("Roots", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Order("sort_order asc, created_at asc")
|
||||
})
|
||||
}
|
||||
err := q.First(&l).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -42,3 +77,62 @@ func (r *LibraryRepository) FindByID(ctx context.Context, id string) (*model.Lib
|
||||
func (r *LibraryRepository) Delete(ctx context.Context, id string) error {
|
||||
return r.db.WithContext(ctx).Delete(&model.Library{}, "id = ?", id).Error
|
||||
}
|
||||
|
||||
func (r *LibraryRepository) ListRoots(ctx context.Context, libraryID string) ([]model.LibraryRoot, error) {
|
||||
if !r.hasLibraryRootsTable() {
|
||||
return nil, nil
|
||||
}
|
||||
var roots []model.LibraryRoot
|
||||
err := r.db.WithContext(ctx).
|
||||
Where("library_id = ?", libraryID).
|
||||
Order("sort_order asc, created_at asc").
|
||||
Find(&roots).Error
|
||||
return roots, err
|
||||
}
|
||||
|
||||
func (r *LibraryRepository) FindRootByID(ctx context.Context, libraryID, rootID string) (*model.LibraryRoot, error) {
|
||||
if !r.hasLibraryRootsTable() {
|
||||
return nil, nil
|
||||
}
|
||||
var root model.LibraryRoot
|
||||
q := r.db.WithContext(ctx).Where("id = ?", rootID)
|
||||
if strings.TrimSpace(libraryID) != "" {
|
||||
q = q.Where("library_id = ?", libraryID)
|
||||
}
|
||||
err := q.First(&root).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &root, nil
|
||||
}
|
||||
|
||||
func (r *LibraryRepository) CreateRoot(ctx context.Context, root *model.LibraryRoot) error {
|
||||
if !r.hasLibraryRootsTable() {
|
||||
return nil
|
||||
}
|
||||
return r.db.WithContext(ctx).Create(root).Error
|
||||
}
|
||||
|
||||
func (r *LibraryRepository) UpdateRoot(ctx context.Context, root *model.LibraryRoot, updates map[string]any) error {
|
||||
if !r.hasLibraryRootsTable() {
|
||||
return nil
|
||||
}
|
||||
if root == nil || strings.TrimSpace(root.ID) == "" || len(updates) == 0 {
|
||||
return nil
|
||||
}
|
||||
return r.db.WithContext(ctx).Model(&model.LibraryRoot{}).Where("id = ?", root.ID).Updates(updates).Error
|
||||
}
|
||||
|
||||
func (r *LibraryRepository) DeleteRoot(ctx context.Context, libraryID, rootID string) error {
|
||||
if !r.hasLibraryRootsTable() {
|
||||
return nil
|
||||
}
|
||||
return r.db.WithContext(ctx).Where("library_id = ?", libraryID).Delete(&model.LibraryRoot{}, "id = ?", rootID).Error
|
||||
}
|
||||
|
||||
func (r *LibraryRepository) hasLibraryRootsTable() bool {
|
||||
return r != nil && r.db != nil && r.db.Migrator().HasTable(&model.LibraryRoot{})
|
||||
}
|
||||
|
||||
@@ -223,6 +223,12 @@ func addMediaPlacementUpdates(updates map[string]any, existing, incoming model.M
|
||||
updates["library_id"] = incoming.LibraryID
|
||||
}
|
||||
}
|
||||
if incoming.LibraryRootID != "" && incoming.LibraryRootID != existing.LibraryRootID {
|
||||
updates["library_root_id"] = incoming.LibraryRootID
|
||||
}
|
||||
if incoming.RelativePath != "" && incoming.RelativePath != existing.RelativePath {
|
||||
updates["relative_path"] = incoming.RelativePath
|
||||
}
|
||||
seasonChanged := (incoming.SeasonNum > 0 || incoming.EpisodeNum > 0) && existing.SeasonNum != incoming.SeasonNum
|
||||
episodeChanged := incoming.EpisodeNum > 0 && existing.EpisodeNum != incoming.EpisodeNum
|
||||
if seasonChanged {
|
||||
@@ -355,6 +361,12 @@ func (r *MediaRepository) DeleteByLibrary(ctx context.Context, libraryID string)
|
||||
return r.db.WithContext(ctx).Where("library_id = ?", libraryID).Delete(&model.Media{}).Error
|
||||
}
|
||||
|
||||
func (r *MediaRepository) DeleteByLibraryRoot(ctx context.Context, libraryID, rootID string) error {
|
||||
return r.db.WithContext(ctx).
|
||||
Where("library_id = ? AND library_root_id = ?", libraryID, rootID).
|
||||
Delete(&model.Media{}).Error
|
||||
}
|
||||
|
||||
// PurgeByLibrary permanently removes media tied to a library. Used for virtual
|
||||
// cloud mounts where "remove mount" must not populate the recycle bin.
|
||||
func (r *MediaRepository) PurgeByLibrary(ctx context.Context, libraryID string) error {
|
||||
|
||||
Reference in New Issue
Block a user