mirror of
https://github.com/tgdrive/teldrive.git
synced 2024-09-20 08:15:55 +08:00
fix bulkmove operation
This commit is contained in:
parent
bb47d88a89
commit
10c13e130b
141
pkg/database/migrations/20231221245015_functions.sql
Normal file
141
pkg/database/migrations/20231221245015_functions.sql
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in a new issue