package engine import ( "context" "fmt" "gosvc/logger" "robotfs/utils" ) func (f *FileSystemManager) DeleteDirectory(ctx context.Context, path utils.FullPath, isRecursive, ignoreRecursiveError bool) error { locker := f.locker.AcquireLock(string(path)) defer f.locker.ReleaseLock(locker) if string(path) == "/" { return nil } entry, err := f.FindEntry(ctx, path) if err != nil { return err } if entry.IsDir { err = f.doBatchDeleteFolderMetaAndData(ctx, entry, isRecursive, ignoreRecursiveError) if err != nil { return err } } // Delete the directory entry itself err = f.doDeleteEntryMetaAndData(ctx, entry) if err != nil { return err } if err := utils.Remove(f.root, string(path), isRecursive); err != nil { return err } return nil } func (f *FileSystemManager) doBatchDeleteFolderMetaAndData(ctx context.Context, entry *utils.Entry, isRecursive, ignoreRecursiveError bool) error { logger.Info("deleting folder => %s", entry.FullPath) lastFileName := "" includeLastFile := false for { lastFileName, err := f.doListDirectoryEntries(ctx, entry.FullPath, lastFileName, includeLastFile, 1000, func(sub *utils.Entry) bool { if sub.IsDir { // Recursively delete subdirectory err := f.doBatchDeleteFolderMetaAndData(ctx, sub, isRecursive, ignoreRecursiveError) if err == nil { err = f.doDeleteEntryMetaAndData(ctx, sub) } if err != nil && !ignoreRecursiveError { return false } } else { // Delete file entry err := f.doDeleteEntryMetaAndData(ctx, sub) if err != nil && !ignoreRecursiveError { return false } } return true }) if err != nil { return fmt.Errorf("list folder %s: %v", entry.FullPath, err) } if lastFileName == "" && !isRecursive { // Check if there are any entries hasEntries := false _, err := f.doListDirectoryEntries(ctx, entry.FullPath, "", false, 1, func(_ *utils.Entry) bool { hasEntries = true return false }) if err != nil { return fmt.Errorf("check directory empty: %v", err) } if hasEntries { return fmt.Errorf("directory not empty: %s", entry.FullPath) } } if lastFileName == "" { break } } if storeDeletionErr := f.meta.DeleteFolderChildren(ctx, entry.FullPath); storeDeletionErr != nil { return fmt.Errorf("delete folder children metadata: %v", storeDeletionErr) } return nil } func (f *FileSystemManager) doDeleteEntryMetaAndData(ctx context.Context, entry *utils.Entry) error { logger.Info("deleting entry => %s", entry.FullPath) if storeDeletionErr := f.meta.DeleteEntry(ctx, entry.FullPath); storeDeletionErr != nil { return fmt.Errorf("delete entry metadata: %v", storeDeletionErr) } return nil }