refactor: improve deletion

This commit is contained in:
divyam234 2024-06-11 19:29:05 +05:30
parent febdb3fe84
commit 54a5fd55e1
4 changed files with 99 additions and 12 deletions

View file

@ -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

View file

@ -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

View file

@ -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"`

View file

@ -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
}