mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-28 11:16:37 +08:00
184 lines
5.1 KiB
Go
184 lines
5.1 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/ShukeBta/MMTL/internal/model"
|
|
)
|
|
|
|
// LibraryRepository persists model.Library records.
|
|
type LibraryRepository struct{ db *gorm.DB }
|
|
|
|
// Create persists a new library row.
|
|
func (r *LibraryRepository) Create(ctx context.Context, l *model.Library) error {
|
|
if l != nil && l.SortOrder == 0 {
|
|
var maxSort int
|
|
_ = r.db.WithContext(ctx).Model(&model.Library{}).Select("COALESCE(MAX(sort_order), -1)").Scan(&maxSort)
|
|
l.SortOrder = maxSort + 1
|
|
}
|
|
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 l != nil && l.SortOrder == 0 {
|
|
var maxSort int
|
|
_ = tx.Model(&model.Library{}).Select("COALESCE(MAX(sort_order), -1)").Scan(&maxSort)
|
|
l.SortOrder = maxSort + 1
|
|
}
|
|
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
|
|
}
|
|
enabled := roots[i].Enabled
|
|
if err := tx.Create(&roots[i]).Error; err != nil {
|
|
return err
|
|
}
|
|
if !enabled {
|
|
if err := tx.Model(&model.LibraryRoot{}).Where("id = ?", roots[i].ID).Update("enabled", false).Error; err != nil {
|
|
return err
|
|
}
|
|
roots[i].Enabled = false
|
|
}
|
|
}
|
|
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
|
|
q := r.db.WithContext(ctx).Order("sort_order asc, 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
|
|
}
|
|
|
|
// SetSortOrder assigns sort_order to libraries, preserving position order for
|
|
// any library not present in the provided map.
|
|
func (r *LibraryRepository) SetSortOrder(ctx context.Context, ids []string) error {
|
|
if len(ids) == 0 {
|
|
return nil
|
|
}
|
|
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
|
for i, id := range ids {
|
|
if err := tx.Model(&model.Library{}).Where("id = ?", id).
|
|
Update("sort_order", i).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// 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
|
|
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
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &l, nil
|
|
}
|
|
|
|
// Delete 物理删除媒体库。
|
|
func (r *LibraryRepository) Delete(ctx context.Context, id string) error {
|
|
return r.db.WithContext(ctx).Unscoped().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
|
|
}
|
|
enabled := root.Enabled
|
|
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
|
if err := tx.Create(root).Error; err != nil {
|
|
return err
|
|
}
|
|
if !enabled {
|
|
if err := tx.Model(&model.LibraryRoot{}).Where("id = ?", root.ID).Update("enabled", false).Error; err != nil {
|
|
return err
|
|
}
|
|
root.Enabled = false
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
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).Unscoped().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{})
|
|
}
|