mirror of
https://github.com/tgdrive/teldrive.git
synced 2025-10-08 22:37:13 +08:00
refactor: improve deletion
This commit is contained in:
parent
febdb3fe84
commit
54a5fd55e1
4 changed files with 99 additions and 12 deletions
|
@ -0,0 +1,83 @@
|
||||||
|
-- +goose Up
|
||||||
|
-- +goose StatementBegin
|
||||||
|
DROP PROCEDURE IF EXISTS teldrive.delete_files;
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE teldrive.delete_folder_recursive(
|
||||||
|
IN src text,
|
||||||
|
IN u_id bigint
|
||||||
|
)
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $procedure$
|
||||||
|
DECLARE
|
||||||
|
folder_id text;
|
||||||
|
folder_ids text[];
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
IF position('/' in src) = 1 THEN
|
||||||
|
select id into folder_id from teldrive.get_file_from_path(src,u_id);
|
||||||
|
IF folder_id IS NULL THEN
|
||||||
|
RAISE EXCEPTION 'source not found';
|
||||||
|
END IF;
|
||||||
|
ELSE
|
||||||
|
folder_id := src;
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM teldrive.files WHERE id = folder_id) THEN
|
||||||
|
RAISE EXCEPTION 'source not found';
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
WITH RECURSIVE folder_tree AS (
|
||||||
|
SELECT id
|
||||||
|
FROM teldrive.files
|
||||||
|
WHERE id = folder_id
|
||||||
|
AND user_id = u_id and type='folder'
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT f.id
|
||||||
|
FROM teldrive.files f
|
||||||
|
JOIN folder_tree ft ON f.parent_id = ft.id
|
||||||
|
WHERE f.user_id = u_id and f.type='folder'
|
||||||
|
) SELECT array_agg(id) INTO folder_ids FROM folder_tree;
|
||||||
|
|
||||||
|
UPDATE teldrive.files
|
||||||
|
SET status = 'pending_deletion'
|
||||||
|
WHERE parent_id = ANY (folder_ids) and type='file' and user_id = u_id;
|
||||||
|
|
||||||
|
DELETE FROM teldrive.files
|
||||||
|
WHERE id = ANY (folder_ids) AND user_id = u_id;
|
||||||
|
END;
|
||||||
|
$procedure$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE teldrive.delete_files_bulk(
|
||||||
|
IN file_ids text[],
|
||||||
|
IN u_id bigint
|
||||||
|
)
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $procedure$
|
||||||
|
DECLARE
|
||||||
|
folder_ids text[];
|
||||||
|
BEGIN
|
||||||
|
WITH RECURSIVE folder_tree AS (
|
||||||
|
SELECT id
|
||||||
|
FROM teldrive.files
|
||||||
|
WHERE id = ANY (file_ids)
|
||||||
|
AND user_id = u_id AND type = 'folder'
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT f.id
|
||||||
|
FROM teldrive.files f
|
||||||
|
JOIN folder_tree ft ON f.parent_id = ft.id
|
||||||
|
WHERE f.user_id = u_id AND f.type = 'folder'
|
||||||
|
) SELECT array_agg(id) INTO folder_ids FROM folder_tree;
|
||||||
|
|
||||||
|
UPDATE teldrive.files
|
||||||
|
SET status = 'pending_deletion'
|
||||||
|
WHERE (id = ANY (file_ids) OR parent_id = ANY (folder_ids))
|
||||||
|
AND type = 'file' AND user_id = u_id;
|
||||||
|
|
||||||
|
DELETE FROM teldrive.files
|
||||||
|
WHERE id = ANY (folder_ids) AND user_id = u_id;
|
||||||
|
END;
|
||||||
|
$procedure$
|
||||||
|
-- +goose StatementEnd
|
|
@ -138,7 +138,7 @@ func (fc *Controller) DeleteFiles(c *gin.Context) {
|
||||||
|
|
||||||
userId, _ := services.GetUserAuth(c)
|
userId, _ := services.GetUserAuth(c)
|
||||||
|
|
||||||
var payload schemas.FileOperation
|
var payload schemas.DeleteOperation
|
||||||
if err := c.ShouldBindJSON(&payload); err != nil {
|
if err := c.ShouldBindJSON(&payload); err != nil {
|
||||||
httputil.NewError(c, http.StatusBadRequest, err)
|
httputil.NewError(c, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -78,6 +78,10 @@ type FileOperation struct {
|
||||||
Files []string `json:"files" binding:"required"`
|
Files []string `json:"files" binding:"required"`
|
||||||
Destination string `json:"destination,omitempty"`
|
Destination string `json:"destination,omitempty"`
|
||||||
}
|
}
|
||||||
|
type DeleteOperation struct {
|
||||||
|
Files []string `json:"files,omitempty"`
|
||||||
|
Source string `json:"source,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type DirMove struct {
|
type DirMove struct {
|
||||||
Source string `json:"source" binding:"required"`
|
Source string `json:"source" binding:"required"`
|
||||||
|
|
|
@ -30,7 +30,6 @@ import (
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
|
||||||
"gorm.io/datatypes"
|
"gorm.io/datatypes"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
|
@ -301,24 +300,25 @@ func (fs *FileService) MakeDirectory(userId int64, payload *schemas.MkDir) (*sch
|
||||||
|
|
||||||
func (fs *FileService) MoveFiles(userId int64, payload *schemas.FileOperation) (*schemas.Message, *types.AppError) {
|
func (fs *FileService) MoveFiles(userId int64, payload *schemas.FileOperation) (*schemas.Message, *types.AppError) {
|
||||||
|
|
||||||
items := pgtype.Array[string]{
|
if err := fs.db.Exec("select * from teldrive.move_items($1 , $2 , $3)", payload.Files, payload.Destination, userId).Error; err != nil {
|
||||||
Elements: payload.Files,
|
|
||||||
Valid: true,
|
|
||||||
Dims: []pgtype.ArrayDimension{{Length: int32(len(payload.Files)), LowerBound: 1}},
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := fs.db.Exec("select * from teldrive.move_items(? , ? , ?)", items, payload.Destination, userId).Error; err != nil {
|
|
||||||
return nil, &types.AppError{Error: err}
|
return nil, &types.AppError{Error: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &schemas.Message{Message: "files moved"}, nil
|
return &schemas.Message{Message: "files moved"}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FileService) DeleteFiles(userId int64, payload *schemas.FileOperation) (*schemas.Message, *types.AppError) {
|
func (fs *FileService) DeleteFiles(userId int64, payload *schemas.DeleteOperation) (*schemas.Message, *types.AppError) {
|
||||||
|
|
||||||
if err := fs.db.Exec("call teldrive.delete_files($1)", payload.Files).Error; err != nil {
|
if payload.Source != "" {
|
||||||
|
if err := fs.db.Exec("call teldrive.delete_folder_recursive($1 , $2)", payload.Source, userId).Error; err != nil {
|
||||||
return nil, &types.AppError{Error: err}
|
return nil, &types.AppError{Error: err}
|
||||||
}
|
}
|
||||||
|
} else if payload.Source == "" && len(payload.Files) > 0 {
|
||||||
|
if err := fs.db.Exec("call teldrive.delete_files_bulk($1 , $2)", payload.Files, userId).Error; err != nil {
|
||||||
|
return nil, &types.AppError{Error: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return &schemas.Message{Message: "files deleted"}, nil
|
return &schemas.Message{Message: "files deleted"}, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue