From 71df067a7640d6e441fd97a2ac551e014323d59b Mon Sep 17 00:00:00 2001 From: HFO4 <912394456@qq.com> Date: Thu, 21 Apr 2022 13:58:22 +0800 Subject: [PATCH] fix: create directory now ignore conflict error, it will return the existed folder --- models/folder.go | 8 ++++++-- pkg/filesystem/hooks.go | 12 ++++-------- pkg/filesystem/manage.go | 9 +++------ pkg/task/import.go | 18 +++++++----------- pkg/webdav/webdav.go | 6 +----- 5 files changed, 21 insertions(+), 32 deletions(-) diff --git a/models/folder.go b/models/folder.go index 6bb9d7b..251c127 100644 --- a/models/folder.go +++ b/models/folder.go @@ -23,11 +23,15 @@ type Folder struct { // Create 创建目录 func (folder *Folder) Create() (uint, error) { - if err := DB.Create(folder).Error; err != nil { + tx := DB.Begin() + if err := tx.FirstOrCreate(folder, *folder).Error; err != nil { + tx.Rollback() util.Log().Warning("无法插入目录记录, %s", err) return 0, err } - return folder.ID, nil + + err := tx.Commit().Error + return folder.ID, err } // GetChild 返回folder下名为name的子目录,不存在则返回错误 diff --git a/pkg/filesystem/hooks.go b/pkg/filesystem/hooks.go index fc4a68f..1f03301 100644 --- a/pkg/filesystem/hooks.go +++ b/pkg/filesystem/hooks.go @@ -203,14 +203,10 @@ func SlaveAfterUpload(session *serializer.UploadSession) Hook { func GenericAfterUpload(ctx context.Context, fs *FileSystem, fileHeader fsctx.FileHeader) error { fileInfo := fileHeader.Info() - // 检查路径是否存在,不存在就创建 - isExist, folder := fs.IsPathExist(fileInfo.VirtualPath) - if !isExist { - newFolder, err := fs.CreateDirectory(ctx, fileInfo.VirtualPath) - if err != nil { - return err - } - folder = newFolder + // 创建或查找根目录 + folder, err := fs.CreateDirectory(ctx, fileInfo.VirtualPath) + if err != nil { + return err } // 检查文件是否存在 diff --git a/pkg/filesystem/manage.go b/pkg/filesystem/manage.go index ec6eecf..97050ef 100644 --- a/pkg/filesystem/manage.go +++ b/pkg/filesystem/manage.go @@ -376,7 +376,8 @@ func (fs *FileSystem) listObjects(ctx context.Context, parent string, files []mo return objects } -// CreateDirectory 根据给定的完整创建目录,支持递归创建 +// CreateDirectory 根据给定的完整创建目录,支持递归创建。如果目录已存在,则直接 +// 返回已存在的目录。 func (fs *FileSystem) CreateDirectory(ctx context.Context, fullPath string) (*model.Folder, error) { if fullPath == "/" || fullPath == "." || fullPath == "" { return nil, ErrRootProtected @@ -398,10 +399,6 @@ func (fs *FileSystem) CreateDirectory(ctx context.Context, fullPath string) (*mo // 父目录是否存在 isExist, parent := fs.IsPathExist(base) if !isExist { - // 递归创建父目录 - if _, ok := ctx.Value(fsctx.IgnoreDirectoryConflictCtx).(bool); !ok { - ctx = context.WithValue(ctx, fsctx.IgnoreDirectoryConflictCtx, true) - } newParent, err := fs.CreateDirectory(ctx, base) if err != nil { return nil, err @@ -424,7 +421,7 @@ func (fs *FileSystem) CreateDirectory(ctx context.Context, fullPath string) (*mo if err != nil { if _, ok := ctx.Value(fsctx.IgnoreDirectoryConflictCtx).(bool); !ok { - return nil, ErrFolderExisted + return nil, fmt.Errorf("failed to create folder: %w", err) } } diff --git a/pkg/task/import.go b/pkg/task/import.go index e91bbed..efc32e9 100644 --- a/pkg/task/import.go +++ b/pkg/task/import.go @@ -150,18 +150,14 @@ func (job *ImportTask) Do() { if parent, ok := pathCache[virtualPath]; ok { parentFolder = parent } else { - exist, folder := fs.IsPathExist(virtualPath) - if exist { - parentFolder = folder - } else { - folder, err := fs.CreateDirectory(context.Background(), virtualPath) - if err != nil { - util.Log().Warning("导入任务无法创建用户目录[%s], %s", - virtualPath, err) - continue - } - parentFolder = folder + folder, err := fs.CreateDirectory(context.Background(), virtualPath) + if err != nil { + util.Log().Warning("导入任务无法创建用户目录[%s], %s", + virtualPath, err) + continue } + parentFolder = folder + } // 插入文件记录 diff --git a/pkg/webdav/webdav.go b/pkg/webdav/webdav.go index 241ffd9..770b352 100644 --- a/pkg/webdav/webdav.go +++ b/pkg/webdav/webdav.go @@ -400,11 +400,7 @@ func (h *Handler) handleMkcol(w http.ResponseWriter, r *http.Request, fs *filesy if r.ContentLength > 0 { return http.StatusUnsupportedMediaType, nil } - if strings.Contains(r.UserAgent(), "rclone") { - if _, ok := ctx.Value(fsctx.IgnoreDirectoryConflictCtx).(bool); !ok { - ctx = context.WithValue(ctx, fsctx.IgnoreDirectoryConflictCtx, true) - } - } + if _, err := fs.CreateDirectory(ctx, reqPath); err != nil { return http.StatusConflict, err }