fix bulkmove operation

This commit is contained in:
divyam234 2023-12-22 00:43:26 +05:30
parent bb47d88a89
commit 10c13e130b
4 changed files with 157 additions and 8 deletions

View file

@ -0,0 +1,141 @@
-- +goose Up
-- +goose StatementBegin
DROP FUNCTION IF EXISTS teldrive.update_folder;
DROP FUNCTION IF EXISTS teldrive.move_directory;
DROP FUNCTION IF EXISTS teldrive.move_items;
CREATE OR REPLACE FUNCTION teldrive.update_folder(
folder_id TEXT,
new_name TEXT,
u_id bigint
) RETURNS SETOF teldrive.files
LANGUAGE plpgsql
AS $$
DECLARE
old_path TEXT;
new_path TEXT;
BEGIN
SELECT
path
INTO
old_path
FROM
teldrive.files
WHERE
id = folder_id and user_id = u_id;
new_path := substring(old_path from '(.*)/[^/]*$') || '/' || new_name;
UPDATE
teldrive.files
SET path = new_path ,name = new_name WHERE id = folder_id and user_id = u_id;
UPDATE
teldrive.files
SET path = new_path || substring(path, length(old_path) + 1)
WHERE
type='folder' and user_id = u_id and path LIKE old_path || '/%';
RETURN QUERY
SELECT
*
FROM
teldrive.files
WHERE
id = folder_id;
END;
$$;
CREATE OR REPLACE FUNCTION teldrive.move_directory(src text, dest text, u_id bigint)
RETURNS void
LANGUAGE plpgsql
AS $$
DECLARE
src_parent TEXT;
src_base TEXT;
dest_parent TEXT;
dest_base TEXT;
dest_id text;
dest_parent_id text;
src_id text;
begin
SELECT id into src_id FROM teldrive.files WHERE path = src and user_id = u_id;
SELECT id into dest_id FROM teldrive.files WHERE path = dest and user_id = u_id;
IF src_id is NULL THEN
RAISE EXCEPTION 'source directory not found';
END IF;
IF dest_id is not NULL then
RAISE EXCEPTION 'destination directory exists';
END IF;
SELECT parent, base INTO src_parent,src_base FROM teldrive.split_path(src);
SELECT parent, base INTO dest_parent, dest_base FROM teldrive.split_path(dest);
IF src_parent != dest_parent then
select id into dest_id from teldrive.create_directories(u_id,dest);
UPDATE teldrive.files SET parent_id = dest_id WHERE parent_id = src_id;
update
teldrive.files
SET path = dest || substring(path, length(src) + 1)
where type='folder' and user_id = u_id and path LIKE src || '/%';
delete from teldrive.files where id = src_id;
END IF;
IF src_base != dest_base and src_parent = dest_parent then
perform teldrive.update_folder(src_id,dest_base,u_id);
END IF;
END;
$$
;
CREATE OR REPLACE FUNCTION teldrive.move_items(file_ids text[], dest text, u_id bigint)
RETURNS VOID AS $$
declare
dest_id TEXT;
BEGIN
SELECT id INTO dest_id FROM teldrive.files WHERE path = dest and user_id = u_id;
IF dest_id is NULL then
select id into dest_id from teldrive.create_directories(u_id,dest);
END IF;
UPDATE teldrive.files
SET parent_id = dest_id
WHERE id = ANY(file_ids);
WITH RECURSIVE folders AS (
SELECT id, name, path,
CASE
WHEN dest = '/' THEN '/' || name
ELSE dest || '/' || name
END as new_path
FROM teldrive.files
WHERE id = ANY(file_ids) AND type = 'folder' and user_id = u_id
UNION ALL
SELECT f.id, f.name, f.path,
CASE
WHEN fo.new_path = '/' THEN '/' || f.name
ELSE fo.new_path || '/' || f.name
END
FROM teldrive.files f
INNER JOIN folders fo ON f.parent_id = fo.id WHERE type = 'folder'
)
UPDATE teldrive.files
SET path = folders.new_path
FROM folders
WHERE teldrive.files.id = folders.id;
END;
$$ LANGUAGE plpgsql;
-- +goose StatementEnd

View file

@ -28,6 +28,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/jackc/pgx/v5/pgconn"
"github.com/jackc/pgx/v5/pgtype"
"github.com/mitchellh/mapstructure"
"gorm.io/gorm"
"gorm.io/gorm/clause"
@ -139,6 +140,8 @@ func (fs *FileService) UpdateFile(c *gin.Context) (*schemas.FileOut, *types.AppE
fileID := c.Param("fileID")
userId, _ := getUserAuth(c)
var fileUpdate schemas.UpdateFile
var files []models.File
@ -148,7 +151,7 @@ func (fs *FileService) UpdateFile(c *gin.Context) (*schemas.FileOut, *types.AppE
}
if fileUpdate.Type == "folder" && fileUpdate.Name != "" {
if err := fs.Db.Raw("select * from teldrive.update_folder(?, ?)", fileID, fileUpdate.Name).Scan(&files).Error; err != nil {
if err := fs.Db.Raw("select * from teldrive.update_folder(?, ?, ?)", fileID, fileUpdate.Name, userId).Scan(&files).Error; err != nil {
return nil, fs.logAndReturn(updateFileContext, err, http.StatusInternalServerError)
}
} else {
@ -421,15 +424,16 @@ func (fs *FileService) MoveFiles(c *gin.Context) (*schemas.Message, *types.AppEr
if err := c.ShouldBindJSON(&payload); err != nil {
return nil, fs.logAndReturn(moveFilesContext, err, http.StatusBadRequest)
}
userId, _ := getUserAuth(c)
var destination models.File
if err := fs.Db.Model(&models.File{}).Select("id").Where("path = ?", payload.Destination).First(&destination).Error; errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fs.logAndReturn(moveFilesContext, err, http.StatusNotFound)
items := pgtype.Array[string]{
Elements: payload.Files,
Valid: true,
Dims: []pgtype.ArrayDimension{{Length: 1, LowerBound: 1}},
}
if err := fs.Db.Model(&models.File{}).Where("id IN ?", payload.Files).UpdateColumn("parent_id", destination.ID).Error; err != nil {
return nil, fs.logAndReturn(moveFilesContext, err, http.StatusInternalServerError)
if err := fs.Db.Exec("select * from teldrive.move_items(? , ? , ?)", items, payload.Destination, userId).Error; err != nil {
return nil, fs.logAndReturn(moveDirectoryContext, err, http.StatusInternalServerError)
}
return &schemas.Message{Message: "files moved"}, nil

View file

@ -246,6 +246,10 @@ func (us *UploadService) UploadFile(c *gin.Context) (*schemas.UploadPartOut, *ty
}
if err := us.Db.Create(partUpload).Error; err != nil {
//delete uploaded part if upload fails
if message.ID != 0 {
api.ChannelsDeleteMessages(ctx, &tg.ChannelsDeleteMessagesRequest{Channel: channel, ID: []int{message.ID}})
}
return err
}

@ -1 +1 @@
Subproject commit f5a2e43f0e63c4602f03a45b5b26249f4d3e50c9
Subproject commit 63cc5067eb3e767f0699f4e259de328041cf0618