added dirMove functionality

This commit is contained in:
divyam234 2023-11-02 01:27:07 +05:30
parent 88faca0c78
commit f2ca5162a3
5 changed files with 168 additions and 72 deletions

View file

@ -37,77 +37,6 @@ end;
$$;
-- +goose StatementEnd
-- +goose StatementBegin
create function teldrive.update_folder(folder_id text,
new_name text default null,
new_path text default null)
returns setof teldrive.files
language plpgsql
as $$
declare folder record;
path_items text [];
begin
if new_path is null then
select
*
into
folder
from
teldrive.files
where
id = folder_id;
path_items := string_to_array(folder.path,
'/');
path_items [array_length(path_items,
1)] := new_name;
new_path := array_to_string(path_items,
'/');
end if;
update
teldrive.files
set
path = new_path,
name = new_name
where
id = folder_id;
for folder in
select
*
from
teldrive.files
where
type = 'folder'
and parent_id = folder_id loop call teldrive.update_folder(
folder.id,
folder.name,
concat(new_path,
'/',
folder.name)
);
end loop;
return query
select
*
from
teldrive.files
where
id = folder_id;
end;
$$
;
-- +goose StatementEnd
-- +goose StatementBegin
create procedure teldrive.delete_files(in file_ids text[],
in op text default 'bulk')
@ -184,5 +113,4 @@ $$
-- +goose Down
drop procedure if exists teldrive.update_size;
drop function if exists teldrive.update_folder;
drop procedure if exists teldrive.delete_files;

View file

@ -0,0 +1,134 @@
-- +goose Up
-- +goose StatementBegin
CREATE OR REPLACE FUNCTION teldrive.split_path(path text, OUT parent text, OUT base text) AS $$
BEGIN
IF path = '/' THEN
parent := '/';
base := NULL;
RETURN;
END IF;
IF left(path, 1) <> '/' THEN
path := '/' || path;
END IF;
IF right(path, 1) = '/' THEN
path := left(path, length(path) - 1);
END IF;
parent := left(path, length(path) - position('/' in reverse(path)));
base := right(path, position('/' in reverse(path)) - 1);
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION teldrive.update_folder(
folder_id TEXT,
new_name TEXT,
new_path TEXT DEFAULT NULL
) RETURNS SETOF teldrive.files
LANGUAGE plpgsql
AS $$
DECLARE
folder RECORD;
path_items TEXT[];
BEGIN
IF new_path IS NULL THEN
SELECT
*
INTO
folder
FROM
teldrive.files
WHERE
id = folder_id;
path_items := string_to_array(folder.path, '/');
path_items[array_length(path_items, 1)] := new_name;
new_path := array_to_string(path_items, '/');
END IF;
UPDATE
teldrive.files
SET
path = new_path,
name = new_name
WHERE
id = folder_id;
FOR folder IN
SELECT
*
FROM
teldrive.files
WHERE
type = 'folder'
AND parent_id = folder_id
LOOP
perform from teldrive.update_folder(
folder.id,
folder.name,
concat(new_path, '/', folder.name)
);
END LOOP;
RETURN QUERY
SELECT
*
FROM
teldrive.files
WHERE
id = folder_id;
END;
$$;
CREATE OR REPLACE FUNCTION teldrive.move_directory(src text, dest text,user_id bigint) RETURNS VOID AS $$
DECLARE
src_parent TEXT;
src_base TEXT;
dest_parent TEXT;
dest_base TEXT;
dest_id text;
src_id text;
BEGIN
IF NOT EXISTS (SELECT 1 FROM teldrive.files WHERE path = src) THEN
RAISE EXCEPTION 'source directory not found';
END IF;
IF EXISTS (SELECT 1 FROM teldrive.files WHERE path = dest) 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(user_id,dest);
update teldrive.files set parent_id = dest_id where parent_id = (select id from teldrive.files where path = src) and id != dest_id;
IF POSITION(CONCAT(src,'/') IN dest) = 0 then
delete from teldrive.files where path = src;
END IF;
END IF;
IF src_base != dest_base and src_parent = dest_parent then
select id into src_id from teldrive.files where path = src;
perform from teldrive.update_folder(src_id,dest_base);
END IF;
END;
$$ LANGUAGE plpgsql;
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
drop function if exists teldrive.split_path;
drop function if exists teldrive.update_folder;
drop function if exists teldrive.move_directory;
-- +goose StatementEnd

View file

@ -107,4 +107,16 @@ func addFileRoutes(rg *gin.RouterGroup) {
c.JSON(http.StatusOK, res)
})
r.POST("/movedir", Authmiddleware, func(c *gin.Context) {
res, err := fileService.MoveDirectory(c)
if err != nil {
c.AbortWithError(err.Code, err.Error)
return
}
c.JSON(http.StatusOK, res)
})
}

View file

@ -73,6 +73,11 @@ type FileOperation struct {
Destination string `json:"destination,omitempty"`
}
type DirMove struct {
Source string `json:"source"`
Destination string `json:"destination"`
}
type MkDir struct {
Path string `json:"path"`
}

View file

@ -306,6 +306,23 @@ func (fs *FileService) DeleteFiles(c *gin.Context) (*schemas.Message, *types.App
return &schemas.Message{Status: true, Message: "files deleted"}, nil
}
func (fs *FileService) MoveDirectory(c *gin.Context) (*schemas.Message, *types.AppError) {
var payload schemas.DirMove
if err := c.ShouldBindJSON(&payload); err != nil {
return nil, &types.AppError{Error: errors.New("invalid request payload"), Code: http.StatusBadRequest}
}
userId, _ := getUserAuth(c)
if err := fs.Db.Exec("select * from teldrive.move_directory(? , ? , ?)", payload.Source, payload.Destination, userId).Error; err != nil {
return nil, &types.AppError{Error: errors.New("failed to move directory"), Code: http.StatusInternalServerError}
}
return &schemas.Message{Status: true, Message: "directory moved"}, nil
}
func (fs *FileService) GetFileStream(c *gin.Context) {
w := c.Writer