Finish add/remove root paths
This commit is contained in:
parent
c198e68daf
commit
d78cef300a
|
@ -28,3 +28,17 @@ func (a *Album) BeforeSave(tx *gorm.DB) (err error) {
|
|||
a.PathHash = hex.EncodeToString(hash[:])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Album) GetChildren(db *gorm.DB) (children []*Album, err error) {
|
||||
err = db.Raw(`
|
||||
WITH recursive sub_albums AS (
|
||||
SELECT * FROM albums AS root WHERE id = ?
|
||||
UNION ALL
|
||||
SELECT child.* FROM albums AS child JOIN sub_albums ON child.parent_album_id = sub_albums.id
|
||||
)
|
||||
|
||||
SELECT * FROM sub_albums
|
||||
`, a.ID).Find(&children).Error
|
||||
|
||||
return children, err
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@ package models
|
|||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Model struct {
|
||||
|
@ -14,5 +12,4 @@ type Model struct {
|
|||
type ModelTimestamps struct {
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
DeletedAt gorm.DeletedAt `gorm:"index"`
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@ package resolvers
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
api "github.com/photoview/photoview/api/graphql"
|
||||
"github.com/photoview/photoview/api/graphql/auth"
|
||||
|
@ -106,6 +109,8 @@ func (r *mutationResolver) InitialSetupWizard(ctx context.Context, username stri
|
|||
return nil, errors.New("not initial setup")
|
||||
}
|
||||
|
||||
rootPath = path.Clean(rootPath)
|
||||
|
||||
var token *models.AccessToken
|
||||
|
||||
transactionError := r.Database.Transaction(func(tx *gorm.DB) error {
|
||||
|
@ -220,12 +225,45 @@ func (r *mutationResolver) DeleteUser(ctx context.Context, id int) (*models.User
|
|||
|
||||
func (r *mutationResolver) UserAddRootPath(ctx context.Context, id int, rootPath string) (*models.Album, error) {
|
||||
|
||||
rootPath = path.Clean(rootPath)
|
||||
|
||||
var user models.User
|
||||
if err := r.Database.First(&user, id).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: Check if path exists and that user does not already own rootPath, directly or indirectly
|
||||
if !models.ValidRootPath(rootPath) {
|
||||
return nil, errors.New("invalid root path")
|
||||
}
|
||||
|
||||
upperPaths := make([]string, 1)
|
||||
upperPath := rootPath
|
||||
upperPaths[0] = upperPath
|
||||
for {
|
||||
|
||||
substrIndex := strings.LastIndex(upperPath, "/")
|
||||
if substrIndex == -1 {
|
||||
break
|
||||
}
|
||||
|
||||
if substrIndex == 0 {
|
||||
upperPaths = append(upperPaths, "/")
|
||||
break
|
||||
}
|
||||
|
||||
upperPath = upperPath[0:substrIndex]
|
||||
upperPaths = append(upperPaths, upperPath)
|
||||
}
|
||||
|
||||
var upperAlbums []models.Album
|
||||
if err := r.Database.Model(&user).Association("Albums").Find(&upperAlbums, "albums.path IN (?)", upperPaths); err != nil {
|
||||
// if err := r.Database.Model(models.Album{}).Where("path IN (?)", upperPaths).Find(&upperAlbums).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(upperAlbums) > 0 {
|
||||
return nil, errors.New(fmt.Sprintf("user already owns a path containing this path: %s", upperAlbums[0].Path))
|
||||
}
|
||||
|
||||
newAlbum, err := scanner.NewRootAlbum(r.Database, rootPath, &user)
|
||||
if err != nil {
|
||||
|
@ -242,7 +280,22 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
result := r.Database.Exec("DELETE FROM user_albums WHERE album_id = ? AND user_id = ?", albumID, userID)
|
||||
if err := r.Database.Raw("DELETE FROM user_albums WHERE user_id = ? AND album_id = ?", userID, albumID).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
children, err := album.GetChildren(r.Database)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
childAlbumIDs := make([]int, len(children))
|
||||
for i, child := range children {
|
||||
childAlbumIDs[i] = child.ID
|
||||
}
|
||||
|
||||
// result := r.Database.Delete(models.Album{}, "id IN (?) OR id = ?", childAlbumIDs, album.ID)
|
||||
result := r.Database.Exec("DELETE FROM user_albums WHERE user_id = ? and album_id IN (?)", userID, childAlbumIDs)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
|
|
@ -19,6 +19,20 @@ func NewRootAlbum(db *gorm.DB, rootPath string, owner *models.User) (*models.Alb
|
|||
*owner,
|
||||
}
|
||||
|
||||
var matchedAlbums []models.Album
|
||||
if err := db.Where("path_hash = MD5(?)", rootPath).Find(&matchedAlbums).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(matchedAlbums) > 0 {
|
||||
album := matchedAlbums[0]
|
||||
|
||||
if err := db.Model(&owner).Association("Albums").Append(&album); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to add owner to already existing album")
|
||||
}
|
||||
|
||||
return &album, nil
|
||||
} else {
|
||||
album := models.Album{
|
||||
Title: path.Base(rootPath),
|
||||
Path: rootPath,
|
||||
|
@ -30,6 +44,7 @@ func NewRootAlbum(db *gorm.DB, rootPath string, owner *models.User) (*models.Alb
|
|||
}
|
||||
|
||||
return &album, nil
|
||||
}
|
||||
}
|
||||
|
||||
func scanAlbum(album *models.Album, cache *AlbumScannerCache, db *gorm.DB) {
|
||||
|
|
Loading…
Reference in New Issue