teldrive/database/migrations/20231102005615_functions.sql
2023-11-02 01:27:07 +05:30

134 lines
3.1 KiB
PL/PgSQL

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