From a28d2030900bed85b4a8da7a6b43fb0882f5ba68 Mon Sep 17 00:00:00 2001 From: divyam234 <47589864+divyam234@users.noreply.github.com> Date: Thu, 18 Jul 2024 16:57:09 +0530 Subject: [PATCH] refactor: add option to prevent error from get_file_from_path --- .../migrations/20240718164345_function.sql | 61 +++++++++++++++++++ pkg/services/file.go | 8 +-- 2 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 internal/database/migrations/20240718164345_function.sql diff --git a/internal/database/migrations/20240718164345_function.sql b/internal/database/migrations/20240718164345_function.sql new file mode 100644 index 0000000..323b2a3 --- /dev/null +++ b/internal/database/migrations/20240718164345_function.sql @@ -0,0 +1,61 @@ +-- +goose Up +-- +goose StatementBegin + +DROP FUNCTION IF EXISTS teldrive.get_file_from_path; + +CREATE OR REPLACE FUNCTION teldrive.get_file_from_path(full_path text, u_id bigint,throw_error boolean DEFAULT false) + RETURNS SETOF teldrive.files + LANGUAGE plpgsql +AS $function$ +DECLARE + target_id text; +begin + + IF full_path = '/' then + full_path := ''; + END IF; + + WITH RECURSIVE dir_hierarchy AS ( + SELECT + root.id, + root.name, + root.parent_id, + 0 AS depth, + '' as path + FROM + teldrive.files as root + WHERE + root.parent_id = 'root' AND root.user_id = u_id + + UNION ALL + + SELECT + f.id, + f.name, + f.parent_id, + dh.depth + 1 AS depth, + dh.path || '/' || f.name + FROM + teldrive.files f + JOIN + dir_hierarchy dh ON dh.id = f.parent_id + WHERE f.type = 'folder' AND f.user_id = u_id + ) + + SELECT id into target_id FROM dir_hierarchy dh + WHERE dh.path = full_path + ORDER BY dh.depth DESC + LIMIT 1; + + IF throw_error IS true AND target_id IS NULL THEN + RAISE EXCEPTION 'file not found for path: %', full_path; + END IF; + + RETURN QUERY select * from teldrive.files where id=target_id; + +END; +$function$ +; + + +-- +goose StatementEnd \ No newline at end of file diff --git a/pkg/services/file.go b/pkg/services/file.go index fa69b29..2fc0a91 100644 --- a/pkg/services/file.go +++ b/pkg/services/file.go @@ -206,7 +206,7 @@ func (fs *FileService) ListFiles(userId int64, fquery *schemas.FileQuery) (*sche if fquery.Op == "list" { if fquery.Path != "" && fquery.ParentID == "" { - query.Where("parent_id in (SELECT id FROM teldrive.get_file_from_path(?, ?))", fquery.Path, userId) + query.Where("parent_id in (SELECT id FROM teldrive.get_file_from_path(?, ?, ?))", fquery.Path, userId, true) } if fquery.ParentID != "" { query.Where("parent_id = ?", fquery.ParentID) @@ -273,7 +273,7 @@ func (fs *FileService) ListFiles(userId int64, fquery *schemas.FileQuery) (*sche query.Where("parent_id = ?", fquery.ParentID) } if fquery.ParentID == "" && fquery.Path != "" && fquery.Query == "" { - query.Where("parent_id in (SELECT id FROM teldrive.get_file_from_path(?, ?))", fquery.Path, userId) + query.Where("parent_id in (SELECT id FROM teldrive.get_file_from_path(?, ?, ?))", fquery.Path, userId, true) } if fquery.Type != "" { query.Where("type = ?", fquery.Type) @@ -307,7 +307,7 @@ func (fs *FileService) ListFiles(userId int64, fquery *schemas.FileQuery) (*sche if fquery.DeepSearch && fquery.Query != "" && fquery.Path != "" { fileQuery = fs.db.Clauses(exclause.With{Recursive: true, CTEs: []exclause.CTE{{Name: "subdirs", Subquery: exclause.Subquery{DB: fs.db.Model(&models.File{}).Select("id", "parent_id"). - Where("id in (SELECT id FROM teldrive.get_file_from_path(?, ?))", fquery.Path, userId). + Where("id in (SELECT id FROM teldrive.get_file_from_path(?, ?, ?))", fquery.Path, userId, true). Clauses(exclause.NewUnion("ALL ?", fs.db.Table("teldrive.files as f").Select("f.id", "f.parent_id"). Joins("inner join subdirs ON f.parent_id = subdirs.id")))}}}}) @@ -354,7 +354,7 @@ func (fs *FileService) getFileFromPath(path string, userId int64) (*models.File, var res []models.File - if err := fs.db.Raw("select * from teldrive.get_file_from_path(?, ?)", path, userId). + if err := fs.db.Raw("select * from teldrive.get_file_from_path(?, ?, ?)", path, userId, true). Scan(&res).Error; err != nil { return nil, err