mirror of
https://github.com/tgdrive/teldrive.git
synced 2025-01-10 17:19:56 +08:00
262 lines
6.8 KiB
PL/PgSQL
262 lines
6.8 KiB
PL/PgSQL
-- +goose Up
|
|
-- +goose StatementBegin
|
|
|
|
CREATE OR REPLACE PROCEDURE teldrive.update_size() LANGUAGE PLPGSQL AS $$
|
|
DECLARE
|
|
rec RECORD;
|
|
total_size BIGINT;
|
|
BEGIN
|
|
FOR rec IN
|
|
SELECT id
|
|
FROM files
|
|
WHERE type = 'folder'
|
|
ORDER BY depth DESC
|
|
LOOP
|
|
total_size := (
|
|
SELECT SUM(size) AS total_size
|
|
FROM teldrive.files
|
|
WHERE parent_id = rec.id
|
|
);
|
|
|
|
UPDATE teldrive.files
|
|
SET size = total_size
|
|
WHERE id = rec.id;
|
|
END LOOP;
|
|
END;
|
|
$$;
|
|
|
|
|
|
CREATE OR REPLACE PROCEDURE teldrive.delete_files(IN file_ids TEXT[], IN op TEXT DEFAULT 'bulk') LANGUAGE PLPGSQL AS $$
|
|
DECLARE
|
|
rec RECORD;
|
|
BEGIN
|
|
IF op = 'bulk' THEN
|
|
FOR rec IN
|
|
SELECT id, type
|
|
FROM teldrive.files
|
|
WHERE id = ANY (file_ids)
|
|
LOOP
|
|
IF rec.type = 'folder' THEN
|
|
CALL teldrive.delete_files(ARRAY[rec.id], 'single');
|
|
END IF;
|
|
|
|
DELETE FROM teldrive.files
|
|
WHERE id = rec.id;
|
|
END LOOP;
|
|
ELSE
|
|
FOR rec IN
|
|
SELECT id, type
|
|
FROM teldrive.files
|
|
WHERE parent_id = file_ids[1]
|
|
LOOP
|
|
IF rec.type = 'folder' THEN
|
|
CALL teldrive.delete_files(ARRAY[rec.id], 'single');
|
|
END IF;
|
|
|
|
DELETE FROM teldrive.files
|
|
WHERE id = rec.id;
|
|
END LOOP;
|
|
END IF;
|
|
END;
|
|
$$;
|
|
|
|
|
|
CREATE OR REPLACE FUNCTION teldrive.create_directories(
|
|
IN tg_id BIGINT,
|
|
IN long_path TEXT
|
|
) RETURNS SETOF teldrive.files AS $$
|
|
DECLARE
|
|
path_parts TEXT[];
|
|
current_directory_id TEXT;
|
|
new_directory_id TEXT;
|
|
directory_name TEXT;
|
|
path_so_far TEXT;
|
|
depth_dir INTEGER;
|
|
BEGIN
|
|
path_parts := string_to_array(regexp_replace(long_path, '^/+', ''), '/');
|
|
|
|
path_so_far := '';
|
|
depth_dir := 0;
|
|
|
|
SELECT id INTO current_directory_id
|
|
FROM teldrive.files
|
|
WHERE parent_id = 'root' AND user_id = tg_id;
|
|
|
|
FOR directory_name IN SELECT unnest(path_parts) LOOP
|
|
path_so_far := CONCAT(path_so_far, '/', directory_name);
|
|
depth_dir := depth_dir + 1;
|
|
|
|
SELECT id INTO new_directory_id
|
|
FROM teldrive.files
|
|
WHERE parent_id = current_directory_id
|
|
AND "name" = directory_name
|
|
AND "user_id" = tg_id;
|
|
|
|
IF new_directory_id IS NULL THEN
|
|
INSERT INTO teldrive.files ("name", "type", mime_type, parent_id, "user_id", starred, "depth", "path")
|
|
VALUES (directory_name, 'folder', 'teldrive/folder', current_directory_id, tg_id, false, depth_dir, path_so_far)
|
|
RETURNING id INTO new_directory_id;
|
|
END IF;
|
|
|
|
current_directory_id := new_directory_id;
|
|
END LOOP;
|
|
|
|
RETURN QUERY SELECT * FROM teldrive.files WHERE id = current_directory_id;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
|
|
|
|
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,u_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 and user_id = u_id) THEN
|
|
RAISE EXCEPTION 'source directory not found';
|
|
END IF;
|
|
|
|
IF EXISTS (SELECT 1 FROM teldrive.files WHERE path = dest and user_id = u_id) 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 = (select id from teldrive.files where path = src) and id != dest_id and user_id = u_id;
|
|
|
|
IF POSITION(CONCAT(src,'/') IN dest) = 0 then
|
|
delete from teldrive.files where path = src and user_id = u_id;
|
|
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 and user_id = u_id;
|
|
perform from teldrive.update_folder(src_id,dest_base);
|
|
END IF;
|
|
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
|
|
|
|
CREATE OR REPLACE FUNCTION teldrive.account_stats(
|
|
IN u_id BIGINT
|
|
) RETURNS TABLE (total_size BIGINT, total_files BIGINT, ch_id BIGINT,ch_name TEXT ) AS $$
|
|
DECLARE
|
|
total_size BIGINT;
|
|
total_files BIGINT;
|
|
ch_id BIGINT;
|
|
ch_name TEXT;
|
|
BEGIN
|
|
SELECT COUNT(*), SUM(size) into total_files,total_size FROM teldrive.files WHERE user_id=u_id AND type= 'file' and status='active';
|
|
SELECT channel_id ,channel_name into ch_id,ch_name FROM teldrive.channels WHERE selected=TRUE AND user_id=u_id;
|
|
RETURN QUERY SELECT total_size,total_files,ch_id,ch_name;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
|
|
-- +goose StatementEnd
|
|
|
|
-- +goose Down
|
|
-- +goose StatementBegin
|
|
DROP PROCEDURE IF EXISTS teldrive.update_size;
|
|
DROP PROCEDURE IF EXISTS teldrive.delete_files;
|
|
DROP FUNCTION IF EXISTS teldrive.create_directories;
|
|
DROP FUNCTION IF EXISTS teldrive.split_path;
|
|
DROP FUNCTION IF EXISTS teldrive.update_folder;
|
|
DROP FUNCTION IF EXISTS teldrive.move_directory;
|
|
DROP FUNCTION IF EXISTS teldrive.account_stats;
|
|
-- +goose StatementEnd
|