mirror of
https://github.com/tgdrive/teldrive.git
synced 2025-09-28 17:34:26 +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)
|
||||
|
||||
var payload schemas.FileOperation
|
||||
var payload schemas.DeleteOperation
|
||||
if err := c.ShouldBindJSON(&payload); err != nil {
|
||||
httputil.NewError(c, http.StatusBadRequest, err)
|
||||
return
|
||||
|
|
|
@ -78,6 +78,10 @@ type FileOperation struct {
|
|||
Files []string `json:"files" binding:"required"`
|
||||
Destination string `json:"destination,omitempty"`
|
||||
}
|
||||
type DeleteOperation struct {
|
||||
Files []string `json:"files,omitempty"`
|
||||
Source string `json:"source,omitempty"`
|
||||
}
|
||||
|
||||
type DirMove struct {
|
||||
Source string `json:"source" binding:"required"`
|
||||
|
|
|
@ -30,7 +30,6 @@ import (
|
|||
"github.com/gotd/td/tg"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"gorm.io/datatypes"
|
||||
"gorm.io/gorm"
|
||||
"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) {
|
||||
|
||||
items := pgtype.Array[string]{
|
||||
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 {
|
||||
if err := fs.db.Exec("select * from teldrive.move_items($1 , $2 , $3)", payload.Files, payload.Destination, userId).Error; err != nil {
|
||||
return nil, &types.AppError{Error: err}
|
||||
}
|
||||
|
||||
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}
|
||||
}
|
||||
} 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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue