From 98af02c565bc1ddbf25dbbdabe899476e28eaa2b Mon Sep 17 00:00:00 2001 From: Abhishek Shroff Date: Sun, 29 Sep 2024 14:03:58 +0530 Subject: [PATCH] [server] Merge rename functionality into move route --- server/internal/api/routes/resources.go | 42 +++--------------------- server/internal/core/filesystem.go | 43 +++++++++++-------------- server/internal/db/resources.sql.go | 34 +++++++++++++++++++ server/internal/webdav/handler.go | 12 ++----- server/sql/queries/resources.sql | 9 ++++++ 5 files changed, 68 insertions(+), 72 deletions(-) diff --git a/server/internal/api/routes/resources.go b/server/internal/api/routes/resources.go index e8158196..26aa38ea 100644 --- a/server/internal/api/routes/resources.go +++ b/server/internal/api/routes/resources.go @@ -48,12 +48,9 @@ type resourceMkdirParams struct { ParentID uuid.UUID `json:"parent_id" binding:"required"` } -type resourceRenameParams struct { - Name string `json:"name" binding:"required"` -} - type resourceMoveParams struct { - ParentID uuid.UUID `json:"parent_id" binding:"required"` + ParentID *uuid.UUID `json:"parent_id"` + Name string `json:"name"` } func SetupResourceRoutes(r *gin.RouterGroup) { @@ -63,7 +60,6 @@ func SetupResourceRoutes(r *gin.RouterGroup) { group.GET("/details/:id", handleResourceDetailsRoute) group.GET("/contents/:id", handleResourceContentsRoute) group.POST("/mkdir/:id", handleResourceMkdirRoute) - group.POST("/rename/:id", handleResourceRenameRoute) group.POST("/move/:id", handleResourceMoveRoute) group.PUT("/upload/:id", handleResourceUploadRoute) group.DELETE("/delete/:id", handleResourceDeleteRoute) @@ -192,40 +188,10 @@ func handleResourceMkdirRoute(c *gin.Context) { c.JSON(200, responseFromResource(res)) } -func handleResourceRenameRoute(c *gin.Context) { - var params resourceRenameParams - err := c.ShouldBindJSON(¶ms) - if err != nil || params.Name == "" { - panic(errInvalidParams) - } - - resourceID, err := uuid.Parse(c.Param("id")) - if err != nil { - panic(errResourceIDInvalid) - } - - fs := auth.GetFileSystem(c) - r, err := fs.ResourceByID(resourceID) - if err != nil { - if errors.Is(err, iofs.ErrNotExist) { - panic(errResourceNotFound) - } - panic(err) - } - if r, err := fs.UpdateName(r, params.Name); err != nil { - if errors.Is(err, core.ErrInsufficientPermissions) { - panic(errInsufficientPermissions) - } - panic(err) - } else { - c.JSON(200, responseFromResource(r)) - } -} - func handleResourceMoveRoute(c *gin.Context) { var params resourceMoveParams err := c.ShouldBindJSON(¶ms) - if err != nil || params.ParentID == uuid.Nil { + if err != nil || (params.ParentID == nil && params.Name == "") { panic(errInvalidParams) } @@ -243,7 +209,7 @@ func handleResourceMoveRoute(c *gin.Context) { panic(err) } - if r, err := fs.UpdateParent(r, params.ParentID); err != nil { + if r, err := fs.UpdateNameParent(r, params.Name, params.ParentID); err != nil { if errors.Is(err, core.ErrInsufficientPermissions) { panic(errInsufficientPermissions) } diff --git a/server/internal/core/filesystem.go b/server/internal/core/filesystem.go index 5a0667a7..471622d7 100644 --- a/server/internal/core/filesystem.go +++ b/server/internal/core/filesystem.go @@ -40,8 +40,7 @@ type FileSystem interface { ReadDir(r Resource) ([]Resource, error) CreateMemberResource(r Resource, id uuid.UUID, name string, dir bool) (Resource, error) DeleteRecursive(r Resource, hardDelete bool) (uuid.UUIDs, error) - UpdateName(r Resource, name string) (Resource, error) - UpdateParent(r Resource, parent uuid.UUID) (Resource, error) + UpdateNameParent(r Resource, name string, parent *uuid.UUID) (Resource, error) UpdatePermissions(r Resource, username string, permission Permission) error } @@ -266,19 +265,6 @@ func (f filesystem) DeleteRecursive(r Resource, hardDelete bool) (uuid.UUIDs, er } func (f filesystem) UpdateName(r Resource, name string) (Resource, error) { - if r.Name() == name { - return r, nil - } - if r.ParentID() == nil { - return nil, ErrInsufficientPermissions - } - parent, err := f.ResourceByID(*r.ParentID()) - if err != nil { - return nil, err - } - if parent.UserPermission() < PermissionReadWrite { - return nil, ErrInsufficientPermissions - } if r, err := f.db.UpdateResourceName(f.ctx, db.UpdateResourceNameParams{ID: r.ID(), Name: name}); err != nil { return nil, err } else { @@ -297,13 +283,17 @@ func (f filesystem) UpdateName(r Resource, name string) (Resource, error) { } } -func (f filesystem) UpdateParent(r Resource, parent uuid.UUID) (Resource, error) { +func (f filesystem) UpdateNameParent(r Resource, name string, parent *uuid.UUID) (Resource, error) { if r.ParentID() == nil { return nil, ErrInsufficientPermissions } - if *r.ParentID() == parent { - return nil, nil + if name == r.Name() { + name = "" } + if parent == r.ParentID() { + parent = nil + } + oldParent, err := f.ResourceByID(*r.ParentID()) if err != nil { return nil, err @@ -311,14 +301,17 @@ func (f filesystem) UpdateParent(r Resource, parent uuid.UUID) (Resource, error) if oldParent.UserPermission() < PermissionReadWrite { return nil, ErrInsufficientPermissions } - newParent, err := f.ResourceByID(parent) - if err != nil { - return nil, err + + if parent != nil { + newParent, err := f.ResourceByID(*parent) + if err != nil { + return nil, err + } + if newParent.UserPermission() < PermissionReadWrite { + return nil, ErrInsufficientPermissions + } } - if newParent.UserPermission() < PermissionReadWrite { - return nil, ErrInsufficientPermissions - } - if r, err := f.db.UpdateResourceParent(f.ctx, db.UpdateResourceParentParams{ID: r.ID(), Parent: parent}); err != nil { + if r, err := f.db.UpdateResourceNameParent(f.ctx, db.UpdateResourceNameParentParams{ID: r.ID(), Name: name, Parent: parent}); err != nil { return nil, err } else { return resource{ diff --git a/server/internal/db/resources.sql.go b/server/internal/db/resources.sql.go index 987639ce..3de83b5e 100644 --- a/server/internal/db/resources.sql.go +++ b/server/internal/db/resources.sql.go @@ -223,6 +223,40 @@ func (q *Queries) UpdateResourceName(ctx context.Context, arg UpdateResourceName return i, err } +const updateResourceNameParent = `-- name: UpdateResourceNameParent :one +UPDATE resources +SET + name = CASE WHEN ($1::text = '') THEN name ELSE $1::text END, + parent = COALESCE($2, parent), + modified = NOW() +WHERE id = $3::uuid +RETURNING id, parent, name, dir, created, modified, deleted, size, sha256sum, permissions +` + +type UpdateResourceNameParentParams struct { + Name string + Parent *uuid.UUID + ID uuid.UUID +} + +func (q *Queries) UpdateResourceNameParent(ctx context.Context, arg UpdateResourceNameParentParams) (Resource, error) { + row := q.db.QueryRow(ctx, updateResourceNameParent, arg.Name, arg.Parent, arg.ID) + var i Resource + err := row.Scan( + &i.ID, + &i.Parent, + &i.Name, + &i.Dir, + &i.Created, + &i.Modified, + &i.Deleted, + &i.Size, + &i.Sha256sum, + &i.Permissions, + ) + return i, err +} + const updateResourceParent = `-- name: UpdateResourceParent :one UPDATE resources SET diff --git a/server/internal/webdav/handler.go b/server/internal/webdav/handler.go index 81447528..2687172a 100644 --- a/server/internal/webdav/handler.go +++ b/server/internal/webdav/handler.go @@ -146,15 +146,9 @@ func (a adapter) Rename(ctx context.Context, oldName, newName string) error { return fs.ErrNotExist } - if *src.ParentID() != parent.ID() { - if _, err = a.fs.UpdateParent(src, parent.ID()); err != nil { - return err - } - } - if src.Name() != newName && newName != "" && newName != "/" { - if _, err = a.fs.UpdateName(src, newName); err != nil { - return err - } + parentID := parent.ID() + if _, err = a.fs.UpdateNameParent(src, newName, &parentID); err != nil { + return err } return nil } diff --git a/server/sql/queries/resources.sql b/server/sql/queries/resources.sql index 45df3a01..4c53a1c3 100644 --- a/server/sql/queries/resources.sql +++ b/server/sql/queries/resources.sql @@ -35,6 +35,15 @@ SET WHERE id = @id::uuid RETURNING *; +-- name: UpdateResourceNameParent :one +UPDATE resources +SET + name = CASE WHEN (@name::text = '') THEN name ELSE @name::text END, + parent = COALESCE(sqlc.narg('parent'), parent), + modified = NOW() +WHERE id = @id::uuid +RETURNING *; + -- name: DeleteRecursive :many