mirror of
https://github.com/tgdrive/teldrive.git
synced 2025-02-22 22:13:25 +08:00
refactor: query shared files by path to support breadcrumbs
This commit is contained in:
parent
ad6e0ccb22
commit
99bf608792
4 changed files with 84 additions and 25 deletions
52
internal/database/migrations/20240915121635_function.sql
Normal file
52
internal/database/migrations/20240915121635_function.sql
Normal file
|
@ -0,0 +1,52 @@
|
|||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE OR REPLACE FUNCTION teldrive.get_path_from_file_id(file_id uuid)
|
||||
RETURNS text
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
full_path TEXT;
|
||||
trimmed_path TEXT;
|
||||
BEGIN
|
||||
WITH RECURSIVE path_hierarchy AS (
|
||||
SELECT
|
||||
f.id,
|
||||
f.name,
|
||||
f.parent_id,
|
||||
f.name AS path_segment
|
||||
FROM
|
||||
teldrive.files f
|
||||
WHERE
|
||||
f.id = file_id
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
p.id,
|
||||
p.name,
|
||||
p.parent_id,
|
||||
CASE
|
||||
WHEN ph.parent_id IS NULL THEN ph.path_segment
|
||||
ELSE p.name || '/' || ph.path_segment
|
||||
END AS path_segment
|
||||
FROM
|
||||
teldrive.files p
|
||||
JOIN
|
||||
path_hierarchy ph ON ph.parent_id = p.id
|
||||
)
|
||||
|
||||
SELECT path_segment INTO full_path
|
||||
FROM path_hierarchy
|
||||
WHERE parent_id IS NULL;
|
||||
|
||||
SELECT
|
||||
CASE
|
||||
WHEN position('/' in full_path) > 0 THEN substring(full_path from position('/' in full_path) + 1)
|
||||
ELSE full_path
|
||||
END INTO trimmed_path;
|
||||
|
||||
RETURN '/' || trimmed_path;
|
||||
END;
|
||||
$function$
|
||||
;
|
||||
-- +goose StatementEnd
|
|
@ -117,16 +117,20 @@ type FileShareIn struct {
|
|||
}
|
||||
|
||||
type FileShareOut struct {
|
||||
ID string `json:"id"`
|
||||
ID string `json:"id,omitempty"`
|
||||
ExpiresAt *time.Time `json:"expiresAt,omitempty"`
|
||||
Protected bool `json:"protected"`
|
||||
UserID int64 `json:"userId,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type FileShare struct {
|
||||
Password *string
|
||||
ExpiresAt *time.Time
|
||||
Type string
|
||||
FileId string
|
||||
UserId int64
|
||||
FileID string
|
||||
UserID int64
|
||||
Path string
|
||||
Name string
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@ type ShareAccess struct {
|
|||
}
|
||||
|
||||
type ShareFileQuery struct {
|
||||
ParentID string `form:"parentId"`
|
||||
Sort string `form:"sort"`
|
||||
Order string `form:"order"`
|
||||
Limit int `form:"limit"`
|
||||
Page int `form:"page"`
|
||||
Path string `form:"path"`
|
||||
Sort string `form:"sort"`
|
||||
Order string `form:"order"`
|
||||
Limit int `form:"limit"`
|
||||
Page int `form:"page"`
|
||||
}
|
||||
|
|
|
@ -36,9 +36,12 @@ func NewShareService(db *gorm.DB, fs *FileService, cache cache.Cacher) *ShareSer
|
|||
|
||||
func (ss *ShareService) GetShareById(shareId string) (*schemas.FileShareOut, *types.AppError) {
|
||||
|
||||
var result []models.FileShare
|
||||
var result []schemas.FileShare
|
||||
|
||||
if err := ss.db.Model(&models.FileShare{}).Where("id = ?", shareId).Find(&result).Error; err != nil {
|
||||
if err := ss.db.Model(&models.FileShare{}).Where("file_shares.id = ?", shareId).
|
||||
Select("file_shares.*", "f.type", "f.name").
|
||||
Joins("left join teldrive.files as f on f.id = file_shares.file_id").
|
||||
Scan(&result).Error; err != nil {
|
||||
return nil, &types.AppError{Error: err}
|
||||
}
|
||||
|
||||
|
@ -54,6 +57,8 @@ func (ss *ShareService) GetShareById(shareId string) (*schemas.FileShareOut, *ty
|
|||
ExpiresAt: result[0].ExpiresAt,
|
||||
Protected: result[0].Password != nil,
|
||||
UserID: result[0].UserID,
|
||||
Type: result[0].Type,
|
||||
Name: result[0].Name,
|
||||
}
|
||||
|
||||
return res, nil
|
||||
|
@ -82,7 +87,6 @@ func (ss *ShareService) ListShareFiles(shareId string, query *schemas.ShareFileQ
|
|||
var (
|
||||
userId int64
|
||||
fileType string
|
||||
fileId string
|
||||
)
|
||||
|
||||
var result []schemas.FileShare
|
||||
|
@ -91,7 +95,8 @@ func (ss *ShareService) ListShareFiles(shareId string, query *schemas.ShareFileQ
|
|||
|
||||
if err := ss.cache.Get(key, &result); err != nil {
|
||||
if err := ss.db.Model(&models.FileShare{}).Where("file_shares.id = ?", shareId).
|
||||
Select("file_shares.*", "f.type").
|
||||
Select("file_shares.*", "f.type",
|
||||
"(select get_path_from_file_id as path from teldrive.get_path_from_file_id(f.id))").
|
||||
Joins("left join teldrive.files as f on f.id = file_shares.file_id").
|
||||
Scan(&result).Error; err != nil {
|
||||
return nil, &types.AppError{Error: err}
|
||||
|
@ -118,34 +123,32 @@ func (ss *ShareService) ListShareFiles(shareId string, query *schemas.ShareFileQ
|
|||
|
||||
}
|
||||
|
||||
userId = result[0].UserId
|
||||
userId = result[0].UserID
|
||||
|
||||
fileType = "folder"
|
||||
|
||||
fileId = query.ParentID
|
||||
|
||||
if query.ParentID == "" {
|
||||
if query.Path == "" {
|
||||
fileType = result[0].Type
|
||||
fileId = result[0].FileId
|
||||
}
|
||||
|
||||
if fileType == "folder" {
|
||||
return ss.fs.ListFiles(userId, &schemas.FileQuery{
|
||||
ParentID: fileId,
|
||||
Limit: query.Limit,
|
||||
Page: query.Page,
|
||||
Order: query.Order,
|
||||
Sort: query.Sort,
|
||||
Op: "list"})
|
||||
Path: result[0].Path + query.Path,
|
||||
Limit: query.Limit,
|
||||
Page: query.Page,
|
||||
Order: query.Order,
|
||||
Sort: query.Sort,
|
||||
Op: "list"})
|
||||
} else {
|
||||
var file models.File
|
||||
if err := ss.db.Where("id = ?", fileId).First(&file).Error; err != nil {
|
||||
if err := ss.db.Where("id = ?", result[0].FileID).First(&file).Error; err != nil {
|
||||
if database.IsRecordNotFoundErr(err) {
|
||||
return nil, &types.AppError{Error: database.ErrNotFound, Code: http.StatusNotFound}
|
||||
}
|
||||
return nil, &types.AppError{Error: err}
|
||||
}
|
||||
return &schemas.FileResponse{Files: []schemas.FileOut{*mapper.ToFileOut(file)}}, nil
|
||||
return &schemas.FileResponse{Files: []schemas.FileOut{*mapper.ToFileOut(file)},
|
||||
Meta: schemas.Meta{TotalPages: 1, Count: 1, CurrentPage: 1}}, nil
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue